Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:GA
at.2219
at-3.1.13-pam.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File at-3.1.13-pam.patch of Package at.2219
Index: atd.c =================================================================== --- atd.c.orig +++ atd.c @@ -89,10 +89,14 @@ int selinux_enabled=0; #include <selinux/flask.h> #include <selinux/av_permissions.h> #endif +#ifndef LOG_ATD +#define LOG_ATD LOG_DAEMON +#endif + /* Macros */ #define BATCH_INTERVAL_DEFAULT 60 #define CHECK_INTERVAL 3600 @@ -114,11 +118,11 @@ static int nothing_to_do; unsigned int batch_interval; static int run_as_daemon = 0; static volatile sig_atomic_t term_signal = 0; -#ifdef HAVE_PAM +#ifdef WITH_PAM #include <security/pam_appl.h> static pam_handle_t *pamh = NULL; static const struct pam_conv conv = { @@ -126,16 +130,17 @@ static const struct pam_conv conv = { }; #define PAM_FAIL_CHECK if (retcode != PAM_SUCCESS) { \ fprintf(stderr,"\n%s\n",pam_strerror(pamh, retcode)); \ syslog(LOG_ERR,"%s",pam_strerror(pamh, retcode)); \ + pam_close_session(pamh, PAM_SILENT); \ pam_end(pamh, retcode); exit(1); \ } #define PAM_END { retcode = pam_close_session(pamh,0); \ pam_end(pamh,retcode); } -#endif /* HAVE_PAM */ +#endif /* WITH_PAM */ /* Signal handlers */ RETSIGTYPE set_term(int dummy) { @@ -263,10 +268,23 @@ static int set_selinux_context(const cha freecon(user_context); return 0; } #endif +#undef ATD_MAIL_PROGRAM +#undef ATD_MAIL_NAME +#if defined(SENDMAIL) +#define ATD_MAIL_PROGRAM SENDMAIL +#define ATD_MAIL_NAME "sendmail" +#elif defined(MAILC) +#define ATD_MAIL_PROGRAM MAILC +#define ATD_MAIL_NAME "mail" +#elif defined(MAILX) +#define ATD_MAIL_PROGRAM MAILX +#define ATD_MAIL_NAME "mailx" +#endif + static void run_file(const char *filename, uid_t uid, gid_t gid) { /* Run a file by by spawning off a process which redirects I/O, * spawns a subshell, then waits for it to complete and sends @@ -288,11 +306,11 @@ run_file(const char *filename, uid_t uid int ngid; char queue; char fmt[64]; unsigned long jobno; int rc; -#ifdef HAVE_PAM +#ifdef WITH_PAM int retcode; #endif #ifdef _SC_LOGIN_NAME_MAX errno = 0; @@ -450,20 +468,24 @@ run_file(const char *filename, uid_t uid write_string(fd_out, mailname); write_string(fd_out, "\n\n"); fstat(fd_out, &buf); size = buf.st_size; -#ifdef HAVE_PAM +#ifdef WITH_PAM PRIV_START retcode = pam_start("atd", pentry->pw_name, &conv, &pamh); PAM_FAIL_CHECK; + retcode = pam_set_item(pamh, PAM_TTY, "atd"); + PAM_FAIL_CHECK; retcode = pam_acct_mgmt(pamh, PAM_SILENT); PAM_FAIL_CHECK; retcode = pam_open_session(pamh, PAM_SILENT); PAM_FAIL_CHECK; retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED | PAM_SILENT); PAM_FAIL_CHECK; + closelog(); + openlog("atd", LOG_PID, LOG_ATD); PRIV_END #endif close(STDIN_FILENO); close(STDOUT_FILENO); @@ -474,10 +496,20 @@ run_file(const char *filename, uid_t uid perr("Error in fork"); else if (pid == 0) { char *nul = NULL; char **nenvp = &nul; +#ifdef WITH_PAM + char **pam_envp=0L; +#endif + + PRIV_START +#ifdef WITH_PAM + pam_envp = pam_getenvlist(pamh); + if ( ( pam_envp != 0L ) && (pam_envp[0] != 0L) ) + nenvp = pam_envp; +#endif /* Set up things for the child; we want standard input from the * input file, and standard output and error sent to our output file. */ if (lseek(fd_in, (off_t) 0, SEEK_SET) < 0) @@ -493,12 +525,10 @@ run_file(const char *filename, uid_t uid perr("Error in I/O redirection"); close(fd_in); close(fd_out); - PRIV_START - nice((tolower((int) queue) - 'a' + 1) * 2); if (initgroups(pentry->pw_name, pentry->pw_gid)) perr("Cannot initialize the supplementary group access list"); @@ -526,10 +556,20 @@ run_file(const char *filename, uid_t uid if (security_getenforce()==1) perr("Could not resset exec context for user %s\n", pentry->pw_name); #endif //end +#ifdef WITH_PAM + if ( ( nenvp != &nul ) && (pam_envp != 0L) && (*pam_envp != 0L)) + { + for( nenvp = pam_envp; *nenvp != 0L; nenvp++) + free(*nenvp); + free( pam_envp ); + nenvp = &nul; + pam_envp=0L; + } +#endif PRIV_END } /* We're the parent. Let's wait. */ close(fd_in); @@ -538,18 +578,10 @@ run_file(const char *filename, uid_t uid non-blocking waitpid. So this blocking one will eventually return with an ECHILD error. */ waitpid(pid, (int *) NULL, 0); -#ifdef HAVE_PAM - PRIV_START - pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT); - retcode = pam_close_session(pamh, PAM_SILENT); - pam_end(pamh, retcode); - PRIV_END -#endif - /* Send mail. Unlink the output file after opening it, so it * doesn't hang around after the run. */ fstat(fd_out, &buf); lseek(fd_out, 0, SEEK_SET); @@ -570,19 +602,51 @@ run_file(const char *filename, uid_t uid if (unlink(filename) == -1) syslog(LOG_WARNING, "Warning: removing output file for job %li failed: %s", jobno, strerror(errno)); +#ifdef WITH_PAM + pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT ); + pam_close_session(pamh, PAM_SILENT); + pam_end(pamh, PAM_ABORT); + closelog(); + openlog("atd", LOG_PID, LOG_ATD); +#endif + /* The job is now finished. We can delete its input file. */ chdir(ATJOB_DIR); unlink(newname); free(newname); if (((send_mail != -1) && (buf.st_size != size)) || (send_mail == 1)) { + int mail_pid = -1; + +#ifdef WITH_PAM PRIV_START + retcode = pam_start("atd", pentry->pw_name, &conv, &pamh); + PAM_FAIL_CHECK; + retcode = pam_set_item(pamh, PAM_TTY, "atd"); + PAM_FAIL_CHECK; + retcode = pam_acct_mgmt(pamh, PAM_SILENT); + PAM_FAIL_CHECK; + retcode = pam_open_session(pamh, PAM_SILENT); + PAM_FAIL_CHECK; + retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED | PAM_SILENT); + PAM_FAIL_CHECK; + /* PAM has now re-opened our log to auth.info ! */ + closelog(); + openlog("atd", LOG_PID, LOG_ATD); + PRIV_END +#endif + + mail_pid = fork(); + + if ( mail_pid == 0 ) + { + PRIV_START if (initgroups(pentry->pw_name, pentry->pw_gid)) perr("Cannot initialize the supplementary group access list"); if (setgid(gid) < 0) @@ -591,18 +655,85 @@ run_file(const char *filename, uid_t uid if (setuid(uid) < 0) perr("Cannot set user id"); chdir ("/"); +#ifdef WITH_SELINUX + if (selinux_enabled>0) { + security_context_t user_context=NULL; + security_context_t file_context=NULL; + int retval=0; + struct av_decision avd; + + if (get_default_context(pentry->pw_name, NULL, &user_context)) + perr("execle: couldn't get security context for user %s\n", pentry->pw_name); + /* + * Since crontab files are not directly executed, + * crond must ensure that the crontab file has + * a context that is appropriate for the context of + * the user cron job. It performs an entrypoint + * permission check for this purpose. + */ + if (fgetfilecon(STDIN_FILENO, &file_context) < 0) + perr("fgetfilecon FAILED %s", filename); + + retval = security_compute_av(user_context, + file_context, + SECCLASS_FILE, + FILE__ENTRYPOINT, + &avd); + freecon(file_context); + if (retval || ((FILE__ENTRYPOINT & avd.allowed) != FILE__ENTRYPOINT)) { + if (security_getenforce()==1) + perr("Not allowed to set exec context to %s for user %s\n", user_context,pentry->pw_name); + } + + if (setexeccon(user_context) < 0) { + if (security_getenforce()==1) { + perr("Could not set exec context to %s for user %s\n", user_context,pentry->pw_name); + } else { + syslog(LOG_ERR, "Could not set exec context to %s for user %s\n", user_context,pentry->pw_name); + } + } + freecon(user_context); + } +#endif + #if defined(SENDMAIL) execl(SENDMAIL, "sendmail", "-i", mailname, (char *) NULL); #else #error "No mail command specified." #endif perr("Exec failed for mail command"); - PRIV_END + exit (-1); + +#ifdef WITH_SELINUX + if (selinux_enabled>0) { + if (setexeccon(NULL) < 0) { + perr("Could not resset exec context for user %s\n", pentry->pw_name); + } + } +#endif + + PRIV_END; + } else if ( mail_pid == -1 ) + { + perr("fork of mailer failed"); + } + else + { + /* Parent */ + waitpid(mail_pid, (int *) NULL, 0); + } +#ifdef WITH_PAM + pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT ); + pam_close_session(pamh, PAM_SILENT); + pam_end(pamh, PAM_ABORT); + closelog(); + openlog("atd", LOG_PID, LOG_ATD); +#endif } exit(EXIT_SUCCESS); } static time_t @@ -817,16 +948,11 @@ main(int argc, char *argv[]) daemon_gid = ge->gr_gid; RELINQUISH_PRIVS_ROOT(daemon_uid, daemon_gid) -#ifndef LOG_CRON -#define LOG_CRON LOG_DAEMON -#endif - - openlog("atd", LOG_PID, LOG_CRON); - + openlog("atd", LOG_PID, LOG_ATD); opterr = 0; errno = 0; run_as_daemon = 1; batch_interval = BATCH_INTERVAL_DEFAULT; Index: config.h.in =================================================================== --- config.h.in.orig +++ config.h.in @@ -69,13 +69,10 @@ #undef HAVE_NLIST_H /* Define to 1 for PAM support */ #undef HAVE_PAM -/* Define if you are building with_selinux */ -#undef WITH_SELINUX - /* Define to 1 if you have the `pstat_getdynamic' function. */ #undef HAVE_PSTAT_GETDYNAMIC /* Define to 1 if you have the <security/pam_appl.h> header file. */ #undef HAVE_SECURITY_PAM_APPL_H @@ -143,11 +140,11 @@ #undef HAVE_VPRINTF /* Define to 1 if you have the `waitpid' function. */ #undef HAVE_WAITPID -/* Define to 1 if we need to provide our own yywrap() */ +/* need yywrap */ #undef NEED_YYWRAP /* Define to 1 if your `struct nlist' has an `n_un' member. Obsolete, depend on `HAVE_STRUCT_NLIST_N_UN_N_NAME */ #undef NLIST_NAME_UNION @@ -193,10 +190,13 @@ /* Define to 1 for Encore UMAX 4.3 that has <inq_status/cpustats.h> instead of <sys/cpustats.h>. */ #undef UMAX4_3 +/* use PAM */ +#undef WITH_PAM + /* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a `char[]'. */ #undef YYTEXT_POINTER /* Define to empty if `const' does not conform to ANSI C. */ Index: perm.c =================================================================== --- perm.c.orig +++ perm.c @@ -106,18 +106,19 @@ user_in_file(const char *path, const cha /* Global functions */ int check_permission() { - uid_t uid = geteuid(); + uid_t euid = geteuid(), uid=getuid(), egid=getegid(), gid=getgid(); struct passwd *pentry; int allow = 0, deny = 1; + int retcode=0; - if (uid == 0) + if (euid == 0) return 1; - if ((pentry = getpwuid(uid)) == NULL) { + if ((pentry = getpwuid(euid)) == NULL) { perror("Cannot access user database"); exit(EXIT_FAILURE); } allow = user_in_file(ETCDIR "/at.allow", pentry->pw_name); Index: configure.ac =================================================================== --- configure.ac.orig +++ configure.ac @@ -265,7 +265,14 @@ AC_DEFINE(WITH_SELINUX), ) AC_CHECK_LIB(selinux, is_selinux_enabled, SELINUXLIB=-lselinux) AC_SUBST(SELINUXLIB) AC_SUBST(WITH_SELINUX) +AC_ARG_WITH(pam, +[ --with-pam Define to enable pam support ], +AC_DEFINE(WITH_PAM), +) +AC_CHECK_LIB(pam, pam_start, PAMLIB='-lpam -lpam_misc') +AC_SUBST(PAMLIB) + AC_CONFIG_FILES(Makefile atrun atd.8 atrun.8 at.1 at.allow.5 batch) AC_OUTPUT
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor