Hello community, here is the log from the commit of package at.3872 for openSUSE:13.1:Update checked in at 2015-07-04 11:17:08 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:13.1:Update/at.3872 (Old) and /work/SRC/openSUSE:13.1:Update/.at.3872.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "at.3872" Changes: -------- New Changes file: --- /dev/null 2015-06-25 09:04:34.320025005 +0200 +++ /work/SRC/openSUSE:13.1:Update/.at.3872.new/at.changes 2015-07-04 11:17:11.000000000 +0200 @@ -0,0 +1,621 @@ +------------------------------------------------------------------- +Tue Jun 23 16:48:56 UTC 2015 - [email protected] + +- loadavg on Linux is a sum over all CPUs, so multiply LOADAVG_MX + by the amount of CPUs when comparing to loadavg (bnc#889174) + * added at-adjust_load_to_cpu_count.patch + +------------------------------------------------------------------- +Tue Oct 7 13:52:25 UTC 2014 - [email protected] + +- Replace at-3.1.13-sane-envkeys.patch with the upstream fix + (bnc#899160) + +------------------------------------------------------------------- +Thu Oct 2 13:39:45 UTC 2014 - [email protected] + +- Add at-3.1.13-sane-envkeys.patch to skip exporting variables with + awkward keys (bnc#899160). + +------------------------------------------------------------------- +Tue Jul 29 07:02:16 UTC 2014 - [email protected] + +- introduced -o <timeformat> switch for atq [bnc#879402] + * added at-atq-timeformat.patch + +------------------------------------------------------------------- +Tue Nov 12 15:37:29 UTC 2013 - [email protected] + +- use old privs model (fixes bnc#849720) + * at-backport-old-privs.patch +- do not install sysvinit script and service file together +- add sticky bit to atjobs + +------------------------------------------------------------------- +Tue Oct 22 06:38:25 UTC 2013 - [email protected] + +- adding service hook was in %verifyscript section not in %post + +------------------------------------------------------------------- +Sun Oct 6 23:02:00 UTC 2013 - [email protected] + +- at-secure_getenv.patch at must use secure_getenv. + +------------------------------------------------------------------- +Mon Jul 15 13:50:37 UTC 2013 - [email protected] + +- No http://0pointer.de/public/systemd-units/atd.service anymore + +------------------------------------------------------------------- +Sat Jul 13 00:09:02 UTC 2013 - [email protected] + +- systemd: start as non-forking service +- systemd: start after systemd-user-sessions.service + +------------------------------------------------------------------- +Sat Jul 13 00:05:41 UTC 2013 - [email protected] + +- Use /run not /var/run to store the pid file + +------------------------------------------------------------------- +Thu Jun 20 01:52:46 UTC 2013 - [email protected] + +- at.sleep move away from pm-utils to systemd-sleep + +------------------------------------------------------------------- +Tue Jun 18 15:09:18 UTC 2013 - [email protected] + +- at-makefile-deps.patch: fix makefile dependencies + +------------------------------------------------------------------- +Tue Jun 11 13:09:18 UTC 2013 - [email protected] + +- updated to upstream 3.1.13 +- ported patches to new source code in session with Stefan Seyfried +- removed unnecessary patches + +------------------------------------------------------------------- +Sun Apr 14 06:45:53 UTC 2013 - [email protected] + +- Ordering after syslog.target is no longer recommended. + +------------------------------------------------------------------- +Wed Feb 6 14:17:35 UTC 2013 - [email protected] + +- fix author information in at-parse-suse-sysconfig.patch (bnc#780259#c25) + +------------------------------------------------------------------- +Sun Jan 6 20:43:45 UTC 2013 - [email protected] + +- Use simpler HXmap_get in at-parse-suse-sysconfig.patch + (bnc#780259) + +------------------------------------------------------------------- +Wed Nov 28 21:46:58 UTC 2012 - [email protected] + +- When sysconfig variables are empty, do not set stuff to zero + just use the defaults. + +------------------------------------------------------------------- +Wed Nov 28 20:51:49 UTC 2012 - [email protected] + +- Fix systemd unit and sysconfig parsing the right way. + +------------------------------------------------------------------- +Mon Nov 26 18:11:09 UTC 2012 - [email protected] + +- use /etc/sysconfig/atd variables in atd.service (bnc#780259#c4) + +------------------------------------------------------------------- +Thu Sep 13 21:24:09 UTC 2012 - [email protected] + +- fix atd.service (bnc#780259) + +------------------------------------------------------------------- +Tue Dec 20 19:56:52 UTC 2011 - [email protected] + +- add autoconf as buildrequire to avoid implicit dependency + +------------------------------------------------------------------- +Tue Dec 20 11:26:55 UTC 2011 - [email protected] + +- remove call to suse_update_config (very old work around) + +------------------------------------------------------------------- +Mon Dec 5 19:19:40 UTC 2011 - [email protected] + +- Fix rpmlint warnings + +------------------------------------------------------------------- +Mon Dec 5 19:05:48 UTC 2011 - [email protected] + +- Support systemd. + +------------------------------------------------------------------- +Sat Sep 17 13:28:30 UTC 2011 - [email protected] + +- Remove redundant tags/sections from specfile +- Use %_smp_mflags for parallel build + +------------------------------------------------------------------- +Fri May 13 07:45:00 UTC 2011 - [email protected] + +- added missing license to distribution (bnc#693355) + +------------------------------------------------------------------- +Tue Apr 19 07:40:28 UTC 2011 - [email protected] + +- wrong jobdir mtime handling fixed (bnc#680113) + thanks to Ingo Schwarze + +------------------------------------------------------------------- +Tue Apr 5 15:36:24 UTC 2011 - [email protected] + +- fixed atd-atrm race condition (bnc#679857) + +------------------------------------------------------------------- +Tue Mar 1 15:33:34 UTC 2011 - [email protected] + +- fixed bug introduced with at-3.1.8-tomorrow.patch (bnc#672586) + +------------------------------------------------------------------- +Mon Feb 7 16:10:28 CET 2011 - [email protected] + +- source pm-utils functions in suspend/resume script to avoid + errors + +------------------------------------------------------------------- +Tue Feb 1 09:49:43 UTC 2011 - [email protected] + +- at now shifts jobs with passed time without a date to tomorrow + (bnc#668485) + +------------------------------------------------------------------- +Wed Nov 10 12:51:25 UTC 2010 - [email protected] + +- own parent directories + +------------------------------------------------------------------- +Tue Sep 28 04:53:33 UTC 2010 - [email protected] + +- /etc/at.deny has wrong account name [bnc#632250] + +------------------------------------------------------------------- +Tue Jul 20 20:29:11 UTC 2010 - [email protected] + +- wake up atd after suspend [bnc#592349] + +------------------------------------------------------------------- +Sat Jul 17 02:24:46 UTC 2010 - [email protected] + +- improve spec file +- Should Recommend smtp_daemon + +------------------------------------------------------------------- +Wed Nov 18 17:18:44 UTC 2009 - [email protected] + +- added pam conversion function (reworked pam.patch) fate#306386 ++++ 424 more lines (skipped) ++++ between /dev/null ++++ and /work/SRC/openSUSE:13.1:Update/.at.3872.new/at.changes New: ---- at-3.1.13-documentation-dir.patch at-3.1.13-formatbugs.patch at-3.1.13-joblist.patch at-3.1.13-leak-fix.patch at-3.1.13-massive_batch.patch at-3.1.13-pam-session-as-root.patch at-3.1.13-pam.patch at-3.1.13-pie.patch at-3.1.13-queue-nice-level.patch at-3.1.13-sane-envkeys.patch at-3.1.13-selinux.patch at-3.1.13-tomorrow.patch at-3.1.13.patch at-3.1.8-denylist.patch at-3.1.8-eal3-manpages.patch at-3.1.8-jobdir-mtime.patch at-adjust_load_to_cpu_count.patch at-atq-timeformat.patch at-backport-old-privs.patch at-makefile-deps.patch at-parse-suse-sysconfig.patch at-piddir.patch at-secure_getenv.patch at.changes at.sleep at.spec at_3.1.13.orig.tar.gz atd.init atd.pamd atd.service sysconfig.atd ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ at.spec ++++++ # # spec file for package at # # Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed # upon. The license for this file, and modifications and additions to the # file, is the same license as for the pristine package itself (unless the # license for the pristine package is not an Open Source License, in which # case the license is the MIT License). An "Open Source License" is a # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. # Please submit bugfixes or comments via http://bugs.opensuse.org/ # Name: at BuildRequires: autoconf >= 2.69 BuildRequires: automake BuildRequires: bison BuildRequires: flex BuildRequires: libselinux-devel BuildRequires: pam-devel Url: ftp://ftp.debian.org/debian/pool/main/a/at Version: 3.1.13 Release: 0 Summary: A Job Manager License: GPL-2.0+ Group: System/Daemons Source: at_3.1.13.orig.tar.gz Source1: atd.init Source2: atd.pamd Source3: sysconfig.atd Source4: at.sleep Source5: atd.service Patch0: %{name}-3.1.13.patch Patch4: %{name}-3.1.13-joblist.patch Patch5: %{name}-3.1.13-selinux.patch Patch6: %{name}-3.1.13-pie.patch Patch7: %{name}-3.1.8-eal3-manpages.patch ## no bugs anymore for patch8. Just paranoia checking Patch8: %{name}-3.1.13-formatbugs.patch Patch9: %{name}-3.1.13-pam.patch Patch10: %{name}-3.1.13-massive_batch.patch Patch11: %{name}-3.1.13-documentation-dir.patch Patch12: %{name}-3.1.13-queue-nice-level.patch # PATCH-FIX-UPSTREAM pam-session-as-root (bnc#408986, bnc#239210) Patch14: %{name}-3.1.13-pam-session-as-root.patch # PATCH-FIX-UPSTREAM clean-up opened descriptors (bnc#533454, bnc#523346) Patch15: %{name}-3.1.13-leak-fix.patch #PATCH-FIX-OPENSUSE add proper system users to the deny list Patch16: at-3.1.8-denylist.patch #PATCH-FIX-UPSTREAM plan jobs with past time to tomorrow (bnc#672586) Patch17: %{name}-3.1.13-tomorrow.patch #PATCH-FIX-UPSTREAM wrong mtime handling of jobdir (bnc#680113) Patch19: %{name}-3.1.8-jobdir-mtime.patch Patch20: at-parse-suse-sysconfig.patch #PATCH-FIX-UPSTREAM fix makefile dependencies Patch21: at-makefile-deps.patch #PATCH-FIX-OPENSUSE Set pid dir to /run not /var/run Patch22: at-piddir.patch Patch23: at-secure_getenv.patch #PATCH-FIX-OPENSUSE backport privs from 3.1.8 (bnc#849720) Patch24: at-backport-old-privs.patch #PATCH-FIX-UPSTREAM [email protected] add -o switch to specify time format (bnc#879402) Patch25: at-atq-timeformat.patch #PATCH-FIX-UPSTREAM skip exporting variables with awkward keys (bnc#899160) Patch26: at-3.1.13-sane-envkeys.patch Patch28: at-adjust_load_to_cpu_count.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build PreReq: %{_sbindir}/useradd %{_sbindir}/groupadd %fillup_prereq %insserv_prereq PreReq: permissions Recommends: smtp_daemon %if 0%{?suse_version} > 1140 BuildRequires: libHX-devel BuildRequires: pkgconfig BuildRequires: pkgconfig(systemd) %{?systemd_requires} %define has_systemd 1 %endif %description This program allows you to run jobs at specified times. %prep %setup -q %patch0 %patch4 %patch5 %patch6 %patch7 %patch8 %patch9 %patch10 %patch11 %patch12 %patch14 %patch15 %patch16 %patch17 -p1 %patch19 %patch20 -p1 %patch21 -p1 %patch22 %patch23 -p1 %patch24 -p1 %patch25 %patch26 -p1 %patch28 -p1 %build rm -fv y.tab.c y.tab.h lex.yy.c lex.yy.o y.tab.o autoreconf -fiv export SENDMAIL=%{_sbindir}/sendmail %configure \ --with-pam \ --with-selinux \ --with-daemon_username=at \ --with-daemon_groupname=at make %{?_smp_mflags} %install mkdir -p $RPM_BUILD_ROOT/etc/pam.d mkdir -p $RPM_BUILD_ROOT/usr/{bin,sbin,share/man/man{1,5,8}} mkdir -p $RPM_BUILD_ROOT/var/adm/fillup-templates export CFLAGS="$RPM_OPT_FLAGS" export SENDMAIL=%{_sbindir}/sendmail make install IROOT=$RPM_BUILD_ROOT # Don't install docs here in this way mkdir docs mv $RPM_BUILD_ROOT/%{_prefix}/doc/at/* docs/ %if ! %{has_systemd} mkdir -p $RPM_BUILD_ROOT/etc/init.d install %SOURCE1 $RPM_BUILD_ROOT/etc/init.d/atd ln -sf ../../etc/init.d/atd $RPM_BUILD_ROOT%{_sbindir}/rcatd %else install -D -m 0644 %{S:5} %{buildroot}%{_unitdir}/atd.service %{__install} -D -m 0755 %{S:4} %{buildroot}%{_prefix}/lib/systemd/system-sleep/atd.sh ln -sf ../../%{_sbindir}/service $RPM_BUILD_ROOT%{_sbindir}/rcatd %endif install -m644 %SOURCE2 $RPM_BUILD_ROOT/etc/pam.d/atd install -m644 %SOURCE3 $RPM_BUILD_ROOT/var/adm/fillup-templates %pre %{_sbindir}/groupadd -g 25 -o -r at 2> /dev/null || : %{_sbindir}/useradd -r -o -g at -u 25 -s /bin/bash -c "Batch jobs daemon" -d /var/spool/atjobs at 2> /dev/null || : %if 0%{?has_systemd} %service_add_pre atd.service %endif %preun %stop_on_removal atd %if 0%{?has_systemd} %service_del_preun atd.service %endif %post # update hack # the rcscript used to be /etc/init.d/at if [ -f etc/init.d/at ] ; then rm -f etc/init.d/at %{insserv_cleanup} fi %set_permissions /usr/bin/at %if 0%{?has_systemd} %service_add_post atd.service %else %{fillup_and_insserv -n atd atd } %endif %verifyscript %verify_permissions -e /usr/bin/at %postun %insserv_cleanup %if 0%{?has_systemd} %service_del_postun atd.service %else %restart_on_update atd %endif %files %defattr(-,root,root) %doc Problems Copyright COPYING README ChangeLog timespec %config(noreplace) /etc/at.deny %{_sbindir}/rcatd %config %attr(644,root,root) /etc/pam.d/atd %verify(not mode) %attr(4750,root,trusted) %{_bindir}/at %{_bindir}/atq %{_bindir}/atrm %{_bindir}/batch %{_mandir}/man?/* %{_sbindir}/atd %{_sbindir}/atrun %attr(700,at,at) %dir /var/spool/atspool %attr(1770,at,at) %dir /var/spool/atjobs %attr(600,at,at) /var/spool/atjobs/.SEQ /var/adm/fillup-templates/sysconfig.atd %if 0%{?has_systemd} %{_unitdir}/atd.service %{_prefix}/lib/systemd/system-sleep/atd.sh %else %config /etc/init.d/atd %endif %changelog ++++++ at-3.1.13-documentation-dir.patch ++++++ Index: at.1.in =================================================================== --- at.1.in.orig +++ at.1.in @@ -124,11 +124,11 @@ to run a job at 10:00am on July 31, you .B at 10am Jul 31 and to run a job at 1am tomorrow, you would do .B at 1am tomorrow. .PP The definition of the time specification can be found in -.IR @prefix@/share/doc/at/timespec . +.IR @prefix@/share/doc/packages/at/timespec . .PP For both .BR at " and " batch , commands are read from standard input or the file specified with the ++++++ at-3.1.13-formatbugs.patch ++++++ Index: daemon.h =================================================================== --- daemon.h.orig +++ daemon.h @@ -3,15 +3,15 @@ void daemon_cleanup(void); void #ifdef HAVE_ATTRIBUTE_NORETURN __attribute__((noreturn)) #endif -pabort (const char *fmt, ...); +pabort (const char *fmt, ...) __attribute__((__format__(printf,1,2))); void #ifdef HAVE_ATTRIBUTE_NORETURN __attribute__((noreturn)) #endif -perr (const char *fmt, ...); +perr (const char *fmt, ...) __attribute__((__format__(printf,1,2))); extern int daemon_debug; extern int daemon_foreground; Index: panic.h =================================================================== --- panic.h.orig +++ panic.h @@ -24,11 +24,13 @@ __attribute__((noreturn)) panic(char *a); void #ifdef HAVE_ATTRIBUTE_NORETURN __attribute__((noreturn)) #endif -perr(const char *a, ...); +perr(const char *a, ...) +__attribute__((__format__(printf,1,2))) +; void #ifdef HAVE_ATTRIBUTE_NORETURN __attribute__((noreturn)) #endif usage(void); ++++++ at-3.1.13-joblist.patch ++++++ Index: at.c =================================================================== --- at.c.orig +++ at.c @@ -132,11 +132,13 @@ char atverify = 0; /* verify time inste static void sigc(int signo); static void alarmc(int signo); static char *cwdname(void); static void writefile(time_t runtimer, char queue); -static void list_jobs(void); +static void list_jobs(long *, int); +static int in_job_list(long, long *, int); +static long *get_job_list(int, char *[], int *); /* Signal catching functions */ static RETSIGTYPE sigc(int signo) @@ -545,12 +547,24 @@ writefile(time_t runtimer, char queue) break; } return; } +static int +in_job_list(long job, long *joblist, int len) +{ + int i; + + for (i = 0; i < len; i++) + if (job == joblist[i]) + return 1; + + return 0; +} + static void -list_jobs(void) +list_jobs(long *joblist, int len) { /* List all a user's jobs in the queue, by looping through ATJOB_DIR, * or everybody's if we are root */ DIR *spool; @@ -585,10 +599,14 @@ list_jobs(void) continue; if (sscanf(dirent->d_name, "%c%5lx%8lx", &queue, &jobno, &ctm) != 3) continue; + /* If jobs are given, only list those jobs */ + if (joblist && !in_job_list(jobno, joblist, len)) + continue; + if (atqueue && (queue != atqueue)) continue; runtimer = 60 * (time_t) ctm; runtime = localtime(&runtimer); @@ -706,10 +724,33 @@ process_jobs(int argc, char **argv, int } } return rc; } /* delete_jobs */ +static long * +get_job_list(int argc, char *argv[], int *joblen) +{ + int i, len; + long *joblist; + char *ep; + + joblist = NULL; + len = argc; + if (len > 0) { + joblist = (long *) mymalloc(len * sizeof(*joblist)); + for (i = 0; i < argc; i++) { + errno = 0; + if ((joblist[i] = strtol(argv[i], &ep, 10)) < 0 || + ep == argv[i] || *ep != '\0' || errno) + panic("invalid job number"); + } + } + + *joblen = len; + return joblist; +} + /* Global functions */ void * mymalloc(size_t n) { @@ -731,10 +772,12 @@ main(int argc, char **argv) int program = AT; /* our default program */ char *options = "q:f:MmvlrdhVct:"; /* default options for at */ int disp_version = 0; time_t timer = 0; + long *joblist = NULL; + int joblen = 0; struct passwd *pwe; struct group *ge; RELINQUISH_PRIVS @@ -868,12 +911,13 @@ main(int argc, char **argv) switch (program) { int i; case ATQ: REDUCE_PRIV(daemon_uid, daemon_gid) - - list_jobs(); + if (queue_set == 0) + joblist = get_job_list(argc - optind, argv + optind, &joblen); + list_jobs(joblist, joblen); break; case ATRM: REDUCE_PRIV(daemon_uid, daemon_gid) Index: panic.c =================================================================== --- panic.c.orig +++ panic.c @@ -93,10 +93,11 @@ usage(void) /* Print usage and exit. */ fprintf(stderr, "Usage: at [-V] [-q x] [-f file] [-mlbv] timespec ...\n" " at [-V] [-q x] [-f file] [-mlbv] -t time\n" " at -c job ...\n" + " at [-V] -l [job ...]\n" " atq [-V] [-q x]\n" " at [ -rd ] job ...\n" " atrm [-V] job ...\n" " batch\n"); exit(EXIT_FAILURE); ++++++ at-3.1.13-leak-fix.patch ++++++ Index: at.c =================================================================== --- at.c.orig +++ at.c @@ -616,10 +616,13 @@ list_jobs(long *joblist, int len) if ((pwd = getpwuid(buf.st_uid))) printf("%ld\t%s %c %s\n", jobno, timestr, queue, pwd->pw_name); else printf("%ld\t%s %c\n", jobno, timestr, queue); } + + closedir(spool); + PRIV_END } static int process_jobs(int argc, char **argv, int what) @@ -698,10 +701,11 @@ process_jobs(int argc, char **argv, int if (fp) { while ((ch = getc(fp)) != EOF) { putchar(ch); } done = 1; + fclose(fp); } else { perr("Cannot open %.500s", dirent->d_name); rc = EXIT_FAILURE; } ++++++ at-3.1.13-massive_batch.patch ++++++ Index: atd.c =================================================================== --- atd.c.orig +++ atd.c @@ -112,13 +112,14 @@ gid_t daemon_gid = (gid_t) - 3; static char *namep; static double load_avg = LOADAVG_MX; static time_t now; static time_t last_chg; -static int nothing_to_do; +static int nothing_to_do = 0; unsigned int batch_interval; static int run_as_daemon = 0; +static int hupped = 0; static volatile sig_atomic_t term_signal = 0; #ifdef WITH_PAM #include <security/pam_appl.h> @@ -146,14 +147,14 @@ set_term(int dummy) { term_signal = 1; return; } -RETSIGTYPE -sdummy(int dummy) +RETSIGTYPE +set_hup(int dummy) { - /* Empty signal handler */ + hupped = 1; nothing_to_do = 0; return; } /* SIGCHLD handler - discards completion status of children */ @@ -807,10 +808,11 @@ run_loop() 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); run_batch = 0; nothing_to_do = 1; @@ -1043,11 +1045,11 @@ main(int argc, char *argv[]) * A signal handler setting term_signal will make sure there's * a clean exit. */ sigaction(SIGHUP, NULL, &act); - act.sa_handler = sdummy; + act.sa_handler = set_hup; sigaction(SIGHUP, &act, NULL); sigaction(SIGTERM, NULL, &act); act.sa_handler = set_term; sigaction(SIGTERM, &act, NULL); @@ -1059,12 +1061,13 @@ main(int argc, char *argv[]) daemon_setup(); do { now = time(NULL); next_invocation = run_loop(); - if (next_invocation > now) { + if ((next_invocation > now) && (!hupped)) { sleep(next_invocation - now); } + hupped = 0; } while (!term_signal); daemon_cleanup(); exit(EXIT_SUCCESS); } ++++++ at-3.1.13-pam-session-as-root.patch ++++++ Index: atd.c =================================================================== --- atd.c.orig +++ atd.c @@ -663,15 +663,17 @@ run_file(const char *filename, uid_t uid if (unlink(filename) == -1) syslog(LOG_WARNING, "Warning: removing output file for job %li failed: %s", jobno, strerror(errno)); #ifdef WITH_PAM + PRIV_START 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); + PRIV_END #endif /* The job is now finished. We can delete its input file. */ chdir(ATJOB_DIR); @@ -784,15 +786,17 @@ run_file(const char *filename, uid_t uid { /* Parent */ waitpid(mail_pid, (int *) NULL, 0); } #ifdef WITH_PAM + PRIV_START 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); + PRIV_END #endif } exit(EXIT_SUCCESS); } ++++++ at-3.1.13-pam.patch ++++++ Index: atd.c =================================================================== --- atd.c.orig +++ atd.c @@ -89,10 +89,14 @@ int selinux_enabled=0; #include <selinux/flask.h> #include <selinux/av_permissions.h> #endif +#ifndef LOG_ATD +#define LOG_ATD LOG_DAEMON +#endif + /* Macros */ #define BATCH_INTERVAL_DEFAULT 60 #define CHECK_INTERVAL 3600 @@ -114,11 +118,11 @@ static int nothing_to_do; unsigned int batch_interval; static int run_as_daemon = 0; static volatile sig_atomic_t term_signal = 0; -#ifdef HAVE_PAM +#ifdef WITH_PAM #include <security/pam_appl.h> static pam_handle_t *pamh = NULL; static const struct pam_conv conv = { @@ -126,16 +130,17 @@ static const struct pam_conv conv = { }; #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); \ pam_end(pamh,retcode); } -#endif /* HAVE_PAM */ +#endif /* WITH_PAM */ /* Signal handlers */ RETSIGTYPE set_term(int dummy) { @@ -263,10 +268,23 @@ static int set_selinux_context(const cha freecon(user_context); return 0; } #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) { /* Run a file by by spawning off a process which redirects I/O, * spawns a subshell, then waits for it to complete and sends @@ -288,11 +306,11 @@ run_file(const char *filename, uid_t uid int ngid; char queue; char fmt[64]; unsigned long jobno; int rc; -#ifdef HAVE_PAM +#ifdef WITH_PAM int retcode; #endif #ifdef _SC_LOGIN_NAME_MAX errno = 0; @@ -450,20 +468,24 @@ run_file(const char *filename, uid_t uid write_string(fd_out, mailname); write_string(fd_out, "\n\n"); fstat(fd_out, &buf); size = buf.st_size; -#ifdef HAVE_PAM +#ifdef WITH_PAM PRIV_START 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; + closelog(); + openlog("atd", LOG_PID, LOG_ATD); PRIV_END #endif close(STDIN_FILENO); close(STDOUT_FILENO); @@ -474,10 +496,20 @@ run_file(const char *filename, uid_t uid perr("Error in fork"); else if (pid == 0) { char *nul = NULL; char **nenvp = &nul; +#ifdef WITH_PAM + char **pam_envp=0L; +#endif + + 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. */ if (lseek(fd_in, (off_t) 0, SEEK_SET) < 0) @@ -493,12 +525,10 @@ run_file(const char *filename, uid_t uid perr("Error in I/O redirection"); close(fd_in); close(fd_out); - PRIV_START - nice((tolower((int) queue) - 'a' + 1) * 2); if (initgroups(pentry->pw_name, pentry->pw_gid)) perr("Cannot initialize the supplementary group access list"); @@ -526,10 +556,20 @@ run_file(const char *filename, uid_t uid if (security_getenforce()==1) perr("Could not resset exec context for user %s\n", pentry->pw_name); #endif //end +#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. */ close(fd_in); @@ -538,18 +578,10 @@ run_file(const char *filename, uid_t uid non-blocking waitpid. So this blocking one will eventually return with an ECHILD error. */ waitpid(pid, (int *) NULL, 0); -#ifdef HAVE_PAM - PRIV_START - pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT); - retcode = pam_close_session(pamh, PAM_SILENT); - 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. */ fstat(fd_out, &buf); lseek(fd_out, 0, SEEK_SET); @@ -570,19 +602,51 @@ run_file(const char *filename, uid_t uid if (unlink(filename) == -1) syslog(LOG_WARNING, "Warning: removing output file for job %li failed: %s", jobno, strerror(errno)); +#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); free(newname); if (((send_mail != -1) && (buf.st_size != size)) || (send_mail == 1)) { + int mail_pid = -1; + +#ifdef WITH_PAM PRIV_START + 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); + PRIV_END +#endif + + mail_pid = fork(); + + if ( mail_pid == 0 ) + { + PRIV_START if (initgroups(pentry->pw_name, pentry->pw_gid)) perr("Cannot initialize the supplementary group access list"); if (setgid(gid) < 0) @@ -591,18 +655,85 @@ run_file(const char *filename, uid_t uid if (setuid(uid) < 0) perr("Cannot set user id"); 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; + + 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); + } + + 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 defined(SENDMAIL) execl(SENDMAIL, "sendmail", "-i", mailname, (char *) NULL); #else #error "No mail command specified." #endif perr("Exec failed for mail command"); - PRIV_END + exit (-1); + +#ifdef WITH_SELINUX + if (selinux_enabled>0) { + if (setexeccon(NULL) < 0) { + perr("Could not resset exec context for user %s\n", pentry->pw_name); + } + } +#endif + + 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 } exit(EXIT_SUCCESS); } static time_t @@ -817,16 +948,11 @@ main(int argc, char *argv[]) daemon_gid = ge->gr_gid; 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; Index: config.h.in =================================================================== --- config.h.in.orig +++ config.h.in @@ -69,13 +69,10 @@ #undef HAVE_NLIST_H /* Define to 1 for PAM support */ #undef HAVE_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 /* Define to 1 if you have the <security/pam_appl.h> header file. */ #undef HAVE_SECURITY_PAM_APPL_H @@ -143,11 +140,11 @@ #undef HAVE_VPRINTF /* Define to 1 if you have the `waitpid' function. */ #undef HAVE_WAITPID -/* Define to 1 if we need to provide our own yywrap() */ +/* need yywrap */ #undef NEED_YYWRAP /* Define to 1 if your `struct nlist' has an `n_un' member. Obsolete, depend on `HAVE_STRUCT_NLIST_N_UN_N_NAME */ #undef NLIST_NAME_UNION @@ -193,10 +190,13 @@ /* Define to 1 for Encore UMAX 4.3 that has <inq_status/cpustats.h> instead of <sys/cpustats.h>. */ #undef UMAX4_3 +/* use PAM */ +#undef WITH_PAM + /* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a `char[]'. */ #undef YYTEXT_POINTER /* Define to empty if `const' does not conform to ANSI C. */ Index: perm.c =================================================================== --- perm.c.orig +++ perm.c @@ -106,18 +106,19 @@ user_in_file(const char *path, const cha /* Global functions */ int check_permission() { - uid_t uid = geteuid(); + uid_t euid = geteuid(), uid=getuid(), egid=getegid(), gid=getgid(); struct passwd *pentry; int allow = 0, deny = 1; + int retcode=0; - if (uid == 0) + if (euid == 0) return 1; - if ((pentry = getpwuid(uid)) == NULL) { + if ((pentry = getpwuid(euid)) == NULL) { perror("Cannot access user database"); exit(EXIT_FAILURE); } allow = user_in_file(ETCDIR "/at.allow", pentry->pw_name); Index: configure.ac =================================================================== --- configure.ac.orig +++ configure.ac @@ -265,7 +265,14 @@ 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_CONFIG_FILES(Makefile atrun atd.8 atrun.8 at.1 at.allow.5 batch) AC_OUTPUT ++++++ at-3.1.13-pie.patch ++++++ Index: Makefile.in =================================================================== --- Makefile.in.orig +++ Makefile.in @@ -65,17 +65,17 @@ LIST = Filelist Filelist.asc .PHONY: all install clean dist distclean all: at atd atrun at: $(ATOBJECTS) - $(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 $(RUNOBJECTS) $(LIBS) $(PAMLIB) $(SELINUXLIB) + $(CC) $(CFLAGS) -o atd -pie $(RUNOBJECTS) $(LIBS) $(PAMLIB) $(SELINUXLIB) y.tab.c y.tab.h: parsetime.y $(YACC) -d parsetime.y lex.yy.c: parsetime.l @@ -83,11 +83,11 @@ lex.yy.c: parsetime.l atrun: atrun.in configure .c.o: - $(CC) -c $(CFLAGS) $(DEFS) $*.c + $(CC) -c $(CFLAGS) -fpie $(DEFS) $*.c install: all $(INSTALL) -m 755 -d $(IROOT)$(etcdir) $(INSTALL) -m 755 -d $(IROOT)$(bindir) $(INSTALL) -m 755 -d $(IROOT)$(sbindir) ++++++ at-3.1.13-queue-nice-level.patch ++++++ Index: atd.c =================================================================== --- atd.c.orig +++ atd.c @@ -577,11 +577,11 @@ run_file(const char *filename, uid_t uid perr("Error in I/O redirection"); close(fd_in); close(fd_out); - nice((tolower((int) queue) - 'a' + 1) * 2); + nice((tolower((int) queue) - 'a' ) ); if (initgroups(pentry->pw_name, pentry->pw_gid)) perr("Cannot initialize the supplementary group access list"); if (setgid(ngid) < 0) ++++++ at-3.1.13-sane-envkeys.patch ++++++ commit 482f5962d9584d6110b940f0f51ab5919a6eb8a0 Author: Ansgar Burchardt <[email protected]> Date: Sun Sep 28 17:06:12 2014 +0200 at: only retain variables whose name consists of alphanumerics and underscores Since a recent security update[1] bash might export variables named BASH_FUNC_*() to the environment which the serialization code in at cannot handle properly. [1] <https://www.debian.org/security/2014/dsa-3035> Index: at-3.1.8/at.c =================================================================== --- at-3.1.8.orig/at.c +++ at-3.1.8/at.c @@ -363,6 +363,22 @@ writefile(time_t runtimer, char queue) int export = 1; char *eqp; + /* Only accept alphanumerics and underscore in variable names. + * Also require the name to not start with a digit. + * Some shells don't like other variable names. + */ + { + char *p = *atenv; + if (isdigit(*p)) + export = 0; + for (; *p != '=' && *p != '\0'; ++p) { + if (!isalnum(*p) && *p != '_') { + export = 0; + break; + } + } + } + eqp = strchr(*atenv, '='); if (ap == NULL) eqp = *atenv; ++++++ at-3.1.13-selinux.patch ++++++ Index: atd.c =================================================================== --- atd.c.orig +++ atd.c @@ -81,10 +81,18 @@ #ifndef HAVE_GETLOADAVG #include "getloadavg.h" #endif +#ifdef WITH_SELINUX +#include <selinux/selinux.h> +#include <selinux/get_context_list.h> +int selinux_enabled=0; +#include <selinux/flask.h> +#include <selinux/av_permissions.h> +#endif + /* Macros */ #define BATCH_INTERVAL_DEFAULT 60 #define CHECK_INTERVAL 3600 @@ -193,10 +201,72 @@ 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) { /* Run a file by by spawning off a process which redirects I/O, * spawns a subshell, then waits for it to complete and sends @@ -440,13 +510,25 @@ run_file(const char *filename, uid_t uid if (SIG_ERR == signal(SIGCHLD, SIG_DFL)) perr("Cannot reset signal handler to default"); chdir("/"); - +#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 (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 +//end PRIV_END } /* We're the parent. Let's wait. */ @@ -715,10 +797,14 @@ main(int argc, char *argv[]) time_t next_invocation; struct sigaction act; 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. */ if ((pwe = getpwnam(DAEMON_USERNAME)) == NULL) Index: config.h.in =================================================================== --- config.h.in.orig +++ config.h.in @@ -69,10 +69,13 @@ #undef HAVE_NLIST_H /* Define to 1 for PAM support */ #undef HAVE_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 /* Define to 1 if you have the <security/pam_appl.h> header file. */ #undef HAVE_SECURITY_PAM_APPL_H Index: configure.ac =================================================================== --- configure.ac.orig +++ configure.ac @@ -257,7 +257,15 @@ AC_ARG_WITH(daemon_groupname, DAEMON_GROUPNAME=daemon AC_MSG_RESULT(daemon) ) AC_SUBST(DAEMON_GROUPNAME) +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_CONFIG_FILES(Makefile atrun atd.8 atrun.8 at.1 at.allow.5 batch) AC_OUTPUT Index: Makefile.in =================================================================== --- Makefile.in.orig +++ Makefile.in @@ -37,10 +37,12 @@ DEFS = @DEFS@ -DVERSION=\"$(VERSION)\" -DLFILE=\"$(LFILE)\" -Wall 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 RUNOBJECTS = atd.o daemon.o $(LIBOBJS) CSRCS = at.c atd.c panic.c perm.c posixtm.c daemon.c getloadavg.c \ @@ -69,11 +71,11 @@ at: $(ATOBJECTS) rm -f $(CLONES) $(LN_S) -f at atq $(LN_S) -f at atrm atd: $(RUNOBJECTS) - $(CC) $(CFLAGS) -o atd $(RUNOBJECTS) $(LIBS) $(PAMLIB) + $(CC) $(CFLAGS) -o atd $(RUNOBJECTS) $(LIBS) $(PAMLIB) $(SELINUXLIB) y.tab.c y.tab.h: parsetime.y $(YACC) -d parsetime.y lex.yy.c: parsetime.l ++++++ at-3.1.13-tomorrow.patch ++++++ Index: at-3.1.13/parsetime.y =================================================================== --- at-3.1.13.orig/parsetime.y +++ at-3.1.13/parsetime.y @@ -504,10 +504,15 @@ parsetime(time_t currtime, int argc, cha if (isgmt) { exectime -= timezone; if (currtm.tm_isdst && !exectm.tm_isdst) exectime -= 3600; } + /* exectime zeroes its seconds, thus we need +60, + * else "now" will be scheduled to tomorrow */ + if (currtime > exectime + 60) { + exectime += 24*3600; + } if (exectime < currtime) panic("refusing to create job destined in the past"); return exectime; } else { ++++++ at-3.1.13.patch ++++++ Index: Makefile.in =================================================================== --- Makefile.in.orig +++ Makefile.in @@ -84,39 +84,39 @@ atrun: atrun.in .c.o: $(CC) -c $(CFLAGS) $(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) -m 755 -d $(IROOT)$(etcdir) + $(INSTALL) -m 755 -d $(IROOT)$(bindir) + $(INSTALL) -m 755 -d $(IROOT)$(sbindir) + $(INSTALL) -m 755 -d $(IROOT)$(docdir) + $(INSTALL) -m 755 -d $(IROOT)$(atdocdir) + $(INSTALL) -m 755 -d $(IROOT)$(ATJOB_DIR) + $(INSTALL) -m 755 -d $(IROOT)$(ATSPOOL_DIR) + chmod 1770 $(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 640 at.deny $(IROOT)$(etcdir)/ + $(INSTALL) -m 6755 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" <atrun.8>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)/ - 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)/ + $(INSTALL) -m 644 at.deny.5 $(IROOT)$(man5dir)/ + $(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* dist: checkin $(DIST) $(LIST) Filelist.asc Index: Problems =================================================================== --- Problems.orig +++ Problems @@ -3,10 +3,10 @@ Possible reasons why at may not run for - HAVE you run ./configure ? If that fails for some mysterious reasons, you can also do a make -f Makefile.old install -- You may not have a user or group 'daemon' on your system. +- You may not have a user or group 'at' on your system. - If you find numerous 'try again' error messages in your syslog files, you have too many processes running; recompile your kernel for a larger number Index: atd.c =================================================================== --- atd.c.orig +++ atd.c @@ -314,11 +314,16 @@ run_file(const char *filename, uid_t uid jobno, filename); } if ((fflags = fcntl(fd_in, F_GETFD)) < 0) perr("Error in fcntl"); - fcntl(fd_in, F_SETFD, fflags & ~FD_CLOEXEC); + /* + ** fcntl(fd_in, F_SETFD, fflags & ~FD_CLOEXEC); + ** What's that? This fcntl() removes the CLOSE_ON_EXEC flag. + */ + if(fcntl(fd_in, F_SETFD, fflags | FD_CLOEXEC) < 0) + perr("Error in fcntl"); /* * 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 * opened as "root" but it is read as "daemon" which fails over @@ -431,10 +436,13 @@ run_file(const char *filename, uid_t uid perr("Cannot change group"); if (setuid(uid) < 0) perr("Cannot set user id"); + if (SIG_ERR == signal(SIGCHLD, SIG_DFL)) + perr("Cannot reset signal handler to default"); + chdir("/"); if (execle("/bin/sh", "sh", (char *) NULL, nenvp) != 0) perr("Exec failed for /bin/sh"); @@ -612,11 +620,12 @@ run_loop() if (run_time + CHECK_INTERVAL <= now) { /* Something went wrong the last time this was executed. * Let's remove the lockfile and reschedule. */ - strncpy(lock_name, dirent->d_name, sizeof(lock_name)); + strncpy(lock_name, dirent->d_name, sizeof(lock_name)-1); + lock_name[sizeof(lock_name)-1] = 0; lock_name[0] = '='; unlink(lock_name); next_job = now; nothing_to_do = 0; } @@ -646,11 +655,12 @@ run_loop() * at a higher priority than anything before, keep its * filename. */ run_batch++; if (strcmp(batch_name, dirent->d_name) > 0) { - strncpy(batch_name, dirent->d_name, sizeof(batch_name)); + strncpy(batch_name, dirent->d_name, sizeof(batch_name)-1); + batch_name[sizeof(batch_name)-1] = 0; batch_uid = buf.st_uid; batch_gid = buf.st_gid; batch_queue = queue; } } Index: configure.ac =================================================================== --- configure.ac.orig +++ configure.ac @@ -129,11 +129,11 @@ else fi AC_DEFINE_UNQUOTED(PIDFILE, "$PIDDIR/atd.pid", [What is the name of our PID file?]) AC_MSG_RESULT($PIDDIR) AC_MSG_CHECKING(location of spool directory) -if test -d /var/spool/atjobs ; then +if test -d /var/spool; then sp=/var/spool AC_MSG_RESULT(Using existing /var/spool/at{jobs|run}) elif test -d /var/spool/cron ; then sp=/var/spool/cron AC_MSG_RESULT(/var/spool/cron) ++++++ at-3.1.8-denylist.patch ++++++ --- at.deny.orig +++ at.deny @@ -1,24 +1,12 @@ -alias -backup +root bin daemon -ftp -games -gnats -guest -irc lp mail +news +uucp +games man +wwwrun +ftp nobody -operator -proxy -qmaild -qmaill -qmailp -qmailq -qmailr -qmails -sync -sys -www-data ++++++ at-3.1.8-eal3-manpages.patch ++++++ --- /dev/null +++ at.allow.5 @@ -0,0 +1,36 @@ +.Id $Id: at.allow.5,v 1.1 1997/09/28 20:00:28 ig25 Exp $ +.TH AT.ALLOW 5 "Sep 1997" "" "Linux Programmer's Manual" +.SH NAME +at.allow, at.deny \- determine who can submit jobs via at or batch +.SH DESCRIPTION +The +.I /etc/at.allow +and +.I /etc/at.deny +files determine which user can submit commands for later execution via +.BR at (1) +or +.BR batch (1) . +.PP +The format of the files is a list of usernames, one on each line. Whitespace +is not permitted. +.PP +The superuser may always use +.BR at . +.PP +If the file +.I /etc/at.allow +exists, only usernames mentioned in it are allowed to use +.BR at . +.PP +If +.I /etc/at.allow +does not exist, +.I /etc/at.deny +is checked. +.SH "SEE ALSO" +.BR at (1), +.BR atrun (1), +.BR cron (8), +.BR crontab (1), +.BR atd (8). --- /dev/null +++ at.deny.5 @@ -0,0 +1,36 @@ +.Id $Id: at.allow.5,v 1.1 1997/09/28 20:00:28 ig25 Exp $ +.TH AT.ALLOW 5 "Sep 1997" "" "Linux Programmer's Manual" +.SH NAME +at.allow, at.deny \- determine who can submit jobs via at or batch +.SH DESCRIPTION +The +.I /etc/at.allow +and +.I /etc/at.deny +files determine which user can submit commands for later execution via +.BR at (1) +or +.BR batch (1) . +.PP +The format of the files is a list of usernames, one on each line. Whitespace +is not permitted. +.PP +The superuser may always use +.BR at . +.PP +If the file +.I /etc/at.allow +exists, only usernames mentioned in it are allowed to use +.BR at . +.PP +If +.I /etc/at.allow +does not exist, +.I /etc/at.deny +is checked. +.SH "SEE ALSO" +.BR at (1), +.BR atrun (1), +.BR cron (8), +.BR crontab (1), +.BR atd (8). ++++++ at-3.1.8-jobdir-mtime.patch ++++++ Copyright (c) 2009 Ingo Schwarze <[email protected]> This patch is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Index: atd.c =================================================================== --- atd.c.orig +++ atd.c @@ -792,7 +792,7 @@ run_loop() if (stat(".", &buf) == -1) perr("Cannot stat " ATJOB_DIR); - if (nothing_to_do && buf.st_mtime <= last_chg) + if (nothing_to_do && buf.st_mtime == last_chg) return next_job; last_chg = buf.st_mtime; ++++++ at-adjust_load_to_cpu_count.patch ++++++ Index: at-3.1.16/at.1.in =================================================================== --- at-3.1.16.orig/at.1.in 2015-06-23 18:12:35.348993941 +0200 +++ at-3.1.16/at.1.in 2015-06-23 18:48:39.666401868 +0200 @@ -68,6 +68,9 @@ deletes jobs, identified by their job nu executes commands when system load levels permit; in other words, when the load average drops below @LOADAVG_MX@, or the value specified in the invocation of .BR atd . +Note that because of the load meaning on Linux, +this number is multiplied by the amount of CPUs when compared to the +system loadavg. .PP .B At allows fairly complex time Index: at-3.1.16/atd.c =================================================================== --- at-3.1.16.orig/atd.c 2015-06-23 18:12:35.353994001 +0200 +++ at-3.1.16/atd.c 2015-06-23 18:31:52.137058536 +0200 @@ -763,6 +763,7 @@ run_loop() int run_batch; static time_t next_batch = 0; double currlavg[3]; + int cpu_count = 1; /* Main loop. Open spool directory for reading and look over all the * files in there. If the filename indicates that the job should be run, @@ -907,7 +908,14 @@ run_loop() #ifdef GETLOADAVG_PRIVILEGED END_PRIV #endif - if (currlavg[0] < load_avg) { +#ifdef _SC_NPROCESSORS_ONLN + cpu_count = sysconf(_SC_NPROCESSORS_ONLN); + if (cpu_count < 1) { + cpu_count = 1; + } +#endif + + if (currlavg[0] < load_avg * cpu_count) { run_file(batch_name, batch_uid, batch_gid); run_batch--; } Index: at-3.1.16/atd.8.in =================================================================== --- at-3.1.16.orig/atd.8.in 2014-09-30 08:29:02.000000000 +0200 +++ at-3.1.16/atd.8.in 2015-06-23 18:48:17.519128303 +0200 @@ -20,10 +20,8 @@ runs jobs queued by .B -l Specifies a limiting load factor, over which batch jobs should not be run, instead of the compile-time choice of @LOADAVG_MX@. -For an SMP system with -.I n -CPUs, you will probably want to set this higher than -.IR n-1. +This number is multiplied by the amount of CPUs when comparing +to /proc/loadavg, because loadavg is a sum over all processors on Linux. .TP 8 .B -b Specify the minimum interval in seconds between the start of two ++++++ at-atq-timeformat.patch ++++++ Index: at.c =================================================================== --- at.c.orig 2014-07-29 09:01:10.198172629 +0200 +++ at.c 2014-07-29 09:01:10.202172629 +0200 @@ -132,9 +132,10 @@ char *namep; char atfile[] = ATJOB_DIR "/12345678901234"; -char *atinput = (char *) 0; /* where to get input from */ -char atqueue = 0; /* which queue to examine for jobs (atq) */ -char atverify = 0; /* verify time instead of queuing job */ +char *atinput = (char *) 0; /* where to get input from */ +char atqueue = 0; /* which queue to examine for jobs (atq) */ +char atverify = 0; /* verify time instead of queuing job */ +char *timeformat = TIMEFORMAT_POSIX; /* time format (atq) */ /* Function declarations */ @@ -494,7 +495,7 @@ runtime = localtime(&runtimer); - strftime(timestr, TIMESIZE, TIMEFORMAT_POSIX, runtime); + strftime(timestr, TIMESIZE, timeformat, runtime); fprintf(stderr, "job %ld at %s\n", jobno, timestr); /* Signal atd, if present. Usual precautions taken... */ @@ -608,7 +609,7 @@ runtimer = 60 * (time_t) ctm; runtime = localtime(&runtimer); - strftime(timestr, TIMESIZE, TIMEFORMAT_POSIX, runtime); + strftime(timestr, TIMESIZE, timeformat, runtime); if ((pwd = getpwuid(buf.st_uid))) printf("%ld\t%s %c %s\n", jobno, timestr, queue, pwd->pw_name); @@ -805,7 +806,7 @@ */ if (strcmp(pgm, "atq") == 0) { program = ATQ; - options = "hq:V"; + options = "hq:Vo:"; } else if (strcmp(pgm, "atrm") == 0) { program = ATRM; options = "hV"; @@ -889,6 +890,10 @@ timer -= timer % 60; break; + case 'o': + timeformat = optarg; + break; + default: usage(); break; Index: at.1.in =================================================================== --- at.1.in.orig 2014-07-29 09:01:10.114172631 +0200 +++ at.1.in 2014-07-29 09:01:10.202172629 +0200 @@ -29,6 +29,8 @@ .RB [ -V ] .RB [ -q .IR queue ] +.RB [ -o +.IR timeformat ] .br .B at .RB [ -rd ] @@ -254,6 +256,9 @@ .B \-c cats the jobs listed on the command line to standard output. +.TP 8 +.BI \-o " fmt" +strftime-like time format used for the job list .SH FILES .I @ATJBD@ .br Index: panic.c =================================================================== --- panic.c.orig 2014-07-29 09:01:10.074172631 +0200 +++ panic.c 2014-07-29 09:01:10.202172629 +0200 @@ -96,7 +96,7 @@ " at [-V] [-q x] [-f file] [-mlbv] -t time\n" " at -c job ...\n" " at [-V] -l [job ...]\n" - " atq [-V] [-q x]\n" + " atq [-V] [-q x] [-o timeformat]\n" " at [ -rd ] job ...\n" " atrm [-V] job ...\n" " batch\n"); ++++++ at-backport-old-privs.patch ++++++ From: Michal Vyskocil <[email protected]> Subject: Backport old privs at since 3.10 have substantially changed the priviledge model, which is tied to Debian setup of at. As SUSE does use a different layout, this patch introduces back the PRIV_START/PRIV_END + fchown where needed. References: https://bugzilla.novell.com/show_bug.cgi?id=849720 --- at.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) Index: at-3.1.13/at.c =================================================================== --- at-3.1.13.orig/at.c +++ at-3.1.13/at.c @@ -154,18 +154,11 @@ sigc(int signo) /* If the user presses ^C, remove the spool file and exit */ 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); } @@ -325,18 +318,14 @@ writefile(time_t runtimer, char queue) * bit. Yes, this is a kluge. */ cmask = umask(S_IRUSR | S_IWUSR | S_IXUSR); - seteuid(real_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); 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 @@ -679,11 +668,7 @@ process_jobs(int argc, char **argv, int switch (what) { case ATRM: - /* - We need the unprivileged uid here since the file is owned by the real - (not effective) uid. - */ - setregid(real_gid, effective_gid); + PRIV_START if (queue == '=') { fprintf(stderr, "Warning: deleting running job\n"); @@ -693,7 +678,7 @@ process_jobs(int argc, char **argv, int rc = EXIT_FAILURE; } - setregid(effective_gid, real_gid); + PRIV_END done = 1; break; @@ -703,21 +688,25 @@ process_jobs(int argc, char **argv, int FILE *fp; int ch; - setregid(real_gid, effective_gid); - fp = fopen(dirent->d_name, "r"); + PRIV_START + + fp = fopen(dirent->d_name, "r"); + + PRIV_END if (fp) { while ((ch = getc(fp)) != EOF) { putchar(ch); } done = 1; + PRIV_START fclose(fp); + PRIV_END } else { perr("Cannot open %.500s", dirent->d_name); rc = EXIT_FAILURE; } - setregid(effective_gid, real_gid); } break; ++++++ at-makefile-deps.patch ++++++ Index: at-3.1.13/Makefile.in =================================================================== --- at-3.1.13.orig/Makefile.in +++ at-3.1.13/Makefile.in @@ -75,9 +75,12 @@ at: $(ATOBJECTS) atd: $(RUNOBJECTS) $(CC) $(CFLAGS) -o atd -pie $(RUNOBJECTS) $(LIBS) $(PAMLIB) $(SELINUXLIB) -y.tab.c y.tab.h: parsetime.y +y.tab.c y.tab.h: stamp-yacc; @: +stamp-yacc: parsetime.y $(YACC) -d parsetime.y + touch $@ +lex.yy.o: y.tab.h lex.yy.c: parsetime.l $(LEX) -i parsetime.l ++++++ at-parse-suse-sysconfig.patch ++++++ From: Cristian Rodr�guez <[email protected]> Last updated by: Jan Engelhardt <[email protected]> http://bugzilla.novell.com/780259 --- Makefile.in | 4 ++-- atd.c | 21 +++++++++++++++++++++ configure.in | 44 +++++++++++++++++++++++++++----------------- 3 files changed, 50 insertions(+), 19 deletions(-) Index: at-3.1.13/Makefile.in =================================================================== --- at-3.1.13.orig/Makefile.in +++ at-3.1.13/Makefile.in @@ -25,19 +25,19 @@ LN_S = @LN_S@ YACC = @YACC@ LEX = @LEX@ LEXLIB = @LEXLIB@ CC = @CC@ -CFLAGS = -I$(srcdir) @CFLAGS@ +CFLAGS = -I$(srcdir) @CFLAGS@ @HX_CFLAGS@ LDFLAGS = @LDFLAGS@ LFILE = $(ATJOB_DIR)/.SEQ DEFS = @DEFS@ -DVERSION=\"$(VERSION)\" \ -DETCDIR=\"$(etcdir)\" -DLOADAVG_MX=$(LOADAVG_MX) \ -DDAEMON_USERNAME=\"$(DAEMON_USERNAME)\" \ -DDAEMON_GROUPNAME=\"$(DAEMON_GROUPNAME)\" \ -DLFILE=\"$(LFILE)\" -Wall -LIBS = @LIBS@ +LIBS = @LIBS@ @HX_LIBS@ LIBOBJS = @LIBOBJS@ INSTALL = @INSTALL@ PAMLIB = @PAMLIB@ SELINUXLIB = @SELINUXLIB@ Index: at-3.1.13/atd.c =================================================================== --- at-3.1.13.orig/atd.c +++ at-3.1.13/atd.c @@ -72,10 +72,14 @@ #ifdef HAVE_UNISTD_H #include <syslog.h> #endif +#include <libHX/defs.h> +#include <libHX/map.h> +#include <libHX/option.h> + /* Local headers */ #include "privs.h" #include "daemon.h" @@ -956,10 +960,11 @@ main(int argc, char *argv[]) * For those files which are to be executed, run_file() is called, which forks * off a child which takes care of I/O redirection, forks off another child * for execution and yet another one, optionally, for sending mail. * Files which already have run are removed during the next invocation. */ + struct HXmap *sc_map; int c; time_t next_invocation; struct sigaction act; struct passwd *pwe; struct group *ge; @@ -1024,10 +1029,26 @@ main(int argc, char *argv[]) pabort("idiotic option - aborted"); break; } } + sc_map = HX_shconfig_map("/etc/sysconfig/atd"); + if (sc_map != NULL) { + char *v; + + v = HXmap_get(sc_map, "ATD_BATCH_INTERVAL"); + if (v != NULL && strlen(v) > 0) { + batch_interval = strtol(v, NULL, 0); + syslog(LOG_INFO, "sysconfig requested batch_interval to be set to %d\n", batch_interval); + } + v = HXmap_get(sc_map, "ATD_LOADAVG"); + if (v != NULL && strlen(v) > 0) { + load_avg = strtod(v, NULL); + syslog(LOG_INFO, "sysconfig requested load_avg to be set to %f\n", load_avg); + } + } + namep = argv[0]; if (chdir(ATJOB_DIR) != 0) perr("Cannot change to " ATJOB_DIR); if (optind < argc) Index: at-3.1.13/configure.ac =================================================================== --- at-3.1.13.orig/configure.ac +++ at-3.1.13/configure.ac @@ -3,11 +3,11 @@ dnl Process this file with autoconf to p AC_INIT(at, 3.1.13) AC_CONFIG_SRCDIR(at.c) AC_PREFIX_DEFAULT(/usr) AC_CONFIG_HEADER(config.h) -AC_PREREQ([2.64]) +AC_PREREQ([2.69]) VERSION=AC_PACKAGE_VERSION if test "X$CFLAGS" = "X"; then CFLAGS="-O2 -g -Wall" fi @@ -37,41 +37,50 @@ case "$host" in *) AC_MSG_RESULT(no) ;; esac AC_MSG_CHECKING(Trying to compile a trivial ANSI C program) -AC_TRY_RUN([ main(int ac, char **av) { return 0; } ], - AC_MSG_RESULT(yes), - AC_MSG_RESULT(no) - AC_MSG_ERROR(Could not compile and run even a trivial ANSI C program - check CC.), - AC_MSG_ERROR(Could not compile and run even a trivial ANSI C program - check CC.)) +AC_RUN_IFELSE([AC_LANG_SOURCE([[ main(int ac, char **av) { return 0; } ]])],[AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no) + AC_MSG_ERROR(Could not compile and run even a trivial ANSI C program - check CC.)],[AC_MSG_ERROR(Could not compile and run even a trivial ANSI C program - check CC.)]) AC_MSG_CHECKING(__attribute__((noreturn))) -AC_TRY_COMPILE([], [void __attribute__((noreturn)) panic(void);], +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[void __attribute__((noreturn)) panic(void);]])],[ AC_MSG_RESULT(yes) AC_DEFINE(HAVE_ATTRIBUTE_NORETURN, 1, [Define to 1 if compiler supports __attribute__((noreturn))]), AC_MSG_RESULT(no) -) +]) dnl Checks for libraries. AC_CHECK_LIB(fl,yywrap, - [], - AC_DEFINE(NEED_YYWRAP, 1, - [Define to 1 if we need to provide our own yywrap()]) + [], + AC_DEFINE([NEED_YYWRAP], 1, [need yywrap]) ) +PKG_CHECK_MODULES([HX], [libHX]) + dnl Checks for header files. AC_HEADER_DIRENT AC_HEADER_STDC AC_HEADER_SYS_WAIT AC_CHECK_HEADERS(fcntl.h syslog.h unistd.h errno.h sys/fcntl.h getopt.h) AC_CHECK_HEADERS(stdarg.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST -AC_TYPE_SIGNAL +AC_DIAGNOSE([obsolete],[your code may safely assume C89 semantics that RETSIGTYPE is void. +Remove this warning and the `AC_CACHE_CHECK' when you adjust the code.])dnl +AC_CACHE_CHECK([return type of signal handlers],[ac_cv_type_signal],[AC_COMPILE_IFELSE( +[AC_LANG_PROGRAM([#include <sys/types.h> +#include <signal.h> +], + [return *(signal (0, 0)) (0) == 1;])], + [ac_cv_type_signal=int], + [ac_cv_type_signal=void])]) +AC_DEFINE_UNQUOTED([RETSIGTYPE],[$ac_cv_type_signal],[Define as the return type of signal handlers + (`int' or `void').]) + AC_TYPE_UID_T AC_TYPE_MODE_T AC_TYPE_OFF_T AC_TYPE_PID_T AC_TYPE_SIZE_T @@ -258,20 +267,20 @@ AC_ARG_WITH(daemon_groupname, AC_MSG_RESULT(daemon) ) AC_SUBST(DAEMON_GROUPNAME) AC_ARG_WITH(selinux, -[ --with-selinux Define to run with selinux], -AC_DEFINE(WITH_SELINUX), +[ --with-selinux Define to run with selinux], +AC_DEFINE([WITH_SELINUX] , [1], [enable 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_DEFINE([WITH_PAM], [1], [use PAM]), ) AC_CHECK_LIB(pam, pam_start, PAMLIB='-lpam -lpam_misc') AC_SUBST(PAMLIB) AC_CONFIG_FILES(Makefile atrun atd.8 atrun.8 at.1 at.allow.5 batch) ++++++ at-piddir.patch ++++++ --- configure.ac.orig +++ configure.ac @@ -136,6 +136,7 @@ elif test -d /usr/run ; then else PIDDIR="$ETCDIR" fi +PIDDIR=/run AC_DEFINE_UNQUOTED(PIDFILE, "$PIDDIR/atd.pid", [What is the name of our PID file?]) AC_MSG_RESULT($PIDDIR) ++++++ at-secure_getenv.patch ++++++ --- at-3.1.13.orig/configure.ac +++ at-3.1.13/configure.ac @@ -17,8 +17,9 @@ AC_SUBST(VERSION) AC_CANONICAL_HOST dnl Checks for programs. - -AC_PROG_CC +AC_USE_SYSTEM_EXTENSIONS +AC_PROG_CC_STDC +AC_SYS_LARGEFILE AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_YACC @@ -58,6 +59,7 @@ AC_CHECK_LIB(fl,yywrap, PKG_CHECK_MODULES([HX], [libHX]) +AC_CHECK_FUNCS([__secure_getenv secure_getenv]) dnl Checks for header files. AC_HEADER_DIRENT AC_HEADER_STDC --- at-3.1.13.orig/at.c +++ at-3.1.13/at.c @@ -97,6 +97,14 @@ #define DEFAULT_QUEUE 'a' #define BATCH_QUEUE 'b' +#ifndef HAVE_SECURE_GETENV +# ifdef HAVE___SECURE_GETENV +# define secure_getenv __secure_getenv +# else +# error neither secure_getenv nor __secure_getenv is available +# endif +#endif + enum { ATQ, BATCH, ATRM, AT, CAT }; /* what program we want to run */ @@ -359,7 +367,7 @@ writefile(time_t runtimer, char queue) */ mailname = getlogin(); if (mailname == NULL) - mailname = getenv("LOGNAME"); + mailname = secure_getenv("LOGNAME"); if (mailname == NULL || mailname[0] == '\0' || getpwnam(mailname) == NULL) { pass_entry = getpwuid(real_uid); if (pass_entry != NULL) ++++++ at.sleep ++++++ #!/bin/sh case $1/$2 in pre/*) systemctl --quiet is-enabled atd && systemctl stop atd ;; post/*) systemctl --quiet is-enabled atd && systemctl restart atd ;; esac ++++++ atd.init ++++++ #! /bin/sh # Copyright (c) 1995-2002 SuSE GmbH Nuernberg, Germany. # # Author: Kurt Garloff <[email protected]> # # /etc/init.d/at # # and symbolic its link # # /sbin/rcat # # System startup script for the at daemon # ### BEGIN INIT INFO # Provides: at # Required-Start: $remote_fs $time # Required-Stop: $remote_fs # X-UnitedLinux-Default-Enabled: no # Default-Start: 2 3 5 # Default-Stop: 0 1 6 # Description: Start AT batch job daemon ### END INIT INFO ATD_BIN=/usr/sbin/atd test -x $ATD_BIN || exit 5 ATD_CONFIG=/etc/sysconfig/atd test -r $ATD_CONFIG && source /etc/sysconfig/atd # Shell functions sourced from /etc/rc.status: # rc_check check and set local and overall rc status # rc_status check and set local and overall rc status # rc_status -v ditto but be verbose in local rc status # rc_status -v -r ditto and clear the local rc status # rc_failed set local and overall rc status to failed # rc_failed <num> set local and overall rc status to <num><num> # rc_reset clear local rc status (overall remains) # rc_exit exit appropriate to overall rc status . /etc/rc.status # First reset status of this service rc_reset # Return values acc. to LSB for all commands but status: # 0 - success # 1 - generic or unspecified error # 2 - invalid or excess argument(s) # 3 - unimplemented feature (e.g. "reload") # 4 - insufficient privilege # 5 - program is not installed # 6 - program is not configured # 7 - program is not running # # Note that starting an already running service, stopping # or restarting a not-running service as well as the restart # with force-reload (in case signalling is not supported) are # considered a success. case "$1" in start) echo -n "Starting service at daemon" ATD_ARGS="" if [ -n "$ATD_BATCH_INTERVAL" ]; then ATD_ARGS="-b $ATD_BATCH_INTERVAL"; fi if [ -n "$ATD_LOADAVG" ]; then ATD_ARGS="$ATD_ARGS -l $ATD_LOADAVG" fi ## Start daemon with startproc(8). If this fails ## the echo return value is set appropriate. # NOTE: startproc return 0, even if service is # already running to match LSB spec. startproc $ATD_BIN $ATD_ARGS # Remember status and be verbose rc_status -v ;; stop) echo -n "Shutting down service at daemon" ## Stop daemon with killproc(8) and if this fails ## set echo the echo return value. killproc -TERM $ATD_BIN # Remember status and be verbose rc_status -v ;; try-restart) ## Stop the service and if this succeeds (i.e. the ## service was running before), start it again. ## Note: try-restart is not (yet) part of LSB (as of 0.7.5) $0 status >/dev/null && $0 restart # Remember status and be quiet rc_status ;; restart) ## Stop the service and regardless of whether it was ## running or not, start it again. $0 stop $0 start # Remember status and be quiet rc_status ;; force-reload) ## Signal the daemon to reload its config. Most daemons ## do this on signal 1 (SIGHUP). ## If it does not support it, restart. echo -n "Reload service at daemon" ## Otherwise: $0 stop && $0 start rc_status ;; reload) ## Like force-reload, but if daemon does not support ## signalling, do nothing (!) # If it supports signalling: echo -n "Reload service at daemon" ## Otherwise if it does not support reload: rc_failed 3 rc_status -v ;; status) echo -n "Checking for at daemon: " ## Check status with checkproc(8), if process is running ## checkproc will return with exit status 0. # Status has a slightly different for the status command: # 0 - service running # 1 - service dead, but /var/run/ pid file exists # 2 - service dead, but /var/lock/ lock file exists # 3 - service not running # NOTE: checkproc returns LSB compliant status values. checkproc $ATD_BIN rc_status -v ;; *) echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload}" exit 1 ;; esac rc_exit ++++++ atd.pamd ++++++ # # The PAM configuration file for the at daemon # # auth sufficient pam_rootok.so auth include common-auth account include common-account password include common-password session include common-session ++++++ atd.service ++++++ [Unit] Description=Execution Queue Daemon After=systemd-user-sessions.service [Service] ExecStart=/usr/sbin/atd -f [Install] WantedBy=multi-user.target ++++++ sysconfig.atd ++++++ ## Path: System/At ## Description: minimum interval between start of two batch jobs ## Type: string ## Default: "" ## ServiceRestart: atd # # minimum interval between start of two batch jobs, "" for default # ATD_BATCH_INTERVAL="" ## Path: System/At ## Description: load limiting factor for atd ## Type: string ## Default: "" ## ServiceRestart: atd # load limiting factor for atd, "" for default # ATD_LOADAVG=""
