]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] add user/groupname support
authorWilly Tarreau <w@1wt.eu>
Sun, 25 Mar 2007 13:39:23 +0000 (15:39 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 25 Mar 2007 13:39:23 +0000 (15:39 +0200)
Patch from Marcus Rueckert for 1.2.17 :
 "I added the attached patch to haproxy. I don't have a static uid/gid for
  haproxy so i need to specify the username/groupname to run it as non
  root user."

doc/haproxy-en.txt
doc/haproxy-fr.txt
src/cfgparse.c

index ab26df579552090faf07d799dee269b9a066a19f..dbe78f5f50af9a4b879e0dc75cbd3c70aa535355 100644 (file)
@@ -112,6 +112,8 @@ the following ones :
   - maxconn <number>
   - uid <user id>
   - gid <group id>
+  - user <user name>
+  - group <group name>
   - chroot <directory>
   - nbproc <number>
   - daemon
@@ -197,9 +199,14 @@ In the 'global' section, the 'uid' parameter sets a numerical user identifier
 which the process will switch to after binding its listening sockets. The value
 '0', which normally represents the super-user, here indicates that the UID must
 not change during startup. It's the default behaviour. The 'gid' parameter does
-the same for the group identifier. It's particularly advised against use of
-generic accounts such as 'nobody' because it has the same consequences as using
-'root' if other services use them.
+the same for the group identifier. If setting an uid is not possible because of
+deployment constraints, it is possible to set a user name with the 'user'
+keyword followed by a valid user name. The same is true for the gid. It is
+possible to specify a group name after the 'group' keyword.
+
+It is particularly advised against use of generic accounts such as 'nobody'
+because it has the same consequences as using 'root' if other services use
+them.
 
 The 'chroot' parameter makes the process isolate itself in an empty directory
 just before switching its UID. This type of isolation (chroot) can sometimes
@@ -227,11 +234,18 @@ directories. Do not forget to allow core dumps prior to start the process :
 Example :
 ---------
 
+    # with uid/gid
     global
         uid     30000
         gid     30000
         chroot  /var/chroot/haproxy
 
+    # with user/group
+    global
+        user    haproxy
+        group   public
+        chroot  /var/chroot/haproxy
+
 
 1.4) Startup modes
 ------------------
index 9282cb42dd6150f511fe2ff4cc8891ff141e7665..7f6d2318d1b72433e09091d3537a03eea955b991 100644 (file)
@@ -119,6 +119,8 @@ support
   - maxconn <nombre>
   - uid <identifiant>
   - gid <identifiant>
+  - user <nom d'utilisateur>
+  - group <nom de groupe>
   - chroot <répertoire>
   - nbproc <nombre>
   - daemon
@@ -208,9 +210,14 @@ utilisateur, poss
 l'on ne souhaite pas changer cet identifiant et conserver la valeur courante.
 C'est la valeur par défaut. De la même manière, le paramètre 'gid' correspond à
 un identifiant de groupe, et utilise par défaut la valeur 0 pour ne rien
-changer. Il est particulièrement déconseillé d'utiliser des comptes génériques
-tels que 'nobody' car cette pratique revient à utiliser 'root' si d'autres
-processus utilisent les mêmes identifiants.
+changer. Dans le cas où il ne serait pas possible de spécifier un identifiant
+numérique pour l'uid, il est possible de spécifier un nom d'utilisateur après
+le mot-clé 'user'. De la même manière, il est possible de préciser un nom de
+groupe après le mot-clé 'group'.
+
+Il est particulièrement déconseillé d'utiliser des comptes génériques tels que
+'nobody' car cette pratique revient à utiliser 'root' si d'autres processus
+utilisent les mêmes identifiants.
 
 Le paramètre 'chroot' autorise à changer la racine du processus une fois le
 programme lancé, de sorte que ni le processus, ni l'un de ses descendants ne
@@ -246,11 +253,19 @@ lancer le programme :
 Exemple :
 ---------
 
+    # with uid/gid
     global
         uid        30000
         gid        30000
         chroot  /var/chroot/haproxy
 
+    # with user/group
+    global
+        user    haproxy
+        group   public
+        chroot  /var/chroot/haproxy
+
+
 1.4) Modes de fonctionnement
 ----------------------------
 Le service peut fonctionner dans plusieurs modes :
index ae5433ea4247709fb30f702fa2cf374b1ddd123f..4c1f032ec6bdb02d4208d8bc53e9e5113d356874 100644 (file)
@@ -15,6 +15,8 @@
 #include <string.h>
 #include <netdb.h>
 #include <ctype.h>
+#include <pwd.h>
+#include <grp.h>
 
 #include <common/cfgparse.h>
 #include <common/config.h>
@@ -269,7 +271,7 @@ int cfg_parse_global(const char *file, int linenum, char **args)
        }
        else if (!strcmp(args[0], "uid")) {
                if (global.uid != 0) {
-                       Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
+                       Alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
                        return 0;
                }
                if (*(args[1]) == 0) {
@@ -280,7 +282,7 @@ int cfg_parse_global(const char *file, int linenum, char **args)
        }
        else if (!strcmp(args[0], "gid")) {
                if (global.gid != 0) {
-                       Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
+                       Alert("parsing [%s:%d] : group/gid already specified. Continuing.\n", file, linenum);
                        return 0;
                }
                if (*(args[1]) == 0) {
@@ -289,6 +291,40 @@ int cfg_parse_global(const char *file, int linenum, char **args)
                }
                global.gid = atol(args[1]);
        }
+       /* user/group name handling */
+       else if (!strcmp(args[0], "user")) {
+               struct passwd *ha_user;
+               if (global.uid != 0) {
+                       Alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
+                       return 0;
+               }
+               errno = 0;
+               ha_user = getpwnam(args[1]);
+               if (ha_user != NULL) {
+                       global.uid = (int)ha_user->pw_uid;
+               }
+               else {
+                       Alert("parsing [%s:%d] : cannot find user id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
+                       exit(1);
+               }
+       }
+       else if (!strcmp(args[0], "group")) {
+               struct group *ha_group;
+               if (global.gid != 0) {
+                       Alert("parsing [%s:%d] : gid/group was already specified. Continuing.\n", file, linenum, args[0]);
+                       return 0;
+               }
+               errno = 0;
+               ha_group = getgrnam(args[1]);
+               if (ha_group != NULL) {
+                       global.gid = (int)ha_group->gr_gid;
+               }
+               else {
+                       Alert("parsing [%s:%d] : cannot find group id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
+                       exit(1);
+               }
+       }
+       /* end of user/group name handling*/
        else if (!strcmp(args[0], "nbproc")) {
                if (global.nbproc != 0) {
                        Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);