diff -ur gkrellm-2.1.5/gkrellmd.1 gkrellm-2.1.5.new/gkrellmd.1 --- gkrellm-2.1.5/gkrellmd.1 Mon Sep 16 20:17:28 2002 +++ gkrellm-2.1.5.new/gkrellmd.1 Thu Jan 23 17:23:36 2003 @@ -36,6 +36,18 @@ .B \-\-allow-host hostname ] +[ +.B \-U +| +.B \-\-user +username +] +[ +.B \-G +| +.B \-\-group +groupname +] .SH "DESCRIPTION" .PP @@ -113,6 +125,17 @@ arguments if you want command line allowed hosts to override and not be additive to those specified in gkrellmd.conf files. +.B -U, --user username +Changes user to +.I username +after startup. Useful if you want to run gkrellmd as root, but set +it to run with another privilleges; typically as the +.I nobody +user. +.B -G, --group groupname +Changes group to +.I groupname +after startup. .SH "FILES" .TP .I /etc/gkrellmd.conf Only in gkrellm-2.1.5.new: gkrellmd.1~ diff -ur gkrellm-2.1.5/server/gkrellmd.conf gkrellm-2.1.5.new/server/gkrellmd.conf --- gkrellm-2.1.5/server/gkrellmd.conf Tue Oct 1 17:16:55 2002 +++ gkrellm-2.1.5.new/server/gkrellmd.conf Thu Jan 23 17:15:53 2003 @@ -21,6 +21,11 @@ #allow-host 127.0.0.1 #allow-host ::1 +# Drop privilleges after startup (you must start gkrellmd as root to do it). +# +#user nobody +#group proc + # Run in background and detach from the controlling terminal #detach diff -ur gkrellm-2.1.5/server/gkrellmd.h gkrellm-2.1.5.new/server/gkrellmd.h --- gkrellm-2.1.5/server/gkrellmd.h Thu Jan 9 01:04:25 2003 +++ gkrellm-2.1.5.new/server/gkrellmd.h Thu Jan 23 16:58:40 2003 @@ -41,6 +41,8 @@ #include #include #include +#include +#include #if defined(__solaris__) #include #endif diff -ur gkrellm-2.1.5/server/main.c gkrellm-2.1.5.new/server/main.c --- gkrellm-2.1.5/server/main.c Thu Jan 9 01:04:53 2003 +++ gkrellm-2.1.5.new/server/main.c Thu Jan 23 17:11:27 2003 @@ -47,6 +47,10 @@ static gboolean detach_flag; +struct { + uid_t uid; + uid_t gid; + } drop_privs = { 0, 0 }; static void cb_sigterm(gint sig) @@ -288,6 +292,24 @@ _GK.fs_interval = atoi(arg); else if (!strcmp(config, "nfs-interval")) _GK.nfs_interval = atoi(arg); +#if !defined(WIN32) + else if (!strcmp(config, "user") || !strcmp(config, "U")) + { + struct passwd *tmp; + if ((tmp=getpwnam(arg)) != (struct passwd*) 0) + drop_privs.uid = tmp->pw_uid; + else + return -1; + } + else if (!strcmp(config, "group") || !strcmp(config, "G")) + { + struct group *tmp; + if ((tmp=getgrnam(arg)) != (struct group*) 0) + drop_privs.gid = tmp->gr_gid; + else + return -1; + } +#endif else return -1; return 1; @@ -361,6 +383,8 @@ printf(_(" -c, --clear-hosts Clears the current list of allowed hosts.\n")); #if !defined(WIN32) printf(_(" -d, --detach Run in background and detach from terminal.\n")); + printf(_(" -U, --user username Change to this username after startup.\n")); + printf(_(" -G, --group groupname Change to this group after startup.\n")); #endif printf(_(" -V, --verbose\n")); printf(_(" -v, --version\n")); @@ -532,7 +556,11 @@ return; #if defined(HAVE_DAEMON) - daemon(0, 0); + if (daemon(0, 0)) + { + fprintf(stderr, "gkrellmd detach failed: %s\n", strerror(errno)); + exit(1); + } #else i = fork(); if (i > 0) @@ -563,6 +591,23 @@ #endif } + + +static void +drop_privilleges(void) + { +#if !defined(WIN32) + if (drop_privs.gid > (uid_t)0) + { + (void) setgroups((size_t)0, (gid_t*)0); + (void) setgid(drop_privs.gid); + } + if (drop_privs.uid > (uid_t)0) + (void) setuid(drop_privs.uid); +#endif + } + + #if defined(WIN32) && defined(_WINDOWS) int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, @@ -610,6 +655,8 @@ read_config(); get_args(argc, argv); + drop_privilleges(); + if (detach_flag) detach_from_terminal(); else