Blame SOURCES/0029-SECRETS-Create-DB-path-before-the-operation-itself.patch

bb7cd1
From 27e11e8f03e1bad5d1be276efaf1406b16b11625 Mon Sep 17 00:00:00 2001
bb7cd1
From: Jakub Hrozek <jhrozek@redhat.com>
bb7cd1
Date: Tue, 3 Jan 2017 16:00:38 +0100
bb7cd1
Subject: [PATCH 29/36] SECRETS: Create DB path before the operation itself
bb7cd1
MIME-Version: 1.0
bb7cd1
Content-Type: text/plain; charset=UTF-8
bb7cd1
Content-Transfer-Encoding: 8bit
bb7cd1
bb7cd1
This is a refactoring where instead of creating the ldb path in the
bb7cd1
operation itself, we create the ldb path when creating the local db request
bb7cd1
and pass the path to the operation.
bb7cd1
bb7cd1
This would allow us to store different kind of objects in the secrets
bb7cd1
storage later.
bb7cd1
bb7cd1
Reviewed-by: Michal Židek <mzidek@redhat.com>
bb7cd1
Reviewed-by: Simo Sorce <simo@redhat.com>
bb7cd1
---
bb7cd1
 src/responder/secrets/local.c | 170 +++++++++++++++++++++---------------------
bb7cd1
 1 file changed, 84 insertions(+), 86 deletions(-)
bb7cd1
bb7cd1
diff --git a/src/responder/secrets/local.c b/src/responder/secrets/local.c
bb7cd1
index ed70193bcb27d84eaf449f6f7571c94f466c9896..9dcdd9925e542499d3a962b4998103b07c26a5ab 100644
bb7cd1
--- a/src/responder/secrets/local.c
bb7cd1
+++ b/src/responder/secrets/local.c
bb7cd1
@@ -199,39 +199,36 @@ static char *local_dn_to_path(TALLOC_CTX *mem_ctx,
bb7cd1
     return path;
bb7cd1
 }
bb7cd1
 
bb7cd1
+struct local_db_req {
bb7cd1
+    char *path;
bb7cd1
+    struct ldb_dn *basedn;
bb7cd1
+};
bb7cd1
+
bb7cd1
 #define LOCAL_SIMPLE_FILTER "(type=simple)"
bb7cd1
 #define LOCAL_CONTAINER_FILTER "(type=container)"
bb7cd1
 
bb7cd1
 static int local_db_get_simple(TALLOC_CTX *mem_ctx,
bb7cd1
                                struct local_context *lctx,
bb7cd1
-                               const char *req_path,
bb7cd1
+                               struct local_db_req *lc_req,
bb7cd1
                                char **secret)
bb7cd1
 {
bb7cd1
     TALLOC_CTX *tmp_ctx;
bb7cd1
     static const char *attrs[] = { "secret", "enctype", NULL };
bb7cd1
     struct ldb_result *res;
bb7cd1
-    struct ldb_dn *dn;
bb7cd1
     const char *attr_secret;
bb7cd1
     const char *attr_enctype;
bb7cd1
     int ret;
bb7cd1
 
bb7cd1
-    DEBUG(SSSDBG_TRACE_FUNC, "Retrieving a secret from [%s]\n", req_path);
bb7cd1
+    DEBUG(SSSDBG_TRACE_FUNC, "Retrieving a secret from [%s]\n", lc_req->path);
bb7cd1
 
bb7cd1
     tmp_ctx = talloc_new(mem_ctx);
bb7cd1
     if (!tmp_ctx) return ENOMEM;
bb7cd1
 
bb7cd1
-    ret = local_db_dn(tmp_ctx, lctx->ldb, req_path, &dn;;
bb7cd1
-    if (ret != EOK) {
bb7cd1
-        DEBUG(SSSDBG_OP_FAILURE,
bb7cd1
-              "local_db_dn failed [%d]: %s\n", ret, sss_strerror(ret));
bb7cd1
-        goto done;
bb7cd1
-    }
bb7cd1
-
bb7cd1
     DEBUG(SSSDBG_TRACE_INTERNAL,
bb7cd1
           "Searching for [%s] at [%s] with scope=base\n",
bb7cd1
-          LOCAL_SIMPLE_FILTER, ldb_dn_get_linearized(dn));
bb7cd1
+          LOCAL_SIMPLE_FILTER, ldb_dn_get_linearized(lc_req->basedn));
bb7cd1
 
bb7cd1
-    ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE,
bb7cd1
+    ret = ldb_search(lctx->ldb, tmp_ctx, &res, lc_req->basedn, LDB_SCOPE_BASE,
bb7cd1
                      attrs, "%s", LOCAL_SIMPLE_FILTER);
bb7cd1
     if (ret != EOK) {
bb7cd1
         DEBUG(SSSDBG_TRACE_LIBS,
bb7cd1
@@ -278,34 +275,26 @@ done:
bb7cd1
 
bb7cd1
 static int local_db_list_keys(TALLOC_CTX *mem_ctx,
bb7cd1
                               struct local_context *lctx,
bb7cd1
-                              const char *req_path,
bb7cd1
+                              struct local_db_req *lc_req,
bb7cd1
                               char ***_keys,
bb7cd1
                               int *num_keys)
bb7cd1
 {
bb7cd1
     TALLOC_CTX *tmp_ctx;
bb7cd1
     static const char *attrs[] = { "secret", NULL };
bb7cd1
     struct ldb_result *res;
bb7cd1
-    struct ldb_dn *dn;
bb7cd1
     char **keys;
bb7cd1
     int ret;
bb7cd1
 
bb7cd1
     tmp_ctx = talloc_new(mem_ctx);
bb7cd1
     if (!tmp_ctx) return ENOMEM;
bb7cd1
 
bb7cd1
-    DEBUG(SSSDBG_TRACE_FUNC, "Listing keys at [%s]\n", req_path);
bb7cd1
-
bb7cd1
-    ret = local_db_dn(tmp_ctx, lctx->ldb, req_path, &dn;;
bb7cd1
-    if (ret != EOK) {
bb7cd1
-        DEBUG(SSSDBG_OP_FAILURE,
bb7cd1
-              "local_db_dn failed [%d]: %s\n", ret, sss_strerror(ret));
bb7cd1
-        goto done;
bb7cd1
-    }
bb7cd1
+    DEBUG(SSSDBG_TRACE_FUNC, "Listing keys at [%s]\n", lc_req->path);
bb7cd1
 
bb7cd1
     DEBUG(SSSDBG_TRACE_INTERNAL,
bb7cd1
           "Searching for [%s] at [%s] with scope=subtree\n",
bb7cd1
-          LOCAL_SIMPLE_FILTER, ldb_dn_get_linearized(dn));
bb7cd1
+          LOCAL_SIMPLE_FILTER, ldb_dn_get_linearized(lc_req->basedn));
bb7cd1
 
bb7cd1
-    ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_SUBTREE,
bb7cd1
+    ret = ldb_search(lctx->ldb, tmp_ctx, &res, lc_req->basedn, LDB_SCOPE_SUBTREE,
bb7cd1
                      attrs, "%s", LOCAL_SIMPLE_FILTER);
bb7cd1
     if (ret != EOK) {
bb7cd1
         DEBUG(SSSDBG_TRACE_LIBS,
bb7cd1
@@ -327,7 +316,7 @@ static int local_db_list_keys(TALLOC_CTX *mem_ctx,
bb7cd1
     }
bb7cd1
 
bb7cd1
     for (unsigned i = 0; i < res->count; i++) {
bb7cd1
-        keys[i] = local_dn_to_path(keys, dn, res->msgs[i]->dn);
bb7cd1
+        keys[i] = local_dn_to_path(keys, lc_req->basedn, res->msgs[i]->dn);
bb7cd1
         if (!keys[i]) {
bb7cd1
             ret = ENOMEM;
bb7cd1
             goto done;
bb7cd1
@@ -474,7 +463,7 @@ static int local_check_max_payload_size(struct local_context *lctx,
bb7cd1
 
bb7cd1
 static int local_db_put_simple(TALLOC_CTX *mem_ctx,
bb7cd1
                                struct local_context *lctx,
bb7cd1
-                               const char *req_path,
bb7cd1
+                               struct local_db_req *lc_req,
bb7cd1
                                const char *secret)
bb7cd1
 {
bb7cd1
     struct ldb_message *msg;
bb7cd1
@@ -482,20 +471,14 @@ static int local_db_put_simple(TALLOC_CTX *mem_ctx,
bb7cd1
     char *enc_secret;
bb7cd1
     int ret;
bb7cd1
 
bb7cd1
+    DEBUG(SSSDBG_TRACE_FUNC, "Adding a secret to [%s]\n", lc_req->path);
bb7cd1
+
bb7cd1
     msg = ldb_msg_new(mem_ctx);
bb7cd1
     if (!msg) {
bb7cd1
         ret = ENOMEM;
bb7cd1
         goto done;
bb7cd1
     }
bb7cd1
-
bb7cd1
-    DEBUG(SSSDBG_TRACE_FUNC, "Adding a secret to [%s]\n", req_path);
bb7cd1
-
bb7cd1
-    ret = local_db_dn(msg, lctx->ldb, req_path, &msg->dn);
bb7cd1
-    if (ret != EOK) {
bb7cd1
-        DEBUG(SSSDBG_OP_FAILURE,
bb7cd1
-              "local_db_dn failed [%d]: %s\n", ret, sss_strerror(ret));
bb7cd1
-        goto done;
bb7cd1
-    }
bb7cd1
+    msg->dn = lc_req->basedn;
bb7cd1
 
bb7cd1
     /* make sure containers exist */
bb7cd1
     ret = local_db_check_containers(msg, lctx, msg->dn);
bb7cd1
@@ -585,32 +568,24 @@ done:
bb7cd1
 
bb7cd1
 static int local_db_delete(TALLOC_CTX *mem_ctx,
bb7cd1
                            struct local_context *lctx,
bb7cd1
-                           const char *req_path)
bb7cd1
+                           struct local_db_req *lc_req)
bb7cd1
 {
bb7cd1
     TALLOC_CTX *tmp_ctx;
bb7cd1
-    struct ldb_dn *dn;
bb7cd1
     static const char *attrs[] = { NULL };
bb7cd1
     struct ldb_result *res;
bb7cd1
     int ret;
bb7cd1
 
bb7cd1
-    DEBUG(SSSDBG_TRACE_FUNC, "Removing a secret from [%s]\n", req_path);
bb7cd1
+    DEBUG(SSSDBG_TRACE_FUNC, "Removing a secret from [%s]\n", lc_req->path);
bb7cd1
 
bb7cd1
     tmp_ctx = talloc_new(mem_ctx);
bb7cd1
     if (!tmp_ctx) return ENOMEM;
bb7cd1
 
bb7cd1
-    ret = local_db_dn(mem_ctx, lctx->ldb, req_path, &dn;;
bb7cd1
-    if (ret != EOK) {
bb7cd1
-        DEBUG(SSSDBG_OP_FAILURE,
bb7cd1
-              "local_db_dn failed [%d]: %s\n", ret, sss_strerror(ret));
bb7cd1
-        goto done;
bb7cd1
-    }
bb7cd1
-
bb7cd1
     DEBUG(SSSDBG_TRACE_INTERNAL,
bb7cd1
           "Searching for [%s] at [%s] with scope=base\n",
bb7cd1
-          LOCAL_CONTAINER_FILTER, ldb_dn_get_linearized(dn));
bb7cd1
+          LOCAL_CONTAINER_FILTER, ldb_dn_get_linearized(lc_req->basedn));
bb7cd1
 
bb7cd1
-    ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE,
bb7cd1
-                    attrs, LOCAL_CONTAINER_FILTER);
bb7cd1
+    ret = ldb_search(lctx->ldb, tmp_ctx, &res, lc_req->basedn, LDB_SCOPE_BASE,
bb7cd1
+                     attrs, LOCAL_CONTAINER_FILTER);
bb7cd1
     if (ret != EOK) {
bb7cd1
         DEBUG(SSSDBG_TRACE_LIBS,
bb7cd1
               "ldb_search returned %d: %s\n", ret, ldb_strerror(ret));
bb7cd1
@@ -619,8 +594,8 @@ static int local_db_delete(TALLOC_CTX *mem_ctx,
bb7cd1
 
bb7cd1
     if (res->count == 1) {
bb7cd1
         DEBUG(SSSDBG_TRACE_INTERNAL,
bb7cd1
-              "Searching for children of [%s]\n", ldb_dn_get_linearized(dn));
bb7cd1
-        ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_ONELEVEL,
bb7cd1
+              "Searching for children of [%s]\n", ldb_dn_get_linearized(lc_req->basedn));
bb7cd1
+        ret = ldb_search(lctx->ldb, tmp_ctx, &res, lc_req->basedn, LDB_SCOPE_ONELEVEL,
bb7cd1
                          attrs, NULL);
bb7cd1
         if (ret != EOK) {
bb7cd1
             DEBUG(SSSDBG_TRACE_LIBS,
bb7cd1
@@ -632,13 +607,13 @@ static int local_db_delete(TALLOC_CTX *mem_ctx,
bb7cd1
             ret = EEXIST;
bb7cd1
             DEBUG(SSSDBG_OP_FAILURE,
bb7cd1
                   "Failed to remove '%s': Container is not empty\n",
bb7cd1
-                  ldb_dn_get_linearized(dn));
bb7cd1
+                  ldb_dn_get_linearized(lc_req->basedn));
bb7cd1
 
bb7cd1
             goto done;
bb7cd1
         }
bb7cd1
     }
bb7cd1
 
bb7cd1
-    ret = ldb_delete(lctx->ldb, dn);
bb7cd1
+    ret = ldb_delete(lctx->ldb, lc_req->basedn);
bb7cd1
     if (ret != EOK) {
bb7cd1
         DEBUG(SSSDBG_TRACE_LIBS,
bb7cd1
               "ldb_delete returned %d: %s\n", ret, ldb_strerror(ret));
bb7cd1
@@ -653,25 +628,19 @@ done:
bb7cd1
 
bb7cd1
 static int local_db_create(TALLOC_CTX *mem_ctx,
bb7cd1
                            struct local_context *lctx,
bb7cd1
-                           const char *req_path)
bb7cd1
+                           struct local_db_req *lc_req)
bb7cd1
 {
bb7cd1
     struct ldb_message *msg;
bb7cd1
     int ret;
bb7cd1
 
bb7cd1
+    DEBUG(SSSDBG_TRACE_FUNC, "Creating a container at [%s]\n", lc_req->path);
bb7cd1
+
bb7cd1
     msg = ldb_msg_new(mem_ctx);
bb7cd1
     if (!msg) {
bb7cd1
         ret = ENOMEM;
bb7cd1
         goto done;
bb7cd1
     }
bb7cd1
-
bb7cd1
-    DEBUG(SSSDBG_TRACE_FUNC, "Creating a container at [%s]\n", req_path);
bb7cd1
-
bb7cd1
-    ret = local_db_dn(msg, lctx->ldb, req_path, &msg->dn);
bb7cd1
-    if (ret != EOK) {
bb7cd1
-        DEBUG(SSSDBG_OP_FAILURE,
bb7cd1
-              "local_db_dn failed [%d]: %s\n", ret, sss_strerror(ret));
bb7cd1
-        goto done;
bb7cd1
-    }
bb7cd1
+    msg->dn = lc_req->basedn;
bb7cd1
 
bb7cd1
     /* make sure containers exist */
bb7cd1
     ret = local_db_check_containers(msg, lctx, msg->dn);
bb7cd1
@@ -724,10 +693,13 @@ done:
bb7cd1
 }
bb7cd1
 
bb7cd1
 static int local_secrets_map_path(TALLOC_CTX *mem_ctx,
bb7cd1
+                                  struct ldb_context *ldb,
bb7cd1
                                   struct sec_req_ctx *secreq,
bb7cd1
-                                  char **local_db_path)
bb7cd1
+                                  struct local_db_req **_lc_req)
bb7cd1
 {
bb7cd1
     int ret;
bb7cd1
+    struct local_db_req *lc_req;
bb7cd1
+    const char *basedn;
bb7cd1
 
bb7cd1
     /* be strict for now */
bb7cd1
     if (secreq->parsed_url.fragment != NULL) {
bb7cd1
@@ -755,20 +727,46 @@ static int local_secrets_map_path(TALLOC_CTX *mem_ctx,
bb7cd1
         }
bb7cd1
     }
bb7cd1
 
bb7cd1
-    /* drop SEC_BASEPATH prefix */
bb7cd1
-    *local_db_path =
bb7cd1
-        talloc_strdup(mem_ctx, &secreq->mapped_path[sizeof(SEC_BASEPATH) - 1]);
bb7cd1
-    if (!*local_db_path) {
bb7cd1
-        DEBUG(SSSDBG_CRIT_FAILURE,
bb7cd1
-              "Failed to map request to local db path\n");
bb7cd1
+    lc_req = talloc(mem_ctx, struct local_db_req);
bb7cd1
+    if (lc_req == NULL) {
bb7cd1
         return ENOMEM;
bb7cd1
     }
bb7cd1
 
bb7cd1
-    DEBUG(SSSDBG_TRACE_LIBS, "Local DB path is %s\n", *local_db_path);
bb7cd1
-    return EOK;
bb7cd1
+    /* drop the prefix and select a basedn instead */
bb7cd1
+    if (strncmp(secreq->mapped_path,
bb7cd1
+                SEC_BASEPATH, sizeof(SEC_BASEPATH) - 1) == 0) {
bb7cd1
+        lc_req->path = talloc_strdup(lc_req,
bb7cd1
+                                     secreq->mapped_path + (sizeof(SEC_BASEPATH) - 1));
bb7cd1
+        basedn = SECRETS_BASEDN;
bb7cd1
+    } else {
bb7cd1
+        ret = EINVAL;
bb7cd1
+        goto done;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    if (lc_req->path == NULL) {
bb7cd1
+        DEBUG(SSSDBG_CRIT_FAILURE,
bb7cd1
+              "Failed to map request to local db path\n");
bb7cd1
+        ret = ENOMEM;
bb7cd1
+        goto done;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    ret = local_db_dn(mem_ctx, ldb, basedn, lc_req->path, &lc_req->basedn);
bb7cd1
+    if (ret != EOK) {
bb7cd1
+        DEBUG(SSSDBG_CRIT_FAILURE,
bb7cd1
+              "Failed to map request to local db DN\n");
bb7cd1
+        goto done;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    DEBUG(SSSDBG_TRACE_LIBS, "Local DB path is %s\n", lc_req->path);
bb7cd1
+    ret = EOK;
bb7cd1
+    *_lc_req = lc_req;
bb7cd1
+done:
bb7cd1
+    if (ret != EOK) {
bb7cd1
+        talloc_free(lc_req);
bb7cd1
+    }
bb7cd1
+    return ret;
bb7cd1
 }
bb7cd1
 
bb7cd1
-
bb7cd1
 struct local_secret_state {
bb7cd1
     struct tevent_context *ev;
bb7cd1
     struct sec_req_ctx *secreq;
bb7cd1
@@ -785,7 +783,7 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
bb7cd1
     struct sec_data body = { 0 };
bb7cd1
     const char *content_type;
bb7cd1
     bool body_is_json;
bb7cd1
-    char *req_path;
bb7cd1
+    struct local_db_req *lc_req;
bb7cd1
     char *secret;
bb7cd1
     char **keys;
bb7cd1
     int nkeys;
bb7cd1
@@ -821,14 +819,14 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
bb7cd1
     }
bb7cd1
     DEBUG(SSSDBG_TRACE_LIBS, "Content-Type: %s\n", content_type);
bb7cd1
 
bb7cd1
-    ret = local_secrets_map_path(state, secreq, &req_path);
bb7cd1
+    ret = local_secrets_map_path(state, lctx->ldb, secreq, &lc_req);
bb7cd1
     if (ret) goto done;
bb7cd1
 
bb7cd1
     switch (secreq->method) {
bb7cd1
     case HTTP_GET:
bb7cd1
-        DEBUG(SSSDBG_TRACE_LIBS, "Processing HTTP GET at [%s]\n", req_path);
bb7cd1
-        if (req_path[strlen(req_path) - 1] == '/') {
bb7cd1
-            ret = local_db_list_keys(state, lctx, req_path, &keys, &nkeys);
bb7cd1
+        DEBUG(SSSDBG_TRACE_LIBS, "Processing HTTP GET at [%s]\n", lc_req->path);
bb7cd1
+        if (lc_req->path[strlen(lc_req->path) - 1] == '/') {
bb7cd1
+            ret = local_db_list_keys(state, lctx, lc_req, &keys, &nkeys);
bb7cd1
             if (ret) goto done;
bb7cd1
 
bb7cd1
             ret = sec_array_to_json(state, keys, nkeys, &body.data);
bb7cd1
@@ -838,7 +836,7 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
bb7cd1
             break;
bb7cd1
         }
bb7cd1
 
bb7cd1
-        ret = local_db_get_simple(state, lctx, req_path, &secret);
bb7cd1
+        ret = local_db_get_simple(state, lctx, lc_req, &secret);
bb7cd1
         if (ret) goto done;
bb7cd1
 
bb7cd1
         if (body_is_json) {
bb7cd1
@@ -855,7 +853,7 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
bb7cd1
         break;
bb7cd1
 
bb7cd1
     case HTTP_PUT:
bb7cd1
-        DEBUG(SSSDBG_TRACE_LIBS, "Processing HTTP PUT at [%s]\n", req_path);
bb7cd1
+        DEBUG(SSSDBG_TRACE_LIBS, "Processing HTTP PUT at [%s]\n", lc_req->path);
bb7cd1
         if (body_is_json) {
bb7cd1
             ret = sec_json_to_simple_secret(state, secreq->body.data,
bb7cd1
                                             &secret);
bb7cd1
@@ -866,27 +864,27 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
bb7cd1
         }
bb7cd1
         if (ret) goto done;
bb7cd1
 
bb7cd1
-        ret = local_db_put_simple(state, lctx, req_path, secret);
bb7cd1
+        ret = local_db_put_simple(state, lctx, lc_req, secret);
bb7cd1
         if (ret) goto done;
bb7cd1
         break;
bb7cd1
 
bb7cd1
     case HTTP_DELETE:
bb7cd1
-        ret = local_db_delete(state, lctx, req_path);
bb7cd1
+        ret = local_db_delete(state, lctx, lc_req);
bb7cd1
         if (ret) goto done;
bb7cd1
         break;
bb7cd1
 
bb7cd1
     case HTTP_POST:
bb7cd1
-        DEBUG(SSSDBG_TRACE_LIBS, "Processing HTTP POST at [%s]\n", req_path);
bb7cd1
-        plen = strlen(req_path);
bb7cd1
+        DEBUG(SSSDBG_TRACE_LIBS, "Processing HTTP POST at [%s]\n", lc_req->path);
bb7cd1
+        plen = strlen(lc_req->path);
bb7cd1
 
bb7cd1
-        if (req_path[plen - 1] != '/') {
bb7cd1
+        if (lc_req->path[plen - 1] != '/') {
bb7cd1
             ret = EINVAL;
bb7cd1
             goto done;
bb7cd1
         }
bb7cd1
 
bb7cd1
-        req_path[plen - 1] = '\0';
bb7cd1
+        lc_req->path[plen - 1] = '\0';
bb7cd1
 
bb7cd1
-        ret = local_db_create(state, lctx, req_path);
bb7cd1
+        ret = local_db_create(state, lctx, lc_req);
bb7cd1
         if (ret) goto done;
bb7cd1
         break;
bb7cd1
 
bb7cd1
-- 
bb7cd1
2.9.3
bb7cd1