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
    }
  
  
  

Reply via email to