diff --git a/.fmf/version b/.fmf/version new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/.fmf/version @@ -0,0 +1 @@ +1 diff --git a/.gitignore b/.gitignore index c4d8252..f334ce1 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,15 @@ at_3.1.12.orig.tar.gz /at_3.1.13.orig.tar.gz /at_3.1.14.orig.tar.gz /at_3.1.16.orig.tar.gz +/at_3.1.18.orig.tar.gz +/at_3.1.20.orig.tar.gz +/at_3.1.23.orig.tar.gz +/at_3.1.23.orig.tar.gz.asc +/at_3.2.1.orig.tar.gz +/at_3.2.1.orig.tar.gz.asc +/at_3.2.2.orig.tar.gz +/at_3.2.2.orig.tar.gz.asc +/at_3.2.4.orig.tar.gz +/at_3.2.4.orig.tar.gz.asc +/at_3.2.5.orig.tar.gz +/at_3.2.5.orig.tar.gz.sig diff --git a/at-3.1.14-makefile.patch b/at-3.1.14-makefile.patch deleted file mode 100644 index 816f335..0000000 --- a/at-3.1.14-makefile.patch +++ /dev/null @@ -1,82 +0,0 @@ -diff -up at-3.1.14/Makefile.in.make at-3.1.14/Makefile.in ---- at-3.1.14/Makefile.in.make 2013-09-08 14:43:53.000000000 +0200 -+++ at-3.1.14/Makefile.in 2013-09-19 16:48:03.605192754 +0200 -@@ -67,13 +67,13 @@ LIST = Filelist Filelist.asc - all: at atd atd.service atrun - - at: $(ATOBJECTS) -- $(CC) $(LDFLAGS) -o at $(ATOBJECTS) $(LIBS) $(LEXLIB) -+ $(CC) $(LDFLAGS) -o at -pie $(ATOBJECTS) $(LIBS) $(LEXLIB) $(SELINUXLIB) $(PAMLIB) - rm -f $(CLONES) - $(LN_S) -f at atq - $(LN_S) -f at atrm - - atd: $(RUNOBJECTS) -- $(CC) $(LDFLAGS) -o atd $(RUNOBJECTS) $(LIBS) $(PAMLIB) -+ $(CC) $(LDFLAGS) -o atd -pie $(RUNOBJECTS) $(LIBS) $(SELINUXLIB) $(PAMLIB) - - y.tab.c y.tab.h: parsetime.y - $(YACC) -d parsetime.y -@@ -88,38 +88,41 @@ atrun: atrun.in - 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) -- $(INSTALL) -g root -o root -m 755 -d $(IROOT)$(bindir) -- $(INSTALL) -g root -o root -m 755 -d $(IROOT)$(sbindir) -- $(INSTALL) -g root -o root -m 755 -d $(IROOT)$(docdir) -- $(INSTALL) -g root -o root -m 755 -d $(IROOT)$(atdocdir) -- $(INSTALL) -g $(DAEMON_GROUPNAME) -o $(DAEMON_USERNAME) -m 755 -d $(IROOT)$(ATSPOOL_DIR) $(IROOT)$(ATJOB_DIR) -- chmod 1770 $(IROOT)$(ATSPOOL_DIR) $(IROOT)$(ATJOB_DIR) -+ $(INSTALL) root -m 755 -d $(IROOT)$(etcdir) -+ $(INSTALL) root -m 755 -d $(IROOT)$(bindir) -+ $(INSTALL) root -m 755 -d $(IROOT)$(sbindir) -+ $(INSTALL) root -m 755 -d $(IROOT)$(docdir) -+ $(INSTALL) root -m 755 -d $(IROOT)$(atdocdir) -+ $(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) -- 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 at $(IROOT)$(bindir) -+ 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 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) -- $(INSTALL) -d -o root -g root -m 755 $(IROOT)$(man1dir) -- $(INSTALL) -d -o root -g root -m 755 $(IROOT)$(man5dir) -- $(INSTALL) -d -o root -g root -m 755 $(IROOT)$(man8dir) -- $(INSTALL) -g root -o root -m 755 atd $(IROOT)$(sbindir) -- $(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) -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 -- $(INSTALL) -g root -o root -m 644 atd.8 $(IROOT)$(man8dir)/ -+ $(INSTALL) -m 644 atd.8 $(IROOT)$(man8dir)/ - sed "s,\$${exec_prefix},$(exec_prefix),g" tmpman -- $(INSTALL) -g root -o root -m 644 tmpman $(IROOT)$(man8dir)/atrun.8 -+ $(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 -- $(INSTALL) -g root -o root -m 644 $(DOCS) $(IROOT)$(atdocdir) -+ $(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* diff --git a/at-3.1.14-selinux.patch b/at-3.1.14-selinux.patch deleted file mode 100644 index abee8b4..0000000 --- a/at-3.1.14-selinux.patch +++ /dev/null @@ -1,154 +0,0 @@ -diff -up at-3.1.14/config.h.in.selinux at-3.1.14/config.h.in ---- at-3.1.14/config.h.in.selinux 2013-09-26 15:06:55.177049852 +0200 -+++ at-3.1.14/config.h.in 2013-09-26 15:06:55.180049850 +0200 -@@ -71,6 +71,9 @@ - /* Define if you are building with_pam */ - #undef WITH_PAM - -+/* Define if you are building with_selinux */ -+#undef WITH_SELINUX -+ - /* Define to 1 if you have the `pstat_getdynamic' function. */ - #undef HAVE_PSTAT_GETDYNAMIC - -diff -up at-3.1.14/configure.ac.selinux at-3.1.14/configure.ac ---- at-3.1.14/configure.ac.selinux 2013-09-26 15:06:55.178049851 +0200 -+++ at-3.1.14/configure.ac 2013-09-26 15:06:55.180049850 +0200 -@@ -246,6 +246,14 @@ AC_DEFINE(WITH_PAM), - AC_CHECK_LIB(pam, pam_start, PAMLIB='-lpam -lpam_misc') - AC_SUBST(PAMLIB) - -+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_MSG_CHECKING(groupname to run under) - AC_ARG_WITH(daemon_groupname, - [ --with-daemon_groupname=DAEMON_GROUPNAME Groupname to run under (default daemon) ], -diff -up at-3.1.14/Makefile.in.selinux at-3.1.14/Makefile.in ---- at-3.1.14/Makefile.in.selinux 2013-09-26 15:06:55.175049853 +0200 -+++ at-3.1.14/Makefile.in 2013-09-26 15:06:55.180049850 +0200 -@@ -40,6 +40,7 @@ LIBS = @LIBS@ - LIBOBJS = @LIBOBJS@ - INSTALL = @INSTALL@ - PAMLIB = @PAMLIB@ -+SELINUXLIB = @SELINUXLIB@ - - CLONES = atq atrm - ATOBJECTS = at.o panic.o perm.o posixtm.o y.tab.o lex.yy.o -diff -up at-3.1.14/atd.c.selinux2 at-3.1.14/atd.c ---- at-3.1.14/atd.c.selinux2 2013-12-04 11:27:28.729005384 +0100 -+++ at-3.1.14/atd.c 2013-12-04 11:30:17.709091150 +0100 -@@ -83,6 +83,14 @@ - #include "getloadavg.h" - #endif - -+#ifdef WITH_SELINUX -+#include -+#include -+int selinux_enabled=0; -+#include -+#include -+#endif -+ - #ifndef LOG_ATD - #define LOG_ATD LOG_DAEMON - #endif -@@ -191,6 +199,68 @@ myfork() - #define fork myfork - #endif - -+#ifdef WITH_SELINUX -+static int set_selinux_context(const char *name, const char *filename) { -+ security_context_t user_context=NULL; -+ security_context_t file_context=NULL; -+ struct av_decision avd; -+ int retval=-1; -+ char *seuser=NULL; -+ char *level=NULL; -+ -+ if (getseuserbyname(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", name); -+ } else { -+ syslog(LOG_ERR, "execle: couldn't get security context for user %s\n", name); -+ return -1; -+ } -+ } -+ } -+ -+ /* -+ * 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,name); -+ } else { -+ syslog(LOG_ERR, "Not allowed to set exec context to %s for user %s\n", user_context,name); -+ retval = -1; -+ goto err; -+ } -+ } -+ if (setexeccon(user_context) < 0) { -+ if (security_getenforce()==1) { -+ perr("Could not set exec context to %s for user %s\n", user_context,name); -+ retval = -1; -+ } else { -+ syslog(LOG_ERR, "Could not set exec context to %s for user %s\n", user_context,name); -+ } -+ } -+ err: -+ freecon(user_context); -+ return 0; -+} -+#endif -+ - static void - run_file(const char *filename, uid_t uid, gid_t gid) - { -@@ -419,6 +489,13 @@ run_file(const char *filename, uid_t uid - - nice((tolower((int) queue) - 'a' + 1) * 2); - -+#ifdef WITH_SELINUX -+ if (selinux_enabled > 0) { -+ if (set_selinux_context(pentry->pw_name, filename) < 0) -+ perr("SELinux Failed to set context\n"); -+ } -+#endif -+ - if (initgroups(pentry->pw_name, pentry->pw_gid)) - perr("Cannot initialize the supplementary group access list"); - -@@ -712,6 +789,10 @@ main(int argc, char *argv[]) - 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. - */ diff --git a/at-3.1.14-usePOSIXtimers.patch b/at-3.1.14-usePOSIXtimers.patch deleted file mode 100644 index ebf7d8d..0000000 --- a/at-3.1.14-usePOSIXtimers.patch +++ /dev/null @@ -1,111 +0,0 @@ -diff -up at-3.1.14/atd.c.timers at-3.1.14/atd.c ---- at-3.1.14/atd.c.timers 2013-12-02 11:03:01.250080057 +0100 -+++ at-3.1.14/atd.c 2013-12-02 11:06:15.560243498 +0100 -@@ -831,6 +831,54 @@ run_loop() - return next_job; - } - -+#ifdef HAVE_CLOCK_GETTIME -+timer_t timer; -+struct itimerspec timeout; -+ -+void timer_setup() -+{ -+ struct sigevent sev; -+ -+ sev.sigev_notify = SIGEV_SIGNAL; -+ sev.sigev_signo = SIGHUP; -+ sev.sigev_value.sival_ptr = &timer; -+ -+ memset(&timeout, 0, sizeof(timeout)); -+ -+ if (timer_create(CLOCK_REALTIME, &sev, &timer) < 0) -+ pabort("unable to create timer"); -+} -+ -+time_t atd_gettime() -+{ -+ struct timespec curtime; -+ -+ clock_gettime(CLOCK_REALTIME, &curtime); -+ -+ return curtime.tv_sec; -+} -+ -+void atd_setalarm(time_t next) -+{ -+ timeout.it_value.tv_sec = next; -+ timer_settime(timer, TIMER_ABSTIME, &timeout, NULL); -+ pause(); -+} -+#else -+void timer_setup() -+{ -+} -+ -+time_t atd_gettime() -+{ -+ return time(NULL); -+} -+ -+void atd_setalarm(time_t next) -+{ -+ sleep(next - atd_gettime()); -+} -+#endif - /* Global functions */ - - int -@@ -936,7 +984,7 @@ main(int argc, char *argv[]) - sigaction(SIGCHLD, &act, NULL); - - if (!run_as_daemon) { -- now = time(NULL); -+ now = atd_gettime(); - run_loop(); - exit(EXIT_SUCCESS); - } -@@ -959,13 +1007,14 @@ main(int argc, char *argv[]) - act.sa_handler = set_term; - sigaction(SIGINT, &act, NULL); - -+ timer_setup(); - daemon_setup(); - - do { -- now = time(NULL); -+ now = atd_gettime(); - next_invocation = run_loop(); - if (next_invocation > now) { -- sleep(next_invocation - now); -+ atd_setalarm(next_invocation); - } - } while (!term_signal); - daemon_cleanup(); -diff -up at-3.1.14/config.h.in.timers at-3.1.14/config.h.in ---- at-3.1.14/config.h.in.timers 2013-12-02 11:00:27.000000000 +0100 -+++ at-3.1.14/config.h.in 2013-12-02 11:02:06.521033976 +0100 -@@ -38,6 +38,9 @@ - /* Define to 1 if you have the `getloadavg' function. */ - #undef HAVE_GETLOADAVG - -+/* Define to 1 if you have the `clock_gettime' function. */ -+#undef HAVE_TIMER_CREATE -+ - /* Define to 1 if you have the header file. */ - #undef HAVE_GETOPT_H - -diff -up at-3.1.14/configure.ac.timers at-3.1.14/configure.ac ---- at-3.1.14/configure.ac.timers 2013-12-02 11:00:27.000000000 +0100 -+++ at-3.1.14/configure.ac 2013-12-02 11:02:45.217066560 +0100 -@@ -254,6 +254,10 @@ AC_CHECK_LIB(selinux, is_selinux_enabled - AC_SUBST(SELINUXLIB) - AC_SUBST(WITH_SELINUX) - -+dnl check for POSIX timer functions -+AC_SEARCH_LIBS([timer_create],[rt]) -+AC_CHECK_FUNCS([timer_create]) -+ - AC_MSG_CHECKING(groupname to run under) - AC_ARG_WITH(daemon_groupname, - [ --with-daemon_groupname=DAEMON_GROUPNAME Groupname to run under (default daemon) ], diff --git a/at-3.1.16-clear-nonjobs.patch b/at-3.1.16-clear-nonjobs.patch new file mode 100644 index 0000000..05fc2c2 --- /dev/null +++ b/at-3.1.16-clear-nonjobs.patch @@ -0,0 +1,42 @@ +diff -up at-3.1.16/atd.c.clear-nonjobs at-3.1.16/atd.c +--- at-3.1.16/atd.c.clear-nonjobs 2014-12-11 10:32:24.000000000 +0100 ++++ at-3.1.16/atd.c 2015-09-09 11:40:22.544679351 +0200 +@@ -414,10 +414,22 @@ run_file(const char *filename, uid_t uid + sprintf(fmt, "#!/bin/sh\n# atrun uid=%%d gid=%%d\n# mail %%%ds %%d", + mailsize ); + ++ /* Unlink the file unless there was an error reading it (perhaps ++ * temporary). ++ * If the file has a bogus format there is no reason in trying ++ * to run it again and again. ++ */ + if (fscanf(stream, fmt, +- &nuid, &ngid, mailname, &send_mail) != 4) +- pabort("File %.500s is in wrong format - aborting", +- filename); ++ &nuid, &ngid, mailname, &send_mail) != 4) { ++ if (ferror(stream)) ++ perr("Error reading the job file"); ++ ++ unlink(filename); ++ pabort("File %.500s is in wrong format - aborting", ++ filename); ++ } ++ ++ unlink(filename); + + if (mailname[0] == '-') + pabort("illegal mail name %.300s in job %8lu (%.300s)", mailname, +@@ -427,12 +439,6 @@ run_file(const char *filename, uid_t uid + pabort("Job %8lu (%.500s) - userid %d does not match file uid %d", + jobno, filename, nuid, uid); + +- /* We are now committed to executing this script. Unlink the +- * original. +- */ +- +- unlink(filename); +- + fclose(stream); + if (chdir(ATSPOOL_DIR) < 0) + perr("Cannot chdir to " ATSPOOL_DIR); diff --git a/at-3.1.16-noabort.patch b/at-3.1.16-noabort.patch deleted file mode 100644 index 58ffdd2..0000000 --- a/at-3.1.16-noabort.patch +++ /dev/null @@ -1,157 +0,0 @@ -diff -up at-3.1.16/atd.c.noabort at-3.1.16/atd.c ---- at-3.1.16/atd.c.noabort 2014-10-02 11:08:26.000000000 +0200 -+++ at-3.1.16/atd.c 2014-11-06 16:07:54.851652541 +0100 -@@ -221,7 +221,7 @@ static int set_selinux_context(const cha - security_context_t user_context=NULL; - security_context_t file_context=NULL; - struct av_decision avd; -- int retval=-1; -+ int retval=0; - char *seuser=NULL; - char *level=NULL; - -@@ -230,12 +230,9 @@ static int set_selinux_context(const cha - free(seuser); - free(level); - if (retval) { -- if (security_getenforce()==1) { -- perr("execle: couldn't get security context for user %s\n", name); -- } else { -- syslog(LOG_ERR, "execle: couldn't get security context for user %s\n", name); -- return -1; -- } -+ lerr("execle: couldn't get security context for user %s\n", name); -+ retval = -1; -+ goto err; - } - } - -@@ -246,8 +243,11 @@ static int set_selinux_context(const cha - * 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); -+ if (fgetfilecon(STDIN_FILENO, &file_context) < 0) { -+ lerr("fgetfilecon FAILED %s", filename); -+ retval = -1; -+ goto err; -+ } - - retval = security_compute_av(user_context, - file_context, -@@ -256,25 +256,21 @@ static int set_selinux_context(const cha - &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,name); -- } else { -- syslog(LOG_ERR, "Not allowed to set exec context to %s for user %s\n", user_context,name); -- retval = -1; -- goto err; -- } -+ lerr("Not allowed to set exec context to %s for user %s\n", user_context,name); -+ retval = -1; -+ goto err; - } - if (setexeccon(user_context) < 0) { -- if (security_getenforce()==1) { -- perr("Could not set exec context to %s for user %s\n", user_context,name); -- retval = -1; -- } else { -- syslog(LOG_ERR, "Could not set exec context to %s for user %s\n", user_context,name); -- } -+ lerr("Could not set exec context to %s for user %s\n", user_context,name); -+ retval = -1; -+ goto err; - } - err: -- freecon(user_context); -- return 0; -+ if (retval < 0 && security_getenforce() != 1) -+ retval = 0; -+ if (user_context) -+ freecon(user_context); -+ return retval; - } - #endif - -@@ -347,9 +343,12 @@ run_file(const char *filename, uid_t uid - */ - - pid = fork(); -- if (pid == -1) -- perr("Cannot fork"); -- -+ if (pid == -1) { -+ lerr("Cannot fork for job execution"); -+ free(mailname); -+ free(newname); -+ return; -+ } - else if (pid != 0) { - free(mailname); - free(newname); -@@ -667,15 +666,19 @@ run_loop() - * up. - */ - -- if (stat(".", &buf) == -1) -- perr("Cannot stat " ATJOB_DIR); -+ if (stat(".", &buf) == -1) { -+ lerr("Cannot stat " ATJOB_DIR); -+ return next_job; -+ } - - if (nothing_to_do && buf.st_mtime <= last_chg) - return next_job; - last_chg = buf.st_mtime; - -- if ((spool = opendir(".")) == NULL) -- perr("Cannot read " ATJOB_DIR); -+ if ((spool = opendir(".")) == NULL) { -+ lerr("Cannot read " ATJOB_DIR); -+ return next_job; -+ } - - run_batch = 0; - nothing_to_do = 1; -diff -up at-3.1.16/daemon.c.noabort at-3.1.16/daemon.c ---- at-3.1.16/daemon.c.noabort 2014-09-30 08:29:02.000000000 +0200 -+++ at-3.1.16/daemon.c 2014-11-06 15:37:22.109277583 +0100 -@@ -83,6 +83,22 @@ perr(const char *fmt,...) - } - - void -+lerr(const char *fmt,...) -+{ -+ char buf[1024]; -+ va_list args; -+ -+ va_start(args, fmt); -+ vsnprintf(buf, sizeof(buf), fmt, args); -+ va_end(args); -+ -+ if (daemon_debug) { -+ perror(buf); -+ } else -+ syslog(LOG_ERR, "%s: %m", buf); -+} -+ -+void - pabort(const char *fmt,...) - { - char buf[1024]; -diff -up at-3.1.16/daemon.h.noabort at-3.1.16/daemon.h ---- at-3.1.16/daemon.h.noabort 2014-09-30 08:29:02.000000000 +0200 -+++ at-3.1.16/daemon.h 2014-11-06 15:36:10.461660104 +0100 -@@ -13,5 +13,8 @@ __attribute__((noreturn)) - #endif - perr (const char *fmt, ...); - -+void -+lerr (const char *fmt, ...); -+ - extern int daemon_debug; - extern int daemon_foreground; diff --git a/at-3.1.20-log-jobs.patch b/at-3.1.20-log-jobs.patch new file mode 100644 index 0000000..44cc7d3 --- /dev/null +++ b/at-3.1.20-log-jobs.patch @@ -0,0 +1,14 @@ +diff -up at-3.1.20/atd.c.log-jobs at-3.1.20/atd.c +--- at-3.1.20/atd.c.log-jobs 2018-05-23 15:09:35.158362293 +0200 ++++ at-3.1.20/atd.c 2018-05-23 15:18:39.153965582 +0200 +@@ -376,6 +376,10 @@ run_file(const char *filename, uid_t uid + pabort("Userid %lu not found - aborting job %8lu (%.500s)", + (unsigned long) uid, jobno, filename); + } ++ ++ syslog(LOG_INFO, "Starting job %lu (%.500s) for user '%s' (%lu)", ++ jobno, filename, pentry->pw_name, (unsigned long) uid); ++ + PRIV_START + + stream = fopen(filename, "r"); diff --git a/at-3.1.23-document-n.patch b/at-3.1.23-document-n.patch new file mode 100644 index 0000000..39e77e4 --- /dev/null +++ b/at-3.1.23-document-n.patch @@ -0,0 +1,23 @@ +diff -up at-3.1.23/atd.8.in.document-n at-3.1.23/atd.8.in +--- at-3.1.23/atd.8.in.document-n 2018-08-27 14:49:09.824182482 +0200 ++++ at-3.1.23/atd.8.in 2018-08-27 14:50:34.625518639 +0200 +@@ -9,6 +9,7 @@ atd \- run jobs queued for later executi + .IR batch_interval ] + .RB [ \-d ] + .RB [ \-f ] ++.RB [ \-n ] + .RB [ \-s ] + .SH DESCRIPTION + .B atd +@@ -44,6 +45,11 @@ in the foreground. + Process the at/batch queue only once. + This is primarily of use for compatibility with old versions of + .BR at ; ++.TP ++.B \-n ++Append the hostname of the system to the subject of the e-mails sent by ++.BR atd . ++.TP 8 + .B "atd \-s" + is equivalent to the old + .B atrun diff --git a/at-3.2.2-lock-locks.patch b/at-3.2.2-lock-locks.patch new file mode 100644 index 0000000..5b97d34 --- /dev/null +++ b/at-3.2.2-lock-locks.patch @@ -0,0 +1,108 @@ +diff -ur b/atd.c a/atd.c +--- b/atd.c 2021-04-25 03:31:30.000000000 +0200 ++++ a/atd.c 2021-05-21 13:00:45.135020670 +0200 +@@ -74,6 +74,9 @@ + #include + #endif + ++#include ++#include ++ + /* Local headers */ + + #include "privs.h" +@@ -275,7 +278,7 @@ + * mail to the user. + */ + pid_t pid; +- int fd_out, fd_in; ++ int fd_out, fd_in, fd_std; + char jobbuf[9]; + char *mailname = NULL; + size_t mailsize = 128; +@@ -390,6 +393,10 @@ + + fcntl(fd_in, F_SETFD, fflags & ~FD_CLOEXEC); + ++ if (flock(fd_in, LOCK_EX | LOCK_NB) != 0) ++ perr("Somebody already locked the job %8lu (%.500s) - " ++ "aborting", jobno, filename); ++ + /* + * If the spool directory is mounted via NFS `atd' isn't able to + * read from the job file and will bump out here. The file is +@@ -520,10 +527,7 @@ + PRIV_END + } + /* We're the parent. Let's wait. +- */ +- close(fd_in); +- +- /* We inherited the master's SIGCHLD handler, which does a ++ We inherited the master's SIGCHLD handler, which does a + non-blocking waitpid. So this blocking one will eventually + return with an ECHILD error. + */ +@@ -548,14 +552,14 @@ + /* some sendmail implementations are confused if stdout, stderr are + * not available, so let them point to /dev/null + */ +- if ((fd_in = open("/dev/null", O_WRONLY)) < 0) ++ if ((fd_std = open("/dev/null", O_WRONLY)) < 0) + perr("Could not open /dev/null."); +- if (dup2(fd_in, STDOUT_FILENO) < 0) ++ if (dup2(fd_std, STDOUT_FILENO) < 0) + perr("Could not use /dev/null as standard output."); +- if (dup2(fd_in, STDERR_FILENO) < 0) ++ if (dup2(fd_std, STDERR_FILENO) < 0) + perr("Could not use /dev/null as standard error."); +- if (fd_in != STDOUT_FILENO && fd_in != STDERR_FILENO) +- close(fd_in); ++ if (fd_std != STDOUT_FILENO && fd_std != STDERR_FILENO) ++ close(fd_std); + + if (unlink(filename) == -1) + syslog(LOG_WARNING, "Warning: removing output file for job %li failed: %s", +@@ -563,7 +567,12 @@ + + /* The job is now finished. We can delete its input file. + */ +- chdir(ATJOB_DIR); ++ if (chdir(ATJOB_DIR) != 0) ++ perr("Somebody removed %s directory from under us.", ATJOB_DIR); ++ ++ /* This also removes the flock */ ++ (void)close(fd_in); ++ + unlink(newname); + free(newname); + +@@ -673,16 +682,18 @@ + + /* Skip lock files */ + if (queue == '=') { +- /* FIXME: calhariz */ +- /* I think the following code is broken, but commenting it +- may cause unknow side effects. Make a release and see +- in the wild how it works. For more information see: +- https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=818508 */ +- +- /* if ((buf.st_nlink == 1) && (run_time + CHECK_INTERVAL <= now)) { */ +- /* /\* Remove stale lockfile FIXME: lock the lockfile, if you fail, it's still in use. *\/ */ +- /* unlink(dirent->d_name); */ +- /* } */ ++ if ((buf.st_nlink == 1) && (run_time + CHECK_INTERVAL <= now)) { ++ int fd; ++ ++ fd = open(dirent->d_name, O_RDONLY); ++ if (fd != -1) { ++ if (flock(fd, LOCK_EX | LOCK_NB) == 0) { ++ unlink(dirent->d_name); ++ syslog(LOG_NOTICE, "removing stale lock file %s\n", dirent->d_name); ++ } ++ (void)close(fd); ++ } ++ } + continue; + } + /* Skip any other file types which may have been invented in diff --git a/at-3.1.14-shell.patch b/at-3.2.2-shell.patch similarity index 66% rename from at-3.1.14-shell.patch rename to at-3.2.2-shell.patch index 49f66f1..9e383b8 100644 --- a/at-3.1.14-shell.patch +++ b/at-3.2.2-shell.patch @@ -1,19 +1,19 @@ -diff -up at-3.1.14/at.c.shell at-3.1.14/at.c ---- at-3.1.14/at.c.shell 2014-01-06 17:58:17.555564746 +0100 -+++ at-3.1.14/at.c 2014-01-06 17:59:17.699720002 +0100 +diff -ur b/at.c a/at.c +--- b/at.c 2021-04-25 03:31:30.000000000 +0200 ++++ a/at.c 2021-05-21 12:51:48.123335137 +0200 @@ -62,11 +62,8 @@ #include #include - + -#ifdef TM_IN_SYS_TIME #include -#else #include -#endif - + #ifdef HAVE_UNISTD_H #include -@@ -239,6 +236,12 @@ writefile(time_t runtimer, char queue) +@@ -245,6 +242,12 @@ int kill_errno; int rc; int mailsize = 128; @@ -23,25 +23,26 @@ diff -up at-3.1.14/at.c.shell at-3.1.14/at.c + + gettimeofday(&tv, &tz); + srandom(getpid()+tv.tv_usec); - + /* Install the signal handler for SIGINT; terminate after removing the * spool file if necessary -@@ -449,6 +452,9 @@ writefile(time_t runtimer, char queue) +@@ -492,6 +495,9 @@ fprintf(fp, " || {\n\t echo 'Execution directory " "inaccessible' >&2\n\t exit 1\n}\n"); - + + i = random(); + fprintf(fp, "${SHELL:-/bin/sh} << \'marcinDELIMITER%08lx\'\n", i); + istty = isatty(fileno(stdin)); if (istty) { - fprintf(stderr, "at> "); -@@ -464,7 +470,7 @@ writefile(time_t runtimer, char queue) + runtime = localtime(&runtimer); +@@ -512,7 +518,7 @@ if (istty) { fprintf(stderr, "\n"); } - fprintf(fp, "\n"); -+ fprintf(fp, "marcinDELIMITER%08lx\n", i); ++ fprintf(fp, "\nmarcinDELIMITER%08lx\n", i); if (ferror(fp)) panic("Output error"); - + fflush(fp); +Only in a: .vscode diff --git a/at-3.1.14-wrong_format.patch b/at-3.2.5-aborted-jobs.patch similarity index 56% rename from at-3.1.14-wrong_format.patch rename to at-3.2.5-aborted-jobs.patch index b2a5ef4..568ef4b 100644 --- a/at-3.1.14-wrong_format.patch +++ b/at-3.2.5-aborted-jobs.patch @@ -1,23 +1,22 @@ -diff -up at-3.1.14/atd.c.seg at-3.1.14/atd.c ---- at-3.1.14/atd.c.seg 2013-12-02 14:33:48.650769756 +0100 -+++ at-3.1.14/atd.c 2013-12-02 14:52:49.057437721 +0100 -@@ -752,14 +752,17 @@ run_loop() +diff -ur b/atd.c a/atd.c +--- b/atd.c 2022-02-22 15:55:28.745663105 +0100 ++++ a/atd.c 2022-02-22 16:07:26.416578085 +0100 +@@ -722,12 +722,18 @@ /* Is the file already locked? */ if (buf.st_nlink > 1) { -- if (run_time + CHECK_INTERVAL <= now) { -- -+ if (buf.st_mtime + CHECK_INTERVAL <= now) { ++ if (run_time < buf.st_mtime) ++ run_time = buf.st_mtime; + if (run_time + CHECK_INTERVAL <= now) { + /* Something went wrong the last time this was executed. * Let's remove the lockfile and reschedule. + * We also change the timestamp to avoid rerunning the job more + * than once every CHECK_INTERVAL. */ strncpy(lock_name, dirent->d_name, sizeof(lock_name)); - lock_name[sizeof(lock_name)-1] = '\0'; - lock_name[0] = '='; + if (utime(lock_name, 0) < 0) + syslog(LOG_ERR, "utime couldn't be set for lock file %s\n", lock_name); + lock_name[sizeof(lock_name)-1] = '\0'; + lock_name[0] = '='; unlink(lock_name); - next_job = now; - nothing_to_do = 0; diff --git a/at-3.2.5-address-sast.patch b/at-3.2.5-address-sast.patch new file mode 100644 index 0000000..ecf981c --- /dev/null +++ b/at-3.2.5-address-sast.patch @@ -0,0 +1,57 @@ +From 43e8b5b5dd72bb9a80679dec8c15a24f00888a53 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Stan=C4=9Bk?= +Date: Wed, 26 Jun 2024 16:59:31 +0200 +Subject: [PATCH] Address issues from static analyzer +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +- Tweak types in run_file() to prevent overflow +- Initialize all members of of struct tm in posix_time_parse(). + +The static analyzer findings: https://issues.redhat.com/browse/RHEL-44999 + +Signed-off-by: Jan Staněk +--- + atd.c | 4 ++-- + posixtm.c | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/atd.c b/atd.c +index 64fdd83..3908de3 100644 +--- a/atd.c ++++ b/atd.c +@@ -279,7 +279,7 @@ run_file(const char *filename, uid_t uid, gid_t gid) + int fd_out, fd_in; + char jobbuf[9]; + char *mailname = NULL; +- int mailsize = 128; ++ size_t mailsize = 128; + char *newname; + FILE *stream; + int send_mail = 0; +@@ -292,7 +292,7 @@ run_file(const char *filename, uid_t uid, gid_t gid) + char queue; + char fmt[64]; + unsigned long jobno; +- int rc; ++ long rc; + #ifdef HAVE_PAM + int retcode; + #endif +diff --git a/posixtm.c b/posixtm.c +index cf4ec09..06b22fa 100644 +--- a/posixtm.c ++++ b/posixtm.c +@@ -188,7 +188,7 @@ posix_time_parse (struct tm *tm, const char *s, unsigned int syntax_bits) + bool + posixtime (time_t *p, const char *s, unsigned int syntax_bits) + { +- struct tm tm0; ++ struct tm tm0 = {0}; + struct tm tm1; + struct tm const *tm; + time_t t; +-- +GitLab + diff --git a/at-3.1.14-mailwithhostname.patch b/at-3.2.5-mailwithhostname.patch similarity index 67% rename from at-3.1.14-mailwithhostname.patch rename to at-3.2.5-mailwithhostname.patch index a2b3f79..a601db4 100644 --- a/at-3.1.14-mailwithhostname.patch +++ b/at-3.2.5-mailwithhostname.patch @@ -1,7 +1,7 @@ -diff -up at-3.1.14/atd.c.mail at-3.1.14/atd.c ---- at-3.1.14/atd.c.mail 2013-12-04 11:39:44.556239282 +0100 -+++ at-3.1.14/atd.c 2013-12-04 11:40:50.544234246 +0100 -@@ -100,6 +100,10 @@ int selinux_enabled=0; +diff -ur b/atd.c a/atd.c +--- b/atd.c 2022-02-22 15:21:06.649147600 +0100 ++++ a/atd.c 2022-02-22 15:49:13.640184845 +0100 +@@ -98,6 +98,10 @@ #define BATCH_INTERVAL_DEFAULT 60 #define CHECK_INTERVAL 3600 @@ -12,35 +12,35 @@ diff -up at-3.1.14/atd.c.mail at-3.1.14/atd.c /* Global variables */ uid_t real_uid, effective_uid; -@@ -117,6 +121,7 @@ static time_t last_chg; - static int nothing_to_do; +@@ -115,6 +119,7 @@ + static int nothing_to_do = 0; unsigned int batch_interval; static int run_as_daemon = 0; +static int mail_with_hostname = 0; + static int hupped = 0; static volatile sig_atomic_t term_signal = 0; - -@@ -298,6 +303,7 @@ run_file(const char *filename, uid_t uid +@@ -301,6 +306,7 @@ char fmt[64]; unsigned long jobno; - int rc; + long rc; + char hostbuf[MAXHOSTNAMELEN]; #ifdef WITH_PAM int retcode; #endif -@@ -452,6 +458,11 @@ run_file(const char *filename, uid_t uid +@@ -455,6 +461,11 @@ write_string(fd_out, "Subject: Output from your job "); write_string(fd_out, jobbuf); + if (mail_with_hostname > 0) { -+ gethostname(hostbuf, MAXHOSTNAMELEN-1); ++ gethostname(hostbuf, MAXHOSTNAMELEN-1); + write_string(fd_out, " "); + write_string(fd_out, hostbuf); + } write_string(fd_out, "\nTo: "); write_string(fd_out, mailname); write_string(fd_out, "\n\n"); -@@ -843,7 +854,7 @@ main(int argc, char *argv[]) +@@ -905,7 +916,7 @@ run_as_daemon = 1; batch_interval = BATCH_INTERVAL_DEFAULT; @@ -49,7 +49,7 @@ diff -up at-3.1.14/atd.c.mail at-3.1.14/atd.c switch (c) { case 'l': if (sscanf(optarg, "%lf", &load_avg) != 1) -@@ -865,6 +876,10 @@ main(int argc, char *argv[]) +@@ -927,6 +938,10 @@ daemon_foreground++; break; diff --git a/at-3.2.5-make.patch b/at-3.2.5-make.patch new file mode 100644 index 0000000..e8ebcc2 --- /dev/null +++ b/at-3.2.5-make.patch @@ -0,0 +1,86 @@ +diff -ur b/Makefile.in a/Makefile.in +--- b/Makefile.in 2022-02-05 11:00:57.000000000 +0100 ++++ a/Makefile.in 2022-03-08 16:05:28.088069816 +0100 +@@ -76,13 +76,13 @@ + all: at atd atd.service atrun + + at: $(ATOBJECTS) +- $(CC) $(LDFLAGS) -o at $(ATOBJECTS) $(LIBS) $(LEXLIB) ++ $(CC) $(LDFLAGS) -pie -o at $(ATOBJECTS) $(LIBS) $(LEXLIB) + rm -f $(CLONES) + $(LN_S) -f at atq + $(LN_S) -f at atrm + + atd: $(RUNOBJECTS) +- $(CC) $(LDFLAGS) -o atd $(RUNOBJECTS) $(LIBS) $(PAMLIB) $(SELINUXLIB) ++ $(CC) $(LDFLAGS) -pie -o atd $(RUNOBJECTS) $(LIBS) $(PAMLIB) $(SELINUXLIB) + + y.tab.c y.tab.h: parsetime.y + $(YACC) -d parsetime.y +@@ -99,40 +99,43 @@ + configure + + .c.o: +- $(CC) -c $(CFLAGS) $(DEFS) $*.c ++ $(CC) -c $(CFLAGS) -fPIE $(DEFS) $*.c + + install: all +- $(INSTALL) -g root -o root -m 755 -d $(DESTDIR)$(etcdir) +- $(INSTALL) -g root -o root -m 755 -d $(DESTDIR)$(bindir) +- $(INSTALL) -g root -o root -m 755 -d $(DESTDIR)$(sbindir) +- $(INSTALL) -g root -o root -m 755 -d $(DESTDIR)$(atdatadir) +- $(INSTALL) -g root -o root -m 755 -d $(DESTDIR)$(docdir) +- $(INSTALL) -g root -o root -m 755 -d $(DESTDIR)$(atdocdir) +- $(INSTALL) -g $(DAEMON_GROUPNAME) -o $(DAEMON_USERNAME) -m 755 -d $(DESTDIR)$(ATSPOOL_DIR) $(DESTDIR)$(ATJOB_DIR) +- chmod 1770 $(DESTDIR)$(ATSPOOL_DIR) $(DESTDIR)$(ATJOB_DIR) ++ $(INSTALL) -m 755 -d $(DESTDIR)$(etcdir) ++ $(INSTALL) -m 755 -d $(DESTDIR)$(bindir) ++ $(INSTALL) -m 755 -d $(DESTDIR)$(sbindir) ++ $(INSTALL) -m 755 -d $(DESTDIR)$(atdatadir) ++ $(INSTALL) -m 755 -d $(DESTDIR)$(docdir) ++ $(INSTALL) -m 755 -d $(DESTDIR)$(atdocdir) ++ $(INSTALL) -m 755 -d $(DESTDIR)$(etcdir)/pam.d/ ++ $(INSTALL) -g $(DAEMON_GROUPNAME) -o $(DAEMON_USERNAME) -m 755 -d $(DESTDIR)$(ATSPOOL_DIR) ++ chmod 700 $(DESTDIR)$(ATJOB_DIR) $(DESTDIR)$(ATSPOOL_DIR) ++ chown $(DAEMON_USERNAME):$(DAEMON_GROUPNAME) $(DESTDIR)$(ATJOB_DIR) $(DESTDIR)$(ATSPOOL_DIR) + touch $(DESTDIR)$(LFILE) + chmod 600 $(DESTDIR)$(LFILE) + chown $(DAEMON_USERNAME):$(DAEMON_GROUPNAME) $(DESTDIR)$(LFILE) +- test -f $(DESTDIR)$(etcdir)/at.allow || test -f $(DESTDIR)$(etcdir)/at.deny || $(INSTALL) -o root -g $(DAEMON_GROUPNAME) -m 640 at.deny $(DESTDIR)$(etcdir)/ +- $(INSTALL) -g $(DAEMON_GROUPNAME) -o $(DAEMON_USERNAME) -m 6755 at $(DESTDIR)$(bindir) ++ test -f $(DESTDIR)$(etcdir)/at.allow || test -f $(DESTDIR)$(etcdir)/at.deny || $(INSTALL) -m 600 at.deny $(DESTDIR)$(etcdir)/ ++ $(INSTALL) -o $(INSTALL_ROOT_USER) -g $(DAEMON_GROUPNAME) pam_atd $(DESTDIR)$(etcdir)/pam.d/atd ++ $(INSTALL) -m 4755 at $(DESTDIR)$(bindir) + $(LN_S) -f at $(DESTDIR)$(bindir)/atq + $(LN_S) -f at $(DESTDIR)$(bindir)/atrm +- $(INSTALL) -g root -o root -m 755 batch $(DESTDIR)$(bindir) +- $(INSTALL) -g root -o root -m 755 batch-job $(DESTDIR)$(atdatadir) +- $(INSTALL) -d -o root -g root -m 755 $(DESTDIR)$(man1dir) +- $(INSTALL) -d -o root -g root -m 755 $(DESTDIR)$(man5dir) +- $(INSTALL) -d -o root -g root -m 755 $(DESTDIR)$(man8dir) +- $(INSTALL) -g root -o root -m 755 atd $(DESTDIR)$(sbindir) +- $(INSTALL) -g root -o root -m 755 atrun $(DESTDIR)$(sbindir) +- $(INSTALL) -g root -o root -m 644 at.1 $(DESTDIR)$(man1dir)/ ++ $(INSTALL) -m 755 batch $(DESTDIR)$(bindir) ++ $(INSTALL) -m 755 batch-job $(DESTDIR)$(atdatadir) ++ $(INSTALL) -d -m 755 $(DESTDIR)$(man1dir) ++ $(INSTALL) -d -m 755 $(DESTDIR)$(man5dir) ++ $(INSTALL) -d -m 755 $(DESTDIR)$(man8dir) ++ $(INSTALL) -m 755 atd $(DESTDIR)$(sbindir) ++ $(INSTALL) -m 755 atrun $(DESTDIR)$(sbindir) ++ $(INSTALL) -m 644 at.1 $(DESTDIR)$(man1dir)/ + cd $(DESTDIR)$(man1dir) && $(LN_S) -f at.1 atq.1 && $(LN_S) -f at.1 batch.1 && $(LN_S) -f at.1 atrm.1 +- $(INSTALL) -g root -o root -m 644 atd.8 $(DESTDIR)$(man8dir)/ ++ $(INSTALL) -m 644 atd.8 $(DESTDIR)$(man8dir)/ + sed "s,\$${exec_prefix},$(exec_prefix),g" tmpman +- $(INSTALL) -g root -o root -m 644 tmpman $(DESTDIR)$(man8dir)/atrun.8 ++ $(INSTALL) -m 644 tmpman $(DESTDIR)$(man8dir)/atrun.8 + rm -f tmpman +- $(INSTALL) -g root -o root -m 644 at.allow.5 $(DESTDIR)$(man5dir)/ ++ $(INSTALL) -m 644 at.allow.5 $(DESTDIR)$(man5dir)/ + cd $(DESTDIR)$(man5dir) && $(LN_S) -f at.allow.5 at.deny.5 +- $(INSTALL) -g root -o root -m 644 $(DOCS) $(DESTDIR)$(atdocdir) ++ $(INSTALL) -m 644 $(DOCS) $(DESTDIR)$(atdocdir) + rm -f $(DESTDIR)$(mandir)/cat1/at.1* $(DESTDIR)$(mandir)/cat1/batch.1* \ + $(DESTDIR)$(mandir)/cat1/atq.1* + rm -f $(DESTDIR)$(mandir)/cat1/atd.8* diff --git a/at-3.1.14-nitpicks.patch b/at-3.2.5-nitpicks.patch similarity index 66% rename from at-3.1.14-nitpicks.patch rename to at-3.2.5-nitpicks.patch index 6ad8e7a..3765552 100644 --- a/at-3.1.14-nitpicks.patch +++ b/at-3.2.5-nitpicks.patch @@ -1,7 +1,7 @@ -diff -up at-3.1.14/at.1.in.nit at-3.1.14/at.1.in ---- at-3.1.14/at.1.in.nit 2013-09-08 14:43:53.000000000 +0200 -+++ at-3.1.14/at.1.in 2013-12-04 11:36:29.737279969 +0100 -@@ -204,7 +204,7 @@ queue for +diff -ur b/at.1.in a/at.1.in +--- b/at.1.in 2022-01-29 17:42:19.000000000 +0100 ++++ a/at.1.in 2022-02-22 15:19:47.598996428 +0100 +@@ -226,7 +226,7 @@ .BR batch . Queues with higher letters run with increased niceness. The special queue "=" is reserved for jobs which are currently running. @@ -10,10 +10,10 @@ diff -up at-3.1.14/at.1.in.nit at-3.1.14/at.1.in If a job is submitted to a queue designated with an uppercase letter, the job is treated as if it were submitted to batch at the time of the job. Once the time is reached, the batch processing rules with respect to load -diff -up at-3.1.14/atd.c.nit at-3.1.14/atd.c ---- at-3.1.14/atd.c.nit 2013-12-04 11:36:29.733279967 +0100 -+++ at-3.1.14/atd.c 2013-12-04 11:38:44.551247496 +0100 -@@ -198,6 +198,18 @@ myfork() +diff -ur b/atd.c a/atd.c +--- b/atd.c 2022-02-22 15:14:02.736336912 +0100 ++++ a/atd.c 2022-02-22 15:19:02.163909540 +0100 +@@ -197,6 +197,18 @@ #define fork myfork #endif @@ -31,8 +31,8 @@ diff -up at-3.1.14/atd.c.nit at-3.1.14/atd.c +#endif #ifdef WITH_SELINUX - static int set_selinux_context(const char *name, const char *filename) { -@@ -337,6 +349,9 @@ run_file(const char *filename, uid_t uid + static int +@@ -340,6 +352,9 @@ free(newname); return; } @@ -42,39 +42,39 @@ diff -up at-3.1.14/atd.c.nit at-3.1.14/atd.c /* Let's see who we mail to. Hopefully, we can read it from * the command file; if not, send it to the owner, or, failing that, * to root. -@@ -505,6 +520,9 @@ run_file(const char *filename, uid_t uid +@@ -508,6 +523,9 @@ if (setuid(uid) < 0) perr("Cannot set user id"); -+ if (SIG_ERR == signal(SIGCHLD, SIG_DFL)) ++ if (SIG_ERR == signal(SIGCHLD, SIG_DFL)) + perr("Cannot reset signal handler to default"); + chdir("/"); execle("/bin/sh", "sh", (char *) NULL, nenvp); -@@ -570,6 +588,9 @@ run_file(const char *filename, uid_t uid +@@ -573,6 +591,9 @@ if (setuid(uid) < 0) perr("Cannot set user id"); -+ if (SIG_ERR == signal(SIGCHLD, SIG_DFL)) ++ if (SIG_ERR == signal(SIGCHLD, SIG_DFL)) + perr("Cannot reset signal handler to default"); + chdir ("/"); #if defined(SENDMAIL) -@@ -697,6 +718,7 @@ run_loop() +@@ -707,6 +728,7 @@ * Let's remove the lockfile and reschedule. */ strncpy(lock_name, dirent->d_name, sizeof(lock_name)); -+ lock_name[sizeof(lock_name)-1] = '\0'; ++ lock_name[sizeof(lock_name)-1] = '\0'; lock_name[0] = '='; unlink(lock_name); next_job = now; -@@ -731,6 +753,7 @@ run_loop() +@@ -741,6 +763,7 @@ run_batch++; if (strcmp(batch_name, dirent->d_name) > 0) { strncpy(batch_name, dirent->d_name, sizeof(batch_name)); -+ batch_name[sizeof(batch_name)-1] = '\0'; ++ batch_name[sizeof(batch_name)-1] = '\0'; batch_uid = buf.st_uid; batch_gid = buf.st_gid; batch_queue = queue; diff --git a/at-3.2.5-noabort.patch b/at-3.2.5-noabort.patch new file mode 100644 index 0000000..2d72301 --- /dev/null +++ b/at-3.2.5-noabort.patch @@ -0,0 +1,44 @@ +diff -ur b/atd.c a/atd.c +--- b/atd.c 2022-02-22 16:09:15.683717386 +0100 ++++ a/atd.c 2022-02-22 16:12:48.992989327 +0100 +@@ -344,9 +344,12 @@ + */ + + pid = fork(); +- if (pid == -1) +- perr("Cannot fork"); +- ++ if (pid == -1) { ++ lerr("Cannot fork for job execution"); ++ free(mailname); ++ free(newname); ++ return; ++ } + else if (pid != 0) { + free(mailname); + free(newname); +@@ -659,16 +662,20 @@ + * up. + */ + +- if (stat(".", &buf) == -1) +- perr("Cannot stat " ATJOB_DIR); ++ if (stat(".", &buf) == -1) { ++ lerr("Cannot stat " ATJOB_DIR); ++ return next_job; ++ } + + if (nothing_to_do && buf.st_mtime == last_chg) + return next_job; + last_chg = buf.st_mtime; + + hupped = 0; +- if ((spool = opendir(".")) == NULL) +- perr("Cannot read " ATJOB_DIR); ++ if ((spool = opendir(".")) == NULL) { ++ lerr("Cannot read " ATJOB_DIR); ++ return next_job; ++ } + + run_batch = 0; + nothing_to_do = 1; diff --git a/at-3.1.14-pam.patch b/at-3.2.5-pam.patch similarity index 77% rename from at-3.1.14-pam.patch rename to at-3.2.5-pam.patch index aac72e8..eba2f84 100644 --- a/at-3.1.14-pam.patch +++ b/at-3.2.5-pam.patch @@ -1,7 +1,7 @@ -diff -up at-3.1.14/at.c.pam at-3.1.14/at.c ---- at-3.1.14/at.c.pam 2013-09-08 14:43:53.000000000 +0200 -+++ at-3.1.14/at.c 2013-12-04 11:09:56.165752053 +0100 -@@ -144,18 +144,13 @@ sigc(int signo) +diff -ur b/at.c a/at.c +--- b/at.c 2022-01-29 17:42:19.000000000 +0100 ++++ a/at.c 2022-02-23 18:42:45.941757090 +0100 +@@ -155,18 +155,12 @@ /* If the user presses ^C, remove the spool file and exit */ if (fcreated) { @@ -16,20 +16,19 @@ diff -up at-3.1.14/at.c.pam at-3.1.14/at.c - unlink(atfile); - setregid(effective_gid, real_gid); - /* -+ unlink(atfile); PRIV_END - */ } exit(EXIT_FAILURE); } -@@ -315,26 +310,19 @@ writefile(time_t runtimer, char queue) +@@ -326,26 +320,19 @@ * bit. Yes, this is a kluge. */ cmask = umask(S_IRUSR | S_IWUSR | S_IXUSR); - seteuid(real_uid); + if ((seteuid(effective_uid)) < 0) + perr("Error in seteuid: %s", errno); - if ((fd = open(atfile, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, S_IRUSR)) == -1) + if ((fd = open(atfile, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY | O_SYNC, S_IRUSR)) == -1) perr("Cannot create atjob file %.500s", atfile); - seteuid(effective_uid); @@ -52,7 +51,7 @@ diff -up at-3.1.14/at.c.pam at-3.1.14/at.c /* We've successfully created the file; let's set the flag so it * gets removed in case of an interrupt or error. */ -@@ -654,7 +642,7 @@ process_jobs(int argc, char **argv, int +@@ -733,7 +720,7 @@ We need the unprivileged uid here since the file is owned by the real (not effective) uid. */ @@ -61,7 +60,7 @@ diff -up at-3.1.14/at.c.pam at-3.1.14/at.c if (queue == '=') { fprintf(stderr, "Warning: deleting running job\n"); -@@ -663,8 +651,8 @@ process_jobs(int argc, char **argv, int +@@ -742,8 +729,8 @@ perr("Cannot unlink %.500s", dirent->d_name); rc = EXIT_FAILURE; } @@ -71,7 +70,7 @@ diff -up at-3.1.14/at.c.pam at-3.1.14/at.c done = 1; break; -@@ -674,7 +662,7 @@ process_jobs(int argc, char **argv, int +@@ -753,7 +740,7 @@ FILE *fp; int ch; @@ -80,7 +79,7 @@ diff -up at-3.1.14/at.c.pam at-3.1.14/at.c fp = fopen(dirent->d_name, "r"); if (fp) { -@@ -687,7 +675,7 @@ process_jobs(int argc, char **argv, int +@@ -768,7 +755,7 @@ perr("Cannot open %.500s", dirent->d_name); rc = EXIT_FAILURE; } @@ -89,21 +88,21 @@ diff -up at-3.1.14/at.c.pam at-3.1.14/at.c } break; -diff -up at-3.1.14/atd.c.pam at-3.1.14/atd.c ---- at-3.1.14/atd.c.pam 2013-09-08 14:43:53.000000000 +0200 -+++ at-3.1.14/atd.c 2013-12-04 11:14:31.780617480 +0100 -@@ -83,6 +83,10 @@ - #include "getloadavg.h" - #endif +diff -ur b/atd.c a/atd.c +--- b/atd.c 2022-01-29 17:42:19.000000000 +0100 ++++ a/atd.c 2022-02-23 18:50:53.743511813 +0100 +@@ -91,6 +91,10 @@ + + /* Macros */ +#ifndef LOG_ATD +#define LOG_ATD LOG_DAEMON +#endif + - /* Macros */ - #define BATCH_INTERVAL_DEFAULT 60 -@@ -108,7 +112,7 @@ static int run_as_daemon = 0; + #define CHECK_INTERVAL 3600 + +@@ -115,7 +119,7 @@ static volatile sig_atomic_t term_signal = 0; @@ -112,7 +111,7 @@ diff -up at-3.1.14/atd.c.pam at-3.1.14/atd.c #include static pam_handle_t *pamh = NULL; -@@ -117,15 +121,7 @@ static const struct pam_conv conv = { +@@ -124,15 +128,7 @@ NULL }; @@ -129,16 +128,16 @@ diff -up at-3.1.14/atd.c.pam at-3.1.14/atd.c /* Signal handlers */ RETSIGTYPE -@@ -220,7 +216,7 @@ run_file(const char *filename, uid_t uid +@@ -293,7 +289,7 @@ char fmt[64]; unsigned long jobno; - int rc; + long rc; -#ifdef HAVE_PAM +#ifdef WITH_PAM int retcode; #endif -@@ -377,17 +373,11 @@ run_file(const char *filename, uid_t uid +@@ -450,17 +446,11 @@ fstat(fd_out, &buf); size = buf.st_size; @@ -161,12 +160,12 @@ diff -up at-3.1.14/atd.c.pam at-3.1.14/atd.c #endif close(STDIN_FILENO); -@@ -401,7 +391,14 @@ run_file(const char *filename, uid_t uid - else if (pid == 0) { +@@ -475,6 +465,14 @@ char *nul = NULL; char **nenvp = &nul; -+ char **pam_envp=0L; ++ char **pam_envp=0L; ++ + PRIV_START +#ifdef WITH_PAM + pam_envp = pam_getenvlist(pamh); @@ -176,16 +175,15 @@ diff -up at-3.1.14/atd.c.pam at-3.1.14/atd.c /* Set up things for the child; we want standard input from the * input file, and standard output and error sent to our output file. */ -@@ -420,8 +417,6 @@ run_file(const char *filename, uid_t uid +@@ -493,7 +491,6 @@ close(fd_in); close(fd_out); - PRIV_START -- - nice((tolower((int) queue) - 'a' + 1) * 2); - if (initgroups(pentry->pw_name, pentry->pw_gid)) -@@ -435,9 +430,9 @@ run_file(const char *filename, uid_t uid + nice((tolower((int) queue) - 'a') * 2); + +@@ -515,9 +512,9 @@ chdir("/"); @@ -198,7 +196,7 @@ diff -up at-3.1.14/atd.c.pam at-3.1.14/atd.c PRIV_END } /* We're the parent. Let's wait. -@@ -450,14 +445,6 @@ run_file(const char *filename, uid_t uid +@@ -530,14 +527,6 @@ */ waitpid(pid, (int *) NULL, 0); @@ -213,7 +211,7 @@ diff -up at-3.1.14/atd.c.pam at-3.1.14/atd.c /* Send mail. Unlink the output file after opening it, so it * doesn't hang around after the run. */ -@@ -488,8 +475,13 @@ run_file(const char *filename, uid_t uid +@@ -568,8 +557,13 @@ unlink(newname); free(newname); @@ -227,7 +225,7 @@ diff -up at-3.1.14/atd.c.pam at-3.1.14/atd.c PRIV_START if (initgroups(pentry->pw_name, pentry->pw_gid)) -@@ -511,7 +503,20 @@ run_file(const char *filename, uid_t uid +@@ -591,7 +585,20 @@ perr("Exec failed for mail command"); PRIV_END @@ -236,7 +234,7 @@ diff -up at-3.1.14/atd.c.pam at-3.1.14/atd.c + syslog(LOG_ERR, "fork of mailer failed: %m"); + } + /* Parent */ -+ waitpid(mail_pid, (int *) NULL, 0); ++ waitpid(mail_pid, (int *) NULL, 0); } + +#ifdef WITH_PAM @@ -248,10 +246,10 @@ diff -up at-3.1.14/atd.c.pam at-3.1.14/atd.c exit(EXIT_SUCCESS); } -diff -up at-3.1.14/config.h.in.pam at-3.1.14/config.h.in ---- at-3.1.14/config.h.in.pam 2013-09-08 14:43:53.000000000 +0200 -+++ at-3.1.14/config.h.in 2013-12-04 11:09:56.165752053 +0100 -@@ -68,8 +68,8 @@ +diff -ur b/config.h.in a/config.h.in +--- b/config.h.in 2022-01-29 17:42:19.000000000 +0100 ++++ a/config.h.in 2022-02-23 18:51:31.467570176 +0100 +@@ -74,8 +74,8 @@ /* Define to 1 if you have the header file. */ #undef HAVE_NLIST_H @@ -262,10 +260,10 @@ diff -up at-3.1.14/config.h.in.pam at-3.1.14/config.h.in /* Define to 1 if you have the `pstat_getdynamic' function. */ #undef HAVE_PSTAT_GETDYNAMIC -diff -up at-3.1.14/configure.ac.pam at-3.1.14/configure.ac ---- at-3.1.14/configure.ac.pam 2013-09-08 14:43:53.000000000 +0200 -+++ at-3.1.14/configure.ac 2013-12-04 11:09:56.165752053 +0100 -@@ -78,7 +78,7 @@ AC_FUNC_GETLOADAVG +diff -ur b/configure.ac a/configure.ac +--- b/configure.ac 2022-01-29 17:42:19.000000000 +0100 ++++ a/configure.ac 2022-02-23 18:53:08.516720324 +0100 +@@ -97,7 +97,7 @@ AC_CHECK_FUNCS(getcwd mktime strftime setreuid setresuid sigaction waitpid) AC_CHECK_HEADERS(security/pam_appl.h, [ PAMLIB="-lpam" @@ -274,7 +272,7 @@ diff -up at-3.1.14/configure.ac.pam at-3.1.14/configure.ac ]) dnl Checking for programs -@@ -239,6 +239,13 @@ AC_ARG_WITH(daemon_username, +@@ -260,6 +260,13 @@ ) AC_SUBST(DAEMON_USERNAME) @@ -285,12 +283,24 @@ diff -up at-3.1.14/configure.ac.pam at-3.1.14/configure.ac +AC_CHECK_LIB(pam, pam_start, PAMLIB='-lpam -lpam_misc') +AC_SUBST(PAMLIB) + - AC_MSG_CHECKING(groupname to run under) - AC_ARG_WITH(daemon_groupname, - [ --with-daemon_groupname=DAEMON_GROUPNAME Groupname to run under (default daemon) ], -diff -up at-3.1.14/perm.c.pam at-3.1.14/perm.c ---- at-3.1.14/perm.c.pam 2013-09-08 14:43:53.000000000 +0200 -+++ at-3.1.14/perm.c 2013-12-04 11:09:56.165752053 +0100 + AC_ARG_WITH(selinux, + [ --with-selinux Define to run with selinux (default=check)], + [], +diff -ur b/Makefile.in a/Makefile.in +--- b/Makefile.in 2022-02-23 18:33:26.999892289 +0100 ++++ a/Makefile.in 2022-02-23 18:53:28.600751396 +0100 +@@ -76,7 +76,7 @@ + all: at atd atd.service atrun + + at: $(ATOBJECTS) +- $(CC) $(LDFLAGS) -pie -o at $(ATOBJECTS) $(LIBS) $(LEXLIB) ++ $(CC) $(LDFLAGS) -pie -o at $(ATOBJECTS) $(LIBS) $(LEXLIB) $(PAMLIB) + rm -f $(CLONES) + $(LN_S) -f at atq + $(LN_S) -f at atrm +diff -ur b/perm.c a/perm.c +--- b/perm.c 2022-01-29 17:42:19.000000000 +0100 ++++ a/perm.c 2022-02-23 18:56:21.401018761 +0100 @@ -51,6 +51,14 @@ #define PRIV_END while(0) #endif @@ -306,7 +316,7 @@ diff -up at-3.1.14/perm.c.pam at-3.1.14/perm.c /* Structures and unions */ -@@ -108,18 +116,45 @@ user_in_file(const char *path, const cha +@@ -108,18 +116,45 @@ int check_permission() { @@ -355,10 +365,10 @@ diff -up at-3.1.14/perm.c.pam at-3.1.14/perm.c allow = user_in_file(ETCDIR "/at.allow", pentry->pw_name); if (allow==0 || allow==1) return allow; -diff -up at-3.1.14/privs.h.pam at-3.1.14/privs.h ---- at-3.1.14/privs.h.pam 2013-09-08 14:43:53.000000000 +0200 -+++ at-3.1.14/privs.h 2013-12-04 11:09:56.166752054 +0100 -@@ -144,3 +144,63 @@ extern gid_t real_gid, effective_gid, da +diff -ur b/privs.h a/privs.h +--- b/privs.h 2022-01-29 17:42:19.000000000 +0100 ++++ a/privs.h 2022-02-23 18:58:20.920203690 +0100 +@@ -144,3 +144,62 @@ #error "Cannot implement user ID swapping without setreuid or setresuid" #endif #endif @@ -421,4 +431,3 @@ diff -up at-3.1.14/privs.h.pam at-3.1.14/privs.h +} + +#endif -+ diff --git a/at-3.2.5-past-date.patch b/at-3.2.5-past-date.patch new file mode 100644 index 0000000..6344c40 --- /dev/null +++ b/at-3.2.5-past-date.patch @@ -0,0 +1,33 @@ +From 6c131df8c85cb2761faf551f8f9db179e216fc09 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ond=C5=99ej=20Poho=C5=99elsk=C3=BD?= +Date: Wed, 25 Jun 2025 14:35:31 +0200 +Subject: [PATCH] Reject past dates when using -t option + +-t option was missing validation to reject past dates, unlike the +regular time parsing. + +Add the same past date validation used by parsetime() to the posixtime() +code path to ensure consistent behavior when parsing time. +--- + at.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/at.c b/at.c +index 8d0feaa..3fb0582 100644 +--- a/at.c ++++ b/at.c +@@ -951,6 +951,11 @@ main(int argc, char **argv) + fprintf(stderr, "invalid date format: %s\n", optarg); + exit(EXIT_FAILURE); + } ++ /* Check if the parsed time is in the past */ ++ if (timer < time(NULL)) { ++ fprintf(stderr, "at: refusing to create job destined in the past\n"); ++ exit(EXIT_FAILURE); ++ } + break; + + case 'o': +-- +2.49.0 + diff --git a/at-tmpfiles.conf b/at-tmpfiles.conf new file mode 100644 index 0000000..8eec9a7 --- /dev/null +++ b/at-tmpfiles.conf @@ -0,0 +1,6 @@ +# at - Tmpfiles configuration for at daemon +# Create /var/spool/at directory structure for the at daemon + +d /var/spool/at 0700 root root - - +d /var/spool/at/spool 0700 root root - - +f /var/spool/at/.SEQ 0600 root root - - diff --git a/at.spec b/at.spec index 79105ab..60d9fd4 100644 --- a/at.spec +++ b/at.spec @@ -1,40 +1,45 @@ %bcond_without pam -Summary: Job spooling tools -Name: at -Version: 3.1.16 -Release: 5%{?dist} +Summary: Job spooling tools +Name: at +Version: 3.2.5 +Release: 20%{?dist} # http://packages.debian.org/changelogs/pool/main/a/at/current/copyright # + install-sh is MIT license with changes under Public Domain -License: GPLv3+ and GPLv2+ and ISC and MIT and Public Domain -Group: System Environment/Daemons -URL: http://ftp.debian.org/debian/pool/main/a/at +License: GPL-3.0-or-later AND GPL-2.0-or-later AND ISC +URL: http://ftp.debian.org/debian/pool/main/a/at -Source: http://ftp.debian.org/debian/pool/main/a/at/at_%{version}.orig.tar.gz +Source: http://software.calhariz.com/at/at_%{version}.orig.tar.gz # git upstream source git://git.debian.org/git/collab-maint/at.git -Source1: pam_atd -Source3: atd.sysconf -Source5: atd.systemd +Source1: pam_atd +Source2: at-tmpfiles.conf +Source3: atd.sysconf +Source5: atd.systemd -Patch0: at-aarch64.patch -Patch1: at-3.1.14-makefile.patch -Patch2: at-3.1.14-pam.patch -Patch3: at-3.1.14-selinux.patch -Patch4: at-3.1.14-opt_V.patch -Patch5: at-3.1.14-shell.patch -Patch6: at-3.1.14-nitpicks.patch -Patch8: at-3.1.14-fix_no_export.patch -Patch9: at-3.1.14-mailwithhostname.patch -Patch10: at-3.1.14-usePOSIXtimers.patch -Patch12: at-3.1.14-wrong_format.patch -Patch13: at-3.1.16-noabort.patch -Patch14: at-3.1.16-fclose-error.patch +Patch: at-3.2.5-address-sast.patch +Patch: at-aarch64.patch +Patch: at-3.2.5-make.patch +Patch: at-3.2.5-pam.patch +Patch: at-3.1.14-opt_V.patch +Patch: at-3.2.2-shell.patch +Patch: at-3.2.5-nitpicks.patch +Patch: at-3.1.14-fix_no_export.patch +Patch: at-3.2.5-mailwithhostname.patch +Patch: at-3.2.5-aborted-jobs.patch +Patch: at-3.2.5-noabort.patch +Patch: at-3.1.16-fclose-error.patch +Patch: at-3.1.16-clear-nonjobs.patch +Patch: at-3.2.2-lock-locks.patch +Patch: at-3.1.23-document-n.patch +Patch: at-3.1.20-log-jobs.patch +Patch: at-3.2.5-past-date.patch -BuildRequires: fileutils /etc/init.d +BuildRequires: gcc BuildRequires: flex flex-static bison autoconf BuildRequires: libselinux-devel >= 1.27.9 BuildRequires: perl(Test::Harness) BuildRequires: perl(Test::More) +BuildRequires: systemd-rpm-macros %if %{with pam} BuildRequires: pam-devel @@ -42,6 +47,7 @@ BuildRequires: pam-devel Conflicts: crontabs <= 1.5 # No, I'm not kidding BuildRequires: smtpdaemon +BuildRequires: make Requires(post): systemd-units Requires(preun): systemd-units @@ -62,58 +68,44 @@ need to be repeated at the same time every day/week, etc. you should use crontab instead. %prep -%setup -q +%autosetup -N cp %{SOURCE1} . -%patch0 -p1 -b .arm -%patch1 -p1 -b .make -%patch2 -p1 -b .pam -%patch3 -p1 -b .selinux -%patch4 -p1 -b .opt_V -%patch5 -p1 -b .shell -%patch6 -p1 -b .nit -%patch8 -p1 -b .export -%patch9 -p1 -b .mail -%patch10 -p1 -b .posix -%patch12 -p1 -b .wrong -%patch13 -p1 -b .noabort -%patch14 -p1 -b .fclose +%autopatch -p1 %build -# patch9 touches configure.in -autoconf # uselles files rm -f lex.yy.* y.tab.* + %configure --with-atspool=%{_localstatedir}/spool/at/spool \ - --with-jobdir=%{_localstatedir}/spool/at \ - --with-daemon_username=root \ - --with-daemon_groupname=root \ - --with-selinux \ -%if %{with pam} - --with-pam -%endif + --with-jobdir=%{_localstatedir}/spool/at \ + --with-daemon_username=root \ + --with-daemon_groupname=root \ + --with-selinux \ + %{?with_pam:--with-pam} make %install make install \ - DAEMON_USERNAME=`id -nu`\ - DAEMON_GROUPNAME=`id -ng` \ - DESTDIR=%{buildroot}\ - sbindir=%{buildroot}%{_prefix}/sbin\ - bindir=%{buildroot}%{_bindir}\ - prefix=%{buildroot}%{_prefix}\ - exec_prefix=%{buildroot}%{_prefix}\ - docdir=%{buildroot}/usr/doc\ - mandir=%{buildroot}%{_mandir}\ - etcdir=%{buildroot}%{_sysconfdir} \ - ATJOB_DIR=%{buildroot}%{_localstatedir}/spool/at \ - ATSPOOL_DIR=%{buildroot}%{_localstatedir}/spool/at/spool \ - INSTALL_ROOT_USER=`id -nu` \ - INSTALL_ROOT_GROUP=`id -nu`; + DAEMON_USERNAME=`id -nu` \ + DAEMON_GROUPNAME=`id -ng` \ + DESTDIR=%{buildroot} \ + sbindir=%{_bindir} \ + bindir=%{_bindir} \ + datadir=%{_datadir} \ + prefix=%{_prefix} \ + exec_prefix=%{_prefix} \ + docdir=%{_prefix}/doc \ + mandir=%{_mandir} \ + etcdir=%{_sysconfdir} \ + ATJOB_DIR=%{_localstatedir}/spool/at \ + ATSPOOL_DIR=%{_localstatedir}/spool/at/spool \ + INSTALL_ROOT_USER=`id -nu` \ + INSTALL_ROOT_GROUP=`id -nu`; echo > %{buildroot}%{_sysconfdir}/at.deny mkdir docs -cp %{buildroot}/%{_prefix}/doc/at/* docs/ +cp %{buildroot}%{_prefix}/doc/at/* docs/ mkdir -p %{buildroot}%{_sysconfdir}/pam.d install -m 644 %{SOURCE1} %{buildroot}%{_sysconfdir}/pam.d/atd @@ -125,18 +117,24 @@ install -m 644 %{SOURCE3} %{buildroot}/etc/sysconfig/atd mkdir -p %{buildroot}/%{_unitdir}/ install -m 644 %{SOURCE5} %{buildroot}/%{_unitdir}/atd.service +# install tmpfiles configuration +mkdir -p %{buildroot}%{_tmpfilesdir} +install -m 644 %{SOURCE2} %{buildroot}%{_tmpfilesdir}/at.conf + # remove unpackaged files from the buildroot rm -r %{buildroot}%{_prefix}/doc +# Remove .SEQ file created by make install - tmpfiles will create it +rm -f %{buildroot}%{_localstatedir}/spool/at/.SEQ %check make test %post -touch %{_localstatedir}/spool/at/.SEQ -chmod 600 %{_localstatedir}/spool/at/.SEQ -chown daemon:daemon %{_localstatedir}/spool/at/.SEQ %systemd_post atd.service +# Create directories and files using tmpfiles +%tmpfiles_create at.conf + %preun %systemd_preun atd.service @@ -157,23 +155,187 @@ chown daemon:daemon %{_localstatedir}/spool/at/.SEQ /bin/systemctl daemon-reload >/dev/null 2>&1 || : %files -%doc docs/* -%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/at.deny -%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/sysconfig/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) %{_sysconfdir}/pam.d/atd -%{_sbindir}/atrun -%attr(0755,root,root) %{_sbindir}/atd +%license Copyright COPYING +%doc README timespec ChangeLog +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/at.deny +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/sysconfig/atd +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/pam.d/atd +%attr(0700,root,root) %dir %{_localstatedir}/spool/at +%attr(0700,root,root) %dir %{_localstatedir}/spool/at/spool +%{_tmpfilesdir}/at.conf +%{_bindir}/atrun +%attr(0755,root,root) %{_bindir}/atd %{_mandir}/man*/* %{_bindir}/batch %{_bindir}/atrm %{_bindir}/atq -%attr(4755,root,root) %{_bindir}/at -%attr(0644,root,root) /%{_unitdir}/atd.service +%attr(4755,root,root) %{_bindir}/at +%{_datadir}/at/ +%attr(0644,root,root) /%{_unitdir}/atd.service %changelog +* Fri Jan 16 2026 Fedora Release Engineering - 3.2.5-20 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild + +* Thu Sep 18 2025 Ondřej Pohořelský - 3.2.5-19 +- Add /var/spool/at and /var/spool/at/spool directories into %%files section +- Resolves: rhbz#2396330 + +* Wed Aug 27 2025 Ondřej Pohořelský - 3.2.5-18 +- Use systemd-tmpfiles for /var/spool/at directories + +* Wed Jul 23 2025 Fedora Release Engineering - 3.2.5-17 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + +* Wed Jun 25 2025 Ondřej Pohořelský - 3.2.5-16 +- Fix past date handling with -t option + +* Mon May 05 2025 Ondřej Pohořelský - 3.2.5-15 +- Claim ownership of /usr/share/at +- Resolves: rhbz#2283298 + +* Mon Jan 27 2025 Ondřej Pohořelský - 3.2.5-14 +- Unify bin and sbin directories +- Resolves: rhbz#2339910 + +* Thu Jan 16 2025 Fedora Release Engineering - 3.2.5-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + +* Thu Aug 8 2024 Ales Nezbeda - 3.2.5-12 +- Backport fixes from upstream PR +- https://salsa.debian.org/debian/at/-/merge_requests/34 + +* Wed Jul 17 2024 Fedora Release Engineering - 3.2.5-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + +* Thu May 02 2024 Ondřej Pohořelský - 3.2.5-10 +- Corrected document-n patch +- Resolves: rhbz#2276918 + +* Mon Jan 22 2024 Fedora Release Engineering - 3.2.5-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Fri Jan 19 2024 Fedora Release Engineering - 3.2.5-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Wed Jul 19 2023 Fedora Release Engineering - 3.2.5-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + +* Mon Jun 26 2023 Ondřej Pohořelský - 3.2.5-6 +- Convert licenses to SPDX format +- Dropped MIT and Public Domain license as they are not present in upstream sources + +* Wed Jan 18 2023 Fedora Release Engineering - 3.2.5-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Wed Jul 20 2022 Fedora Release Engineering - 3.2.5-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Thu Mar 31 2022 Jan Staněk - 3.2.5-3 +- Add preceding newline to delimiter in at-3.2.2-shell.patch + +* Tue Mar 08 2022 Ondřej Pohořelský - 3.2.5-2 +- Add mising directory and batch-job script into at-3.2.5-make.patch +- Defined datadir in %%install section and listed batch-job in %%files section + +* Tue Mar 01 2022 Ondřej Pohořelský - 3.2.5-1 +- Update to new upstream release +- Removed at-3.1.14-usePOSIXtimers.patch and at-3.2.23-coverity-fix.patch, because + upstream implemented them +- Defined folder paths without %%{buildroot} in order to make them work with latest + Makefile changes +- Resolves: rhbz#2048132 + +* Wed Jan 19 2022 Fedora Release Engineering - 3.2.2-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Wed Jul 21 2021 Fedora Release Engineering - 3.2.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Fri May 21 2021 Ondřej Pohořelský - 3.2.2-1 +- Update to new upstream release + +* Fri Apr 16 2021 Jan Staněk - 3.1.23-8 +- Patch issues found by coverity (rhbz#1938678) + +* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek - 3.1.23-7 +- Rebuilt for updated systemd-rpm-macros + See https://pagure.io/fesco/issue/2583. + +* Tue Jan 26 2021 Fedora Release Engineering - 3.1.23-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Mon Jul 27 2020 Fedora Release Engineering - 3.1.23-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Tue Jan 28 2020 Fedora Release Engineering - 3.1.23-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Wed Jul 24 2019 Fedora Release Engineering - 3.1.23-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Thu Jan 31 2019 Fedora Release Engineering - 3.1.23-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Mon Aug 27 2018 Tomáš Mráz - 3.1.23-1 +- new upstream release + +* Thu Jul 12 2018 Fedora Release Engineering - 3.1.20-12 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Wed May 23 2018 Tomáš Mráz - 3.1.20-11 +- log the jobs being run + +* Sun Feb 25 2018 Florian Weimer - 3.1.20-10 +- Drop "BuildRequires: fileutils /etc/init.d" + +* Wed Feb 07 2018 Fedora Release Engineering - 3.1.20-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Thu Sep 14 2017 Tomáš Mráz - 3.1.20-8 +- improve the wrong_format patch, also rename it to correct name + +* Thu Sep 14 2017 Tomáš Mráz - 3.1.20-7 +- the ownership of the spool directory should be root as at is configured + with daemon username root +- document the -n option + +* Wed Aug 02 2017 Fedora Release Engineering - 3.1.20-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 3.1.20-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Tue Mar 28 2017 Tomáš Mráz - 3.1.20-4 +- fix the POSIX timers support (#1436523) + +* Fri Feb 10 2017 Fedora Release Engineering - 3.1.20-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Thu Feb 2 2017 Tomáš Mráz - 3.1.20-2 +- properly include the license files + +* Fri Jul 1 2016 Tomáš Mráz - 3.1.20-1 +- new upstream release +- properly lock the lock files to be able to safely remove + stale ones + +* Mon May 23 2016 Tomáš Mráz - 3.1.18-2 +- SIGPIPE should not be ignored in atd (#1338039) + +* Wed Mar 23 2016 Tomáš Mráz - 3.1.18-1 +- new upstream release +- correct the DST correction when using UTC time specification (#1320322) + +* Wed Feb 03 2016 Fedora Release Engineering - 3.1.16-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Sep 9 2015 Tomáš Mráz - 3.1.16-7 +- clear non-job files from at dir + +* Wed Jun 17 2015 Fedora Release Engineering - 3.1.16-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + * Fri Nov 28 2014 Tomáš Mráz - 3.1.16-5 - superfluous patch dropped @@ -238,7 +400,7 @@ chown daemon:daemon %{_localstatedir}/spool/at/.SEQ - Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild * Mon Nov 14 2011 Marcela Mašláňová - 3.1.13-5 -- 754156 fix typo in script +- 754156 fix typo in script * Mon Nov 14 2011 Marcela Mašláňová - 3.1.13-5 - fix incorrect option in test in 56atd @@ -280,7 +442,7 @@ chown daemon:daemon %{_localstatedir}/spool/at/.SEQ - 617320 systemd init script replacement * Mon Mar 15 2010 Marcela Mašláňová - 3.1.12-5 -- 568222 interrupted 'at' job creates empty job for non-root +- 568222 interrupted 'at' job creates empty job for non-root * Mon Mar 1 2010 Marcela Mašláňová - 3.1.12-4 - 568779 atd is alway runnig after suspend/resume @@ -337,8 +499,8 @@ chown daemon:daemon %{_localstatedir}/spool/at/.SEQ - 486227 add hyphen date into manual page. * Wed Dec 3 2008 Marcela Mašláňová - 3.1.10-27 -- 464393 add script into pm-utils, because daemon wasn't taking all jobs - after suspend/hibernate +- 464393 add script into pm-utils, because daemon wasn't taking all jobs + after suspend/hibernate * Fri Oct 24 2008 Marcela Mašláňová - 3.1.10-26 - update init script according to SysVInitScript @@ -415,7 +577,7 @@ chown daemon:daemon %{_localstatedir}/spool/at/.SEQ - rhbz#224597 * Fri Oct 27 2006 Marcela Maslanova - 3.1.10-6 -- fix daylight-saving again +- fix daylight-saving again - fix #214759 - problem with seteuid * Wed Oct 25 2006 Marcela Maslanova - 3.1.10-5 @@ -450,11 +612,11 @@ chown daemon:daemon %{_localstatedir}/spool/at/.SEQ - use include instead of pam_stack in pam config * Fri Jun 03 2005 Jason Vas Dias 3.1.8-78 -- fix bug 159220: add pam_loginuid to pam session stack in /etc/pam.d/atd +- fix bug 159220: add pam_loginuid to pam session stack in /etc/pam.d/atd - fix bug 102341: add '-r' synonym for '-d' / atrm for POSIX / SuS conformance * Fri Apr 08 2005 Jason Vas Dias 3.1.8-77 -- always call pam_setcred(pamh, PAM_DELETE_CRED) before session +- always call pam_setcred(pamh, PAM_DELETE_CRED) before session - close * Tue Apr 05 2005 Jason Vas Dias 3.1.8-70 @@ -465,7 +627,7 @@ chown daemon:daemon %{_localstatedir}/spool/at/.SEQ - user can know when using at(1) if PAM permission is denied. * Tue Mar 08 2005 Jason Vas Dias 3.1.8-67 -- better fix for bug 150131: change DAEMON_USERNAME and +- better fix for bug 150131: change DAEMON_USERNAME and - DAEMON_GROUPNAME to 'root' . * Mon Mar 07 2005 Jason Vas Dias 3.1.8-66 @@ -483,7 +645,7 @@ chown daemon:daemon %{_localstatedir}/spool/at/.SEQ - details of blacklisted variables. * Tue Sep 28 2004 Rik van Riel 3.1.8-58 -- fix typo in man page, bug 112303 +- fix typo in man page, bug 112303 - (regenerated at-3.1.8-man-timespec-path.patch with fix) * Tue Aug 03 2004 Jason Vas Dias @@ -616,7 +778,7 @@ chown daemon:daemon %{_localstatedir}/spool/at/.SEQ - updated patch update, still bug #46546 * Wed Jul 18 2001 Crutcher Dunnavant -- applied enrico.scholz@informatik.tu-chemnitz.de's change to the env patch to +- applied enrico.scholz@informatik.tu-chemnitz.de's change to the env patch to - address bug #46546 * Mon Jun 25 2001 Crutcher Dunnavant @@ -699,7 +861,7 @@ chown daemon:daemon %{_localstatedir}/spool/at/.SEQ * Mon May 24 1999 Jeff Johnson - reset SIGCHLD before exec (#3016). -* Sun Mar 21 1999 Cristian Gafton +* Sun Mar 21 1999 Cristian Gafton - auto rebuild in the new build environment (release 8) * Thu Mar 18 1999 Cristian Gafton diff --git a/atd.systemd b/atd.systemd index 7bdf82c..962b0d0 100644 --- a/atd.systemd +++ b/atd.systemd @@ -1,10 +1,13 @@ [Unit] -Description=Job spooling tools +Description=Deferred execution scheduler +Documentation=man:atd(8) After=syslog.target systemd-user-sessions.service [Service] EnvironmentFile=/etc/sysconfig/atd ExecStart=/usr/sbin/atd -f $OPTS +IgnoreSIGPIPE=no +KillMode=process [Install] WantedBy=multi-user.target diff --git a/plans/ci.fmf b/plans/ci.fmf new file mode 100644 index 0000000..c1627f9 --- /dev/null +++ b/plans/ci.fmf @@ -0,0 +1,5 @@ +summary: Basic smoke test +discover: + how: fmf +execute: + how: tmt diff --git a/sources b/sources index 117a254..9e44a81 100644 --- a/sources +++ b/sources @@ -1 +1,2 @@ -d05da75d9b75d93917ffb16ab48b1e19 at_3.1.16.orig.tar.gz +SHA512 (at_3.2.5.orig.tar.gz) = 542e8948bbdc1d06934070cbfe242688b541ef6342c6b0351255f8b9d7a3ed915a9304b5cf5442dfc15845b3d2b926ebecbfc5bccd204519d0a2775b27f8139c +SHA512 (at_3.2.5.orig.tar.gz.sig) = 5a38cb7da5b85233ede79e7b90aec7705250e315c5b4bcccb9c1c9a6453a9cc5c79c840023a44ac5d087137596c2b4b98971e233ea1fbbaa0c82833e53dcd8ac diff --git a/tests/initscript/Makefile b/tests/initscript/Makefile new file mode 100644 index 0000000..9b15af0 --- /dev/null +++ b/tests/initscript/Makefile @@ -0,0 +1,61 @@ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Makefile of /CoreOS/at/Sanity/initscript +# Description: Initscript sanity +# Author: Radek Biba +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2009 Red Hat, Inc. All rights reserved. +# +# This copyrighted material is made available to anyone wishing +# to use, modify, copy, or redistribute it subject to the terms +# and conditions of the GNU General Public License version 2. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +export TEST=/CoreOS/at/Sanity/initscript +export TESTVERSION=1.0 + +BUILT_FILES= + +FILES=$(METADATA) runtest.sh Makefile PURPOSE + +.PHONY: all install download clean + +run: $(FILES) build + ./runtest.sh + +build: $(BUILT_FILES) + chmod a+x runtest.sh + +clean: + rm -f *~ $(BUILT_FILES) + +$(METADATA): Makefile + @echo "Owner: Radek Biba " > $(METADATA) + @echo "Name: $(TEST)" >> $(METADATA) + @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) + @echo "Path: $(TEST_DIR)" >> $(METADATA) + @echo "Description: Initscript sanity" >> $(METADATA) + @echo "Type: Sanity" >> $(METADATA) + @echo "TestTime: 5m" >> $(METADATA) + @echo "Releases: -RHEL3 -RHEL4 -RHELServer5 -RHELClient5 -RedHatEnterpriseLinux3 -RedHatEnterpriseLinux4 -RedHatEnterpriseLinuxClient5 -RedHatEnterpriseLinuxServer5" >> $(METADATA) + @echo "RunFor: at" >> $(METADATA) + @echo "Requires: at" >> $(METADATA) + @echo "Priority: Normal" >> $(METADATA) + @echo "License: GPLv2" >> $(METADATA) + @echo "Confidential: no" >> $(METADATA) + @echo "Destructive: no" >> $(METADATA) + + rhts-lint $(METADATA) diff --git a/tests/initscript/PURPOSE b/tests/initscript/PURPOSE new file mode 100644 index 0000000..7845ec7 --- /dev/null +++ b/tests/initscript/PURPOSE @@ -0,0 +1,3 @@ +PURPOSE of /CoreOS/at/Sanity/initscript +Description: Initscript sanity +Author: Radek Biba diff --git a/tests/initscript/main.fmf b/tests/initscript/main.fmf new file mode 100644 index 0000000..275b067 --- /dev/null +++ b/tests/initscript/main.fmf @@ -0,0 +1,12 @@ +summary: Initscript sanity +description: '' +contact: Radek Biba +component: + - at +test: ./runtest.sh +framework: beakerlib +recommend: + - at +duration: 5m +extra-summary: /CoreOS/at/Sanity/initscript +extra-task: /CoreOS/at/Sanity/initscript diff --git a/tests/initscript/runtest.sh b/tests/initscript/runtest.sh new file mode 100755 index 0000000..67ecc2d --- /dev/null +++ b/tests/initscript/runtest.sh @@ -0,0 +1,87 @@ +#!/bin/bash +# vim: dict=/usr/share/rhts-library/dictionary.vim cpt=.,w,b,u,t,i,k +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# runtest.sh of /CoreOS/at/Sanity/initscript +# Description: Initscript sanity +# Author: Radek Biba +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2009 Red Hat, Inc. All rights reserved. +# +# This copyrighted material is made available to anyone wishing +# to use, modify, copy, or redistribute it subject to the terms +# and conditions of the GNU General Public License version 2. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Include rhts environment +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +PACKAGE="at" +SERVICE="atd" + +rlJournalStart + rlPhaseStartSetup "Prepare" + rlServiceStop $SERVICE + rlPhaseEnd + if rlIsRHEL "<7"; then + rlPhaseStartTest "Mandatory actions" + for ACTION in "start" "stop" "restart" "force-reload" "status" ; do + rlRun "grep -i \"usage.*$ACTION\" /etc/init.d/$SERVICE" + done + rlPhaseEnd + fi + rlPhaseStartTest "Start" + rlRun "service $SERVICE start" 0 + rlRun "service $SERVICE status" 0 + rlRun "service $SERVICE start" 0 + rlRun "service $SERVICE status" 0 + rlRun "service $SERVICE restart" 0 + rlRun "service $SERVICE status" 0 + rlRun "service $SERVICE force-reload" 0 + rlRun "service $SERVICE status" 0 + rlRun "service $SERVICE try-restart" 0 + rlRun "service $SERVICE status" 0 + rlPhaseEnd + rlPhaseStartTest "Stop" + rlRun "service $SERVICE stop" 0 + rlRun "service $SERVICE status" 3 + rlRun "service $SERVICE stop" 0 + rlRun "service $SERVICE status" 3 + rlRun "service $SERVICE try-restart" 0 + rlRun "service $SERVICE status" 3 + rlPhaseEnd + rlPhaseStartTest "Dead service" + rlRun "touch /var/lock/subsys/$SERVICE" + rlRun "service $SERVICE status" $( + if rlIsRHEL "<7"; then + echo 2; + else + echo 3; + fi + ) + rlRun "service $SERVICE start" 0 + rlRun "service $SERVICE status" 0 + rlPhaseEnd + rlPhaseStartTest "Invalid arguments" + rlRun "service $SERVICE" 2 + rlRun "service $SERVICE fubar" 2 + rlPhaseEnd + + rlPhaseStartCleanup "Restore" + rlServiceRestore $SERVICE + rlPhaseEnd +rlJournalPrintText +rlJournalEnd