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

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