diff --git a/at-3.1.10-dont_fork.patch b/at-3.1.10-dont_fork.patch index 22dc5b1..2d855a0 100644 --- a/at-3.1.10-dont_fork.patch +++ b/at-3.1.10-dont_fork.patch @@ -1,408 +1,33 @@ ---- at-3.1.10/atd.8.in.dont_fork 2005-08-29 10:08:51.000000000 +0200 -+++ at-3.1.10/atd.8.in 2007-01-29 15:46:09.000000000 +0100 -@@ -10,6 +10,7 @@ - .IR batch_interval ] - .RB [ -d ] - .RB [ -s ] -+.RB [ -n ] - .SH DESCRIPTION - .B atd - runs jobs queued by -@@ -46,6 +47,9 @@ - is installed as - .B @prefix@/sbin/atrun - for backward compatibility. -+.TP 8 -+.B -n -+Don't fork option. - .SH WARNING - .B atd - won't work if its spool directory is mounted via NFS even if ---- at-3.1.10/atd.c.dont_fork 2007-01-29 15:46:09.000000000 +0100 -+++ at-3.1.10/atd.c 2007-01-29 16:31:27.000000000 +0100 -@@ -73,6 +73,42 @@ - #ifdef HAVE_UNISTD_H - #include - #endif -+#ifdef WITH_PAM -+/* -+ * We must check if the atd daemon userid will be allowed to gain the job owner user's -+ * credentials with PAM . If not, the user has been denied at(1) usage, eg. with pam_access. -+ */ -+ setreuid(daemon_uid, daemon_uid); -+ setregid(daemon_gid, daemon_gid); -+ -+# define PAM_FAIL_CHECK if (retcode != PAM_SUCCESS) { \ -+ fprintf(stderr,"PAM authentication failure: %s\n",pam_strerror(pamh, retcode)); \ -+ pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT ); -+ pam_close_session(pamh,PAM_SILENT); \ -+ pam_end(pamh, retcode); \ -+ setregid(gid,egid); \ -+ setreuid(uid,euid); \ -+ return(0); \ -+ } -+ retcode = pam_start("atd", pentry->pw_name, &conv, &pamh); -+ PAM_FAIL_CHECK; -+ retcode = pam_set_item(pamh, PAM_TTY, "atd"); -+ PAM_FAIL_CHECK; -+ retcode = pam_acct_mgmt(pamh, PAM_SILENT); -+ PAM_FAIL_CHECK; -+ retcode = pam_open_session(pamh, PAM_SILENT); -+ PAM_FAIL_CHECK; -+ retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED | PAM_SILENT); -+ PAM_FAIL_CHECK; -+ -+ pam_close_session(pamh,PAM_SILENT); -+ pam_end(pamh, PAM_ABORT); -+ -+ setregid(gid,egid); -+ setreuid(uid,euid); -+ -+#endif -+ - - /* Local headers */ - -@@ -83,6 +119,10 @@ - #include "getloadavg.h" - #endif - -+#ifndef LOG_ATD -+#define LOG_ATD LOG_DAEMON -+#endif -+ - /* Macros */ - - #define BATCH_INTERVAL_DEFAULT 60 -@@ -196,6 +236,19 @@ - #define fork myfork - #endif - -+#undef ATD_MAIL_PROGRAM -+#undef ATD_MAIL_NAME -+#if defined(SENDMAIL) -+#define ATD_MAIL_PROGRAM SENDMAIL -+#define ATD_MAIL_NAME "sendmail" -+#elif defined(MAILC) -+#define ATD_MAIL_PROGRAM MAILC -+#define ATD_MAIL_NAME "mail" -+#elif defined(MAILX) -+#define ATD_MAIL_PROGRAM MAILX -+#define ATD_MAIL_NAME "mailx" -+#endif -+ - static void - run_file(char *filename, uid_t uid, gid_t gid) - { -@@ -420,6 +473,8 @@ - PAM_FAIL_CHECK; - retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED | PAM_SILENT); - PAM_FAIL_CHECK; -+ closelog(); -+ openlog("atd", LOG_PID, LOG_ATD); - PRIV_END - #endif - -@@ -434,6 +489,14 @@ - else if (pid == 0) { - char *nul = NULL; - char **nenvp = &nul; -+ char **pam_envp=0L; -+ -+ PRIV_START -+ #ifdef WITH_PAM -+ pam_envp = pam_getenvlist(pamh); -+ if ( ( pam_envp != 0L ) && (pam_envp[0] != 0L) ) -+ nenvp = pam_envp; -+ #endif - - /* Set up things for the child; we want standard input from the - * input file, and standard output and error sent to our output file. -@@ -455,8 +518,6 @@ - if (chdir(ATJOB_DIR) < 0) - perr("Cannot chdir to " ATJOB_DIR); - -- PRIV_START -- - nice((tolower((int) queue) - 'a' + 1) * 2); - - if (initgroups(pentry->pw_name, pentry->pw_gid)) -@@ -472,10 +533,93 @@ - perr("Cannot reset signal handler to default"); - - chdir("/"); -+#ifdef WITH_SELINUX -+ if (selinux_enabled>0) { -+ security_context_t user_context=NULL; -+ security_context_t file_context=NULL; -+ int retval=0; -+ struct av_decision avd; -+ char *seuser=NULL; -+ char *level=NULL; -+ -+ if (getseuserbyname(pentry->pw_name, &seuser, &level) == 0) { -+ retval=get_default_context_with_level(seuser, level, NULL, &user_context); -+ free(seuser); -+ free(level); -+ if (retval) { -+ if (security_getenforce()==1) { -+ perr("execle: couldn't get security context for user %s\n", pentry->pw_name); -+ } else { -+ syslog(LOG_ERR, "execle: couldn't get security context for user %s\n", pentry->pw_name); -+ goto out; -+ } -+ } -+ } -+ -+ /* -+ * Since crontab files are not directly executed, -+ * crond must ensure that the crontab file has -+ * a context that is appropriate for the context of -+ * the user cron job. It performs an entrypoint -+ * permission check for this purpose. -+ */ -+ if (fgetfilecon(STDIN_FILENO, &file_context) < 0) -+ perr("fgetfilecon FAILED %s", filename); -+ -+ retval = security_compute_av(user_context, -+ file_context, -+ SECCLASS_FILE, -+ FILE__ENTRYPOINT, -+ &avd); -+ freecon(file_context); -+ if (retval || ((FILE__ENTRYPOINT & avd.allowed) != FILE__ENTRYPOINT)) { -+ if (security_getenforce()==1) { -+ perr("Not allowed to set exec context to %s for user %s\n", user_context,pentry->pw_name); -+ } else { -+ syslog(LOG_ERR, "Not allowed to set exec context to %s for user %s\n", user_context,pentry->pw_name); -+ goto out; -+ } -+ } -+ -+ if (setexeccon(user_context) < 0) { -+ if (security_getenforce()==1) { -+ -+ perr("Could not set exec context to %s for user %s\n", user_context,pentry->pw_name); -+ } else { -+ syslog(LOG_ERR, "Could not set exec context to %s for user %s\n", user_context,pentry->pw_name); -+ } -+ } -+ out: -+ freecon(user_context); -+ } -+#endif -+ -+ - - if (execle("/bin/sh", "sh", (char *) NULL, nenvp) != 0) -+ - perr("Exec failed for /bin/sh"); - -+#ifdef WITH_SELINUX -+ if (selinux_enabled>0) { -+ if (setexeccon(NULL) < 0) -+ if (security_getenforce()==1) -+ perr("Could not resset exec context for user %s\n", pentry->pw_name); -+ } -+ } -+#endif -+ -+#ifdef WITH_PAM -+ if ( ( nenvp != &nul ) && (pam_envp != 0L) && (*pam_envp != 0L)) -+ { -+ for( nenvp = pam_envp; *nenvp != 0L; nenvp++) -+ free(*nenvp); -+ free( pam_envp ); -+ nenvp = &nul; -+ pam_envp=0L; -+ } -+#endif -+ - PRIV_END - } - /* We're the parent. Let's wait. -@@ -507,14 +651,43 @@ - unlink(filename); - } - -+#ifdef WITH_PAM -+ pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT ); -+ pam_close_session(pamh, PAM_SILENT); -+ pam_end(pamh, PAM_ABORT); -+ closelog(); -+ openlog("atd", LOG_PID, LOG_ATD); -+#endif -+ - /* The job is now finished. We can delete its input file. - */ - chdir(ATJOB_DIR); - unlink(newname); - -+#ifdef ATD_MAIL_PROGRAM - if (((send_mail != -1) && (buf.st_size != size)) || (send_mail == 1)) { -- -- PRIV_START -+ int mail_pid = -1; -+#ifdef WITH_PAM -+ retcode = pam_start("atd", pentry->pw_name, &conv, &pamh); -+ PAM_FAIL_CHECK; -+ retcode = pam_set_item(pamh, PAM_TTY, "atd"); -+ PAM_FAIL_CHECK; -+ retcode = pam_acct_mgmt(pamh, PAM_SILENT); -+ PAM_FAIL_CHECK; -+ retcode = pam_open_session(pamh, PAM_SILENT); -+ PAM_FAIL_CHECK; -+ retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED | PAM_SILENT); -+ PAM_FAIL_CHECK; -+ /* PAM has now re-opened our log to auth.info ! */ -+ closelog(); -+ openlog("atd", LOG_PID, LOG_ATD); -+#endif -+ -+ mail_pid = fork(); -+ -+ if ( mail_pid == 0 ) -+ { -+ PRIV_START - - if (initgroups(pentry->pw_name, pentry->pw_gid)) - perr("Cannot delete saved userids"); -@@ -527,16 +700,81 @@ - - chdir ("/"); - --#if defined(SENDMAIL) -- execl(SENDMAIL, "sendmail", mailname, (char *) NULL); --#else --/*#error "No mail command specified."*/ -- perr("No mail command specified."); -+#ifdef WITH_SELINUX -+ if (selinux_enabled>0) { -+ security_context_t user_context=NULL; -+ security_context_t file_context=NULL; -+ int retval=0; -+ struct av_decision avd; -+ -+ if (get_default_context(pentry->pw_name, NULL, &user_context)) -+ perr("execle: couldn't get security context for user %s\n", pentry->pw_name); -+ /* -+ * Since crontab files are not directly executed, -+ * crond must ensure that the crontab file has -+ * a context that is appropriate for the context of -+ * the user cron job. It performs an entrypoint -+ * permission check for this purpose. -+ */ -+ if (fgetfilecon(STDIN_FILENO, &file_context) < 0) -+ perr("fgetfilecon FAILED %s", filename); -+ -+ retval = security_compute_av(user_context, -+ file_context, -+ SECCLASS_FILE, -+ FILE__ENTRYPOINT, -+ &avd); -+ freecon(file_context); -+ if (retval || ((FILE__ENTRYPOINT & avd.allowed) != FILE__ENTRYPOINT)) { -+ if (security_getenforce()==1) { -+ perr("Not allowed to set exec context to %s for user %s\n", user_context,pentry->pw_name); -+ } else { -+ syslog(LOG_ERR, "Not allowed to set exec context to %s for user %s\n", user_context,pentry->pw_name); -+ goto out; -+ } -+ } -+ -+ if (setexeccon(user_context) < 0) { -+ if (security_getenforce()==1) { -+ perr("Could not set exec context to %s for user %s\n", user_context,pentry->pw_name); -+ } else { -+ syslog(LOG_ERR, "Could not set exec context to %s for user %s\n", user_context,pentry->pw_name); -+ } -+ } -+ freecon(user_context); -+ } -+#endif -+ -+ execl(ATD_MAIL_PROGRAM, ATD_MAIL_NAME, mailname, (char *) NULL); -+ perr("Exec failed for mail command"); -+ exit(-1); -+#ifdef WITH_SELINUX -+ if (selinux_enabled>0) { -+ if (setexeccon(NULL) < 0) -+ if (security_getenforce()==1) -+ perr("Could not resset exec context for user %s\n", pentry->pw_name); -+ } -+ } - #endif -- perr("Exec failed for mail command"); - -- PRIV_END -+ PRIV_END -+ } else -+ if ( mail_pid == -1 ) { -+ perr("fork of mailer failed"); -+ } else { -+ /* Parent */ -+ waitpid(mail_pid, (int *) NULL, 0); +--- at-3.1.10/atd.c.dont_fork 2007-01-30 11:02:37.000000000 +0100 ++++ at-3.1.10/atd.c 2007-01-30 11:07:23.000000000 +0100 +@@ -1001,7 +1001,7 @@ + run_as_daemon = 1; + batch_interval = BATCH_INTERVAL_DEFAULT; + +- while ((c = getopt(argc, argv, "sdl:b:")) != EOF) { ++ while ((c = getopt(argc, argv, "sdl:b:n")) != EOF) { + switch (c) { + case 'l': + if (sscanf(optarg, "%lf", &load_avg) != 1) +@@ -1014,10 +1014,15 @@ + if (sscanf(optarg, "%ud", &batch_interval) != 1) + pabort("garbled option -b"); + break; ++ + case 'd': + daemon_debug++; ++ /* go through another option*/ + -+#ifdef WITH_PAM -+ pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT ); -+ pam_close_session(pamh, PAM_SILENT); -+ pam_end(pamh, PAM_ABORT); -+ closelog(); -+ openlog("atd", LOG_PID, LOG_ATD); -+#endif -+ } - } -+#endif - exit(EXIT_SUCCESS); - } - -@@ -736,6 +974,10 @@ - struct passwd *pwe; - struct group *ge; - -+#ifdef WITH_SELINUX -+ selinux_enabled=is_selinux_enabled(); -+#endif -+ - /* We don't need root privileges all the time; running under uid and gid - * daemon is fine. - */ -@@ -752,11 +994,7 @@ - - RELINQUISH_PRIVS_ROOT(daemon_uid, daemon_gid) - --#ifndef LOG_CRON --#define LOG_CRON LOG_DAEMON --#endif ++ case 'n': ++ daemon_nofork++; + break; - -- openlog("atd", LOG_PID, LOG_CRON); -+ openlog("atd", LOG_PID, LOG_ATD); - - opterr = 0; - errno = 0; -@@ -784,6 +1022,9 @@ ++ + case 's': run_as_daemon = 0; break; - -+ case 'n': -+ daemon_nofork = 1; -+ break; - case '?': - pabort("unknown option"); - break; -@@ -806,6 +1047,10 @@ - act.sa_flags = SA_NOCLDSTOP; - sigaction(SIGCHLD, &act, NULL); - -+ if (daemon_nofork) { -+ daemon_setup(); -+ } -+ - if (!run_as_daemon) { - now = time(NULL); - run_loop(); --- at-3.1.10/daemon.c.dont_fork 2005-08-05 05:16:01.000000000 +0200 -+++ at-3.1.10/daemon.c 2007-01-29 15:46:09.000000000 +0100 ++++ at-3.1.10/daemon.c 2007-01-30 11:06:19.000000000 +0100 @@ -50,7 +50,8 @@ static const char *svnid = "$Id$"; @@ -434,9 +59,29 @@ PRIV_START --- at-3.1.10/daemon.h.dont_fork 2005-08-05 05:16:01.000000000 +0200 -+++ at-3.1.10/daemon.h 2007-01-29 15:46:09.000000000 +0100 ++++ at-3.1.10/daemon.h 2007-01-30 11:07:54.000000000 +0100 @@ -14,3 +14,4 @@ perr (const char *fmt, ...); extern int daemon_debug; +extern int daemon_nofork; +--- at-3.1.8/atd.8.in.dontfork 2002-01-18 08:41:03.000000000 +0100 ++++ at-3.1.8/atd.8.in 2007-01-30 10:51:51.000000000 +0100 +@@ -10,6 +10,7 @@ + .IR batch_interval ] + .RB [ -d ] + .RB [ -s ] ++.RB [ -n ] + .SH DESCRIPTION + .B atd + runs jobs queued by +@@ -46,6 +47,9 @@ + is installed as + .B @prefix@/sbin/atrun + for backward compatibility. ++.TP 8 ++.B -n ++Don't fork option. + .SH WARNING + .B atd + won't work if its spool directory is mounted via NFS even if diff --git a/at.spec b/at.spec index cb47e75..c391ef9 100644 --- a/at.spec +++ b/at.spec @@ -42,8 +42,8 @@ Patch26: at-3.1.10-fix_no_export.patch #Patch32: at-3.1.8-pam_loginuid.patch #Patch33: at-3.1.8-getseuserbyname.patch #Patch34: at-3.1.8-install_no_chown.patch -Patch35: at-3.1.10-dont_fork.patch -Patch36: at-3.1.10-pam.patch +Patch35: at-3.1.10-pam.patch +Patch36: at-3.1.10-dont_fork.patch Patch37: at-3.1.10-makefile.patch Patch38: at-3.1.10-daylight.patch Patch39: at-3.1.10-perm.patch @@ -114,8 +114,8 @@ cp %{SOURCE1} . #%patch32 -p1 -b .pam_loginuid -> in pam.patch #%patch33 -p1 -b .getseuserbyname -> pam.patch #%patch34 -p1 -b .install_no_chown -> makefile.patch -%patch35 -p1 -b .dont_fork -%patch36 -p1 -b .pam +%patch35 -p1 -b .pam +%patch36 -p1 -b .dont_fork %patch37 -p1 -b .makefile %patch38 -p1 -b .daylight %patch39 -p1 -b .perm