last_patch95 from vodz:
authorEric Andersen <andersen@codepoet.org>
Mon, 28 Jul 2003 07:40:39 +0000 (07:40 -0000)
committerEric Andersen <andersen@codepoet.org>
Mon, 28 Jul 2003 07:40:39 +0000 (07:40 -0000)
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

include/libbb.h
libbb/Makefile.in
libbb/vfork_daemon_rexec.c [new file with mode: 0644]
miscutils/Config.in
miscutils/crond.c
networking/Config.in
networking/Makefile.in
networking/httpd.c
networking/inetd.c
sysklogd/klogd.c
sysklogd/syslogd.c

index a4d8c719688566a2ae9e4c1cdba226796ce870ee..6b75b8a894161d0f49177b09e2538c86492912a1 100644 (file)
@@ -453,4 +453,6 @@ extern llist_t *llist_add_to(llist_t *old_head, char *new_item);
 void print_login_issue(const char *issue_file, const char *tty);
 void print_login_prompt(void);
 
+void vfork_daemon_rexec(int argc, char **argv, char *foreground_opt);
+
 #endif /* __LIBCONFIG_H__ */
index c4886e3ff84eb34d118b5d83d7d276c9b2dc1d09..b60adc959109cee90b306e6f3b8a3fb70164ea30 100644 (file)
@@ -48,7 +48,7 @@ LIBBB_SRC:= \
        fclose_nonstdin.c fflush_stdout_and_exit.c getopt_ulflags.c \
        default_error_retval.c wfopen_input.c speed_table.c \
        perror_nomsg_and_die.c perror_nomsg.c skip_whitespace.c \
-       warn_ignoring_args.c concat_subpath_file.c
+       warn_ignoring_args.c concat_subpath_file.c vfork_daemon_rexec.c
 
 LIBBB_OBJS=$(patsubst %.c,$(LIBBB_DIR)%.o, $(LIBBB_SRC))
 
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c
new file mode 100644 (file)
index 0000000..c8f9d27
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Rexec program for system have fork() as vfork() with foregound option
+ * Copyright (C) Vladminr Oleynik and many different people.
+ */
+
+#include <unistd.h>
+#include "libbb.h"
+
+
+#if defined(__uClinux__)
+void vfork_daemon_rexec(int argc, char **argv, char *foreground_opt)
+{
+       char **vfork_args;
+       int a = 0;
+
+       vfork_args = xcalloc(sizeof(char *), argc + 3);
+       while(*argv) {
+           vfork_args[a++] = *argv;
+           argv++;
+       }
+       vfork_args[a] = foreground_opt;
+       execvp("/proc/self/exe", vfork_args);
+       vfork_args[0] = "/bin/busybox";
+       execv(vfork_args[0], vfork_args);
+       bb_perror_msg_and_die("execv %s", vfork_args[0]);
+}
+#endif /* uClinux */
index b4a3475de78bbf571b331b417b0105ba0a4a6bb6..0c56f0ee97cac3bb7072f39785b6ce3135daea0e 100644 (file)
@@ -19,6 +19,13 @@ config CONFIG_CROND
          Crond is a background daemon that parses individual crontab
          files and executes commands on behalf of the users in question.
 
+config CONFIG_FEATURE_CROND_CALL_SENDMAIL
+       bool "  Using /usr/sbin/sendmail?"
+       default n
+       depends on CONFIG_CROND
+       help
+         Support call /usr/sbin/sendmail for send cmd outputs.
+
 config CONFIG_CRONTAB
        bool "crontab"
        default n
index 9d9ecc2903c19a7ddbc8bcb8cbaec5401a24129d..198bc2d85f3ace3f72a439e116bb934bf4b27364 100644 (file)
 #ifndef TMPDIR
 #define TMPDIR          "/var/spool/cron"
 #endif
-#ifndef LOG_FILE
-#define LOG_FILE        "/var/log/cron"
-#endif
 #ifndef SENDMAIL
 #define SENDMAIL        "/usr/sbin/sendmail"
 #endif
 #ifndef SENDMAIL_ARGS
-#define SENDMAIL_ARGS   "-t", "-oem", "-i"
+#define SENDMAIL_ARGS   "-ti", "oem"
 #endif
 #ifndef CRONUPDATE
 #define CRONUPDATE      "cron.update"
@@ -57,6 +54,7 @@
 #define MAXLINES        256             /* max lines in non-root crontabs */
 #endif
 
+static const char def_sh[] = "/bin/sh";
 
 
 typedef struct CronFile {
@@ -71,7 +69,7 @@ typedef struct CronFile {
 typedef struct CronLine {
     struct CronLine *cl_Next;
     char        *cl_Shell;      /* shell command                        */
-    int         cl_Pid;         /* running pid, 0, or armed (-1)        */
+    pid_t       cl_Pid;         /* running pid, 0, or armed (-1)        */
     int         cl_MailFlag;    /* running pid is for mail              */
     int         cl_MailPos;     /* 'empty file' size                    */
     char        cl_Mins[60];    /* 0-59                                 */
@@ -92,13 +90,9 @@ static short DebugOpt;
 #endif
 
 static short LogLevel = 8;
-static short ForegroundOpt;
-static short LoggerOpt;
-static const char  *LogFile = LOG_FILE;
+static const char  *LogFile;
 static const char  *CDir = CRONTABS;
 
-static void log(int level, const char *ctl, ...);
-static void log9(const char *ctl, ...);
 static void startlogger(void);
 
 static void CheckUpdates(void);
@@ -106,14 +100,54 @@ static void SynchronizeDir(void);
 static int TestJobs(time_t t1, time_t t2);
 static void RunJobs(void);
 static int CheckJobs(void);
-static void RunJob(CronFile *file, CronLine *line);
-static void EndJob(const CronFile *file, CronLine *line);
+
+static void RunJob(const char *user, CronLine *line);
+#ifdef CONFIG_FEATURE_CROND_CALL_SENDMAIL
+static void EndJob(const char *user, CronLine *line);
+#else
+#define EndJob(user, line)  line->cl_Pid = 0
+#endif
 
 static void DeleteFile(const char *userName);
 
 static CronFile *FileBase;
 
 
+static void
+log(const char *ctl, ...)
+{
+    va_list va;
+    int level = (int)(ctl[0] & 0xf);
+    int type = level == 20 ?
+                   LOG_ERR : ((ctl[0] & 0100) ? LOG_WARNING : LOG_NOTICE);
+
+
+    va_start(va, ctl);
+    if (level >= LogLevel) {
+
+#ifdef FEATURE_DEBUG_OPT
+       if (DebugOpt) vfprintf(stderr, ctl, va);
+       else
+#endif
+           if (LogFile == 0) vsyslog(type, ctl, va);
+           else {
+                int  logfd;
+
+                if ((logfd = open(LogFile, O_WRONLY|O_CREAT|O_APPEND, 600)) >= 0) {
+                   vdprintf(logfd, ctl, va);
+                   close(logfd);
+#ifdef FEATURE_DEBUG_OPT
+                } else {
+                   bb_perror_msg("Can't open log file");
+#endif
+               }
+           }
+    }
+    va_end(va);
+    if(ctl[0] & 0200)
+       exit(20);
+}
+
 int
 crond_main(int ac, char **av)
 {
@@ -138,10 +172,8 @@ crond_main(int ac, char **av)
            );
     if(opt & 1)
        LogLevel = atoi(lopt);
-    LoggerOpt = opt & 2;
-    if(LoggerOpt)
+    if(opt & 2)
        if (*Lopt != 0) LogFile = Lopt;
-    ForegroundOpt = opt & 4;
     if(opt & 32) {
        if (*copt != 0) CDir = copt;
        }
@@ -157,7 +189,7 @@ crond_main(int ac, char **av)
      */
 
     if (chdir(CDir) != 0)
-       bb_perror_msg_and_die("chdir");
+       bb_perror_msg_and_die("%s", CDir);
 
     signal(SIGHUP,SIG_IGN);   /* hmm.. but, if kill -HUP original
                                 * version - his died. ;(
@@ -168,9 +200,15 @@ crond_main(int ac, char **av)
      * optional detach from controlling terminal
      */
 
-    if (ForegroundOpt == 0) {
-       if(daemon(1, 0) < 0)
+    if (!(opt & 4)) {
+       if(daemon(1, 0) < 0) {
                bb_perror_msg_and_die("daemon");
+#if defined(__uClinux__)
+       } else {
+           /* reexec for vfork() do continue parent */
+           vfork_daemon_rexec(ac, av, "-f");
+       }
+#endif /* uClinux */
     }
 
     (void)startlogger();                /* need if syslog mode selected */
@@ -180,7 +218,8 @@ crond_main(int ac, char **av)
      *             of 1 second.
      */
 
-    log(9,"%s " VERSION " dillon, started, log level %d\n", av[0], LogLevel);
+    log("\011%s " VERSION " dillon, started, log level %d\n", bb_applet_name,
+                                               LogLevel);
 
     SynchronizeDir();
 
@@ -221,11 +260,11 @@ crond_main(int ac, char **av)
            CheckUpdates();
 #ifdef FEATURE_DEBUG_OPT
            if (DebugOpt)
-               log(5, "Wakeup dt=%d\n", dt);
+               log("\005Wakeup dt=%d\n", dt);
 #endif
            if (dt < -60*60 || dt > 60*60) {
                t1 = t2;
-               log9("time disparity of %d minutes detected\n", dt / 60);
+               log("\111time disparity of %d minutes detected\n", dt / 60);
            } else if (dt > 0) {
                TestJobs(t1, t2);
                RunJobs();
@@ -242,81 +281,10 @@ crond_main(int ac, char **av)
 }
 
 
-static void
-vlog(int level, int MLOG_LEVEL, const char *ctl, va_list va)
-{
-    char buf[1024];
-    int  logfd;
-
-    if (level >= LogLevel) {
-
-       vsnprintf(buf,sizeof(buf), ctl, va);
-#ifdef FEATURE_DEBUG_OPT
-       if (DebugOpt) fprintf(stderr,"%s",buf);
-       else
-#endif
-           if (LoggerOpt == 0) syslog(MLOG_LEVEL, "%s", buf);
-           else {
-                if ((logfd = open(LogFile,O_WRONLY|O_CREAT|O_APPEND,600)) >= 0){
-                   write(logfd, buf, strlen(buf));
-                   close(logfd);
-                } else
-#ifdef FEATURE_DEBUG_OPT
-                   bb_perror_msg("Can't open log file")
-#endif
-                                                       ;
-           }
-    }
-}
-
-/*
-       set log_level=9 and log messages
-*/
-
-static void
-log9(const char *ctl, ...)
-{
-    va_list va;
-
-    va_start(va, ctl);
-    vlog(9, LOG_WARNING, ctl, va);
-    va_end(va);
-}
-
-/*
-       normal logger call point.
-*/
-
-static void
-log(int level, const char *ctl, ...)
-{
-    va_list va;
-
-    va_start(va, ctl);
-    vlog(level, LOG_NOTICE, ctl, va);
-    va_end(va);
-}
-
+#if defined(FEATURE_DEBUG_OPT) || defined(CONFIG_FEATURE_CROND_CALL_SENDMAIL)
 /*
-       Original: void
-                 logfd(int fd, const char *ctl, ...)
-       Updated to: log_error (used by jobs.c)
+    write to temp file..
 */
-
-static void
-log_err(const char *ctl, ...)
-{
-    va_list va;
-
-    va_start(va, ctl);
-    vlog(20, LOG_ERR, ctl, va);
-    va_end(va);
-}
-
-/*
-       used by jobs.c (write to temp file..)
-*/
-
 static void
 fdprintf(int fd, const char *ctl, ...)
 {
@@ -326,10 +294,11 @@ fdprintf(int fd, const char *ctl, ...)
     vdprintf(fd, ctl, va);
     va_end(va);
 }
+#endif
 
 
 static int
-ChangeUser(const char *user, short dochdir)
+ChangeUser(const char *user)
 {
     struct passwd *pas;
 
@@ -338,58 +307,55 @@ ChangeUser(const char *user, short dochdir)
      */
 
     if ((pas = getpwnam(user)) == 0) {
-       log(9, "failed to get uid for %s", user);
+       log("\011failed to get uid for %s", user);
        return(-1);
     }
     setenv("USER", pas->pw_name, 1);
     setenv("HOME", pas->pw_dir, 1);
-    setenv("SHELL", "/bin/sh", 1);
+    setenv("SHELL", def_sh, 1);
 
     /*
      * Change running state to the user in question
      */
 
     if (initgroups(user, pas->pw_gid) < 0) {
-       log(9, "initgroups failed: %s %m", user);
+       log("\011initgroups failed: %s %m", user);
        return(-1);
     }
-    if (setregid(pas->pw_gid, pas->pw_gid) < 0) {
-       log(9, "setregid failed: %s %d", user, pas->pw_gid);
+    /* drop all priviledges */
+    if (setgid(pas->pw_gid) < 0) {
+       log("\011setgid failed: %s %d", user, pas->pw_gid);
        return(-1);
     }
-    if (setreuid(pas->pw_uid, pas->pw_uid) < 0) {
-       log(9, "setreuid failed: %s %d", user, pas->pw_uid);
+    if (setuid(pas->pw_uid) < 0) {
+       log("\011setuid failed: %s %d", user, pas->pw_uid);
        return(-1);
     }
-    if (dochdir) {
        if (chdir(pas->pw_dir) < 0) {
-           log(8, "chdir failed: %s %s", user, pas->pw_dir);
+       log("\011chdir failed: %s: %m", pas->pw_dir);
            if (chdir(TMPDIR) < 0) {
-               log(9, "chdir failed: %s %s", TMPDIR, user);
+           log("\011chdir failed: %s: %m", TMPDIR);
                return(-1);
            }
        }
-    }
     return(pas->pw_uid);
 }
 
 static void
 startlogger(void)
 {
+    if (LogFile == 0)
+       openlog(bb_applet_name, LOG_CONS|LOG_PID, LOG_CRON);
+#ifdef FEATURE_DEBUG_OPT
+    else { /* test logfile */
     int  logfd;
 
-    if (LoggerOpt == 0)
-       openlog(bb_applet_name, LOG_CONS|LOG_PID,LOG_CRON);
-
-    else { /* test logfile */
-       if ((logfd = open(LogFile,O_WRONLY|O_CREAT|O_APPEND,600)) >= 0)
+       if ((logfd = open(LogFile, O_WRONLY|O_CREAT|O_APPEND, 600)) >= 0)
           close(logfd);
        else
-#ifdef FEATURE_DEBUG_OPT
-          printf("Failed to open log file '%s' reason: %m", LogFile)
-#endif
-                                                                       ;
+          bb_perror_msg("Failed to open log file '%s' reason", LogFile);
     }
+#endif
 }
 
 
@@ -493,7 +459,7 @@ ParseField(char *user, char *ary, int modvalue, int off,
         */
 
        if (skip == 0) {
-           log9("failed user %s parsing %s\n", user, base);
+           log("\111failed user %s parsing %s\n", user, base);
            return(NULL);
        }
        if (*ptr == '-' && n2 < 0) {
@@ -532,7 +498,7 @@ ParseField(char *user, char *ary, int modvalue, int off,
            } while (n1 != n2 && --failsafe);
 
            if (failsafe == 0) {
-               log9("failed user %s parsing %s\n", user, base);
+               log("\111failed user %s parsing %s\n", user, base);
                return(NULL);
            }
        }
@@ -544,7 +510,7 @@ ParseField(char *user, char *ary, int modvalue, int off,
     }
 
     if (*ptr != ' ' && *ptr != '\t' && *ptr != '\n') {
-       log9("failed user %s parsing %s\n", user, base);
+       log("\111failed user %s parsing %s\n", user, base);
        return(NULL);
     }
 
@@ -556,8 +522,8 @@ ParseField(char *user, char *ary, int modvalue, int off,
        int i;
 
        for (i = 0; i < modvalue; ++i)
-           log(5, "%d", ary[i]);
-       log(5, "\n");
+           log("\005%d", ary[i]);
+       log("\005\n");
     }
 #endif
 
@@ -636,7 +602,7 @@ SynchronizeFile(const char *fileName)
 
 #ifdef FEATURE_DEBUG_OPT
                    if (DebugOpt)
-                       log9("User %s Entry %s\n", fileName, buf);
+                       log("\111User %s Entry %s\n", fileName, buf);
 #endif
 
                    /*
@@ -674,7 +640,7 @@ SynchronizeFile(const char *fileName)
 
 #ifdef FEATURE_DEBUG_OPT
                    if (DebugOpt) {
-                       log9("    Command %s\n", ptr);
+                       log("\111    Command %s\n", ptr);
                    }
 #endif
 
@@ -686,7 +652,7 @@ SynchronizeFile(const char *fileName)
                FileBase = file;
 
                if (maxLines == 0 || maxEntries == 0)
-                   log9("Maximum number of lines reached for user %s\n", fileName);
+                   log("\111Maximum number of lines reached for user %s\n", fileName);
            }
            fclose(fi);
        }
@@ -712,21 +678,17 @@ static void
 SynchronizeDir(void)
 {
     /*
-     * Attempt to delete the database.  Note that we have to make a copy
-     * of the string
+     * Attempt to delete the database.
      */
 
     for (;;) {
        CronFile *file;
-       char *user;
 
        for (file = FileBase; file && file->cf_Deleted; file = file->cf_Next)
            ;
        if (file == NULL)
            break;
-       user = strdup(file->cf_User);
-       DeleteFile(user);
-       free(user);
+       DeleteFile(file->cf_User);
     }
 
     /*
@@ -740,8 +702,7 @@ SynchronizeDir(void)
 
     remove(CRONUPDATE);
     if (chdir(CDir) < 0) {
-       log9("unable to find %s\n", CDir);
-       exit(20);
+       log("\311unable to find %s\n", CDir);
     }
     {
        DIR *dir;
@@ -754,12 +715,11 @@ SynchronizeDir(void)
                if (getpwnam(den->d_name))
                    SynchronizeFile(den->d_name);
                else
-                   log(7, "ignoring %s\n", den->d_name);
+                   log("\007ignoring %s\n", den->d_name);
            }
            closedir(dir);
        } else {
-           log9("Unable to open current dir!\n");
-           exit(20);
+           log("\311Unable to open current dir!\n");
        }
     }
 }
@@ -836,14 +796,14 @@ TestJobs(time_t t1, time_t t2)
            for (file = FileBase; file; file = file->cf_Next) {
 #ifdef FEATURE_DEBUG_OPT
                if (DebugOpt)
-                   log(5, "FILE %s:\n", file->cf_User);
+                   log("\005FILE %s:\n", file->cf_User);
 #endif
                if (file->cf_Deleted)
                    continue;
                for (line = file->cf_LineBase; line; line = line->cl_Next) {
 #ifdef FEATURE_DEBUG_OPT
                    if (DebugOpt)
-                       log(5, "    LINE %s\n", line->cl_Shell);
+                       log("\005    LINE %s\n", line->cl_Shell);
 #endif
                    if (line->cl_Mins[tp->tm_min] &&
                        line->cl_Hrs[tp->tm_hour] &&
@@ -852,10 +812,10 @@ TestJobs(time_t t1, time_t t2)
                    ) {
 #ifdef FEATURE_DEBUG_OPT
                        if (DebugOpt)
-                           log(5, "    JobToDo: %d %s\n", line->cl_Pid, line->cl_Shell);
+                           log("\005    JobToDo: %d %s\n", line->cl_Pid, line->cl_Shell);
 #endif
                        if (line->cl_Pid > 0) {
-                           log(8, "    process already running: %s %s\n",
+                           log("\010    process already running: %s %s\n",
                                file->cf_User,
                                line->cl_Shell
                            );
@@ -885,9 +845,9 @@ RunJobs(void)
            for (line = file->cf_LineBase; line; line = line->cl_Next) {
                if (line->cl_Pid < 0) {
 
-                   RunJob(file, line);
+                   RunJob(file->cf_User, line);
 
-                   log(8, "USER %s pid %3d cmd %s\n",
+                   log("\010USER %s pid %3d cmd %s\n",
                        file->cf_User,
                        line->cl_Pid,
                        line->cl_Shell
@@ -926,7 +886,7 @@ CheckJobs(void)
                    int r = wait4(line->cl_Pid, &status, WNOHANG, NULL);
 
                    if (r < 0 || r == line->cl_Pid) {
-                       EndJob(file, line);
+                       EndJob(file->cf_User, line);
                        if (line->cl_Pid)
                            file->cf_Running = 1;
                    } else if (r == 0) {
@@ -941,83 +901,54 @@ CheckJobs(void)
 }
 
 
-
+#ifdef CONFIG_FEATURE_CROND_CALL_SENDMAIL
 static void
-RunJob(CronFile *file, CronLine *line)
+ForkJob(const char *user, CronLine *line, int mailFd,
+       const char *prog, const char *cmd, const char *arg, const char *mailf)
 {
-    char mailFile[128];
-    int mailFd;
-
-    line->cl_Pid = 0;
-    line->cl_MailFlag = 0;
-
-    /*
-     * open mail file - owner root so nobody can screw with it.
-     */
-
-    snprintf(mailFile, sizeof(mailFile), TMPDIR "/cron.%s.%d",
-            file->cf_User, getpid());
-    mailFd = open(mailFile, O_CREAT|O_TRUNC|O_WRONLY|O_EXCL|O_APPEND, 0600);
-
-    if (mailFd >= 0) {
-       line->cl_MailFlag = 1;
-       fdprintf(mailFd, "To: %s\nSubject: cron: %s\n\n",
-           file->cf_User,
-           line->cl_Shell
-       );
-       line->cl_MailPos = lseek(mailFd, 0, 1);
-    }
-
     /*
      * Fork as the user in question and run program
      */
+    pid_t pid = fork();
 
-    if ((line->cl_Pid = fork()) == 0) {
+    line->cl_Pid = pid;
+    if (pid == 0) {
        /*
-        * CHILD, FORK OK
+        * CHILD
         */
 
        /*
         * Change running state to the user in question
         */
 
-       if (ChangeUser(file->cf_User, 1) < 0)
-           return;
+       if (ChangeUser(user) < 0)
+           exit(0);
 
 #ifdef FEATURE_DEBUG_OPT
        if (DebugOpt)
-           log(5, "Child Running %s\n", line->cl_Shell);
+           log("\005Child Running %s\n", prog);
 #endif
 
-       /*
-        * stdin is already /dev/null, setup stdout and stderr
-        */
-
        if (mailFd >= 0) {
-           dup2(mailFd, 1);
-           dup2(mailFd, 2);
+           dup2(mailFd, mailf != NULL);
+           dup2((mailf ? mailFd : 1), 2);
            close(mailFd);
-       } else {
-           log_err("unable to create mail file user %s file %s, output to /dev/null\n",
-               file->cf_User,
-               mailFile
-           );
        }
-       execl("/bin/sh", "/bin/sh", "-c", line->cl_Shell, NULL, NULL);
-       log_err("unable to exec, user %s cmd /bin/sh -c %s\n",
-           file->cf_User,
-           line->cl_Shell
-       );
-       fdprintf(1, "Exec failed: /bin/sh -c %s\n", line->cl_Shell);
+       execl(prog, prog, cmd, arg, NULL);
+       log("\024unable to exec, user %s cmd %s %s %s\n", user,
+           prog, cmd, arg);
+       if(mailf)
+           fdprintf(1, "Exec failed: %s -c %s\n", prog, arg);
        exit(0);
-    } else if (line->cl_Pid < 0) {
+    } else if (pid < 0) {
        /*
-        * PARENT, FORK FAILED
+        * FORK FAILED
         */
-       log_err("couldn't fork, user %s\n", file->cf_User);
+       log("\024couldn't fork, user %s\n", user);
        line->cl_Pid = 0;
-       remove(mailFile);
-    } else {
+       if(mailf)
+           remove(mailf);
+    } else if(mailf) {
        /*
         * PARENT, FORK SUCCESS
         *
@@ -1026,10 +957,9 @@ RunJob(CronFile *file, CronLine *line)
        char mailFile2[128];
 
        snprintf(mailFile2, sizeof(mailFile2), TMPDIR "/cron.%s.%d",
-               file->cf_User, line->cl_Pid);
-       rename(mailFile, mailFile2);
+                                   user, pid);
+       rename(mailf, mailFile2);
     }
-
     /*
      * Close the mail file descriptor.. we can't just leave it open in
      * a structure, closing it later, because we might run out of descriptors
@@ -1039,12 +969,42 @@ RunJob(CronFile *file, CronLine *line)
        close(mailFd);
 }
 
+static void
+RunJob(const char *user, CronLine *line)
+{
+    char mailFile[128];
+    int mailFd;
+
+    line->cl_Pid = 0;
+    line->cl_MailFlag = 0;
+
+    /*
+     * open mail file - owner root so nobody can screw with it.
+     */
+
+    snprintf(mailFile, sizeof(mailFile), TMPDIR "/cron.%s.%d",
+            user, getpid());
+    mailFd = open(mailFile, O_CREAT|O_TRUNC|O_WRONLY|O_EXCL|O_APPEND, 0600);
+
+    if (mailFd >= 0) {
+       line->cl_MailFlag = 1;
+       fdprintf(mailFd, "To: %s\nSubject: cron: %s\n\n", user,
+                                                   line->cl_Shell);
+       line->cl_MailPos = lseek(mailFd, 0, 1);
+    } else {
+           log("\024unable to create mail file user %s file %s, output to /dev/null\n",
+                       user, mailFile);
+    }
+
+    ForkJob(user, line, mailFd, def_sh, "-c", line->cl_Shell, mailFile);
+}
+
 /*
  * EndJob - called when job terminates and when mail terminates
  */
 
 static void
-EndJob(const CronFile *file, CronLine *line)
+EndJob(const char *user, CronLine *line)
 {
     int mailFd;
     char mailFile[128];
@@ -1065,7 +1025,7 @@ EndJob(const CronFile *file, CronLine *line)
      */
 
     snprintf(mailFile, sizeof(mailFile), TMPDIR "/cron.%s.%d",
-            file->cf_User, line->cl_Pid);
+            user, line->cl_Pid);
     line->cl_Pid = 0;
 
     if (line->cl_MailFlag != 1)
@@ -1093,46 +1053,47 @@ EndJob(const CronFile *file, CronLine *line)
        close(mailFd);
        return;
     }
+    ForkJob(user, line, mailFd, SENDMAIL, SENDMAIL_ARGS, NULL);
+}
+#else
+/* crond whithout sendmail */
 
-    if ((line->cl_Pid = fork()) == 0) {
+static void
+RunJob(const char *user, CronLine *line)
+{
        /*
-        * CHILD, FORK OK
+     * Fork as the user in question and run program
         */
+    pid_t pid = fork();
 
+    if (pid == 0) {
        /*
-        * change user id - no way in hell security can be compromised
-        * by the mailing and we already verified the mail file.
+        * CHILD
         */
 
-       if (ChangeUser(file->cf_User, 1) < 0)
-           exit(0);
-
        /*
-        * run sendmail with mail file as standard input, only if
-        * mail file exists!
+        * Change running state to the user in question
         */
 
-       dup2(mailFd, 0);
-       dup2(1, 2);
-       close(mailFd);
+       if (ChangeUser(user) < 0)
+           exit(0);
+
+#ifdef FEATURE_DEBUG_OPT
+       if (DebugOpt)
+           log("\005Child Running %s\n", def_sh);
+#endif
 
-       execl(SENDMAIL, SENDMAIL, SENDMAIL_ARGS, NULL, NULL);
-       log_err("unable to exec %s %s, user %s, output to sink null",
-           SENDMAIL,
-           SENDMAIL_ARGS,
-           file->cf_User
-       );
+       execl(def_sh, def_sh, "-c", line->cl_Shell, NULL);
+       log("\024unable to exec, user %s cmd %s -c %s\n", user,
+           def_sh, line->cl_Shell);
        exit(0);
-    } else if (line->cl_Pid < 0) {
-       /*
-        * PARENT, FORK FAILED
-        */
-       log_err("unable to fork, user %s", file->cf_User);
-       line->cl_Pid = 0;
-    } else {
+    } else if (pid < 0) {
        /*
-        * PARENT, FORK OK
+        * FORK FAILED
         */
+       log("\024couldn't fork, user %s\n", user);
+       pid = 0;
     }
-    close(mailFd);
+    line->cl_Pid = pid;
 }
+#endif /* CONFIG_FEATURE_CROND_CALL_SENDMAIL */
index 406b991634ccbebf1da81f0e6bd6fd5097f9d48d..0bd17fb6342942f47751c0f8360e9f620980d259 100644 (file)
@@ -58,6 +58,13 @@ config CONFIG_FEATURE_HTTPD_BASIC_AUTH
          Utilizes password settings from /etc/httpd.conf for basic
          authentication on a per url basis.
 
+config CONFIG_FEATURE_HTTPD_AUTH_MD5
+       bool "  Enable support MD5 crypted password for httpd.conf"
+       default n
+       depends on CONFIG_FEATURE_HTTPD_BASIC_AUTH
+       help
+         Please help my - send patch for set this help message
+
 
 if !CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
 config CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP
@@ -105,7 +112,7 @@ config CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV
 
 config CONFIG_FEATURE_HTTPD_SET_CGI_VARS_TO_ENV
        bool "  Enable setting of CGI_varname=value environment vars for CGI"
-       default y
+       default n
        depends on CONFIG_FEATURE_HTTPD_CGI
        help
          This option parses POST or GET arguments from a form and
index 7d0d0b8bc10d7b10cbd504a1cc4167fbf0c8db04..7748d066b5d1b00978126d5775b4a5d0fd65ec38 100644 (file)
@@ -53,6 +53,13 @@ NETWORKING-$(CONFIG_WGET)            += wget.o
 
 libraries-y+=$(NETWORKING_DIR)$(NETWORKING_AR)
 
+needcrypt-y:=
+needcrypt-$(CONFIG_FEATURE_HTTPD_AUTH_MD5) := y
+
+ifeq ($(needcrypt-y),y)
+  LIBRARIES += -lcrypt
+endif
+
 $(NETWORKING_DIR)$(NETWORKING_AR): $(patsubst %,$(NETWORKING_DIR)%, $(NETWORKING-y))
        $(AR) -ro $@ $(patsubst %,$(NETWORKING_DIR)%, $(NETWORKING-y))
 
index d3d88fcb6c5b6f875fd23a6a41d9dc5e4bd2b3d2..d58414b558328abf3372ea7b817bd7372d8a0069 100644 (file)
@@ -153,12 +153,14 @@ static const char home[] = "./";
 /* Config options, disable this for do very small module */
 //#define CONFIG_FEATURE_HTTPD_CGI
 //#define CONFIG_FEATURE_HTTPD_BASIC_AUTH
+//#define CONFIG_FEATURE_HTTPD_AUTH_MD5
 
 #ifdef HTTPD_STANDALONE
 /* standalone, enable all features */
 #undef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
 /* unset config option for remove warning as redefined */
 #undef CONFIG_FEATURE_HTTPD_BASIC_AUTH
+#undef CONFIG_FEATURE_HTTPD_AUTH_MD5
 #undef CONFIG_FEATURE_HTTPD_SET_CGI_VARS_TO_ENV
 #undef CONFIG_FEATURE_HTTPD_ENCODE_URL_STR
 #undef CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV
@@ -168,6 +170,7 @@ static const char home[] = "./";
 #undef CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP
 /* enable all features now */
 #define CONFIG_FEATURE_HTTPD_BASIC_AUTH
+#define CONFIG_FEATURE_HTTPD_AUTH_MD5
 #define CONFIG_FEATURE_HTTPD_SET_CGI_VARS_TO_ENV
 #define CONFIG_FEATURE_HTTPD_ENCODE_URL_STR
 #define CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV
@@ -425,11 +428,11 @@ static void parse_conf(const char *path, int flag)
     }
 
     while((f = fopen(cf, "r")) == NULL) {
-       if(flag != FIRST_PARSE) {
+       if(flag == SUBDIR_PARSE || flag == FIND_FROM_HTTPD_ROOT) {
            /* config file not found, no changes to config */
            return;
        }
-       if(config->configFile)      /* if -c option given */
+       if(config->configFile && flag == FIRST_PARSE) /* if -c option given */
            bb_perror_msg_and_die("%s", cf);
        flag = FIND_FROM_HTTPD_ROOT;
        cf = httpd_conf;
@@ -1326,10 +1329,38 @@ static int checkPerm(const char *path, const char *request)
            if(strncmp(p0, path, l) == 0 &&
                            (l == 1 || path[l] == '/' || path[l] == 0)) {
                /* path match found.  Check request */
+
+               /* for check next /path:user:password */
+               prev = p0;
+#ifdef CONFIG_FEATURE_HTTPD_AUTH_MD5
+               {
+                       char *cipher;
+                       char *pp;
+                       char *u = strchr(request, ':');
+
+                       if(u == NULL) {
+                               /* bad request, ':' required */
+                               continue;
+                       }
+                       if(strncmp(p, request, u-request) != 0) {
+                               /* user uncompared */
+                               continue;
+                       }
+                       pp = strchr(p, ':');
+                       if(pp && pp[1] == '$' && pp[2] == '1' &&
+                                                pp[3] == '$' && pp[4]) {
+                               pp++;
+                               cipher = pw_encrypt(u+1, pp);
+                               if (strcmp(cipher, pp) == 0)
+                                       return 1;   /* Ok */
+                               /* unauthorized */
+                               continue;
+                       }
+               }
+#endif
                if (strcmp(p, request) == 0)
                    return 1;   /* Ok */
-               /* unauthorized, but check next /path:user:password */
-               prev = p0;
+               /* unauthorized */
            }
        }
     }   /* for */
@@ -1731,7 +1762,12 @@ static const char httpd_opts[]="c:d:h:"
 #endif
 #ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
                                "r:"
-#define OPT_INC_2 1
+# ifdef CONFIG_FEATURE_HTTPD_AUTH_MD5
+                               "m:"
+# define OPT_INC_2 2
+# else
+# define OPT_INC_2 1
+#endif
 #else
 #define OPT_INC_2 0
 #endif
@@ -1740,14 +1776,15 @@ static const char httpd_opts[]="c:d:h:"
 #ifdef CONFIG_FEATURE_HTTPD_SETUID
                                "u:"
 #endif
-#endif
+#endif /* CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY */
                                        ;
 
 #define OPT_CONFIG_FILE (1<<0)
 #define OPT_DECODE_URL  (1<<1)
 #define OPT_HOME_HTTPD  (1<<2)
 #define OPT_ENCODE_URL  (1<<(2+OPT_INC_1))
-#define OPT_REALM       (1<<(2+OPT_INC_1+OPT_INC_2))
+#define OPT_REALM       (1<<(3+OPT_INC_1))
+#define OPT_MD5         (1<<(4+OPT_INC_1))
 #define OPT_PORT        (1<<(3+OPT_INC_1+OPT_INC_2))
 #define OPT_DEBUG       (1<<(4+OPT_INC_1+OPT_INC_2))
 #define OPT_SETUID      (1<<(5+OPT_INC_1+OPT_INC_2))
@@ -1778,6 +1815,10 @@ int httpd_main(int argc, char *argv[])
   long uid = -1;
 #endif
 
+#ifdef CONFIG_FEATURE_HTTPD_AUTH_MD5
+  const char *pass;
+#endif
+
   config = xcalloc(1, sizeof(*config));
 #ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
   config->realm = "Web Server Authentication";
@@ -1796,6 +1837,9 @@ int httpd_main(int argc, char *argv[])
 #endif
 #ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
                        , &(config->realm)
+# ifdef CONFIG_FEATURE_HTTPD_AUTH_MD5
+                       , &pass
+# endif
 #endif
 #ifndef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
                        , &s_port
@@ -1815,6 +1859,12 @@ int httpd_main(int argc, char *argv[])
       return 0;
   }
 #endif
+#ifdef CONFIG_FEATURE_HTTPD_AUTH_MD5
+  if(opt & OPT_MD5) {
+      printf("%s\n", pw_encrypt(pass, "$1$"));
+      return 0;
+  }
+#endif
 #ifndef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
     if(opt & OPT_PORT)
        config->port = bb_xgetlarg(s_port, 10, 1, 0xffff);
index 33b97ba94e23e288ccfd0a8624c15eb72ea54677..af262c39c8177535fdb8fe562feef5189a50d765 100644 (file)
@@ -806,7 +806,9 @@ inetd_main(int argc, char *argv[])
        struct passwd *pwd;
        struct group *grp = NULL;
        struct sigaction sa;
-       int ch, pid;
+       int pid;
+       unsigned long opt;
+       char *sq;
        gid_t gid;
 
 #ifdef INETD_UNSUPPORT_BILTIN
@@ -828,14 +830,21 @@ inetd_main(int argc, char *argv[])
        LastArg = environ[-1] + strlen(environ[-1]);
 #endif
 
-       while ((ch = getopt(argc, argv, "q:")) != EOF)
-               switch(ch) {
-               case 'q':
+#if defined(__uClinux__)
+       opt = bb_getopt_ulflags(argc, argv, "q:f", &sq);
+       if (!(opt & 4)) {
+           daemon(0, 0);
+           /* reexec for vfork() do continue parent */
+           vfork_daemon_rexec(argc, argv, "-f");
+       }
+#else
+       opt = bb_getopt_ulflags(ac, av, "q:", &sq);
+       daemon(0, 0);
+#endif /* uClinux */
+
+       if(opt & 1) {
                        global_queuelen = atoi(optarg);
                        if (global_queuelen < 8) global_queuelen=8;
-                       break;
-               default:
-                       bb_show_usage(); // "[-q len] [conf]"
                }
        argc -= optind;
        argv += optind;
@@ -843,7 +852,6 @@ inetd_main(int argc, char *argv[])
        if (argc > 0)
                CONFIG = argv[0];
 
-       daemon(0, 0);
        openlog(bb_applet_name, LOG_PID | LOG_NOWAIT, LOG_DAEMON);
        {
                FILE *fp;
index f537a4bb8184e23aa4b9343848dc0507031f9eeb..2e187b19973a2be180d1f822b51042efab6806e2 100644 (file)
@@ -150,8 +150,8 @@ extern int klogd_main(int argc, char **argv)
 #if !defined(__UCLIBC__) || defined(__UCLIBC_HAS_MMU__)
                if (daemon(0, 1) < 0)
                        bb_perror_msg_and_die("daemon");
-#else
-               bb_error_msg_and_die("daemon not supported");
+#if defined(__uClinux__)
+               vfork_daemon_rexec(argc, argv, "-n");
 #endif
        }
        doKlogd(console_log_level);
index 67324116ddf2c394c10436c1d5d166ff72fdb9a3..c554536c8bc6f15a03ece480715c0e0c3d212d1e 100644 (file)
@@ -632,11 +632,12 @@ extern int syslogd_main(int argc, char **argv)
 
        umask(0);
 
-#if ! defined(__uClinux__)
        if ((doFork == TRUE) && (daemon(0, 1) < 0)) {
                bb_perror_msg_and_die("daemon");
-       }
+#if ! defined(__uClinux__)
+               vfork_daemon_rexec(argc, argv, "-n");
 #endif
+       }
        doSyslogd();
 
        return EXIT_SUCCESS;