bc9aef5aa3
- bypass the PAM check in crontab for root (#1169175)
236 lines
7.3 KiB
Diff
236 lines
7.3 KiB
Diff
diff --git a/src/cron.c b/src/cron.c
|
|
index 901a655..d8b2978 100644
|
|
--- a/src/cron.c
|
|
+++ b/src/cron.c
|
|
@@ -525,7 +525,6 @@ static void find_jobs(int vtime, cron_db * db, int doWild, int doNonWild, long v
|
|
int minute, hour, dom, month, dow;
|
|
user *u;
|
|
entry *e;
|
|
- const char *uname;
|
|
|
|
/* The support for the job-specific timezones is not perfect. There will
|
|
* be jobs missed or run twice during the DST change in the job timezone.
|
|
@@ -562,40 +561,30 @@ static void find_jobs(int vtime, cron_db * db, int doWild, int doNonWild, long v
|
|
*/
|
|
for (u = db->head; u != NULL; u = u->next) {
|
|
for (e = u->crontab; e != NULL; e = e->next) {
|
|
- Debug(DSCH | DEXT, ("user [%s:%ld:%ld:...] cmd=\"%s\"\n",
|
|
- e->pwd->pw_name, (long) e->pwd->pw_uid,
|
|
- (long) e->pwd->pw_gid, e->cmd));
|
|
- uname = e->pwd->pw_name;
|
|
- /* check if user exists in time of job is being run f.e. ldap */
|
|
- if (getpwnam(uname) != NULL) {
|
|
- time_t virtualSecond = (vtime - e->delay) * SECONDS_PER_MINUTE;
|
|
- time_t virtualGMTSecond = virtualSecond - vGMToff;
|
|
- job_tz = env_get("CRON_TZ", e->envp);
|
|
- maketime(job_tz, orig_tz);
|
|
- /* here we test whether time is NOW */
|
|
- if (bit_test(e->minute, minute) &&
|
|
- bit_test(e->hour, hour) &&
|
|
- bit_test(e->month, month) &&
|
|
- (((e->flags & DOM_STAR) || (e->flags & DOW_STAR))
|
|
- ? (bit_test(e->dow, dow) && bit_test(e->dom, dom))
|
|
+ time_t virtualSecond = (vtime - e->delay) * SECONDS_PER_MINUTE;
|
|
+ time_t virtualGMTSecond = virtualSecond - vGMToff;
|
|
+ job_tz = env_get("CRON_TZ", e->envp);
|
|
+ maketime(job_tz, orig_tz);
|
|
+
|
|
+ /* here we test whether time is NOW */
|
|
+ if (bit_test(e->minute, minute) &&
|
|
+ bit_test(e->hour, hour) &&
|
|
+ bit_test(e->month, month) &&
|
|
+ (((e->flags & DOM_STAR) || (e->flags & DOW_STAR))
|
|
+ ? (bit_test(e->dow, dow) && bit_test(e->dom, dom))
|
|
: (bit_test(e->dow, dow) || bit_test(e->dom, dom))
|
|
- )
|
|
- ) {
|
|
- if (job_tz != NULL && vGMToff != GMToff)
|
|
- /* do not try to run the jobs from different timezones
|
|
- * during the DST switch of the default timezone.
|
|
- */
|
|
- continue;
|
|
-
|
|
- if ((doNonWild &&
|
|
- !(e->flags & (MIN_STAR | HR_STAR))) ||
|
|
- (doWild && (e->flags & (MIN_STAR | HR_STAR))))
|
|
- job_add(e, u); /*will add job, if it isn't in queue already for NOW. */
|
|
- }
|
|
- }
|
|
- else {
|
|
- log_it(uname, getpid(), "ERROR", "getpwnam() failed",errno);
|
|
- Debug(DSCH | DEXT, ("%s:%d pid=%d time=%ld getpwnam(%s) failed errno=%d error=%s\n",__FILE__,__LINE__,getpid(),time(NULL),uname,errno,strerror(errno)));
|
|
+ )
|
|
+ ) {
|
|
+ if (job_tz != NULL && vGMToff != GMToff)
|
|
+ /* do not try to run the jobs from different timezones
|
|
+ * during the DST switch of the default timezone.
|
|
+ */
|
|
+ continue;
|
|
+
|
|
+ if ((doNonWild &&
|
|
+ !(e->flags & (MIN_STAR | HR_STAR))) ||
|
|
+ (doWild && (e->flags & (MIN_STAR | HR_STAR))))
|
|
+ job_add(e, u); /*will add job, if it isn't in queue already for NOW. */
|
|
}
|
|
}
|
|
}
|
|
diff --git a/src/entry.c b/src/entry.c
|
|
index fa69524..3638207 100644
|
|
--- a/src/entry.c
|
|
+++ b/src/entry.c
|
|
@@ -99,6 +99,7 @@ entry *load_entry(FILE * file, void (*error_func) (), struct passwd *pw,
|
|
char envstr[MAX_ENVSTR];
|
|
char **tenvp;
|
|
char *p;
|
|
+ struct passwd temppw;
|
|
|
|
Debug(DPARS, ("load_entry()...about to eat comments\n"));
|
|
|
|
@@ -286,11 +287,15 @@ entry *load_entry(FILE * file, void (*error_func) (), struct passwd *pw,
|
|
|
|
pw = getpwnam(username);
|
|
if (pw == NULL) {
|
|
- ecode = e_username;
|
|
- goto eof;
|
|
- }
|
|
- Debug(DPARS, ("load_entry()...uid %ld, gid %ld\n",
|
|
+ Debug(DPARS, ("load_entry()...unknown user entry\n"));
|
|
+ memset(&temppw, 0, sizeof (temppw));
|
|
+ temppw.pw_name = username;
|
|
+ temppw.pw_passwd = "";
|
|
+ pw = &temppw;
|
|
+ } else {
|
|
+ Debug(DPARS, ("load_entry()...uid %ld, gid %ld\n",
|
|
(long) pw->pw_uid, (long) pw->pw_gid));
|
|
+ }
|
|
}
|
|
|
|
if ((e->pwd = pw_dup(pw)) == NULL) {
|
|
@@ -331,17 +336,11 @@ entry *load_entry(FILE * file, void (*error_func) (), struct passwd *pw,
|
|
else
|
|
log_it("CRON", getpid(), "ERROR", "can't set SHELL", 0);
|
|
}
|
|
- if (!env_get("HOME", e->envp)) {
|
|
- if (glue_strings(envstr, sizeof envstr, "HOME", pw->pw_dir, '=')) {
|
|
- if ((tenvp = env_set(e->envp, envstr)) == NULL) {
|
|
- ecode = e_memory;
|
|
- goto eof;
|
|
- }
|
|
- e->envp = tenvp;
|
|
- }
|
|
- else
|
|
- log_it("CRON", getpid(), "ERROR", "can't set HOME", 0);
|
|
+ if ((tenvp = env_update_home(e->envp, pw->pw_dir)) == NULL) {
|
|
+ ecode = e_memory;
|
|
+ goto eof;
|
|
}
|
|
+ e->envp = tenvp;
|
|
#ifndef LOGIN_CAP
|
|
/* If login.conf is in used we will get the default PATH later. */
|
|
if (ChangePath && !env_get("PATH", e->envp)) {
|
|
diff --git a/src/env.c b/src/env.c
|
|
index 479e6cc..7cc5aed 100644
|
|
--- a/src/env.c
|
|
+++ b/src/env.c
|
|
@@ -25,6 +25,7 @@
|
|
#include <errno.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
+#include <sys/types.h>
|
|
#include <unistd.h>
|
|
|
|
#include "globals.h"
|
|
@@ -295,3 +296,19 @@ char *env_get(const char *name, char **envp) {
|
|
}
|
|
return (NULL);
|
|
}
|
|
+
|
|
+char **env_update_home(char **envp, const char *dir) {
|
|
+ char envstr[MAX_ENVSTR];
|
|
+
|
|
+ if (dir == NULL || *dir == '\0' || env_get("HOME", envp)) {
|
|
+ return envp;
|
|
+ }
|
|
+
|
|
+ if (glue_strings(envstr, sizeof envstr, "HOME", dir, '=')) {
|
|
+ envp = env_set(envp, envstr);
|
|
+ }
|
|
+ else
|
|
+ log_it("CRON", getpid(), "ERROR", "can't set HOME", 0);
|
|
+
|
|
+ return envp;
|
|
+}
|
|
diff --git a/src/funcs.h b/src/funcs.h
|
|
index 76376b9..ddf9e2a 100644
|
|
--- a/src/funcs.h
|
|
+++ b/src/funcs.h
|
|
@@ -82,7 +82,8 @@ char *env_get(const char *, char **),
|
|
*first_word(const char *, const char *),
|
|
**env_init(void),
|
|
**env_copy(char **),
|
|
- **env_set(char **, const char *);
|
|
+ **env_set(char **, const char *),
|
|
+ **env_update_home(char **, const char *);
|
|
|
|
user *load_user(int, struct passwd *, const char *, const char *, const char *),
|
|
*find_user(cron_db *, const char *, const char *);
|
|
diff --git a/src/job.c b/src/job.c
|
|
index 8ad14db..60a404a 100644
|
|
--- a/src/job.c
|
|
+++ b/src/job.c
|
|
@@ -22,6 +22,11 @@
|
|
#include "config.h"
|
|
|
|
#include <stdlib.h>
|
|
+#include <pwd.h>
|
|
+#include <errno.h>
|
|
+#include <sys/types.h>
|
|
+#include <unistd.h>
|
|
+#include <string.h>
|
|
|
|
#include "funcs.h"
|
|
#include "globals.h"
|
|
@@ -36,12 +41,42 @@ static job *jhead = NULL, *jtail = NULL;
|
|
|
|
void job_add(entry * e, user * u) {
|
|
job *j;
|
|
+ struct passwd *newpwd;
|
|
+ struct passwd *temppwd;
|
|
+ const char *uname;
|
|
|
|
/* if already on queue, keep going */
|
|
for (j = jhead; j != NULL; j = j->next)
|
|
if (j->e == e && j->u == u)
|
|
return;
|
|
|
|
+ uname = e->pwd->pw_name;
|
|
+ /* check if user exists in time of job is being run f.e. ldap */
|
|
+ if ((temppwd = getpwnam(uname)) != NULL) {
|
|
+ char **tenvp;
|
|
+
|
|
+ Debug(DSCH | DEXT, ("user [%s:%ld:%ld:...] cmd=\"%s\"\n",
|
|
+ e->pwd->pw_name, (long) temppwd->pw_uid,
|
|
+ (long) temppwd->pw_gid, e->cmd));
|
|
+ if ((newpwd = pw_dup(temppwd)) == NULL) {
|
|
+ log_it(uname, getpid(), "ERROR", "memory allocation failed", errno);
|
|
+ return;
|
|
+ }
|
|
+ free(e->pwd);
|
|
+ e->pwd = newpwd;
|
|
+
|
|
+ if ((tenvp = env_update_home(e->envp, e->pwd->pw_dir)) == NULL) {
|
|
+ log_it(uname, getpid(), "ERROR", "memory allocation failed", errno);
|
|
+ return;
|
|
+ }
|
|
+ e->envp = tenvp;
|
|
+ } else {
|
|
+ log_it(uname, getpid(), "ERROR", "getpwnam() failed",errno);
|
|
+ Debug(DSCH | DEXT, ("%s:%d pid=%d time=%ld getpwnam(%s) failed errno=%d error=%s\n",
|
|
+ __FILE__,__LINE__,getpid(),time(NULL),uname,errno,strerror(errno)));
|
|
+ return;
|
|
+ }
|
|
+
|
|
/* build a job queue element */
|
|
if ((j = (job *) malloc(sizeof (job))) == NULL)
|
|
return;
|