Accepting request 512270 from home:scarabeus_iv:branches:Base:System

- Drop patch at-3.1.8-eal3-manpages.patch merged upstream differently

- Version update to at 3.1.20 to match latest upstream:
  * Pam and selinux implemented upstream
  * various tiny fixes
- Rebase patches:
  * at-3.1.13-documentation-dir.patch
  * at-3.1.13-massive_batch.patch
  * at-3.1.14-joblist.patch
  * at-3.1.14-parse-suse-sysconfig.patch
  * at-3.1.14-usePOSIXtimers.patch
  * at-3.1.14.patch
- Drop no longer needed patches:
  * at-3.1.13-formatbugs.patch
  * at-3.1.13-pam-session-as-root.patch
  * at-3.1.13-pam.patch
  * at-3.1.13-queue-nice-level.patch
  * at-3.1.14-selinux.patch

OBS-URL: https://build.opensuse.org/request/show/512270
OBS-URL: https://build.opensuse.org/package/show/Base:System/at?expand=0&rev=102
This commit is contained in:
Kristyna Streitova 2017-07-27 14:14:04 +00:00 committed by Git OBS Bridge
parent 38615f981b
commit 658a744b4d
16 changed files with 70 additions and 874 deletions

View File

@ -2,10 +2,8 @@ Index: at.1.in
=================================================================== ===================================================================
--- at.1.in.orig --- at.1.in.orig
+++ at.1.in +++ at.1.in
@@ -124,11 +124,11 @@ to run a job at 10:00am on July 31, you @@ -132,7 +132,7 @@ the past, the job will run as soon as po
.B at 10am Jul 31 it will run more likely at 8:05pm.
and to run a job at 1am tomorrow, you would do
.B at 1am tomorrow.
.PP .PP
The definition of the time specification can be found in The definition of the time specification can be found in
-.IR @prefix@/share/doc/at/timespec . -.IR @prefix@/share/doc/at/timespec .
@ -13,5 +11,3 @@ Index: at.1.in
.PP .PP
For both For both
.BR at " and " batch , .BR at " and " batch ,
commands are read from standard input or the file specified
with the

View File

@ -1,41 +0,0 @@
Index: daemon.h
===================================================================
--- daemon.h.orig
+++ daemon.h
@@ -3,15 +3,15 @@ void daemon_cleanup(void);
void
#ifdef HAVE_ATTRIBUTE_NORETURN
__attribute__((noreturn))
#endif
-pabort (const char *fmt, ...);
+pabort (const char *fmt, ...) __attribute__((__format__(printf,1,2)));
void
#ifdef HAVE_ATTRIBUTE_NORETURN
__attribute__((noreturn))
#endif
-perr (const char *fmt, ...);
+perr (const char *fmt, ...) __attribute__((__format__(printf,1,2)));
extern int daemon_debug;
extern int daemon_foreground;
Index: panic.h
===================================================================
--- panic.h.orig
+++ panic.h
@@ -24,11 +24,13 @@ __attribute__((noreturn))
panic(char *a);
void
#ifdef HAVE_ATTRIBUTE_NORETURN
__attribute__((noreturn))
#endif
-perr(const char *a, ...);
+perr(const char *a, ...)
+__attribute__((__format__(printf,1,2)))
+;
void
#ifdef HAVE_ATTRIBUTE_NORETURN
__attribute__((noreturn))
#endif
usage(void);

View File

@ -2,9 +2,7 @@ Index: atd.c
=================================================================== ===================================================================
--- atd.c.orig --- atd.c.orig
+++ atd.c +++ atd.c
@@ -112,13 +112,14 @@ gid_t daemon_gid = (gid_t) - 3; @@ -108,9 +108,10 @@ static char *namep;
static char *namep;
static double load_avg = LOADAVG_MX; static double load_avg = LOADAVG_MX;
static time_t now; static time_t now;
static time_t last_chg; static time_t last_chg;
@ -16,11 +14,7 @@ Index: atd.c
static volatile sig_atomic_t term_signal = 0; static volatile sig_atomic_t term_signal = 0;
#ifdef WITH_PAM @@ -141,10 +142,10 @@ set_term(int dummy)
#include <security/pam_appl.h>
@@ -146,14 +147,14 @@ set_term(int dummy)
{
term_signal = 1;
return; return;
} }
@ -34,11 +28,7 @@ Index: atd.c
nothing_to_do = 0; nothing_to_do = 0;
return; return;
} }
@@ -647,6 +648,7 @@ run_loop()
/* SIGCHLD handler - discards completion status of children */
@@ -807,10 +808,11 @@ run_loop()
if (nothing_to_do && buf.st_mtime <= last_chg)
return next_job; return next_job;
last_chg = buf.st_mtime; last_chg = buf.st_mtime;
@ -46,11 +36,7 @@ Index: atd.c
if ((spool = opendir(".")) == NULL) if ((spool = opendir(".")) == NULL)
perr("Cannot read " ATJOB_DIR); perr("Cannot read " ATJOB_DIR);
run_batch = 0; @@ -898,7 +900,7 @@ main(int argc, char *argv[])
nothing_to_do = 1;
@@ -1043,11 +1045,11 @@ main(int argc, char *argv[])
* A signal handler setting term_signal will make sure there's
* a clean exit.
*/ */
sigaction(SIGHUP, NULL, &act); sigaction(SIGHUP, NULL, &act);
@ -59,11 +45,7 @@ Index: atd.c
sigaction(SIGHUP, &act, NULL); sigaction(SIGHUP, &act, NULL);
sigaction(SIGTERM, NULL, &act); sigaction(SIGTERM, NULL, &act);
act.sa_handler = set_term; @@ -914,9 +916,10 @@ main(int argc, char *argv[])
sigaction(SIGTERM, &act, NULL);
@@ -1059,12 +1061,13 @@ main(int argc, char *argv[])
daemon_setup();
do { do {
now = time(NULL); now = time(NULL);
next_invocation = run_loop(); next_invocation = run_loop();
@ -75,4 +57,3 @@ Index: atd.c
} while (!term_signal); } while (!term_signal);
daemon_cleanup(); daemon_cleanup();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
}

View File

@ -1,40 +0,0 @@
Index: atd.c
===================================================================
--- atd.c.orig
+++ atd.c
@@ -663,15 +663,17 @@ run_file(const char *filename, uid_t uid
if (unlink(filename) == -1)
syslog(LOG_WARNING, "Warning: removing output file for job %li failed: %s",
jobno, strerror(errno));
#ifdef WITH_PAM
+ PRIV_START
pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT );
pam_close_session(pamh, PAM_SILENT);
pam_end(pamh, PAM_ABORT);
closelog();
openlog("atd", LOG_PID, LOG_ATD);
+ PRIV_END
#endif
/* The job is now finished. We can delete its input file.
*/
chdir(ATJOB_DIR);
@@ -784,15 +786,17 @@ run_file(const char *filename, uid_t uid
{
/* Parent */
waitpid(mail_pid, (int *) NULL, 0);
}
#ifdef WITH_PAM
+ PRIV_START
pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT );
pam_close_session(pamh, PAM_SILENT);
pam_end(pamh, PAM_ABORT);
closelog();
openlog("atd", LOG_PID, LOG_ATD);
+ PRIV_END
#endif
}
exit(EXIT_SUCCESS);
}

View File

@ -1,365 +0,0 @@
Index: atd.c
===================================================================
--- atd.c.orig
+++ atd.c
@@ -91,6 +91,10 @@ int selinux_enabled=0;
#include <selinux/av_permissions.h>
#endif
+#ifndef LOG_ATD
+#define LOG_ATD LOG_DAEMON
+#endif
+
/* Macros */
#define BATCH_INTERVAL_DEFAULT 60
@@ -116,7 +120,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;
@@ -128,12 +132,13 @@ static const struct pam_conv conv = {
#define PAM_FAIL_CHECK if (retcode != PAM_SUCCESS) { \
fprintf(stderr,"\n%s\n",pam_strerror(pamh, retcode)); \
syslog(LOG_ERR,"%s",pam_strerror(pamh, retcode)); \
+ pam_close_session(pamh, PAM_SILENT); \
pam_end(pamh, retcode); exit(1); \
}
#define PAM_END { retcode = pam_close_session(pamh,0); \
pam_end(pamh,retcode); }
-#endif /* HAVE_PAM */
+#endif /* WITH_PAM */
/* Signal handlers */
RETSIGTYPE
@@ -265,6 +270,19 @@ static int set_selinux_context(const cha
}
#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)
{
@@ -290,7 +308,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
@@ -452,16 +470,20 @@ 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_set_item(pamh, PAM_TTY, "atd");
+ PAM_FAIL_CHECK;
retcode = pam_acct_mgmt(pamh, PAM_SILENT);
PAM_FAIL_CHECK;
retcode = pam_open_session(pamh, PAM_SILENT);
PAM_FAIL_CHECK;
retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED | PAM_SILENT);
PAM_FAIL_CHECK;
+ closelog();
+ openlog("atd", LOG_PID, LOG_ATD);
PRIV_END
#endif
@@ -476,6 +498,16 @@ run_file(const char *filename, uid_t uid
else if (pid == 0) {
char *nul = NULL;
char **nenvp = &nul;
+#ifdef WITH_PAM
+ char **pam_envp=0L;
+#endif
+
+ PRIV_START
+#ifdef WITH_PAM
+ pam_envp = pam_getenvlist(pamh);
+ if ( ( pam_envp != 0L ) && (pam_envp[0] != 0L) )
+ nenvp = pam_envp;
+#endif
/* Set up things for the child; we want standard input from the
* input file, and standard output and error sent to our output file.
@@ -495,8 +527,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))
@@ -528,6 +558,16 @@ run_file(const char *filename, uid_t uid
#endif
//end
+#ifdef WITH_PAM
+ if ( ( nenvp != &nul ) && (pam_envp != 0L) && (*pam_envp != 0L))
+ {
+ for( nenvp = pam_envp; *nenvp != 0L; nenvp++)
+ free(*nenvp);
+ free( pam_envp );
+ nenvp = &nul;
+ pam_envp=0L;
+ }
+#endif
PRIV_END
}
/* We're the parent. Let's wait.
@@ -540,14 +580,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.
*/
@@ -572,6 +604,14 @@ run_file(const char *filename, uid_t uid
syslog(LOG_WARNING, "Warning: removing output file for job %li failed: %s",
jobno, strerror(errno));
+#ifdef WITH_PAM
+ pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT );
+ pam_close_session(pamh, PAM_SILENT);
+ pam_end(pamh, PAM_ABORT);
+ closelog();
+ openlog("atd", LOG_PID, LOG_ATD);
+#endif
+
/* The job is now finished. We can delete its input file.
*/
chdir(ATJOB_DIR);
@@ -580,7 +620,31 @@ run_file(const char *filename, uid_t uid
if (((send_mail != -1) && (buf.st_size != size)) || (send_mail == 1)) {
+ int mail_pid = -1;
+
+#ifdef WITH_PAM
PRIV_START
+ retcode = pam_start("atd", pentry->pw_name, &conv, &pamh);
+ PAM_FAIL_CHECK;
+ retcode = pam_set_item(pamh, PAM_TTY, "atd");
+ PAM_FAIL_CHECK;
+ retcode = pam_acct_mgmt(pamh, PAM_SILENT);
+ PAM_FAIL_CHECK;
+ retcode = pam_open_session(pamh, PAM_SILENT);
+ PAM_FAIL_CHECK;
+ retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED | PAM_SILENT);
+ PAM_FAIL_CHECK;
+ /* PAM has now re-opened our log to auth.info ! */
+ closelog();
+ openlog("atd", LOG_PID, LOG_ATD);
+ PRIV_END
+#endif
+
+ mail_pid = fork();
+
+ if ( mail_pid == 0 )
+ {
+ PRIV_START
if (initgroups(pentry->pw_name, pentry->pw_gid))
perr("Cannot initialize the supplementary group access list");
@@ -593,6 +657,47 @@ run_file(const char *filename, uid_t uid
chdir ("/");
+#ifdef WITH_SELINUX
+ if (selinux_enabled>0) {
+ security_context_t user_context=NULL;
+ security_context_t file_context=NULL;
+ int retval=0;
+ struct av_decision avd;
+
+ if (get_default_context(pentry->pw_name, NULL, &user_context))
+ perr("execle: couldn't get security context for user %s\n", pentry->pw_name);
+ /*
+ * Since crontab files are not directly executed,
+ * crond must ensure that the crontab file has
+ * a context that is appropriate for the context of
+ * the user cron job. It performs an entrypoint
+ * permission check for this purpose.
+ */
+ if (fgetfilecon(STDIN_FILENO, &file_context) < 0)
+ perr("fgetfilecon FAILED %s", filename);
+
+ retval = security_compute_av(user_context,
+ file_context,
+ SECCLASS_FILE,
+ FILE__ENTRYPOINT,
+ &avd);
+ freecon(file_context);
+ if (retval || ((FILE__ENTRYPOINT & avd.allowed) != FILE__ENTRYPOINT)) {
+ if (security_getenforce()==1)
+ perr("Not allowed to set exec context to %s for user %s\n", user_context,pentry->pw_name);
+ }
+
+ if (setexeccon(user_context) < 0) {
+ if (security_getenforce()==1) {
+ perr("Could not set exec context to %s for user %s\n", user_context,pentry->pw_name);
+ } else {
+ syslog(LOG_ERR, "Could not set exec context to %s for user %s\n", user_context,pentry->pw_name);
+ }
+ }
+ freecon(user_context);
+ }
+#endif
+
#if defined(SENDMAIL)
execl(SENDMAIL, "sendmail", "-i", mailname, (char *) NULL);
#else
@@ -600,7 +705,33 @@ run_file(const char *filename, uid_t uid
#endif
perr("Exec failed for mail command");
- PRIV_END
+ exit (-1);
+
+#ifdef WITH_SELINUX
+ if (selinux_enabled>0) {
+ if (setexeccon(NULL) < 0) {
+ perr("Could not resset exec context for user %s\n", pentry->pw_name);
+ }
+ }
+#endif
+
+ PRIV_END;
+ } else if ( mail_pid == -1 )
+ {
+ perr("fork of mailer failed");
+ }
+ else
+ {
+ /* Parent */
+ waitpid(mail_pid, (int *) NULL, 0);
+ }
+#ifdef WITH_PAM
+ pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT );
+ pam_close_session(pamh, PAM_SILENT);
+ pam_end(pamh, PAM_ABORT);
+ closelog();
+ openlog("atd", LOG_PID, LOG_ATD);
+#endif
}
exit(EXIT_SUCCESS);
}
@@ -819,12 +950,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;
run_as_daemon = 1;
Index: config.h.in
===================================================================
--- config.h.in.orig
+++ config.h.in
@@ -71,9 +71,6 @@
/* Define to 1 for PAM support */
#undef HAVE_PAM
-/* Define if you are building with_selinux */
-#undef WITH_SELINUX
-
/* Define to 1 if you have the `pstat_getdynamic' function. */
#undef HAVE_PSTAT_GETDYNAMIC
@@ -145,7 +142,7 @@
/* Define to 1 if you have the `waitpid' function. */
#undef HAVE_WAITPID
-/* Define to 1 if we need to provide our own yywrap() */
+/* need yywrap */
#undef NEED_YYWRAP
/* Define to 1 if your `struct nlist' has an `n_un' member. Obsolete, depend
@@ -195,6 +192,9 @@
<sys/cpustats.h>. */
#undef UMAX4_3
+/* use PAM */
+#undef WITH_PAM
+
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
`char[]'. */
#undef YYTEXT_POINTER
Index: perm.c
===================================================================
--- perm.c.orig
+++ perm.c
@@ -108,14 +108,15 @@ 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;
+ int retcode=0;
- if (uid == 0)
+ if (euid == 0)
return 1;
- if ((pentry = getpwuid(uid)) == NULL) {
+ if ((pentry = getpwuid(euid)) == NULL) {
perror("Cannot access user database");
exit(EXIT_FAILURE);
}
Index: configure.ac
===================================================================
--- configure.ac.orig
+++ configure.ac
@@ -277,5 +277,12 @@ AC_CHECK_LIB(selinux, is_selinux_enabled
AC_SUBST(SELINUXLIB)
AC_SUBST(WITH_SELINUX)
+AC_ARG_WITH(pam,
+[ --with-pam Define to enable pam support ],
+AC_DEFINE([WITH_PAM], [1], [use PAM]),
+)
+AC_CHECK_LIB(pam, pam_start, PAMLIB='-lpam -lpam_misc')
+AC_SUBST(PAMLIB)
+
AC_CONFIG_FILES(Makefile atrun atd.8 atrun.8 at.1 at.allow.5 batch)
AC_OUTPUT

View File

@ -1,17 +0,0 @@
Index: atd.c
===================================================================
--- atd.c.orig
+++ atd.c
@@ -577,11 +577,11 @@ run_file(const char *filename, uid_t uid
perr("Error in I/O redirection");
close(fd_in);
close(fd_out);
- nice((tolower((int) queue) - 'a' + 1) * 2);
+ nice((tolower((int) queue) - 'a' ) );
if (initgroups(pentry->pw_name, pentry->pw_gid))
perr("Cannot initialize the supplementary group access list");
if (setgid(ngid) < 0)

View File

@ -2,9 +2,7 @@ Index: at.c
=================================================================== ===================================================================
--- at.c.orig --- at.c.orig
+++ at.c +++ at.c
@@ -132,11 +132,13 @@ char atverify = 0; /* verify time inste @@ -134,7 +134,9 @@ static void sigc(int signo);
static void sigc(int signo);
static void alarmc(int signo); static void alarmc(int signo);
static char *cwdname(void); static char *cwdname(void);
static void writefile(time_t runtimer, char queue); static void writefile(time_t runtimer, char queue);
@ -15,11 +13,7 @@ Index: at.c
/* Signal catching functions */ /* Signal catching functions */
static RETSIGTYPE @@ -566,8 +568,20 @@ writefile(time_t runtimer, char queue)
sigc(int signo)
@@ -545,12 +547,24 @@ writefile(time_t runtimer, char queue)
break;
}
return; return;
} }
@ -41,11 +35,7 @@ Index: at.c
{ {
/* List all a user's jobs in the queue, by looping through ATJOB_DIR, /* List all a user's jobs in the queue, by looping through ATJOB_DIR,
* or everybody's if we are root * or everybody's if we are root
*/ @@ -606,6 +620,10 @@ list_jobs(void)
DIR *spool;
@@ -585,10 +599,14 @@ list_jobs(void)
continue;
if (sscanf(dirent->d_name, "%c%5lx%8lx", &queue, &jobno, &ctm) != 3) if (sscanf(dirent->d_name, "%c%5lx%8lx", &queue, &jobno, &ctm) != 3)
continue; continue;
@ -56,11 +46,7 @@ Index: at.c
if (atqueue && (queue != atqueue)) if (atqueue && (queue != atqueue))
continue; continue;
runtimer = 60 * (time_t) ctm; @@ -727,6 +745,29 @@ process_jobs(int argc, char **argv, int
runtime = localtime(&runtimer);
@@ -706,10 +724,33 @@ process_jobs(int argc, char **argv, int
}
}
return rc; return rc;
} /* delete_jobs */ } /* delete_jobs */
@ -90,12 +76,8 @@ Index: at.c
/* Global functions */ /* Global functions */
void * void *
mymalloc(size_t n) @@ -752,6 +793,8 @@ main(int argc, char **argv)
{ char *options = "q:f:MmbvlrdhVct:"; /* default options for at */
@@ -731,10 +772,12 @@ main(int argc, char **argv)
int program = AT; /* our default program */
char *options = "q:f:MmvlrdhVct:"; /* default options for at */
int disp_version = 0; int disp_version = 0;
time_t timer = 0; time_t timer = 0;
+ long *joblist = NULL; + long *joblist = NULL;
@ -103,11 +85,7 @@ Index: at.c
struct passwd *pwe; struct passwd *pwe;
struct group *ge; struct group *ge;
RELINQUISH_PRIVS @@ -889,8 +932,9 @@ main(int argc, char **argv)
@@ -868,12 +911,13 @@ main(int argc, char **argv)
switch (program) {
int i;
case ATQ: case ATQ:
REDUCE_PRIV(daemon_uid, daemon_gid) REDUCE_PRIV(daemon_uid, daemon_gid)
@ -119,15 +97,11 @@ Index: at.c
break; break;
case ATRM: case ATRM:
REDUCE_PRIV(daemon_uid, daemon_gid)
Index: panic.c Index: panic.c
=================================================================== ===================================================================
--- panic.c.orig --- panic.c.orig
+++ panic.c +++ panic.c
@@ -93,10 +93,11 @@ usage(void) @@ -95,6 +95,7 @@ usage(void)
/* Print usage and exit.
*/
fprintf(stderr, "Usage: at [-V] [-q x] [-f file] [-mMlbv] timespec ...\n" fprintf(stderr, "Usage: at [-V] [-q x] [-f file] [-mMlbv] timespec ...\n"
" at [-V] [-q x] [-f file] [-mMlbv] -t time\n" " at [-V] [-q x] [-f file] [-mMlbv] -t time\n"
" at -c job ...\n" " at -c job ...\n"
@ -135,5 +109,3 @@ Index: panic.c
" atq [-V] [-q x]\n" " atq [-V] [-q x]\n"
" at [ -rd ] job ...\n" " at [ -rd ] job ...\n"
" atrm [-V] job ...\n" " atrm [-V] job ...\n"
" batch\n");
exit(EXIT_FAILURE);

View File

@ -46,7 +46,7 @@ Index: atd.c
/* Local headers */ /* Local headers */
#include "privs.h" #include "privs.h"
@@ -930,6 +934,7 @@ main(int argc, char *argv[]) @@ -798,6 +802,7 @@ main(int argc, char *argv[])
* for execution and yet another one, optionally, for sending mail. * for execution and yet another one, optionally, for sending mail.
* Files which already have run are removed during the next invocation. * Files which already have run are removed during the next invocation.
*/ */
@ -54,7 +54,7 @@ Index: atd.c
int c; int c;
time_t next_invocation; time_t next_invocation;
struct sigaction act; struct sigaction act;
@@ -998,6 +1003,22 @@ main(int argc, char *argv[]) @@ -875,6 +880,22 @@ main(int argc, char *argv[])
} }
} }
@ -81,8 +81,8 @@ Index: configure.ac
=================================================================== ===================================================================
--- configure.ac.orig --- configure.ac.orig
+++ configure.ac +++ configure.ac
@@ -53,6 +53,8 @@ AC_CHECK_LIB(fl,yywrap, @@ -54,6 +54,8 @@ AC_CHECK_LIB(fl,yywrap,
AC_DEFINE([NEED_YYWRAP], 1, [need yywrap]) [Define to 1 if we need to provide our own yywrap()])
) )
+PKG_CHECK_MODULES([HX], [libHX]) +PKG_CHECK_MODULES([HX], [libHX])

View File

@ -1,226 +0,0 @@
Index: atd.c
===================================================================
--- atd.c.orig
+++ atd.c
@@ -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
+
/* Macros */
#define BATCH_INTERVAL_DEFAULT 60
@@ -195,6 +203,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)
{
@@ -442,9 +512,21 @@ 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");
+#ifdef WITH_SELINUX
+ if (selinux_enabled>0)
+ if (setexeccon(NULL) < 0)
+ if (security_getenforce()==1)
+ perr("Could not resset exec context for user %s\n", pentry->pw_name);
+#endif
+//end
PRIV_END
}
@@ -717,6 +799,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.
*/
Index: config.h.in
===================================================================
--- config.h.in.orig
+++ config.h.in
@@ -71,6 +71,9 @@
/* Define to 1 for PAM support */
#undef HAVE_PAM
+/* Define if you are building with_selinux */
+#undef WITH_SELINUX
+
/* Define to 1 if you have the `pstat_getdynamic' function. */
#undef HAVE_PSTAT_GETDYNAMIC
Index: configure.ac
===================================================================
--- configure.ac.orig
+++ configure.ac
@@ -5,7 +5,7 @@ AC_CONFIG_SRCDIR(at.c)
AC_PREFIX_DEFAULT(/usr)
AC_CONFIG_HEADER(config.h)
-AC_PREREQ([2.64])
+AC_PREREQ([2.69])
VERSION=AC_PACKAGE_VERSION
if test "X$CFLAGS" = "X"; then
@@ -40,18 +40,17 @@ case "$host" in
esac
AC_MSG_CHECKING(__attribute__((noreturn)))
-AC_TRY_COMPILE([], [void __attribute__((noreturn)) panic(void);],
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[void __attribute__((noreturn)) panic(void);]])],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_ATTRIBUTE_NORETURN, 1,
[Define to 1 if compiler supports __attribute__((noreturn))]),
AC_MSG_RESULT(no)
-)
+])
dnl Checks for libraries.
AC_CHECK_LIB(fl,yywrap,
[],
- AC_DEFINE(NEED_YYWRAP, 1,
- [Define to 1 if we need to provide our own yywrap()])
+ AC_DEFINE([NEED_YYWRAP], 1, [need yywrap])
)
dnl Checks for header files.
@@ -63,7 +62,17 @@ AC_CHECK_HEADERS(stdarg.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
-AC_TYPE_SIGNAL
+AC_DIAGNOSE([obsolete],[your code may safely assume C89 semantics that RETSIGTYPE is void.
+Remove this warning and the `AC_CACHE_CHECK' when you adjust the code.])dnl
+AC_CACHE_CHECK([return type of signal handlers],[ac_cv_type_signal],[AC_COMPILE_IFELSE(
+[AC_LANG_PROGRAM([#include <sys/types.h>
+#include <signal.h>
+],
+ [return *(signal (0, 0)) (0) == 1;])],
+ [ac_cv_type_signal=int],
+ [ac_cv_type_signal=void])])
+AC_DEFINE_UNQUOTED([RETSIGTYPE],[$ac_cv_type_signal],[Define as the return type of signal handlers
+ (`int' or `void').])
AC_TYPE_UID_T
AC_TYPE_MODE_T
AC_TYPE_OFF_T
@@ -260,5 +269,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] , [1], [enable selinux]),
+)
+AC_CHECK_LIB(selinux, is_selinux_enabled, SELINUXLIB=-lselinux)
+AC_SUBST(SELINUXLIB)
+AC_SUBST(WITH_SELINUX)
+
AC_CONFIG_FILES(Makefile atrun atd.8 atrun.8 at.1 at.allow.5 batch)
AC_OUTPUT
Index: Makefile.in
===================================================================
--- Makefile.in.orig
+++ Makefile.in
@@ -40,6 +40,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
@@ -73,7 +75,7 @@ at: $(ATOBJECTS)
$(LN_S) -f at atrm
atd: $(RUNOBJECTS)
- $(CC) $(LDFLAGS) -o atd $(RUNOBJECTS) $(LIBS) $(PAMLIB)
+ $(CC) $(LDFLAGS) -o atd $(RUNOBJECTS) $(LIBS) $(PAMLIB) $(SELINUXLIB)
y.tab.c y.tab.h: parsetime.y
$(YACC) -d parsetime.y

View File

@ -1,6 +1,8 @@
--- at-3.1.15.orig/atd.c Index: at-3.1.20/atd.c
+++ at-3.1.15/atd.c ===================================================================
@@ -919,6 +919,54 @@ run_loop() --- at-3.1.20.orig/atd.c
+++ at-3.1.20/atd.c
@@ -787,6 +787,54 @@ run_loop()
return next_job; return next_job;
} }
@ -55,7 +57,7 @@
/* Global functions */ /* Global functions */
int int
@@ -1032,7 +1080,7 @@ main(int argc, char *argv[]) @@ -909,7 +957,7 @@ main(int argc, char *argv[])
sigaction(SIGCHLD, &act, NULL); sigaction(SIGCHLD, &act, NULL);
if (!run_as_daemon) { if (!run_as_daemon) {
@ -64,7 +66,7 @@
run_loop(); run_loop();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
@@ -1055,13 +1103,14 @@ main(int argc, char *argv[]) @@ -932,13 +980,14 @@ main(int argc, char *argv[])
act.sa_handler = set_term; act.sa_handler = set_term;
sigaction(SIGINT, &act, NULL); sigaction(SIGINT, &act, NULL);
@ -81,8 +83,10 @@
} }
hupped = 0; hupped = 0;
} while (!term_signal); } while (!term_signal);
--- at-3.1.15.orig/config.h.in Index: at-3.1.20/config.h.in
+++ at-3.1.15/config.h.in ===================================================================
--- at-3.1.20.orig/config.h.in
+++ at-3.1.20/config.h.in
@@ -38,6 +38,9 @@ @@ -38,6 +38,9 @@
/* Define to 1 if you have the `getloadavg' function. */ /* Define to 1 if you have the `getloadavg' function. */
#undef HAVE_GETLOADAVG #undef HAVE_GETLOADAVG
@ -93,11 +97,13 @@
/* Define to 1 if you have the <getopt.h> header file. */ /* Define to 1 if you have the <getopt.h> header file. */
#undef HAVE_GETOPT_H #undef HAVE_GETOPT_H
--- at-3.1.15.orig/configure.ac Index: at-3.1.20/configure.ac
+++ at-3.1.15/configure.ac ===================================================================
@@ -254,6 +254,12 @@ AC_ARG_WITH(daemon_username, --- at-3.1.20.orig/configure.ac
) +++ at-3.1.20/configure.ac
AC_SUBST(DAEMON_USERNAME) @@ -263,6 +263,12 @@ fi
AC_SUBST(SELINUXLIB)
AC_SUBST(WITH_SELINUX)
+dnl check for POSIX timer functions +dnl check for POSIX timer functions
+AC_SEARCH_LIBS([timer_create],[rt]) +AC_SEARCH_LIBS([timer_create],[rt])

View File

@ -55,7 +55,7 @@ Index: Makefile.in
- cd $(IROOT)$(man5dir) && $(LN_S) -f at.allow.5 at.deny.5 - cd $(IROOT)$(man5dir) && $(LN_S) -f at.allow.5 at.deny.5
- $(INSTALL) -g root -o root -m 644 $(DOCS) $(IROOT)$(atdocdir) - $(INSTALL) -g root -o root -m 644 $(DOCS) $(IROOT)$(atdocdir)
+ $(INSTALL) -m 644 at.allow.5 $(IROOT)$(man5dir)/ + $(INSTALL) -m 644 at.allow.5 $(IROOT)$(man5dir)/
+ $(INSTALL) -m 644 at.deny.5 $(IROOT)$(man5dir)/ + cd $(IROOT)$(man5dir) && $(LN_S) -f at.allow.5 at.deny.5
+ $(INSTALL) -m 644 $(DOCS) $(IROOT)$(atdocdir) + $(INSTALL) -m 644 $(DOCS) $(IROOT)$(atdocdir)
rm -f $(IROOT)$(mandir)/cat1/at.1* $(IROOT)$(mandir)/cat1/batch.1* \ rm -f $(IROOT)$(mandir)/cat1/at.1* $(IROOT)$(mandir)/cat1/batch.1* \
$(IROOT)$(mandir)/cat1/atq.1* $(IROOT)$(mandir)/cat1/atq.1*

View File

@ -1,78 +0,0 @@
--- /dev/null
+++ at.allow.5
@@ -0,0 +1,36 @@
+.Id $Id: at.allow.5,v 1.1 1997/09/28 20:00:28 ig25 Exp $
+.TH AT.ALLOW 5 "Sep 1997" "" "Linux Programmer's Manual"
+.SH NAME
+at.allow, at.deny \- determine who can submit jobs via at or batch
+.SH DESCRIPTION
+The
+.I /etc/at.allow
+and
+.I /etc/at.deny
+files determine which user can submit commands for later execution via
+.BR at (1)
+or
+.BR batch (1) .
+.PP
+The format of the files is a list of usernames, one on each line. Whitespace
+is not permitted.
+.PP
+The superuser may always use
+.BR at .
+.PP
+If the file
+.I /etc/at.allow
+exists, only usernames mentioned in it are allowed to use
+.BR at .
+.PP
+If
+.I /etc/at.allow
+does not exist,
+.I /etc/at.deny
+is checked.
+.SH "SEE ALSO"
+.BR at (1),
+.BR atrun (1),
+.BR cron (8),
+.BR crontab (1),
+.BR atd (8).
--- /dev/null
+++ at.deny.5
@@ -0,0 +1,36 @@
+.Id $Id: at.allow.5,v 1.1 1997/09/28 20:00:28 ig25 Exp $
+.TH AT.ALLOW 5 "Sep 1997" "" "Linux Programmer's Manual"
+.SH NAME
+at.allow, at.deny \- determine who can submit jobs via at or batch
+.SH DESCRIPTION
+The
+.I /etc/at.allow
+and
+.I /etc/at.deny
+files determine which user can submit commands for later execution via
+.BR at (1)
+or
+.BR batch (1) .
+.PP
+The format of the files is a list of usernames, one on each line. Whitespace
+is not permitted.
+.PP
+The superuser may always use
+.BR at .
+.PP
+If the file
+.I /etc/at.allow
+exists, only usernames mentioned in it are allowed to use
+.BR at .
+.PP
+If
+.I /etc/at.allow
+does not exist,
+.I /etc/at.deny
+is checked.
+.SH "SEE ALSO"
+.BR at (1),
+.BR atrun (1),
+.BR cron (8),
+.BR crontab (1),
+.BR atd (8).

View File

@ -1,3 +1,28 @@
-------------------------------------------------------------------
Sat Jul 22 07:21:45 UTC 2017 - tchvatal@suse.com
- Drop patch at-3.1.8-eal3-manpages.patch merged upstream differently
-------------------------------------------------------------------
Sat Jul 22 07:07:28 UTC 2017 - tchvatal@suse.com
- Version update to at 3.1.20 to match latest upstream:
* Pam and selinux implemented upstream
* various tiny fixes
- Rebase patches:
* at-3.1.13-documentation-dir.patch
* at-3.1.13-massive_batch.patch
* at-3.1.14-joblist.patch
* at-3.1.14-parse-suse-sysconfig.patch
* at-3.1.14-usePOSIXtimers.patch
* at-3.1.14.patch
- Drop no longer needed patches:
* at-3.1.13-formatbugs.patch
* at-3.1.13-pam-session-as-root.patch
* at-3.1.13-pam.patch
* at-3.1.13-queue-nice-level.patch
* at-3.1.14-selinux.patch
------------------------------------------------------------------- -------------------------------------------------------------------
Tue Oct 13 13:36:03 UTC 2015 - kstreitova@suse.com Tue Oct 13 13:36:03 UTC 2015 - kstreitova@suse.com

25
at.spec
View File

@ -1,7 +1,7 @@
# #
# spec file for package at # spec file for package at
# #
# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. # Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
# #
# All modifications and additions to the file contributed by third parties # All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed # remain the property of their copyright owners, unless otherwise agreed
@ -17,7 +17,7 @@
Name: at Name: at
Version: 3.1.16 Version: 3.1.20
Release: 0 Release: 0
Summary: A Job Manager Summary: A Job Manager
License: GPL-2.0+ License: GPL-2.0+
@ -29,16 +29,8 @@ Source3: sysconfig.atd
Source5: atd.service Source5: atd.service
Patch0: at-3.1.14.patch Patch0: at-3.1.14.patch
Patch4: at-3.1.14-joblist.patch Patch4: at-3.1.14-joblist.patch
Patch5: at-3.1.14-selinux.patch
Patch7: at-3.1.8-eal3-manpages.patch
## no bugs anymore for patch8. Just paranoia checking
Patch8: at-3.1.13-formatbugs.patch
Patch9: at-3.1.13-pam.patch
Patch10: at-3.1.13-massive_batch.patch Patch10: at-3.1.13-massive_batch.patch
Patch11: at-3.1.13-documentation-dir.patch Patch11: at-3.1.13-documentation-dir.patch
Patch12: at-3.1.13-queue-nice-level.patch
# PATCH-FIX-UPSTREAM pam-session-as-root (bnc#408986, bnc#239210)
Patch14: at-3.1.13-pam-session-as-root.patch
# PATCH-FIX-UPSTREAM clean-up opened descriptors (bnc#533454, bnc#523346) # PATCH-FIX-UPSTREAM clean-up opened descriptors (bnc#533454, bnc#523346)
Patch15: at-3.1.13-leak-fix.patch Patch15: at-3.1.13-leak-fix.patch
#PATCH-FIX-OPENSUSE add proper system users to the deny list #PATCH-FIX-OPENSUSE add proper system users to the deny list
@ -86,14 +78,8 @@ This program allows you to run jobs at specified times.
%setup -q %setup -q
%patch0 %patch0
%patch4 %patch4
%patch5
%patch7
%patch8
%patch9
%patch10 %patch10
%patch11 %patch11
%patch12
%patch14
%patch15 %patch15
%patch16 %patch16
%patch17 -p1 %patch17 -p1
@ -109,13 +95,10 @@ This program allows you to run jobs at specified times.
%patch29 -p1 %patch29 -p1
%build %build
rm -fv y.tab.c y.tab.h lex.yy.c lex.yy.o y.tab.o
autoreconf -fiv
export CFLAGS="%{?optflags} -fPIE"
export LDFLAGS="-pie"
export SENDMAIL=%{_sbindir}/sendmail export SENDMAIL=%{_sbindir}/sendmail
autoreconf -fvi
%configure \ %configure \
--with-pam \ --with-pam \
--with-selinux \ --with-selinux \

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cb9af59c6a54edce9536ba629841055409d1f89d8ae26494727a97141fb4d5c1
size 123174

3
at_3.1.20.orig.tar.gz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0871923cab73050b98ace020664eb2ddc1e669e4166b5abb64d864d02fcefab9
size 127666