diff options
author | Fabiano FidĂȘncio <fidencio@redhat.com> | 2016-09-01 12:04:30 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2016-09-16 15:14:04 +0200 |
commit | ab7b33fd7d820688545d5994a402cedf4bcdb6e1 (patch) | |
tree | 6447b25bc7e66286c2556e08fe6c6dd01ebada5d | |
parent | 35ba922bc51416f02877b53a6f25c04104ae5f03 (diff) | |
download | sssd-ab7b33fd7d820688545d5994a402cedf4bcdb6e1.tar.gz sssd-ab7b33fd7d820688545d5994a402cedf4bcdb6e1.tar.xz sssd-ab7b33fd7d820688545d5994a402cedf4bcdb6e1.zip |
SECRETS: Don't remove a container when it has children
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 <fidencio@redhat.com>
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
-rw-r--r-- | src/responder/secrets/local.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/src/responder/secrets/local.c b/src/responder/secrets/local.c index 5b5745d67..b13e77f04 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, |