diff --recursive -u httpd_1.4-orig/src/Makefile httpd_1.4/src/Makefile --- httpd_1.4-orig/src/Makefile Sun Apr 30 22:12:19 1995 +++ httpd_1.4/src/Makefile Tue May 23 11:24:28 1995 @@ -16,8 +16,9 @@ # determine if it is a parsed file, use -DXBITHACK # If you don't want to use the multiple child architecture, use -DNO_PASS # -CFLAGS= -O2 -g -DPEM_AUTH -#CFLAGS= -g -Wall -ansi -pedantic -DPEM_AUTH +# CFLAGS= -O2 -g -DPEM_AUTH +# CFLAGS= -g -Wall -ansi -pedantic -DPEM_AUTH +CFLAGS = -O2 -Wall # Place here any extra libraries you may need to link to. You # shouldn't have to. @@ -53,7 +54,7 @@ # For Sequent # AUX_CFLAGS= -DSEQUENT # For Linux -m486 ONLY IF YOU HAVE 486 BINARY SUPPORT IN KERNEL -# AUX_CFLAGS= -DLINUX +AUX_CFLAGS= -DLINUX # For NetBSD 1.0 # May not need -lcrypt if its included in your libc # AUX_CFLAGS= -DNETBSD diff --recursive -u httpd_1.4-orig/src/http_ipc.c httpd_1.4/src/http_ipc.c --- httpd_1.4-orig/src/http_ipc.c Fri Apr 21 09:03:34 1995 +++ httpd_1.4/src/http_ipc.c Tue May 23 11:24:28 1995 @@ -281,4 +281,38 @@ #endif -#endif +#ifdef FD_LINUX + +int pass_fd(int clifd, int fd) { + char buf[128]; + + sprintf(buf, "/proc/%d/fd/%d", (int)getpid(), fd); + if (write(clifd, buf, sizeof(buf)) < 0) { + log_error("pass_fd: write failed"); + return(-1); + } + read(clifd, buf, 2); /* Wait for OK */ + return(0); +} + +int recv_fd(int servfd) { + char buf[128]; + int fd; + + if (read(servfd, buf, sizeof(buf)) != sizeof(buf)) { + log_error("recv_fd: read failed"); + return(-1); + } + fd = open(buf, O_RDWR); + (void) write(servfd, "OK", 2); /* Tell 'em we've aquired the fd */ + if (fd < 0) { + log_error(strerror(errno)); + log_error(buf); + log_error("recv_fd: open failed"); + } + return(fd); +} + +#endif + +#endif diff --recursive -u httpd_1.4-orig/src/httpd.c httpd_1.4/src/httpd.c --- httpd_1.4-orig/src/httpd.c Tue May 2 14:20:06 1995 +++ httpd_1.4/src/httpd.c Tue May 23 12:16:13 1995 @@ -307,7 +307,9 @@ int x; /* struct passwd* pwent; */ - +#ifdef LINUX + static int switch_uid = 0; +#endif /* Only try to switch if we're running as root */ if(!getuid()) { @@ -316,8 +318,24 @@ /* Now, make absolutely certain we don't have any privileges * except those mentioned in the configuration file. */ +#ifdef LINUX + /* + * This is very tricky, because we want to switch real + * and effective UID while retaining a saved uid. + * Don't change this unless you know what you're doing! + */ + + /* First, make us set-uid. */ + if (setreuid(user_id, -1) == -1) + die(CONF_ERROR,"unable to change uid",stdout); + /* Saved uid is now 0. Reset effective uid. */ + if (seteuid(user_id) == -1) + die(CONF_ERROR,"unable to change uid",stdout); + switch_uid = 1; +#else if (setuid(user_id) == -1) die(CONF_ERROR,"unable to change uid",stdout); +#endif standalone = 1; } @@ -344,8 +362,25 @@ initialize_request(); dup2(parent_pipe,0); dup2(parent_pipe,1); - if ((csd = recv_fd(parent_pipe)) < 0) { +#ifdef LINUX + /* Switch to root privilige temporarily */ + if (switch_uid && seteuid(0) < 0) { + log_error("child error: seteuid(0)"); + goto fatal; + } +#endif + csd = recv_fd(parent_pipe); +#ifdef LINUX + /* Give up priviliges. */ + if (switch_uid && seteuid(user_id) < 0) { + standalone = 0; + die(CONF_ERROR,"unable to change uid",stdout); + goto fatal; + } +#endif + if (csd < 0) { log_error("child error: recv_fd()"); +fatal: close(0); close(1); close(sd); @@ -610,7 +645,7 @@ extern char *optarg; extern int optind; -main(int argc, char *argv[]) +int main(int argc, char *argv[]) { int c; diff --recursive -u httpd_1.4-orig/src/httpd.h httpd_1.4/src/httpd.h --- httpd_1.4-orig/src/httpd.h Tue May 2 14:25:25 1995 +++ httpd_1.4/src/httpd.h Tue May 23 11:24:29 1995 @@ -144,7 +144,7 @@ #define JMP_BUF jmp_buf #elif defined(LINUX) -#define NO_PASS +#define FD_LINUX #undef BSD #undef NO_KILLPG #undef NO_SETSID @@ -295,7 +295,7 @@ #endif /* If we haven't set anything about file descriptor passing, set NO_PASS */ -#if !defined(FD_BSD) && !defined(FD_SYSV) && !defined(NO_PASS) +#if !defined(FD_BSD) && !defined(FD_SYSV) && !defined(FD_LINUX) && !defined(NO_PASS) #define NO_PASS #endif