Fix patches to apply correctly. PAM and SElinux patches were rewritten to correct way. Thanks to: Tomas Mraz

This commit is contained in:
Marcela Mašláňová 2013-12-04 11:45:09 +01:00
parent 2d6e674bb5
commit 6d4186b4e5
9 changed files with 251 additions and 647 deletions

View File

@ -1,426 +0,0 @@
diff -up at-3.1.13/at.c.pam at-3.1.13/at.c
--- at-3.1.13/at.c.pam 2012-04-19 16:50:57.491000001 +0200
+++ at-3.1.13/at.c 2012-04-19 16:50:57.505000001 +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 2012-04-19 16:50:57.498000001 +0200
+++ at-3.1.13/atd.c 2012-04-19 16:52:37.209000138 +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,11 @@ 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
+ AT_START_PAM;
+ AT_OPEN_PAM_SESSION;
+ closelog();
+ openlog("atd", LOG_PID, LOG_ATD);
#endif
close(STDIN_FILENO);
@@ -419,7 +405,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 +431,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 +449,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 +471,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 +501,20 @@ 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
+ AT_START_PAM;
+ AT_OPEN_PAM_SESSION;
+ 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 +539,21 @@ 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
+ AT_CLOSE_PAM;
+ 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 2012-04-19 16:50:57.506000001 +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 2012-04-19 16:50:57.506000001 +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 2012-04-19 16:53:09.192001742 +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,45 @@ 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);
+ }
+
+ AT_START_PAM;
+ AT_CLOSE_PAM;
+ 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 2012-04-19 16:53:46.296016675 +0200
@@ -144,3 +144,63 @@ 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) \
+
+static int pam_session_opened = 0; //global for open session
+
+#define AT_START_PAM { \
+ retcode = pam_start("atd", pentry->pw_name, &conv, &pamh); \
+ PAM_FAIL_CHECK; \
+ retcode = pam_set_item(pamh, PAM_TTY, "atd"); \
+ PAM_FAIL_CHECK; \
+ retcode = pam_acct_mgmt(pamh, PAM_SILENT); \
+ PAM_FAIL_CHECK; \
+}
+
+#define AT_OPEN_PAM_SESSION { \
+ retcode = pam_open_session(pamh, PAM_SILENT); \
+ PAM_FAIL_CHECK; \
+ retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED | PAM_SILENT); \
+ PAM_FAIL_CHECK; \
+ if (retcode == PAM_SUCCESS) \
+ pam_session_opened = 1; \
+}
+
+#define AT_CLOSE_PAM { \
+ if (pam_session_opened != 0) { \
+ pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT); \
+ pam_close_session(pamh, PAM_SILENT); \
+ } \
+ pam_end(pamh, PAM_SUCCESS); \
+}
+
+#endif
+

View File

@ -1,6 +1,6 @@
diff -up at-3.1.13/atd.c.selinux at-3.1.13/atd.c
--- at-3.1.13/atd.c.selinux 2012-11-01 15:11:21.368772308 +0100
+++ at-3.1.13/atd.c 2012-11-01 15:13:16.809162818 +0100
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
@ -16,8 +16,8 @@ diff -up at-3.1.13/atd.c.selinux at-3.1.13/atd.c
#ifndef LOG_ATD
#define LOG_ATD LOG_DAEMON
#endif
@@ -202,6 +210,68 @@ myfork()
#define ATD_MAIL_NAME "mailx"
@@ -191,6 +199,68 @@ myfork()
#define fork myfork
#endif
+#ifdef WITH_SELINUX
@ -85,32 +85,21 @@ diff -up at-3.1.13/atd.c.selinux at-3.1.13/atd.c
static void
run_file(const char *filename, uid_t uid, gid_t gid)
{
@@ -446,9 +516,23 @@ run_file(const char *filename, uid_t uid
perr("Cannot reset signal handler to default");
@@ -419,6 +489,13 @@ run_file(const char *filename, uid_t uid
nice((tolower((int) queue) - 'a' + 1) * 2);
chdir("/");
-
+#ifdef WITH_SELINUX
+ if (selinux_enabled > 0) {
+ if (set_selinux_context(pentry->pw_name, filename) < 0)
+ perr("SELinux Failed to set context\n");
+ }
+ 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");
+//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))
{
@@ -751,6 +835,10 @@ main(int argc, char *argv[])
+
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;
@ -121,45 +110,3 @@ diff -up at-3.1.13/atd.c.selinux at-3.1.13/atd.c
/* We don't need root privileges all the time; running under uid and gid
* daemon is fine.
*/
diff -up at-3.1.13/config.h.in.selinux at-3.1.13/config.h.in
--- at-3.1.13/config.h.in.selinux 2012-11-01 15:11:21.368772308 +0100
+++ at-3.1.13/config.h.in 2012-11-01 15:11:21.371772392 +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.13/configure.ac.selinux at-3.1.13/configure.ac
--- at-3.1.13/configure.ac.selinux 2012-11-01 15:11:21.369772335 +0100
+++ at-3.1.13/configure.ac 2012-11-01 15:11:21.372772420 +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 at.allow.5 batch)
AC_OUTPUT
diff -up at-3.1.13/Makefile.in.selinux at-3.1.13/Makefile.in
--- at-3.1.13/Makefile.in.selinux 2012-11-01 15:11:21.361772115 +0100
+++ at-3.1.13/Makefile.in 2012-11-01 15:11:21.372772420 +0100
@@ -39,6 +39,8 @@ 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

View File

@ -0,0 +1,15 @@
diff -up at-3.1.14/at.c.export at-3.1.14/at.c
--- at-3.1.14/at.c.export 2013-10-07 14:53:59.980521240 +0200
+++ at-3.1.14/at.c 2013-10-07 14:54:35.722560527 +0200
@@ -388,8 +388,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,6 +1,6 @@
diff -up at-3.1.14/atd.c.mail at-3.1.14/atd.c
--- at-3.1.14/atd.c.mail 2013-12-02 10:47:06.000000000 +0100
+++ at-3.1.14/atd.c 2013-12-02 10:51:23.000000000 +0100
--- at-3.1.14/atd.c.mail 2013-12-04 11:39:44.556239282 +0100
+++ at-3.1.14/atd.c 2013-12-04 11:40:50.544234246 +0100
@@ -100,6 +100,10 @@ int selinux_enabled=0;
#define BATCH_INTERVAL_DEFAULT 60
#define CHECK_INTERVAL 3600
@ -25,7 +25,7 @@ diff -up at-3.1.14/atd.c.mail at-3.1.14/atd.c
unsigned long jobno;
int rc;
+ char hostbuf[MAXHOSTNAMELEN];
#ifdef WTIH_PAM
#ifdef WITH_PAM
int retcode;
#endif
@@ -452,6 +458,11 @@ run_file(const char *filename, uid_t uid
@ -40,7 +40,7 @@ diff -up at-3.1.14/atd.c.mail at-3.1.14/atd.c
write_string(fd_out, "\nTo: ");
write_string(fd_out, mailname);
write_string(fd_out, "\n\n");
@@ -872,7 +883,7 @@ main(int argc, char *argv[])
@@ -843,7 +854,7 @@ main(int argc, char *argv[])
run_as_daemon = 1;
batch_interval = BATCH_INTERVAL_DEFAULT;
@ -49,7 +49,7 @@ diff -up at-3.1.14/atd.c.mail at-3.1.14/atd.c
switch (c) {
case 'l':
if (sscanf(optarg, "%lf", &load_avg) != 1)
@@ -894,6 +905,10 @@ main(int argc, char *argv[])
@@ -865,6 +876,10 @@ main(int argc, char *argv[])
daemon_foreground++;
break;

89
at-3.1.14-nitpicks.patch Normal file
View File

@ -0,0 +1,89 @@
diff -up at-3.1.14/at.1.in.nit at-3.1.14/at.1.in
--- at-3.1.14/at.1.in.nit 2013-09-08 14:43:53.000000000 +0200
+++ at-3.1.14/at.1.in 2013-12-04 11:36:29.737279969 +0100
@@ -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
diff -up at-3.1.14/atd.c.nit at-3.1.14/atd.c
--- at-3.1.14/atd.c.nit 2013-12-04 11:36:29.733279967 +0100
+++ at-3.1.14/atd.c 2013-12-04 11:38:44.551247496 +0100
@@ -198,6 +198,18 @@ myfork()
#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
#ifdef WITH_SELINUX
static int set_selinux_context(const char *name, const char *filename) {
@@ -337,6 +349,9 @@ run_file(const char *filename, uid_t uid
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.
@@ -505,6 +520,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("/");
execle("/bin/sh", "sh", (char *) NULL, nenvp);
@@ -570,6 +588,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)
@@ -697,6 +718,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;
@@ -731,6 +753,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;

12
at-3.1.14-nowrap.patch Normal file
View File

@ -0,0 +1,12 @@
diff -up at-3.1.14/at.c.wrap at-3.1.14/at.c
--- at-3.1.14/at.c.wrap 2013-12-02 15:42:10.000000000 +0100
+++ at-3.1.14/at.c 2013-12-02 15:45:42.679092990 +0100
@@ -304,7 +304,7 @@ 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);

View File

@ -1,15 +1,14 @@
diff -up at-3.1.14/at.c.pam at-3.1.14/at.c
--- at-3.1.14/at.c.pam 2013-09-08 14:43:53.000000000 +0200
+++ at-3.1.14/at.c 2013-10-07 14:39:15.670837532 +0200
@@ -144,18 +144,14 @@ sigc(int signo)
+++ at-3.1.14/at.c 2013-12-04 11:09:56.165752053 +0100
@@ -144,18 +144,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.
*/
@ -17,19 +16,19 @@ diff -up at-3.1.14/at.c.pam at-3.1.14/at.c
- unlink(atfile);
- setregid(effective_gid, real_gid);
- /*
+ unlink(atfile);
+ unlink(atfile);
PRIV_END
- */
}
exit(EXIT_FAILURE);
}
@@ -315,26 +311,19 @@ writefile(time_t runtimer, char queue)
@@ -315,26 +310,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 ((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);
@ -53,7 +52,7 @@ diff -up at-3.1.14/at.c.pam at-3.1.14/at.c
/* We've successfully created the file; let's set the flag so it
* gets removed in case of an interrupt or error.
*/
@@ -654,7 +643,7 @@ process_jobs(int argc, char **argv, int
@@ -654,7 +642,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.
*/
@ -62,16 +61,17 @@ diff -up at-3.1.14/at.c.pam at-3.1.14/at.c
if (queue == '=') {
fprintf(stderr, "Warning: deleting running job\n");
@@ -664,7 +653,7 @@ process_jobs(int argc, char **argv, int
@@ -663,8 +651,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);
+ PRIV_END
done = 1;
break;
@@ -674,7 +663,7 @@ process_jobs(int argc, char **argv, int
@@ -674,7 +662,7 @@ process_jobs(int argc, char **argv, int
FILE *fp;
int ch;
@ -80,7 +80,7 @@ diff -up at-3.1.14/at.c.pam at-3.1.14/at.c
fp = fopen(dirent->d_name, "r");
if (fp) {
@@ -687,7 +676,7 @@ process_jobs(int argc, char **argv, int
@@ -687,7 +675,7 @@ process_jobs(int argc, char **argv, int
perr("Cannot open %.500s", dirent->d_name);
rc = EXIT_FAILURE;
}
@ -91,7 +91,7 @@ diff -up at-3.1.14/at.c.pam at-3.1.14/at.c
diff -up at-3.1.14/atd.c.pam at-3.1.14/atd.c
--- at-3.1.14/atd.c.pam 2013-09-08 14:43:53.000000000 +0200
+++ at-3.1.14/atd.c 2013-10-07 14:40:22.102988905 +0200
+++ at-3.1.14/atd.c 2013-12-04 11:14:31.780617480 +0100
@@ -83,6 +83,10 @@
#include "getloadavg.h"
#endif
@ -134,7 +134,7 @@ diff -up at-3.1.14/atd.c.pam at-3.1.14/atd.c
unsigned long jobno;
int rc;
-#ifdef HAVE_PAM
+#ifdef WTIH_PAM
+#ifdef WITH_PAM
int retcode;
#endif
@ -161,22 +161,22 @@ diff -up at-3.1.14/atd.c.pam at-3.1.14/atd.c
#endif
close(STDIN_FILENO);
@@ -401,6 +391,14 @@ run_file(const char *filename, uid_t uid
@@ -401,7 +391,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.
@@ -420,8 +418,6 @@ run_file(const char *filename, uid_t uid
*/
@@ -420,8 +417,6 @@ run_file(const char *filename, uid_t uid
close(fd_in);
close(fd_out);
@ -185,25 +185,20 @@ diff -up at-3.1.14/atd.c.pam at-3.1.14/atd.c
nice((tolower((int) queue) - 'a' + 1) * 2);
if (initgroups(pentry->pw_name, pentry->pw_gid))
@@ -438,6 +434,17 @@ run_file(const char *filename, uid_t uid
if (execle("/bin/sh", "sh", (char *) NULL, nenvp) != 0)
perr("Exec failed for /bin/sh");
@@ -435,9 +430,9 @@ run_file(const char *filename, uid_t uid
+#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
+
chdir("/");
- if (execle("/bin/sh", "sh", (char *) NULL, nenvp) != 0)
- perr("Exec failed for /bin/sh");
-
+ execle("/bin/sh", "sh", (char *) NULL, nenvp);
+ perr("Exec failed for /bin/sh");
+ /* perr exits, the PRIV_END is just for nice form */
PRIV_END
}
/* We're the parent. Let's wait.
@@ -450,14 +457,6 @@ run_file(const char *filename, uid_t uid
@@ -450,14 +445,6 @@ run_file(const char *filename, uid_t uid
*/
waitpid(pid, (int *) NULL, 0);
@ -218,62 +213,44 @@ diff -up at-3.1.14/atd.c.pam at-3.1.14/atd.c
/* Send mail. Unlink the output file after opening it, so it
* doesn't hang around after the run.
*/
@@ -488,7 +487,20 @@ run_file(const char *filename, uid_t uid
@@ -488,8 +475,13 @@ 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
+ AT_START_PAM;
+ AT_OPEN_PAM_SESSION;
+ closelog();
+ openlog("atd", LOG_PID, LOG_ATD);
+#endif
+
+ mail_pid = fork();
+
+ if ( mail_pid == 0 )
+ {
+ mail_pid = fork();
+
+ if ( mail_pid == 0 ) {
PRIV_START
@@ -511,7 +523,22 @@ run_file(const char *filename, uid_t uid
if (initgroups(pentry->pw_name, pentry->pw_gid))
@@ -511,7 +503,20 @@ 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
+ AT_CLOSE_PAM;
+ closelog();
+ openlog("atd", LOG_PID, LOG_ATD);
+#endif
+ }
+ else if ( mail_pid == -1 ) {
+ syslog(LOG_ERR, "fork of mailer failed: %m");
+ }
+ /* Parent */
+ waitpid(mail_pid, (int *) NULL, 0);
}
+#endif /* ATD_MAIL_PROGRAM */
+
+#ifdef WITH_PAM
+ AT_CLOSE_PAM;
+ closelog();
+ openlog("atd", LOG_PID, LOG_ATD);
+#endif
+#endif
exit(EXIT_SUCCESS);
}
@@ -727,7 +754,7 @@ main(int argc, char *argv[])
#define LOG_CRON LOG_DAEMON
#endif
- openlog("atd", LOG_PID, LOG_CRON);
+ openlog("atd", LOG_PID, LOG_ATD);
opterr = 0;
errno = 0;
diff -up at-3.1.14/config.h.in.pam at-3.1.14/config.h.in
--- at-3.1.14/config.h.in.pam 2013-09-08 14:43:53.000000000 +0200
+++ at-3.1.14/config.h.in 2013-10-07 14:39:15.670837532 +0200
+++ at-3.1.14/config.h.in 2013-12-04 11:09:56.165752053 +0100
@@ -68,8 +68,8 @@
/* Define to 1 if you have the <nlist.h> header file. */
#undef HAVE_NLIST_H
@ -287,7 +264,7 @@ diff -up at-3.1.14/config.h.in.pam at-3.1.14/config.h.in
#undef HAVE_PSTAT_GETDYNAMIC
diff -up at-3.1.14/configure.ac.pam at-3.1.14/configure.ac
--- at-3.1.14/configure.ac.pam 2013-09-08 14:43:53.000000000 +0200
+++ at-3.1.14/configure.ac 2013-10-07 14:39:15.671837535 +0200
+++ at-3.1.14/configure.ac 2013-12-04 11:09:56.165752053 +0100
@@ -78,7 +78,7 @@ AC_FUNC_GETLOADAVG
AC_CHECK_FUNCS(getcwd mktime strftime setreuid setresuid sigaction waitpid)
AC_CHECK_HEADERS(security/pam_appl.h, [
@ -313,7 +290,7 @@ diff -up at-3.1.14/configure.ac.pam at-3.1.14/configure.ac
[ --with-daemon_groupname=DAEMON_GROUPNAME Groupname to run under (default daemon) ],
diff -up at-3.1.14/perm.c.pam at-3.1.14/perm.c
--- at-3.1.14/perm.c.pam 2013-09-08 14:43:53.000000000 +0200
+++ at-3.1.14/perm.c 2013-10-07 14:39:15.671837535 +0200
+++ at-3.1.14/perm.c 2013-12-04 11:09:56.165752053 +0100
@@ -51,6 +51,14 @@
#define PRIV_END while(0)
#endif
@ -380,14 +357,13 @@ diff -up at-3.1.14/perm.c.pam at-3.1.14/perm.c
return allow;
diff -up at-3.1.14/privs.h.pam at-3.1.14/privs.h
--- at-3.1.14/privs.h.pam 2013-09-08 14:43:53.000000000 +0200
+++ at-3.1.14/privs.h 2013-10-07 14:39:15.671837535 +0200
@@ -144,3 +144,64 @@ extern gid_t real_gid, effective_gid, da
+++ at-3.1.14/privs.h 2013-12-04 11:09:56.166752054 +0100
@@ -144,3 +144,63 @@ extern gid_t real_gid, effective_gid, da
#error "Cannot implement user ID swapping without setreuid or setresuid"
#endif
#endif
+
+#ifdef WITH_PAM
+int retcode;
+/* PAM failed after session was open. */
+#define PAM_SESSION_FAIL if (retcode != PAM_SUCCESS) \
+ pam_close_session(pamh,PAM_SILENT);

View File

@ -1,8 +1,50 @@
diff -up at-3.1.14/atd.c.selinux at-3.1.14/atd.c
--- at-3.1.14/atd.c.selinux 2013-09-26 15:06:55.177049852 +0200
+++ at-3.1.14/atd.c 2013-09-26 16:33:23.981355661 +0200
@@ -87,6 +87,14 @@
#define LOG_ATD LOG_DAEMON
diff -up at-3.1.14/config.h.in.selinux at-3.1.14/config.h.in
--- at-3.1.14/config.h.in.selinux 2013-09-26 15:06:55.177049852 +0200
+++ at-3.1.14/config.h.in 2013-09-26 15:06:55.180049850 +0200
@@ -71,6 +71,9 @@
/* Define if you are building with_pam */
#undef WITH_PAM
+/* Define if you are building with_selinux */
+#undef WITH_SELINUX
+
/* Define to 1 if you have the `pstat_getdynamic' function. */
#undef HAVE_PSTAT_GETDYNAMIC
diff -up at-3.1.14/configure.ac.selinux at-3.1.14/configure.ac
--- at-3.1.14/configure.ac.selinux 2013-09-26 15:06:55.178049851 +0200
+++ at-3.1.14/configure.ac 2013-09-26 15:06:55.180049850 +0200
@@ -246,6 +246,14 @@ AC_DEFINE(WITH_PAM),
AC_CHECK_LIB(pam, pam_start, PAMLIB='-lpam -lpam_misc')
AC_SUBST(PAMLIB)
+AC_ARG_WITH(selinux,
+[ --with-selinux Define to run with selinux],
+AC_DEFINE(WITH_SELINUX),
+)
+AC_CHECK_LIB(selinux, is_selinux_enabled, SELINUXLIB=-lselinux)
+AC_SUBST(SELINUXLIB)
+AC_SUBST(WITH_SELINUX)
+
AC_MSG_CHECKING(groupname to run under)
AC_ARG_WITH(daemon_groupname,
[ --with-daemon_groupname=DAEMON_GROUPNAME Groupname to run under (default daemon) ],
diff -up at-3.1.14/Makefile.in.selinux at-3.1.14/Makefile.in
--- at-3.1.14/Makefile.in.selinux 2013-09-26 15:06:55.175049853 +0200
+++ at-3.1.14/Makefile.in 2013-09-26 15:06:55.180049850 +0200
@@ -40,6 +40,7 @@ LIBS = @LIBS@
LIBOBJS = @LIBOBJS@
INSTALL = @INSTALL@
PAMLIB = @PAMLIB@
+SELINUXLIB = @SELINUXLIB@
CLONES = atq atrm
ATOBJECTS = at.o panic.o perm.o posixtm.o y.tab.o lex.yy.o
diff -up at-3.1.14/atd.c.selinux2 at-3.1.14/atd.c
--- at-3.1.14/atd.c.selinux2 2013-12-04 11:27:28.729005384 +0100
+++ at-3.1.14/atd.c 2013-12-04 11:30:17.709091150 +0100
@@ -83,6 +83,14 @@
#include "getloadavg.h"
#endif
+#ifdef WITH_SELINUX
@ -13,9 +55,9 @@ diff -up at-3.1.14/atd.c.selinux at-3.1.14/atd.c
+#include <selinux/av_permissions.h>
+#endif
+
/* Macros */
#define BATCH_INTERVAL_DEFAULT 60
#ifndef LOG_ATD
#define LOG_ATD LOG_DAEMON
#endif
@@ -191,6 +199,68 @@ myfork()
#define fork myfork
#endif
@ -85,31 +127,21 @@ diff -up at-3.1.14/atd.c.selinux at-3.1.14/atd.c
static void
run_file(const char *filename, uid_t uid, gid_t gid)
{
@@ -431,9 +501,23 @@ run_file(const char *filename, uid_t uid
@@ -419,6 +489,13 @@ run_file(const char *filename, uid_t uid
chdir("/");
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");
+ }
+ 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");
if (initgroups(pentry->pw_name, pentry->pw_gid))
perr("Cannot initialize the supplementary group access list");
+#ifdef WITH_SELINUX
+ if (selinux_enabled>0)
+ if (setexeccon(NULL) < 0)
+ if (security_getenforce()==1)
+ perr("Could not resset exec context for user %s\n", pentry->pw_name);
+#endif
+
#ifdef WITH_PAM
if ( ( nenvp != &nul ) && (pam_envp != 0L) && (*pam_envp != 0L))
{
@@ -732,6 +816,10 @@ main(int argc, char *argv[])
@@ -712,6 +789,10 @@ main(int argc, char *argv[])
struct passwd *pwe;
struct group *ge;
@ -120,45 +152,3 @@ diff -up at-3.1.14/atd.c.selinux at-3.1.14/atd.c
/* We don't need root privileges all the time; running under uid and gid
* daemon is fine.
*/
diff -up at-3.1.14/config.h.in.selinux at-3.1.14/config.h.in
--- at-3.1.14/config.h.in.selinux 2013-09-26 15:06:55.177049852 +0200
+++ at-3.1.14/config.h.in 2013-09-26 15:06:55.180049850 +0200
@@ -71,6 +71,9 @@
/* Define if you are building with_pam */
#undef WITH_PAM
+/* Define if you are building with_selinux */
+#undef WITH_SELINUX
+
/* Define to 1 if you have the `pstat_getdynamic' function. */
#undef HAVE_PSTAT_GETDYNAMIC
diff -up at-3.1.14/configure.ac.selinux at-3.1.14/configure.ac
--- at-3.1.14/configure.ac.selinux 2013-09-26 15:06:55.178049851 +0200
+++ at-3.1.14/configure.ac 2013-09-26 15:06:55.180049850 +0200
@@ -246,6 +246,14 @@ AC_DEFINE(WITH_PAM),
AC_CHECK_LIB(pam, pam_start, PAMLIB='-lpam -lpam_misc')
AC_SUBST(PAMLIB)
+AC_ARG_WITH(selinux,
+[ --with-selinux Define to run with selinux],
+AC_DEFINE(WITH_SELINUX),
+)
+AC_CHECK_LIB(selinux, is_selinux_enabled, SELINUXLIB=-lselinux)
+AC_SUBST(SELINUXLIB)
+AC_SUBST(WITH_SELINUX)
+
AC_MSG_CHECKING(groupname to run under)
AC_ARG_WITH(daemon_groupname,
[ --with-daemon_groupname=DAEMON_GROUPNAME Groupname to run under (default daemon) ],
diff -up at-3.1.14/Makefile.in.selinux at-3.1.14/Makefile.in
--- at-3.1.14/Makefile.in.selinux 2013-09-26 15:06:55.175049853 +0200
+++ at-3.1.14/Makefile.in 2013-09-26 15:06:55.180049850 +0200
@@ -40,6 +40,7 @@ LIBS = @LIBS@
LIBOBJS = @LIBOBJS@
INSTALL = @INSTALL@
PAMLIB = @PAMLIB@
+SELINUXLIB = @SELINUXLIB@
CLONES = atq atrm
ATOBJECTS = at.o panic.o perm.o posixtm.o y.tab.o lex.yy.o

View File

@ -76,6 +76,7 @@ cp %{SOURCE1} .
%patch1 -p1 -b .make
%patch2 -p1 -b .pam
%patch3 -p1 -b .selinux
%patch100 -p1 -b .selinux2
%patch4 -p1 -b .opt_V
%patch5 -p1 -b .shell
%patch6 -p1 -b .nit