From 3d023a3d0495dbcb882688d956c42500993824b2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 26 May 2016 11:37:30 +0200
Subject: [PATCH] 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
---
 src/db/sysdb_sudo.c                        | 199 ++++++++++++--------
 src/db/sysdb_sudo.h                        |  21 +++
 src/responder/sudo/sudosrv_get_sudorules.c | 293 +++++++++++++++++++++++------
 src/tests/cmocka/test_sysdb_sudo.c         |  73 ++-----
 4 files changed, 397 insertions(+), 189 deletions(-)

diff --git a/src/db/sysdb_sudo.c b/src/db/sysdb_sudo.c
index 5f1a8a13eda0ad3ae93192c84b954a69bf735b2f..601fb63f236a7ed9eede130fd8cf4c3a1559fc4b 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);
-    }
-
-    /* build global filter */
-
-    filter = talloc_asprintf(tmp_ctx, "(&(%s=%s)",
-                             SYSDB_OBJECTCLASS, SYSDB_SUDO_CACHE_OC);
-    NULL_CHECK(filter, ret, done);
-
-    if (specific_filter[0] != '\0') {
-        filter = talloc_asprintf_append(filter, "(|%s)", specific_filter);
-        NULL_CHECK(filter, ret, done);
-    }
-
-    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);
-    }
-
-    filter = talloc_strdup_append(filter, ")");
-    NULL_CHECK(filter, ret, done);
-
-    ret = EOK;
-    *_filter = talloc_steal(mem_ctx, filter);
+    talloc_steal(mem_ctx, filter);
 
 done:
     talloc_free(tmp_ctx);
-    return ret;
+
+    if (ret != EOK) {
+        return NULL;
+    }
+
+    return filter;
+}
+
+char *
+sysdb_sudo_filter_expired(TALLOC_CTX *mem_ctx,
+                          const char *username,
+                          char **groupnames,
+                          uid_t uid)
+{
+    char *userfilter;
+    char *filter;
+    time_t now;
+
+    userfilter = sysdb_sudo_filter_userinfo(mem_ctx, username, groupnames, uid);
+    if (userfilter == NULL) {
+        return NULL;
+    }
+
+    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_asprintf(mem_ctx, "(&(%s=%s)(|%s))",
+                             SYSDB_OBJECTCLASS, SYSDB_SUDO_CACHE_OC,
+                             userfilter);
+    talloc_free(userfilter);
+
+    return filter;
+}
+
+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
+}
diff --git a/src/db/sysdb_sudo.h b/src/db/sysdb_sudo.h
index c9dadb799cf5cd5e92f9c2be784d546beab81c47..9c2456cf89dde6c5f1e047e0a6ade981e0a875d8 100644
--- a/src/db/sysdb_sudo.h
+++ b/src/db/sysdb_sudo.h
@@ -96,6 +96,27 @@ errno_t sysdb_sudo_filter_rules_by_time(TALLOC_CTX *mem_ctx,
                                         uint32_t *_num_rules,
                                         struct sysdb_attrs ***_rules);
 
+char *
+sysdb_sudo_filter_expired(TALLOC_CTX *mem_ctx,
+                          const char *username,
+                          char **groupnames,
+                          uid_t uid);
+
+char *
+sysdb_sudo_filter_defaults(TALLOC_CTX *mem_ctx);
+
+char *
+sysdb_sudo_filter_user(TALLOC_CTX *mem_ctx,
+                       const char *username,
+                       char **groupnames,
+                       uid_t uid);
+
+char *
+sysdb_sudo_filter_netgroups(TALLOC_CTX *mem_ctx,
+                            const char *username,
+                            char **groupnames,
+                            uid_t uid);
+
 errno_t
 sysdb_get_sudo_filter(TALLOC_CTX *mem_ctx, const char *username,
                       uid_t uid, char **groupnames, unsigned int flags,
diff --git a/src/responder/sudo/sudosrv_get_sudorules.c b/src/responder/sudo/sudosrv_get_sudorules.c
index 9095d77ba022ce0f4c6c830ca142a2cdebce8670..120b6ef3da8e7e817c0eb5d29c0e6f0e7049ff49 100644
--- a/src/responder/sudo/sudosrv_get_sudorules.c
+++ b/src/responder/sudo/sudosrv_get_sudorules.c
@@ -116,16 +116,11 @@ sort_sudo_rules(struct sysdb_attrs **rules, size_t count, bool lower_wins)
 static errno_t sudosrv_query_cache(TALLOC_CTX *mem_ctx,
                                    struct sss_domain_info *domain,
                                    const char **attrs,
-                                   unsigned int flags,
-                                   const char *username,
-                                   uid_t uid,
-                                   char **groupnames,
-                                   bool inverse_order,
+                                   const char *filter,
                                    struct sysdb_attrs ***_rules,
                                    uint32_t *_count)
 {
     TALLOC_CTX *tmp_ctx;
-    char *filter;
     errno_t ret;
     size_t count;
     struct sysdb_attrs **rules;
@@ -136,14 +131,6 @@ static errno_t sudosrv_query_cache(TALLOC_CTX *mem_ctx,
         return ENOMEM;
     }
 
-    ret = sysdb_get_sudo_filter(tmp_ctx, username, uid, groupnames,
-                                flags, &filter);
-    if (ret != EOK) {
-        DEBUG(SSSDBG_CRIT_FAILURE, "Could not construct the search filter "
-              "[%d]: %s\n", ret, sss_strerror(ret));
-        goto done;
-    }
-
     DEBUG(SSSDBG_FUNC_DATA, "Searching sysdb with [%s]\n", filter);
 
     if (IS_SUBDOMAIN(domain)) {
@@ -170,12 +157,6 @@ static errno_t sudosrv_query_cache(TALLOC_CTX *mem_ctx,
         goto done;
     }
 
-    ret = sort_sudo_rules(rules, count, inverse_order);
-    if (ret != EOK) {
-        DEBUG(SSSDBG_OP_FAILURE, "Could not sort rules by sudoOrder\n");
-        goto done;
-    }
-
     *_rules = talloc_steal(mem_ctx, rules);
     *_count = (uint32_t)count;
 
@@ -194,24 +175,131 @@ static errno_t sudosrv_expired_rules(TALLOC_CTX *mem_ctx,
                                      struct sysdb_attrs ***_rules,
                                      uint32_t *_num_rules)
 {
-    unsigned int flags = SYSDB_SUDO_FILTER_NONE;
     const char *attrs[] = { SYSDB_NAME, NULL };
+    char *filter;
     errno_t ret;
 
-    flags =   SYSDB_SUDO_FILTER_INCLUDE_ALL
-            | SYSDB_SUDO_FILTER_INCLUDE_DFL
-            | SYSDB_SUDO_FILTER_ONLY_EXPIRED
-            | SYSDB_SUDO_FILTER_USERINFO;
+    filter = sysdb_sudo_filter_expired(NULL, username, groups, uid);
+    if (filter == NULL) {
+        return ENOMEM;
+    }
 
-    ret = sudosrv_query_cache(mem_ctx, domain, attrs, flags,
-                              username, uid, groups, false,
+    ret = sudosrv_query_cache(mem_ctx, domain, attrs, filter,
                               _rules, _num_rules);
+    talloc_free(filter);
+
+    return ret;
+}
+
+static errno_t sudosrv_cached_rules_by_user(TALLOC_CTX *mem_ctx,
+                                            struct sss_domain_info *domain,
+                                            uid_t uid,
+                                            const char *username,
+                                            char **groupnames,
+                                            struct sysdb_attrs ***_rules,
+                                            uint32_t *_num_rules)
+{
+    TALLOC_CTX *tmp_ctx;
+    struct sysdb_attrs **rules;
+    uint32_t num_rules;
+    uint32_t i;
+    const char *filter;
+    const char *val;
+    errno_t ret;
+    const char *attrs[] = { SYSDB_OBJECTCLASS,
+                            SYSDB_SUDO_CACHE_AT_CN,
+                            SYSDB_SUDO_CACHE_AT_HOST,
+                            SYSDB_SUDO_CACHE_AT_COMMAND,
+                            SYSDB_SUDO_CACHE_AT_OPTION,
+                            SYSDB_SUDO_CACHE_AT_RUNAS,
+                            SYSDB_SUDO_CACHE_AT_RUNASUSER,
+                            SYSDB_SUDO_CACHE_AT_RUNASGROUP,
+                            SYSDB_SUDO_CACHE_AT_NOTBEFORE,
+                            SYSDB_SUDO_CACHE_AT_NOTAFTER,
+                            SYSDB_SUDO_CACHE_AT_ORDER,
+                            NULL };
+
+    tmp_ctx = talloc_new(NULL);
+    if (tmp_ctx == NULL) {
+        return ENOMEM;
+    }
+
+    filter = sysdb_sudo_filter_user(tmp_ctx, username, groupnames, uid);
+    if (filter == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    ret = sudosrv_query_cache(tmp_ctx, domain, attrs, filter,
+                              &rules, &num_rules);
+    if (ret != EOK) {
+        goto done;
+    }
+
+    val = talloc_asprintf(tmp_ctx, "#%"SPRIuid, uid);
+    if (val == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    /* Add sudoUser: #uid to prevent conflicts with fqnames. */
+    DEBUG(SSSDBG_TRACE_FUNC, "Replacing sudoUser attribute with "
+          "sudoUser: %s\n", val);
+    for (i = 0; i < num_rules; i++) {
+        ret = sysdb_attrs_add_string(rules[i], SYSDB_SUDO_CACHE_AT_USER, val);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_CRIT_FAILURE, "Unable to alter sudoUser attribute "
+                  "[%d]: %s\n", ret, sss_strerror(ret));
+        }
+    }
+
+    *_rules = talloc_steal(mem_ctx, rules);
+    *_num_rules = num_rules;
+
+    ret = EOK;
+
+done:
+    talloc_free(tmp_ctx);
+    return ret;
+}
+
+static errno_t sudosrv_cached_rules_by_ng(TALLOC_CTX *mem_ctx,
+                                          struct sss_domain_info *domain,
+                                          uid_t uid,
+                                          const char *username,
+                                          char **groupnames,
+                                          struct sysdb_attrs ***_rules,
+                                          uint32_t *_num_rules)
+{
+    char *filter;
+    errno_t ret;
+    const char *attrs[] = { SYSDB_OBJECTCLASS,
+                            SYSDB_SUDO_CACHE_AT_CN,
+                            SYSDB_SUDO_CACHE_AT_USER,
+                            SYSDB_SUDO_CACHE_AT_HOST,
+                            SYSDB_SUDO_CACHE_AT_COMMAND,
+                            SYSDB_SUDO_CACHE_AT_OPTION,
+                            SYSDB_SUDO_CACHE_AT_RUNAS,
+                            SYSDB_SUDO_CACHE_AT_RUNASUSER,
+                            SYSDB_SUDO_CACHE_AT_RUNASGROUP,
+                            SYSDB_SUDO_CACHE_AT_NOTBEFORE,
+                            SYSDB_SUDO_CACHE_AT_NOTAFTER,
+                            SYSDB_SUDO_CACHE_AT_ORDER,
+                            NULL };
+
+    filter = sysdb_sudo_filter_netgroups(NULL, username, groupnames, uid);
+    if (filter == NULL) {
+        return ENOMEM;
+    }
+
+    ret = sudosrv_query_cache(mem_ctx, domain, attrs, filter,
+                              _rules, _num_rules);
+    talloc_free(filter);
 
     return ret;
 }
 
 static errno_t sudosrv_cached_rules(TALLOC_CTX *mem_ctx,
-                                    enum sss_sudo_type type,
                                     struct sss_domain_info *domain,
                                     uid_t uid,
                                     const char *username,
@@ -220,50 +308,147 @@ static errno_t sudosrv_cached_rules(TALLOC_CTX *mem_ctx,
                                     struct sysdb_attrs ***_rules,
                                     uint32_t *_num_rules)
 {
-    unsigned int flags = SYSDB_SUDO_FILTER_NONE;
+    TALLOC_CTX *tmp_ctx;
+    struct sysdb_attrs **user_rules;
+    struct sysdb_attrs **ng_rules;
+    struct sysdb_attrs **rules;
+    uint32_t num_user_rules;
+    uint32_t num_ng_rules;
+    uint32_t num_rules;
+    uint32_t rule_iter, i;
+    errno_t ret;
+
+    tmp_ctx = talloc_new(NULL);
+    if (tmp_ctx == NULL) {
+        return ENOMEM;
+    }
+
+    ret = sudosrv_cached_rules_by_user(tmp_ctx, domain, uid, username, groups,
+                                       &user_rules, &num_user_rules);
+    if (ret != EOK) {
+        goto done;
+    }
+
+    ret = sudosrv_cached_rules_by_ng(tmp_ctx, domain, uid, username, groups,
+                                     &ng_rules, &num_ng_rules);
+    if (ret != EOK) {
+        goto done;
+    }
+
+    num_rules = num_user_rules + num_ng_rules;
+    if (num_rules == 0) {
+        *_rules = NULL;
+        *_num_rules = 0;
+        ret = EOK;
+        goto done;
+    }
+
+    rules = talloc_array(tmp_ctx, struct sysdb_attrs *, num_rules);
+    if (rules == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    rule_iter = 0;
+    for (i = 0; i < num_user_rules; rule_iter++, i++) {
+        rules[rule_iter] = talloc_steal(rules, user_rules[i]);
+    }
+
+    for (i = 0; i < num_ng_rules; rule_iter++, i++) {
+        rules[rule_iter] = talloc_steal(rules, ng_rules[i]);
+    }
+
+    ret = sort_sudo_rules(rules, num_rules, inverse_order);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE, "Could not sort rules by sudoOrder\n");
+        goto done;
+    }
+
+    *_rules = talloc_steal(mem_ctx, rules);
+    *_num_rules = num_rules;
+
+    ret = EOK;
+
+done:
+    talloc_free(tmp_ctx);
+    return ret;
+}
+
+static errno_t sudosrv_cached_defaults(TALLOC_CTX *mem_ctx,
+                                       struct sss_domain_info *domain,
+                                       struct sysdb_attrs ***_rules,
+                                       uint32_t *_num_rules)
+{
+    char *filter;
+    errno_t ret;
+    const char *attrs[] = { SYSDB_OBJECTCLASS,
+                            SYSDB_SUDO_CACHE_AT_CN,
+                            SYSDB_SUDO_CACHE_AT_USER,
+                            SYSDB_SUDO_CACHE_AT_HOST,
+                            SYSDB_SUDO_CACHE_AT_COMMAND,
+                            SYSDB_SUDO_CACHE_AT_OPTION,
+                            SYSDB_SUDO_CACHE_AT_RUNAS,
+                            SYSDB_SUDO_CACHE_AT_RUNASUSER,
+                            SYSDB_SUDO_CACHE_AT_RUNASGROUP,
+                            SYSDB_SUDO_CACHE_AT_NOTBEFORE,
+                            SYSDB_SUDO_CACHE_AT_NOTAFTER,
+                            SYSDB_SUDO_CACHE_AT_ORDER,
+                            NULL };
+
+    filter = sysdb_sudo_filter_defaults(NULL);
+    if (filter == NULL) {
+        return ENOMEM;
+    }
+
+    ret = sudosrv_query_cache(mem_ctx, domain, attrs, filter,
+                              _rules, _num_rules);
+    talloc_free(filter);
+
+    return ret;
+}
+
+static errno_t sudosrv_fetch_rules(TALLOC_CTX *mem_ctx,
+                                   enum sss_sudo_type type,
+                                   struct sss_domain_info *domain,
+                                   uid_t uid,
+                                   const char *username,
+                                   char **groups,
+                                   bool inverse_order,
+                                   struct sysdb_attrs ***_rules,
+                                   uint32_t *_num_rules)
+{
     struct sysdb_attrs **rules;
     const char *debug_name = "unknown";
     uint32_t num_rules;
     errno_t ret;
-    const char *attrs[] = { SYSDB_OBJECTCLASS,
-                            SYSDB_SUDO_CACHE_AT_CN,
-                            SYSDB_SUDO_CACHE_AT_USER,
-                            SYSDB_SUDO_CACHE_AT_HOST,
-                            SYSDB_SUDO_CACHE_AT_COMMAND,
-                            SYSDB_SUDO_CACHE_AT_OPTION,
-                            SYSDB_SUDO_CACHE_AT_RUNAS,
-                            SYSDB_SUDO_CACHE_AT_RUNASUSER,
-                            SYSDB_SUDO_CACHE_AT_RUNASGROUP,
-                            SYSDB_SUDO_CACHE_AT_NOTBEFORE,
-                            SYSDB_SUDO_CACHE_AT_NOTAFTER,
-                            SYSDB_SUDO_CACHE_AT_ORDER,
-                            NULL };
 
     switch (type) {
     case SSS_SUDO_USER:
         DEBUG(SSSDBG_TRACE_FUNC, "Retrieving rules for [%s@%s]\n",
               username, domain->name);
         debug_name = "rules";
-        flags = SYSDB_SUDO_FILTER_USERINFO | SYSDB_SUDO_FILTER_INCLUDE_ALL;
+
+        ret = sudosrv_cached_rules(mem_ctx, domain, uid, username, groups,
+                                   inverse_order, &rules, &num_rules);
+
         break;
     case SSS_SUDO_DEFAULTS:
         debug_name = "default options";
         DEBUG(SSSDBG_TRACE_FUNC, "Retrieving default options for [%s@%s]\n",
               username, domain->name);
-        flags = SYSDB_SUDO_FILTER_INCLUDE_DFL;
+
+        ret = sudosrv_cached_defaults(mem_ctx, domain, &rules, &num_rules);
+
         break;
     }
 
-    ret = sudosrv_query_cache(mem_ctx, domain, attrs, flags,
-                              username, uid, groups,
-                              inverse_order, &rules, &num_rules);
     if (ret != EOK) {
-        DEBUG(SSSDBG_CRIT_FAILURE,
-              "Unable to retrieve sudo rules [%d]: %s\n", ret, strerror(ret));
+        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve %s [%d]: %s\n",
+              debug_name, ret, sss_strerror(ret));
         return ret;
     }
 
-    DEBUG(SSSDBG_TRACE_FUNC, "Returning %d %s for [%s@%s]\n",
+    DEBUG(SSSDBG_TRACE_FUNC, "Returning %u %s for [%s@%s]\n",
           num_rules, debug_name, username, domain->name);
 
     *_rules = rules;
@@ -541,10 +726,10 @@ static void sudosrv_get_rules_done(struct tevent_req *subreq)
               "in cache.\n");
     }
 
-    ret = sudosrv_cached_rules(state, state->type, state->domain, state->uid,
-                               state->username, state->groups,
-                               state->inverse_order,
-                               &state->rules, &state->num_rules);
+    ret = sudosrv_fetch_rules(state, state->type, state->domain, state->uid,
+                              state->username, state->groups,
+                              state->inverse_order,
+                              &state->rules, &state->num_rules);
 
     if (ret != EOK) {
         tevent_req_error(req, ret);
diff --git a/src/tests/cmocka/test_sysdb_sudo.c b/src/tests/cmocka/test_sysdb_sudo.c
index 7289454a4f7fb30ef1532226d3d5ea788b83f34a..04997173bb1efb144069d93c0f3ff2ed9bbe08ff 100644
--- a/src/tests/cmocka/test_sysdb_sudo.c
+++ b/src/tests/cmocka/test_sysdb_sudo.c
@@ -163,8 +163,6 @@ void test_store_sudo(void **state)
 {
     errno_t ret;
     char *filter;
-    int uid = 0;
-    char **groupnames = NULL;
     const char *attrs[] = { SYSDB_SUDO_CACHE_AT_CN, SYSDB_SUDO_CACHE_AT_HOST,
                             SYSDB_SUDO_CACHE_AT_RUNASUSER,
                             SYSDB_SUDO_CACHE_AT_USER, NULL };
@@ -182,10 +180,8 @@ void test_store_sudo(void **state)
     ret = sysdb_sudo_store(test_ctx->tctx->dom, &rule, 1);
     assert_int_equal(ret, EOK);
 
-    ret = sysdb_get_sudo_filter(test_ctx, users[0].name,
-                                uid, groupnames, SYSDB_SUDO_FILTER_USERNAME,
-                                &filter);
-    assert_int_equal(ret, EOK);
+    filter = sysdb_sudo_filter_user(test_ctx, users[0].name, NULL, 0);
+    assert_non_null(filter);
 
     ret = sysdb_search_sudo_rules(test_ctx, test_ctx->tctx->dom, filter,
                                   attrs, &msgs_count, &msgs);
@@ -222,8 +218,6 @@ void test_sudo_purge_by_filter(void **state)
     errno_t ret;
     struct sysdb_attrs *rule;
     char *delete_filter;
-    int uid = 0;
-    char **groupnames = NULL;
     struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state,
                                                          struct sysdb_test_ctx);
 
@@ -235,12 +229,8 @@ void test_sudo_purge_by_filter(void **state)
     assert_int_equal(ret, EOK);
     assert_int_equal(get_stored_rules_count(test_ctx), 1);
 
-    ret = sysdb_get_sudo_filter(test_ctx, users[0].name,
-                                uid, groupnames, SYSDB_SUDO_FILTER_USERNAME,
-                                &delete_filter);
-    assert_int_equal(ret, EOK);
-    assert_string_equal(delete_filter,
-                        "(&(objectClass=sudoRule)(|(sudoUser=test_user1)))");
+    delete_filter = sysdb_sudo_filter_user(test_ctx, users[0].name, NULL, 0);
+    assert_non_null(delete_filter);
 
     ret = sysdb_sudo_purge(test_ctx->tctx->dom, delete_filter, NULL, 0);
     assert_int_equal(ret, EOK);
@@ -289,25 +279,6 @@ void test_sudo_set_get_last_full_refresh(void **state)
     assert_int_equal(now, loaded_time);
 }
 
-void test_sudo_get_filter(void **state)
-{
-    errno_t ret;
-    char *filter;
-    int uid = 0;
-    char **groupnames = NULL;
-    struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state,
-                                                         struct sysdb_test_ctx);
-
-    ret = sysdb_get_sudo_filter(test_ctx, users[0].name,
-                                uid, groupnames, SYSDB_SUDO_FILTER_USERNAME,
-                                &filter);
-    assert_int_equal(ret, EOK);
-    assert_string_equal(filter,
-                        "(&(objectClass=sudoRule)(|(sudoUser=test_user1)))");
-
-    talloc_zfree(filter);
-}
-
 void test_get_sudo_user_info(void **state)
 {
     errno_t ret;
@@ -360,8 +331,6 @@ void test_set_sudo_rule_attr_add(void **state)
     const char *attrs[] = { SYSDB_SUDO_CACHE_AT_CN, SYSDB_SUDO_CACHE_AT_COMMAND,
                             NULL };
     char *filter;
-    int uid = 0;
-    char **groupnames = NULL;
     struct ldb_message **msgs = NULL;
     size_t msgs_count;
     const char *result;
@@ -386,10 +355,8 @@ void test_set_sudo_rule_attr_add(void **state)
                                    new_rule, SYSDB_MOD_ADD);
     assert_int_equal(ret, EOK);
 
-    ret = sysdb_get_sudo_filter(test_ctx, users[0].name,
-                                uid, groupnames, SYSDB_SUDO_FILTER_USERNAME,
-                                &filter);
-    assert_int_equal(ret, EOK);
+    filter = sysdb_sudo_filter_user(test_ctx, users[0].name, NULL, 0);
+    assert_non_null(filter);
 
     ret = sysdb_search_sudo_rules(test_ctx, test_ctx->tctx->dom, filter,
                                   attrs, &msgs_count, &msgs);
@@ -418,8 +385,6 @@ void test_set_sudo_rule_attr_replace(void **state)
     struct sysdb_attrs *new_rule;
     const char *attrs[] = { SYSDB_SUDO_CACHE_AT_CN, SYSDB_CACHE_EXPIRE, NULL };
     char *filter;
-    int uid = 0;
-    char **groupnames = NULL;
     struct ldb_message **msgs = NULL;
     size_t msgs_count;
     const char *result;
@@ -443,10 +408,8 @@ void test_set_sudo_rule_attr_replace(void **state)
                                    new_rule, SYSDB_MOD_REP);
     assert_int_equal(ret, EOK);
 
-    ret = sysdb_get_sudo_filter(test_ctx, users[0].name,
-                                uid, groupnames, SYSDB_SUDO_FILTER_USERNAME,
-                                &filter);
-    assert_int_equal(ret, EOK);
+    filter = sysdb_sudo_filter_user(test_ctx, users[0].name, NULL, 0);
+    assert_non_null(filter);
 
     ret = sysdb_search_sudo_rules(test_ctx, test_ctx->tctx->dom, filter,
                                   attrs, &msgs_count, &msgs);
@@ -475,8 +438,6 @@ void test_set_sudo_rule_attr_delete(void **state)
     const char *attrs[] = { SYSDB_SUDO_CACHE_AT_CN, SYSDB_SUDO_CACHE_AT_HOST,
                             NULL };
     char *filter;
-    int uid = 0;
-    char **groupnames = NULL;
     struct ldb_message **msgs = NULL;
     size_t msgs_count;
     const char *result;
@@ -501,10 +462,8 @@ void test_set_sudo_rule_attr_delete(void **state)
                                    new_rule, LDB_FLAG_MOD_DELETE);
     assert_int_equal(ret, EOK);
 
-    ret = sysdb_get_sudo_filter(test_ctx, users[0].name,
-                                uid, groupnames, SYSDB_SUDO_FILTER_USERNAME,
-                                &filter);
-    assert_int_equal(ret, EOK);
+    filter = sysdb_sudo_filter_user(test_ctx, users[0].name, NULL, 0);
+    assert_non_null(filter);
 
     ret = sysdb_search_sudo_rules(test_ctx, test_ctx->tctx->dom, filter,
                                   attrs, &msgs_count, &msgs);
@@ -529,7 +488,7 @@ void test_set_sudo_rule_attr_delete(void **state)
 void test_search_sudo_rules(void **state)
 {
     errno_t ret;
-    char *filter;
+    const char *filter;
     const char *attrs[] = { SYSDB_NAME, NULL };
     struct ldb_message **msgs = NULL;
     size_t msgs_count;
@@ -552,9 +511,7 @@ void test_search_sudo_rules(void **state)
     assert_int_equal(ret, EOK);
     assert_int_equal(get_stored_rules_count(test_ctx), 2);
 
-    ret = sysdb_get_sudo_filter(test_ctx, NULL, 0, NULL,
-                                SYSDB_SUDO_FILTER_NONE, &filter);
-    assert_int_equal(ret, EOK);
+    filter = "(objectClass=" SYSDB_SUDO_CACHE_OC ")";
 
     ret = sysdb_search_sudo_rules(test_ctx, test_ctx->tctx->dom, filter,
                                   attrs, &msgs_count, &msgs);
@@ -577,7 +534,6 @@ void test_search_sudo_rules(void **state)
     talloc_zfree(tmp_rules[0]);
     talloc_zfree(tmp_rules[1]);
     talloc_zfree(msgs);
-    talloc_zfree(filter);
 }
 
 void test_filter_rules_by_time(void **state)
@@ -706,11 +662,6 @@ int main(int argc, const char *argv[])
                                         test_sysdb_setup,
                                         test_sysdb_teardown),
 
-        /* sysdb_get_sudo_filter() */
-        cmocka_unit_test_setup_teardown(test_sudo_get_filter,
-                                        test_sysdb_setup,
-                                        test_sysdb_teardown),
-
         /* sysdb_get_sudo_user_info() */
         cmocka_unit_test_setup_teardown(test_get_sudo_user_info,
                                         test_sysdb_setup,
-- 
2.1.0

