From e643368f97f1c8bbe2d0c4ba88f534e6bd16ff1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcela=20Ma=C5=A1l=C3=A1=C5=88ov=C3=A1?= Date: Tue, 3 Jul 2007 14:24:48 +0000 Subject: [PATCH] Change patches. --- at-3.1.10-dont_fork.patch | 91 ++-- at-3.1.10-makefile.patch | 68 ++- at-3.1.10-pam.patch | 865 +++++++++++++++++++++----------------- at-3.1.10-perm.patch | 77 +--- at-3.1.8-t_option.patch | 191 +++++++-- at.spec | 82 ++-- 6 files changed, 748 insertions(+), 626 deletions(-) diff --git a/at-3.1.10-dont_fork.patch b/at-3.1.10-dont_fork.patch index 51e0842..4d56bf2 100644 --- a/at-3.1.10-dont_fork.patch +++ b/at-3.1.10-dont_fork.patch @@ -1,33 +1,39 @@ ---- 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; +--- at-3.1.10/atd.8.in.fork 2005-08-29 10:08:51.000000000 +0200 ++++ at-3.1.10/atd.8.in 2007-07-03 14:04:05.000000000 +0200 +@@ -1,5 +1,5 @@ + .Id $Id$ +-.TH ATD 8 "Mar 1997" local "Linux Programmer's Manual" ++.TH ATD 3 "Jun 2007" at-3.1.10 "Linux Programmer's Manual" + .SH NAME + atd \- run jobs queued for later execution + .SH SYNOPSIS +@@ -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/daemon.h.fork 2005-08-05 05:16:01.000000000 +0200 ++++ at-3.1.10/daemon.h 2007-07-03 14:02:22.000000000 +0200 +@@ -14,3 +14,4 @@ + perr (const char *fmt, ...); -- 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*/ -+ -+ case 'n': -+ daemon_nofork++; - break; -- -+ - case 's': - run_as_daemon = 0; - break; ---- at-3.1.10/daemon.c.dont_fork 2005-08-05 05:16:01.000000000 +0200 -+++ at-3.1.10/daemon.c 2007-01-30 11:06:19.000000000 +0100 + extern int daemon_debug; ++extern int daemon_nofork; +--- at-3.1.10/daemon.c.fork 2005-08-05 05:16:01.000000000 +0200 ++++ at-3.1.10/daemon.c 2007-07-03 14:01:51.000000000 +0200 @@ -50,7 +50,8 @@ static const char *svnid = "$Id$"; @@ -58,30 +64,3 @@ 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-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-3.1.10-makefile.patch b/at-3.1.10-makefile.patch index 5fe5f1b..53379c8 100644 --- a/at-3.1.10-makefile.patch +++ b/at-3.1.10-makefile.patch @@ -1,23 +1,36 @@ ---- at-3.1.10/Makefile.in.makefile 2006-09-12 08:33:38.000000000 +0200 -+++ at-3.1.10/Makefile.in 2006-09-12 08:44:52.000000000 +0200 -@@ -69,13 +69,13 @@ +--- at-3.1.10/Makefile.in.old 2005-08-29 10:08:28.000000000 +0200 ++++ at-3.1.10/Makefile.in 2007-07-02 15:38:48.000000000 +0200 +@@ -51,7 +51,7 @@ + privs.h + + OTHERS = parsetime.l parsetime.y +- ++TEST_VERBOSE = 0 + DOCS = Problems Copyright README ChangeLog timespec + + MISC = COPYING Makefile.in configure acconfig.h install-sh \ +@@ -67,13 +67,13 @@ all: at atd atrun at: $(ATOBJECTS) -- $(CC) $(CFLAGS) -o at -pie $(ATOBJECTS) $(LIBS) $(LEXLIB) -+ $(CC) $(CFLAGS) -o at -pie $(ATOBJECTS) $(LIBS) $(LEXLIB) $(PAMLIB) +- $(CC) $(CFLAGS) -o at $(ATOBJECTS) $(LIBS) $(LEXLIB) ++ $(CC) $(CFLAGS) -o at -pie $(ATOBJECTS) $(LIBS) $(LEXLIB) rm -f $(CLONES) $(LN_S) -f at atq $(LN_S) -f at atrm atd: $(RUNOBJECTS) -- $(CC) $(CFLAGS) -o atd -pie $(RUNOBJECTS) $(LIBS) $(PAMLIB) -+ $(CC) $(CFLAGS) -o atd -pie $(RUNOBJECTS) $(LIBS) $(SELINUXLIB) $(PAMLIB) +- $(CC) $(CFLAGS) -o atd $(RUNOBJECTS) $(LIBS) $(PAMLIB) ++ $(CC) $(CFLAGS) -o atd -pie $(RUNOBJECTS) $(LIBS) $(PAMLIB) y.tab.c y.tab.h: parsetime.y $(YACC) -d parsetime.y -@@ -90,35 +90,38 @@ - $(CC) -c $(CFLAGS) -fpie $(DEFS) $*.c +@@ -85,38 +85,42 @@ + configure + + .c.o: +- $(CC) -c $(CFLAGS) $(DEFS) $*.c ++ $(CC) -c $(CFLAGS) -fpie $(DEFS) $*.c install: all - $(INSTALL) -g root -o root -m 755 -d $(IROOT)$(etcdir) @@ -33,18 +46,18 @@ + $(INSTALL) -m 755 -d $(IROOT)$(docdir) + $(INSTALL) -m 755 -d $(IROOT)$(atdocdir) + $(INSTALL) -m 755 -d $(IROOT)$(ATJOB_DIR) -+ $(INSTALL) -m 755 -d $(IROOT)$(etcdir)/pam.d -+ $(INSTALL) -g $(DAEMON_GROUPNAME) -o $(DAEMON_USERNAME) -m 755 -d $(IROOT) $(ATSPOOL_DIR) -+ chmod 700 $(IROOT)$(ATSPOOL_DIR) $(IROOT)$(ATJOB_DIR) ++ $(INSTALL) -m 755 -d $(IROOT)$(etcdir)/pam.d ++ $(INSTALL) -g $(DAEMON_GROUPNAME) -o $(DAEMON_USERNAME) -m 755 -d $(IROOT)$(ATSPOOL_DIR) ++ chmod 700 $(IROOT)$(ATJOB_DIR) $(IROOT)$(ATSPOOL_DIR) ++ chown $(DAEMON_USERNAME):$(DAEMON_GROUPNAME) $(IROOT)$(ATJOB_DIR) $(IROOT)$(ATSPOOL_DIR) touch $(IROOT)$(LFILE) chmod 600 $(IROOT)$(LFILE) -- chown $(DAEMON_USERNAME):$(DAEMON_GROUPNAME) $(IROOT)$(LFILE) + chown $(DAEMON_USERNAME):$(DAEMON_GROUPNAME) $(IROOT)$(LFILE) - test -f $(IROOT)$(etcdir)/at.allow || test -f $(IROOT)$(etcdir)/at.deny || $(INSTALL) -o root -g $(DAEMON_GROUPNAME) -m 640 at.deny $(IROOT)$(etcdir)/ - $(INSTALL) -g $(DAEMON_GROUPNAME) -o $(DAEMON_USERNAME) -m 6755 -s at $(IROOT)$(bindir) -+ chown $(DAEMON_USERNAME):$(DAEMON_GROUPNAME) $(IROOT)$(ATJOB_DIR) $(IROOT)$(ATSPOOL_DIR) -+ test -f $(IROOT)$(etcdir)/at.allow || test -f $(IROOT)$(etcdir)/at.deny || $(INSTALL) -m 600 at.deny $(IROOT)$(etcdir)/ ++ test -f $(IROOT)$(etcdir)/at.allow || test -f $(IROOT)$(etcdir)/at.deny || $(INSTALL) -m 600 at.deny $(IROOT)$(etcdir)/ + $(INSTALL) -o $(INSTALL_ROOT_USER) -g $(DAEMON_GROUPNAME) pam_atd $(IROOT)$(etcdir)/pam.d/atd -+ $(INSTALL) -m 4755 -s at $(IROOT)$(bindir) ++ $(INSTALL) -m 4755 at $(IROOT)$(bindir) $(LN_S) -f at $(IROOT)$(bindir)/atq $(LN_S) -f at $(IROOT)$(bindir)/atrm - $(INSTALL) -g root -o root -m 755 batch $(IROOT)$(bindir) @@ -55,10 +68,10 @@ - $(INSTALL) -g root -o root -m 755 atrun $(IROOT)$(sbindir) - $(INSTALL) -g root -o root -m 644 at.1 $(IROOT)$(man1dir)/ + $(INSTALL) -m 755 batch $(IROOT)$(bindir) -+ $(INSTALL) -m 755 -d $(IROOT)$(man1dir) -+ $(INSTALL) -m 755 -d $(IROOT)$(man5dir) -+ $(INSTALL) -m 755 -d $(IROOT)$(man8dir) -+ $(INSTALL) -m 755 -s atd $(IROOT)$(sbindir) ++ $(INSTALL) -d -m 755 $(IROOT)$(man1dir) ++ $(INSTALL) -d -m 755 $(IROOT)$(man5dir) ++ $(INSTALL) -d -m 755 $(IROOT)$(man8dir) ++ $(INSTALL) -m 755 atd $(IROOT)$(sbindir) + $(INSTALL) -m 755 atrun $(IROOT)$(sbindir) + $(INSTALL) -m 644 at.1 $(IROOT)$(man1dir)/ cd $(IROOT)$(man1dir) && $(LN_S) -f at.1 atq.1 && $(LN_S) -f at.1 batch.1 && $(LN_S) -f at.1 atrm.1 @@ -69,10 +82,21 @@ + $(INSTALL) -m 644 tmpman $(IROOT)$(man8dir)/atrun.8 rm -f tmpman - $(INSTALL) -g root -o root -m 644 at_allow.5 $(IROOT)$(man5dir)/ -+ $(INSTALL) -m 644 at_allow.5 $(IROOT)$(man5dir)/ - cd $(IROOT)$(man5dir) && $(LN_S) -f at_allow.5 at_deny.5 +- cd $(IROOT)$(man5dir) && $(LN_S) -f at_allow.5 at_deny.5 - $(INSTALL) -g root -o root -m 644 $(DOCS) $(IROOT)$(atdocdir) ++ $(INSTALL) -m 644 at_allow.5 $(IROOT)$(man5dir)/ ++ cd $(IROOT)$(man5dir) && $(LN_S) -f at_allow.5 at_deny.5 + $(INSTALL) -m 644 $(DOCS) $(IROOT)$(atdocdir) rm -f $(IROOT)$(mandir)/cat1/at.1* $(IROOT)$(mandir)/cat1/batch.1* \ $(IROOT)$(mandir)/cat1/atq.1* rm -f $(IROOT)$(mandir)/cat1/atd.8* +@@ -150,6 +154,9 @@ + parsetest: lex.yy.c y.tab.c + $(CC) -o parsetest $(CFLAGS) $(DEFS) -DTEST_PARSER -DNEED_YYWRAP lex.yy.c y.tab.c + ++test: parsetest ++ PERL_DL_NONLAZY=1 perl -e 'use Test::Harness qw(&runtests $$verbose); $$verbose=$(TEST_VERBOSE); runtests @ARGV;' test.pl ++ + .depend: $(CSRCS) + gcc $(CFLAGS) $(DEFS) -MM $(CSRCS) > .depend + diff --git a/at-3.1.10-pam.patch b/at-3.1.10-pam.patch index 3d3bc5f..9cc8b26 100644 --- a/at-3.1.10-pam.patch +++ b/at-3.1.10-pam.patch @@ -1,367 +1,5 @@ ---- at-3.1.10/atd.c.pam 2006-09-12 15:01:55.000000000 +0200 -+++ at-3.1.10/atd.c 2006-09-12 15:26:49.000000000 +0200 -@@ -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); -+ -+#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 -- -- openlog("atd", LOG_PID, LOG_CRON); -+ openlog("atd", LOG_PID, LOG_ATD); - - opterr = 0; - errno = 0; --- at-3.1.10/perm.c.pam 2005-08-05 05:16:01.000000000 +0200 -+++ at-3.1.10/perm.c 2006-09-12 15:06:30.000000000 +0200 ++++ at-3.1.10/perm.c 2007-07-03 13:29:24.000000000 +0200 @@ -51,6 +51,14 @@ #define PRIV_END while(0) #endif @@ -377,7 +15,7 @@ /* Structures and unions */ -@@ -109,18 +117,58 @@ +@@ -109,18 +117,54 @@ int check_permission() { @@ -385,10 +23,9 @@ + uid_t euid = geteuid(), uid=getuid(), egid=getegid(), gid=getgid(); struct passwd *pentry; int allow = 0, deny = 1; - +- - if (uid == 0) -+ int retcode=0; -+ ++ int retcode = 0; + if (euid == 0) return 1; @@ -408,12 +45,11 @@ + +# 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_close_session(pamh,PAM_SILENT); \ + pam_end(pamh, retcode); \ -+ setregid(gid,egid); \ -+ setreuid(uid,euid); \ -+ return(0); \ ++ setregid(gid,egid); \ ++ setreuid(uid,euid); \ ++ return(0); \ + } + retcode = pam_start("atd", pentry->pw_name, &conv, &pamh); + PAM_FAIL_CHECK; @@ -426,6 +62,7 @@ + retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED | PAM_SILENT); + PAM_FAIL_CHECK; + ++ pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT ); + pam_close_session(pamh,PAM_SILENT); + pam_end(pamh, PAM_ABORT); + @@ -433,33 +70,481 @@ + setreuid(uid,euid); + +#endif -+ -+ + allow = user_in_file(ETCDIR "/at.allow", pentry->pw_name); if (allow==0 || allow==1) return allow; ---- at-3.1.10/config.h.in.__ 2006-09-07 18:47:06.000000000 +0200 -+++ at-3.1.10/config.h.in 2006-09-07 18:48:12.000000000 +0200 -@@ -181,3 +181,9 @@ +--- at-3.1.10/config.h.in.pam 2005-08-05 05:16:02.000000000 +0200 ++++ at-3.1.10/config.h.in 2007-07-03 13:29:24.000000000 +0200 +@@ -181,3 +181,10 @@ #undef HAVE_ATTRIBUTE_NORETURN #undef HAVE_PAM + ++/* Define if you are building with_pam */ ++#undef WITH_PAM ++ +/* Define if you are building with_selinux */ +#undef WITH_SELINUX + -+/* Define if you are building with_pam */ -+#undef WITH_PAM ---- at-3.1.10/configure.in._ 2005-08-05 05:16:02.000000000 +0200 -+++ at-3.1.10/configure.in 2006-09-07 16:21:19.000000000 +0200 -@@ -88,6 +88,9 @@ - if test "$ac_cv_path_SENDMAIL" != "" ; then - AC_DEFINE_UNQUOTED(SENDMAIL,"$ac_cv_path_SENDMAIL") - MAIL_CMD="$ac_cv_path_SENDMAIL" -+#AC_PATH_PROG(GETOPT, getopt, , $PATH:/bin:/usr/bin:/usr/local/bin ) -+#if test "$ac_cv_path_GETOPT" != "" ; then -+#AC_DEFINE_UNQUOTED(GETOPT,"$ac_cv_path_GETOPT") - fi +--- at-3.1.10/configure.in.pam 2005-08-05 05:16:02.000000000 +0200 ++++ at-3.1.10/configure.in 2007-07-03 13:29:24.000000000 +0200 +@@ -316,4 +316,19 @@ + ) + AC_SUBST(DAEMON_GROUPNAME) - AC_SUBST(MAIL_CMD) ++AC_ARG_WITH(selinux, ++[ --with-selinux Define to run with selinux], ++AC_DEFINE(WITH_SELINUX), ++) ++AC_CHECK_LIB(selinux, is_selinux_enabled, SELINUXLIB=-lselinux) ++AC_SUBST(SELINUXLIB) ++AC_SUBST(WITH_SELINUX) ++ ++AC_ARG_WITH(pam, ++[ --with-pam Define to enable pam support ], ++AC_DEFINE(WITH_PAM), ++) ++AC_CHECK_LIB(pam, pam_start, PAMLIB='-lpam -lpam_misc') ++AC_SUBST(PAMLIB) ++ + AC_OUTPUT(Makefile atrun atd.8 atrun.8 at.1 batch) +--- at-3.1.10/atd.c.pam 2007-07-03 13:29:24.000000000 +0200 ++++ at-3.1.10/atd.c 2007-07-03 13:52:38.000000000 +0200 +@@ -74,6 +74,14 @@ + #include + #endif + ++#ifdef WITH_SELINUX ++#include ++#include ++int selinux_enabled=0; ++#include ++#include ++#endif ++ + /* Local headers */ + + #include "privs.h" +@@ -83,6 +91,10 @@ + #include "getloadavg.h" + #endif + ++#ifndef LOG_ATD ++#define LOG_ATD LOG_DAEMON ++#endif ++ + /* Macros */ + + #define BATCH_INTERVAL_DEFAULT 60 +@@ -121,6 +133,7 @@ + #define PAM_FAIL_CHECK if (retcode != PAM_SUCCESS) { \ + fprintf(stderr,"\n%s\n",pam_strerror(pamh, retcode)); \ + syslog(LOG_ERR,"%s",pam_strerror(pamh, retcode)); \ ++ pam_close_session(pamh, PAM_SILENT); \ + pam_end(pamh, retcode); exit(1); \ + } + #define PAM_END { retcode = pam_close_session(pamh,0); \ +@@ -196,6 +209,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(const char *filename, uid_t uid, gid_t gid) + { +@@ -378,18 +404,22 @@ + fstat(fd_out, &buf); + size = buf.st_size; + +-#ifdef HAVE_PAM +- PRIV_START ++//add for fedora, removed HAVE_PAM ++#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; +- PRIV_END ++ closelog(); ++ openlog("atd", LOG_PID, LOG_ATD); + #endif ++//end + + close(STDIN_FILENO); + close(STDOUT_FILENO); +@@ -402,6 +432,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. +@@ -423,8 +461,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)) +@@ -441,10 +477,90 @@ + + 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) { ++ if (security_getenforce() > 0) { ++ perr("fgetfilecon FAILED %s", filename); ++ } else { ++ syslog(LOG_ERR, "fgetfilecon FAILED %s", filename); ++ goto out; ++ } ++ } ++ 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); ++ } ++ ++ 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 ++ + if (execle("/bin/sh", "sh", (char *) NULL, nenvp) != 0) + perr("Exec failed for /bin/sh"); +- ++//add for fedora ++#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 ++//end ++//add for fedora ++#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 ++//end + } + /* We're the parent. Let's wait. + */ +@@ -456,7 +572,7 @@ + return with an ECHILD error. + */ + waitpid(pid, (int *) NULL, 0); +- ++/* remove because WITH_PAM + #ifdef HAVE_PAM + PRIV_START + pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT); +@@ -464,7 +580,7 @@ + pam_end(pamh, retcode); + PRIV_END + #endif +- ++*/ + /* Send mail. Unlink the output file after opening it, so it + * doesn't hang around after the run. + */ +@@ -472,6 +588,13 @@ + if (open(filename, O_RDONLY) != STDIN_FILENO) + perr("Open of jobfile failed"); + ++#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 + unlink(filename); + + /* The job is now finished. We can delete its input file. +@@ -480,8 +603,30 @@ + unlink(newname); + free(newname); + ++#ifdef ATD_MAIL_PROGRAM + if (((send_mail != -1) && (buf.st_size != size)) || (send_mail == 1)) { ++ int mail_pid = -1; ++//add for fedora ++#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 ++//end ++ mail_pid = fork(); + ++ if ( mail_pid == 0 ) ++ { + PRIV_START + + if (initgroups(pentry->pw_name, pentry->pw_gid)) +@@ -495,16 +640,80 @@ + + 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); ++ } ++ } ++ out: ++ freecon(user_context); ++ } ++#endif ++ execl(ATD_MAIL_PROGRAM, ATD_MAIL_NAME, mailname, (char *) NULL); ++ perr("Exec faile 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 ++ } ++ else if ( mail_pid == -1 ) { ++ perr("fork of mailer failed"); ++ } ++ else { ++ /* Parent */ ++ waitpid(mail_pid, (int *) NULL, 0); ++ } ++#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); + } + +@@ -702,6 +911,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. + */ +@@ -718,18 +931,13 @@ + + RELINQUISH_PRIVS_ROOT(daemon_uid, daemon_gid) + +-#ifndef LOG_CRON +-#define LOG_CRON LOG_DAEMON +-#endif +- +- openlog("atd", LOG_PID, LOG_CRON); +- ++ openlog("atd", LOG_PID, LOG_ATD); + opterr = 0; + errno = 0; + 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) +@@ -742,10 +950,15 @@ + if (sscanf(optarg, "%ud", &batch_interval) != 1) + pabort("garbled option -b"); + break; ++ + case 'd': + daemon_debug++; ++ /* go through another option*/ ++ ++ case 'n': ++ daemon_nofork++; + break; +- ++ + case 's': + run_as_daemon = 0; + break; +--- at-3.1.10/Makefile.in.pam 2007-07-03 13:29:24.000000000 +0200 ++++ at-3.1.10/Makefile.in 2007-07-03 13:29:24.000000000 +0200 +@@ -41,6 +41,7 @@ + LIBOBJS = @LIBOBJS@ + INSTALL = @INSTALL@ + PAMLIB = @PAMLIB@ ++SELINUXLIB = @SELINUXLIB@ + + CLONES = atq atrm + ATOBJECTS = at.o panic.o perm.o y.tab.o lex.yy.o +@@ -67,13 +68,13 @@ + all: at atd atrun + + at: $(ATOBJECTS) +- $(CC) $(CFLAGS) -o at -pie $(ATOBJECTS) $(LIBS) $(LEXLIB) ++ $(CC) $(CFLAGS) -o at -pie $(ATOBJECTS) $(LIBS) $(LEXLIB) $(PAMLIB) + rm -f $(CLONES) + $(LN_S) -f at atq + $(LN_S) -f at atrm + + atd: $(RUNOBJECTS) +- $(CC) $(CFLAGS) -o atd -pie $(RUNOBJECTS) $(LIBS) $(PAMLIB) ++ $(CC) $(CFLAGS) -o atd -pie $(RUNOBJECTS) $(LIBS) $(SELINUXLIB) $(PAMLIB) + + y.tab.c y.tab.h: parsetime.y + $(YACC) -d parsetime.y +--- at-3.1.10/pam_atd.pam 2007-07-03 13:29:24.000000000 +0200 ++++ at-3.1.10/pam_atd 2007-07-03 13:29:24.000000000 +0200 +@@ -0,0 +1,13 @@ ++# The PAM configuration file for the at daemon ++# ++# ++auth sufficient pam_rootok.so ++auth include system-auth ++auth required pam_env.so ++account include system-auth ++session required pam_loginuid.so ++session include system-auth ++# Sets up user limits, please uncomment and read /etc/security/limits.conf ++# to enable this functionality. ++# session required pam_limits.so ++# diff --git a/at-3.1.10-perm.patch b/at-3.1.10-perm.patch index 57ea7cf..27cd5a4 100644 --- a/at-3.1.10-perm.patch +++ b/at-3.1.10-perm.patch @@ -1,29 +1,12 @@ ---- at-3.1.10/at.c.perm 2006-11-14 12:26:27.000000000 +0100 -+++ at-3.1.10/at.c 2006-11-14 12:28:15.000000000 +0100 -@@ -144,17 +144,12 @@ - */ - if (fcreated) { - /* -- PRIV_START -- - We need the unprivileged uid here since the file is owned by the real - (not effective) uid. - */ - setregid(real_gid, effective_gid); - unlink(atfile); - setregid(effective_gid, real_gid); -- /* -- PRIV_END -- */ - } - exit(EXIT_FAILURE); - } -@@ -314,18 +309,18 @@ +--- at-3.1.10/at.c.perm 2007-07-02 15:40:35.000000000 +0200 ++++ at-3.1.10/at.c 2007-07-02 16:19:54.000000000 +0200 +@@ -314,10 +314,11 @@ * bit. Yes, this is a kluge. */ cmask = umask(S_IRUSR | S_IWUSR | S_IXUSR); - seteuid(real_uid); -+ seteuid(effective_uid); ++ //seteuid(real_uid); ++ seteuid(effective_uid); if ((fd = open(atfile, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, S_IRUSR)) == -1) perr("Cannot create atjob file %.500s", atfile); - seteuid(effective_uid); @@ -31,53 +14,3 @@ if ((fd2 = dup(fd)) < 0) perr("Error in dup() of job file"); - -- /* -+ - if (fchown(fd2, real_uid, real_gid) != 0) - perr("Cannot give away file"); -- */ -+ - - PRIV_END - -@@ -656,6 +651,7 @@ - We need the unprivileged uid here since the file is owned by the real - (not effective) uid. - */ -+// PRIV_START - setregid(real_gid, effective_gid); - - if (queue == '=') { -@@ -668,17 +664,17 @@ - - setregid(effective_gid, real_gid); - done = 1; -- -+// PRIV_END - break; - - case CAT: - { - FILE *fp; - int ch; -- -+ // PRIV_START - setregid(real_gid, effective_gid); - fp = fopen(dirent->d_name, "r"); -- -+ // PRIV_END - if (fp) { - while ((ch = getc(fp)) != EOF) { - putchar(ch); ---- at-3.1.10/Makefile.in.perm 2006-11-14 12:26:27.000000000 +0100 -+++ at-3.1.10/Makefile.in 2006-11-14 12:26:27.000000000 +0100 -@@ -97,7 +97,7 @@ - $(INSTALL) -m 755 -d $(IROOT)$(atdocdir) - $(INSTALL) -m 755 -d $(IROOT)$(ATJOB_DIR) - $(INSTALL) -m 755 -d $(IROOT)$(etcdir)/pam.d -- $(INSTALL) -g $(DAEMON_GROUPNAME) -o $(DAEMON_USERNAME) -m 755 -d $(IROOT) $(ATSPOOL_DIR) -+ $(INSTALL) -g $(DAEMON_GROUPNAME) -o $(DAEMON_USERNAME) -m 755 -d $(IROOT)$(ATSPOOL_DIR) - chmod 700 $(IROOT)$(ATSPOOL_DIR) $(IROOT)$(ATJOB_DIR) - touch $(IROOT)$(LFILE) - chmod 600 $(IROOT)$(LFILE) diff --git a/at-3.1.8-t_option.patch b/at-3.1.8-t_option.patch index 0bd4e8e..22f7ac5 100644 --- a/at-3.1.8-t_option.patch +++ b/at-3.1.8-t_option.patch @@ -1,41 +1,18 @@ ---- at-3.1.10/at.1.in.t_opti 2006-09-12 12:48:04.000000000 +0200 -+++ at-3.1.10/at.1.in 2006-09-12 12:45:40.000000000 +0200 -@@ -12,6 +12,16 @@ - .RB [ -mldbv ] - .B TIME - .br -+.B at -+.RB [ -V ] -+.RB [ -q -+.IR queue ] -+.RB [ -f -+.IR file ] -+.RB [ -mldbv ] -+.RB -t -+.IR time_arg -+.br - .B "at -c" - .I job - .RI [ job... ] -@@ -227,6 +237,15 @@ - .B - \-c - cats the jobs listed on the command line to standard output. -+.TP -+.BI \-t " time_arg" -+Submit the job to be run at the time specified by the -+.BI time_arg -+option argument, which must have the same format as specified for the -+.BR touch(1) -+utility's -+.B -t -+time option argument ([[CC]YY]MMDDhhmm). - .SH FILES - .I @ATJBD@ - .br ---- at-3.1.10/at.c.t_ 2006-09-12 10:15:56.000000000 +0200 -+++ at-3.1.10/at.c 2006-09-12 10:30:17.000000000 +0200 -@@ -750,6 +750,101 @@ +--- at-3.1.10/at.c.t_option 2007-06-28 14:43:51.000000000 +0200 ++++ at-3.1.10/at.c 2007-06-28 14:54:04.000000000 +0200 +@@ -396,8 +396,9 @@ + unsigned int i; + for (i = 0; i < sizeof(no_export) / sizeof(no_export[0]); i++) { + export = export +- && (strncmp(*atenv, no_export[i], +- (size_t) (eqp - *atenv)) != 0); ++ && ( (((size_t) (eqp - *atenv)) != strlen(no_export[i])) ++ ||(strncmp(*atenv, no_export[i],(size_t) (eqp - *atenv)) != 0) ++ ); + } + eqp++; + } +@@ -752,6 +753,102 @@ return p; } @@ -126,8 +103,9 @@ + + if( tm.tm_mday ) + { -+ tm.tm_isdst = tm_now.tm_isdst; -+ return mktime(&tm); ++ tm.tm_isdst = -1; ++ t = mktime(&tm); ++ return t; + } else + return 0L; +} @@ -137,3 +115,136 @@ int main(int argc, char **argv) { +@@ -761,9 +858,9 @@ + char *pgm; + + int program = AT; /* our default program */ +- char *options = "q:f:MmvldhVc"; /* default options for at */ ++ char *options = "q:f:MmvldhVct:"; /* default options for at */ + int disp_version = 0; +- time_t timer; ++ time_t timer=0L; + struct passwd *pwe; + struct group *ge; + +@@ -866,7 +963,9 @@ + program = CAT; + options = ""; + break; +- ++ case 't': ++ timer = t_option(optarg); ++ break; + default: + usage(); + break; +@@ -955,10 +1054,12 @@ + else + queue = DEFAULT_BATCH_QUEUE; + +- if (argc > optind) +- timer = parsetime(argc, argv); +- else +- timer = time(NULL); ++ if( timer == 0L ) { ++ if (argc > optind) ++ timer = parsetime(argc, argv); ++ else ++ timer = time(NULL); ++ } + + if (atverify) { + struct tm *tm = localtime(&timer); +--- at-3.1.10/at.1.in.t_option 2007-06-28 14:43:51.000000000 +0200 ++++ at-3.1.10/at.1.in 2007-06-28 14:43:51.000000000 +0200 +@@ -12,6 +12,16 @@ + .RB [ -mldbv ] + .B TIME + .br ++.B at ++.RB [ -V ] ++.RB [ -q ++.IR queue ] ++.RB [ -f ++.IR file ] ++.RB [ -mldbv ] ++.RB -t ++.IR time_arg ++.br + .B "at -c" + .I job + .RI [ job... ] +@@ -32,8 +42,7 @@ + and + .B batch + read commands from standard input or a specified file which are to +-be executed at a later time, using +-.BR /bin/sh . ++be executed at a later time. + .TP 8 + .BR at + executes commands at a specified time. +@@ -227,6 +236,63 @@ + .B + \-c + cats the jobs listed on the command line to standard output. ++.TP ++.BI \-t " time_arg" ++Submit the job to be run at the time specified by the ++.BI time_arg ++option argument, which must have the same format as specified for the ++.BR touch(1) ++utility's ++.B \-t ++time option argument ([[CC]YY]MMDDhhmm). ++.SH ENVIRONMENT ++.P ++.TP 8 ++.B SHELL ++The value of the SHELL environment variable at the time of ++.B at ++invocation will determine which shell is used to execute the ++.B at ++job commands. If SHELL is unset when ++.B at ++is invoked, the user's login shell will be used; otherwise, ++if SHELL is set when ++.B at ++is invoked, it must contain the path of a shell interpreter ++executable that will be used to run the commands at the specified time. ++.P ++.B at ++will record the values of ++environment variables present at time of ++.B at ++invocation. When the commands are run at the specified time, ++.B at ++will restore these variables to their recorded values . ++These variables are excluded from this processing and are never ++set by ++.B at ++when the commands are run : ++.br ++.BI TERM, ++.BI DISPLAY, ++.BI SHELLOPTS, ++.BI _, ++.BI PPID, ++.BI BASH_VERSINFO, ++.BI EUID, ++.BI UID, ++.BI GROUPS. ++.br ++If the user submitting the ++.B at ++job is not the super-user, variables that alter the behaviour of the ++loader ++.BR ld.so(8), ++such as ++.B LD_LIBRARY_PATH ++, cannot be recorded and restored by ++.B at . ++.P + .SH FILES + .I @ATJBD@ + .br diff --git a/at.spec b/at.spec index e4400b7..e2ebd25 100644 --- a/at.spec +++ b/at.spec @@ -6,7 +6,7 @@ Summary: Job spooling tools Name: at Version: 3.1.10 -Release: 11%{?dist} +Release: 12%{?dist} License: GPL Group: System Environment/Daemons URL: http://ftp.debian.org/debian/pool/main/a/at @@ -14,25 +14,17 @@ Source: http://ftp.debian.org/debian/pool/main/a/at/at_%{major_ver}.tar.gz Source1: test.pl Source2: atd.init Patch0: at-3.1.7-lockfile.patch -Patch1: at-3.1.10-man-timespec-path.patch -Patch2: at-3.1.7-sigchld.patch -Patch3: at-3.1.10-typo.patch -Patch4: at-3.1.10-lexer-parser.patch -Patch5: at-3.1.8-test.patch -Patch6: at-3.1.8-perr.patch -Patch7: at-3.1.10-instinet.patch -Patch8: at-3.1.10-shell.patch -Patch9: at-3.1.10-pie.patch -Patch10: at-3.1.8-t_option.patch -Patch11: at-3.1.10-usage.patch -Patch12: at-3.1.10-fix_no_export.patch -Patch13: at-3.1.10-pam.patch -Patch14: at-3.1.10-dont_fork.patch -Patch15: at-3.1.10-makefile.patch -Patch16: at-3.1.10-daylight.patch -Patch17: at-3.1.10-perm.patch -Patch18: at-3.1.10-newpam.patch -Patch19: at-3.1.10-debug.patch +Patch1: at-3.1.10-makefile.patch +Patch2: at-3.1.10-man-timespec-path.patch +Patch3: at-3.1.7-sigchld.patch +Patch4: at-3.1.10-typo.patch +Patch7: at-3.1.8-perr.patch +#Patch8: at-3.1.8-instinet.patch +Patch9: at-3.1.10-shell.patch +Patch11: at-3.1.8-t_option.patch +Patch14: at-3.1.10-pam.patch +Patch15: at-3.1.10-dont_fork.patch +Patch21: at-3.1.10-perm.patch BuildRequires: fileutils chkconfig /etc/init.d BuildRequires: flex bison autoconf @@ -67,25 +59,17 @@ use crontab instead. cp %{SOURCE1} . %patch0 -p1 -b .lockfile -%patch1 -p1 -b .paths -%patch2 -p1 -b .sigchld -%patch3 -p1 -b .typo -%patch4 -p1 -b .lexer -%patch5 -p1 -b .test -%patch6 -p1 -b .perr -%patch7 -p1 -b .instinet -%patch8 -p1 -b .shell -%patch9 -p1 -b .pie -%patch10 -p1 -b .t_option -%patch11 -p1 -b .usage -%patch12 -p1 -b .fix_no_export -%patch13 -p1 -b .pam -%patch14 -p1 -b .dont_fork -%patch15 -p1 -b .makefile -%patch16 -p1 -b .daylight -%patch17 -p1 -b .perm -%patch18 -p1 -b .newpam -%patch19 -p1 -b .debug +%patch1 -p1 -b .make +%patch2 -p1 -b .paths +%patch3 -p1 -b .sigchld +%patch4 -p1 -b .typo +%patch7 -p1 -b .perr +#%patch8 -p1 -b .instinet #unlink unsucessful jobs, removed -> atd crash +%patch9 -p1 -b .shell +%patch11 -p1 -b .t_option +%patch14 -p1 -b .pam +%patch15 -p1 -b .dont_fork +%patch21 -p1 -b .perm %build # patch10 touches configure.in @@ -104,10 +88,10 @@ rm -f lex.yy.* y.tab.* make %check -# don't run "make test" by default -%{?_without_check: %define _without_check 1} -%{!?_without_check: %define _without_check 1} - +# don't run "make test" by default +%{?_without_check: %define _without_check 1} +%{!?_without_check: %define _without_check 1} + %if ! %{_without_check} LANG=C make test > /dev/null %endif @@ -115,6 +99,7 @@ make %install make install \ DAEMON_USERNAME=`id -nu`\ + DAEMON_GROUPNAME=`id -ng` \ DESTDIR=%{buildroot}\ sbindir=%{buildroot}%{_prefix}/sbin\ bindir=%{buildroot}%{_bindir}\ @@ -122,7 +107,6 @@ make install \ exec_prefix=%{buildroot}%{_prefix}\ docdir=%{buildroot}/usr/doc\ mandir=%{buildroot}%{_mandir}\ - DAEMON_GROUPNAME=`id -ng` \ etcdir=%{buildroot}%{_sysconfdir} \ ATJOB_DIR=%{buildroot}%{_localstatedir}/spool/at \ ATSPOOL_DIR=%{buildroot}%{_localstatedir}/spool/at/spool \ @@ -150,6 +134,7 @@ rm -rf %{buildroot} %post touch %{_localstatedir}/spool/at/.SEQ +chmod 600 %{_localstatedir}/spool/at/.SEQ chown daemon:daemon %{_localstatedir}/spool/at/.SEQ /sbin/chkconfig --add atd @@ -168,11 +153,11 @@ fi %defattr(-,root,root,-) %doc docs/* %config(noreplace) %{_sysconfdir}/at.deny -%attr(0755,root,root) %{_sysconfdir}/rc.d/init.d/atd +%attr(0700,root,root) %{_sysconfdir}/rc.d/init.d/atd %attr(0700,daemon,daemon) %dir %{_localstatedir}/spool/at %attr(0600,daemon,daemon) %verify(not md5 size mtime) %ghost %{_localstatedir}/spool/at/.SEQ %attr(0700,daemon,daemon) %dir %{_localstatedir}/spool/at/spool -%attr(0644,root,root) %config(noreplace) /etc/pam.d/atd +%attr(0640,root,daemon) %config(noreplace) /etc/pam.d/atd %{_sbindir}/atrun %attr(0755,root,root) %{_sbindir}/atd %{_mandir}/man*/* @@ -182,6 +167,11 @@ fi %attr(4755,root,root) %{_bindir}/at %changelog +* Tue Jul 3 2007 Marcela Maslanova - 3.1.10-12 +- crashing atd +- work only for root, still broken some functions +- Resolves: rhbz#243064 + * Tue Mar 27 2007 Marcela Maslanova - 3.1.10-11 - mistake in pam_atd - rhbz#234120