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
}