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 | |
| 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')
| -rw-r--r-- | miscutils/Config.in | 7 | ||||
| -rw-r--r-- | miscutils/crond.c | 411 |
2 files changed, 193 insertions, 225 deletions
diff --git a/miscutils/Config.in b/miscutils/Config.in index b4a3475de..0c56f0ee9 100644 --- a/miscutils/Config.in +++ b/miscutils/Config.in | |||
| @@ -19,6 +19,13 @@ config CONFIG_CROND | |||
| 19 | Crond is a background daemon that parses individual crontab | 19 | Crond is a background daemon that parses individual crontab |
| 20 | files and executes commands on behalf of the users in question. | 20 | files and executes commands on behalf of the users in question. |
| 21 | 21 | ||
| 22 | config CONFIG_FEATURE_CROND_CALL_SENDMAIL | ||
| 23 | bool " Using /usr/sbin/sendmail?" | ||
| 24 | default n | ||
| 25 | depends on CONFIG_CROND | ||
| 26 | help | ||
| 27 | Support call /usr/sbin/sendmail for send cmd outputs. | ||
| 28 | |||
| 22 | config CONFIG_CRONTAB | 29 | config CONFIG_CRONTAB |
| 23 | bool "crontab" | 30 | bool "crontab" |
| 24 | default n | 31 | default n |
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 */ | ||
