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:
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
@@ -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",
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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)
|
||||||
|
@@ -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=")) {
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user