automatic update by autodist [release 3.1.14-1mamba;Thu Oct 10 2013]

This commit is contained in:
Automatic Build System 2024-01-05 20:36:28 +01:00
parent 7f4b0eaa44
commit 21d413ab4f
24 changed files with 1832 additions and 0 deletions

View File

@ -1,2 +1,7 @@
# at
At and batch read commands from standard input or from a specified file.
At allows you to specify that a command will be run at a particular time (now or a specified time in the future).
Batch will execute commands when the system load levels drop to a particular level.
Both commands use /bin/sh to run the commands.

14
at-3.1.10-daylight.patch Normal file
View File

@ -0,0 +1,14 @@
--- at-3.1.10/at.c.daylight 2007-03-31 00:03:47.000000000 +0200
+++ at-3.1.10/at.c 2007-03-31 00:06:23.000000000 +0200
@@ -840,8 +840,9 @@
if( tm.tm_mday )
{
- tm.tm_isdst = tm_now.tm_isdst;
- return mktime(&tm);
+ tm.tm_isdst = -1;
+ t = mktime(&tm);
+ return t;
} else
return 0L;
}

59
at-3.1.10-dont_fork.patch Normal file
View File

@ -0,0 +1,59 @@
--- at-3.1.10/daemon.c.dontfork 2005-08-05 05:16:01.000000000 +0200
+++ at-3.1.10/daemon.c 2006-09-12 13:53:10.000000000 +0200
@@ -50,7 +50,8 @@
static const char *svnid = "$Id$";
-int daemon_debug;
+int daemon_debug = 0;
+int daemon_nofork = 0;
static int
lock_fd(int fd)
@@ -119,15 +120,18 @@
(open("/dev/null", O_RDWR) != 2)) {
perr("Error redirecting I/O");
}
+ }
+ if (daemon_nofork) pid = getpid();
+ else {
pid = fork();
if (pid == -1) {
perr("Cannot fork");
} else if (pid != 0) {
exit(0);
}
+ (void) setsid();
}
old_umask = umask(S_IWGRP | S_IWOTH);
- (void) setsid();
PRIV_START
--- at-3.1.10/atd.8.in.dontfork 2005-08-29 10:08:51.000000000 +0200
+++ at-3.1.10/atd.8.in 2006-09-12 13:53:10.000000000 +0200
@@ -10,6 +10,7 @@
.IR batch_interval ]
.RB [ -d ]
.RB [ -s ]
+.RB [ -n ]
.SH DESCRIPTION
.B atd
runs jobs queued by
@@ -46,6 +47,9 @@
is installed as
.B @prefix@/sbin/atrun
for backward compatibility.
+.TP 8
+.B -n
+Don't fork option.
.SH WARNING
.B atd
won't work if its spool directory is mounted via NFS even if
--- at-3.1.10/daemon.h.dontfork 2005-08-05 05:16:01.000000000 +0200
+++ at-3.1.10/daemon.h 2006-09-12 13:54:43.000000000 +0200
@@ -14,3 +14,4 @@
perr (const char *fmt, ...);
extern int daemon_debug;
+extern int daemon_nofork;

View File

@ -0,0 +1,84 @@
--- at-3.1.10/at.c.fix 2006-09-12 13:21:16.000000000 +0200
+++ at-3.1.10/at.c 2006-09-12 13:20:08.000000000 +0200
@@ -396,8 +396,9 @@
unsigned int i;
for (i = 0; i < sizeof(no_export) / sizeof(no_export[0]); i++) {
export = export
- && (strncmp(*atenv, no_export[i],
- (size_t) (eqp - *atenv)) != 0);
+ && ( (((size_t) (eqp - *atenv)) != strlen(no_export[i]))
+ ||(strncmp(*atenv, no_export[i],(size_t) (eqp - *atenv)) != 0)
+ );
}
eqp++;
}
--- at-3.1.10/at.1.in.fix 2006-09-12 13:21:16.000000000 +0200
+++ at-3.1.10/at.1.in 2006-09-12 13:10:28.000000000 +0200
@@ -42,8 +42,7 @@
and
.B batch
read commands from standard input or a specified file which are to
-be executed at a later time, using
-.BR /bin/sh .
+be executed at a later time.
.TP 8
.BR at
executes commands at a specified time.
@@ -244,8 +243,56 @@
option argument, which must have the same format as specified for the
.BR touch(1)
utility's
-.B -t
+.B \-t
time option argument ([[CC]YY]MMDDhhmm).
+.SH ENVIRONMENT
+.P
+.TP 8
+.B SHELL
+The value of the SHELL environment variable at the time of
+.B at
+invocation will determine which shell is used to execute the
+.B at
+job commands. If SHELL is unset when
+.B at
+is invoked, the user's login shell will be used; otherwise,
+if SHELL is set when
+.B at
+is invoked, it must contain the path of a shell interpreter
+executable that will be used to run the commands at the specified time.
+.P
+.B at
+will record the values of
+environment variables present at time of
+.B at
+invocation. When the commands are run at the specified time,
+.B at
+will restore these variables to their recorded values .
+These variables are excluded from this processing and are never
+set by
+.B at
+when the commands are run :
+.br
+.BI TERM,
+.BI DISPLAY,
+.BI SHELLOPTS,
+.BI _,
+.BI PPID,
+.BI BASH_VERSINFO,
+.BI EUID,
+.BI UID,
+.BI GROUPS.
+.br
+If the user submitting the
+.B at
+job is not the super-user, variables that alter the behaviour of the
+loader
+.BR ld.so(8),
+such as
+.B LD_LIBRARY_PATH
+, cannot be recorded and restored by
+.B at .
+.P
.SH FILES
.I @ATJBD@
.br

245
at-3.1.10-instinet.patch Normal file
View File

@ -0,0 +1,245 @@
--- at-3.1.10/atd.c.instinet 2006-09-12 11:01:10.000000000 +0200
+++ at-3.1.10/atd.c 2006-09-12 11:24:49.000000000 +0200
@@ -102,7 +102,7 @@
static const char *svnid = "$Id$";
static double load_avg = LOADAVG_MX;
static time_t now;
-static time_t last_chg;
+//static time_t last_chg;
static int nothing_to_do;
unsigned int batch_interval;
static int run_as_daemon = 0;
@@ -197,7 +197,7 @@
#endif
static void
-run_file(const char *filename, uid_t uid, gid_t gid)
+run_file(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
@@ -208,7 +208,7 @@
char jobbuf[9];
char *mailname = NULL;
int mailsize = 128;
- char *newname;
+ char newname[256];
FILE *stream;
int send_mail = 0;
struct stat buf, lbuf;
@@ -242,11 +242,17 @@
sprintf(jobbuf, "%8lu", jobno);
- if ((newname = malloc(strlen(filename) + 1)) == NULL)
- pabort("Job %8lu : out of virtual memory", jobno);
+ if( strlen( filename ) >= sizeof( newname ) - 1 )
+ pabort("File name too long: %s", filename );
strcpy(newname, filename);
+ newname[0] = '!';
+
+ if( rename( filename, newname ) < 0 )
+ perr( "Error renaming job file." );
+
+ filename[0] = '!';
newname[0] = '=';
/* We try to make a hard link to lock the file. If we fail, then
@@ -264,14 +270,15 @@
}
}
/* If something goes wrong between here and the unlink() call,
- * the job gets restarted as soon as the "=" entry is cleared
- * by the main atd loop.
- */
+ * the job will remain in the "!" queue.
+ * no point in retrying, and need glaring proof that something went wrong
+ */
pid = fork();
- if (pid == -1)
+ if (pid == -1) {
+ unlink(newname);
perr("Cannot fork");
-
+ }
else if (pid != 0) {
free(mailname);
free(newname);
@@ -284,6 +291,7 @@
pentry = getpwuid(uid);
if (pentry == NULL) {
+ unlink(newname);
pabort("Userid %lu not found - aborting job %8lu (%.500s)",
(unsigned long) uid, jobno, filename);
}
@@ -293,35 +301,43 @@
PRIV_END
- if (stream == NULL)
+ if (stream == NULL) {
+ unlink( newname );
perr("Cannot open input file");
-
- if ((fd_in = dup(fileno(stream))) < 0)
+ }
+ if ((fd_in = dup(fileno(stream))) < 0) {
+ unlink( newname );
perr("Error duplicating input file descriptor");
-
- if (fstat(fd_in, &buf) == -1)
+ }
+ if (fstat(fd_in, &buf) == -1) {
+ unlink( newname );
perr("Error in fstat of input file descriptor");
-
- if (lstat(filename, &lbuf) == -1)
+ }
+ if (lstat(filename, &lbuf) == -1) {
+ unlink( newname );
perr("Error in fstat of input file");
-
- if (S_ISLNK(lbuf.st_mode))
+ }
+ if (S_ISLNK(lbuf.st_mode)) {
+ unlink( newname );
perr("Symbolic link encountered in job %8lu (%.500s) - aborting",
jobno, filename);
-
+ }
if ((lbuf.st_dev != buf.st_dev) || (lbuf.st_ino != buf.st_ino) ||
(lbuf.st_uid != buf.st_uid) || (lbuf.st_gid != buf.st_gid) ||
- (lbuf.st_size != buf.st_size))
+ (lbuf.st_size != buf.st_size)) {
+ unlink( newname );
perr("Somebody changed files from under us for job %8lu (%.500s) - "
"aborting", jobno, filename);
-
+ }
if (buf.st_nlink > 2) {
+ unlink( newname );
perr("Somebody is trying to run a linked script for job %8lu (%.500s)",
jobno, filename);
}
- if ((fflags = fcntl(fd_in, F_GETFD)) < 0)
+ if ((fflags = fcntl(fd_in, F_GETFD)) < 0) {
+ unlink( newname );
perr("Error in fcntl");
-
+ }
fcntl(fd_in, F_SETFD, fflags & ~FD_CLOEXEC);
/*
@@ -335,28 +351,44 @@
mailsize );
if (fscanf(stream, fmt,
- &nuid, &ngid, mailname, &send_mail) != 4)
+ &nuid, &ngid, mailname, &send_mail) != 4) {
+ unlink( newname );
pabort("File %.500s is in wrong format - aborting",
filename);
+ }
- if (mailname[0] == '-')
+ if (mailname[0] == '-') {
+ unlink( newname );
pabort("illegal mail name %.300s in job %8lu (%.300s)", mailname,
jobno, filename);
-
- if (nuid != uid)
+ }
+ if (nuid != uid) {
+ unlink( newname );
pabort("Job %8lu (%.500s) - userid %d does not match file uid %d",
jobno, filename, nuid, uid);
-
+ }
+ if (ngid != gid) {
+ unlink( newname );
+ pabort("Job %8lu %.500s - groupid %d does not match file gid %d",
+ jobno, filename, ngid, gid);
+ }
/* We are now committed to executing this script. Unlink the
* original.
*/
unlink(filename);
+ /* If we bail out from now on, the job gets stuck in "="
+ * The main loop should take care of that.
+ */
+
fclose(stream);
+
if (chdir(ATSPOOL_DIR) < 0)
perr("Cannot chdir to " ATSPOOL_DIR);
+ filename[0] = queue;
+
/* Create a file to hold the output of the job we are about to run.
* Write the mail header. Complain in case
*/
@@ -466,19 +498,19 @@
#endif
/* Send mail. Unlink the output file after opening it, so it
- * doesn't hang around after the run.
+ * doesn't hang around after the run (if we are to send mail).
*/
- stat(filename, &buf);
- if (open(filename, O_RDONLY) != STDIN_FILENO)
- perr("Open of jobfile failed");
-
- unlink(filename);
+ if( send_mail != -1 ) {
+ stat(filename, &buf);
+ if (open(filename, O_RDONLY) != STDIN_FILENO)
+ perr("Open of jobfile failed");
+ unlink(filename);
+ }
/* 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)) {
@@ -508,6 +540,8 @@
exit(EXIT_SUCCESS);
}
+#define CHECK_INTERVAL_5MIN 300
+
static time_t
run_loop()
{
@@ -537,7 +571,7 @@
* atrun.
*/
- next_job = now + CHECK_INTERVAL;
+ next_job = now + CHECK_INTERVAL_5MIN;
if (next_batch == 0)
next_batch = now;
@@ -548,11 +582,11 @@
if (stat(".", &buf) == -1)
perr("Cannot stat " ATJOB_DIR);
-
+/*
if (nothing_to_do && buf.st_mtime <= last_chg)
return next_job;
last_chg = buf.st_mtime;
-
+*/
if ((spool = opendir(".")) == NULL)
perr("Cannot read " ATJOB_DIR);

View File

@ -0,0 +1,14 @@
--- at-3.1.10/parsetime.y.parser 2005-08-05 05:31:04.000000000 +0200
+++ at-3.1.10/parsetime.y 2006-09-07 12:47:45.000000000 +0200
@@ -55,8 +55,10 @@
%%
timespec : spec_base
| spec_base inc_or_dec
+ {
+ time_only = 0;
+ }
;
-
spec_base : date
| time
{

View File

@ -0,0 +1,11 @@
--- at-3.1.10/at.1.in.path 2005-08-29 10:09:24.000000000 +0200
+++ at-3.1.10/at.1.in 2006-09-07 11:07:21.000000000 +0200
@@ -110,7 +110,7 @@
.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 ,

83
at-3.1.10-perm.patch Normal file
View File

@ -0,0 +1,83 @@
--- at-3.1.10/at.c.perm 2006-11-14 12:26:27.000000000 +0100
+++ at-3.1.10/at.c 2006-11-14 12:28:15.000000000 +0100
@@ -144,17 +144,12 @@
*/
if (fcreated) {
/*
- PRIV_START
-
We need the unprivileged uid here since the file is owned by the real
(not effective) uid.
*/
setregid(real_gid, effective_gid);
unlink(atfile);
setregid(effective_gid, real_gid);
- /*
- PRIV_END
- */
}
exit(EXIT_FAILURE);
}
@@ -314,18 +309,18 @@
* bit. Yes, this is a kluge.
*/
cmask = umask(S_IRUSR | S_IWUSR | S_IXUSR);
- seteuid(real_uid);
+ seteuid(effective_uid);
if ((fd = open(atfile, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, S_IRUSR)) == -1)
perr("Cannot create atjob file %.500s", atfile);
- seteuid(effective_uid);
+ //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
@@ -656,6 +651,7 @@
We need the unprivileged uid here since the file is owned by the real
(not effective) uid.
*/
+// PRIV_START
setregid(real_gid, effective_gid);
if (queue == '=') {
@@ -668,17 +664,17 @@
setregid(effective_gid, real_gid);
done = 1;
-
+// PRIV_END
break;
case CAT:
{
FILE *fp;
int ch;
-
+ // PRIV_START
setregid(real_gid, effective_gid);
fp = fopen(dirent->d_name, "r");
-
+ // PRIV_END
if (fp) {
while ((ch = getc(fp)) != EOF) {
putchar(ch);
--- at-3.1.10/Makefile.in.perm 2006-11-14 12:26:27.000000000 +0100
+++ at-3.1.10/Makefile.in 2006-11-14 12:26:27.000000000 +0100
@@ -97,7 +97,7 @@
$(INSTALL) -m 755 -d $(IROOT)$(atdocdir)
$(INSTALL) -m 755 -d $(IROOT)$(ATJOB_DIR)
$(INSTALL) -m 755 -d $(IROOT)$(etcdir)/pam.d
- $(INSTALL) -g $(DAEMON_GROUPNAME) -o $(DAEMON_USERNAME) -m 755 -d $(IROOT) $(ATSPOOL_DIR)
+ $(INSTALL) -g $(DAEMON_GROUPNAME) -o $(DAEMON_USERNAME) -m 755 -d $(IROOT)$(ATSPOOL_DIR)
chmod 700 $(IROOT)$(ATSPOOL_DIR) $(IROOT)$(ATJOB_DIR)
touch $(IROOT)$(LFILE)
chmod 600 $(IROOT)$(LFILE)

27
at-3.1.10-pie.patch Normal file
View File

@ -0,0 +1,27 @@
--- at-3.1.10/Makefile.in.pie 2006-09-12 08:28:13.000000000 +0200
+++ at-3.1.10/Makefile.in 2006-09-12 08:30:47.000000000 +0200
@@ -69,13 +69,13 @@
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)
+ $(CC) $(CFLAGS) -o atd -pie $(RUNOBJECTS) $(LIBS) $(PAMLIB)
y.tab.c y.tab.h: parsetime.y
$(YACC) -d parsetime.y
@@ -87,7 +87,7 @@
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)

56
at-3.1.10-typo.patch Normal file
View File

@ -0,0 +1,56 @@
--- at-3.1.10/atrun.8.in.typo 2005-08-29 10:08:41.000000000 +0200
+++ at-3.1.10/atrun.8.in 2006-09-12 10:00:57.000000000 +0200
@@ -11,7 +11,7 @@
.B atrun
runs jobs queued by
.BR at(1) .
-It is a shell script containing invoking
+It is a shell script invoking
.B @sbindir@/atd
with the
.I -s
--- at-3.1.10/atd.c.typo 2006-09-12 10:00:57.000000000 +0200
+++ at-3.1.10/atd.c 2006-09-12 10:07:19.000000000 +0200
@@ -316,7 +316,7 @@
"aborting", jobno, filename);
if (buf.st_nlink > 2) {
- perr("Someboy is trying to run a linked script for job %8lu (%.500s)",
+ perr("Somebody is trying to run a linked script for job %8lu (%.500s)",
jobno, filename);
}
if ((fflags = fcntl(fd_in, F_GETFD)) < 0)
@@ -607,6 +607,7 @@
* Let's remove the lockfile and reschedule.
*/
strncpy(lock_name, dirent->d_name, sizeof(lock_name));
+ lock_name[sizeof(lock_name)-1] = '\0';
lock_name[0] = '=';
unlink(lock_name);
next_job = now;
@@ -623,7 +624,7 @@
nothing_to_do = 0;
/* There's a job for later. Note its execution time if it's
- * the earlierst so far.
+ * the earliest so far.
*/
if (run_time > now) {
if (next_job > run_time) {
@@ -641,6 +642,7 @@
run_batch++;
if (strcmp(batch_name, dirent->d_name) > 0) {
strncpy(batch_name, dirent->d_name, sizeof(batch_name));
+ batch_name[sizeof(batch_name)-1] = '\0';
batch_uid = buf.st_uid;
batch_gid = buf.st_gid;
batch_queue = queue;
@@ -683,7 +685,7 @@
int
main(int argc, char *argv[])
{
-/* Browse through ATJOB_DIR, checking all the jobfiles wether they should
+/* Browse through ATJOB_DIR, checking all the jobfiles whether they should
* be executed and or deleted. The queue is coded into the first byte of
* the job filename, the date (in minutes since Eon) as a hex number in the
* following eight bytes, followed by a dot and a serial number. A file

12
at-3.1.10-usage.patch Normal file
View File

@ -0,0 +1,12 @@
--- at-3.1.10/panic.c.usage 2006-09-07 13:21:23.000000000 +0200
+++ at-3.1.10/panic.c 2006-09-07 13:24:00.000000000 +0200
@@ -92,7 +92,8 @@
/* Print usage and exit.
*/
fprintf(stderr, "Usage: at [-V] [-q x] [-f file] [-mldbv] time\n"
- " at -c job ...\n"
+ " at [-V] [-q x] [-f file] [-m] -t [[CC]YY]MMDDhhmm\n"
+ " at -c job [job...]\n"
" atq [-V] [-q x]\n"
" atrm [-V] job ...\n"
" batch\n");

17
at-3.1.12-opt_V.patch Normal file
View File

@ -0,0 +1,17 @@
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

152
at-3.1.12-selinux.patch Normal file
View File

@ -0,0 +1,152 @@
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.
*/

55
at-3.1.12-shell.patch Normal file
View File

@ -0,0 +1,55 @@
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;

82
at-3.1.13-makefile.patch Normal file
View File

@ -0,0 +1,82 @@
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*

430
at-3.1.13-pam.patch Normal file
View File

@ -0,0 +1,430 @@
diff -up at-3.1.13/at.c.pam at-3.1.13/at.c
--- at-3.1.13/at.c.pam 2011-07-29 13:51:50.234127938 +0200
+++ at-3.1.13/at.c 2011-07-29 13:51:50.245127883 +0200
@@ -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.13/atd.c.pam at-3.1.13/atd.c
--- at-3.1.13/atd.c.pam 2011-07-29 13:51:50.240127908 +0200
+++ at-3.1.13/atd.c 2011-07-29 13:54:35.805384873 +0200
@@ -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
@@ -235,7 +227,7 @@ run_file(const char *filename, uid_t uid
char fmt[64];
unsigned long jobno;
int rc;
-#ifdef HAVE_PAM
+#ifdef WITH_PAM
int retcode;
#endif
@@ -395,17 +387,10 @@ run_file(const char *filename, uid_t uid
fstat(fd_out, &buf);
size = buf.st_size;
-#ifdef HAVE_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;
- PRIV_END
+#ifdef WITH_PAM
+ PAM_HANDLING;
+ closelog();
+ openlog("atd", LOG_PID, LOG_ATD);
#endif
close(STDIN_FILENO);
@@ -419,7 +404,14 @@ 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
/* Set up things for the child; we want standard input from the
* input file, and standard output and error sent to our output file.
*/
@@ -438,8 +430,6 @@ run_file(const char *filename, uid_t uid
close(fd_in);
close(fd_out);
- PRIV_START
-
nice((tolower((int) queue) - 'a' + 1) * 2);
if (initgroups(pentry->pw_name, pentry->pw_gid))
@@ -458,7 +448,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.
@@ -471,14 +470,6 @@ run_file(const char *filename, uid_t uid
*/
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.
*/
@@ -509,8 +500,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))
@@ -535,7 +537,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.13/config.h.in.pam at-3.1.13/config.h.in
--- at-3.1.13/config.h.in.pam 2011-06-25 14:43:14.000000000 +0200
+++ at-3.1.13/config.h.in 2011-07-29 13:51:50.246127878 +0200
@@ -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.13/configure.ac.pam at-3.1.13/configure.ac
--- at-3.1.13/configure.ac.pam 2011-06-25 14:43:14.000000000 +0200
+++ at-3.1.13/configure.ac 2011-07-29 13:51:50.247127873 +0200
@@ -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.13/perm.c.pam at-3.1.13/perm.c
--- at-3.1.13/perm.c.pam 2011-06-25 14:43:14.000000000 +0200
+++ at-3.1.13/perm.c 2011-07-29 13:51:50.248127868 +0200
@@ -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.13/privs.h.pam at-3.1.13/privs.h
--- at-3.1.13/privs.h.pam 2011-06-25 14:43:14.000000000 +0200
+++ at-3.1.13/privs.h 2011-07-29 13:51:50.248127868 +0200
@@ -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
+

11
at-3.1.7-lockfile.patch Normal file
View File

@ -0,0 +1,11 @@
--- at-3.1.7/at.c.lockfile Wed Oct 22 17:56:22 1997
+++ at-3.1.7/at.c Wed Oct 22 17:56:40 1997
@@ -199,7 +199,7 @@
fscanf(fid, "%5lx", &jobno);
rewind(fid);
} else {
- fid = fopen(ATJOB_DIR "/.SEQ", "w");
+ fid = fopen(LFILE, "w");
if (fid == NULL)
return EOF;
}

12
at-3.1.7-sigchld.patch Normal file
View File

@ -0,0 +1,12 @@
--- at-3.1.7/atd.c.sigchld Mon May 24 16:56:41 1999
+++ at-3.1.7/atd.c Mon May 24 16:58:57 1999
@@ -348,6 +348,9 @@
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)

12
at-3.1.8-perr.patch Normal file
View File

@ -0,0 +1,12 @@
--- at-3.1.8/atd.c.org 2002-07-19 16:20:24.000000000 +0900
+++ at-3.1.8/atd.c 2002-07-19 16:22:30.000000000 +0900
@@ -453,7 +453,8 @@
#elif defined(MAILX)
execl(MAILX, "mailx", mailname, (char *) NULL);
#else
-#error "No mail command specified."
+/*#error "No mail command specified."*/
+ perr("No mail command specified.");
#endif
perr("Exec failed for mail command");

139
at-3.1.8-t_option.patch Normal file
View File

@ -0,0 +1,139 @@
--- at-3.1.10/at.1.in.t_opti 2006-09-12 12:48:04.000000000 +0200
+++ at-3.1.10/at.1.in 2006-09-12 12:45:40.000000000 +0200
@@ -12,6 +12,16 @@
.RB [ -mldbv ]
.B TIME
.br
+.B at
+.RB [ -V ]
+.RB [ -q
+.IR queue ]
+.RB [ -f
+.IR file ]
+.RB [ -mldbv ]
+.RB -t
+.IR time_arg
+.br
.B "at -c"
.I job
.RI [ job... ]
@@ -227,6 +237,15 @@
.B
\-c
cats the jobs listed on the command line to standard output.
+.TP
+.BI \-t " time_arg"
+Submit the job to be run at the time specified by the
+.BI time_arg
+option argument, which must have the same format as specified for the
+.BR touch(1)
+utility's
+.B -t
+time option argument ([[CC]YY]MMDDhhmm).
.SH FILES
.I @ATJBD@
.br
--- at-3.1.10/at.c.t_ 2006-09-12 10:15:56.000000000 +0200
+++ at-3.1.10/at.c 2006-09-12 10:30:17.000000000 +0200
@@ -750,6 +750,101 @@
return p;
}
+/* Handle POSIX.2 '-t' option :
+ * Parses time string in "touch(1)" format:
+ * [[CC]YY]MMDDhhmm[.ss]
+ * and returns time_t .
+ */
+time_t
+t_option(char *s)
+{
+ time_t t=time(0L);
+ struct tm tm, tm_now=*localtime(&t);
+ int l;
+
+ if((s == 0L) || (*s == '\0'))
+ {
+ return 0L;
+ };
+ memset(&tm,'\0',sizeof(tm));
+ l = strnlen(s,15);
+ switch(l)
+ {
+ case 15:
+ /* CCYYMMDDhhmm.ss */
+ sscanf(s, "%4d%2d%2d%2d%2d.%2d",
+ &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec
+ );
+ if(tm.tm_year)
+ tm.tm_year -= 1900 ;
+
+ break;
+
+ case 13:
+ /* YYMMDDhhmm.ss */
+ sscanf(s, "%2d%2d%2d%2d%2d.%2d",
+ &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec
+ );
+ if(tm.tm_year)
+ tm.tm_year += 100 ; /* Y2.1K+ bug! */
+
+ break;
+
+ case 11:
+ /* MMDDhhmm.ss */
+ sscanf(s, "%2d%2d%2d%2d.%2d",
+ &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec
+ );
+
+ tm.tm_year = tm_now.tm_year;
+
+ if(tm.tm_mon)
+ tm.tm_mon -= 1;
+ break;
+
+ case 12:
+ /* CCYYMMDDhhmm */
+ sscanf(s, "%4d%2d%2d%2d%2d",
+ &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min
+ );
+ if(tm.tm_year)
+ tm.tm_year -= 1900 ;
+ break;
+
+ case 10:
+ /* YYMMDDhhmm */
+ sscanf(s, "%2d%2d%2d%2d%2d",
+ &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min
+ );
+ if(tm.tm_year)
+ tm.tm_year += 100 ; /* Y2.1K+ bug! */
+ break;
+
+ case 8:
+ /* MMDDhhmm */
+ sscanf(s, "%2d%2d%2d%2d",
+ &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min
+ );
+ if( tm.tm_mday )
+ tm.tm_year = tm_now.tm_year;
+ break;
+ default:
+ break;
+ }
+
+ if( tm.tm_mon )
+ tm.tm_mon -= 1;
+
+ if( tm.tm_mday )
+ {
+ tm.tm_isdst = tm_now.tm_isdst;
+ return mktime(&tm);
+ } else
+ return 0L;
+}
+
+
+
int
main(int argc, char **argv)
{

23
at-3.1.8-test.patch Normal file
View File

@ -0,0 +1,23 @@
diff -u at-3.1.8/Makefile.in.orig at-3.1.8/Makefile.in
--- at-3.1.8/Makefile.in.orig Wed Feb 14 13:59:09 2001
+++ at-3.1.8/Makefile.in Mon Feb 19 14:48:42 2001
@@ -51,6 +51,8 @@
OTHERS = parsetime.l parsetime.y
+TEST_VERBOSE = 0
+
DOCS = Problems Copyright README ChangeLog timespec
MISC = COPYING Makefile.in configure acconfig.h install-sh \
@@ -150,6 +152,9 @@
parsetest: lex.yy.c y.tab.c
$(CC) -o parsetest $(CFLAGS) $(DEFS) -DTEST_PARSER -DNEED_YYWRAP lex.yy.c y.tab.c
+
+test: parsetest
+ PERL_DL_NONLAZY=1 perl -e 'use Test::Harness qw(&runtests $$verbose); $$verbose=$(TEST_VERBOSE); runtests @ARGV;' test.pl
.depend: $(CSRCS)
gcc $(CFLAGS) $(DEFS) -MM $(CSRCS) > .depend
diff -u at-3.1.8/test.pl.orig at-3.1.8/test.pl

191
at.spec Normal file
View File

@ -0,0 +1,191 @@
%define atdaemon_groupid 65022
%define atdaemon_userid 65022
Name: at
Version: 3.1.14
Release: 1mamba
Summary: Job spooling tools
Group: System/Servers
Vendor: openmamba
Distribution: openmamba
Packager: Silvan Calarco <silvan.calarco@mambasoft.it>
URL: http://ftp.debian.org/debian/pool/main/a/at/
Source0: http://ftp.debian.org/debian/pool/main/a/at/at_%{version}.orig.tar.gz
Source1: atd-initscript
Source2: atd-pam
# patches stolen from fedora
Patch0: %{name}-3.1.7-lockfile.patch
Patch1: %{name}-3.1.10-man-timespec-path.patch
Patch2: %{name}-3.1.7-sigchld.patch
Patch3: %{name}-3.1.10-typo.patch
Patch4: %{name}-3.1.10-lexer-parser.patch
Patch5: %{name}-3.1.8-test.patch
Patch6: %{name}-3.1.8-perr.patch
Patch7: %{name}-3.1.10-instinet.patch
Patch8: %{name}-3.1.12-shell.patch
Patch9: %{name}-3.1.10-pie.patch
Patch10: %{name}-3.1.8-t_option.patch
Patch11: %{name}-3.1.10-usage.patch
Patch12: %{name}-3.1.10-fix_no_export.patch
Patch13: %{name}-3.1.10-dont_fork.patch
Patch14: %{name}-3.1.13-pam.patch
Patch15: %{name}-3.1.13-makefile.patch
Patch16: %{name}-3.1.10-daylight.patch
Patch17: %{name}-3.1.10-perm.patch
Patch18: %{name}-3.1.12-opt_V.patch
Patch19: %{name}-3.1.12-selinux.patch
License: GPL
## AUTOBUILDREQ-BEGIN
BuildRequires: glibc-devel
BuildRequires: pam-devel
## AUTOBUILDREQ-END
BuildRequires: libselinux-devel
BuildRequires: systemd-devel
BuildRoot: %{_tmppath}/%{name}-%{version}-root
%description
At and batch read commands from standard input or from a specified file.
At allows you to specify that a command will be run at a particular time (now or a specified time in the future).
Batch will execute commands when the system load levels drop to a particular level.
Both commands use /bin/sh to run the commands.
%prep
%setup -q
#%patch0 -p1 -b .lockfile
#%patch1 -p1 -b .paths
%patch2 -p1 -b .sigchld
#%patch3 -p1 -b .typo
%patch4 -p1 -b .lexer
%patch5 -p1 -b .test
%patch6 -p1 -b .perr
#%patch7 -p1 -b .instinet
%patch8 -p1 -b .shell
#%patch9 -p1 -b .pie
%patch10 -p1 -b .t_option
#%patch11 -p1 -b .usage
%patch12 -p1 -b .fix_no_export
#%patch13 -p1 -b .dont_fork
%patch14 -p1 -b .pam
#%patch15 -p1 -b .makefile
%patch16 -p1 -b .daylight
#%patch17 -p1 -b .perm
%patch18 -p1 -b .opt_V
#%patch19 -p1 -b .selinux
install %{SOURCE2} pam_atd
sed -i "s|-g root||g" Makefile.in
sed -i "s|-o root||g" Makefile.in
%build
# for patch2
rm -f lex.yy.* y.tab.*
sed -i "s|/var/run|/run|g" configure
%configure \
--with-atspool=%{_localstatedir}/spool/at/spool \
--with-jobdir=%{_localstatedir}/spool/at \
--with-daemon_username=atdaemon \
--with-daemon_groupname=atdaemon \
--with-systemdsystemunitdir=%_unitdir
%make -j1
#LANG=C make test >/dev/null
%install
[ "%{buildroot}" != / ] && rm -rf "%{buildroot}"
%makeinstall \
IROOT=%{buildroot} \
DAEMON_USERNAME=`id -nu` \
DAEMON_GROUPNAME=`id -ng` \
INSTALL_ROOT_USER=`id -nu` \
INSTALL_ROOT_GROUP=`id -nu` \
docdir=%{_docdir}
# prefix=%{buildroot}%{_prefix} \
# bindir=%{buildroot}%{_bindir} \
# sbindir=%{buildroot}%{_sbindir} \
# etcdir=%{buildroot}%{_sysconfdir} \
# mandir=%{buildroot}%{_mandir} \
# ATJOB_DIR=%{buildroot}%{_localstatedir}/spool/at \
# ATSPOOL_DIR=%{buildroot}%{_localstatedir}/spool/at/spool \
#install -D -m 0755 %{S:1} %{buildroot}%{_initrddir}/atd
%clean
[ "%{buildroot}" != / ] && rm -rf "%{buildroot}"
%pre
groupadd -g %{atdaemon_groupid} atdaemon 2>/dev/null
useradd -u %{atdaemon_userid} -g atdaemon -c "at daemon" \
-d /var/empty -s /bin/false atdaemon 2>/dev/null
exit 0
%post
touch %{_localstatedir}/spool/at/.SEQ
chmod 600 %{_localstatedir}/spool/at/.SEQ
chown atdaemon:atdaemon %{_localstatedir}/spool/at/.SEQ
#/sbin/chkconfig --add atd
exit 0
%preun
if [ $1 -eq 0 ]; then
service atd stop >/dev/null 2>&1
/sbin/chkconfig --del atd
userdel atdaemon >/dev/null 2>&1
fi
exit 0
%postun
if [ $1 -eq 1 ]; then
service atd condrestart >/dev/null 2>&1
fi
exit 0
%files
%defattr(-,root,root)
%attr(4755,root,root) %{_bindir}/at
%config(noreplace) %{_sysconfdir}/at.deny
#%attr(0640,root,atdaemon) %config(noreplace) /etc/pam.d/atd
%{_bindir}/batch
%{_bindir}/atrm
%{_bindir}/atq
%{_sbindir}/atrun
%{_sbindir}/atd
/lib/systemd/system/atd.service
%attr(0700,atdaemon,atdaemon) %dir %{_localstatedir}/spool/at
%attr(0700,atdaemon,atdaemon) %dir %{_localstatedir}/spool/at/spool
%ghost %{_localstatedir}/spool/at/.SEQ
%{_mandir}/man1/*
%{_mandir}/man5/*
%{_mandir}/man8/*
%dir %{_docdir}/at
%{_docdir}/at
%changelog
* Thu Oct 10 2013 Automatic Build System <autodist@mambasoft.it> 3.1.14-1mamba
- automatic update by autodist
* Sat Sep 10 2011 Automatic Build System <autodist@mambasoft.it> 3.1.13-1mamba
- automatic version update by autodist
* Sun Dec 27 2009 Silvan Calarco <silvan.calarco@mambasoft.it> 3.1.12-1mamba
- update to 3.1.12
* Mon Aug 25 2008 Aleph0 <aleph0@openmamba.org> 3.1.10-3mamba
- remove broken symlink to debian copyright
* Mon Jul 02 2007 Silvan Calarco <silvan.calarco@mambasoft.it> 3.1.10-2mamba
- fix pam file for new release
* Wed Jan 17 2007 Davide Madrisan <davide.madrisan@qilinux.it> 3.1.10-1qilnx
- update to version 3.1.10 by autospec
- added missing build requirements
- fixed permissions of at binary
- enabled support for pam
- use the service script to start/restart/stop the atd service
- fixed owner and group for /var/spool/at/.SEQ
- modified homedir for atd daemon: now is /var/empty
* Thu Apr 29 2004 Silvan Calarco <silvan.calarco@mambasoft.it> 3.1.8-1qilnx
- first build

85
atd-initscript Normal file
View File

@ -0,0 +1,85 @@
#!/bin/bash
#
# /etc/rc.d/init.d/atd
#
# Starts the at daemon
#
# chkconfig: 345 40 60
# 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.
# processname: atd
# Source function library.
. /etc/init.d/functions
test -x /usr/sbin/atd || exit 0
RETVAL=0
#
# See how we were called.
#
prog="atd"
start() {
# Check if atd is already running
if [ ! -f /var/lock/subsys/atd ]; then
echo -n $"Starting $prog: "
daemon /usr/sbin/atd
RETVAL=$?
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/atd
echo
fi
return $RETVAL
}
stop() {
echo -n $"Stopping $prog: "
killproc /usr/sbin/atd
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/atd
echo
return $RETVAL
}
restart() {
stop
start
}
reload() {
restart
}
status_at() {
status /usr/sbin/atd
}
case "$1" in
start)
start
;;
stop)
stop
;;
reload|restart)
restart
;;
condrestart)
if [ -f /var/lock/subsys/atd ]; then
restart
fi
;;
status)
status_at
;;
*)
echo $"Usage: $0 {start|stop|restart|condrestart|status}"
exit 1
esac
exit $?
exit $RETVAL

13
atd-pam Normal file
View File

@ -0,0 +1,13 @@
#
# The PAM configuration file for the at daemon
#
#
auth sufficient pam_rootok.so
auth include system-auth
auth required pam_env.so
account include system-auth
session include system-auth
# Sets up user limits, please uncomment and read /etc/security/limits.conf
# to enable this functionality.
# session required pam_limits.so
#