int main(int argc, char **argv) { char *fcgi_app = NULL, *addr = NULL; unsigned short port = 0; int child_count = 1; int o; struct sockaddr_un un; 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; case 'p': port = strtol(optarg, NULL, 10);/* port */ break; case 'C': child_count = strtol(optarg, NULL, 10);/* */ break; case 'v': show_version(); return 0; case 'h': show_help(); return 0; default: show_help(); return -1; } } if (optind < argc) { fcgi_app = argv[optind]; } if (fcgi_app == NULL || port == 0) { show_help(); return -1; } return fcgi_spawn_connection(fcgi_app, addr, port, child_count); }
int main(int argc, char **argv) { char *fcgi_app = NULL, *changeroot = NULL, *username = NULL, *groupname = NULL, *unixsocket = NULL, *pid_file = NULL, *addr = NULL; char **fcgi_app_argv = { NULL }; unsigned short port = 0; int child_count = 5; int fork_count = 1; int i_am_root, o; int pid_fd = -1; int nofork = 0; struct sockaddr_un un; i_am_root = (getuid() == 0); 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; case 'p': port = strtol(optarg, NULL, 10);/* port */ break; case 'C': child_count = strtol(optarg, NULL, 10);/* */ break; case 'F': fork_count = strtol(optarg, NULL, 10);/* */ break; case 's': unixsocket = optarg; /* unix-domain socket */ break; case 'c': if (i_am_root) { changeroot = optarg; }/* chroot() */ break; case 'u': if (i_am_root) { username = optarg; } /* set user */ break; case 'g': if (i_am_root) { groupname = optarg; } /* set group */ break; case 'n': nofork = 1; break; case 'P': pid_file = optarg; /* PID file */ break; case 'v': show_version(); return 0; case 'h': show_help(); return 0; default: show_help(); return -1; } } if (optind < argc) { fcgi_app_argv = &argv[optind]; } if ((fcgi_app == NULL && fcgi_app_argv == NULL) || (port == 0 && unixsocket == NULL)) { show_help(); return -1; } if (unixsocket && port) { fprintf(stderr, "%s.%d: %s\n", __FILE__, __LINE__, "either a unix domain socket or a tcp-port, but not both\n"); return -1; } if (unixsocket && strlen(unixsocket) > sizeof(un.sun_path) - 1) { fprintf(stderr, "%s.%d: %s\n", __FILE__, __LINE__, "path of the unix socket is too long\n"); return -1; } /* UID handling */ if (!i_am_root && (geteuid() == 0 || getegid() == 0)) { /* we are setuid-root */ fprintf(stderr, "%s.%d: %s\n", __FILE__, __LINE__, "Are you nuts ? Don't apply a SUID bit to this binary\n"); return -1; } if (pid_file && (-1 == (pid_fd = open(pid_file, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)))) { struct stat st; if (errno != EEXIST) { fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n", __FILE__, __LINE__, pid_file, strerror(errno)); return -1; } /* ok, file exists */ if (0 != stat(pid_file, &st)) { fprintf(stderr, "%s.%d: stating pid-file '%s' failed: %s\n", __FILE__, __LINE__, pid_file, strerror(errno)); return -1; } /* is it a regular file ? */ if (!S_ISREG(st.st_mode)) { fprintf(stderr, "%s.%d: pid-file exists and isn't regular file: '%s'\n", __FILE__, __LINE__, pid_file); return -1; } if (-1 == (pid_fd = open(pid_file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) { fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n", __FILE__, __LINE__, pid_file, strerror(errno)); return -1; } } if (i_am_root) { struct group *grp = NULL; struct passwd *pwd = NULL; /* set user and group */ if (username) { if (NULL == (pwd = getpwnam(username))) { fprintf(stderr, "%s.%d: %s, %s\n", __FILE__, __LINE__, "can't find username", username); return -1; } if (pwd->pw_uid == 0) { fprintf(stderr, "%s.%d: %s\n", __FILE__, __LINE__, "I will not set uid to 0\n"); return -1; } } if (groupname) { if (NULL == (grp = getgrnam(groupname))) { fprintf(stderr, "%s.%d: %s %s\n", __FILE__, __LINE__, "can't find groupname", groupname); return -1; } if (grp->gr_gid == 0) { fprintf(stderr, "%s.%d: %s\n", __FILE__, __LINE__, "I will not set gid to 0\n"); return -1; } /* do the change before we do the chroot() */ setgid(grp->gr_gid); setgroups(0, NULL); if (username) { initgroups(username, grp->gr_gid); } } if (changeroot) { if (-1 == chroot(changeroot)) { fprintf(stderr, "%s.%d: %s %s\n", __FILE__, __LINE__, "chroot failed: ", strerror(errno)); return -1; } if (-1 == chdir("/")) { fprintf(stderr, "%s.%d: %s %s\n", __FILE__, __LINE__, "chdir failed: ", strerror(errno)); return -1; } } /* drop root privs */ if (username) { setuid(pwd->pw_uid); } } return fcgi_spawn_connection(fcgi_app, fcgi_app_argv, addr, port, unixsocket, fork_count, child_count, pid_fd, nofork); }