Allow numerical user and group ids for -u/-g (fixes #1141)

git-svn-id: svn://svn.lighttpd.net/spawn-fcgi/trunk@13 4a9f3682-ca7b-49a8-9a55-ba4640e46f83
master
Stefan Bühler 14 years ago
parent 5cf8f0b73e
commit 691b66dadf

@ -10,3 +10,4 @@ NEWS
* Modified the log messages format (more details on errors, no source line)
* Only try to connect to unix socket (not tcp) before spawning (fixes again #1575)
* Only disconnect from terminal in fork mode (keep stderr/stdout open in nofork mode)
* Allow numerical user and group ids for -u/-g (fixes #1141)

@ -269,6 +269,64 @@ static int fcgi_spawn_connection(char *appPath, char **appArgv, char *addr, unsi
return rc;
}
static int find_user_group(const char *user, const char *group, uid_t *uid, gid_t *gid, const char **username) {
uid_t my_uid = 0;
gid_t my_gid = 0;
struct passwd *my_pwd;
struct group *my_grp;
*uid = 0; *gid = 0;
if (username) *username = NULL;
if (user) {
my_uid = strtol(user, NULL, 10);
if (my_uid <= 0) {
if (NULL == (my_pwd = getpwnam(user))) {
fprintf(stderr, "spawn-fcgi: can't find username %s\n", user);
return -1;
}
my_uid = my_pwd->pw_uid;
if (my_uid == 0) {
fprintf(stderr, "spawn-fcgi: I will not set uid to 0\n");
return -1;
}
if (username) *username = user;
} else {
my_pwd = getpwuid(my_uid);
if (username) *username = my_pwd->pw_name;
}
}
if (group) {
my_gid = strtol(group, NULL, 10);
if (my_gid <= 0) {
if (NULL == (my_grp = getgrnam(group))) {
fprintf(stderr, "spawn-fcgi: can't find groupname %s\n", group);
return -1;
}
my_gid = my_grp->gr_gid;
if (my_gid == 0) {
fprintf(stderr, "spawn-fcgi: I will not set gid to 0\n");
return -1;
}
}
} else if (my_pwd) {
my_gid = my_pwd->pw_gid;
if (my_gid == 0) {
fprintf(stderr, "spawn-fcgi: I will not set gid to 0\n");
return -1;
}
}
*uid = my_uid;
*gid = my_gid;
return 0;
}
static void show_version () {
char *b = "spawn-fcgi" "-" PACKAGE_VERSION \
@ -294,11 +352,11 @@ static void show_help () {
" -P <path> name of PID-file for spawed process\n" \
" -n no fork (for daemontools)\n" \
" -v show version\n" \
" -h show this help\n" \
" -?, -h show this help\n" \
"(root only)\n" \
" -c <dir> chroot to directory\n" \
" -u <user> change to user-id\n" \
" -g <group> change to group-id\n" \
" -g <group> change to group-id (default: default group of user if -u is given)\n" \
;
write(1, b, strlen(b));
}
@ -324,7 +382,7 @@ int main(int argc, char **argv) {
i_am_root = (getuid() == 0);
while (-1 != (o = getopt(argc, argv, "c:f:g:hna:p:u:vC:F:s:P:"))) {
while (-1 != (o = getopt(argc, argv, "c:f:g:?hna:p:u:vC:F:s:P:"))) {
switch(o) {
case 'f': fcgi_app = optarg; break;
case 'a': addr = optarg;/* ip addr */ break;
@ -338,6 +396,7 @@ int main(int argc, char **argv) {
case 'n': nofork = 1; break;
case 'P': pid_file = optarg; /* PID file */ break;
case 'v': show_version(); return 0;
case '?':
case 'h': show_help(); return 0;
default:
show_help();
@ -407,43 +466,22 @@ int main(int argc, char **argv) {
}
if (i_am_root) {
struct group *grp = NULL;
struct passwd *pwd = NULL;
uid_t uid;
gid_t gid;
const char* real_username;
/* set user and group */
if (username) {
if (NULL == (pwd = getpwnam(username))) {
fprintf(stderr, "spawn-fcgi: can't find username %s\n", username);
return -1;
}
if (pwd->pw_uid == 0) {
fprintf(stderr, "spawn-fcgi: I will not set uid to 0\n");
return -1;
}
}
if (groupname) {
if (NULL == (grp = getgrnam(groupname))) {
fprintf(stderr, "spawn-fcgi: can't find groupname %s\n", groupname);
return -1;
}
if (grp->gr_gid == 0) {
fprintf(stderr, "spawn-fcgi: I will not set gid to 0\n");
return -1;
}
/* Change group before chroot, when we have access
* to /etc/group
*/
setgid(grp->gr_gid);
setgroups(0, NULL);
if (-1 == find_user_group(username, groupname, &uid, &gid, &real_username))
return -1;
if (username) {
initgroups(username, grp->gr_gid);
/* Change group before chroot, when we have access
* to /etc/group
*/
if (gid != 0) {
setgid(gid);
setgroups(0, NULL);
if (real_username) {
initgroups(real_username, gid);
}
}
if (changeroot) {
@ -458,8 +496,8 @@ int main(int argc, char **argv) {
}
/* drop root privs */
if (username) {
setuid(pwd->pw_uid);
if (uid != 0) {
setuid(uid);
}
}

Loading…
Cancel
Save