You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Rob Hartill <ro...@imdb.com> on 1997/01/03 04:35:14 UTC

suexec modification (w/diffs) (fwd)

----- Forwarded message from Curtis Wilbar -----

From: Curtis Wilbar <cu...@ici.net>
Date: Thu, 2 Jan 1997 20:53:52 -0500 (EST)
Message-Id: <19...@pike.ici.net>
To: apache-bugs@apache.org
Subject: suexec modification (w/diffs)
Cc: curtis@ici.net


Due to a goof-up... the diffs didn't get included...  they appear at the
end of this e-mail message....:

----- Begin Included Message -----

>From curtis@ici.net Thu Jan  2 20:44:05 1997
From: Curtis Wilbar <cu...@ici.net>
Date: Thu, 2 Jan 1997 20:43:25 -0500 (EST)
To: apache-bugs@apache.org
Subject: suexec modification
Cc: curtis@ici.net
Content-Length: 1405


I recently sent mail with a modifcation of suexec to allow it to compile
and run under SunOS, and Solaris.

I mentioned another modification that I was working on.  I have briefly
tested this, and it seems to work.

I figure that if this is a capability that I wanted here, there must be
others who would desire this capability as well.

This mod may have been more appropriate in the server code, but it was
50/50, and easier to implement and test separately in the suexec code.

Here's the summary of the new capability....

if compiled with -DRUNASOWN, then suexec will run the cgi as the owner and
group of the cgi program being called.  The group ownership of the file
must match the group the user belongs to in the password file.  The
directory the cgi is in must match owner/group of the cgi program as well.
The existing checks for setuid and directory writability by others is
retained as well.

This also contains my setenv function call (as SunOS and Solaris do not have
this system call).  -DNOSETENV is required to enable my write of the setenv
function (which uses putenv as the actual system call).

Please give me feedback as to wether or not these changes are:

1. desirable
2. addressed to the wrong people (should I be using an addr other then
   apache-bugs@apache.org).

Thanks...

-- Curt

Curtis H. Wilbar Jr.
Chief Technology Officer
The Internet Connection, Inc.
curtis@ici.net


----- End Included Message -----

*** suexec.c.orig	Fri Dec 27 17:21:23 1996
--- suexec.c	Thu Jan  2 20:35:55 1997
***************
*** 120,125 ****
--- 120,153 ----
      return;
  }
  
+ 
+ /* [Curtis H. Wilbar Jr. 12/31/96]                  */
+ /* created a setenv call as SunOS does not have one */
+ /* to use this mod, add -DNOSETENV to your compile  */
+ #ifdef NOSETENV
+ int setenv(char vname[], char vvalue[], int overwrite) {
+ 
+    char *vnevv;
+    int  retval;
+ 
+    if ( overwrite || (getenv(vname) == NULL) ) {
+       vnevv = malloc(strlen(vname) + strlen(vvalue) + 2);
+ 
+       strcpy(vnevv, vname);
+       strcat(vnevv, "=");
+       strcat(vnevv, vvalue);
+ 
+       retval = putenv(vnevv);
+ 
+       free(vnevv);
+ 
+       return(retval);
+    } else {
+       return(-1);
+    }
+ }
+ #endif
+ 
  int main(int argc, char *argv[], char **env)
  {
      int doclen;             /* length of the docroot     */
***************
*** 137,142 ****
--- 165,177 ----
      struct stat dir_info;   /* directory info holder     */
      struct stat prg_info;   /* program info holder       */
  
+ /* [Curtis H. Wilbar Jr. 1/2/97]                    */
+ /* -DRUNASOWN will allow the execution of the cgi   */
+ /* as the owner/group of the cgi file called        */
+ #ifdef RUNASOWN
+     struct passwd *uinfo;   /* user information          */
+     struct group  *ginfo;   /* group information         */
+ #endif
      
  
      /*
***************
*** 299,308 ****
       * Error out if the target name/group is different from
       * the name/group of the cwd or the program.
       */
      if ((pw->pw_uid != dir_info.st_uid) ||
  	(gr->gr_gid != dir_info.st_gid) ||
  	(pw->pw_uid != prg_info.st_uid) ||
! 	(gr->gr_gid != prg_info.st_gid))
      {
  	log_err("target uid/gid (%ld/%ld) mismatch with directory (%ld/%ld) or program (%ld/%ld)\n",
  		 pw->pw_uid, gr->gr_gid,
--- 334,344 ----
       * Error out if the target name/group is different from
       * the name/group of the cwd or the program.
       */
+ #ifndef RUNASOWN
      if ((pw->pw_uid != dir_info.st_uid) ||
  	(gr->gr_gid != dir_info.st_gid) ||
  	(pw->pw_uid != prg_info.st_uid) ||
!         (gr->gr_gid != prg_info.st_gid))
      {
  	log_err("target uid/gid (%ld/%ld) mismatch with directory (%ld/%ld) or program (%ld/%ld)\n",
  		 pw->pw_uid, gr->gr_gid,
***************
*** 310,316 ****
--- 346,372 ----
  		 prg_info.st_uid, prg_info.st_gid);
  	exit(115);
      }
+ #else
+     uinfo = getpwuid(prg_info.st_uid);
+     ginfo = getgrgid(prg_info.st_gid);
+     if ((dir_info.st_uid != prg_info.st_uid) ||
+         (dir_info.st_gid != prg_info.st_gid))
+     {
+ 	log_err("program uid/gid (%ld/%ld) mismatch with directory (%ld/%ld)\n",
+ 		 prg_info.st_uid, prg_info.st_gid,
+ 		 dir_info.st_uid, dir_info.st_gid);
+ 	exit(115);
+     }
  
+     if (uinfo->pw_gid != prg_info.st_gid)
+     {
+ 	log_err("program uid/gid (%ld/%ld) mismatch with program owner (%ld/%ld)\n",
+ 		 prg_info.st_uid, prg_info.st_gid,
+ 		 uinfo->pw_uid, uinfo->pw_gid);
+ 	exit(115);
+     }
+ #endif
+ 
      /*
       * Error out if attempt is made to execute as root.  Tsk tsk.
       */
***************
*** 331,347 ****
--- 387,415 ----
       * Log the transaction here to be sure we have an open log 
       * before we setuid().
       */
+ #ifndef RUNASOWN
      log_err("uid: (%s/%s) gid: (%s/%s) %s\n",
               target_uname, pw->pw_name,
               target_gname, gr->gr_name,
               cmd);
+ #else
+     log_err("uid: (%s/%s) gid: (%s/%s) %s\n",
+              target_uname, uinfo->pw_name,
+              target_gname, ginfo->gr_name,
+              cmd);
+ #endif
  
      /*
       * Initialize the group access list for the target user,
       * and setgid() to the target group. If unsuccessful, error out.
       */
+ #ifndef RUNASOWN
      uid = pw->pw_uid;
      gid = gr->gr_gid;
+ #else
+     uid = prg_info.st_uid;
+     gid = prg_info.st_gid;
+ #endif
      if ((initgroups(target_uname,gid) != 0) || ((setgid(gid)) != 0)) {
          log_err("failed to setgid (%ld: %s/%s)\n", gid, cwd, cmd);
          exit(118);

----- End of forwarded message from Curtis Wilbar -----

-- 
Rob Hartill.       Internet Movie Database Ltd.    http://www.imdb.com/