From b1fe893002a506ace1b2930a0cb5d5bd5d4fa9f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= Date: Thu, 1 Sep 2016 12:04:30 +0200 Subject: [PATCH 64/79] SECRETS: Don't remove a container when it has children MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's return and log an error in case the container to be removed has children. The approach taken introduced at least one new search in every delete operation. As far as I understand searching in the BASE scope is quite cheap and that's the reason I decided to just do the search in the ONELEVEL scope when the requested to be deleted dn is for sure a container. Resolves: https://fedorahosted.org/sssd/ticket/3167 Signed-off-by: Fabiano FidĂȘncio Reviewed-by: Jakub Hrozek (cherry picked from commit ab7b33fd7d820688545d5994a402cedf4bcdb6e1) --- src/responder/secrets/local.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/responder/secrets/local.c b/src/responder/secrets/local.c index 5b5745d6732987c6057788b2099f45ad0799f151..b13e77f0453f3201d1f9f352bb0b331792de1106 100644 --- a/src/responder/secrets/local.c +++ b/src/responder/secrets/local.c @@ -372,14 +372,43 @@ int local_db_delete(TALLOC_CTX *mem_ctx, struct local_context *lctx, const char *req_path) { + TALLOC_CTX *tmp_ctx; struct ldb_dn *dn; + static const char *attrs[] = { NULL }; + struct ldb_result *res; int ret; + tmp_ctx = talloc_new(mem_ctx); + if (!tmp_ctx) return ENOMEM; + ret = local_db_dn(mem_ctx, lctx->ldb, req_path, &dn); - if (ret != EOK) return ret; + if (ret != EOK) goto done; + + ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, + attrs, LOCAL_CONTAINER_FILTER); + if (ret != EOK) goto done; + + if (res->count == 1) { + ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_ONELEVEL, + attrs, NULL); + if (ret != EOK) goto done; + + if (res->count > 0) { + ret = EEXIST; + DEBUG(SSSDBG_OP_FAILURE, + "Failed to remove '%s': Container is not empty\n", + ldb_dn_get_linearized(dn)); + + goto done; + } + } ret = ldb_delete(lctx->ldb, dn); - return sysdb_error_to_errno(ret); + ret = sysdb_error_to_errno(ret); + +done: + talloc_free(tmp_ctx); + return ret; } int local_db_create(TALLOC_CTX *mem_ctx, -- 2.9.3