summaryrefslogtreecommitdiff
path: root/lib/util/util_ldb.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2009-06-02 17:27:37 +1000
committerAndrew Tridgell <tridge@samba.org>2009-06-04 14:10:11 +1000
commit8ca8dabe4615416153be9be7be16558e43d17381 (patch)
tree880fb0f26e8ca7596b07873377b24084f6491c6e /lib/util/util_ldb.c
parentda3ee2790089e771689afbebef021a8c8c776306 (diff)
downloadsamba-8ca8dabe4615416153be9be7be16558e43d17381.tar.gz
samba-8ca8dabe4615416153be9be7be16558e43d17381.tar.bz2
samba-8ca8dabe4615416153be9be7be16558e43d17381.zip
add gendb_search_single_extended_dn()
This function searches for a single record using a given filter, adding the extended-dn control so that any returned DNs will have the GUID and SID fields returned. This will be used in the sam auth code to prevent us doing a member= search for the groups, which invokes an unindexed search.
Diffstat (limited to 'lib/util/util_ldb.c')
-rw-r--r--lib/util/util_ldb.c95
1 files changed, 95 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;
+}