From bec3ef98aa550c3beb4a762c789d0d0d6ea48910 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Wilfried=20G=C3=B6esgens?= Date: Fri, 22 Jan 2010 19:21:15 +0000 Subject: [PATCH] * port our setuid function from citserver to webcit; -u can now specify the UID to run as --- webcit/sysdep.c | 41 +++++++++++++++++++++++++++++++++++++++++ webcit/webserver.c | 10 ++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/webcit/sysdep.c b/webcit/sysdep.c index 84ea33d06..36155ed84 100644 --- a/webcit/sysdep.c +++ b/webcit/sysdep.c @@ -63,6 +63,8 @@ #include "snprintf.h" #endif +#include "webserver.h" + pthread_mutex_t Critters[MAX_SEMAPHORES]; /* Things needing locking */ pthread_key_t MyConKey; /* TSD key for MyContext() */ pthread_key_t MyReq; /* TSD key for MyReq() */ @@ -94,3 +96,42 @@ void end_critical_section(int which_one) pthread_mutex_unlock(&Critters[which_one]); } +void drop_root(uid_t UID) +{ + struct passwd pw, *pwp = NULL; + + /* + * Now that we've bound the sockets, change to the Citadel user id and its + * corresponding group ids + */ + if (UID != -1) { + +#ifdef HAVE_GETPWUID_R +#ifdef SOLARIS_GETPWUID + pwp = getpwuid_r(UID, &pw, pwbuf, sizeof(pwbuf)); +#else // SOLARIS_GETPWUID + getpwuid_r(UID, &pw, pwbuf, sizeof(pwbuf), &pwp); +#endif // SOLARIS_GETPWUID +#else // HAVE_GETPWUID_R + pwp = NULL; +#endif // HAVE_GETPWUID_R + + if (pwp == NULL) + lprintf(CTDL_CRIT, "WARNING: getpwuid(%ld): %s\n" + "Group IDs will be incorrect.\n", UID, + strerror(errno)); + else { + initgroups(pw.pw_name, pw.pw_gid); + if (setgid(pw.pw_gid)) + lprintf(CTDL_CRIT, "setgid(%ld): %s\n", (long)pw.pw_gid, + strerror(errno)); + } + lprintf(CTDL_INFO, "Changing uid to %ld\n", (long)UID); + if (setuid(UID) != 0) { + lprintf(CTDL_CRIT, "setuid() failed: %s\n", strerror(errno)); + } +#if defined (HAVE_SYS_PRCTL_H) && defined (PR_SET_DUMPABLE) + prctl(PR_SET_DUMPABLE, 1); +#endif + } +} diff --git a/webcit/webserver.c b/webcit/webserver.c index 03b6c42b7..c70419b3b 100644 --- a/webcit/webserver.c +++ b/webcit/webserver.c @@ -36,6 +36,7 @@ extern pthread_key_t MyConKey; extern int ig_tcp_server(char *ip_addr, int port_number, int queue_len); extern int ig_uds_server(char *sockpath, int queue_len); +extern void drop_root(uid_t UID); char ctdl_key_dir[PATH_MAX]=SSL_DIR; char file_crpt_file_key[PATH_MAX]=""; @@ -315,6 +316,7 @@ webcit_calc_dirs_n_files(int relh, const char *basedir, int home, char *webcitdi */ int main(int argc, char **argv) { + uid_t UID = -1; size_t basesize = 2; /* how big should strbufs be on creation? */ pthread_t SessThread; /* Thread descriptor */ pthread_attr_t attr; /* Thread attributes */ @@ -355,11 +357,14 @@ int main(int argc, char **argv) /* Parse command line */ #ifdef HAVE_OPENSSL - while ((a = getopt(argc, argv, "h:i:p:t:T:B:x:dD:G:cfsS:Z")) != EOF) + while ((a = getopt(argc, argv, "u:h:i:p:t:T:B:x:dD:G:cfsS:Z")) != EOF) #else - while ((a = getopt(argc, argv, "h:i:p:t:T:B:x:dD:G:cfZ")) != EOF) + while ((a = getopt(argc, argv, "u:h:i:p:t:T:B:x:dD:G:cfZ")) != EOF) #endif switch (a) { + case 'u': + UID = atol(optarg); + break; case 'h': hdir = strdup(optarg); relh=hdir[0]!='/'; @@ -580,6 +585,7 @@ int main(int argc, char **argv) init_ssl(); } #endif + drop_root(UID); /* Start a few initial worker threads */ for (i = 0; i < (MIN_WORKER_THREADS); ++i) { -- 2.30.2