/* * Creates the user-privileged slave process. It is called * from the privileged monitor process and returns twice. It returns 0 * for the user-privileged slave process and 1 for the monitor process. */ int monitor_post_auth() { slave_pid = fork(); if (slave_pid == -1) fatalx("fork of user-privileged slave failed"); snprintf(ttyline, sizeof(ttyline), "ftp%ld", slave_pid == 0 ? (long)getpid() : (long)slave_pid); if (slave_pid == 0) { /* User privileged slave */ close(fd_slave); set_slave_signals(); return (0); } /* We have to keep stdout open, because reply() needs it. */ if ((nullfd = open(_PATH_DEVNULL, O_RDWR, 0)) == -1) fatalx("cannot open %s: %m", _PATH_DEVNULL); dup2(nullfd, STDIN_FILENO); dup2(nullfd, STDERR_FILENO); close(nullfd); close(fd_monitor); return (1); }
/* * Creates the privileged monitor process. It returns twice. * It returns 1 for the unprivileged slave process and 0 for the * user-privileged slave process after successful authentication. */ int monitor_init(void) { struct passwd *pw; int pair[2]; if (socketpair(AF_LOCAL, SOCK_STREAM, PF_UNSPEC, pair) == -1) fatalx("socketpair failed"); fd_monitor = pair[0]; fd_slave = pair[1]; set_monitor_signals(); slave_pid = fork(); if (slave_pid == -1) fatalx("fork of unprivileged slave failed"); if (slave_pid == 0) { /* Unprivileged slave */ set_slave_signals(); if ((pw = getpwnam(FTPD_PRIVSEP_USER)) == NULL) fatalx("privilege separation user %s not found", FTPD_PRIVSEP_USER); if (chroot(pw->pw_dir) == -1) fatalx("chroot %s: %m", pw->pw_dir); if (chdir("/") == -1) fatalx("chdir /: %m"); if (setgroups(1, &pw->pw_gid) == -1) fatalx("setgroups: %m"); if (setegid(pw->pw_gid) == -1) fatalx("setegid failed"); if (setgid(pw->pw_gid) == -1) fatalx("setgid failed"); if (seteuid(pw->pw_uid) == -1) fatalx("seteuid failed"); if (setuid(pw->pw_uid) == -1) fatalx("setuid failed"); endpwent(); close(fd_slave); return (1); } #ifdef HASSETPROCTITLE setproctitle("%s: [priv pre-auth]", remotehost); #endif handle_cmds(); /* User-privileged slave */ return (0); }
int main(int argc, char *argv[]) { printf("ISAKMP: main : <<<START>>> \n"); fd_set *rfds, *wfds; int n, m; size_t mask_size; struct timeval tv, *timeout; // closefrom(STDERR_FILENO + 1); /* * Make sure init() won't alloc fd 0, 1 or 2, as daemon() will close * them. */ /* for (n = 0; n <= 2; n++) if (fcntl(n, F_GETFL, 0) == -1 && errno == EBADF) (void) open("/dev/null", n ? O_WRONLY : O_RDONLY, 0); */ /* Log cmd line parsing and initialization errors to stderr. */ log_to(stderr); parse_args(argc, argv); log_init(debug); /* Open protocols and services databases. */ setprotoent(1); setservent(1); /* Open command fifo */ ui_init(); set_slave_signals(); /* Daemonize before forking unpriv'ed child */ if (!debug) if (daemon(0, 0)) log_fatal("main: daemon (0, 0) failed"); /* Set timezone before priv'separation */ tzset(); write_pid_file(); /* if (monitor_init(debug)) { // The parent, with privileges enters infinite monitor loop. //monitor_loop(debug); //exit(0); // Never reached. }*/ /* Child process only from this point on, no privileges left. */ init(); /* If we wanted IKE packet capture to file, initialize it now. */ if (pcap_file != 0) log_packet_init(pcap_file); /* Allocate the file descriptor sets just big enough. */ // we change here //n = getdtablesize(); n = 1000; mask_size = howmany(n, NFDBITS) * sizeof(fd_mask); rfds = (fd_set *) malloc(mask_size); if (!rfds) log_fatal("main: malloc (%lu) failed", (unsigned long)mask_size); wfds = (fd_set *) malloc(mask_size); if (!wfds) log_fatal("main: malloc (%lu) failed", (unsigned long)mask_size); //monitor_init_done(); while (1) { /* If someone has sent SIGHUP to us, reconfigure. */ if (sighupped) { sighupped = 0; log_print("SIGHUP received"); reinit(); } /* and if someone sent SIGUSR1, do a state report. */ if (sigusr1ed) { sigusr1ed = 0; log_print("SIGUSR1 received"); report(); } /* * and if someone set 'sigtermed' (SIGTERM, SIGINT or via the * UI), this indicates we should start a controlled shutdown * of the daemon. * * Note: Since _one_ message is sent per iteration of this * enclosing while-loop, and we want to send a number of * DELETE notifications, we must loop atleast this number of * times. The daemon_shutdown() function starts by queueing * the DELETEs, all other calls just increments the * 'sigtermed' variable until it reaches a "safe" value, and * the daemon exits. */ if (sigtermed) daemon_shutdown(); /* Setup the descriptors to look for incoming messages at. */ bzero(rfds, mask_size); n = transport_fd_set(rfds); FD_SET(ui_socket, rfds); if (ui_socket + 1 > n) n = ui_socket + 1; /* * XXX Some day we might want to deal with an abstract * application class instead, with many instantiations * possible. */ if (!app_none && app_socket >= 0) { FD_SET(app_socket, rfds); if (app_socket + 1 > n) n = app_socket + 1; } /* Setup the descriptors that have pending messages to send. */ bzero(wfds, mask_size); m = transport_pending_wfd_set(wfds); printf(" m = %d , n = %d \n", m,n); if (m > n) n = m; /* Find out when the next timed event is. */ timeout = &tv; timer_next_event(&timeout); printf(" select (n n= %d )\n ",n ); n = select(n, rfds, wfds, 0, timeout); if (n == -1) { if (errno != EINTR) { log_error("main: select"); /* * In order to give the unexpected error * condition time to resolve without letting * this process eat up all available CPU * we sleep for a short while. */ sleep(1); } } else if (n) { transport_handle_messages(rfds); transport_send_messages(wfds); if (FD_ISSET(ui_socket, rfds)) ui_handler(); if (!app_none && app_socket >= 0 && FD_ISSET(app_socket, rfds)) app_handler(); } timer_handle_expirations(); } }