From 0a68d6799eab3a4c3b73e5bfff4c87c320cfb83e Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Mon, 19 Sep 2016 06:19:49 -0600 Subject: [PATCH] Fix matching when no sudoRunAsUser is present in a sudoRole. If only a sudoRunAsGroup is present, match on the invoking user if the -g option was specified and the group matched. If no sudoRunAsGroup is present and the -g option was specified, allow it if it matches the passwd gid of the runas user. This matches the behavior of the sudoers backend. --- plugins/sudoers/ldap.c | 45 ++++++++++++++++++++++++++++-------------- plugins/sudoers/sssd.c | 44 +++++++++++++++++++++++++++-------------- 2 files changed, 59 insertions(+), 30 deletions(-) diff --git a/plugins/sudoers/ldap.c b/plugins/sudoers/ldap.c index 03a31f5ae..20c5605df 100644 --- a/plugins/sudoers/ldap.c +++ b/plugins/sudoers/ldap.c @@ -757,7 +757,7 @@ sudo_ldap_check_host(LDAP *ld, LDAPMessage *entry, struct passwd *pw) } static int -sudo_ldap_check_runas_user(LDAP *ld, LDAPMessage *entry) +sudo_ldap_check_runas_user(LDAP *ld, LDAPMessage *entry, int group_matched) { struct berval **bv, **p; char *val; @@ -768,8 +768,28 @@ sudo_ldap_check_runas_user(LDAP *ld, LDAPMessage *entry) bv = ldap_get_values_len(ld, entry, "sudoRunAsUser"); if (bv == NULL) bv = ldap_get_values_len(ld, entry, "sudoRunAs"); /* old style */ - if (bv == NULL) - debug_return_int(false); + if (bv == NULL) { + if (!ISSET(sudo_user.flags, RUNAS_USER_SPECIFIED)) + debug_return_int(UNSPEC); + switch (group_matched) { + case UNSPEC: + /* + * No runas user or group entries. Match runas_default + * against what the user specified on the command line. + */ + ret = userpw_matches(def_runas_default, runas_pw->pw_name, runas_pw); + break; + case true: + /* + * No runas user entries but have a matching runas group entry. + * If trying to run as the invoking user, allow it. + */ + if (strcmp(user_name, runas_pw->pw_name) == 0) + ret = true; + break; + } + debug_return_int(ret); + } /* * BUG: @@ -830,8 +850,13 @@ sudo_ldap_check_runas_group(LDAP *ld, LDAPMessage *entry) /* get the values from the entry */ bv = ldap_get_values_len(ld, entry, "sudoRunAsGroup"); - if (bv == NULL) + if (bv == NULL) { + if (!ISSET(sudo_user.flags, RUNAS_USER_SPECIFIED)) { + if (runas_pw->pw_gid == runas_gr->gr_gid) + ret = true; /* runas group matches passwd db */ + } debug_return_int(ret); + } /* walk through values returned, looking for a match */ for (p = bv; *p != NULL && !ret; p++) { @@ -861,19 +886,9 @@ sudo_ldap_check_runas(LDAP *ld, LDAPMessage *entry) if (!entry) debug_return_bool(false); - if (ISSET(sudo_user.flags, RUNAS_USER_SPECIFIED) || !ISSET(sudo_user.flags, RUNAS_GROUP_SPECIFIED)) - user_matched = sudo_ldap_check_runas_user(ld, entry); if (ISSET(sudo_user.flags, RUNAS_GROUP_SPECIFIED)) group_matched = sudo_ldap_check_runas_group(ld, entry); - - /* - * If there are no runas entries, match runas_default against - * what the user specified on the command line. - */ - if (user_matched == UNSPEC && group_matched == UNSPEC) { - debug_return_int(userpw_matches(def_runas_default, runas_pw->pw_name, - runas_pw)); - } + user_matched = sudo_ldap_check_runas_user(ld, entry, group_matched); debug_return_bool(group_matched != false && user_matched != false); } diff --git a/plugins/sudoers/sssd.c b/plugins/sudoers/sssd.c index f77f2c3e1..bb2f139da 100644 --- a/plugins/sudoers/sssd.c +++ b/plugins/sudoers/sssd.c @@ -561,7 +561,7 @@ sudo_sss_checkpw(struct sudo_nss *nss, struct passwd *pw) } static int -sudo_sss_check_runas_user(struct sudo_sss_handle *handle, struct sss_sudo_rule *sss_rule) +sudo_sss_check_runas_user(struct sudo_sss_handle *handle, struct sss_sudo_rule *sss_rule, int group_matched) { char **val_array = NULL; char *val; @@ -580,7 +580,28 @@ sudo_sss_check_runas_user(struct sudo_sss_handle *handle, struct sss_sudo_rule * break; case ENOENT: sudo_debug_printf(SUDO_DEBUG_INFO, "sudoRunAsUser: no result."); - debug_return_int(false); + if (!ISSET(sudo_user.flags, RUNAS_USER_SPECIFIED)) + debug_return_int(UNSPEC); + switch (group_matched) { + case UNSPEC: + /* + * No runas user or group entries. Match runas_default + * against what the user specified on the command line. + */ + sudo_debug_printf(SUDO_DEBUG_INFO, "Matching against runas_default"); + ret = userpw_matches(def_runas_default, runas_pw->pw_name, runas_pw); + break; + case true: + /* + * No runas user entries but have a matching runas group entry. + * If trying to run as the invoking user, allow it. + */ + sudo_debug_printf(SUDO_DEBUG_INFO, "Matching against user_name"); + if (strcmp(user_name, runas_pw->pw_name) == 0) + ret = true; + break; + } + debug_return_int(ret); default: sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values(sudoRunAsUser): %d", i); @@ -667,7 +688,11 @@ sudo_sss_check_runas_group(struct sudo_sss_handle *handle, struct sss_sudo_rule break; case ENOENT: sudo_debug_printf(SUDO_DEBUG_INFO, "sudoRunAsGroup: no result."); - debug_return_int(false); + if (!ISSET(sudo_user.flags, RUNAS_USER_SPECIFIED)) { + if (runas_pw->pw_gid == runas_gr->gr_gid) + ret = true; /* runas group matches passwd db */ + } + debug_return_int(ret); default: sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values(sudoRunAsGroup): %d", i); @@ -705,20 +730,9 @@ sudo_sss_check_runas(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule) if (rule == NULL) debug_return_bool(false); - if (ISSET(sudo_user.flags, RUNAS_USER_SPECIFIED) || !ISSET(sudo_user.flags, RUNAS_GROUP_SPECIFIED)) - user_matched = sudo_sss_check_runas_user(handle, rule); if (ISSET(sudo_user.flags, RUNAS_GROUP_SPECIFIED)) group_matched = sudo_sss_check_runas_group(handle, rule); - - /* - * If there are no runas entries, match runas_default against - * what the user specified on the command line. - */ - if (user_matched == UNSPEC && group_matched == UNSPEC) { - sudo_debug_printf(SUDO_DEBUG_INFO, "Matching against runas_default"); - debug_return_int(userpw_matches(def_runas_default, runas_pw->pw_name, - runas_pw)); - } + user_matched = sudo_sss_check_runas_user(handle, rule, group_matched); debug_return_bool(group_matched != false && user_matched != false); } -- 2.40.0