From 636a8361a5dd57bb6e64b3dfcf85532e40cd122f Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgallagh@redhat.com>
Date: Wed, 16 Jun 2010 15:33:57 -0400
Subject: [PATCH 3/4] Move setup of filter_users and filter_groups to negcache.c

Creates a new function - sss_ncache_prepopulate() - that can be
shared with other responders, such as PAM.
---
 src/responder/common/negcache.c |  207 +++++++++++++++++++++++++++++++++++++++
 src/responder/common/negcache.h |    8 ++
 src/responder/nss/nsssrv.c      |  192 +-----------------------------------
 3 files changed, 220 insertions(+), 187 deletions(-)

diff --git a/src/responder/common/negcache.c b/src/responder/common/negcache.c
index aef9080a8a31b5b252c236ba2bf5a5bf4e127eae..521a2e76e68f4e1a93bb04f362de3d03acb992fd 100644
--- a/src/responder/common/negcache.c
+++ b/src/responder/common/negcache.c
@@ -20,6 +20,7 @@
 */
 
 #include "util/util.h"
+#include "confdb/confdb.h"
 #include <fcntl.h>
 #include <time.h>
 #include "tdb.h"
@@ -319,3 +320,209 @@ int sss_ncache_reset_permament(struct sss_nc_ctx *ctx)
 
     return EOK;
 }
+
+errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache,
+                               struct confdb_ctx *cdb,
+                               struct sss_names_ctx *names_ctx,
+                               struct sss_domain_info *domain_list)
+{
+    errno_t ret;
+    bool filter_set = false;
+    char **filter_list = NULL;
+    char *name = NULL;
+    struct sss_domain_info *dom = NULL;
+    char *domainname = NULL;
+    char *conf_path = NULL;
+    TALLOC_CTX *tmpctx = talloc_new(NULL);
+    int i;
+
+    /* Populate domain-specific negative cache entries */
+    for (dom = domain_list; dom; dom = dom->next) {
+        conf_path = talloc_asprintf(tmpctx, CONFDB_DOMAIN_PATH_TMPL,
+                                    dom->name);
+        if (!conf_path) {
+            ret = ENOMEM;
+            goto done;
+        }
+
+        talloc_zfree(filter_list);
+        ret = confdb_get_string_as_list(cdb, tmpctx, conf_path,
+                                        CONFDB_NSS_FILTER_USERS,
+                                        &filter_list);
+        if (ret == ENOENT) continue;
+        if (ret != EOK) goto done;
+        filter_set = true;
+
+        for (i = 0; (filter_list && filter_list[i]); i++) {
+            ret = sss_parse_name(tmpctx, names_ctx, filter_list[i],
+                                 &domainname, &name);
+            if (ret != EOK) {
+                DEBUG(1, ("Invalid name in filterUsers list: [%s] (%d)\n",
+                         filter_list[i], ret));
+                continue;
+            }
+
+            if (domainname && strcmp(domainname, dom->name)) {
+                DEBUG(1, ("Mismatch between domain name (%s) and name "
+                          "set in FQN  (%s), skipping user %s\n",
+                          dom->name, domainname, name));
+                continue;
+            }
+
+            ret = sss_ncache_set_user(ncache, true, dom->name, name);
+            if (ret != EOK) {
+                DEBUG(1, ("Failed to store permanent user filter for [%s]"
+                          " (%d [%s])\n", filter_list[i],
+                          ret, strerror(ret)));
+                continue;
+            }
+        }
+    }
+
+    ret = confdb_get_string_as_list(cdb, tmpctx, CONFDB_NSS_CONF_ENTRY,
+                                    CONFDB_NSS_FILTER_USERS, &filter_list);
+    if (ret == ENOENT) {
+        if (!filter_set) {
+            filter_list = talloc_array(tmpctx, char *, 2);
+            if (!filter_list) {
+                ret = ENOMEM;
+                goto done;
+            }
+            filter_list[0] = talloc_strdup(tmpctx, "root");
+            if (!filter_list[0]) {
+                ret = ENOMEM;
+                goto done;
+            }
+            filter_list[1] = NULL;
+        }
+        ret = EOK;
+    }
+    else if (ret != EOK) goto done;
+
+    for (i = 0; (filter_list && filter_list[i]); i++) {
+        ret = sss_parse_name(tmpctx, names_ctx, filter_list[i],
+                             &domainname, &name);
+        if (ret != EOK) {
+            DEBUG(1, ("Invalid name in filterUsers list: [%s] (%d)\n",
+                     filter_list[i], ret));
+            continue;
+        }
+        if (domainname) {
+            ret = sss_ncache_set_user(ncache, true, domainname, name);
+            if (ret != EOK) {
+                DEBUG(1, ("Failed to store permanent user filter for [%s]"
+                          " (%d [%s])\n", filter_list[i],
+                          ret, strerror(ret)));
+                continue;
+            }
+        } else {
+            for (dom = domain_list; dom; dom = dom->next) {
+                ret = sss_ncache_set_user(ncache, true, dom->name, name);
+                if (ret != EOK) {
+                   DEBUG(1, ("Failed to store permanent user filter for"
+                             " [%s:%s] (%d [%s])\n",
+                             dom->name, filter_list[i],
+                             ret, strerror(ret)));
+                    continue;
+                }
+            }
+        }
+    }
+
+    filter_set = false;
+    for (dom = domain_list; dom; dom = dom->next) {
+        conf_path = talloc_asprintf(tmpctx, CONFDB_DOMAIN_PATH_TMPL, dom->name);
+        if (!conf_path) {
+            ret = ENOMEM;
+            goto done;
+        }
+
+        talloc_zfree(filter_list);
+        ret = confdb_get_string_as_list(cdb, tmpctx, conf_path,
+                                        CONFDB_NSS_FILTER_GROUPS, &filter_list);
+        if (ret == ENOENT) continue;
+        if (ret != EOK) goto done;
+        filter_set = true;
+
+        for (i = 0; (filter_list && filter_list[i]); i++) {
+            ret = sss_parse_name(tmpctx, names_ctx, filter_list[i],
+                                 &domainname, &name);
+            if (ret != EOK) {
+                DEBUG(1, ("Invalid name in filterGroups list: [%s] (%d)\n",
+                         filter_list[i], ret));
+                continue;
+            }
+
+            if (domainname && strcmp(domainname, dom->name)) {
+                DEBUG(1, ("Mismatch betwen domain name (%s) and name "
+                          "set in FQN  (%s), skipping group %s\n",
+                          dom->name, domainname, name));
+                continue;
+            }
+
+            ret = sss_ncache_set_group(ncache, true, dom->name, name);
+            if (ret != EOK) {
+                DEBUG(1, ("Failed to store permanent group filter for [%s]"
+                          " (%d [%s])\n", filter_list[i],
+                          ret, strerror(ret)));
+                continue;
+            }
+        }
+    }
+
+    ret = confdb_get_string_as_list(cdb, tmpctx, CONFDB_NSS_CONF_ENTRY,
+                                    CONFDB_NSS_FILTER_GROUPS, &filter_list);
+    if (ret == ENOENT) {
+        if (!filter_set) {
+            filter_list = talloc_array(tmpctx, char *, 2);
+            if (!filter_list) {
+                ret = ENOMEM;
+                goto done;
+            }
+            filter_list[0] = talloc_strdup(tmpctx, "root");
+            if (!filter_list[0]) {
+                ret = ENOMEM;
+                goto done;
+            }
+            filter_list[1] = NULL;
+        }
+        ret = EOK;
+    }
+    else if (ret != EOK) goto done;
+
+    for (i = 0; (filter_list && filter_list[i]); i++) {
+        ret = sss_parse_name(tmpctx, names_ctx, filter_list[i],
+                             &domainname, &name);
+        if (ret != EOK) {
+            DEBUG(1, ("Invalid name in filterGroups list: [%s] (%d)\n",
+                     filter_list[i], ret));
+            continue;
+        }
+        if (domainname) {
+            ret = sss_ncache_set_group(ncache, true, domainname, name);
+            if (ret != EOK) {
+                DEBUG(1, ("Failed to store permanent group filter for"
+                          " [%s] (%d [%s])\n", filter_list[i],
+                          ret, strerror(ret)));
+                continue;
+            }
+        } else {
+            for (dom = domain_list; dom; dom = dom->next) {
+                ret = sss_ncache_set_group(ncache, true, dom->name, name);
+                if (ret != EOK) {
+                   DEBUG(1, ("Failed to store permanent group filter for"
+                             " [%s:%s] (%d [%s])\n",
+                             dom->name, filter_list[i],
+                             ret, strerror(ret)));
+                    continue;
+                }
+            }
+        }
+    }
+
+    ret = EOK;
+
+done:
+    talloc_free(tmpctx);
+    return ret;
+}
diff --git a/src/responder/common/negcache.h b/src/responder/common/negcache.h
index d310c9e3d9897d13298c4ffa945d036b43536a8c..68be9f02e9980ac03ea2a0b76e23fc68c0a1436c 100644
--- a/src/responder/common/negcache.h
+++ b/src/responder/common/negcache.h
@@ -48,4 +48,12 @@ int sss_ncache_set_gid(struct sss_nc_ctx *ctx, bool permanent, gid_t gid);
 
 int sss_ncache_reset_permament(struct sss_nc_ctx *ctx);
 
+/* Set up the negative cache with values from filter_users and
+ * filter_groups in the sssd.conf
+ */
+errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache,
+                               struct confdb_ctx *cdb,
+                               struct sss_names_ctx *names_ctx,
+                               struct sss_domain_info *domain_list);
+
 #endif /* _NSS_NEG_CACHE_H_ */
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index 24753674af348288f40f8d14fb2d4b42bbc3d73b..f14d698f2195b70021bf831296e5ce04c3746ce4 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -67,12 +67,7 @@ static int nss_get_config(struct nss_ctx *nctx,
                           struct confdb_ctx *cdb)
 {
     TALLOC_CTX *tmpctx;
-    struct sss_domain_info *dom;
-    const char *conf_path;
-    char *domain, *name;
-    char **filter_list = NULL;
-    int ret, i;
-    bool filter_set;
+    int ret;
 
     tmpctx = talloc_new(nctx);
     if (!tmpctx) return ENOMEM;
@@ -92,7 +87,6 @@ static int nss_get_config(struct nss_ctx *nctx,
                          &nctx->filter_users_in_groups);
     if (ret != EOK) goto done;
 
-
     ret = confdb_get_int(cdb, nctx, CONFDB_NSS_CONF_ENTRY,
                          CONFDB_NSS_ENTRY_CACHE_NOWAIT_PERCENTAGE, 0,
                          &nctx->cache_refresh_percent);
@@ -104,186 +98,10 @@ static int nss_get_config(struct nss_ctx *nctx,
         nctx->cache_refresh_percent = 0;
     }
 
-    filter_set = false;
-    for (dom = rctx->domains; dom; dom = dom->next) {
-        conf_path = talloc_asprintf(tmpctx, CONFDB_DOMAIN_PATH_TMPL, dom->name);
-        if (!conf_path) {
-            ret = ENOMEM;
-            goto done;
-        }
-
-        talloc_zfree(filter_list);
-        ret = confdb_get_string_as_list(cdb, tmpctx, conf_path,
-                                        CONFDB_NSS_FILTER_USERS, &filter_list);
-        if (ret == ENOENT) continue;
-        if (ret != EOK) goto done;
-        filter_set = true;
-
-        for (i = 0; (filter_list && filter_list[i]); i++) {
-            ret = sss_parse_name(tmpctx, nctx->rctx->names,
-                                 filter_list[i], &domain, &name);
-            if (ret != EOK) {
-                DEBUG(1, ("Invalid name in filterUsers list: [%s] (%d)\n",
-                         filter_list[i], ret));
-                continue;
-            }
-
-            if (domain && strcmp(domain, dom->name)) {
-                DEBUG(1, ("Mismatch betwen domain name (%s) and name "
-                          "set in FQN  (%s), skipping user %s\n",
-                          dom->name, domain, name));
-                continue;
-            }
-
-            ret = sss_ncache_set_user(nctx->ncache, true, dom->name, name);
-            if (ret != EOK) {
-                DEBUG(1, ("Failed to store permanent user filter for [%s]"
-                          " (%d [%s])\n", filter_list[i],
-                          ret, strerror(ret)));
-                continue;
-            }
-        }
-    }
-
-    ret = confdb_get_string_as_list(cdb, tmpctx, CONFDB_NSS_CONF_ENTRY,
-                                    CONFDB_NSS_FILTER_USERS, &filter_list);
-    if (ret == ENOENT) {
-        if (!filter_set) {
-            filter_list = talloc_array(tmpctx, char *, 2);
-            if (!filter_list) {
-                ret = ENOMEM;
-                goto done;
-            }
-            filter_list[0] = talloc_strdup(tmpctx, "root");
-            if (!filter_list[0]) {
-                ret = ENOMEM;
-                goto done;
-            }
-            filter_list[1] = NULL;
-        }
-        ret = EOK;
-    }
-    else if (ret != EOK) goto done;
-
-    for (i = 0; (filter_list && filter_list[i]); i++) {
-        ret = sss_parse_name(tmpctx, nctx->rctx->names,
-                             filter_list[i], &domain, &name);
-        if (ret != EOK) {
-            DEBUG(1, ("Invalid name in filterUsers list: [%s] (%d)\n",
-                     filter_list[i], ret));
-            continue;
-        }
-        if (domain) {
-            ret = sss_ncache_set_user(nctx->ncache, true, domain, name);
-            if (ret != EOK) {
-                DEBUG(1, ("Failed to store permanent user filter for [%s]"
-                          " (%d [%s])\n", filter_list[i],
-                          ret, strerror(ret)));
-                continue;
-            }
-        } else {
-            for (dom = rctx->domains; dom; dom = dom->next) {
-                ret = sss_ncache_set_user(nctx->ncache, true, dom->name, name);
-                if (ret != EOK) {
-                   DEBUG(1, ("Failed to store permanent user filter for"
-                             " [%s:%s] (%d [%s])\n",
-                             dom->name, filter_list[i],
-                             ret, strerror(ret)));
-                    continue;
-                }
-            }
-        }
-    }
-
-    filter_set = false;
-    for (dom = rctx->domains; dom; dom = dom->next) {
-        conf_path = talloc_asprintf(tmpctx, CONFDB_DOMAIN_PATH_TMPL, dom->name);
-        if (!conf_path) {
-            ret = ENOMEM;
-            goto done;
-        }
-
-        talloc_zfree(filter_list);
-        ret = confdb_get_string_as_list(cdb, tmpctx, conf_path,
-                                        CONFDB_NSS_FILTER_GROUPS, &filter_list);
-        if (ret == ENOENT) continue;
-        if (ret != EOK) goto done;
-        filter_set = true;
-
-        for (i = 0; (filter_list && filter_list[i]); i++) {
-            ret = sss_parse_name(tmpctx, nctx->rctx->names,
-                                 filter_list[i], &domain, &name);
-            if (ret != EOK) {
-                DEBUG(1, ("Invalid name in filterGroups list: [%s] (%d)\n",
-                         filter_list[i], ret));
-                continue;
-            }
-
-            if (domain && strcmp(domain, dom->name)) {
-                DEBUG(1, ("Mismatch betwen domain name (%s) and name "
-                          "set in FQN  (%s), skipping group %s\n",
-                          dom->name, domain, name));
-                continue;
-            }
-
-            ret = sss_ncache_set_group(nctx->ncache, true, dom->name, name);
-            if (ret != EOK) {
-                DEBUG(1, ("Failed to store permanent group filter for [%s]"
-                          " (%d [%s])\n", filter_list[i],
-                          ret, strerror(ret)));
-                continue;
-            }
-        }
-    }
-
-    ret = confdb_get_string_as_list(cdb, tmpctx, CONFDB_NSS_CONF_ENTRY,
-                                    CONFDB_NSS_FILTER_GROUPS, &filter_list);
-    if (ret == ENOENT) {
-        if (!filter_set) {
-            filter_list = talloc_array(tmpctx, char *, 2);
-            if (!filter_list) {
-                ret = ENOMEM;
-                goto done;
-            }
-            filter_list[0] = talloc_strdup(tmpctx, "root");
-            if (!filter_list[0]) {
-                ret = ENOMEM;
-                goto done;
-            }
-            filter_list[1] = NULL;
-        }
-        ret = EOK;
-    }
-    else if (ret != EOK) goto done;
-
-    for (i = 0; (filter_list && filter_list[i]); i++) {
-        ret = sss_parse_name(tmpctx, nctx->rctx->names,
-                             filter_list[i], &domain, &name);
-        if (ret != EOK) {
-            DEBUG(1, ("Invalid name in filterGroups list: [%s] (%d)\n",
-                     filter_list[i], ret));
-            continue;
-        }
-        if (domain) {
-            ret = sss_ncache_set_group(nctx->ncache, true, domain, name);
-            if (ret != EOK) {
-                DEBUG(1, ("Failed to store permanent group filter for"
-                          " [%s] (%d [%s])\n", filter_list[i],
-                          ret, strerror(ret)));
-                continue;
-            }
-        } else {
-            for (dom = rctx->domains; dom; dom = dom->next) {
-                ret = sss_ncache_set_group(nctx->ncache, true, dom->name, name);
-                if (ret != EOK) {
-                   DEBUG(1, ("Failed to store permanent group filter for"
-                             " [%s:%s] (%d [%s])\n",
-                             dom->name, filter_list[i],
-                             ret, strerror(ret)));
-                    continue;
-                }
-            }
-        }
+    ret = sss_ncache_prepopulate(nctx->ncache, cdb, nctx->rctx->names,
+                                 nctx->rctx->domains);
+    if (ret != EOK) {
+        goto done;
     }
 
     ret = confdb_get_string(cdb, nctx, CONFDB_NSS_CONF_ENTRY,
-- 
1.7.0.1

