diff options
author | Pavel Březina <pbrezina@redhat.com> | 2016-05-26 11:37:30 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2016-07-07 10:30:26 +0200 |
commit | 61913b8f0d1ba54d82640500d7486fac5f72b030 (patch) | |
tree | 21ed1952b88d463468d690a22f40328e4bbf4d7c /src/db/sysdb_sudo.c | |
parent | 552390afcc81af96ca201fa6c25ddefbbecbeb4e (diff) | |
download | sssd-61913b8f0d1ba54d82640500d7486fac5f72b030.tar.gz sssd-61913b8f0d1ba54d82640500d7486fac5f72b030.tar.xz sssd-61913b8f0d1ba54d82640500d7486fac5f72b030.zip |
sudo: solve problems with fully qualified names
sudo expects the same name in sudo rule as login name. Therefore
if fully qualified name is used or even enforced by setting
use_fully_qualified_names to true or by forcing default domain
with default_domain_suffix sssd is able to correctly return the
rules but sudo can't match the user with contect of sudoUser
attribute since it is not qualified.
This patch changes the rules on the fly to avoid using names at all.
We do this in two steps:
1. We fetch all rules that match current user name, id or groups and
replace sudoUser attribute with sudoUser: #uid.
2. We fetch complementry rules that contain netgroups since it is
expected we don't have infromation about existing netgroups in
cache, sudo still needs to evaluate it for us if needed.
This patch also remove test for sysdb_get_sudo_filter since it wasn't
sufficient anyway and I did not rewrite it since I don't thing it
is a good thing to have filter tests that depends on exact filter
order.
Resolves:
https://fedorahosted.org/sssd/ticket/2919
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
Diffstat (limited to 'src/db/sysdb_sudo.c')
-rw-r--r-- | src/db/sysdb_sudo.c | 185 |
1 files changed, 118 insertions, 67 deletions
diff --git a/src/db/sysdb_sudo.c b/src/db/sysdb_sudo.c index 5f1a8a13e..601fb63f2 100644 --- a/src/db/sysdb_sudo.c +++ b/src/db/sysdb_sudo.c @@ -215,105 +215,156 @@ done: return ret; } -errno_t -sysdb_get_sudo_filter(TALLOC_CTX *mem_ctx, const char *username, - uid_t uid, char **groupnames, unsigned int flags, - char **_filter) +static char * +sysdb_sudo_filter_userinfo(TALLOC_CTX *mem_ctx, + const char *username, + char **groupnames, + uid_t uid) { - TALLOC_CTX *tmp_ctx = NULL; - char *filter = NULL; - char *specific_filter = NULL; - char *sanitized = NULL; - time_t now; + const char *attr = SYSDB_SUDO_CACHE_AT_USER; + TALLOC_CTX *tmp_ctx; + char *sanitized_name; + char *filter; errno_t ret; int i; tmp_ctx = talloc_new(NULL); - NULL_CHECK(tmp_ctx, ret, done); - - /* build specific filter */ + if (tmp_ctx == NULL) { + return NULL; + } - specific_filter = talloc_zero(tmp_ctx, char); /* assign to tmp_ctx */ - NULL_CHECK(specific_filter, ret, done); + filter = talloc_asprintf(tmp_ctx, "(%s=ALL)", attr); + if (filter == NULL) { + ret = ENOMEM; + goto done; + } - if (flags & SYSDB_SUDO_FILTER_INCLUDE_ALL) { - specific_filter = talloc_asprintf_append(specific_filter, "(%s=ALL)", - SYSDB_SUDO_CACHE_AT_USER); - NULL_CHECK(specific_filter, ret, done); + ret = sss_filter_sanitize(tmp_ctx, username, &sanitized_name); + if (ret != EOK) { + goto done; } - if (flags & SYSDB_SUDO_FILTER_INCLUDE_DFL) { - specific_filter = talloc_asprintf_append(specific_filter, "(%s=defaults)", - SYSDB_NAME); - NULL_CHECK(specific_filter, ret, done); + filter = talloc_asprintf_append(filter, "(%s=%s)", attr, sanitized_name); + if (filter == NULL) { + ret = ENOMEM; + goto done; } - if ((flags & SYSDB_SUDO_FILTER_USERNAME) && (username != NULL)) { - ret = sss_filter_sanitize(tmp_ctx, username, &sanitized); - if (ret != EOK) { + if (uid != 0) { + filter = talloc_asprintf_append(filter, "(%s=#%"SPRIuid")", attr, uid); + if (filter == NULL) { + ret = ENOMEM; goto done; } - - specific_filter = talloc_asprintf_append(specific_filter, "(%s=%s)", - SYSDB_SUDO_CACHE_AT_USER, - sanitized); - NULL_CHECK(specific_filter, ret, done); - } - - if ((flags & SYSDB_SUDO_FILTER_UID) && (uid != 0)) { - specific_filter = talloc_asprintf_append(specific_filter, "(%s=#%llu)", - SYSDB_SUDO_CACHE_AT_USER, - (unsigned long long) uid); - NULL_CHECK(specific_filter, ret, done); } - if ((flags & SYSDB_SUDO_FILTER_GROUPS) && (groupnames != NULL)) { + if (groupnames != NULL) { for (i=0; groupnames[i] != NULL; i++) { - ret = sss_filter_sanitize(tmp_ctx, groupnames[i], &sanitized); + ret = sss_filter_sanitize(tmp_ctx, groupnames[i], &sanitized_name); if (ret != EOK) { goto done; } - specific_filter = talloc_asprintf_append(specific_filter, "(%s=%%%s)", - SYSDB_SUDO_CACHE_AT_USER, - sanitized); - NULL_CHECK(specific_filter, ret, done); + filter = talloc_asprintf_append(filter, "(%s=%%%s)", attr, + sanitized_name); + if (filter == NULL) { + ret = ENOMEM; + goto done; + } } } - if (flags & SYSDB_SUDO_FILTER_NGRS) { - specific_filter = talloc_asprintf_append(specific_filter, "(%s=+*)", - SYSDB_SUDO_CACHE_AT_USER); - NULL_CHECK(specific_filter, ret, done); + talloc_steal(mem_ctx, filter); + +done: + talloc_free(tmp_ctx); + + if (ret != EOK) { + return NULL; } - /* build global filter */ + return filter; +} - filter = talloc_asprintf(tmp_ctx, "(&(%s=%s)", - SYSDB_OBJECTCLASS, SYSDB_SUDO_CACHE_OC); - NULL_CHECK(filter, ret, done); +char * +sysdb_sudo_filter_expired(TALLOC_CTX *mem_ctx, + const char *username, + char **groupnames, + uid_t uid) +{ + char *userfilter; + char *filter; + time_t now; - if (specific_filter[0] != '\0') { - filter = talloc_asprintf_append(filter, "(|%s)", specific_filter); - NULL_CHECK(filter, ret, done); + userfilter = sysdb_sudo_filter_userinfo(mem_ctx, username, groupnames, uid); + if (userfilter == NULL) { + return NULL; } - if (flags & SYSDB_SUDO_FILTER_ONLY_EXPIRED) { - now = time(NULL); - filter = talloc_asprintf_append(filter, "(&(%s<=%lld))", - SYSDB_CACHE_EXPIRE, (long long)now); - NULL_CHECK(filter, ret, done); + now = time(NULL); + filter = talloc_asprintf(mem_ctx, + "(&(%s=%s)(%s<=%lld)(|(%s=defaults)%s(%s=+*)))", + SYSDB_OBJECTCLASS, SYSDB_SUDO_CACHE_OC, + SYSDB_CACHE_EXPIRE, (long long)now, + SYSDB_NAME, + userfilter, + SYSDB_SUDO_CACHE_AT_USER); + talloc_free(userfilter); + + return filter; +} + +char * +sysdb_sudo_filter_defaults(TALLOC_CTX *mem_ctx) +{ + return talloc_asprintf(mem_ctx, "(&(%s=%s)(%s=defaults))", + SYSDB_OBJECTCLASS, SYSDB_SUDO_CACHE_OC, + SYSDB_NAME); +} + +char * +sysdb_sudo_filter_user(TALLOC_CTX *mem_ctx, + const char *username, + char **groupnames, + uid_t uid) +{ + char *userfilter; + char *filter; + + userfilter = sysdb_sudo_filter_userinfo(mem_ctx, username, groupnames, uid); + if (userfilter == NULL) { + return NULL; } - filter = talloc_strdup_append(filter, ")"); - NULL_CHECK(filter, ret, done); + filter = talloc_asprintf(mem_ctx, "(&(%s=%s)(|%s))", + SYSDB_OBJECTCLASS, SYSDB_SUDO_CACHE_OC, + userfilter); + talloc_free(userfilter); - ret = EOK; - *_filter = talloc_steal(mem_ctx, filter); + return filter; +} -done: - talloc_free(tmp_ctx); - return ret; +char * +sysdb_sudo_filter_netgroups(TALLOC_CTX *mem_ctx, + const char *username, + char **groupnames, + uid_t uid) +{ + char *userfilter; + char *filter; + + userfilter = sysdb_sudo_filter_userinfo(mem_ctx, username, groupnames, uid); + if (userfilter == NULL) { + return NULL; + } + + filter = talloc_asprintf(mem_ctx, "(&(%s=%s)(%s=+*)(!(|%s)))", + SYSDB_OBJECTCLASS, SYSDB_SUDO_CACHE_OC, + SYSDB_SUDO_CACHE_AT_USER, + userfilter); + talloc_free(userfilter); + + return filter; } errno_t @@ -985,4 +1036,4 @@ sysdb_set_sudo_rule_attr(struct sss_domain_info *domain, done: talloc_free(tmp_ctx); return ret; -}
\ No newline at end of file +} |