>From dc613eca1c7b0ce0821f5d01bb2e5afae8a8b401 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <pavel.reichl@redhat.com>
Date: Wed, 8 Jan 2014 16:03:08 +0000
Subject: [PATCH 2/2] simple access: refresh master domain info

To correctly decide if an object is a member of the main sssd domain, a flat name
is needed. However, the information may not be available when the module is
inited so it may be necessary to refresh this data later while processing a
request.

Resolves:
https://fedorahosted.org/sssd/ticket/2189
---
 src/providers/simple/simple_access.c | 75 ++++++++++++++++++++++++++++--------
 src/providers/simple/simple_access.h |  2 +
 2 files changed, 60 insertions(+), 17 deletions(-)

diff --git a/src/providers/simple/simple_access.c b/src/providers/simple/simple_access.c
index f2bfe755039fd7a370749fd3ce94a47c62c216bc..60179e3e4ac144b265ae7193b7b1b1305108be61 100644
--- a/src/providers/simple/simple_access.c
+++ b/src/providers/simple/simple_access.c
@@ -33,6 +33,7 @@
 #define CONFDB_SIMPLE_DENY_GROUPS "simple_deny_groups"
 
 static void simple_access_check(struct tevent_req *req);
+static int sssm_simple_access_obtain_filter_lists(struct simple_ctx *ctx);
 
 void simple_access_handler(struct be_req *be_req)
 {
@@ -40,13 +41,15 @@ void simple_access_handler(struct be_req *be_req)
     struct pam_data *pd;
     struct tevent_req *req;
     struct simple_ctx *ctx;
+    int ret;
 
     pd = talloc_get_type(be_req_get_data(be_req), struct pam_data);
 
     pd->pam_status = PAM_SYSTEM_ERR;
 
     if (pd->cmd != SSS_PAM_ACCT_MGMT) {
-        DEBUG(4, ("simple access does not handles pam task %d.\n", pd->cmd));
+        DEBUG(SSSDBG_CONF_SETTINGS,
+              ("simple access does not handles pam task %d.\n", pd->cmd));
         pd->pam_status = PAM_MODULE_UNKNOWN;
         goto done;
     }
@@ -54,6 +57,15 @@ void simple_access_handler(struct be_req *be_req)
     ctx = talloc_get_type(be_ctx->bet_info[BET_ACCESS].pvt_bet_data,
                           struct simple_ctx);
 
+    if (ctx->refresh_filter_lists) {
+        ret = sssm_simple_access_obtain_filter_lists(ctx);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to refresh filter lists\n"));
+        } else {
+            ctx->refresh_filter_lists = false;
+        }
+    }
+
     req = simple_access_check_send(be_req, be_ctx->ev, ctx, pd->user);
     if (!req) {
         pd->pam_status = PAM_SYSTEM_ERR;
@@ -176,6 +188,34 @@ int sssm_simple_access_init(struct be_ctx *bectx, struct bet_ops **ops,
 {
     int ret = EINVAL;
     struct simple_ctx *ctx;
+    ctx = talloc_zero(bectx, struct simple_ctx);
+    if (ctx == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_zero failed.\n"));
+        return ENOMEM;
+    }
+
+    ctx->domain = bectx->domain;
+    ctx->be_ctx = bectx;
+
+    ret = sssm_simple_access_obtain_filter_lists(ctx);
+    if (ret != EOK && (ret != EAGAIN || ctx->refresh_filter_lists == false)) {
+        goto failed;
+    }
+
+    *ops = &simple_access_ops;
+    *pvt_data = ctx;
+
+    return EOK;
+
+failed:
+    talloc_free(ctx);
+    return ret;
+}
+
+static int sssm_simple_access_obtain_filter_lists(struct simple_ctx *ctx)
+{
+    struct be_ctx *bectx = ctx->be_ctx;
+    int ret;
     int i;
     struct {
         const char *name;
@@ -188,20 +228,25 @@ int sssm_simple_access_init(struct be_ctx *bectx, struct bet_ops **ops,
                  {"Deny groups", CONFDB_SIMPLE_DENY_GROUPS, NULL, NULL},
                  {NULL, NULL, NULL, NULL}};
 
-    ctx = talloc_zero(bectx, struct simple_ctx);
-    if (ctx == NULL) {
-        DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_zero failed.\n"));
-        return ENOMEM;
-    }
-
-    ctx->domain = bectx->domain;
-    ctx->be_ctx = bectx;
-
     lists[0].ctx_list = &ctx->allow_users;
     lists[1].ctx_list = &ctx->deny_users;
     lists[2].ctx_list = &ctx->allow_groups;
     lists[3].ctx_list = &ctx->deny_groups;
 
+    ret = sysdb_master_domain_update(bectx->domain);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_FUNC_DATA, ("Update of master domain failed [%d]: %s.\n",
+                                 ret, sss_strerror(ret)));
+        goto failed;
+    }
+
+    if (bectx->domain->flat_name == NULL) {
+        /* Cache is probably empty. */
+        DEBUG(SSSDBG_FUNC_DATA,
+              ("Flat name of master domain is not supposed to be NULL.\n"));
+        ctx->refresh_filter_lists = true;
+    }
+
     for (i = 0; lists[i].name != NULL; i++) {
         ret = confdb_get_string_as_list(bectx->cdb, ctx, bectx->conf_path,
                                         lists[i].option, &lists[i].orig_list);
@@ -227,16 +272,12 @@ int sssm_simple_access_init(struct be_ctx *bectx, struct bet_ops **ops,
             !ctx->allow_groups &&
             !ctx->deny_users &&
             !ctx->deny_groups) {
-        DEBUG(SSSDBG_OP_FAILURE, ("No rules supplied for simple access provider. "
-                                  "Access will be granted for all users.\n"));
+        DEBUG(SSSDBG_OP_FAILURE,
+              ("No rules supplied for simple access provider. "
+               "Access will be granted for all users.\n"));
     }
-
-    *ops = &simple_access_ops;
-    *pvt_data = ctx;
-
     return EOK;
 
 failed:
-    talloc_free(ctx);
     return ret;
 }
diff --git a/src/providers/simple/simple_access.h b/src/providers/simple/simple_access.h
index 15dfaceb2d9a6670d3559e4a945c2c7a633fad44..e94bca4a87e619696698b25f39e4ec4b256fcc50 100644
--- a/src/providers/simple/simple_access.h
+++ b/src/providers/simple/simple_access.h
@@ -32,6 +32,8 @@ struct simple_ctx {
     char **deny_users;
     char **allow_groups;
     char **deny_groups;
+
+    bool refresh_filter_lists;
 };
 
 struct tevent_req *simple_access_check_send(TALLOC_CTX *mem_ctx,
-- 
1.8.3.1

