diff options
-rw-r--r-- | lib/util/util_ldb.c | 95 | ||||
-rw-r--r-- | lib/util/util_ldb.h | 8 |
2 files changed, 103 insertions, 0 deletions
diff --git a/lib/util/util_ldb.c b/lib/util/util_ldb.c index c11b6879d2..6aea77691b 100644 --- a/lib/util/util_ldb.c +++ b/lib/util/util_ldb.c @@ -130,3 +130,98 @@ char *wrap_casefold(void *context, void *mem_ctx, const char *s, size_t n) } + +/* + search the LDB for a single record, with the extended_dn control + return LDB_SUCCESS on success, or an ldb error code on error + + if the search returns 0 entries, return LDB_ERR_NO_SUCH_OBJECT + if the search returns more than 1 entry, return LDB_ERR_CONSTRAINT_VIOLATION +*/ +int gendb_search_single_extended_dn(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_dn *basedn, + enum ldb_scope scope, + struct ldb_message **msg, + const char * const *attrs, + const char *format, ...) +{ + va_list ap; + int ret; + struct ldb_request *req; + char *filter; + TALLOC_CTX *tmp_ctx; + struct ldb_result *res; + struct ldb_extended_dn_control *ctrl; + + tmp_ctx = talloc_new(mem_ctx); + + res = talloc_zero(tmp_ctx, struct ldb_result); + if (!res) { + return LDB_ERR_OPERATIONS_ERROR; + } + + va_start(ap, format); + filter = talloc_vasprintf(tmp_ctx, format, ap); + va_end(ap); + + if (filter == NULL) { + talloc_free(tmp_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_build_search_req(&req, ldb, tmp_ctx, + basedn, + scope, + filter, + attrs, + NULL, + res, + ldb_search_default_callback, + NULL); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + + ctrl = talloc(tmp_ctx, struct ldb_extended_dn_control); + if (ctrl == NULL) { + talloc_free(tmp_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + + ctrl->type = 1; + + ret = ldb_request_add_control(req, LDB_CONTROL_EXTENDED_DN_OID, true, ctrl); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_request(ldb, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return ret; + } + + if (res->count == 0) { + talloc_free(tmp_ctx); + return LDB_ERR_NO_SUCH_OBJECT; + } + + if (res->count > 1) { + /* the function is only supposed to return a single + entry */ + talloc_free(tmp_ctx); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + *msg = talloc_steal(mem_ctx, res->msgs[0]); + + talloc_free(tmp_ctx); + + return LDB_SUCCESS; +} diff --git a/lib/util/util_ldb.h b/lib/util/util_ldb.h index f9eb028916..4575c6565a 100644 --- a/lib/util/util_ldb.h +++ b/lib/util/util_ldb.h @@ -26,4 +26,12 @@ int gendb_search_dn(struct ldb_context *ldb, int gendb_add_ldif(struct ldb_context *ldb, const char *ldif_string); char *wrap_casefold(void *context, void *mem_ctx, const char *s, size_t n); +int gendb_search_single_extended_dn(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_dn *basedn, + enum ldb_scope scope, + struct ldb_message **msg, + const char * const *attrs, + const char *format, ...) PRINTF_ATTRIBUTE(7,8); + #endif /* __LIB_UTIL_UTIL_LDB_H__ */ |