--- start-stop-daemon.c.orig 2004-05-10 09:21:55.000000000 -0500 +++ start-stop-daemon.c 2005-03-21 20:31:56.000000000 -0500 @@ -21,20 +21,24 @@ * * Modified for Gentoo rc-scripts by Donny Davies : * I removed the BSD/Hurd/OtherOS stuff, added #include * and stuck in a #define VERSION "1.9.18". Now it compiles without * the whole automake/config.h dance. * * Updated by Aron Griffis : * Fetched updates from Debian's dpkg-1.10.20, including fix for * Gentoo bug 22686 (start-stop-daemon in baselayout doesn't allow * altered nicelevel). + * + * Updated by Scott Dial : + * Provides PAM support, Gentoo bug 64700 (start-stop-daemon doesn't use pam) + * */ #define VERSION "1.10.20" #include #define NONRETURNPRINTFFORMAT(x, y) \ __attribute__((noreturn, format(printf, x, y))) #define NONRETURNING \ __attribute__((noreturn)) @@ -95,20 +99,25 @@ #include #include #include #include #include #include #include #include #include +#ifdef USE_PAM +# include +# include +#endif + #ifdef HAVE_ERROR_H # include #endif #ifdef HURD_IHASH_H #include #endif static int testmode = 0; static int quietmode = 0; static int exitnodo = 1; @@ -283,20 +292,21 @@ " start-stop-daemon -K|--stop options ...\n" " start-stop-daemon -H|--help\n" " start-stop-daemon -V|--version\n" "\n" "Options (at least one of --exec|--pidfile|--user is required):\n" " -x|--exec program to start/check if it is running\n" " -p|--pidfile pid file to check\n" " -c|--chuid \n" " change to this user/group before starting process\n" " -u|--user | stop processes owned by this user\n" +" user for PAM session\n" " -g|--group run process as this group\n" " -n|--name stop processes with this name\n" " -s|--signal signal to send (default TERM)\n" " -a|--startas program to start (default is )\n" " -C|--chdir Change to (default is /)\n" " -N|--nicelevel add incr to the process's nice level\n" " -b|--background force the process to detach\n" " -m|--make-pidfile create the pidfile before starting\n" " -R|--retry check whether processes die, and retry\n" " -t|--test test mode, don't do anything\n" @@ -1131,25 +1141,33 @@ x_finished: if (!anykilled) { if (quietmode <= 0) printf("No %s found running; none killed.\n", what_stop); return exitnodo; } else { return 0; } } +#ifdef USE_PAM +// We are not supporting authentication conversations +static struct pam_conv conv = {NULL, NULL }; +#endif int main(int argc, char **argv) NONRETURNING; int main(int argc, char **argv) { +#ifdef USE_PAM + pam_handle_t *pamh=NULL; + int retval; +#endif int devnull_fd = -1; #ifdef HAVE_TIOCNOTTY int tty_fd = -1; #endif progname = argv[0]; parse_options(argc, argv); argc -= optind; argv += optind; @@ -1252,20 +1270,48 @@ fclose(pidf); } if (changeroot != NULL) { if (chdir(changeroot) < 0) fatal("Unable to chdir() to %s", changeroot); if (chroot(changeroot) < 0) fatal("Unable to chroot() to %s", changeroot); } if (changedir != NULL && chdir(changedir) < 0) fatal("Unable to chdir() to %s", changedir); + +// Before we change users, we need to do PAM +#ifdef USE_PAM + // -c takes priority because it will be what the process ends up running as + // -u comes in second to allow daemons to be started as root (as most require) + // but use the effective session for another user + // else we use "nobody" to avoid promoting any daemon + + if(changeuser != NULL) + retval = pam_start("start-stop-daemon", changeuser, &conv, &pamh); + else if (userspec != NULL) + retval = pam_start("start-stop-daemon", userspec, &conv, &pamh); + else + retval = pam_start("start-stop-daemon", "nobody", &conv, &pamh); + + if(retval == PAM_SUCCESS) + retval = pam_authenticate(pamh, PAM_SILENT); + + if(retval == PAM_SUCCESS) + retval = pam_acct_mgmt(pamh, PAM_SILENT); + + if(retval == PAM_SUCCESS) + retval = pam_open_session(pamh, PAM_SILENT); + + if(retval != PAM_SUCCESS) + printf(pam_strerror(pamh, retval)); +#endif + if (changeuser != NULL) { if (setgid(runas_gid)) fatal("Unable to set gid to %d", runas_gid); if (initgroups(changeuser, runas_gid)) fatal("Unable to set initgroups() with gid %d", runas_gid); if (setuid(runas_uid)) fatal("Unable to set uid to %s", changeuser); } if (background) { /* continue background setup */ int i; @@ -1287,13 +1333,19 @@ #endif /* create a new session */ #ifdef HAVE_SETSID setsid(); #else setpgid(0,0); #endif } execv(startas, argv); - fatal("Unable to start %s: %s", startas, strerror(errno)); +#ifdef USE_PAM + if(retval == PAM_SUCCESS) + pam_close_session(pamh, PAM_SILENT); + + pam_end(pamh, retval); +#endif + fatal("Unable to start %s: %s", startas, strerror(errno)); }