[MEDIUM] add user/groupname support

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."
This commit is contained in:
Willy Tarreau 2007-03-25 15:39:23 +02:00
parent b38651a435
commit 95c20aca35
3 changed files with 73 additions and 8 deletions

View 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
------------------

View 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 :

View 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]);