support 'user' and 'group' directives, where the server does
authoraland <aland>
Wed, 8 Nov 2000 20:32:34 +0000 (20:32 +0000)
committeraland <aland>
Wed, 8 Nov 2000 20:32:34 +0000 (20:32 +0000)
setgid && setuid to whatever the user supplies.

This is so that the server doesn't need to run as root...

raddb/radiusd.conf.in
src/main/radiusd.c

index 2ea8c92..d8e1d1c 100644 (file)
@@ -42,6 +42,22 @@ run_dir    = ${localstatedir}/run
 pidfile    = ${run_dir}/radiusd.pid
 
 #
+# user/group: The name (or #number) of the user/group to run httpd as.
+#    On SCO (ODT 3) use "user = nouser" and "group = nogroup".
+#    On HPUX you may not be able to use shared memory as nobody, and the
+#    suggested workaround is to create a user www and use that user.
+#
+#  NOTE that some kernels refuse to setgid(group)
+#  when the value of (unsigned)group is above 60000;
+#  don't use group nobody on these systems!
+#
+#  On systems with shadow passwords, you might have to set 'group = shadow'
+#  for the server to be able to read the shadow password file.
+#
+user = nobody
+group = nobody
+
+#
 #  max_request_time: The maximum time (in seconds) to handle a request.
 #
 #  Requests which take more time than this to process are killed, and
index 28305c9..042c777 100644 (file)
@@ -65,6 +65,9 @@ static const char rcsid[] =
 
 #include       <sys/resource.h>
 
+#include       <grp.h>
+#include       <pwd.h>
+
 /*
  *     Global variables.
  */
@@ -123,6 +126,10 @@ static int         cleanup_delay = CLEANUP_DELAY;
 static int             max_requests = MAX_REQUESTS;
 static int             dont_fork = FALSE;
 static const char      *pid_file = NULL;
+static uid_t           server_uid;
+static gid_t           server_gid;
+static const char      *uid_name = NULL;
+static const char      *gid_name = NULL;
 
 #if !defined(__linux__) && !defined(__GNU_LIBRARY__)
 extern int     errno;
@@ -166,13 +173,15 @@ static CONF_PARSER server_config[] = {
   { "bind_address",       PW_TYPE_IPADDR,     &myip,              "*" },
   { "proxy_requests",     PW_TYPE_BOOLEAN,    &proxy_requests,    "yes" },
   { "hostname_lookups",   PW_TYPE_BOOLEAN,    &librad_dodns,      "0" },
-  { "usercollide",                     PW_TYPE_BOOLEAN,    &mainconfig.do_usercollide,         "no" },
-  { "lower_user",                      PW_TYPE_BOOLEAN,    &mainconfig.do_lower_user,          "no" },
-  { "lower_pass",                      PW_TYPE_BOOLEAN,    &mainconfig.do_lower_pass,          "no" },
-  { "lower_time",                      PW_TYPE_STRING_PTR,    &mainconfig.lower_time,          "before" },
-  { "nospace_user",                    PW_TYPE_BOOLEAN,    &mainconfig.do_nospace_user,        "no" },
-  { "nospace_pass",                    PW_TYPE_BOOLEAN,    &mainconfig.do_nospace_pass,        "no" },
-  { "nospace_time",                    PW_TYPE_STRING_PTR,    &mainconfig.nospace_time,                "before" },
+  { "user",           PW_TYPE_STRING_PTR, &uid_name,  NULL},
+  { "group",          PW_TYPE_STRING_PTR, &gid_name,  NULL},
+  { "usercollide",    PW_TYPE_BOOLEAN,    &mainconfig.do_usercollide, "no" },
+  { "lower_user",     PW_TYPE_BOOLEAN,    &mainconfig.do_lower_user, "no" },
+  { "lower_pass",     PW_TYPE_BOOLEAN,    &mainconfig.do_lower_pass, "no" },
+  { "lower_time",     PW_TYPE_STRING_PTR, &mainconfig.lower_time, "before" },
+  { "nospace_user",   PW_TYPE_BOOLEAN,    &mainconfig.do_nospace_user, "no" },
+  { "nospace_pass",   PW_TYPE_BOOLEAN,    &mainconfig.do_nospace_pass, "no" },
+  { "nospace_time",   PW_TYPE_STRING_PTR, &mainconfig.nospace_time, "before" },
   { NULL, -1, NULL, NULL }
 };
 
@@ -214,9 +223,10 @@ static int reread_config(int reload)
         *      And parse the server's configuration values.
         */
        cs = cf_section_find(NULL);
-       if (!cs)
+       if (!cs) {
+               radlog(L_ERR|L_CONS, "No configuration information in radiusd.conf!");
                return -1;
-
+       }
        cf_section_parse(cs, server_config);
 
        /*
@@ -264,6 +274,49 @@ static int reread_config(int reload)
        }
 
        /*
+        *      Set the UID and GID, but only if we're NOT running
+        *      in debugging mode.
+        */
+       if (!debug_flag) {
+               /*
+                *      Set group.
+                */
+               if (gid_name) {
+                       struct group *gr;
+
+                       gr = getgrnam(gid_name);
+                       if (!gr) {
+                               radlog(L_ERR|L_CONS, "Cannot switch to Group %s: %s", gid_name, strerror(errno));
+                               exit(1);
+                       }
+                       server_gid = gr->gr_gid;
+                       if (setgid(server_gid) < 0) {
+                               radlog(L_ERR|L_CONS, "Failed setting Group to %s: %s", gid_name, strerror(errno));
+                               exit(1);
+                       }
+               }
+
+               /*
+                *      Set UID.
+                */
+               if (uid_name) {
+                       struct passwd *pw;
+
+                       pw = getpwnam(uid_name);
+                       if (!pw) {
+                               radlog(L_ERR|L_CONS, "Cannot switch to User %s: %s", uid_name, strerror(errno));
+                               exit(1);
+                       }
+                       server_uid = pw->pw_uid;
+                       if (setuid(server_uid) < 0) {
+                               radlog(L_ERR|L_CONS, "Failed setting User to %s: %s", uid_name, strerror(errno));
+                               exit(1);
+                       }
+               }
+       }
+
+
+       /*
         *      Parse the server's proxy configuration values.
         */
        if ((proxy_requests) &&