|
|
|
@ -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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|