diff options
-rw-r--r-- | source4/lib/ldb/common/ldb.c | 106 | ||||
-rw-r--r-- | source4/lib/ldb/include/ldb.h | 11 |
2 files changed, 112 insertions, 5 deletions
diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c index 28fe34c767..af89748236 100644 --- a/source4/lib/ldb/common/ldb.c +++ b/source4/lib/ldb/common/ldb.c @@ -779,6 +779,112 @@ int ldb_build_rename_req(struct ldb_request **ret_req, return LDB_SUCCESS; } +int ldb_extended_default_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares) +{ + struct ldb_result *res; + + if (!context) { + ldb_set_errstring(ldb, "NULL Context in callback"); + return LDB_ERR_OPERATIONS_ERROR; + } + + res = talloc_get_type(context, struct ldb_result); + if (!res || !ares) { + ldb_set_errstring(ldb, "NULL res or ares in callback"); + goto error; + } + + switch (ares->type) { + case LDB_REPLY_ENTRY: + case LDB_REPLY_REFERRAL: + case LDB_REPLY_DONE: + ldb_set_errstring(ldb, "invalid ares type in callback"); + goto error; + case LDB_REPLY_EXTENDED: + /* TODO: we should really support controls on entries and referrals too! */ + res->extended = talloc_move(res, &ares->response); + res->controls = talloc_move(res, &ares->controls); + break; + } + talloc_free(ares); + return LDB_SUCCESS; + +error: + talloc_free(ares); + return LDB_ERR_OPERATIONS_ERROR; +} + +int ldb_build_extended_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + void *mem_ctx, + const char *oid, + void *data, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback) +{ + struct ldb_request *req; + + *ret_req = NULL; + + req = talloc(mem_ctx, struct ldb_request); + if (req == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return LDB_ERR_OPERATIONS_ERROR; + } + + req->operation = LDB_EXTENDED; + req->op.extended.oid = oid; + req->op.extended.data = data; + req->controls = controls; + req->context = context; + req->callback = callback; + + *ret_req = req; + + return LDB_SUCCESS; +} + +int ldb_extended(struct ldb_context *ldb, + const char *oid, + void *data, + struct ldb_result **_res) +{ + struct ldb_request *req; + int ret; + struct ldb_result *res; + + *_res = NULL; + + res = talloc_zero(ldb, struct ldb_result); + if (!res) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_build_extended_req(&req, ldb, ldb, + oid, data, NULL, + res, ldb_extended_default_callback); + if (ret != LDB_SUCCESS) goto done; + + ldb_set_timeout(ldb, req, 0); /* use default timeout */ + + ret = ldb_request(ldb, req); + + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + talloc_free(req); + +done: + if (ret != LDB_SUCCESS) { + talloc_free(res); + } + + *_res = res; + return ret; +} + /* note that ldb_search() will automatically replace a NULL 'base' value with the defaultNamingContext from the rootDSE if available. diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index 63cfb04fdd..78d5bba06e 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -674,18 +674,19 @@ enum ldb_state { LDB_ASYNC_DONE }; +struct ldb_extended { + const char *oid; + void *data; +}; + struct ldb_result { unsigned int count; struct ldb_message **msgs; char **refs; + struct ldb_extended *extended; struct ldb_control **controls; }; -struct ldb_extended { - const char *oid; - void *data; -}; - struct ldb_reply { enum ldb_reply_type type; struct ldb_message *message; |