You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Randy Terbush <ra...@zyzzyva.com> on 1997/01/11 00:29:09 UTC
suexec.patch (again?)
Not sure why this did not show up on my first attempt to send
it.
------- Forwarded Message
To: new-httpd@apache.org
Subject: suexec patch
X-uri: http://www.zyzzyva.com/
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Date: Fri, 10 Jan 1997 16:41:05 -0600
From: Randy Terbush <ra...@sierra>
I have the following patch which includes Jason Dour's changes
along with my addition to control environment variables passed
by the suexec wrapper. I'd appreciate comments regarding how I
handled the enviro thing if there is an easier way.
Would appreciate those on the list using suexec giving this a
spin before we unleash it on the public.
Index: suexec.c
===================================================================
RCS file: /export/home/cvs/apache/support/suexec.c,v
retrieving revision 1.10
diff -c -r1.10 suexec.c
*** suexec.c 1997/01/01 18:26:17 1.10
- --- suexec.c 1997/01/10 22:33:03
***************
*** 81,89 ****
- --- 81,121 ----
#include <time.h>
#include <sys/stat.h>
+ #define CLEAN_ENV_BUF 64
+ extern char **environ;
static FILE *log;
+ char *safe_env_lst[] =
+ {
+ "CONTENT_TYPE",
+ "CONTENT_LENGTH",
+ "SERVER_SOFTWARE",
+ "SERVER_NAME",
+ "SERVER_PORT",
+ "REMOTE_HOST",
+ "REMOTE_ADDR",
+ "DOCUMENT_ROOT",
+ "SERVER_ADMIN",
+ "SCRIPT_FILENAME",
+ "REMOTE_USER",
+ "AUTH_TYPE",
+ "REMOTE_IDENT",
+ "REMOTE_PORT",
+ "REDIRECT_QUERY_STRING",
+ "REDIRECT_URL",
+ "GATEWAY_INTERFACE",
+ "SERVER_PROTOCOL",
+ "REQUEST_METHOD",
+ "QUERY_STRING",
+ "SCRIPT_NAME",
+ "PATH_INFO",
+ "FILEPATH_INFO",
+ "PATH_TRANSLATED",
+ NULL
+ };
+
+
static void err_output(const char *fmt, va_list ap)
{
time_t timevar;
***************
*** 120,128 ****
return;
}
! int main(int argc, char *argv[], char **env)
{
- - int doclen; /* length of the docroot */
int userdir = 0; /* ~userdir flag */
uid_t uid; /* user information */
gid_t gid; /* target group placeholder */
- --- 152,197 ----
return;
}
! void clean_env()
! {
! char pathbuf[512];
! char **cleanenv;
! char **ep;
! int cidx = 0;
! int idx;
!
!
! if ((cleanenv = (char **)malloc(CLEAN_ENV_BUF * (sizeof(char *)))) == NULL) {
! log_err("failed to malloc env mem\n");
! exit(120);
! }
!
! for (ep = environ; *ep; ep++) {
! if (!strncmp(*ep, "HTTP_", 5)) {
! cleanenv[cidx] = *ep;
! cidx++;
! }
! else {
! for (idx = 0; safe_env_lst[idx]; idx++) {
! if (!strncmp(*ep, safe_env_lst[idx], strlen(safe_env_lst[idx]))) {
! cleanenv[cidx] = *ep;
! cidx++;
! break;
! }
! }
! }
! }
!
! sprintf(pathbuf, "PATH=%s", SAFE_PATH);
! cleanenv[cidx] = pathbuf;
! cleanenv[++cidx] = NULL;
!
! environ = cleanenv;
! free(cleanenv);
! }
!
! int main(int argc, char *argv[])
{
int userdir = 0; /* ~userdir flag */
uid_t uid; /* user information */
gid_t gid; /* target group placeholder */
***************
*** 211,217 ****
/*
* Get the current working directory, as well as the proper
* document root (dependant upon whether or not it is a
! * ~userdir request. Error out if we cannot get either one,
* or if the current working directory is not in the docroot.
* Use chdir()s and getcwd()s to avoid problems with symlinked
* directories. Yuck.
- --- 280,286 ----
/*
* Get the current working directory, as well as the proper
* document root (dependant upon whether or not it is a
! * ~userdir request). Error out if we cannot get either one,
* or if the current working directory is not in the docroot.
* Use chdir()s and getcwd()s to avoid problems with symlinked
* directories. Yuck.
***************
*** 223,228 ****
- --- 292,298 ----
if (userdir) {
if (((chdir(pw->pw_dir)) != 0) ||
+ ((chdir(USERDIR_SUFFIX)) != 0) ||
((getcwd(dwd, MAXPATHLEN)) == NULL) ||
((chdir(cwd)) != 0))
{
***************
*** 239,247 ****
exit(108);
}
}
!
! doclen = strlen(dwd);
! if ((strncmp(cwd, dwd, doclen)) != 0) {
log_err("command not in docroot (%s/%s)\n", cwd, cmd);
exit(109);
}
- --- 309,316 ----
exit(108);
}
}
!
! if ((strncmp(cwd, dwd, strlen(dwd))) != 0) {
log_err("command not in docroot (%s/%s)\n", cwd, cmd);
exit(109);
}
***************
*** 303,320 ****
}
/*
! * Error out if attempt is made to execute as root. Tsk tsk.
*/
! if (pw->pw_uid == 0) {
! log_err("cannot run as uid 0 (%s)\n", cmd);
exit(116);
}
/*
! * Error out if attempt is made to execute as root group. Tsk tsk.
*/
! if (gr->gr_gid == 0) {
! log_err("cannot run as gid 0 (%s)\n", cmd);
exit(117);
}
- --- 372,393 ----
}
/*
! * Error out if attempt is made to execute as root or as
! * a UID less than UID_MIN. Tsk tsk.
*/
! if ((pw->pw_uid == 0) ||
! (pw->pw_uid < UID_MIN)) {
! log_err("cannot run as forbidden uid (%d/%s)\n", pw->pw_uid, cmd);
exit(116);
}
/*
! * Error out if attempt is made to execute as root group
! * or as a GID less than GID_MIN. Tsk tsk.
*/
! if ((gr->gr_gid == 0) ||
! (gr->gr_gid < GID_MIN)) {
! log_err("cannot run as forbidden gid (%d/%s)\n", gr->gr_gid, cmd);
exit(117);
}
***************
*** 333,339 ****
*/
uid = pw->pw_uid;
gid = gr->gr_gid;
! if ((initgroups(target_uname,gid) != 0) || ((setgid(gid)) != 0)) {
log_err("failed to setgid (%ld: %s/%s)\n", gid, cwd, cmd);
exit(118);
}
- --- 406,412 ----
*/
uid = pw->pw_uid;
gid = gr->gr_gid;
! if (((setgid(gid)) != 0) || (initgroups(pw->pw_name,gid) != 0)) {
log_err("failed to setgid (%ld: %s/%s)\n", gid, cwd, cmd);
exit(118);
}
***************
*** 346,360 ****
exit(119);
}
! if ((setenv("PATH", SAFE_PATH, 1)) != 0) {
! log_err("cannot reset environment PATH\n");
! exit(120);
! }
/*
* Execute the command, replacing our image with its own.
*/
! execve(cmd, &argv[3], env);
/*
* (I can't help myself...sorry.)
- --- 419,430 ----
exit(119);
}
! clean_env();
/*
* Execute the command, replacing our image with its own.
*/
! execv(cmd, argv);
/*
* (I can't help myself...sorry.)
Index: suexec.h
===================================================================
RCS file: /export/home/cvs/apache/support/suexec.h,v
retrieving revision 1.6
diff -c -r1.6 suexec.h
*** suexec.h 1997/01/01 18:26:18 1.6
- --- suexec.h 1997/01/10 22:33:05
***************
*** 68,73 ****
- --- 68,103 ----
#endif
/*
+ * UID_MIN -- Define this as the lowest UID allowed to be a target user
+ * for suEXEC. For most systems, 500 or 100 is common.
+ */
+ #ifndef UID_MIN
+ #define UID_MIN 500
+ #endif
+
+ /*
+ * GID_MIN -- Define this as the lowest GID allowed to be a target group
+ * for suEXEC. For most systems, 100 is common.
+ */
+ #ifndef GID_MIN
+ #define GID_MIN 100
+ #endif
+
+ /*
+ * USERDIR_SUFFIX -- Define to be the same as the UserDir in the conf
+ * file. If you have VirtualHosts with a different
+ * UserDir for each, you will need to define them to
+ * all reside in one parent directory; then name that
+ * parent directory here. IF THIS IS NOT DEFINED
+ * PROPERLY, ~USERDIR CGI REQUESTS WILL NOT WORK!
+ * See the suEXEC documentation for more detailed
+ * information.
+ */
+ #ifndef USERDIR_SUFFIX
+ #define USERDIR_SUFFIX "public_html"
+ #endif
+
+ /*
* LOG_EXEC -- Define this as a filename if you want all suEXEC
* transactions and errors logged for auditing and
* debugging purposes.
------- End of Forwarded Message
Re: suexec.patch (again?)
Posted by Marc Slemko <ma...@znep.com>.
On Fri, 10 Jan 1997, Randy Terbush wrote:
> + char *safe_env_lst[] =
> + {
> + "CONTENT_TYPE",
> + "CONTENT_LENGTH",
> + "SERVER_SOFTWARE",
> + "SERVER_NAME",
> + "SERVER_PORT",
> + "REMOTE_HOST",
> + "REMOTE_ADDR",
> + "DOCUMENT_ROOT",
> + "SERVER_ADMIN",
> + "SCRIPT_FILENAME",
> + "REMOTE_USER",
> + "AUTH_TYPE",
> + "REMOTE_IDENT",
> + "REMOTE_PORT",
> + "REDIRECT_QUERY_STRING",
> + "REDIRECT_URL",
> + "GATEWAY_INTERFACE",
> + "SERVER_PROTOCOL",
> + "REQUEST_METHOD",
> + "QUERY_STRING",
> + "SCRIPT_NAME",
> + "PATH_INFO",
> + "FILEPATH_INFO",
> + "PATH_TRANSLATED",
> + NULL
> + };
What about REDIRECT_STATUS, SCRIPT_URL, SCRIPT_URI, DATE_LOCAL, DATE_GMT
and LAST_MODIFED?
The rest of it looks cool, but I don't run it anywhere right now, so...