new upstream release fixing regression from security fix in bash

- drop sysvinit subpackage
This commit is contained in:
Tomas Mraz 2014-10-02 11:10:27 +02:00
parent 107aa1f03b
commit ad609f98fc
22 changed files with 17 additions and 1641 deletions

4
.gitignore vendored
View File

@ -1,9 +1,7 @@
at_3.1.10.tar.gz
atd.init
atd.sysconf
test.pl
at_3.1.11.orig.tar.gz
at_3.1.12.orig.tar.gz
pam_atd
/at_3.1.13.orig.tar.gz
/at_3.1.14.orig.tar.gz
/at_3.1.16.orig.tar.gz

18
56atd
View File

@ -1,18 +0,0 @@
#!/bin/sh
#
. "${PM_FUNCTIONS}"
case "$1" in
hibernate|suspend)
;;
thaw|resume)
if [ -f /etc/init.d/atd ]; then
/etc/init.d/atd restart
else
systemctl try-restart atd.service
fi
;;
*) exit $NA
;;
esac

View File

@ -1,12 +0,0 @@
--- at-3.1.10/pam_atd.pam 2007-07-03 13:29:24.000000000 +0200
+++ at-3.1.10/pam_atd 2007-07-03 13:29:24.000000000 +0200
@@ -0,0 +1,9 @@
+# The PAM configuration file for the at daemon
+#
+#
+auth required pam_env.so
+auth include password-auth
+account required pam_access.so
+account include password-auth
+session required pam_loginuid.so
+session include password-auth

View File

@ -1,69 +0,0 @@
diff -up at-3.1.12/atd.c.fix at-3.1.12/atd.c
--- at-3.1.12/atd.c.fix 2010-01-18 14:22:19.364913059 +0100
+++ at-3.1.12/atd.c 2010-01-18 14:20:17.867912485 +0100
@@ -458,11 +458,9 @@ run_file(const char *filename, uid_t uid
size = buf.st_size;
#ifdef WITH_PAM
- PRIV_START
- PAM_HANDLING;
+ PAM_HANDLING;
closelog();
openlog("atd", LOG_PID, LOG_ATD);
- PRIV_END
#endif
close(STDIN_FILENO);
@@ -484,7 +482,6 @@ run_file(const char *filename, uid_t uid
if ( ( pam_envp != 0L ) && (pam_envp[0] != 0L) )
nenvp = pam_envp;
#endif
- PRIV_END
/* Set up things for the child; we want standard input from the
* input file, and standard output and error sent to our output file.
*/
@@ -505,8 +502,6 @@ run_file(const char *filename, uid_t uid
if (chdir(ATJOB_DIR) < 0)
perr("Cannot chdir to " ATJOB_DIR);
- PRIV_START
-
nice((tolower((int) queue) - 'a' + 1) * 2);
if (initgroups(pentry->pw_name, pentry->pw_gid))
@@ -531,6 +526,17 @@ run_file(const char *filename, uid_t uid
if (execle("/bin/sh", "sh", (char *) NULL, nenvp) != 0)
perr("Exec failed for /bin/sh");
+
+//add for fedora
+#ifdef WITH_SELINUX
+ if (selinux_enabled>0)
+ if (setexeccon(NULL) < 0)
+ if (security_getenforce()==1)
+ perr("Could not resset exec context for user %s\n", pentry->pw_name);
+
+#endif
+//end
+//add for fedora
#ifdef WITH_PAM
if ( ( nenvp != &nul ) && (pam_envp != 0L) && (*pam_envp != 0L))
{
@@ -553,7 +559,7 @@ run_file(const char *filename, uid_t uid
return with an ECHILD error.
*/
waitpid(pid, (int *) NULL, 0);
-
+/*
#ifdef WITH_PAM
PRIV_START
pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT);
@@ -561,7 +567,7 @@ run_file(const char *filename, uid_t uid
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.
*/

View File

@ -1,15 +0,0 @@
diff -up at-3.1.12/at.c.noexport at-3.1.12/at.c
--- at-3.1.12/at.c.noexport 2011-06-10 14:21:04.000000000 +0200
+++ at-3.1.12/at.c 2011-06-10 14:22:54.247712577 +0200
@@ -391,8 +391,9 @@ writefile(time_t runtimer, char queue)
unsigned int i;
for (i = 0; i < sizeof(no_export) / sizeof(no_export[0]); i++) {
export = export
- && (strncmp(*atenv, no_export[i],
- (size_t) (eqp - *atenv)) != 0);
+ && ((((size_t) (eqp - *atenv)) != strlen(no_export[i]))
+ ||(strncmp(*atenv, no_export[i],(size_t) (eqp - *atenv)) != 0)
+ );
}
eqp++;
}

View File

@ -1,83 +0,0 @@
diff -up at-3.1.12/Makefile.in.make at-3.1.12/Makefile.in
--- at-3.1.12/Makefile.in.make 2009-11-23 16:11:52.000000000 +0100
+++ at-3.1.12/Makefile.in 2009-12-03 13:23:08.794258910 +0100
@@ -65,13 +65,13 @@ LIST = Filelist Filelist.asc
all: at atd atrun
at: $(ATOBJECTS)
- $(CC) $(CFLAGS) -o at $(ATOBJECTS) $(LIBS) $(LEXLIB)
+ $(CC) $(CFLAGS) -o at -pie $(ATOBJECTS) $(LIBS) $(LEXLIB) $(SELINUXLIB) $(PAMLIB)
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 -pie $(RUNOBJECTS) $(LIBS) $(SELINUXLIB) $(PAMLIB)
y.tab.c y.tab.h: parsetime.y
$(YACC) -d parsetime.y
@@ -83,38 +83,42 @@ 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) -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)$(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 -s 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 -s 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)/
+ $(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*

View File

@ -1,121 +0,0 @@
diff -up at-3.1.12/at.1.in.nit at-3.1.12/at.1.in
--- at-3.1.12/at.1.in.nit 2009-11-23 16:11:52.000000000 +0100
+++ at-3.1.12/at.1.in 2010-01-18 14:43:58.287163082 +0100
@@ -121,7 +121,7 @@ and to run a job at 1am tomorrow, you wo
.B at 1am tomorrow.
.PP
The exact definition of the time specification can be found in
-.IR @prefix@/share/doc/at/timespec .
+.IR @prefix@/share/doc/at-@VERSION@/timespec .
.PP
For both
.BR at " and " batch ,
@@ -216,7 +216,7 @@ queue for
.BR batch .
Queues with higher letters run with increased niceness. The special
queue "=" is reserved for jobs which are currently running.
-.P
+
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
@@ -253,7 +253,7 @@ is an alias for
.TP
.B \-v
Shows the time the job will be executed before reading the job.
-.P
+
Times displayed will be in the format "Thu Feb 20 14:50:00 1997".
.TP
.B
diff -up at-3.1.12/atd.c.nit at-3.1.12/atd.c
--- at-3.1.12/atd.c.nit 2009-11-23 16:11:52.000000000 +0100
+++ at-3.1.12/atd.c 2010-01-18 14:42:58.024161433 +0100
@@ -83,6 +83,9 @@
#include "getloadavg.h"
#endif
+#ifndef LOG_ATD
+#define LOG_ATD LOG_DAEMON
+#endif
/* Macros */
#define BATCH_INTERVAL_DEFAULT 60
@@ -194,6 +197,18 @@ myfork()
#define fork myfork
#endif
+#undef ATD_MAIL_PROGRAM
+#undef ATD_MAIL_NAME
+#if defined(SENDMAIL)
+#define ATD_MAIL_PROGRAM SENDMAIL
+#define ATD_MAIL_NAME "sendmail"
+#elif defined(MAILC)
+#define ATD_MAIL_PROGRAM MAILC
+#define ATD_MAIL_NAME "mail"
+#elif defined(MAILX)
+#define ATD_MAIL_PROGRAM MAILX
+#define ATD_MAIL_NAME "mailx"
+#endif
static void
run_file(const char *filename, uid_t uid, gid_t gid)
@@ -276,6 +291,9 @@ run_file(const char *filename, uid_t uid
free(newname);
return;
}
+
+ (void) setsid(); //own session for process
+
/* 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.
@@ -435,6 +453,9 @@ run_file(const char *filename, uid_t uid
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)
@@ -503,6 +524,9 @@ run_file(const char *filename, uid_t uid
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 defined(SENDMAIL)
@@ -617,6 +641,7 @@ run_loop()
* 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[0] = '=';
unlink(lock_name);
next_job = now;
@@ -651,6 +676,7 @@ run_loop()
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_uid = buf.st_uid;
batch_gid = buf.st_gid;
batch_queue = queue;
@@ -725,11 +751,7 @@ main(int argc, char *argv[])
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;

View File

@ -1,19 +0,0 @@
diff -up at-3.1.12/at.c.nowrap at-3.1.12/at.c
--- at-3.1.12/at.c.nowrap 2010-02-18 14:39:50.125518422 +0100
+++ at-3.1.12/at.c 2010-02-22 13:20:03.817150406 +0100
@@ -308,10 +308,13 @@ writefile(time_t runtimer, char queue)
if (*ap == ' ')
*ap = '0';
- if (stat(atfile, &statbuf) != 0)
+ /*if (stat(atfile, &statbuf) != 0) {
if (errno != ENOENT)
perr("Cannot access " ATJOB_DIR);
-
+ } else {
+ perr("atjob file already exists; bailing");
+ }
+ */
/* Create the file. The x bit is only going to be set after it has
* been completely written out, to make sure it is not executed in the
* meantime. To make sure they do not get deleted, turn off their r

View File

@ -1,17 +0,0 @@
diff -up at-3.1.12/at.c.opt_V at-3.1.12/at.c
--- at-3.1.12/at.c.opt_V 2009-11-23 16:11:52.000000000 +0100
+++ at-3.1.12/at.c 2009-12-02 13:20:29.770215516 +0100
@@ -853,10 +853,9 @@ main(int argc, char **argv)
*/
if (disp_version) {
- fprintf(stderr, "at version " VERSION "\n"
- "Please report bugs to the Debian bug tracking system (http://bugs.debian.org/)\n"
- "or contact the maintainers (at@packages.debian.org).\n");
- exit(EXIT_SUCCESS);
+ fprintf(stderr, "at version " VERSION "\n");
+ if (argc == 2)
+ exit(EXIT_SUCCESS);
}
/* select our program

View File

@ -1,430 +0,0 @@
diff -up at-3.1.12/at.c.pam at-3.1.12/at.c
--- at-3.1.12/at.c.pam 2010-03-15 09:57:27.043438000 +0100
+++ at-3.1.12/at.c 2010-03-15 09:58:12.426689166 +0100
@@ -141,18 +141,13 @@ 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);
- /*
+ unlink(atfile);
PRIV_END
- */
}
exit(EXIT_FAILURE);
}
@@ -318,26 +313,19 @@ writefile(time_t runtimer, char queue)
* 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)
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");
- */
+ perr("Cannot give real_uid and real_gid the file");
PRIV_END
- /* We no longer need suid root; now we just need to be able to write
- * to the directory, if necessary.
- */
-
- REDUCE_PRIV(daemon_uid, daemon_gid)
/* We've successfully created the file; let's set the flag so it
* gets removed in case of an interrupt or error.
*/
@@ -661,7 +649,7 @@ process_jobs(int argc, char **argv, int
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");
@@ -670,8 +658,8 @@ process_jobs(int argc, char **argv, int
perr("Cannot unlink %.500s", dirent->d_name);
rc = EXIT_FAILURE;
}
+ PRIV_END
- setregid(effective_gid, real_gid);
done = 1;
break;
@@ -681,7 +669,7 @@ process_jobs(int argc, char **argv, int
FILE *fp;
int ch;
- setregid(real_gid, effective_gid);
+ PRIV_START
fp = fopen(dirent->d_name, "r");
if (fp) {
@@ -694,7 +682,7 @@ process_jobs(int argc, char **argv, int
perr("Cannot open %.500s", dirent->d_name);
rc = EXIT_FAILURE;
}
- setregid(effective_gid, real_gid);
+ PRIV_END
}
break;
diff -up at-3.1.12/atd.c.pam at-3.1.12/atd.c
--- at-3.1.12/atd.c.pam 2010-03-15 09:57:27.047513895 +0100
+++ at-3.1.12/atd.c 2010-03-15 09:57:27.053437466 +0100
@@ -111,7 +111,7 @@ 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;
@@ -120,15 +120,7 @@ static const struct pam_conv conv = {
NULL
};
-#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_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
@@ -234,7 +226,7 @@ run_file(const char *filename, uid_t uid
char queue;
char fmt[64];
unsigned long jobno;
-#ifdef HAVE_PAM
+#ifdef WITH_PAM
int retcode;
#endif
@@ -395,16 +387,11 @@ run_file(const char *filename, uid_t uid
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_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_HANDLING;
+ closelog();
+ openlog("atd", LOG_PID, LOG_ATD);
PRIV_END
#endif
@@ -419,7 +406,15 @@ run_file(const char *filename, uid_t uid
else if (pid == 0) {
char *nul = NULL;
char **nenvp = &nul;
+ char **pam_envp=0L;
+ PRIV_START
+#ifdef WITH_PAM
+ pam_envp = pam_getenvlist(pamh);
+ if ( ( pam_envp != 0L ) && (pam_envp[0] != 0L) )
+ nenvp = pam_envp;
+#endif
+ PRIV_END
/* Set up things for the child; we want standard input from the
* input file, and standard output and error sent to our output file.
*/
@@ -460,7 +455,16 @@ run_file(const char *filename, uid_t uid
if (execle("/bin/sh", "sh", (char *) NULL, nenvp) != 0)
perr("Exec failed for /bin/sh");
-
+#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.
@@ -474,7 +478,7 @@ run_file(const char *filename, uid_t uid
*/
waitpid(pid, (int *) NULL, 0);
-#ifdef HAVE_PAM
+#ifdef WITH_PAM
PRIV_START
pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT);
retcode = pam_close_session(pamh, PAM_SILENT);
@@ -503,6 +507,14 @@ run_file(const char *filename, uid_t uid
if (fd_in != STDOUT_FILENO && fd_in != STDERR_FILENO)
close(fd_in);
+#ifdef WITH_PAM
+ pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT );
+ pam_close_session(pamh, PAM_SILENT);
+ pam_end(pamh, PAM_ABORT);
+ closelog();
+ openlog("atd", LOG_PID, LOG_ATD);
+#endif
+
unlink(filename);
/* The job is now finished. We can delete its input file.
@@ -511,8 +523,19 @@ run_file(const char *filename, uid_t uid
unlink(newname);
free(newname);
+#ifdef ATD_MAIL_PROGRAM
if (((send_mail != -1) && (buf.st_size != size)) || (send_mail == 1)) {
+ int mail_pid = -1;
+#ifdef WITH_PAM
+ PAM_HANDLING;
+ closelog();
+ openlog("atd", LOG_PID, LOG_ATD);
+#endif
+
+ mail_pid = fork();
+ if ( mail_pid == 0 )
+ {
PRIV_START
if (initgroups(pentry->pw_name, pentry->pw_gid))
@@ -537,7 +560,23 @@ run_file(const char *filename, uid_t uid
perr("Exec failed for mail command");
PRIV_END
+ }
+ else if ( mail_pid == -1 ) {
+ perr("fork of mailer failed");
+ }
+ else {
+ /* Parent */
+ waitpid(mail_pid, (int *) NULL, 0);
+ }
+#ifdef WITH_PAM
+ pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT );
+ pam_close_session(pamh, PAM_SILENT);
+ pam_end(pamh, PAM_ABORT);
+ closelog();
+ openlog("atd", LOG_PID, LOG_ATD);
+#endif
}
+#endif
exit(EXIT_SUCCESS);
}
diff -up at-3.1.12/config.h.in.pam at-3.1.12/config.h.in
--- at-3.1.12/config.h.in.pam 2009-11-23 16:11:52.000000000 +0100
+++ at-3.1.12/config.h.in 2010-03-15 09:57:27.054437183 +0100
@@ -68,8 +68,8 @@
/* Define to 1 if you have the <nlist.h> header file. */
#undef HAVE_NLIST_H
-/* Define to 1 for PAM support */
-#undef HAVE_PAM
+/* Define if you are building with_pam */
+#undef WITH_PAM
/* Define to 1 if you have the `pstat_getdynamic' function. */
#undef HAVE_PSTAT_GETDYNAMIC
diff -up at-3.1.12/configure.ac.pam at-3.1.12/configure.ac
--- at-3.1.12/configure.ac.pam 2009-11-23 16:11:52.000000000 +0100
+++ at-3.1.12/configure.ac 2010-03-15 09:57:27.055443883 +0100
@@ -84,7 +84,7 @@ AC_FUNC_GETLOADAVG
AC_CHECK_FUNCS(getcwd mktime strftime setreuid setresuid sigaction waitpid)
AC_CHECK_HEADERS(security/pam_appl.h, [
PAMLIB="-lpam"
- AC_DEFINE(HAVE_PAM, 1, [Define to 1 for PAM support])
+ AC_DEFINE(WITH_PAM, 1, [Define to 1 for PAM support])
])
dnl Checking for programs
@@ -238,6 +238,13 @@ AC_ARG_WITH(daemon_username,
)
AC_SUBST(DAEMON_USERNAME)
+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_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.12/perm.c.pam at-3.1.12/perm.c
--- at-3.1.12/perm.c.pam 2009-11-23 16:11:52.000000000 +0100
+++ at-3.1.12/perm.c 2010-03-15 09:57:27.055443883 +0100
@@ -51,6 +51,14 @@
#define PRIV_END while(0)
#endif
+#ifdef WITH_PAM
+#include <security/pam_appl.h>
+static pam_handle_t *pamh = NULL;
+static const struct pam_conv conv = {
+ NULL
+};
+#endif
+
/* Structures and unions */
@@ -108,18 +116,51 @@ user_in_file(const char *path, const cha
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;
- if (uid == 0)
+ int retcode = 0;
+ if (euid == 0)
return 1;
- if ((pentry = getpwuid(uid)) == NULL) {
+ if ((pentry = getpwuid(euid)) == NULL) {
perror("Cannot access user database");
exit(EXIT_FAILURE);
}
+#ifdef WITH_PAM
+/*
+ * We must check if the atd daemon userid will be allowed to gain the job owner user's
+ * credentials with PAM . If not, the user has been denied at(1) usage, eg. with pam_access.
+ */
+ if (setreuid(daemon_uid, daemon_uid) != 0) {
+ fprintf(stderr, "cannot set egid: %s", strerror(errno));
+ exit(1);
+ }
+ if (setregid(daemon_gid, daemon_gid) != 0) {
+ fprintf(stderr, "cannot set euid: %s", strerror(errno));
+ exit(1);
+ }
+
+ pam_close_session(pamh,PAM_SILENT);
+
+ PAM_HANDLING;
+
+ pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT );
+ pam_close_session(pamh,PAM_SILENT);
+ pam_end(pamh, PAM_ABORT);
+
+ if (setregid(gid,egid) != 0) {
+ fprintf(stderr, "cannot set egid: %s", strerror(errno));
+ exit(1);
+ }
+ if (setreuid(uid,euid) != 0) {
+ fprintf(stderr, "cannot set euid: %s", strerror(errno));
+ exit(1);
+ }
+#endif
+
allow = user_in_file(ETCDIR "/at.allow", pentry->pw_name);
if (allow==0 || allow==1)
return allow;
diff -up at-3.1.12/privs.h.pam at-3.1.12/privs.h
--- at-3.1.12/privs.h.pam 2009-11-23 16:11:52.000000000 +0100
+++ at-3.1.12/privs.h 2010-03-15 09:57:27.060442603 +0100
@@ -144,3 +144,61 @@ extern gid_t real_gid, effective_gid, da
#error "Cannot implement user ID swapping without setreuid or setresuid"
#endif
#endif
+
+#ifdef WITH_PAM
+/* PAM failed after session was open. */
+#define PAM_SESSION_FAIL if (retcode != PAM_SUCCESS) \
+ pam_close_session(pamh,PAM_SILENT);
+
+/* syslog will be logging error messages */
+#ifdef HAVE_UNISTD_H
+#include <syslog.h>
+#endif
+
+/* PAM fail even before opening the session */
+#define PAM_FAIL_CHECK \
+ do { if (retcode != PAM_SUCCESS) { \
+ fprintf(stderr,"PAM failure: %s\n",pam_strerror(pamh, retcode)); \
+ syslog(LOG_ERR,"%s",pam_strerror(pamh, retcode)); \
+ if (pamh) \
+ pam_end(pamh, retcode); \
+ if (setregid(getgid(),getegid()) != 0) { \
+ fprintf(stderr, "cannot set egid: %s", strerror(errno)); \
+ exit(1); \
+ } \
+ if (setreuid(getuid(),geteuid()) != 0) { \
+ fprintf(stderr, "cannot set euid: %s", strerror(errno)); \
+ exit(1); \
+ } \
+ exit(1); \
+ } \
+ } while (0) \
+
+/* PAM - check after every operation whether they passed */
+#define PAM_HANDLING \
+ do { pamh = NULL; \
+ 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_SESSION_FAIL; \
+ PAM_FAIL_CHECK; \
+ } while (0)
+
+/* OLD FAIL_CHECK ONLY FOR perm.c
+ * define PAM_FAIL_CHECK if (retcode != PAM_SUCCESS) { \
+ * fprintf(stderr,"\nPAM failure %s\n",pam_strerror(pamh, retcode)); \
+ * syslog(LOG_ERR,"%s",pam_strerror(pamh, retcode)); \
+ * if (pamh) \
+ * pam_end(pamh, retcode); \
+ * exit(1); \
+ * }
+ */
+
+#endif
+

View File

@ -1,152 +0,0 @@
diff -up at-3.1.12/config.h.in.selinux at-3.1.12/config.h.in
--- at-3.1.12/config.h.in.selinux 2009-12-02 16:32:19.469228959 +0100
+++ at-3.1.12/config.h.in 2009-12-02 16:32:57.706966488 +0100
@@ -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.12/configure.ac.selinux at-3.1.12/configure.ac
--- at-3.1.12/configure.ac.selinux 2009-12-02 16:31:15.323246019 +0100
+++ at-3.1.12/configure.ac 2009-12-02 16:32:01.425966844 +0100
@@ -266,5 +266,13 @@ AC_ARG_WITH(daemon_groupname,
)
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 batch)
AC_OUTPUT
diff -up at-3.1.12/Makefile.in.selinux at-3.1.12/Makefile.in
--- at-3.1.12/Makefile.in.selinux 2009-12-02 16:30:11.923216529 +0100
+++ at-3.1.12/Makefile.in 2009-12-02 16:30:57.949215706 +0100
@@ -39,6 +39,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.12/atd.c.selinux at-3.1.12/atd.c
--- at-3.1.12/atd.c.selinux 2009-12-03 13:03:57.182284669 +0100
+++ at-3.1.12/atd.c 2009-12-03 13:07:20.542272874 +0100
@@ -83,6 +83,14 @@
#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
+
#ifndef LOG_ATD
#define LOG_ATD LOG_DAEMON
#endif
@@ -202,6 +210,68 @@ myfork()
#define ATD_MAIL_NAME "mailx"
#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)
{
@@ -452,6 +522,12 @@ run_file(const char *filename, uid_t uid
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");
@@ -774,6 +850,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.
*/

View File

@ -1,55 +0,0 @@
diff -up at-3.1.12/at.c.shell at-3.1.12/at.c
--- at-3.1.12/at.c.shell 2009-12-02 13:25:12.706989310 +0100
+++ at-3.1.12/at.c 2009-12-02 13:26:01.991966200 +0100
@@ -62,11 +62,8 @@
#include <stdlib.h>
#include <string.h>
-#ifdef TM_IN_SYS_TIME
#include <sys/time.h>
-#else
#include <time.h>
-#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@@ -244,6 +241,12 @@ writefile(time_t runtimer, char queue)
int kill_errno;
int rc;
int mailsize = 128;
+ struct timeval tv;
+ struct timezone tz;
+ long int i;
+
+ gettimeofday(&tv, &tz);
+ srandom(getpid()+tv.tv_usec);
/* Install the signal handler for SIGINT; terminate after removing the
* spool file if necessary
@@ -461,6 +464,9 @@ writefile(time_t runtimer, char queue)
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> ");
@@ -477,6 +483,7 @@ writefile(time_t runtimer, char queue)
fprintf(stderr, "<EOT>\n");
}
fprintf(fp, "\n");
+ fprintf(fp, "marcinDELIMITER%08lx\n", i);
if (ferror(fp))
panic("Output error");
@@ -926,7 +933,7 @@ main(int argc, char **argv)
It also alows a warning diagnostic to be printed. Because of the
possible variance, we always output the diagnostic. */
- fprintf(stderr, "warning: commands will be executed using /bin/sh\n");
+ //fprintf(stderr, "warning: commands will be executed using /bin/sh\n");
writefile(timer, queue);
break;

View File

@ -1,15 +0,0 @@
diff -up at-3.1.13/at.c.add at-3.1.13/at.c
diff -up at-3.1.13/panic.c.add at-3.1.13/panic.c
--- at-3.1.13/panic.c.add 2012-01-27 13:54:46.216466452 +0100
+++ at-3.1.13/panic.c 2012-01-27 13:57:35.123747498 +0100
@@ -92,8 +92,8 @@ 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"
+ fprintf(stderr, "Usage: at [-V] [-q x] [-f file] [-mMlbv] timespec ...\n"
+ " at [-V] [-q x] [-f file] [-mMlbv] -t time\n"
" at -c job ...\n"
" atq [-V] [-q x]\n"
" at [ -rd ] job ...\n"

View File

@ -1,62 +0,0 @@
diff -up at-3.1.13/atd.c.hostname at-3.1.13/atd.c
--- at-3.1.13/atd.c.hostname 2012-01-12 18:19:36.000000000 +0100
+++ at-3.1.13/atd.c 2012-01-12 18:52:34.000000000 +0100
@@ -99,6 +99,10 @@ int selinux_enabled=0;
#define BATCH_INTERVAL_DEFAULT 60
#define CHECK_INTERVAL 3600
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif
+
/* Global variables */
uid_t real_uid, effective_uid;
@@ -116,6 +120,7 @@ static time_t last_chg;
static int nothing_to_do;
unsigned int batch_interval;
static int run_as_daemon = 0;
+static int mail_with_hostname = 0;
static volatile sig_atomic_t term_signal = 0;
@@ -297,6 +302,7 @@ run_file(const char *filename, uid_t uid
char fmt[64];
unsigned long jobno;
int rc;
+ char hostbuf[MAXHOSTNAMELEN];
#ifdef WITH_PAM
int retcode;
#endif
@@ -451,6 +457,11 @@ run_file(const char *filename, uid_t uid
write_string(fd_out, "Subject: Output from your job ");
write_string(fd_out, jobbuf);
+ if (mail_with_hostname > 0) {
+ 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");
@@ -910,7 +921,7 @@ main(int argc, char *argv[])
run_as_daemon = 1;
batch_interval = BATCH_INTERVAL_DEFAULT;
- while ((c = getopt(argc, argv, "sdl:b:f")) != EOF) {
+ while ((c = getopt(argc, argv, "sdnl:b:f")) != EOF) {
switch (c) {
case 'l':
if (sscanf(optarg, "%lf", &load_avg) != 1)
@@ -932,6 +943,10 @@ main(int argc, char *argv[])
daemon_foreground++;
break;
+ case 'n':
+ mail_with_hostname=1;
+ break;
+
case 's':
run_as_daemon = 0;
break;

View File

@ -1,82 +0,0 @@
diff -up at-3.1.13/Makefile.in.make at-3.1.13/Makefile.in
--- at-3.1.13/Makefile.in.make 2011-06-25 14:43:14.000000000 +0200
+++ at-3.1.13/Makefile.in 2011-07-29 08:06:28.317600053 +0200
@@ -65,13 +65,13 @@ LIST = Filelist Filelist.asc
all: at atd atrun
at: $(ATOBJECTS)
- $(CC) $(CFLAGS) -o at $(ATOBJECTS) $(LIBS) $(LEXLIB)
+ $(CC) $(CFLAGS) -o at -pie $(ATOBJECTS) $(LIBS) $(LEXLIB) $(SELINUXLIB) $(PAMLIB)
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 -pie $(RUNOBJECTS) $(LIBS) $(SELINUXLIB) $(PAMLIB)
y.tab.c y.tab.h: parsetime.y
$(YACC) -d parsetime.y
@@ -83,38 +83,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) -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)$(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" <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)/
+ $(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*

View File

@ -1,121 +0,0 @@
diff -up at-3.1.13/at.1.in.nit at-3.1.13/at.1.in
--- at-3.1.13/at.1.in.nit 2011-06-25 14:43:14.000000000 +0200
+++ at-3.1.13/at.1.in 2011-07-28 13:04:41.398174737 +0200
@@ -126,7 +126,7 @@ and to run a job at 1am tomorrow, you wo
.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/at-@VERSION@/timespec .
.PP
For both
.BR at " and " batch ,
@@ -204,7 +204,7 @@ queue for
.BR batch .
Queues with higher letters run with increased niceness. The special
queue "=" is reserved for jobs which are currently running.
-.P
+
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
@@ -248,7 +248,7 @@ is an alias for
.TP
.B \-v
Shows the time the job will be executed before reading the job.
-.P
+
Times displayed will be in the format "Thu Feb 20 14:50:00 1997".
.TP
.B
diff -up at-3.1.13/atd.c.nit at-3.1.13/atd.c
--- at-3.1.13/atd.c.nit 2011-06-25 14:43:14.000000000 +0200
+++ at-3.1.13/atd.c 2011-07-28 13:01:31.577967025 +0200
@@ -83,6 +83,9 @@
#include "getloadavg.h"
#endif
+#ifndef LOG_ATD
+#define LOG_ATD LOG_DAEMON
+#endif
/* Macros */
#define BATCH_INTERVAL_DEFAULT 60
@@ -194,6 +197,18 @@ myfork()
#define fork myfork
#endif
+#undef ATD_MAIL_PROGRAM
+#undef ATD_MAIL_NAME
+#if defined(SENDMAIL)
+#define ATD_MAIL_PROGRAM SENDMAIL
+#define ATD_MAIL_NAME "sendmail"
+#elif defined(MAILC)
+#define ATD_MAIL_PROGRAM MAILC
+#define ATD_MAIL_NAME "mail"
+#elif defined(MAILX)
+#define ATD_MAIL_PROGRAM MAILX
+#define ATD_MAIL_NAME "mailx"
+#endif
static void
run_file(const char *filename, uid_t uid, gid_t gid)
@@ -271,6 +286,9 @@ run_file(const char *filename, uid_t uid
free(newname);
return;
}
+
+ (void) setsid(); //own session for process
+
/* 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.
@@ -433,6 +451,9 @@ run_file(const char *filename, uid_t uid
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)
@@ -501,6 +522,9 @@ run_file(const char *filename, uid_t uid
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 defined(SENDMAIL)
@@ -615,6 +639,7 @@ run_loop()
* 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[0] = '=';
unlink(lock_name);
next_job = now;
@@ -649,6 +674,7 @@ run_loop()
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_uid = buf.st_uid;
batch_gid = buf.st_gid;
batch_queue = queue;
@@ -723,11 +749,7 @@ main(int argc, char *argv[])
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;

View File

@ -1,112 +0,0 @@
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 <selinux/selinux.h>
+#include <selinux/get_context_list.h>
+int selinux_enabled=0;
+#include <selinux/flask.h>
+#include <selinux/av_permissions.h>
+#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.
*/

View File

@ -1,119 +0,0 @@
diff -ur -x configure at-3.1.13.orig/atd.c at-3.1.13/atd.c
--- at-3.1.13.orig/atd.c 2011-11-16 11:30:22.424764253 -0500
+++ at-3.1.13/atd.c 2011-11-16 16:41:12.102831656 -0500
@@ -815,6 +815,54 @@
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
@@ -835,7 +883,6 @@
struct sigaction act;
struct passwd *pwe;
struct group *ge;
-
#ifdef WITH_SELINUX
selinux_enabled=is_selinux_enabled();
#endif
@@ -912,7 +959,7 @@
sigaction(SIGCHLD, &act, NULL);
if (!run_as_daemon) {
- now = time(NULL);
+ now = atd_gettime();
run_loop();
exit(EXIT_SUCCESS);
}
@@ -935,13 +982,15 @@
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 -ur -x configure at-3.1.13.orig/config.h.in at-3.1.13/config.h.in
--- at-3.1.13.orig/config.h.in 2011-11-16 11:30:22.424764253 -0500
+++ at-3.1.13/config.h.in 2011-11-16 16:32:44.485426754 -0500
@@ -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 <getopt.h> header file. */
#undef HAVE_GETOPT_H
diff -ur -x configure at-3.1.13.orig/configure.ac at-3.1.13/configure.ac
--- at-3.1.13.orig/configure.ac 2011-11-16 11:30:22.425764254 -0500
+++ at-3.1.13/configure.ac 2011-11-16 16:31:29.791561747 -0500
@@ -274,5 +274,9 @@
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_CONFIG_FILES(Makefile atrun atd.8 atrun.8 at.1 at.allow.5 batch)
AC_OUTPUT

27
at.spec
View File

@ -2,8 +2,8 @@
Summary: Job spooling tools
Name: at
Version: 3.1.14
Release: 5%{?dist}
Version: 3.1.16
Release: 1%{?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
@ -59,16 +59,6 @@ time-oriented job control. Note: If it is a recurring job that will
need to be repeated at the same time every day/week, etc. you should
use crontab instead.
%package sysvinit
Summary: SysV init script for at
Group: System Environment/Base
Requires: %{name} = %{version}-%{release}
Requires(post): /sbin/chkconfig
%description sysvinit
SysV style init script for at. It needs to be installed only if systemd
is not used as the system init process.
%prep
%setup -q
cp %{SOURCE1} .
@ -126,9 +116,6 @@ cp %{buildroot}/%{_prefix}/doc/at/* docs/
mkdir -p %{buildroot}%{_sysconfdir}/pam.d
install -m 644 %{SOURCE1} %{buildroot}%{_sysconfdir}/pam.d/atd
mkdir -p %{buildroot}%{_sysconfdir}/rc.d/init.d
install -m 755 %{SOURCE2} %{buildroot}%{_sysconfdir}/rc.d/init.d/atd
mkdir -p %{buildroot}/etc/sysconfig
install -m 644 %{SOURCE3} %{buildroot}/etc/sysconfig/atd
@ -167,9 +154,6 @@ chown daemon:daemon %{_localstatedir}/spool/at/.SEQ
/bin/systemctl try-restart atd.service >/dev/null 2>&1 || :
/bin/systemctl daemon-reload >/dev/null 2>&1 || :
%triggerpostun -n at-sysvinit -- at < 3.1.12-9
/sbin/chkconfig --add atd >/dev/null 2>&1 || :
%files
%doc docs/*
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/at.deny
@ -187,10 +171,11 @@ chown daemon:daemon %{_localstatedir}/spool/at/.SEQ
%attr(4755,root,root) %{_bindir}/at
%attr(0644,root,root) /%{_unitdir}/atd.service
%files sysvinit
%attr(0755,root,root) %{_initrddir}/atd
%changelog
* Thu Oct 2 2014 Tomáš Mráz <tmraz@redhat.com> - 3.1.16-1
- new upstream release fixing regression from security fix in bash
- drop sysvinit subpackage
* Fri Aug 15 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.1.14-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild

111
atd.init
View File

@ -1,111 +0,0 @@
#!/bin/sh
#
# atd Starts/stop the "at" daemon
#
# chkconfig: 345 95 5
# description: Runs commands scheduled by the "at" command at the time \
# specified when "at" was run, and runs batch commands when the load \
# average is low enough.
### BEGIN INIT INFO
# Provides: atd at batch
# Required-Start: $local_fs
# Required-Stop: $local_fs
# Default-Start: 345
# Default-Stop: 95
# Short-Description: Starts/stop the "at" daemon
# Description: Runs commands scheduled by the "at" command at the time
# specified when "at" was run, and runs batch commands when the load
# average is low enough.
### END INIT INFO
# Source function library.
. /etc/rc.d/init.d/functions
exec=/usr/sbin/atd
prog="atd"
config=/etc/sysconfig/atd
[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog
lockfile=/var/lock/subsys/$prog
start() {
[ -x $exec ] || exit 5
[ -f $config ] || exit 6
echo -n $"Starting $prog: "
daemon $exec $OPTS && success || failure
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
if [ -n "`pidfileofproc $exec`" ] ; then
killproc $exec
RETVAL=3
else
failure $"Stopping $prog"
fi
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
stop
start
}
reload() {
restart
}
force_reload() {
restart
}
rh_status() {
# run checks to determine if the service is running or use generic status
status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
restart
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
exit 2
esac
exit $?

9
pam_atd Normal file
View File

@ -0,0 +1,9 @@
# The PAM configuration file for the at daemon
#
#
auth required pam_env.so
auth include password-auth
account required pam_access.so
account include password-auth
session required pam_loginuid.so
session include password-auth

View File

@ -1,4 +1 @@
b117781fd68e393443b2a8e478c7c22f atd.init
ac1471fe22f63f666dc7d31173f47ea0 atd.sysconf
000d2f30379d2bf8af09f51416e863ec pam_atd
d41cfd79033b6e49a8838add59a42ac6 at_3.1.14.orig.tar.gz
d05da75d9b75d93917ffb16ab48b1e19 at_3.1.16.orig.tar.gz