fielding 97/04/26 23:55:55
Modified: src CHANGES util_script.h util_script.c Log: Fix the above fix: if suexec is enabled, avoid destroying r->url while obtaining the /~user and save the username in a separate data area so that it won't be overwritten by the call to getgrgid(), and fix some misuse of the pool string allocation functions. Also fixes a general problem with parsing URL query info into args for CGI scripts. Closes PR#339, 367, 354, 453. Reviewed by: Dean Gaudet, Randy Terbush Revision Changes Path 1.251 +7 -0 apache/src/CHANGES Index: CHANGES =================================================================== RCS file: /export/home/cvs/apache/src/CHANGES,v retrieving revision 1.250 retrieving revision 1.251 diff -C3 -r1.250 -r1.251 *** CHANGES 1997/04/27 06:23:20 1.250 --- CHANGES 1997/04/27 06:55:51 1.251 *************** *** 24,29 **** --- 24,36 ---- *) Fix suexec segfault when group doesn't exist. [Gregory Neil Shapiro] PR#367, 368, 354, 453 + *) Fix the above fix: if suexec is enabled, avoid destroying r->url + while obtaining the /~user and save the username in a separate data + area so that it won't be overwritten by the call to getgrgid(), and + fix some misuse of the pool string allocation functions. Also fixes + a general problem with parsing URL query info into args for CGI scripts. + [Roy Fielding] PR#339, 367, 354, 453 + *) Fix IRIX warning about bzero undefined. [Marc Slemko] *) Fix problem with <Directory proxy:...>. [Martin Kraemer] PR#271 1.15 +0 -4 apache/src/util_script.h Index: util_script.h =================================================================== RCS file: /export/home/cvs/apache/src/util_script.h,v retrieving revision 1.14 retrieving revision 1.15 diff -C3 -r1.14 -r1.15 *** util_script.h 1997/03/18 09:46:27 1.14 --- util_script.h 1997/04/27 06:55:52 1.15 *************** *** 56,65 **** #define APACHE_ARG_MAX 512 #endif - char **create_argv(request_rec *r, char *av0, ...); - #ifdef __EMX__ - char **create_argv_cmd(pool *p, char *av0, const char *args, char *path); - #endif char **create_environment(pool *p, table *t); int find_path_info(char *uri, char *path_info); void add_cgi_vars(request_rec *r); --- 56,61 ---- 1.52 +62 -60 apache/src/util_script.c Index: util_script.c =================================================================== RCS file: /export/home/cvs/apache/src/util_script.c,v retrieving revision 1.51 retrieving revision 1.52 diff -C3 -r1.51 -r1.52 *** util_script.c 1997/04/25 13:39:33 1.51 --- util_script.c 1997/04/27 06:55:52 1.52 *************** *** 72,108 **** #define MALFORMED_MESSAGE "malformed header from script. Bad header=" #define MALFORMED_HEADER_LENGTH_TO_SHOW 30 ! char **create_argv(request_rec *r, char *av0, ...) { - int idx; char **av; ! char *t, *arg; ! va_list args; ! av = (char **)palloc(r->pool, APACHE_ARG_MAX); ! av[0] = av0; ! idx = 1; ! ! va_start(args, av0); ! while ((arg = va_arg(args, char *)) != NULL) { ! if ((t = strtok(arg, "+")) == NULL) ! break; ! unescape_url(t); ! av[idx] = escape_shell_cmd(r->pool, t); ! idx++; ! if (idx >= APACHE_ARG_MAX-1) break; ! ! while ((t = strtok(NULL, "+")) != NULL) { ! unescape_url(t); ! assert(idx < APACHE_ARG_MAX); ! av[idx] = escape_shell_cmd(r->pool, t); ! idx++; ! if (idx >= APACHE_ARG_MAX-1) break; ! } } - va_end(args); av[idx] = NULL; return av; --- 72,100 ---- #define MALFORMED_MESSAGE "malformed header from script. Bad header=" #define MALFORMED_HEADER_LENGTH_TO_SHOW 30 ! static char **create_argv(pool *p, char *path, char *user, char *group, ! char *av0, const char *reqargs) { char **av; ! char *t; ! char *args = pstrdup(p, reqargs); ! int idx = 0; ! ! av = (char **)palloc(p, APACHE_ARG_MAX * sizeof(char *)); ! ! if (path) ! av[idx++] = path; ! if (user) ! av[idx++] = user; ! if (group) ! av[idx++] = group; ! av[idx++] = av0; ! while ((idx < APACHE_ARG_MAX) && ((t = strtok(args, "+")) != NULL)) { unescape_url(t); ! av[idx++] = escape_shell_cmd(p, t); } av[idx] = NULL; return av; *************** *** 401,407 **** } #ifdef __EMX__ ! char **create_argv_cmd(pool *p, char *av0, const char *args, char *path) { register int x,n; char **av; char *w; --- 393,400 ---- } #ifdef __EMX__ ! static char **create_argv_cmd(pool *p, char *av0, const char *args, char *path) ! { register int x,n; char **av; char *w; *************** *** 432,444 **** void call_exec (request_rec *r, char *argv0, char **env, int shellcmd) { ! char *execuser; ! core_dir_config *conf; ! struct passwd *pw; ! struct group *gr; ! char *grpname; ! ! conf = (core_dir_config *)get_module_config(r->per_dir_config, &core_module); /* the fd on r->server->error_log is closed, but we need somewhere to * put the error messages from the log_* functions. So, we use stderr, --- 425,432 ---- void call_exec (request_rec *r, char *argv0, char **env, int shellcmd) { ! core_dir_config *conf = ! (core_dir_config *)get_module_config(r->per_dir_config, &core_module); /* the fd on r->server->error_log is closed, but we need somewhere to * put the error messages from the log_* functions. So, we use stderr, *************** *** 525,531 **** char *emxtemp; /* For OS/2 place the variables in the current ! enviornment then it will be inherited. This way the program will also get all of OS/2's other SETs. */ for (emxloop=0; ((emxtemp = env[emxloop]) != NULL); emxloop++) putenv(emxtemp); --- 513,519 ---- char *emxtemp; /* For OS/2 place the variables in the current ! environment so that they will be inherited. This way the program will also get all of OS/2's other SETs. */ for (emxloop=0; ((emxtemp = env[emxloop]) != NULL); emxloop++) putenv(emxtemp); *************** *** 536,580 **** execv("CMD.EXE", create_argv_cmd(r->pool, argv0, r->args, r->filename)); } else ! execv(r->filename, create_argv(r, argv0, r->args, (void *)NULL)); } } #else if ( suexec_enabled && ((r->server->server_uid != user_id) || (r->server->server_gid != group_id) || ! (!strncmp("/~", r->uri, 2))) ) { ! if (!strncmp("/~",r->uri,2)) { ! r->uri += 2; ! if ((pw = getpwnam (getword_nc (r->pool, &r->uri, '/'))) == NULL) { ! log_unixerr("getpwnam", NULL, "invalid username", r->server); ! return; } ! r->uri -= 2; ! if ((gr = getgrgid (pw->pw_gid)) == NULL) { ! if ((grpname = palloc (r->pool, 16)) == NULL) ! return; ! else ! ap_snprintf(grpname, sizeof(grpname), "%d\0", pw->pw_gid); } ! else ! grpname = gr->gr_name; ! execuser = (char *) palloc (r->pool, (sizeof(pw->pw_name) + 1)); ! execuser = pstrcat (r->pool, "~", pw->pw_name, NULL); ! } else { if ((pw = getpwuid (r->server->server_uid)) == NULL) { log_unixerr("getpwuid", NULL, "invalid userid", r->server); return; } ! if ((gr = getgrgid (r->server->server_gid)) == NULL) { log_unixerr("getgrgid", NULL, "invalid groupid", r->server); return; } ! execuser = (char *) palloc (r->pool, sizeof(pw->pw_name)); ! execuser = pw->pw_name; ! } if (shellcmd) execle(SUEXEC_BIN, SUEXEC_BIN, execuser, grpname, argv0, NULL, env); --- 524,579 ---- execv("CMD.EXE", create_argv_cmd(r->pool, argv0, r->args, r->filename)); } else ! execv(r->filename, ! create_argv(r->pool, NULL, NULL, NULL, argv0, r->args)); } } #else if ( suexec_enabled && ((r->server->server_uid != user_id) || (r->server->server_gid != group_id) || ! (!strncmp("/~",r->uri,2))) ) { ! char *execuser, *grpname; ! struct passwd *pw; ! struct group *gr; ! ! if (!strncmp("/~",r->uri,2)) { ! gid_t user_gid; ! char *username = pstrdup(r->pool, r->uri + 2); ! int pos = ind(username, '/'); ! ! if (pos >= 0) username[pos] = '\0'; ! ! if ((pw = getpwnam(username)) == NULL) { ! log_unixerr("getpwnam",username,"invalid username",r->server); ! return; } ! execuser = pstrcat(r->pool, "~", pw->pw_name, NULL); ! user_gid = pw->pw_gid; ! ! if ((gr = getgrgid(user_gid)) == NULL) { ! if ((grpname = palloc (r->pool, 16)) == NULL) ! return; ! else ! ap_snprintf(grpname, 16, "%d", user_gid); } ! else ! grpname = gr->gr_name; ! } else { if ((pw = getpwuid (r->server->server_uid)) == NULL) { log_unixerr("getpwuid", NULL, "invalid userid", r->server); return; } ! execuser = pstrdup(r->pool, pw->pw_name); ! ! if ((gr = getgrgid (r->server->server_gid)) == NULL) { log_unixerr("getgrgid", NULL, "invalid groupid", r->server); return; } ! grpname = gr->gr_name; ! } if (shellcmd) execle(SUEXEC_BIN, SUEXEC_BIN, execuser, grpname, argv0, NULL, env); *************** *** 583,591 **** execle(SUEXEC_BIN, SUEXEC_BIN, execuser, grpname, argv0, NULL, env); else { ! execve(SUEXEC_BIN, ! create_argv(r, SUEXEC_BIN, execuser, grpname, argv0, r->args, (void *)NULL), ! env); } } else { --- 582,591 ---- execle(SUEXEC_BIN, SUEXEC_BIN, execuser, grpname, argv0, NULL, env); else { ! execve(SUEXEC_BIN, ! create_argv(r->pool, SUEXEC_BIN, execuser, grpname, ! argv0, r->args), ! env); } } else { *************** *** 596,602 **** execle(r->filename, argv0, NULL, env); else ! execve(r->filename, create_argv(r, argv0, r->args, (void *)NULL), env); } #endif } --- 596,604 ---- execle(r->filename, argv0, NULL, env); else ! execve(r->filename, ! create_argv(r->pool, NULL, NULL, NULL, argv0, r->args), ! env); } #endif }