You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Rodent of Unusual Size <co...@decus.org> on 1997/06/29 17:05:09 UTC

[PATCH] to enhance "UserDir [enable/disable] username..."

    Okey, Randy, here you are..

    This patch extends the UserDir directive syntax to the following:

     UserDir disabled
        Globally disables translation of ~name as a user directory.
    	(This is not new.)  Can be overridden on a per-username basis by
    	"enable" (see below).  (That part is new.)

     UserDir disabled username ...
        Explicitly prevents the listed usernames from being translated,
    	regardless of the global disablement state.  (Totally new.)

     UserDir enabled username ...
        If userdir translation is globally disabled, usernames specified
    	here will still be translated - unless they also appear in a
    	"disabled username" directive.  (Totally new.)

     UserDir anything-else
        The usual stuff defining translation rules.  (No change.)

    The keywords "disable" and "enable" are synonymous with "disabled"
    and "enabled", respectively.

    This stuff was on hold for 1.2.0.  Votes for HEAD, please..
    Comments on 1.2.1 inclusion?  (I think not - this isn't a bug,
    unless we also add "UserDir disabled root" to the .conf-dist files.)

    #ken    :-)}

Index: mod_userdir.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_userdir.c,v
retrieving revision 1.15
diff -c -r1.15 mod_userdir.c
*** mod_userdir.c	1997/06/15 19:22:32	1.15
--- mod_userdir.c	1997/06/29 16:01:21
***************
*** 76,81 ****
--- 76,88 ----
   *
   * UserDir public_html /usr/web http://www.xyz.com/users
   *
+  * Modified by Ken Coar to provide for the following:
+  *
+  * UserDir disable[d] username ...
+  * UserDir enable[d] username ...
+  *
+  * If "disabled" has no other arguments, *all* ~<username> references are
+  * disabled, except those explicitly turned on with the "enabled" keyword.
   */
  
  #include "httpd.h"
***************
*** 83,143 ****
  
  module userdir_module;
  
  /*
!  * Sever config for this module is a little unconventional...
!  * It's just one string anyway, so why pretend?
   */
  
! void *create_userdir_config (pool *dummy, server_rec *s) { 
!     return (void*)DEFAULT_USER_DIR; 
  }
  
  const char *set_user_dir (cmd_parms *cmd, void *dummy, char *arg)
  {
!     void *server_conf = cmd->server->module_config;
!     
!     set_module_config (server_conf, &userdir_module, pstrdup (cmd->pool, arg));
      return NULL;
  }
  
  command_rec userdir_cmds[] = {
  { "UserDir", set_user_dir, NULL, RSRC_CONF, RAW_ARGS,
!     "the public subdirectory in users' home directories, or 'disabled'" },
  { NULL }
  };
  
  int translate_userdir (request_rec *r)
  {
      void *server_conf = r->server->module_config;
!     const char *userdirs = (char *)get_module_config(server_conf,
! 						     &userdir_module);
      char *name = r->uri;
      const char *w, *dname, *redirect;
      char *x = NULL;
  
!     if (userdirs == NULL || !strcasecmp(userdirs, "disabled") ||
!         (name[0] != '/') || (name[1] != '~')) {
!       return DECLINED;
      }
  
!     while (*userdirs) {
!       const char *userdir = getword_conf (r->pool, &userdirs);
!       char *filename = NULL;
  
!       dname = name + 2;
!       w = getword(r->pool, &dname, '/');
  
!       if (!strcmp(w, ""))
  	return DECLINED;
  
!       /* The 'dname' funny business involves backing it up to capture
!        * the '/' delimiting the "/~user" part from the rest of the URL,
!        * in case there was one (the case where there wasn't being just
!        * "GET /~user HTTP/1.0", for which we don't want to tack on a
!        * '/' onto the filename).
!        */
! 	
!       if (dname[-1] == '/') --dname;
  
        if (strchr(userdir, '*'))
  	x = getword(r->pool, &userdir, '*');
--- 90,260 ----
  
  module userdir_module;
  
+ typedef struct userdir_config {
+     int	    globally_disabled;
+     char    *userdir;
+     table   *enabled_users;
+     table   *disabled_users;
+ } userdir_config;
+ 
  /*
!  * Server config for this module: global disablement flag, a list of usernames
!  * ineligible for UserDir access, a list of those immune to global (but not
!  * explicit) disablement, and the replacement string for all others.
   */
  
! void *create_userdir_config (pool *p, server_rec *s) { 
!     userdir_config
! 	    *newcfg = (userdir_config *) pcalloc (p, sizeof(userdir_config));
! 
!     newcfg->globally_disabled = 0;
!     newcfg->userdir = DEFAULT_USER_DIR;
!     newcfg->enabled_users = make_table (p, 4);
!     newcfg->disabled_users = make_table (p, 4);
!     return (void *) newcfg; 
  }
  
+ #define O_DEFAULT 0
+ #define O_ENABLE 1
+ #define O_DISABLE 2
+ 
  const char *set_user_dir (cmd_parms *cmd, void *dummy, char *arg)
  {
!     userdir_config
! 	    *s_cfg = (userdir_config *) get_module_config
! 					    (
! 						cmd->server->module_config,
! 				    		&userdir_module
! 					    ); 
!     char    *username;
!     const char
! 	    *usernames = arg;
!     char    *kw = getword_conf (cmd->pool, &usernames);
!     table   *usertable;
!     int	    optype = O_DEFAULT;
! 
!     /*
!      * Let's do the comparisons once.
!      */
!     if ((! strcasecmp (kw, "disable")) || (! strcasecmp (kw, "disabled"))) {
! 	optype = O_DISABLE;
! 	/*
! 	 * If there are no usernames specified, this is a global disable - we
! 	 * need do no more at this point than record the fact.
! 	 */
! 	if (strlen (usernames) == 0) {
! 	    s_cfg->globally_disabled = 1;
! 	    return NULL;
! 	}
! 	usertable = s_cfg->disabled_users;
!     }
!     else if ((! strcasecmp (kw, "enable")) || (! strcasecmp (kw, "enabled"))) {
! 	/*
! 	 * The "disable" keyword can stand alone or take a list of names, but
! 	 * the "enable" keyword requires the list.  Whinge if it doesn't have
! 	 * it.
! 	 */
! 	if (strlen (usernames) == 0) {
! 	    return "UserDir \"enable\" keyword requires a list of usernames";
! 	}
! 	optype = O_ENABLE;
! 	usertable = s_cfg->enabled_users;
!     }
!     else {
! 	optype = O_DEFAULT;
!     }
!     /*
!      * If the first (only?) value isn't one of our keywords, just copy the
!      * string to the userdir string.
!      */
!     if (optype == O_DEFAULT) {
! 	s_cfg->userdir = pstrdup (cmd->pool, arg);
! 	return NULL;
!     }
!     /*
!      * Now we just take each word in turn from the command line and add it to
!      * the appropriate table.
!      */
!     while (*usernames) {
! 	username = getword_conf (cmd->pool, &usernames);
! 	table_set (usertable, username, kw);
!     }
      return NULL;
  }
  
  command_rec userdir_cmds[] = {
  { "UserDir", set_user_dir, NULL, RSRC_CONF, RAW_ARGS,
!     "the public subdirectory in users' home directories, or 'disabled', or 'disabled username username...'" },
  { NULL }
  };
  
  int translate_userdir (request_rec *r)
  {
      void *server_conf = r->server->module_config;
!     const userdir_config *s_cfg =
! 	    (userdir_config *) get_module_config (server_conf, &userdir_module);
      char *name = r->uri;
+     const char *userdirs = pstrdup (r->pool, s_cfg->userdir);
      const char *w, *dname, *redirect;
      char *x = NULL;
  
!     /*
!      * If the URI doesn't match our basic pattern, we've nothing to do with
!      * it.
!      */
!     if (
! 	(s_cfg->userdir == NULL) ||
!         (name[0] != '/') ||
! 	(name[1] != '~')
!        ) {
! 	return DECLINED;
      }
  
!     dname = name + 2;
!     w = getword(r->pool, &dname, '/');
  
!     /*
!      * The 'dname' funny business involves backing it up to capture
!      * the '/' delimiting the "/~user" part from the rest of the URL,
!      * in case there was one (the case where there wasn't being just
!      * "GET /~user HTTP/1.0", for which we don't want to tack on a
!      * '/' onto the filename).
!      */
! 	
!     if (dname[-1] == '/') {
! 	--dname;
!     }
  
!     /*
!      * If there's no username, it's not for us.
!      */
!     if (! strcmp(w, "")) {
! 	return DECLINED;
!     }
!     /*
!      * Nor if there's an username but it's in the disabled list.
!      */
!     if (table_get (s_cfg->disabled_users, w) != NULL) {
  	return DECLINED;
+     }
+     /*
+      * If there's a global interdiction on UserDirs, check to see if this name
+      * is one of the Blessed.
+      */
+     if (
+ 	s_cfg->globally_disabled &&
+ 	(table_get (s_cfg->enabled_users, w) == NULL)
+        ) {
+ 	return DECLINED;
+     }
  
!     /*
!      * Special cases all checked, onward to normal substitution processing.
!      */
! 
!     while (*userdirs) {
!       const char *userdir = getword_conf (r->pool, &userdirs);
!       char *filename = NULL;
  
        if (strchr(userdir, '*'))
  	x = getword(r->pool, &userdir, '*');
***************
*** 182,194 ****
            return DECLINED;
  #else /* WIN32 */
  	struct passwd *pw;
! 	if((pw=getpwnam(w)))
  #ifdef __EMX__
! 	  /* Need to manually add user name for OS/2 */
! 	  filename = pstrcat (r->pool, pw->pw_dir, w, "/", userdir, NULL);
  #else
! 	  filename = pstrcat (r->pool, pw->pw_dir, "/", userdir, NULL);
  #endif
  #endif /* WIN32 */
        }
  
--- 299,312 ----
            return DECLINED;
  #else /* WIN32 */
  	struct passwd *pw;
! 	if ((pw = getpwnam(w))) {
  #ifdef __EMX__
! 	    /* Need to manually add user name for OS/2 */
! 	    filename = pstrcat (r->pool, pw->pw_dir, w, "/", userdir, NULL);
  #else
! 	    filename = pstrcat (r->pool, pw->pw_dir, "/", userdir, NULL);
  #endif
+ 	}
  #endif /* WIN32 */
        }
  

Re: [PATCH] to enhance "UserDir [enable/disable] username..."

Posted by Marc Slemko <ma...@znep.com>.
+1 on HEAD, with the following comments:

You use tabs in some places; tabs should not be used, unfortunately.  I
think that is silly and tabs are the best thing since sliced bread, but
that's been gone through before my time...  Yes, they are used other
places but that is no reason to add new code that doesn't conform.  What
is worse than spaces is a mix of tabs and spaces.  Tabs let me set my tab
stops to whatever I feel like.  Spaces make me cry.  Tabs and spaces make
everything wave around on my screen.

And:

 command_rec userdir_cmds[] = {
 { "UserDir", set_user_dir, NULL, RSRC_CONF, RAW_ARGS,
-    "the public subdirectory in users' home directories, or 'disabled'" },
+    "the public subdirectory in users' home directories, or 'disabled', or 'disabled username username...'" },
 { NULL }
 };

Does not completely describe the options.


On Sun, 29 Jun 1997, Rodent of Unusual Size wrote:

>     Okey, Randy, here you are..
> 
>     This patch extends the UserDir directive syntax to the following:
> 
>      UserDir disabled
>         Globally disables translation of ~name as a user directory.
>     	(This is not new.)  Can be overridden on a per-username basis by
>     	"enable" (see below).  (That part is new.)
> 
>      UserDir disabled username ...
>         Explicitly prevents the listed usernames from being translated,
>     	regardless of the global disablement state.  (Totally new.)
> 
>      UserDir enabled username ...
>         If userdir translation is globally disabled, usernames specified
>     	here will still be translated - unless they also appear in a
>     	"disabled username" directive.  (Totally new.)
> 
>      UserDir anything-else
>         The usual stuff defining translation rules.  (No change.)
> 
>     The keywords "disable" and "enable" are synonymous with "disabled"
>     and "enabled", respectively.
> 
>     This stuff was on hold for 1.2.0.  Votes for HEAD, please..
>     Comments on 1.2.1 inclusion?  (I think not - this isn't a bug,
>     unless we also add "UserDir disabled root" to the .conf-dist files.)
> 
>     #ken    :-)}
> 
> Index: mod_userdir.c
> ===================================================================
> RCS file: /export/home/cvs/apache/src/mod_userdir.c,v
> retrieving revision 1.15
> diff -c -r1.15 mod_userdir.c
> *** mod_userdir.c	1997/06/15 19:22:32	1.15
> --- mod_userdir.c	1997/06/29 16:01:21
> ***************
> *** 76,81 ****
> --- 76,88 ----
>    *
>    * UserDir public_html /usr/web http://www.xyz.com/users
>    *
> +  * Modified by Ken Coar to provide for the following:
> +  *
> +  * UserDir disable[d] username ...
> +  * UserDir enable[d] username ...
> +  *
> +  * If "disabled" has no other arguments, *all* ~<username> references are
> +  * disabled, except those explicitly turned on with the "enabled" keyword.
>    */
>   
>   #include "httpd.h"
> ***************
> *** 83,143 ****
>   
>   module userdir_module;
>   
>   /*
> !  * Sever config for this module is a little unconventional...
> !  * It's just one string anyway, so why pretend?
>    */
>   
> ! void *create_userdir_config (pool *dummy, server_rec *s) { 
> !     return (void*)DEFAULT_USER_DIR; 
>   }
>   
>   const char *set_user_dir (cmd_parms *cmd, void *dummy, char *arg)
>   {
> !     void *server_conf = cmd->server->module_config;
> !     
> !     set_module_config (server_conf, &userdir_module, pstrdup (cmd->pool, arg));
>       return NULL;
>   }
>   
>   command_rec userdir_cmds[] = {
>   { "UserDir", set_user_dir, NULL, RSRC_CONF, RAW_ARGS,
> !     "the public subdirectory in users' home directories, or 'disabled'" },
>   { NULL }
>   };
>   
>   int translate_userdir (request_rec *r)
>   {
>       void *server_conf = r->server->module_config;
> !     const char *userdirs = (char *)get_module_config(server_conf,
> ! 						     &userdir_module);
>       char *name = r->uri;
>       const char *w, *dname, *redirect;
>       char *x = NULL;
>   
> !     if (userdirs == NULL || !strcasecmp(userdirs, "disabled") ||
> !         (name[0] != '/') || (name[1] != '~')) {
> !       return DECLINED;
>       }
>   
> !     while (*userdirs) {
> !       const char *userdir = getword_conf (r->pool, &userdirs);
> !       char *filename = NULL;
>   
> !       dname = name + 2;
> !       w = getword(r->pool, &dname, '/');
>   
> !       if (!strcmp(w, ""))
>   	return DECLINED;
>   
> !       /* The 'dname' funny business involves backing it up to capture
> !        * the '/' delimiting the "/~user" part from the rest of the URL,
> !        * in case there was one (the case where there wasn't being just
> !        * "GET /~user HTTP/1.0", for which we don't want to tack on a
> !        * '/' onto the filename).
> !        */
> ! 	
> !       if (dname[-1] == '/') --dname;
>   
>         if (strchr(userdir, '*'))
>   	x = getword(r->pool, &userdir, '*');
> --- 90,260 ----
>   
>   module userdir_module;
>   
> + typedef struct userdir_config {
> +     int	    globally_disabled;
> +     char    *userdir;
> +     table   *enabled_users;
> +     table   *disabled_users;
> + } userdir_config;
> + 
>   /*
> !  * Server config for this module: global disablement flag, a list of usernames
> !  * ineligible for UserDir access, a list of those immune to global (but not
> !  * explicit) disablement, and the replacement string for all others.
>    */
>   
> ! void *create_userdir_config (pool *p, server_rec *s) { 
> !     userdir_config
> ! 	    *newcfg = (userdir_config *) pcalloc (p, sizeof(userdir_config));
> ! 
> !     newcfg->globally_disabled = 0;
> !     newcfg->userdir = DEFAULT_USER_DIR;
> !     newcfg->enabled_users = make_table (p, 4);
> !     newcfg->disabled_users = make_table (p, 4);
> !     return (void *) newcfg; 
>   }
>   
> + #define O_DEFAULT 0
> + #define O_ENABLE 1
> + #define O_DISABLE 2
> + 
>   const char *set_user_dir (cmd_parms *cmd, void *dummy, char *arg)
>   {
> !     userdir_config
> ! 	    *s_cfg = (userdir_config *) get_module_config
> ! 					    (
> ! 						cmd->server->module_config,
> ! 				    		&userdir_module
> ! 					    ); 
> !     char    *username;
> !     const char
> ! 	    *usernames = arg;
> !     char    *kw = getword_conf (cmd->pool, &usernames);
> !     table   *usertable;
> !     int	    optype = O_DEFAULT;
> ! 
> !     /*
> !      * Let's do the comparisons once.
> !      */
> !     if ((! strcasecmp (kw, "disable")) || (! strcasecmp (kw, "disabled"))) {
> ! 	optype = O_DISABLE;
> ! 	/*
> ! 	 * If there are no usernames specified, this is a global disable - we
> ! 	 * need do no more at this point than record the fact.
> ! 	 */
> ! 	if (strlen (usernames) == 0) {
> ! 	    s_cfg->globally_disabled = 1;
> ! 	    return NULL;
> ! 	}
> ! 	usertable = s_cfg->disabled_users;
> !     }
> !     else if ((! strcasecmp (kw, "enable")) || (! strcasecmp (kw, "enabled"))) {
> ! 	/*
> ! 	 * The "disable" keyword can stand alone or take a list of names, but
> ! 	 * the "enable" keyword requires the list.  Whinge if it doesn't have
> ! 	 * it.
> ! 	 */
> ! 	if (strlen (usernames) == 0) {
> ! 	    return "UserDir \"enable\" keyword requires a list of usernames";
> ! 	}
> ! 	optype = O_ENABLE;
> ! 	usertable = s_cfg->enabled_users;
> !     }
> !     else {
> ! 	optype = O_DEFAULT;
> !     }
> !     /*
> !      * If the first (only?) value isn't one of our keywords, just copy the
> !      * string to the userdir string.
> !      */
> !     if (optype == O_DEFAULT) {
> ! 	s_cfg->userdir = pstrdup (cmd->pool, arg);
> ! 	return NULL;
> !     }
> !     /*
> !      * Now we just take each word in turn from the command line and add it to
> !      * the appropriate table.
> !      */
> !     while (*usernames) {
> ! 	username = getword_conf (cmd->pool, &usernames);
> ! 	table_set (usertable, username, kw);
> !     }
>       return NULL;
>   }
>   
>   command_rec userdir_cmds[] = {
>   { "UserDir", set_user_dir, NULL, RSRC_CONF, RAW_ARGS,
> !     "the public subdirectory in users' home directories, or 'disabled', or 'disabled username username...'" },
>   { NULL }
>   };
>   
>   int translate_userdir (request_rec *r)
>   {
>       void *server_conf = r->server->module_config;
> !     const userdir_config *s_cfg =
> ! 	    (userdir_config *) get_module_config (server_conf, &userdir_module);
>       char *name = r->uri;
> +     const char *userdirs = pstrdup (r->pool, s_cfg->userdir);
>       const char *w, *dname, *redirect;
>       char *x = NULL;
>   
> !     /*
> !      * If the URI doesn't match our basic pattern, we've nothing to do with
> !      * it.
> !      */
> !     if (
> ! 	(s_cfg->userdir == NULL) ||
> !         (name[0] != '/') ||
> ! 	(name[1] != '~')
> !        ) {
> ! 	return DECLINED;
>       }
>   
> !     dname = name + 2;
> !     w = getword(r->pool, &dname, '/');
>   
> !     /*
> !      * The 'dname' funny business involves backing it up to capture
> !      * the '/' delimiting the "/~user" part from the rest of the URL,
> !      * in case there was one (the case where there wasn't being just
> !      * "GET /~user HTTP/1.0", for which we don't want to tack on a
> !      * '/' onto the filename).
> !      */
> ! 	
> !     if (dname[-1] == '/') {
> ! 	--dname;
> !     }
>   
> !     /*
> !      * If there's no username, it's not for us.
> !      */
> !     if (! strcmp(w, "")) {
> ! 	return DECLINED;
> !     }
> !     /*
> !      * Nor if there's an username but it's in the disabled list.
> !      */
> !     if (table_get (s_cfg->disabled_users, w) != NULL) {
>   	return DECLINED;
> +     }
> +     /*
> +      * If there's a global interdiction on UserDirs, check to see if this name
> +      * is one of the Blessed.
> +      */
> +     if (
> + 	s_cfg->globally_disabled &&
> + 	(table_get (s_cfg->enabled_users, w) == NULL)
> +        ) {
> + 	return DECLINED;
> +     }
>   
> !     /*
> !      * Special cases all checked, onward to normal substitution processing.
> !      */
> ! 
> !     while (*userdirs) {
> !       const char *userdir = getword_conf (r->pool, &userdirs);
> !       char *filename = NULL;
>   
>         if (strchr(userdir, '*'))
>   	x = getword(r->pool, &userdir, '*');
> ***************
> *** 182,194 ****
>             return DECLINED;
>   #else /* WIN32 */
>   	struct passwd *pw;
> ! 	if((pw=getpwnam(w)))
>   #ifdef __EMX__
> ! 	  /* Need to manually add user name for OS/2 */
> ! 	  filename = pstrcat (r->pool, pw->pw_dir, w, "/", userdir, NULL);
>   #else
> ! 	  filename = pstrcat (r->pool, pw->pw_dir, "/", userdir, NULL);
>   #endif
>   #endif /* WIN32 */
>         }
>   
> --- 299,312 ----
>             return DECLINED;
>   #else /* WIN32 */
>   	struct passwd *pw;
> ! 	if ((pw = getpwnam(w))) {
>   #ifdef __EMX__
> ! 	    /* Need to manually add user name for OS/2 */
> ! 	    filename = pstrcat (r->pool, pw->pw_dir, w, "/", userdir, NULL);
>   #else
> ! 	    filename = pstrcat (r->pool, pw->pw_dir, "/", userdir, NULL);
>   #endif
> + 	}
>   #endif /* WIN32 */
>         }
>   
> 


Re: [PATCH] to enhance "UserDir [enable/disable] username..."

Posted by Dean Gaudet <dg...@arctic.org>.
+1 on HEAD.  -1 on 1.2.1 it's a feature.

Dean

On Sun, 29 Jun 1997, Rodent of Unusual Size wrote:
>     This patch extends the UserDir directive syntax to the following: