]> git.ipfire.org Git - thirdparty/fcron.git/commitdiff
bug corrected : every user can now use fcrontab even if installed
authorThibault Godouet <yo8192@users.noreply.github.com>
Fri, 10 Nov 2000 17:34:02 +0000 (17:34 +0000)
committerThibault Godouet <yo8192@users.noreply.github.com>
Fri, 10 Nov 2000 17:34:02 +0000 (17:34 +0000)
under the non privileged users rights

fcrontab.c
fileconf.c

index c2ac9e9eb795cadd9e134658b6e2e4a16fb56e86..a84ca9755f51454a31761592468f4ca944d2ae15 100644 (file)
@@ -22,7 +22,7 @@
  *  `LICENSE' that comes with the fcron source distribution.
  */
 
- /* $Id: fcrontab.c,v 1.16 2000-09-15 20:17:12 thib Exp $ */
+ /* $Id: fcrontab.c,v 1.17 2000-11-10 17:34:02 thib Exp $ */
 
 /* 
  * The goal of this program is simple : giving a user interface to fcron
@@ -42,7 +42,7 @@
 
 #include "fcrontab.h"
 
-char rcs_info[] = "$Id: fcrontab.c,v 1.16 2000-09-15 20:17:12 thib Exp $";
+char rcs_info[] = "$Id: fcrontab.c,v 1.17 2000-11-10 17:34:02 thib Exp $";
 
 void info(void);
 void usage(void);
@@ -65,7 +65,12 @@ char debug_opt = 0;       /* set to 1 if we are in debug mode */
 #endif
 
 char *user = NULL;
-uid_t uid = 0 ;
+uid_t uid = 0;
+uid_t asuid = 0;
+gid_t asgid = 0;
+uid_t fcrontab_uid = 0;
+gid_t fcrontab_gid = 0;
+char u_opt = 0;
 char  *cdir = FCRONTABS;
 
 char need_sig = 0;           /* do we need to signal fcron daemon */
@@ -245,9 +250,20 @@ copy(char *orig, char *dest)
     FILE *from = NULL, *to = NULL;
     char c;
 
-    if ( (from = fopen(orig, "r")) == NULL
-        || (to = fopen(dest, "w")) == NULL) {
-       error_e("copy");
+    if (uid != 0 && setuid(uid) < 0)
+       die_e("setuid(uid)");
+
+    if ( (from = fopen(orig, "r")) == NULL) {
+       error_e("copy: orig");
+       return ;
+    }
+    if (uid != 0 && setuid(fcrontab_uid) < 0) {
+       fclose(from);
+       die_e("setuid(fcrontab_uid)");
+    }
+
+    if ((to = fopen(dest, "w")) == NULL) {
+       error_e("copy: dest");
        return ;
     }
 
@@ -412,6 +428,10 @@ edit_file(char *buf)
        
     sprintf(tmp, "/tmp/fcrontab.%d", getpid());
 
+    /* create a temp file with user's permissions */
+    if (uid != 0 && setuid(uid) != 0 ) 
+       die_e("Could not change uid"); 
+
     if ( (file = open(tmp, O_CREAT|O_EXCL|O_WRONLY, 0600)) == -1 ) {
        error_e("could not create file %s", tmp);
        goto exiterr;
@@ -420,11 +440,13 @@ edit_file(char *buf)
        error_e("could not fdopen");
        goto exiterr;
     }
+    if (uid != 0 && setuid(fcrontab_uid) != 0 ) 
+       die_e("Could not change uid"); 
 
     /* copy user's fcrontab (if any) to a temp file */
     if ( (f = fopen(buf, "r")) == NULL ) {
        if ( errno != ENOENT ) {
-           error_e("could not open file %s", buf);
+           error_e("could not open file %s uid:%d euid:%d", buf, getuid(), geteuid());
            goto exiterr;
        }
        else
@@ -438,11 +460,18 @@ edit_file(char *buf)
        fclose(f);
     }
 
-    if ( fchown(file, getuid(), getgid()) != 0 ) {
-       error_e("could not chown %s", tmp);
-       goto exiterr;
+    /* if root has given -u option, chown the file in order to be editable
+     * by the user given with -u option */
+    if (u_opt == 1) {
+       /* we need to have euid set to root */
+       if (uid == 0 && setreuid(-1, 0) != 0)
+           die_e("Could not change euid to root");     
+       if ( fchown(file, asuid, asgid) != 0 )
+           die_e("Could not chown %s", tmp);
+       if (uid == 0 && setreuid(0, fcrontab_uid) != 0)
+           die_e("Could not change euid to root");     
     }
-    
+
     fclose(fi);
     close(file);
 
@@ -458,8 +487,16 @@ edit_file(char *buf)
        switch ( pid = fork() ) {
        case 0:
            /* child */
-           if (setuid(getuid()) < 0) {
-               error_e("setuid(getuid())");
+           if (uid == 0)
+               /* we need to become root to perform the gid and uid changes */
+               if (setreuid(0, 0) != 0)
+                   error_e("setreuid(0, 0)");
+           if (setregid(asgid, asgid) < 0) {
+               error_e("setregid(gid, gid)");
+               goto exiterr;
+           }
+           if (setreuid(asuid, asuid) < 0) {
+               error_e("setreuid(uid, uid)");
                goto exiterr;
            }
            execlp(editor, editor, tmp, NULL);
@@ -483,6 +520,18 @@ edit_file(char *buf)
            goto exiterr;
        }
 
+       /* if root has given -u option, chown the file in order to be editable
+        * by the user given with -u option */
+       if (u_opt == 1) {
+           /* we need to have euid set to root */
+           if (uid == 0 && setreuid(-1, 0) != 0)
+               die_e("Could not change euid to root"); 
+           if ( chown(tmp, fcrontab_uid, fcrontab_gid) != 0 )
+               die_e("Could not chown %s", tmp);
+           if (uid == 0 && setreuid(0, fcrontab_uid) != 0)
+               die_e("Could not change euid to root"); 
+       }
+
        /* check if file has been modified */
        if ( stat(tmp, &st) != 0 ) {
            error_e("could not stat %s", tmp);
@@ -551,9 +600,13 @@ install_stdin(void)
     char tmp[FNAME_LEN];
     register char c;
                    
+    /* create a temp file with user's permissions */
+    if (uid != 0 && setuid(uid) < 0)
+       die_e("setuid(uid)");
+
     sprintf(tmp, "/tmp/fcrontab.%d", getpid());
     if( (tmp_file = fopen(tmp, "w")) == NULL )
-       fprintf(stderr, "Could not open '%s': %s\n", tmp,
+       fprintf(stderr, "Could not open2 '%s': %s\n", tmp,
                strerror(errno));
 
     while ( (c = getc(stdin)) != EOF )
@@ -561,8 +614,8 @@ install_stdin(void)
 
     fclose(tmp_file);
 
-    if ( chown(tmp, getuid(), getgid()) != 0 ) {
-       error_e("could not chown %s", tmp);
+    if (uid != 0 && setuid(fcrontab_uid) < 0) {
+       error_e("setuid(fcrontab_uid)");
        goto exiterr;
     }
 
@@ -586,6 +639,10 @@ reinstall(char *buf)
 
     explain("reinstalling %s's fcrontab", user);
 
+      /* create a temp file with user's permissions */
+/*      if (uid != 0 && setuid(uid) < 0) */
+/*     die_e("setuid(uid)"); */
+
     if ( (i = open(buf, O_RDONLY)) < 0) {
        if ( errno == ENOENT ) {
            fprintf(stderr, "Could not reinstall: user %s has no fcrontab\n",
@@ -597,6 +654,10 @@ reinstall(char *buf)
 
        exit (EXIT_ERR);
     }
+/*      if (uid != 0 && setuid(fcrontab_uid) < 0) { */
+/*     close(i); */
+/*     die_e("setuid(fcrontab_uid)"); */
+/*      } */
 
     close(0); dup2(i, 0);
     close(i);
@@ -689,12 +750,16 @@ parseopt(int argc, char *argv[])
            fprintf(stderr, "Could not get user name.\n");
            xexit(EXIT_ERR);
        }
+       asuid = getuid();
+       asgid = getgid();
     }
     else {
        struct passwd *pass;
        if ( ! (pass = getpwnam(user)) )
            die("user '%s' is not in passwd file. Aborting.", user);
-       uid = pass->pw_uid;
+       asuid = pass->pw_uid;
+       asgid = pass->pw_gid;
+       u_opt = 1;
     }
 
     if ( ! is_allowed(user) ) {
@@ -711,6 +776,7 @@ parseopt(int argc, char *argv[])
 int
 main(int argc, char **argv)
 {
+    struct passwd *pass;
 
     memset(buf, 0, sizeof(buf));
     memset(file, 0, sizeof(file));
@@ -721,12 +787,19 @@ main(int argc, char **argv)
     /* interpret command line options */
     parseopt(argc, argv);
 
-    if ( seteuid(0) != 0 )
-       die_e("Could not set uid to root");
-    if ( setegid(0) != 0 )
-       die_e("Could not set gid to root");
+    uid = getuid();
+
+    if ( ! (pass = getpwnam(USERNAME)) )
+       die("user '%s' is not in passwd file. Aborting.", USERNAME);
+    fcrontab_uid = pass->pw_uid;
+    fcrontab_gid = pass->pw_gid;
+    if (uid != 0 && setuid(fcrontab_uid) != 0 ) 
+       die_e("Could not change uid to " USERNAME); 
+/*      if (setgid(fcrontab_gid) != 0) */
+/*     die_e("Could not change gid to " GROUPNAME);  */
+       
 
-    /* this program is seteuid root : we set default permission mode
+    /* this program is seteuid : we set default permission mode
      * to  600 for security reasons */
     umask(066);
 
index affc02aad11881d0302f3f42ab3a35fac2451531..1c196fbd7b49d613afe44b356244b25a57e2a6bd 100644 (file)
@@ -22,7 +22,7 @@
  *  `LICENSE' that comes with the fcron source distribution.
  */
 
- /* $Id: fileconf.c,v 1.22 2000-11-02 10:57:43 thib Exp $ */
+ /* $Id: fileconf.c,v 1.23 2000-11-10 17:35:00 thib Exp $ */
 
 #include "fcrontab.h"
 
@@ -47,6 +47,7 @@ char *file_name;
 int line;
 extern char *user;
 extern uid_t uid;
+extern uid_t fcrontab_uid;
 
 /* warning : all names must have the same length */
 const char *dows_ary[] = {
@@ -165,13 +166,23 @@ read_file(char *filename, char *user)
     /* open file */
 
     /* check if user is allowed to read file */
+    /* create a temp file with user's permissions */
+    if (uid != 0 && setuid(uid) < 0)
+       die_e("setuid(uid)");
+
     if ( access(file_name, R_OK) != 0 )
        die_e("User %s can't read file '%s'", user, file_name);
     else if ( (file = fopen(file_name, "r")) == NULL ) {
-       fprintf(stderr, "Could not open '%s': %s\n", file_name,
+       fprintf(stderr, "Could not open3 '%s': %s\n", file_name,
                strerror(errno));
        return ERR;
     }
+    if (setuid(fcrontab_uid) < 0) {
+       fclose(file);
+       error_e("setuid(fcrontab_uid)");        
+       return ERR;
+    }
+
 
     Alloc(cf, CF);
     default_line.cl_file = cf;
@@ -1132,8 +1143,12 @@ read_field(char *ptr, bitstr_t *ary, int max, const char **names)
        if (debug_opt)
            fprintf(stderr, " %d-%d/%d", start, stop, step);
 
-       for (i = start;  i <= stop;  i += step)
-           bit_set(ary, i);
+       if (start < stop)
+           for (i = start;  i <= stop;  i += step)
+               bit_set(ary, i);
+       else
+           for (i = start;  i >= stop;  i -= step)
+               bit_set(ary, i);
 
        /* finally, remove unwanted values */
        while ( *ptr == '~' ) {