Add support for non-root timestamp dirs. This allows the timestamp
dir to be shared via NFS (though this is not recommended).
This commit is contained in:
27
check.c
27
check.c
@@ -145,6 +145,7 @@ update_timestamp(timestampdir, timestampfile)
|
|||||||
char *timestampfile;
|
char *timestampfile;
|
||||||
{
|
{
|
||||||
|
|
||||||
|
set_perms(PERM_TIMESTAMP, 0);
|
||||||
if (touch(timestampfile ? timestampfile : timestampdir, time(NULL)) == -1) {
|
if (touch(timestampfile ? timestampfile : timestampdir, time(NULL)) == -1) {
|
||||||
if (timestampfile) {
|
if (timestampfile) {
|
||||||
int fd = open(timestampfile, O_WRONLY|O_CREAT|O_TRUNC, 0600);
|
int fd = open(timestampfile, O_WRONLY|O_CREAT|O_TRUNC, 0600);
|
||||||
@@ -158,6 +159,7 @@ update_timestamp(timestampdir, timestampfile)
|
|||||||
log_error(NO_EXIT|USE_ERRNO, "Can't mkdir %s", timestampdir);
|
log_error(NO_EXIT|USE_ERRNO, "Can't mkdir %s", timestampdir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
set_perms(PERM_ROOT, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -307,6 +309,8 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs)
|
|||||||
char *dirparent = def_str(I_TIMESTAMPDIR);
|
char *dirparent = def_str(I_TIMESTAMPDIR);
|
||||||
int status = TS_ERROR; /* assume the worst */
|
int status = TS_ERROR; /* assume the worst */
|
||||||
|
|
||||||
|
set_perms(PERM_TIMESTAMP, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sanity check dirparent and make it if it doesn't already exist.
|
* Sanity check dirparent and make it if it doesn't already exist.
|
||||||
* We start out assuming the worst (that the dir is not sane) and
|
* We start out assuming the worst (that the dir is not sane) and
|
||||||
@@ -318,9 +322,9 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs)
|
|||||||
if (!S_ISDIR(sb.st_mode))
|
if (!S_ISDIR(sb.st_mode))
|
||||||
log_error(NO_EXIT, "%s exists but is not a directory (0%o)",
|
log_error(NO_EXIT, "%s exists but is not a directory (0%o)",
|
||||||
dirparent, sb.st_mode);
|
dirparent, sb.st_mode);
|
||||||
else if (sb.st_uid != 0)
|
else if (sb.st_uid != timestamp_uid)
|
||||||
log_error(NO_EXIT, "%s owned by uid %ld, should be owned by root",
|
log_error(NO_EXIT, "%s owned by uid %ld, should be uid %ld",
|
||||||
dirparent, (long) sb.st_uid);
|
dirparent, (long) sb.st_uid, (long) timestamp_uid);
|
||||||
else if ((sb.st_mode & 0000022))
|
else if ((sb.st_mode & 0000022))
|
||||||
log_error(NO_EXIT,
|
log_error(NO_EXIT,
|
||||||
"%s writable by non-owner (0%o), should be mode 0700",
|
"%s writable by non-owner (0%o), should be mode 0700",
|
||||||
@@ -342,8 +346,10 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs)
|
|||||||
status = TS_MISSING;
|
status = TS_MISSING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (status == TS_ERROR)
|
if (status == TS_ERROR) {
|
||||||
|
set_perms(PERM_ROOT, 0);
|
||||||
return(status);
|
return(status);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sanity check the user's ticket dir. We start by downgrading
|
* Sanity check the user's ticket dir. We start by downgrading
|
||||||
@@ -361,9 +367,9 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs)
|
|||||||
} else
|
} else
|
||||||
log_error(NO_EXIT, "%s exists but is not a directory (0%o)",
|
log_error(NO_EXIT, "%s exists but is not a directory (0%o)",
|
||||||
timestampdir, sb.st_mode);
|
timestampdir, sb.st_mode);
|
||||||
} else if (sb.st_uid != 0)
|
} else if (sb.st_uid != timestamp_uid)
|
||||||
log_error(NO_EXIT, "%s owned by uid %ld, should be owned by root",
|
log_error(NO_EXIT, "%s owned by uid %ld, should be uid %ld",
|
||||||
timestampdir, (long) sb.st_uid);
|
timestampdir, (long) sb.st_uid, (long) timestamp_uid);
|
||||||
else if ((sb.st_mode & 0000022))
|
else if ((sb.st_mode & 0000022))
|
||||||
log_error(NO_EXIT,
|
log_error(NO_EXIT,
|
||||||
"%s writable by non-owner (0%o), should be mode 0700",
|
"%s writable by non-owner (0%o), should be mode 0700",
|
||||||
@@ -402,10 +408,10 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs)
|
|||||||
timestampfile, sb.st_mode);
|
timestampfile, sb.st_mode);
|
||||||
} else {
|
} else {
|
||||||
/* If bad uid or file mode, complain and kill the bogus file. */
|
/* If bad uid or file mode, complain and kill the bogus file. */
|
||||||
if (sb.st_uid != 0) {
|
if (sb.st_uid != timestamp_uid) {
|
||||||
log_error(NO_EXIT,
|
log_error(NO_EXIT,
|
||||||
"%s owned by uid %ld, should be owned by root",
|
"%s owned by uid %ld, should be uid %ld",
|
||||||
timestampfile, (long) sb.st_uid);
|
timestampfile, (long) sb.st_uid, (long) timestamp_uid);
|
||||||
(void) unlink(timestampfile);
|
(void) unlink(timestampfile);
|
||||||
} else if ((sb.st_mode & 0000022)) {
|
} else if ((sb.st_mode & 0000022)) {
|
||||||
log_error(NO_EXIT,
|
log_error(NO_EXIT,
|
||||||
@@ -456,6 +462,7 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_perms(PERM_ROOT, 0);
|
||||||
return(status);
|
return(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
set_perms.c
13
set_perms.c
@@ -145,6 +145,11 @@ set_perms_posix(perm, sudo_mode)
|
|||||||
fatal("seteuid(SUDOERS_UID)", 1);
|
fatal("seteuid(SUDOERS_UID)", 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case PERM_TIMESTAMP:
|
||||||
|
if (seteuid(timestamp_uid))
|
||||||
|
fatal("seteuid(timestamp_uid)", 1);
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* !NO_SAVED_IDS && _SC_SAVED_IDS && _SC_VERSION */
|
#endif /* !NO_SAVED_IDS && _SC_SAVED_IDS && _SC_VERSION */
|
||||||
@@ -213,6 +218,10 @@ set_perms_fallback(perm, sudo_mode)
|
|||||||
fatal("setreuid(0, SUDOERS_UID)", 1);
|
fatal("setreuid(0, SUDOERS_UID)", 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case PERM_TIMESTAMP:
|
||||||
|
if (setreuid(0, timestamp_uid))
|
||||||
|
fatal("setreuid(0, timestamp_uid)", 1);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,6 +285,10 @@ set_perms_fallback(perm, sudo_mode)
|
|||||||
fatal("seteuid(SUDOERS_UID)", 1);
|
fatal("seteuid(SUDOERS_UID)", 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case PERM_TIMESTAMP:
|
||||||
|
if (seteuid(timestamp_uid))
|
||||||
|
fatal("seteuid(timestamp_uid)", 1);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* HAVE_SETREUID */
|
#endif /* HAVE_SETREUID */
|
||||||
|
17
sudo.c
17
sudo.c
@@ -131,6 +131,7 @@ FILE *sudoers_fp = NULL;
|
|||||||
struct interface *interfaces;
|
struct interface *interfaces;
|
||||||
int num_interfaces;
|
int num_interfaces;
|
||||||
int tgetpass_flags;
|
int tgetpass_flags;
|
||||||
|
int timestamp_uid;
|
||||||
extern int errorlineno;
|
extern int errorlineno;
|
||||||
#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
|
#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
|
||||||
static struct rlimit corelimit;
|
static struct rlimit corelimit;
|
||||||
@@ -287,6 +288,22 @@ main(argc, argv, envp)
|
|||||||
log_error(NO_MAIL|MSG_ONLY, "no passwd entry for %s!", *user_runas);
|
log_error(NO_MAIL|MSG_ONLY, "no passwd entry for %s!", *user_runas);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look up the timestamp dir owner if one is specified.
|
||||||
|
*/
|
||||||
|
if (def_str(I_TIMESTAMPOWNER)) {
|
||||||
|
struct passwd *pw;
|
||||||
|
|
||||||
|
if (*def_str(I_TIMESTAMPOWNER) == '#')
|
||||||
|
pw = getpwuid(atoi(def_str(I_TIMESTAMPOWNER) + 1));
|
||||||
|
else
|
||||||
|
pw = getpwnam(def_str(I_TIMESTAMPOWNER));
|
||||||
|
if (!pw)
|
||||||
|
log_error(0, "timestamp owner (%s): No such user",
|
||||||
|
def_str(I_TIMESTAMPOWNER));
|
||||||
|
timestamp_uid = pw->pw_uid;
|
||||||
|
}
|
||||||
|
|
||||||
/* This goes after the sudoers parse since we honor sudoers options. */
|
/* This goes after the sudoers parse since we honor sudoers options. */
|
||||||
if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) {
|
if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) {
|
||||||
remove_timestamp((sudo_mode == MODE_KILL));
|
remove_timestamp((sudo_mode == MODE_KILL));
|
||||||
|
2
sudo.h
2
sudo.h
@@ -116,6 +116,7 @@ struct sudo_user {
|
|||||||
#define PERM_FULL_USER 0x03
|
#define PERM_FULL_USER 0x03
|
||||||
#define PERM_SUDOERS 0x04
|
#define PERM_SUDOERS 0x04
|
||||||
#define PERM_RUNAS 0x05
|
#define PERM_RUNAS 0x05
|
||||||
|
#define PERM_TIMESTAMP 0x06
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Shortcuts for sudo_user contents.
|
* Shortcuts for sudo_user contents.
|
||||||
@@ -235,6 +236,7 @@ extern int Argc;
|
|||||||
extern char **Argv;
|
extern char **Argv;
|
||||||
extern FILE *sudoers_fp;
|
extern FILE *sudoers_fp;
|
||||||
extern int tgetpass_flags;
|
extern int tgetpass_flags;
|
||||||
|
extern int timestamp_uid;
|
||||||
|
|
||||||
extern void (*set_perms) __P((int, int));
|
extern void (*set_perms) __P((int, int));
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user