* `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
#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);
#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 */
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 ;
}
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;
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
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);
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);
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);
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 )
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;
}
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",
exit (EXIT_ERR);
}
+/* if (uid != 0 && setuid(fcrontab_uid) < 0) { */
+/* close(i); */
+/* die_e("setuid(fcrontab_uid)"); */
+/* } */
close(0); dup2(i, 0);
close(i);
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) ) {
int
main(int argc, char **argv)
{
+ struct passwd *pass;
memset(buf, 0, sizeof(buf));
memset(file, 0, sizeof(file));
/* 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);
* `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"
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[] = {
/* 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;
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 == '~' ) {