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 <[EMAIL PROTECTED]>] 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 */ };