httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Randy Terbush <ra...@zyzzyva.com>
Subject Re: [PATCH] Fix suexec goofing in util_script.c
Date Sat, 26 Apr 1997 14:23:44 GMT

+1

I have tested the _non_ ~user parts of this patch. Works great.
Less filling.


> Why is it that every time I try to fix one thing I end up finding
> a bunch of other bugs that need fixing as well?  Anyway, the below
> patch fixes PR#453 and PR#339 and some pre-bugdb reports of scripts
> not getting the right arguments.
> 
> The fix that Jason described earlier today required a new create_argv
> function, which I copied from the existing one and started tooling away
> and then realized that the existing function is totally bogus (for both
> suexec and non-suexec users).  So, rather than creating two bogus
> functions, I just replaced the existing one (and made it static because
> it is specific to util_script and of no use to other files).  Aside from
> being faster and not including an always-false loop test, the new one
> does not lose arguments after the first "+".
> 
> The rest of the change is as described earlier: 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 do so in a way that uses the pool string allocation
> functions correctly.
> 
> .....Roy
> 
> Index: util_script.h
> ===================================================================
> RCS file: /export/home/cvs/apache/src/util_script.h,v
> retrieving revision 1.14
> diff -c -r1.14 util_script.h
> *** util_script.h	1997/03/18 09:46:27	1.14
> --- util_script.h	1997/04/26 00:59:18
> ***************
> *** 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 ----
> Index: util_script.c
> ===================================================================
> RCS file: /export/home/cvs/apache/src/util_script.c,v
> retrieving revision 1.51
> diff -c -r1.51 util_script.c
> *** util_script.c	1997/04/25 13:39:33	1.51
> --- util_script.c	1997/04/26 00:59:18
> ***************
> *** 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
>   }




Mime
View raw message