diff options
author | Eric Andersen <andersen@codepoet.org> | 2003-07-28 07:40:39 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2003-07-28 07:40:39 +0000 |
commit | 35e643b39f6cc77b702c714cfa8e70f1e10601a9 (patch) | |
tree | ad6b608081a4dde117563a1f1e9a6e3892a8752c /miscutils/crond.c | |
parent | 4f4631732cab5886105d8809d4e9b17711def65b (diff) | |
download | busybox-w32-35e643b39f6cc77b702c714cfa8e70f1e10601a9.tar.gz busybox-w32-35e643b39f6cc77b702c714cfa8e70f1e10601a9.tar.bz2 busybox-w32-35e643b39f6cc77b702c714cfa8e70f1e10601a9.zip |
last_patch95 from vodz:
Hi.
Last patch have new libbb function
vfork_rexec() for can use daemon() to uClinux system.
This patched daemons: syslog, klogd, inetd, crond.
This not tested! I havn`t this systems.
Also. Previous patch for feature request MD5 crypt password for
httpd don`t sended to this mailist on 07/15/03
(mailist have Pytom module problem?).
The previous patch included, and have testing.
--w
vodz
Diffstat (limited to 'miscutils/crond.c')
-rw-r--r-- | miscutils/crond.c | 411 |
1 files changed, 186 insertions, 225 deletions
diff --git a/miscutils/crond.c b/miscutils/crond.c index 9d9ecc290..198bc2d85 100644 --- a/miscutils/crond.c +++ b/miscutils/crond.c | |||
@@ -41,14 +41,11 @@ | |||
41 | #ifndef TMPDIR | 41 | #ifndef TMPDIR |
42 | #define TMPDIR "/var/spool/cron" | 42 | #define TMPDIR "/var/spool/cron" |
43 | #endif | 43 | #endif |
44 | #ifndef LOG_FILE | ||
45 | #define LOG_FILE "/var/log/cron" | ||
46 | #endif | ||
47 | #ifndef SENDMAIL | 44 | #ifndef SENDMAIL |
48 | #define SENDMAIL "/usr/sbin/sendmail" | 45 | #define SENDMAIL "/usr/sbin/sendmail" |
49 | #endif | 46 | #endif |
50 | #ifndef SENDMAIL_ARGS | 47 | #ifndef SENDMAIL_ARGS |
51 | #define SENDMAIL_ARGS "-t", "-oem", "-i" | 48 | #define SENDMAIL_ARGS "-ti", "oem" |
52 | #endif | 49 | #endif |
53 | #ifndef CRONUPDATE | 50 | #ifndef CRONUPDATE |
54 | #define CRONUPDATE "cron.update" | 51 | #define CRONUPDATE "cron.update" |
@@ -57,6 +54,7 @@ | |||
57 | #define MAXLINES 256 /* max lines in non-root crontabs */ | 54 | #define MAXLINES 256 /* max lines in non-root crontabs */ |
58 | #endif | 55 | #endif |
59 | 56 | ||
57 | static const char def_sh[] = "/bin/sh"; | ||
60 | 58 | ||
61 | 59 | ||
62 | typedef struct CronFile { | 60 | typedef struct CronFile { |
@@ -71,7 +69,7 @@ typedef struct CronFile { | |||
71 | typedef struct CronLine { | 69 | typedef struct CronLine { |
72 | struct CronLine *cl_Next; | 70 | struct CronLine *cl_Next; |
73 | char *cl_Shell; /* shell command */ | 71 | char *cl_Shell; /* shell command */ |
74 | int cl_Pid; /* running pid, 0, or armed (-1) */ | 72 | pid_t cl_Pid; /* running pid, 0, or armed (-1) */ |
75 | int cl_MailFlag; /* running pid is for mail */ | 73 | int cl_MailFlag; /* running pid is for mail */ |
76 | int cl_MailPos; /* 'empty file' size */ | 74 | int cl_MailPos; /* 'empty file' size */ |
77 | char cl_Mins[60]; /* 0-59 */ | 75 | char cl_Mins[60]; /* 0-59 */ |
@@ -92,13 +90,9 @@ static short DebugOpt; | |||
92 | #endif | 90 | #endif |
93 | 91 | ||
94 | static short LogLevel = 8; | 92 | static short LogLevel = 8; |
95 | static short ForegroundOpt; | 93 | static const char *LogFile; |
96 | static short LoggerOpt; | ||
97 | static const char *LogFile = LOG_FILE; | ||
98 | static const char *CDir = CRONTABS; | 94 | static const char *CDir = CRONTABS; |
99 | 95 | ||
100 | static void log(int level, const char *ctl, ...); | ||
101 | static void log9(const char *ctl, ...); | ||
102 | static void startlogger(void); | 96 | static void startlogger(void); |
103 | 97 | ||
104 | static void CheckUpdates(void); | 98 | static void CheckUpdates(void); |
@@ -106,14 +100,54 @@ static void SynchronizeDir(void); | |||
106 | static int TestJobs(time_t t1, time_t t2); | 100 | static int TestJobs(time_t t1, time_t t2); |
107 | static void RunJobs(void); | 101 | static void RunJobs(void); |
108 | static int CheckJobs(void); | 102 | static int CheckJobs(void); |
109 | static void RunJob(CronFile *file, CronLine *line); | 103 | |
110 | static void EndJob(const CronFile *file, CronLine *line); | 104 | static void RunJob(const char *user, CronLine *line); |
105 | #ifdef CONFIG_FEATURE_CROND_CALL_SENDMAIL | ||
106 | static void EndJob(const char *user, CronLine *line); | ||
107 | #else | ||
108 | #define EndJob(user, line) line->cl_Pid = 0 | ||
109 | #endif | ||
111 | 110 | ||
112 | static void DeleteFile(const char *userName); | 111 | static void DeleteFile(const char *userName); |
113 | 112 | ||
114 | static CronFile *FileBase; | 113 | static CronFile *FileBase; |
115 | 114 | ||
116 | 115 | ||
116 | static void | ||
117 | log(const char *ctl, ...) | ||
118 | { | ||
119 | va_list va; | ||
120 | int level = (int)(ctl[0] & 0xf); | ||
121 | int type = level == 20 ? | ||
122 | LOG_ERR : ((ctl[0] & 0100) ? LOG_WARNING : LOG_NOTICE); | ||
123 | |||
124 | |||
125 | va_start(va, ctl); | ||
126 | if (level >= LogLevel) { | ||
127 | |||
128 | #ifdef FEATURE_DEBUG_OPT | ||
129 | if (DebugOpt) vfprintf(stderr, ctl, va); | ||
130 | else | ||
131 | #endif | ||
132 | if (LogFile == 0) vsyslog(type, ctl, va); | ||
133 | else { | ||
134 | int logfd; | ||
135 | |||
136 | if ((logfd = open(LogFile, O_WRONLY|O_CREAT|O_APPEND, 600)) >= 0) { | ||
137 | vdprintf(logfd, ctl, va); | ||
138 | close(logfd); | ||
139 | #ifdef FEATURE_DEBUG_OPT | ||
140 | } else { | ||
141 | bb_perror_msg("Can't open log file"); | ||
142 | #endif | ||
143 | } | ||
144 | } | ||
145 | } | ||
146 | va_end(va); | ||
147 | if(ctl[0] & 0200) | ||
148 | exit(20); | ||
149 | } | ||
150 | |||
117 | int | 151 | int |
118 | crond_main(int ac, char **av) | 152 | crond_main(int ac, char **av) |
119 | { | 153 | { |
@@ -138,10 +172,8 @@ crond_main(int ac, char **av) | |||
138 | ); | 172 | ); |
139 | if(opt & 1) | 173 | if(opt & 1) |
140 | LogLevel = atoi(lopt); | 174 | LogLevel = atoi(lopt); |
141 | LoggerOpt = opt & 2; | 175 | if(opt & 2) |
142 | if(LoggerOpt) | ||
143 | if (*Lopt != 0) LogFile = Lopt; | 176 | if (*Lopt != 0) LogFile = Lopt; |
144 | ForegroundOpt = opt & 4; | ||
145 | if(opt & 32) { | 177 | if(opt & 32) { |
146 | if (*copt != 0) CDir = copt; | 178 | if (*copt != 0) CDir = copt; |
147 | } | 179 | } |
@@ -157,7 +189,7 @@ crond_main(int ac, char **av) | |||
157 | */ | 189 | */ |
158 | 190 | ||
159 | if (chdir(CDir) != 0) | 191 | if (chdir(CDir) != 0) |
160 | bb_perror_msg_and_die("chdir"); | 192 | bb_perror_msg_and_die("%s", CDir); |
161 | 193 | ||
162 | signal(SIGHUP,SIG_IGN); /* hmm.. but, if kill -HUP original | 194 | signal(SIGHUP,SIG_IGN); /* hmm.. but, if kill -HUP original |
163 | * version - his died. ;( | 195 | * version - his died. ;( |
@@ -168,9 +200,15 @@ crond_main(int ac, char **av) | |||
168 | * optional detach from controlling terminal | 200 | * optional detach from controlling terminal |
169 | */ | 201 | */ |
170 | 202 | ||
171 | if (ForegroundOpt == 0) { | 203 | if (!(opt & 4)) { |
172 | if(daemon(1, 0) < 0) | 204 | if(daemon(1, 0) < 0) { |
173 | bb_perror_msg_and_die("daemon"); | 205 | bb_perror_msg_and_die("daemon"); |
206 | #if defined(__uClinux__) | ||
207 | } else { | ||
208 | /* reexec for vfork() do continue parent */ | ||
209 | vfork_daemon_rexec(ac, av, "-f"); | ||
210 | } | ||
211 | #endif /* uClinux */ | ||
174 | } | 212 | } |
175 | 213 | ||
176 | (void)startlogger(); /* need if syslog mode selected */ | 214 | (void)startlogger(); /* need if syslog mode selected */ |
@@ -180,7 +218,8 @@ crond_main(int ac, char **av) | |||
180 | * of 1 second. | 218 | * of 1 second. |
181 | */ | 219 | */ |
182 | 220 | ||
183 | log(9,"%s " VERSION " dillon, started, log level %d\n", av[0], LogLevel); | 221 | log("\011%s " VERSION " dillon, started, log level %d\n", bb_applet_name, |
222 | LogLevel); | ||
184 | 223 | ||
185 | SynchronizeDir(); | 224 | SynchronizeDir(); |
186 | 225 | ||
@@ -221,11 +260,11 @@ crond_main(int ac, char **av) | |||
221 | CheckUpdates(); | 260 | CheckUpdates(); |
222 | #ifdef FEATURE_DEBUG_OPT | 261 | #ifdef FEATURE_DEBUG_OPT |
223 | if (DebugOpt) | 262 | if (DebugOpt) |
224 | log(5, "Wakeup dt=%d\n", dt); | 263 | log("\005Wakeup dt=%d\n", dt); |
225 | #endif | 264 | #endif |
226 | if (dt < -60*60 || dt > 60*60) { | 265 | if (dt < -60*60 || dt > 60*60) { |
227 | t1 = t2; | 266 | t1 = t2; |
228 | log9("time disparity of %d minutes detected\n", dt / 60); | 267 | log("\111time disparity of %d minutes detected\n", dt / 60); |
229 | } else if (dt > 0) { | 268 | } else if (dt > 0) { |
230 | TestJobs(t1, t2); | 269 | TestJobs(t1, t2); |
231 | RunJobs(); | 270 | RunJobs(); |
@@ -242,81 +281,10 @@ crond_main(int ac, char **av) | |||
242 | } | 281 | } |
243 | 282 | ||
244 | 283 | ||
245 | static void | 284 | #if defined(FEATURE_DEBUG_OPT) || defined(CONFIG_FEATURE_CROND_CALL_SENDMAIL) |
246 | vlog(int level, int MLOG_LEVEL, const char *ctl, va_list va) | ||
247 | { | ||
248 | char buf[1024]; | ||
249 | int logfd; | ||
250 | |||
251 | if (level >= LogLevel) { | ||
252 | |||
253 | vsnprintf(buf,sizeof(buf), ctl, va); | ||
254 | #ifdef FEATURE_DEBUG_OPT | ||
255 | if (DebugOpt) fprintf(stderr,"%s",buf); | ||
256 | else | ||
257 | #endif | ||
258 | if (LoggerOpt == 0) syslog(MLOG_LEVEL, "%s", buf); | ||
259 | else { | ||
260 | if ((logfd = open(LogFile,O_WRONLY|O_CREAT|O_APPEND,600)) >= 0){ | ||
261 | write(logfd, buf, strlen(buf)); | ||
262 | close(logfd); | ||
263 | } else | ||
264 | #ifdef FEATURE_DEBUG_OPT | ||
265 | bb_perror_msg("Can't open log file") | ||
266 | #endif | ||
267 | ; | ||
268 | } | ||
269 | } | ||
270 | } | ||
271 | |||
272 | /* | ||
273 | set log_level=9 and log messages | ||
274 | */ | ||
275 | |||
276 | static void | ||
277 | log9(const char *ctl, ...) | ||
278 | { | ||
279 | va_list va; | ||
280 | |||
281 | va_start(va, ctl); | ||
282 | vlog(9, LOG_WARNING, ctl, va); | ||
283 | va_end(va); | ||
284 | } | ||
285 | |||
286 | /* | ||
287 | normal logger call point. | ||
288 | */ | ||
289 | |||
290 | static void | ||
291 | log(int level, const char *ctl, ...) | ||
292 | { | ||
293 | va_list va; | ||
294 | |||
295 | va_start(va, ctl); | ||
296 | vlog(level, LOG_NOTICE, ctl, va); | ||
297 | va_end(va); | ||
298 | } | ||
299 | |||
300 | /* | 285 | /* |
301 | Original: void | 286 | write to temp file.. |
302 | logfd(int fd, const char *ctl, ...) | ||
303 | Updated to: log_error (used by jobs.c) | ||
304 | */ | 287 | */ |
305 | |||
306 | static void | ||
307 | log_err(const char *ctl, ...) | ||
308 | { | ||
309 | va_list va; | ||
310 | |||
311 | va_start(va, ctl); | ||
312 | vlog(20, LOG_ERR, ctl, va); | ||
313 | va_end(va); | ||
314 | } | ||
315 | |||
316 | /* | ||
317 | used by jobs.c (write to temp file..) | ||
318 | */ | ||
319 | |||
320 | static void | 288 | static void |
321 | fdprintf(int fd, const char *ctl, ...) | 289 | fdprintf(int fd, const char *ctl, ...) |
322 | { | 290 | { |
@@ -326,10 +294,11 @@ fdprintf(int fd, const char *ctl, ...) | |||
326 | vdprintf(fd, ctl, va); | 294 | vdprintf(fd, ctl, va); |
327 | va_end(va); | 295 | va_end(va); |
328 | } | 296 | } |
297 | #endif | ||
329 | 298 | ||
330 | 299 | ||
331 | static int | 300 | static int |
332 | ChangeUser(const char *user, short dochdir) | 301 | ChangeUser(const char *user) |
333 | { | 302 | { |
334 | struct passwd *pas; | 303 | struct passwd *pas; |
335 | 304 | ||
@@ -338,58 +307,55 @@ ChangeUser(const char *user, short dochdir) | |||
338 | */ | 307 | */ |
339 | 308 | ||
340 | if ((pas = getpwnam(user)) == 0) { | 309 | if ((pas = getpwnam(user)) == 0) { |
341 | log(9, "failed to get uid for %s", user); | 310 | log("\011failed to get uid for %s", user); |
342 | return(-1); | 311 | return(-1); |
343 | } | 312 | } |
344 | setenv("USER", pas->pw_name, 1); | 313 | setenv("USER", pas->pw_name, 1); |
345 | setenv("HOME", pas->pw_dir, 1); | 314 | setenv("HOME", pas->pw_dir, 1); |
346 | setenv("SHELL", "/bin/sh", 1); | 315 | setenv("SHELL", def_sh, 1); |
347 | 316 | ||
348 | /* | 317 | /* |
349 | * Change running state to the user in question | 318 | * Change running state to the user in question |
350 | */ | 319 | */ |
351 | 320 | ||
352 | if (initgroups(user, pas->pw_gid) < 0) { | 321 | if (initgroups(user, pas->pw_gid) < 0) { |
353 | log(9, "initgroups failed: %s %m", user); | 322 | log("\011initgroups failed: %s %m", user); |
354 | return(-1); | 323 | return(-1); |
355 | } | 324 | } |
356 | if (setregid(pas->pw_gid, pas->pw_gid) < 0) { | 325 | /* drop all priviledges */ |
357 | log(9, "setregid failed: %s %d", user, pas->pw_gid); | 326 | if (setgid(pas->pw_gid) < 0) { |
327 | log("\011setgid failed: %s %d", user, pas->pw_gid); | ||
358 | return(-1); | 328 | return(-1); |
359 | } | 329 | } |
360 | if (setreuid(pas->pw_uid, pas->pw_uid) < 0) { | 330 | if (setuid(pas->pw_uid) < 0) { |
361 | log(9, "setreuid failed: %s %d", user, pas->pw_uid); | 331 | log("\011setuid failed: %s %d", user, pas->pw_uid); |
362 | return(-1); | 332 | return(-1); |
363 | } | 333 | } |
364 | if (dochdir) { | ||
365 | if (chdir(pas->pw_dir) < 0) { | 334 | if (chdir(pas->pw_dir) < 0) { |
366 | log(8, "chdir failed: %s %s", user, pas->pw_dir); | 335 | log("\011chdir failed: %s: %m", pas->pw_dir); |
367 | if (chdir(TMPDIR) < 0) { | 336 | if (chdir(TMPDIR) < 0) { |
368 | log(9, "chdir failed: %s %s", TMPDIR, user); | 337 | log("\011chdir failed: %s: %m", TMPDIR); |
369 | return(-1); | 338 | return(-1); |
370 | } | 339 | } |
371 | } | 340 | } |
372 | } | ||
373 | return(pas->pw_uid); | 341 | return(pas->pw_uid); |
374 | } | 342 | } |
375 | 343 | ||
376 | static void | 344 | static void |
377 | startlogger(void) | 345 | startlogger(void) |
378 | { | 346 | { |
347 | if (LogFile == 0) | ||
348 | openlog(bb_applet_name, LOG_CONS|LOG_PID, LOG_CRON); | ||
349 | #ifdef FEATURE_DEBUG_OPT | ||
350 | else { /* test logfile */ | ||
379 | int logfd; | 351 | int logfd; |
380 | 352 | ||
381 | if (LoggerOpt == 0) | 353 | if ((logfd = open(LogFile, O_WRONLY|O_CREAT|O_APPEND, 600)) >= 0) |
382 | openlog(bb_applet_name, LOG_CONS|LOG_PID,LOG_CRON); | ||
383 | |||
384 | else { /* test logfile */ | ||
385 | if ((logfd = open(LogFile,O_WRONLY|O_CREAT|O_APPEND,600)) >= 0) | ||
386 | close(logfd); | 354 | close(logfd); |
387 | else | 355 | else |
388 | #ifdef FEATURE_DEBUG_OPT | 356 | bb_perror_msg("Failed to open log file '%s' reason", LogFile); |
389 | printf("Failed to open log file '%s' reason: %m", LogFile) | ||
390 | #endif | ||
391 | ; | ||
392 | } | 357 | } |
358 | #endif | ||
393 | } | 359 | } |
394 | 360 | ||
395 | 361 | ||
@@ -493,7 +459,7 @@ ParseField(char *user, char *ary, int modvalue, int off, | |||
493 | */ | 459 | */ |
494 | 460 | ||
495 | if (skip == 0) { | 461 | if (skip == 0) { |
496 | log9("failed user %s parsing %s\n", user, base); | 462 | log("\111failed user %s parsing %s\n", user, base); |
497 | return(NULL); | 463 | return(NULL); |
498 | } | 464 | } |
499 | if (*ptr == '-' && n2 < 0) { | 465 | if (*ptr == '-' && n2 < 0) { |
@@ -532,7 +498,7 @@ ParseField(char *user, char *ary, int modvalue, int off, | |||
532 | } while (n1 != n2 && --failsafe); | 498 | } while (n1 != n2 && --failsafe); |
533 | 499 | ||
534 | if (failsafe == 0) { | 500 | if (failsafe == 0) { |
535 | log9("failed user %s parsing %s\n", user, base); | 501 | log("\111failed user %s parsing %s\n", user, base); |
536 | return(NULL); | 502 | return(NULL); |
537 | } | 503 | } |
538 | } | 504 | } |
@@ -544,7 +510,7 @@ ParseField(char *user, char *ary, int modvalue, int off, | |||
544 | } | 510 | } |
545 | 511 | ||
546 | if (*ptr != ' ' && *ptr != '\t' && *ptr != '\n') { | 512 | if (*ptr != ' ' && *ptr != '\t' && *ptr != '\n') { |
547 | log9("failed user %s parsing %s\n", user, base); | 513 | log("\111failed user %s parsing %s\n", user, base); |
548 | return(NULL); | 514 | return(NULL); |
549 | } | 515 | } |
550 | 516 | ||
@@ -556,8 +522,8 @@ ParseField(char *user, char *ary, int modvalue, int off, | |||
556 | int i; | 522 | int i; |
557 | 523 | ||
558 | for (i = 0; i < modvalue; ++i) | 524 | for (i = 0; i < modvalue; ++i) |
559 | log(5, "%d", ary[i]); | 525 | log("\005%d", ary[i]); |
560 | log(5, "\n"); | 526 | log("\005\n"); |
561 | } | 527 | } |
562 | #endif | 528 | #endif |
563 | 529 | ||
@@ -636,7 +602,7 @@ SynchronizeFile(const char *fileName) | |||
636 | 602 | ||
637 | #ifdef FEATURE_DEBUG_OPT | 603 | #ifdef FEATURE_DEBUG_OPT |
638 | if (DebugOpt) | 604 | if (DebugOpt) |
639 | log9("User %s Entry %s\n", fileName, buf); | 605 | log("\111User %s Entry %s\n", fileName, buf); |
640 | #endif | 606 | #endif |
641 | 607 | ||
642 | /* | 608 | /* |
@@ -674,7 +640,7 @@ SynchronizeFile(const char *fileName) | |||
674 | 640 | ||
675 | #ifdef FEATURE_DEBUG_OPT | 641 | #ifdef FEATURE_DEBUG_OPT |
676 | if (DebugOpt) { | 642 | if (DebugOpt) { |
677 | log9(" Command %s\n", ptr); | 643 | log("\111 Command %s\n", ptr); |
678 | } | 644 | } |
679 | #endif | 645 | #endif |
680 | 646 | ||
@@ -686,7 +652,7 @@ SynchronizeFile(const char *fileName) | |||
686 | FileBase = file; | 652 | FileBase = file; |
687 | 653 | ||
688 | if (maxLines == 0 || maxEntries == 0) | 654 | if (maxLines == 0 || maxEntries == 0) |
689 | log9("Maximum number of lines reached for user %s\n", fileName); | 655 | log("\111Maximum number of lines reached for user %s\n", fileName); |
690 | } | 656 | } |
691 | fclose(fi); | 657 | fclose(fi); |
692 | } | 658 | } |
@@ -712,21 +678,17 @@ static void | |||
712 | SynchronizeDir(void) | 678 | SynchronizeDir(void) |
713 | { | 679 | { |
714 | /* | 680 | /* |
715 | * Attempt to delete the database. Note that we have to make a copy | 681 | * Attempt to delete the database. |
716 | * of the string | ||
717 | */ | 682 | */ |
718 | 683 | ||
719 | for (;;) { | 684 | for (;;) { |
720 | CronFile *file; | 685 | CronFile *file; |
721 | char *user; | ||
722 | 686 | ||
723 | for (file = FileBase; file && file->cf_Deleted; file = file->cf_Next) | 687 | for (file = FileBase; file && file->cf_Deleted; file = file->cf_Next) |
724 | ; | 688 | ; |
725 | if (file == NULL) | 689 | if (file == NULL) |
726 | break; | 690 | break; |
727 | user = strdup(file->cf_User); | 691 | DeleteFile(file->cf_User); |
728 | DeleteFile(user); | ||
729 | free(user); | ||
730 | } | 692 | } |
731 | 693 | ||
732 | /* | 694 | /* |
@@ -740,8 +702,7 @@ SynchronizeDir(void) | |||
740 | 702 | ||
741 | remove(CRONUPDATE); | 703 | remove(CRONUPDATE); |
742 | if (chdir(CDir) < 0) { | 704 | if (chdir(CDir) < 0) { |
743 | log9("unable to find %s\n", CDir); | 705 | log("\311unable to find %s\n", CDir); |
744 | exit(20); | ||
745 | } | 706 | } |
746 | { | 707 | { |
747 | DIR *dir; | 708 | DIR *dir; |
@@ -754,12 +715,11 @@ SynchronizeDir(void) | |||
754 | if (getpwnam(den->d_name)) | 715 | if (getpwnam(den->d_name)) |
755 | SynchronizeFile(den->d_name); | 716 | SynchronizeFile(den->d_name); |
756 | else | 717 | else |
757 | log(7, "ignoring %s\n", den->d_name); | 718 | log("\007ignoring %s\n", den->d_name); |
758 | } | 719 | } |
759 | closedir(dir); | 720 | closedir(dir); |
760 | } else { | 721 | } else { |
761 | log9("Unable to open current dir!\n"); | 722 | log("\311Unable to open current dir!\n"); |
762 | exit(20); | ||
763 | } | 723 | } |
764 | } | 724 | } |
765 | } | 725 | } |
@@ -836,14 +796,14 @@ TestJobs(time_t t1, time_t t2) | |||
836 | for (file = FileBase; file; file = file->cf_Next) { | 796 | for (file = FileBase; file; file = file->cf_Next) { |
837 | #ifdef FEATURE_DEBUG_OPT | 797 | #ifdef FEATURE_DEBUG_OPT |
838 | if (DebugOpt) | 798 | if (DebugOpt) |
839 | log(5, "FILE %s:\n", file->cf_User); | 799 | log("\005FILE %s:\n", file->cf_User); |
840 | #endif | 800 | #endif |
841 | if (file->cf_Deleted) | 801 | if (file->cf_Deleted) |
842 | continue; | 802 | continue; |
843 | for (line = file->cf_LineBase; line; line = line->cl_Next) { | 803 | for (line = file->cf_LineBase; line; line = line->cl_Next) { |
844 | #ifdef FEATURE_DEBUG_OPT | 804 | #ifdef FEATURE_DEBUG_OPT |
845 | if (DebugOpt) | 805 | if (DebugOpt) |
846 | log(5, " LINE %s\n", line->cl_Shell); | 806 | log("\005 LINE %s\n", line->cl_Shell); |
847 | #endif | 807 | #endif |
848 | if (line->cl_Mins[tp->tm_min] && | 808 | if (line->cl_Mins[tp->tm_min] && |
849 | line->cl_Hrs[tp->tm_hour] && | 809 | line->cl_Hrs[tp->tm_hour] && |
@@ -852,10 +812,10 @@ TestJobs(time_t t1, time_t t2) | |||
852 | ) { | 812 | ) { |
853 | #ifdef FEATURE_DEBUG_OPT | 813 | #ifdef FEATURE_DEBUG_OPT |
854 | if (DebugOpt) | 814 | if (DebugOpt) |
855 | log(5, " JobToDo: %d %s\n", line->cl_Pid, line->cl_Shell); | 815 | log("\005 JobToDo: %d %s\n", line->cl_Pid, line->cl_Shell); |
856 | #endif | 816 | #endif |
857 | if (line->cl_Pid > 0) { | 817 | if (line->cl_Pid > 0) { |
858 | log(8, " process already running: %s %s\n", | 818 | log("\010 process already running: %s %s\n", |
859 | file->cf_User, | 819 | file->cf_User, |
860 | line->cl_Shell | 820 | line->cl_Shell |
861 | ); | 821 | ); |
@@ -885,9 +845,9 @@ RunJobs(void) | |||
885 | for (line = file->cf_LineBase; line; line = line->cl_Next) { | 845 | for (line = file->cf_LineBase; line; line = line->cl_Next) { |
886 | if (line->cl_Pid < 0) { | 846 | if (line->cl_Pid < 0) { |
887 | 847 | ||
888 | RunJob(file, line); | 848 | RunJob(file->cf_User, line); |
889 | 849 | ||
890 | log(8, "USER %s pid %3d cmd %s\n", | 850 | log("\010USER %s pid %3d cmd %s\n", |
891 | file->cf_User, | 851 | file->cf_User, |
892 | line->cl_Pid, | 852 | line->cl_Pid, |
893 | line->cl_Shell | 853 | line->cl_Shell |
@@ -926,7 +886,7 @@ CheckJobs(void) | |||
926 | int r = wait4(line->cl_Pid, &status, WNOHANG, NULL); | 886 | int r = wait4(line->cl_Pid, &status, WNOHANG, NULL); |
927 | 887 | ||
928 | if (r < 0 || r == line->cl_Pid) { | 888 | if (r < 0 || r == line->cl_Pid) { |
929 | EndJob(file, line); | 889 | EndJob(file->cf_User, line); |
930 | if (line->cl_Pid) | 890 | if (line->cl_Pid) |
931 | file->cf_Running = 1; | 891 | file->cf_Running = 1; |
932 | } else if (r == 0) { | 892 | } else if (r == 0) { |
@@ -941,83 +901,54 @@ CheckJobs(void) | |||
941 | } | 901 | } |
942 | 902 | ||
943 | 903 | ||
944 | 904 | #ifdef CONFIG_FEATURE_CROND_CALL_SENDMAIL | |
945 | static void | 905 | static void |
946 | RunJob(CronFile *file, CronLine *line) | 906 | ForkJob(const char *user, CronLine *line, int mailFd, |
907 | const char *prog, const char *cmd, const char *arg, const char *mailf) | ||
947 | { | 908 | { |
948 | char mailFile[128]; | ||
949 | int mailFd; | ||
950 | |||
951 | line->cl_Pid = 0; | ||
952 | line->cl_MailFlag = 0; | ||
953 | |||
954 | /* | ||
955 | * open mail file - owner root so nobody can screw with it. | ||
956 | */ | ||
957 | |||
958 | snprintf(mailFile, sizeof(mailFile), TMPDIR "/cron.%s.%d", | ||
959 | file->cf_User, getpid()); | ||
960 | mailFd = open(mailFile, O_CREAT|O_TRUNC|O_WRONLY|O_EXCL|O_APPEND, 0600); | ||
961 | |||
962 | if (mailFd >= 0) { | ||
963 | line->cl_MailFlag = 1; | ||
964 | fdprintf(mailFd, "To: %s\nSubject: cron: %s\n\n", | ||
965 | file->cf_User, | ||
966 | line->cl_Shell | ||
967 | ); | ||
968 | line->cl_MailPos = lseek(mailFd, 0, 1); | ||
969 | } | ||
970 | |||
971 | /* | 909 | /* |
972 | * Fork as the user in question and run program | 910 | * Fork as the user in question and run program |
973 | */ | 911 | */ |
912 | pid_t pid = fork(); | ||
974 | 913 | ||
975 | if ((line->cl_Pid = fork()) == 0) { | 914 | line->cl_Pid = pid; |
915 | if (pid == 0) { | ||
976 | /* | 916 | /* |
977 | * CHILD, FORK OK | 917 | * CHILD |
978 | */ | 918 | */ |
979 | 919 | ||
980 | /* | 920 | /* |
981 | * Change running state to the user in question | 921 | * Change running state to the user in question |
982 | */ | 922 | */ |
983 | 923 | ||
984 | if (ChangeUser(file->cf_User, 1) < 0) | 924 | if (ChangeUser(user) < 0) |
985 | return; | 925 | exit(0); |
986 | 926 | ||
987 | #ifdef FEATURE_DEBUG_OPT | 927 | #ifdef FEATURE_DEBUG_OPT |
988 | if (DebugOpt) | 928 | if (DebugOpt) |
989 | log(5, "Child Running %s\n", line->cl_Shell); | 929 | log("\005Child Running %s\n", prog); |
990 | #endif | 930 | #endif |
991 | 931 | ||
992 | /* | ||
993 | * stdin is already /dev/null, setup stdout and stderr | ||
994 | */ | ||
995 | |||
996 | if (mailFd >= 0) { | 932 | if (mailFd >= 0) { |
997 | dup2(mailFd, 1); | 933 | dup2(mailFd, mailf != NULL); |
998 | dup2(mailFd, 2); | 934 | dup2((mailf ? mailFd : 1), 2); |
999 | close(mailFd); | 935 | close(mailFd); |
1000 | } else { | ||
1001 | log_err("unable to create mail file user %s file %s, output to /dev/null\n", | ||
1002 | file->cf_User, | ||
1003 | mailFile | ||
1004 | ); | ||
1005 | } | 936 | } |
1006 | execl("/bin/sh", "/bin/sh", "-c", line->cl_Shell, NULL, NULL); | 937 | execl(prog, prog, cmd, arg, NULL); |
1007 | log_err("unable to exec, user %s cmd /bin/sh -c %s\n", | 938 | log("\024unable to exec, user %s cmd %s %s %s\n", user, |
1008 | file->cf_User, | 939 | prog, cmd, arg); |
1009 | line->cl_Shell | 940 | if(mailf) |
1010 | ); | 941 | fdprintf(1, "Exec failed: %s -c %s\n", prog, arg); |
1011 | fdprintf(1, "Exec failed: /bin/sh -c %s\n", line->cl_Shell); | ||
1012 | exit(0); | 942 | exit(0); |
1013 | } else if (line->cl_Pid < 0) { | 943 | } else if (pid < 0) { |
1014 | /* | 944 | /* |
1015 | * PARENT, FORK FAILED | 945 | * FORK FAILED |
1016 | */ | 946 | */ |
1017 | log_err("couldn't fork, user %s\n", file->cf_User); | 947 | log("\024couldn't fork, user %s\n", user); |
1018 | line->cl_Pid = 0; | 948 | line->cl_Pid = 0; |
1019 | remove(mailFile); | 949 | if(mailf) |
1020 | } else { | 950 | remove(mailf); |
951 | } else if(mailf) { | ||
1021 | /* | 952 | /* |
1022 | * PARENT, FORK SUCCESS | 953 | * PARENT, FORK SUCCESS |
1023 | * | 954 | * |
@@ -1026,10 +957,9 @@ RunJob(CronFile *file, CronLine *line) | |||
1026 | char mailFile2[128]; | 957 | char mailFile2[128]; |
1027 | 958 | ||
1028 | snprintf(mailFile2, sizeof(mailFile2), TMPDIR "/cron.%s.%d", | 959 | snprintf(mailFile2, sizeof(mailFile2), TMPDIR "/cron.%s.%d", |
1029 | file->cf_User, line->cl_Pid); | 960 | user, pid); |
1030 | rename(mailFile, mailFile2); | 961 | rename(mailf, mailFile2); |
1031 | } | 962 | } |
1032 | |||
1033 | /* | 963 | /* |
1034 | * Close the mail file descriptor.. we can't just leave it open in | 964 | * Close the mail file descriptor.. we can't just leave it open in |
1035 | * a structure, closing it later, because we might run out of descriptors | 965 | * a structure, closing it later, because we might run out of descriptors |
@@ -1039,12 +969,42 @@ RunJob(CronFile *file, CronLine *line) | |||
1039 | close(mailFd); | 969 | close(mailFd); |
1040 | } | 970 | } |
1041 | 971 | ||
972 | static void | ||
973 | RunJob(const char *user, CronLine *line) | ||
974 | { | ||
975 | char mailFile[128]; | ||
976 | int mailFd; | ||
977 | |||
978 | line->cl_Pid = 0; | ||
979 | line->cl_MailFlag = 0; | ||
980 | |||
981 | /* | ||
982 | * open mail file - owner root so nobody can screw with it. | ||
983 | */ | ||
984 | |||
985 | snprintf(mailFile, sizeof(mailFile), TMPDIR "/cron.%s.%d", | ||
986 | user, getpid()); | ||
987 | mailFd = open(mailFile, O_CREAT|O_TRUNC|O_WRONLY|O_EXCL|O_APPEND, 0600); | ||
988 | |||
989 | if (mailFd >= 0) { | ||
990 | line->cl_MailFlag = 1; | ||
991 | fdprintf(mailFd, "To: %s\nSubject: cron: %s\n\n", user, | ||
992 | line->cl_Shell); | ||
993 | line->cl_MailPos = lseek(mailFd, 0, 1); | ||
994 | } else { | ||
995 | log("\024unable to create mail file user %s file %s, output to /dev/null\n", | ||
996 | user, mailFile); | ||
997 | } | ||
998 | |||
999 | ForkJob(user, line, mailFd, def_sh, "-c", line->cl_Shell, mailFile); | ||
1000 | } | ||
1001 | |||
1042 | /* | 1002 | /* |
1043 | * EndJob - called when job terminates and when mail terminates | 1003 | * EndJob - called when job terminates and when mail terminates |
1044 | */ | 1004 | */ |
1045 | 1005 | ||
1046 | static void | 1006 | static void |
1047 | EndJob(const CronFile *file, CronLine *line) | 1007 | EndJob(const char *user, CronLine *line) |
1048 | { | 1008 | { |
1049 | int mailFd; | 1009 | int mailFd; |
1050 | char mailFile[128]; | 1010 | char mailFile[128]; |
@@ -1065,7 +1025,7 @@ EndJob(const CronFile *file, CronLine *line) | |||
1065 | */ | 1025 | */ |
1066 | 1026 | ||
1067 | snprintf(mailFile, sizeof(mailFile), TMPDIR "/cron.%s.%d", | 1027 | snprintf(mailFile, sizeof(mailFile), TMPDIR "/cron.%s.%d", |
1068 | file->cf_User, line->cl_Pid); | 1028 | user, line->cl_Pid); |
1069 | line->cl_Pid = 0; | 1029 | line->cl_Pid = 0; |
1070 | 1030 | ||
1071 | if (line->cl_MailFlag != 1) | 1031 | if (line->cl_MailFlag != 1) |
@@ -1093,46 +1053,47 @@ EndJob(const CronFile *file, CronLine *line) | |||
1093 | close(mailFd); | 1053 | close(mailFd); |
1094 | return; | 1054 | return; |
1095 | } | 1055 | } |
1056 | ForkJob(user, line, mailFd, SENDMAIL, SENDMAIL_ARGS, NULL); | ||
1057 | } | ||
1058 | #else | ||
1059 | /* crond whithout sendmail */ | ||
1096 | 1060 | ||
1097 | if ((line->cl_Pid = fork()) == 0) { | 1061 | static void |
1062 | RunJob(const char *user, CronLine *line) | ||
1063 | { | ||
1098 | /* | 1064 | /* |
1099 | * CHILD, FORK OK | 1065 | * Fork as the user in question and run program |
1100 | */ | 1066 | */ |
1067 | pid_t pid = fork(); | ||
1101 | 1068 | ||
1069 | if (pid == 0) { | ||
1102 | /* | 1070 | /* |
1103 | * change user id - no way in hell security can be compromised | 1071 | * CHILD |
1104 | * by the mailing and we already verified the mail file. | ||
1105 | */ | 1072 | */ |
1106 | 1073 | ||
1107 | if (ChangeUser(file->cf_User, 1) < 0) | ||
1108 | exit(0); | ||
1109 | |||
1110 | /* | 1074 | /* |
1111 | * run sendmail with mail file as standard input, only if | 1075 | * Change running state to the user in question |
1112 | * mail file exists! | ||
1113 | */ | 1076 | */ |
1114 | 1077 | ||
1115 | dup2(mailFd, 0); | 1078 | if (ChangeUser(user) < 0) |
1116 | dup2(1, 2); | 1079 | exit(0); |
1117 | close(mailFd); | 1080 | |
1081 | #ifdef FEATURE_DEBUG_OPT | ||
1082 | if (DebugOpt) | ||
1083 | log("\005Child Running %s\n", def_sh); | ||
1084 | #endif | ||
1118 | 1085 | ||
1119 | execl(SENDMAIL, SENDMAIL, SENDMAIL_ARGS, NULL, NULL); | 1086 | execl(def_sh, def_sh, "-c", line->cl_Shell, NULL); |
1120 | log_err("unable to exec %s %s, user %s, output to sink null", | 1087 | log("\024unable to exec, user %s cmd %s -c %s\n", user, |
1121 | SENDMAIL, | 1088 | def_sh, line->cl_Shell); |
1122 | SENDMAIL_ARGS, | ||
1123 | file->cf_User | ||
1124 | ); | ||
1125 | exit(0); | 1089 | exit(0); |
1126 | } else if (line->cl_Pid < 0) { | 1090 | } else if (pid < 0) { |
1127 | /* | ||
1128 | * PARENT, FORK FAILED | ||
1129 | */ | ||
1130 | log_err("unable to fork, user %s", file->cf_User); | ||
1131 | line->cl_Pid = 0; | ||
1132 | } else { | ||
1133 | /* | 1091 | /* |
1134 | * PARENT, FORK OK | 1092 | * FORK FAILED |
1135 | */ | 1093 | */ |
1094 | log("\024couldn't fork, user %s\n", user); | ||
1095 | pid = 0; | ||
1136 | } | 1096 | } |
1137 | close(mailFd); | 1097 | line->cl_Pid = pid; |
1138 | } | 1098 | } |
1099 | #endif /* CONFIG_FEATURE_CROND_CALL_SENDMAIL */ | ||