summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/util/util_ldb.c95
-rw-r--r--lib/util/util_ldb.h8
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__ */