Add support for runchroot and runcwd to "sudo -l" and cvtsudoers.

This commit is contained in:
Todd C. Miller
2020-09-01 06:26:05 -06:00
parent 86513c78b6
commit 9ff960457a
13 changed files with 195 additions and 18 deletions

View File

@@ -776,6 +776,13 @@ plugins/sudoers/regress/sudoers/test23.ldif2sudo.ok
plugins/sudoers/regress/sudoers/test23.out.ok
plugins/sudoers/regress/sudoers/test23.sudo.ok
plugins/sudoers/regress/sudoers/test23.toke.ok
plugins/sudoers/regress/sudoers/test24.in
plugins/sudoers/regress/sudoers/test24.json.ok
plugins/sudoers/regress/sudoers/test24.ldif.ok
plugins/sudoers/regress/sudoers/test24.ldif2sudo.ok
plugins/sudoers/regress/sudoers/test24.out.ok
plugins/sudoers/regress/sudoers/test24.sudo.ok
plugins/sudoers/regress/sudoers/test24.toke.ok
plugins/sudoers/regress/sudoers/test3.in
plugins/sudoers/regress/sudoers/test3.json.ok
plugins/sudoers/regress/sudoers/test3.ldif.ok

View File

@@ -579,7 +579,7 @@ cmndspec_continues(struct cmndspec *cs, struct cmndspec *next)
#ifdef HAVE_SELINUX
&& cs->role == next->role && cs->type == next->type
#endif /* HAVE_SELINUX */
;
&& cs->runchroot == next->runchroot && cs->runcwd == next->runcwd;
return ret;
}
@@ -626,10 +626,21 @@ print_cmndspec_json(struct json_container *json,
/* Print options and tags */
if (cs->timeout > 0 || cs->notbefore != UNSPEC || cs->notafter != UNSPEC ||
TAGS_SET(cs->tags) || !TAILQ_EMPTY(options)) {
cs->runchroot != NULL || cs->runcwd != NULL || TAGS_SET(cs->tags) ||
!TAILQ_EMPTY(options)) {
struct cmndtag tag = cs->tags;
sudo_json_open_array(json, "Options");
if (cs->runchroot != NULL) {
value.type = JSON_STRING;
value.u.string = cs->runchroot;
sudo_json_add_value(json, "runchroot", &value);
}
if (cs->runcwd != NULL) {
value.type = JSON_STRING;
value.u.string = cs->runcwd;
sudo_json_add_value(json, "runcwd", &value);
}
if (cs->timeout > 0) {
value.type = JSON_NUMBER;
value.u.number = cs->timeout;

View File

@@ -319,6 +319,7 @@ print_cmndspec_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree,
struct cmndspec *next = *nextp;
struct member *m;
struct tm *tp;
char *attr_val;
bool last_one;
char timebuf[sizeof("20120727121554Z")];
debug_decl(print_cmndspec_ldif, SUDOERS_DEBUG_UTIL);
@@ -365,7 +366,6 @@ print_cmndspec_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree,
/* Print timeout as a sudoOption. */
if (cs->timeout > 0) {
char *attr_val;
if (asprintf(&attr_val, "command_timeout=%d", cs->timeout) == -1) {
sudo_fatalx(U_("%s: %s"), __func__,
U_("unable to allocate memory"));
@@ -414,22 +414,35 @@ print_cmndspec_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree,
}
print_options_ldif(fp, options);
/* Print runchroot and runcwd. */
if (cs->runchroot != NULL) {
if (asprintf(&attr_val, "runchroot=%s", cs->runchroot) == -1) {
sudo_fatalx(U_("%s: %s"), __func__,
U_("unable to allocate memory"));
}
print_attribute_ldif(fp, "sudoOption", attr_val);
free(attr_val);
}
if (cs->runcwd != NULL) {
if (asprintf(&attr_val, "runcwd=%s", cs->runcwd) == -1) {
sudo_fatalx(U_("%s: %s"), __func__,
U_("unable to allocate memory"));
}
print_attribute_ldif(fp, "sudoOption", attr_val);
free(attr_val);
}
#ifdef HAVE_SELINUX
/* Print SELinux role/type */
if (cs->role != NULL && cs->type != NULL) {
char *attr_val;
int len;
len = asprintf(&attr_val, "role=%s", cs->role);
if (len == -1) {
if (asprintf(&attr_val, "role=%s", cs->role) == -1) {
sudo_fatalx(U_("%s: %s"), __func__,
U_("unable to allocate memory"));
}
print_attribute_ldif(fp, "sudoOption", attr_val);
free(attr_val);
len = asprintf(&attr_val, "type=%s", cs->type);
if (len == -1) {
if (asprintf(&attr_val, "type=%s", cs->type) == -1) {
sudo_fatalx(U_("%s: %s"), __func__,
U_("unable to allocate memory"));
}
@@ -441,12 +454,8 @@ print_cmndspec_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree,
#ifdef HAVE_PRIV_SET
/* Print Solaris privs/limitprivs */
if (cs->privs != NULL || cs->limitprivs != NULL) {
char *attr_val;
int len;
if (cs->privs != NULL) {
len = asprintf(&attr_val, "privs=%s", cs->privs);
if (len == -1) {
if (asprintf(&attr_val, "privs=%s", cs->privs) == -1) {
sudo_fatalx(U_("%s: %s"), __func__,
U_("unable to allocate memory"));
}
@@ -454,8 +463,7 @@ print_cmndspec_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree,
free(attr_val);
}
if (cs->limitprivs != NULL) {
len = asprintf(&attr_val, "limitprivs=%s", cs->limitprivs);
if (len == -1) {
if (asprintf(&attr_val, "limitprivs=%s", cs->limitprivs) == -1) {
sudo_fatalx(U_("%s: %s"), __func__,
U_("unable to allocate memory"));
}
@@ -481,7 +489,7 @@ print_cmndspec_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree,
#ifdef HAVE_SELINUX
|| cs->role != next->role || cs->type != next->type
#endif /* HAVE_SELINUX */
;
|| cs->runchroot != next->runchroot || cs->runcwd != next->runcwd;
print_member_ldif(fp, parse_tree, cs->cmnd->name, cs->cmnd->type,
cs->cmnd->negated, CMNDALIAS, "sudoCommand");

View File

@@ -228,6 +228,10 @@ sudoers_format_cmndspec(struct sudo_lbuf *lbuf,
if (cs->type != NULL && FIELD_CHANGED(prev_cs, cs, type))
sudo_lbuf_append(lbuf, "TYPE=%s ", cs->type);
#endif /* HAVE_SELINUX */
if (cs->runchroot != NULL && FIELD_CHANGED(prev_cs, cs, runchroot))
sudo_lbuf_append(lbuf, "CHROOT=%s ", cs->runchroot);
if (cs->runcwd != NULL && FIELD_CHANGED(prev_cs, cs, runcwd))
sudo_lbuf_append(lbuf, "CWD=%s ", cs->runcwd);
if (cs->timeout > 0 && FIELD_CHANGED(prev_cs, cs, timeout)) {
char numbuf[(((sizeof(int) * 8) + 2) / 3) + 2];
(void)snprintf(numbuf, sizeof(numbuf), "%d", cs->timeout);

View File

@@ -516,6 +516,12 @@ sudo_ldap_role_to_priv(const char *cn, void *hosts, void *runasusers,
op = sudo_ldap_parse_option(opt, &var, &val);
if (strcmp(var, "command_timeout") == 0 && val != NULL) {
cmndspec->timeout = parse_timeout(val);
} else if (strcmp(var, "runchroot") == 0 && val != NULL) {
if ((cmndspec->runchroot = strdup(val)) == NULL)
break;
} else if (strcmp(var, "runcwd") == 0 && val != NULL) {
if ((cmndspec->runcwd = strdup(val)) == NULL)
break;
#ifdef HAVE_SELINUX
} else if (strcmp(var, "role") == 0 && val != NULL) {
if ((cmndspec->role = strdup(val)) == NULL)

View File

@@ -426,6 +426,10 @@ new_long_entry(struct cmndspec *cs, struct cmndspec *prev_cs)
if (cs->type && (!prev_cs->type || strcmp(cs->type, prev_cs->type) != 0))
debug_return_bool(true);
#endif /* HAVE_SELINUX */
if (cs->runchroot && (!prev_cs->runchroot || strcmp(cs->runchroot, prev_cs->runchroot) != 0))
debug_return_bool(true);
if (cs->runcwd && (!prev_cs->runcwd || strcmp(cs->runcwd, prev_cs->runcwd) != 0))
debug_return_bool(true);
if (cs->timeout != prev_cs->timeout)
debug_return_bool(true);
if (cs->notbefore != prev_cs->notbefore)
@@ -520,6 +524,10 @@ display_priv_long(struct sudoers_parse_tree *parse_tree, struct passwd *pw,
if (cs->type)
sudo_lbuf_append(lbuf, " Type: %s\n", cs->type);
#endif /* HAVE_SELINUX */
if (cs->runchroot != NULL)
sudo_lbuf_append(lbuf, " Chroot: %s\n", cs->runchroot);
if (cs->runcwd != NULL)
sudo_lbuf_append(lbuf, " Cwd: %s\n", cs->runcwd);
if (cs->timeout > 0) {
char numbuf[(((sizeof(int) * 8) + 2) / 3) + 2];
(void)snprintf(numbuf, sizeof(numbuf), "%d", cs->timeout);

View File

@@ -0,0 +1,6 @@
# Test parsing of CHROOT and CWD syntax
Defaults runcwd=~
Defaults runchroot=/
#
user0 ALL = CHROOT=/var/www CWD=/htdocs /bin/ksh
user1 ALL = CWD=~root /usr/bin/id, CWD=/tmp /bin/ls

View File

@@ -0,0 +1,61 @@
{
"Defaults": [
{
"Options": [
{ "runcwd": "~" }
]
},
{
"Options": [
{ "runchroot": "/" }
]
}
],
"User_Specs": [
{
"User_List": [
{ "username": "user0" }
],
"Host_List": [
{ "hostname": "ALL" }
],
"Cmnd_Specs": [
{
"Options": [
"runchroot": "/var/www",
"runcwd": "/htdocs"
],
"Commands": [
{ "command": "/bin/ksh" }
]
}
]
},
{
"User_List": [
{ "username": "user1" }
],
"Host_List": [
{ "hostname": "ALL" }
],
"Cmnd_Specs": [
{
"Options": [
"runcwd": "~root"
],
"Commands": [
{ "command": "/usr/bin/id" }
]
},
{
"Options": [
"runcwd": "/tmp"
],
"Commands": [
{ "command": "/bin/ls" }
]
}
]
}
]
}

View File

@@ -0,0 +1,39 @@
dn: cn=defaults,ou=SUDOers,dc=sudo,dc=ws
objectClass: top
objectClass: sudoRole
cn: defaults
description: Default sudoOption's go here
sudoOption: runcwd=~
sudoOption: runchroot=/
dn: cn=user0,ou=SUDOers,dc=sudo,dc=ws
objectClass: top
objectClass: sudoRole
cn: user0
sudoUser: user0
sudoHost: ALL
sudoOption: runchroot=/var/www
sudoOption: runcwd=/htdocs
sudoCommand: /bin/ksh
sudoOrder: 1
dn: cn=user1,ou=SUDOers,dc=sudo,dc=ws
objectClass: top
objectClass: sudoRole
cn: user1
sudoUser: user1
sudoHost: ALL
sudoOption: runcwd=~root
sudoCommand: /usr/bin/id
sudoOrder: 2
dn: cn=user1_1,ou=SUDOers,dc=sudo,dc=ws
objectClass: top
objectClass: sudoRole
cn: user1_1
sudoUser: user1
sudoHost: ALL
sudoOption: runcwd=/tmp
sudoCommand: /bin/ls
sudoOrder: 3

View File

@@ -0,0 +1,8 @@
Defaults runcwd=~
Defaults runchroot=/
# sudoRole user0
user0 ALL = CHROOT=/var/www CWD=/htdocs /bin/ksh
# sudoRole user1, user1_1
user1 ALL = CWD=~root /usr/bin/id, CWD=/tmp /bin/ls

View File

@@ -0,0 +1,7 @@
Parses OK
Defaults runcwd=~
Defaults runchroot=/
user0 ALL = CHROOT=/var/www CWD=/htdocs /bin/ksh
user1 ALL = CWD=~root /usr/bin/id, CWD=/tmp /bin/ls

View File

@@ -0,0 +1,6 @@
Defaults runcwd=~
Defaults runchroot=/
user0 ALL = CHROOT=/var/www CWD=/htdocs /bin/ksh
user1 ALL = CWD=~root /usr/bin/id, CWD=/tmp /bin/ls

View File

@@ -0,0 +1,6 @@
#
DEFAULTS DEFVAR = WORD(2)
DEFAULTS DEFVAR = WORD(2)
#
WORD(6) ALL = CHROOT = WORD(5) CWD = WORD(5) COMMAND
WORD(6) ALL = CWD = WORD(5) COMMAND , CWD = WORD(5) COMMAND