Allow sudoers file name, mode, uid and gid to be specified in the

settings list.  The sudo front end does not currently set these
but may in the future.
This commit is contained in:
Todd C. Miller
2011-02-23 13:38:52 -05:00
parent 74c4252c1b
commit 3c0672e2e3
7 changed files with 61 additions and 36 deletions

View File

@@ -713,7 +713,7 @@ add_userspec(struct member *members, struct privilege *privs)
* the current sudoers file to path. * the current sudoers file to path.
*/ */
void void
init_parser(char *path, int quiet) init_parser(const char *path, int quiet)
{ {
struct defaults *d; struct defaults *d;
struct member *m, *binding; struct member *m, *binding;

View File

@@ -682,7 +682,7 @@ add_userspec(struct member *members, struct privilege *privs)
* the current sudoers file to path. * the current sudoers file to path.
*/ */
void void
init_parser(char *path, int quiet) init_parser(const char *path, int quiet)
{ {
struct defaults *d; struct defaults *d;
struct member *m, *binding; struct member *m, *binding;

View File

@@ -83,7 +83,7 @@ sudo_file_open(struct sudo_nss *nss)
{ {
if (def_ignore_local_sudoers) if (def_ignore_local_sudoers)
return -1; return -1;
nss->handle = open_sudoers(_PATH_SUDOERS, FALSE, NULL); nss->handle = open_sudoers(sudoers_file, FALSE, NULL);
return nss->handle ? 0 : -1; return nss->handle ? 0 : -1;
} }
@@ -109,7 +109,7 @@ sudo_file_parse(struct sudo_nss *nss)
if (nss->handle == NULL) if (nss->handle == NULL)
return -1; return -1;
init_parser(_PATH_SUDOERS, 0); init_parser(sudoers_file, 0);
yyin = nss->handle; yyin = nss->handle;
if (yyparse() != 0 || parse_error) { if (yyparse() != 0 || parse_error) {
log_error(NO_EXIT, "parse error in %s near line %d", log_error(NO_EXIT, "parse error in %s near line %d",

View File

@@ -185,7 +185,7 @@ void alias_free(void *);
void alias_apply(int (*)(void *, void *), void *); void alias_apply(int (*)(void *, void *), void *);
void init_aliases(void); void init_aliases(void);
void init_lexer(void); void init_lexer(void);
void init_parser(char *, int); void init_parser(const char *, int);
int alias_compare(const void *, const void *); int alias_compare(const void *, const void *);
#endif /* _SUDO_PARSE_H */ #endif /* _SUDO_PARSE_H */

View File

@@ -246,21 +246,21 @@ set_perms(int perm)
/* assumes euid == ROOT_UID, ruid == user */ /* assumes euid == ROOT_UID, ruid == user */
state->rgid = -1; state->rgid = -1;
state->egid = SUDOERS_GID; state->egid = sudoers_gid;
state->sgid = -1; state->sgid = -1;
if (setresgid(-1, ID(egid), -1)) if (setresgid(-1, ID(egid), -1))
error(1, "unable to change to sudoers gid"); error(1, "unable to change to sudoers gid");
state->ruid = ROOT_UID; state->ruid = ROOT_UID;
/* /*
* If SUDOERS_UID == ROOT_UID and SUDOERS_MODE is group readable * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
* we use a non-zero uid in order to avoid NFS lossage. * we use a non-zero uid in order to avoid NFS lossage.
* Using uid 1 is a bit bogus but should work on all OS's. * Using uid 1 is a bit bogus but should work on all OS's.
*/ */
if (SUDOERS_UID == ROOT_UID && (SUDOERS_MODE & 040)) if (sudoers_uid == ROOT_UID && (sudoers_mode & 040))
state->euid = 1; state->euid = 1;
else else
state->euid = SUDOERS_UID; state->euid = sudoers_uid;
state->suid = ROOT_UID; state->suid = ROOT_UID;
if (setresuid(ID(ruid), ID(euid), ID(suid))) { if (setresuid(ID(ruid), ID(euid), ID(suid))) {
errstr = "setresuid(ROOT_UID, SUDOERS_UID, ROOT_UID)"; errstr = "setresuid(ROOT_UID, SUDOERS_UID, ROOT_UID)";
@@ -475,20 +475,20 @@ set_perms(int perm)
/* assume euid == ROOT_UID, ruid == user */ /* assume euid == ROOT_UID, ruid == user */
state->rgid = -1; state->rgid = -1;
state->egid = SUDOERS_GID; state->egid = sudoers_gid;
if (setregid(-1, ID(egid))) if (setregid(-1, ID(egid)))
error(1, "unable to change to sudoers gid"); error(1, "unable to change to sudoers gid");
state->ruid = ROOT_UID; state->ruid = ROOT_UID;
/* /*
* If SUDOERS_UID == ROOT_UID and SUDOERS_MODE is group readable * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
* we use a non-zero uid in order to avoid NFS lossage. * we use a non-zero uid in order to avoid NFS lossage.
* Using uid 1 is a bit bogus but should work on all OS's. * Using uid 1 is a bit bogus but should work on all OS's.
*/ */
if (SUDOERS_UID == ROOT_UID && (SUDOERS_MODE & 040)) if (sudoers_uid == ROOT_UID && (sudoers_mode & 040))
state->euid = 1; state->euid = 1;
else else
state->euid = SUDOERS_UID; state->euid = sudoers_uid;
if (setreuid(ID(ruid), ID(euid))) { if (setreuid(ID(ruid), ID(euid))) {
errstr = "setreuid(ROOT_UID, SUDOERS_UID)"; errstr = "setreuid(ROOT_UID, SUDOERS_UID)";
goto bad; goto bad;
@@ -706,20 +706,20 @@ set_perms(int perm)
/* assume euid == ROOT_UID, ruid == user */ /* assume euid == ROOT_UID, ruid == user */
state->rgid = -1; state->rgid = -1;
state->egid = SUDOERS_GID; state->egid = sudoers_gid;
if (setegid(ID(egid))) if (setegid(ID(egid)))
error(1, "unable to change to sudoers gid"); error(1, "unable to change to sudoers gid");
state->ruid = ROOT_UID; state->ruid = ROOT_UID;
/* /*
* If SUDOERS_UID == ROOT_UID and SUDOERS_MODE is group readable * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
* we use a non-zero uid in order to avoid NFS lossage. * we use a non-zero uid in order to avoid NFS lossage.
* Using uid 1 is a bit bogus but should work on all OS's. * Using uid 1 is a bit bogus but should work on all OS's.
*/ */
if (SUDOERS_UID == ROOT_UID && (SUDOERS_MODE & 040)) if (sudoers_uid == ROOT_UID && (sudoers_mode & 040))
state->euid = 1; state->euid = 1;
else else
state->euid = SUDOERS_UID; state->euid = sudoers_uid;
if (seteuid(ID(euid))) { if (seteuid(ID(euid))) {
errstr = "seteuid(SUDOERS_UID)"; errstr = "seteuid(SUDOERS_UID)";
goto bad; goto bad;
@@ -803,7 +803,7 @@ bad:
/* /*
* Set uids and gids based on perm via setuid() and setgid(). * Set uids and gids based on perm via setuid() and setgid().
* NOTE: does not support the "stay_setuid" or timestampowner options. * NOTE: does not support the "stay_setuid" or timestampowner options.
* Also, SUDOERS_UID and SUDOERS_GID are not used. * Also, sudoers_uid and sudoers_gid are not used.
*/ */
int int
set_perms(int perm) set_perms(int perm)

View File

@@ -105,11 +105,13 @@ extern GETGROUPS_T *runas_groups;
/* /*
* Globals * Globals
*/ */
char *prev_user; const char *sudoers_file = _PATH_SUDOERS;
mode_t sudoers_mode = SUDOERS_MODE;
uid_t sudoers_uid = SUDOERS_UID;
gid_t sudoers_gid = SUDOERS_GID;
struct sudo_user sudo_user; struct sudo_user sudo_user;
struct passwd *list_pw; struct passwd *list_pw;
struct interface *interfaces; struct interface *interfaces;
static const char *interfaces_string;
int long_list; int long_list;
int debug_level; int debug_level;
uid_t timestamp_uid; uid_t timestamp_uid;
@@ -122,14 +124,16 @@ login_cap_t *lc;
#ifdef HAVE_BSD_AUTH_H #ifdef HAVE_BSD_AUTH_H
char *login_style; char *login_style;
#endif /* HAVE_BSD_AUTH_H */ #endif /* HAVE_BSD_AUTH_H */
sigaction_t saved_sa_int, saved_sa_quit, saved_sa_tstp;
sudo_conv_t sudo_conv; sudo_conv_t sudo_conv;
sudo_printf_t sudo_printf; sudo_printf_t sudo_printf;
int sudo_mode; int sudo_mode;
static char *prev_user;
static char *runas_user; static char *runas_user;
static char *runas_group; static char *runas_group;
static struct sudo_nss_list *snl; static struct sudo_nss_list *snl;
static const char *interfaces_string;
static sigaction_t saved_sa_int, saved_sa_quit, saved_sa_tstp;
/* XXX - must be extern for audit bits of sudo_auth.c */ /* XXX - must be extern for audit bits of sudo_auth.c */
int NewArgc; int NewArgc;
@@ -874,16 +878,16 @@ open_sudoers(const char *sudoers, int doedit, int *keepopen)
* Only works if file system is readable/writable by root. * Only works if file system is readable/writable by root.
*/ */
if ((rootstat = stat_sudoers(sudoers, &statbuf)) == 0 && if ((rootstat = stat_sudoers(sudoers, &statbuf)) == 0 &&
SUDOERS_UID == statbuf.st_uid && SUDOERS_MODE != 0400 && sudoers_uid == statbuf.st_uid && sudoers_mode != 0400 &&
(statbuf.st_mode & 0007777) == 0400) { (statbuf.st_mode & 0007777) == 0400) {
if (chmod(sudoers, SUDOERS_MODE) == 0) { if (chmod(sudoers, sudoers_mode) == 0) {
warningx("fixed mode on %s", sudoers); warningx("fixed mode on %s", sudoers);
SET(statbuf.st_mode, SUDOERS_MODE); SET(statbuf.st_mode, sudoers_mode);
if (statbuf.st_gid != SUDOERS_GID) { if (statbuf.st_gid != sudoers_gid) {
if (chown(sudoers, (uid_t) -1, SUDOERS_GID) == 0) { if (chown(sudoers, (uid_t) -1, sudoers_gid) == 0) {
warningx("set group on %s", sudoers); warningx("set group on %s", sudoers);
statbuf.st_gid = SUDOERS_GID; statbuf.st_gid = sudoers_gid;
} else } else
warning("unable to set group on %s", sudoers); warning("unable to set group on %s", sudoers);
} }
@@ -902,16 +906,16 @@ open_sudoers(const char *sudoers, int doedit, int *keepopen)
log_error(USE_ERRNO|NO_EXIT, "can't stat %s", sudoers); log_error(USE_ERRNO|NO_EXIT, "can't stat %s", sudoers);
else if (!S_ISREG(statbuf.st_mode)) else if (!S_ISREG(statbuf.st_mode))
log_error(NO_EXIT, "%s is not a regular file", sudoers); log_error(NO_EXIT, "%s is not a regular file", sudoers);
else if ((statbuf.st_mode & 07577) != SUDOERS_MODE) else if ((statbuf.st_mode & 07577) != sudoers_mode)
log_error(NO_EXIT, "%s is mode 0%o, should be 0%o", sudoers, log_error(NO_EXIT, "%s is mode 0%o, should be 0%o", sudoers,
(unsigned int) (statbuf.st_mode & 07777), (unsigned int) (statbuf.st_mode & 07777),
(unsigned int) SUDOERS_MODE); (unsigned int) sudoers_mode);
else if (statbuf.st_uid != SUDOERS_UID) else if (statbuf.st_uid != sudoers_uid)
log_error(NO_EXIT, "%s is owned by uid %u, should be %u", sudoers, log_error(NO_EXIT, "%s is owned by uid %u, should be %u", sudoers,
(unsigned int) statbuf.st_uid, (unsigned int) SUDOERS_UID); (unsigned int) statbuf.st_uid, (unsigned int) sudoers_uid);
else if (statbuf.st_gid != SUDOERS_GID) else if (statbuf.st_gid != sudoers_gid)
log_error(NO_EXIT, "%s is owned by gid %u, should be %u", sudoers, log_error(NO_EXIT, "%s is owned by gid %u, should be %u", sudoers,
(unsigned int) statbuf.st_gid, (unsigned int) SUDOERS_GID); (unsigned int) statbuf.st_gid, (unsigned int) sudoers_gid);
else if ((fp = fopen(sudoers, "r")) == NULL) else if ((fp = fopen(sudoers, "r")) == NULL)
log_error(USE_ERRNO|NO_EXIT, "can't open %s", sudoers); log_error(USE_ERRNO|NO_EXIT, "can't open %s", sudoers);
else { else {
@@ -1086,7 +1090,7 @@ sudoers_policy_version(int verbose)
PACKAGE_VERSION); PACKAGE_VERSION);
if (verbose) { if (verbose) {
sudo_printf(SUDO_CONV_INFO_MSG, "\nSudoers path: %s\n", _PATH_SUDOERS); sudo_printf(SUDO_CONV_INFO_MSG, "\nSudoers path: %s\n", sudoers_file);
#ifdef HAVE_LDAP #ifdef HAVE_LDAP
# ifdef _PATH_NSSWITCH_CONF # ifdef _PATH_NSSWITCH_CONF
sudo_printf(SUDO_CONV_INFO_MSG, "nsswitch path: %s\n", _PATH_NSSWITCH_CONF); sudo_printf(SUDO_CONV_INFO_MSG, "nsswitch path: %s\n", _PATH_NSSWITCH_CONF);
@@ -1205,6 +1209,23 @@ deserialize_info(char * const settings[], char * const user_info[])
set_interfaces(interfaces_string); set_interfaces(interfaces_string);
continue; continue;
} }
if (MATCHES(*cur, "sudoers_file=")) {
sudoers_file = *cur + sizeof("sudoers_file=") - 1;
continue;
}
if (MATCHES(*cur, "sudoers_uid=")) {
sudoers_uid = (uid_t) atoi(*cur + sizeof("sudoers_uid=") - 1);
continue;
}
if (MATCHES(*cur, "sudoers_gid=")) {
sudoers_gid = (gid_t) atoi(*cur + sizeof("sudoers_gid=") - 1);
continue;
}
if (MATCHES(*cur, "sudoers_mode=")) {
sudoers_mode = (mode_t) strtol(*cur + sizeof("sudoers_mode=") - 1,
NULL, 8);
continue;
}
} }
for (cur = user_info; *cur != NULL; cur++) { for (cur = user_info; *cur != NULL; cur++) {
@@ -1213,11 +1234,11 @@ deserialize_info(char * const settings[], char * const user_info[])
continue; continue;
} }
if (MATCHES(*cur, "uid=")) { if (MATCHES(*cur, "uid=")) {
user_uid = atoi(*cur + sizeof("uid=") - 1); user_uid = (uid_t) atoi(*cur + sizeof("uid=") - 1);
continue; continue;
} }
if (MATCHES(*cur, "gid=")) { if (MATCHES(*cur, "gid=")) {
user_gid = atoi(*cur + sizeof("gid=") - 1); user_gid = (gid_t) atoi(*cur + sizeof("gid=") - 1);
continue; continue;
} }
if (MATCHES(*cur, "groups=")) { if (MATCHES(*cur, "groups=")) {

View File

@@ -319,6 +319,10 @@ int group_plugin_query(const char *user, const char *group,
#ifndef _SUDO_MAIN #ifndef _SUDO_MAIN
extern struct sudo_user sudo_user; extern struct sudo_user sudo_user;
extern struct passwd *list_pw; extern struct passwd *list_pw;
extern const char *sudoers_file;
extern mode_t sudoers_mode;
extern uid_t sudoers_uid;
extern gid_t sudoers_gid;
extern int long_list; extern int long_list;
extern int sudo_mode; extern int sudo_mode;
extern uid_t timestamp_uid; extern uid_t timestamp_uid;