You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by Rodent of Unusual Size <co...@hyperreal.com> on 1997/06/30 03:32:26 UTC

cvs commit: apache/src CHANGES mod_userdir.c

coar        97/06/29 18:32:25

  Modified:    src       CHANGES mod_userdir.c
  Log:
  	Added ability to selectively enable/disable usernames for UserDir
  	translation.
  
  Reviewed by:	Randy Terbush, Marc Slemko, Dean Gaudet
  
  Revision  Changes    Path
  1.311     +5 -0      apache/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apache/src/CHANGES,v
  retrieving revision 1.310
  retrieving revision 1.311
  diff -C3 -r1.310 -r1.311
  *** CHANGES	1997/06/30 01:28:28	1.310
  --- CHANGES	1997/06/30 01:32:23	1.311
  ***************
  *** 1,5 ****
  --- 1,10 ----
    Changes with Apache 1.3
    
  +   *) Enhance UserDir directive (mod_userdir) to accept a list of
  +      usernames for the 'disable' keyword, and add 'enable user...' to
  +      selectively *en*able userdirs if they're globally disabled.
  +      [Ken Coar]
  + 
      *) If NETSCAPE_DBM_COMPAT is defined in EXTRA_CFLAGS then Apache
         will work with netscape dbm files.  (dbmmanage will probably not
         work however.) [Alexander Spohr <as...@netmatic.com>] PR#444
  
  
  
  1.16      +183 -65   apache/src/mod_userdir.c
  
  Index: mod_userdir.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/mod_userdir.c,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -C3 -r1.15 -r1.16
  *** mod_userdir.c	1997/06/15 19:22:32	1.15
  --- mod_userdir.c	1997/06/30 01:32:24	1.16
  ***************
  *** 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,146 ****
    
    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, '*');
    
    #if defined(__EMX__) || defined(WIN32)
          /* Add support for OS/2 drive letters */
  --- 90,263 ----
    
    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...', or 'enabled 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, '*');
    
    #if defined(__EMX__) || defined(WIN32)
          /* Add support for OS/2 drive letters */
  ***************
  *** 148,154 ****
    #else
          if ((userdir[0] == '/') || (userdir[0] == '\0')) {
    #endif
  ! 	if (x) {
    #ifdef WIN32
              /*
               * Crummy hack. Need to figure out whether we have
  --- 265,271 ----
    #else
          if ((userdir[0] == '/') || (userdir[0] == '\0')) {
    #endif
  !         if (x) {
    #ifdef WIN32
              /*
               * Crummy hack. Need to figure out whether we have
  ***************
  *** 159,194 ****
               */
              if (strchr(x+2, ':')) {
    #else
  ! 	  if (strchr(x, ':')) {
    #endif /* WIN32 */
  ! 	    redirect = pstrcat(r->pool, x, w, userdir, dname, NULL);
  ! 	    table_set (r->headers_out, "Location", redirect);
  ! 	    return REDIRECT;
  ! 	  }
  ! 	  else
  ! 	    filename = pstrcat (r->pool, x, w, userdir, NULL);
  ! 	}
  ! 	else
  ! 	  filename = pstrcat (r->pool, userdir, "/", w, NULL);
          }
          else if (strchr(userdir, ':')) {
  ! 	redirect = pstrcat(r->pool, userdir, "/", w, dname, NULL);
  ! 	table_set (r->headers_out, "Location", redirect);
  ! 	return REDIRECT;
          }
          else {
    #ifdef WIN32
              /* Need to figure out home dirs on NT */
              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 */
          }
    
  --- 276,312 ----
               */
              if (strchr(x+2, ':')) {
    #else
  !           if (strchr(x, ':')) {
    #endif /* WIN32 */
  !             redirect = pstrcat(r->pool, x, w, userdir, dname, NULL);
  !             table_set (r->headers_out, "Location", redirect);
  !             return REDIRECT;
  !           }
  !           else
  !             filename = pstrcat (r->pool, x, w, userdir, NULL);
  !         }
  !         else
  !           filename = pstrcat (r->pool, userdir, "/", w, NULL);
          }
          else if (strchr(userdir, ':')) {
  !         redirect = pstrcat(r->pool, userdir, "/", w, dname, NULL);
  !         table_set (r->headers_out, "Location", redirect);
  !         return REDIRECT;
          }
          else {
    #ifdef WIN32
              /* Need to figure out home dirs on NT */
              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 */
          }
    
  ***************
  *** 198,205 ****
           example, to run a CGI script for the user. 
           */
          if (filename && (!*userdirs || stat(filename, &r->finfo) != -1)) {
  ! 	r->filename = pstrcat(r->pool, filename, dname, NULL);
  ! 	return OK;
          }
        }
    
  --- 316,323 ----
           example, to run a CGI script for the user. 
           */
          if (filename && (!*userdirs || stat(filename, &r->finfo) != -1)) {
  !         r->filename = pstrcat(r->pool, filename, dname, NULL);
  !         return OK;
          }
        }
    
  ***************
  *** 208,226 ****
        
    module userdir_module = {
       STANDARD_MODULE_STUFF,
  !    NULL,			/* initializer */
  !    NULL,			/* dir config creater */
  !    NULL,			/* dir merger --- default is to override */
  !    create_userdir_config,	/* server config */
  !    NULL,			/* merge server config */
  !    userdir_cmds,		/* command table */
  !    NULL,			/* handlers */
  !    translate_userdir,		/*filename translation */
  !    NULL,			/* check_user_id */
  !    NULL,			/* check auth */
  !    NULL,			/* check access */
  !    NULL,			/* type_checker */
  !    NULL,			/* fixups */
  !    NULL,			/* logger */
  !    NULL				/* header parser */
    };
  --- 326,344 ----
        
    module userdir_module = {
       STANDARD_MODULE_STUFF,
  !    NULL,                        /* initializer */
  !    NULL,                        /* dir config creater */
  !    NULL,                        /* dir merger --- default is to override */
  !    create_userdir_config,       /* server config */
  !    NULL,                        /* merge server config */
  !    userdir_cmds,                /* command table */
  !    NULL,                        /* handlers */
  !    translate_userdir,           /*filename translation */
  !    NULL,                        /* check_user_id */
  !    NULL,                        /* check auth */
  !    NULL,                        /* check access */
  !    NULL,                        /* type_checker */
  !    NULL,                        /* fixups */
  !    NULL,                        /* logger */
  !    NULL                         /* header parser */
    };