diff options
author | Andrew Bartlett <abartlet@samba.org> | 2011-07-05 10:01:32 +1000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2011-07-05 17:24:47 +1000 |
commit | 8420a36dc7fe72fb665e065b8673fa44ff1bbf21 (patch) | |
tree | 5350041c1de4cdc73a813949f7cd154c423b3ec5 /source4/lib/ldb-samba | |
parent | c9a6dd56e42beafd297f4aefeb4e00ef9a09073a (diff) | |
download | samba-8420a36dc7fe72fb665e065b8673fa44ff1bbf21.tar.gz samba-8420a36dc7fe72fb665e065b8673fa44ff1bbf21.tar.bz2 samba-8420a36dc7fe72fb665e065b8673fa44ff1bbf21.zip |
ldb: make ldb a top level library for Samba 4.0
Signed-off-by: Andrew Tridgell <tridge@samba.org>
Diffstat (limited to 'source4/lib/ldb-samba')
-rw-r--r-- | source4/lib/ldb-samba/README | 7 | ||||
-rw-r--r-- | source4/lib/ldb-samba/ldb_ildap.c | 879 | ||||
-rw-r--r-- | source4/lib/ldb-samba/ldb_wrap.c | 365 | ||||
-rw-r--r-- | source4/lib/ldb-samba/ldb_wrap.h | 70 | ||||
-rw-r--r-- | source4/lib/ldb-samba/ldif_handlers.c | 1416 | ||||
-rw-r--r-- | source4/lib/ldb-samba/ldif_handlers.h | 23 | ||||
-rw-r--r-- | source4/lib/ldb-samba/pyldb.c | 270 | ||||
-rw-r--r-- | source4/lib/ldb-samba/samba_extensions.c | 119 | ||||
-rw-r--r-- | source4/lib/ldb-samba/wscript_build | 42 |
9 files changed, 0 insertions, 3191 deletions
diff --git a/source4/lib/ldb-samba/README b/source4/lib/ldb-samba/README deleted file mode 100644 index 3fa47159ca..0000000000 --- a/source4/lib/ldb-samba/README +++ /dev/null @@ -1,7 +0,0 @@ -This directory contains Samba specific extensions to ldb. It also -serves as example code on how to extend ldb for your own application. - -The main extension Samba uses is to provide ldif encode/decode -routines for specific attributes, so users can get nice pretty -printing of attributes in ldbedit, while the attributes are stored in -the standard NDR format in the database. diff --git a/source4/lib/ldb-samba/ldb_ildap.c b/source4/lib/ldb-samba/ldb_ildap.c deleted file mode 100644 index 3c28690bd6..0000000000 --- a/source4/lib/ldb-samba/ldb_ildap.c +++ /dev/null @@ -1,879 +0,0 @@ -/* - ldb database library - ildap backend - - Copyright (C) Andrew Tridgell 2005 - Copyright (C) Simo Sorce 2008 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -/* - * Name: ldb_ildap - * - * Component: ldb ildap backend - * - * Description: This is a ldb backend for the internal ldap - * client library in Samba4. By using this backend we are - * independent of a system ldap library - * - * Author: Andrew Tridgell - * - * Modifications: - * - * - description: make the module use asynchronous calls - * date: Feb 2006 - * author: Simo Sorce - */ - -#include "includes.h" -#include "ldb_module.h" -#include "util/dlinklist.h" - -#include "libcli/ldap/libcli_ldap.h" -#include "libcli/ldap/ldap_client.h" -#include "auth/auth.h" -#include "auth/credentials/credentials.h" - -struct ildb_private { - struct ldap_connection *ldap; - struct tevent_context *event_ctx; -}; - -struct ildb_context { - struct ldb_module *module; - struct ldb_request *req; - - struct ildb_private *ildb; - struct ldap_request *ireq; - - /* indicate we are already processing - * the ldap_request in ildb_callback() */ - bool in_ildb_callback; - - bool done; - - struct ildb_destructor_ctx *dc; -}; - -static void ildb_request_done(struct ildb_context *ctx, - struct ldb_control **ctrls, int error) -{ - struct ldb_context *ldb; - struct ldb_reply *ares; - - ldb = ldb_module_get_ctx(ctx->module); - - ctx->done = true; - - if (ctx->req == NULL) { - /* if the req has been freed already just return */ - return; - } - - ares = talloc_zero(ctx->req, struct ldb_reply); - if (!ares) { - ldb_oom(ldb); - ctx->req->callback(ctx->req, NULL); - return; - } - ares->type = LDB_REPLY_DONE; - ares->controls = talloc_steal(ares, ctrls); - ares->error = error; - - ctx->req->callback(ctx->req, ares); -} - -static void ildb_auto_done_callback(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval t, - void *private_data) -{ - struct ildb_context *ac; - - ac = talloc_get_type(private_data, struct ildb_context); - ildb_request_done(ac, NULL, LDB_SUCCESS); -} - -/* - convert a ldb_message structure to a list of ldap_mod structures - ready for ildap_add() or ildap_modify() -*/ -static struct ldap_mod **ildb_msg_to_mods(void *mem_ctx, int *num_mods, - const struct ldb_message *msg, - int use_flags) -{ - struct ldap_mod **mods; - unsigned int i; - int n = 0; - - /* allocate maximum number of elements needed */ - mods = talloc_array(mem_ctx, struct ldap_mod *, msg->num_elements+1); - if (!mods) { - errno = ENOMEM; - return NULL; - } - mods[0] = NULL; - - for (i = 0; i < msg->num_elements; i++) { - const struct ldb_message_element *el = &msg->elements[i]; - - mods[n] = talloc(mods, struct ldap_mod); - if (!mods[n]) { - goto failed; - } - mods[n + 1] = NULL; - mods[n]->type = 0; - mods[n]->attrib = *el; - if (use_flags) { - switch (el->flags & LDB_FLAG_MOD_MASK) { - case LDB_FLAG_MOD_ADD: - mods[n]->type = LDAP_MODIFY_ADD; - break; - case LDB_FLAG_MOD_DELETE: - mods[n]->type = LDAP_MODIFY_DELETE; - break; - case LDB_FLAG_MOD_REPLACE: - mods[n]->type = LDAP_MODIFY_REPLACE; - break; - } - } - n++; - } - - *num_mods = n; - return mods; - -failed: - talloc_free(mods); - return NULL; -} - - -/* - map an ildap NTSTATUS to a ldb error code -*/ -static int ildb_map_error(struct ldb_module *module, NTSTATUS status) -{ - struct ildb_private *ildb; - struct ldb_context *ldb; - TALLOC_CTX *mem_ctx; - - ildb = talloc_get_type(ldb_module_get_private(module), struct ildb_private); - ldb = ldb_module_get_ctx(module); - - if (NT_STATUS_IS_OK(status)) { - return LDB_SUCCESS; - } - - mem_ctx = talloc_new(ildb); - if (!mem_ctx) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - ldb_set_errstring(ldb, - ldap_errstr(ildb->ldap, mem_ctx, status)); - talloc_free(mem_ctx); - if (NT_STATUS_IS_LDAP(status)) { - return NT_STATUS_LDAP_CODE(status); - } - return LDB_ERR_OPERATIONS_ERROR; -} - -static void ildb_request_timeout(struct tevent_context *ev, struct tevent_timer *te, - struct timeval t, void *private_data) -{ - struct ildb_context *ac = talloc_get_type(private_data, struct ildb_context); - - if (ac->ireq->state == LDAP_REQUEST_PENDING) { - DLIST_REMOVE(ac->ireq->conn->pending, ac->ireq); - } - - ildb_request_done(ac, NULL, LDB_ERR_TIME_LIMIT_EXCEEDED); -} - -static void ildb_callback(struct ldap_request *req) -{ - struct ldb_context *ldb; - struct ildb_context *ac; - NTSTATUS status; - struct ldap_SearchResEntry *search; - struct ldap_message *msg; - struct ldb_control **controls; - struct ldb_message *ldbmsg; - char *referral; - bool callback_failed; - bool request_done; - int ret; - int i; - - ac = talloc_get_type(req->async.private_data, struct ildb_context); - ldb = ldb_module_get_ctx(ac->module); - callback_failed = false; - request_done = false; - controls = NULL; - - /* check if we are already processing this request */ - if (ac->in_ildb_callback) { - return; - } - /* mark the request as being in process */ - ac->in_ildb_callback = true; - - if (!NT_STATUS_IS_OK(req->status)) { - ret = ildb_map_error(ac->module, req->status); - ildb_request_done(ac, NULL, ret); - return; - } - - if (req->num_replies < 1) { - ret = LDB_ERR_OPERATIONS_ERROR; - ildb_request_done(ac, NULL, ret); - return; - } - - switch (req->type) { - - case LDAP_TAG_ModifyRequest: - if (req->replies[0]->type != LDAP_TAG_ModifyResponse) { - ret = LDB_ERR_PROTOCOL_ERROR; - break; - } - status = ldap_check_response(ac->ireq->conn, &req->replies[0]->r.GeneralResult); - ret = ildb_map_error(ac->module, status); - request_done = true; - break; - - case LDAP_TAG_AddRequest: - if (req->replies[0]->type != LDAP_TAG_AddResponse) { - ret = LDB_ERR_PROTOCOL_ERROR; - return; - } - status = ldap_check_response(ac->ireq->conn, &req->replies[0]->r.GeneralResult); - ret = ildb_map_error(ac->module, status); - request_done = true; - break; - - case LDAP_TAG_DelRequest: - if (req->replies[0]->type != LDAP_TAG_DelResponse) { - ret = LDB_ERR_PROTOCOL_ERROR; - return; - } - status = ldap_check_response(ac->ireq->conn, &req->replies[0]->r.GeneralResult); - ret = ildb_map_error(ac->module, status); - request_done = true; - break; - - case LDAP_TAG_ModifyDNRequest: - if (req->replies[0]->type != LDAP_TAG_ModifyDNResponse) { - ret = LDB_ERR_PROTOCOL_ERROR; - return; - } - status = ldap_check_response(ac->ireq->conn, &req->replies[0]->r.GeneralResult); - ret = ildb_map_error(ac->module, status); - request_done = true; - break; - - case LDAP_TAG_SearchRequest: - /* loop over all messages */ - for (i = 0; i < req->num_replies; i++) { - - msg = req->replies[i]; - switch (msg->type) { - - case LDAP_TAG_SearchResultDone: - - status = ldap_check_response(ac->ireq->conn, &msg->r.GeneralResult); - if (!NT_STATUS_IS_OK(status)) { - ret = ildb_map_error(ac->module, status); - break; - } - - controls = talloc_steal(ac, msg->controls); - if (msg->r.SearchResultDone.resultcode) { - if (msg->r.SearchResultDone.errormessage) { - ldb_set_errstring(ldb, msg->r.SearchResultDone.errormessage); - } - } - - ret = msg->r.SearchResultDone.resultcode; - request_done = true; - break; - - case LDAP_TAG_SearchResultEntry: - - ldbmsg = ldb_msg_new(ac); - if (!ldbmsg) { - ret = LDB_ERR_OPERATIONS_ERROR; - break; - } - - search = &(msg->r.SearchResultEntry); - - ldbmsg->dn = ldb_dn_new(ldbmsg, ldb, search->dn); - if ( ! ldb_dn_validate(ldbmsg->dn)) { - ret = LDB_ERR_OPERATIONS_ERROR; - break; - } - ldbmsg->num_elements = search->num_attributes; - ldbmsg->elements = talloc_move(ldbmsg, &search->attributes); - - controls = talloc_steal(ac, msg->controls); - - ret = ldb_module_send_entry(ac->req, ldbmsg, controls); - if (ret != LDB_SUCCESS) { - callback_failed = true; - } - - break; - - case LDAP_TAG_SearchResultReference: - - referral = talloc_strdup(ac, msg->r.SearchResultReference.referral); - - ret = ldb_module_send_referral(ac->req, referral); - if (ret != LDB_SUCCESS) { - callback_failed = true; - } - - break; - - default: - /* TAG not handled, fail ! */ - ret = LDB_ERR_PROTOCOL_ERROR; - break; - } - - if (ret != LDB_SUCCESS) { - break; - } - } - - talloc_free(req->replies); - req->replies = NULL; - req->num_replies = 0; - - break; - - default: - ret = LDB_ERR_PROTOCOL_ERROR; - break; - } - - if (ret != LDB_SUCCESS) { - - /* if the callback failed the caller will have freed the - * request. Just return and don't try to use it */ - if ( ! callback_failed) { - request_done = true; - } - } - - /* mark the request as not being in progress */ - ac->in_ildb_callback = false; - - if (request_done) { - ildb_request_done(ac, controls, ret); - } - - return; -} - -static int ildb_request_send(struct ildb_context *ac, struct ldap_message *msg) -{ - struct ldb_context *ldb; - struct ldap_request *req; - - if (!ac) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ldb = ldb_module_get_ctx(ac->module); - - ldb_request_set_state(ac->req, LDB_ASYNC_PENDING); - - req = ldap_request_send(ac->ildb->ldap, msg); - if (req == NULL) { - ldb_set_errstring(ldb, "async send request failed"); - return LDB_ERR_OPERATIONS_ERROR; - } - ac->ireq = talloc_reparent(ac->ildb->ldap, ac, req); - - if (!ac->ireq->conn) { - ldb_set_errstring(ldb, "connection to remote LDAP server dropped?"); - return LDB_ERR_OPERATIONS_ERROR; - } - - talloc_free(req->time_event); - req->time_event = NULL; - if (ac->req->timeout) { - req->time_event = tevent_add_timer(ac->ildb->event_ctx, ac, - timeval_current_ofs(ac->req->timeout, 0), - ildb_request_timeout, ac); - } - - req->async.fn = ildb_callback; - req->async.private_data = ac; - - return LDB_SUCCESS; -} - -/* - search for matching records using an asynchronous function - */ -static int ildb_search(struct ildb_context *ac) -{ - struct ldb_context *ldb; - struct ldb_request *req = ac->req; - struct ldap_message *msg; - int n; - - ldb = ldb_module_get_ctx(ac->module); - - if (!req->callback || !req->context) { - ldb_set_errstring(ldb, "Async interface called with NULL callback function or NULL context"); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (req->op.search.tree == NULL) { - ldb_set_errstring(ldb, "Invalid expression parse tree"); - return LDB_ERR_OPERATIONS_ERROR; - } - - msg = new_ldap_message(req); - if (msg == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->type = LDAP_TAG_SearchRequest; - - if (req->op.search.base == NULL) { - msg->r.SearchRequest.basedn = talloc_strdup(msg, ""); - } else { - msg->r.SearchRequest.basedn = ldb_dn_get_extended_linearized(msg, req->op.search.base, 0); - } - if (msg->r.SearchRequest.basedn == NULL) { - ldb_set_errstring(ldb, "Unable to determine baseDN"); - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (req->op.search.scope == LDB_SCOPE_DEFAULT) { - msg->r.SearchRequest.scope = LDB_SCOPE_SUBTREE; - } else { - msg->r.SearchRequest.scope = req->op.search.scope; - } - - msg->r.SearchRequest.deref = LDAP_DEREFERENCE_NEVER; - msg->r.SearchRequest.timelimit = 0; - msg->r.SearchRequest.sizelimit = 0; - msg->r.SearchRequest.attributesonly = 0; - msg->r.SearchRequest.tree = discard_const(req->op.search.tree); - - for (n = 0; req->op.search.attrs && req->op.search.attrs[n]; n++) /* noop */ ; - msg->r.SearchRequest.num_attributes = n; - msg->r.SearchRequest.attributes = req->op.search.attrs; - msg->controls = req->controls; - - return ildb_request_send(ac, msg); -} - -/* - add a record -*/ -static int ildb_add(struct ildb_context *ac) -{ - struct ldb_request *req = ac->req; - struct ldap_message *msg; - struct ldap_mod **mods; - int i,n; - - msg = new_ldap_message(req); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->type = LDAP_TAG_AddRequest; - - msg->r.AddRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.add.message->dn, 0); - if (msg->r.AddRequest.dn == NULL) { - talloc_free(msg); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - mods = ildb_msg_to_mods(msg, &n, req->op.add.message, 0); - if (mods == NULL) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->r.AddRequest.num_attributes = n; - msg->r.AddRequest.attributes = talloc_array(msg, struct ldb_message_element, n); - if (msg->r.AddRequest.attributes == NULL) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - for (i = 0; i < n; i++) { - msg->r.AddRequest.attributes[i] = mods[i]->attrib; - } - msg->controls = req->controls; - - return ildb_request_send(ac, msg); -} - -/* - modify a record -*/ -static int ildb_modify(struct ildb_context *ac) -{ - struct ldb_request *req = ac->req; - struct ldap_message *msg; - struct ldap_mod **mods; - int i,n; - - msg = new_ldap_message(req); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->type = LDAP_TAG_ModifyRequest; - - msg->r.ModifyRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.mod.message->dn, 0); - if (msg->r.ModifyRequest.dn == NULL) { - talloc_free(msg); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - mods = ildb_msg_to_mods(msg, &n, req->op.mod.message, 1); - if (mods == NULL) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->r.ModifyRequest.num_mods = n; - msg->r.ModifyRequest.mods = talloc_array(msg, struct ldap_mod, n); - if (msg->r.ModifyRequest.mods == NULL) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - for (i = 0; i < n; i++) { - msg->r.ModifyRequest.mods[i] = *mods[i]; - } - msg->controls = req->controls; - return ildb_request_send(ac, msg); -} - -/* - delete a record -*/ -static int ildb_delete(struct ildb_context *ac) -{ - struct ldb_request *req = ac->req; - struct ldap_message *msg; - - msg = new_ldap_message(req); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->type = LDAP_TAG_DelRequest; - - msg->r.DelRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.del.dn, 0); - if (msg->r.DelRequest.dn == NULL) { - talloc_free(msg); - return LDB_ERR_INVALID_DN_SYNTAX; - } - msg->controls = req->controls; - - return ildb_request_send(ac, msg); -} - -/* - rename a record -*/ -static int ildb_rename(struct ildb_context *ac) -{ - struct ldb_request *req = ac->req; - struct ldap_message *msg; - const char *rdn_name; - const struct ldb_val *rdn_val; - - msg = new_ldap_message(req); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->type = LDAP_TAG_ModifyDNRequest; - msg->r.ModifyDNRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.rename.olddn, 0); - if (msg->r.ModifyDNRequest.dn == NULL) { - talloc_free(msg); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - rdn_name = ldb_dn_get_rdn_name(req->op.rename.newdn); - rdn_val = ldb_dn_get_rdn_val(req->op.rename.newdn); - - if ((rdn_name != NULL) && (rdn_val != NULL)) { - msg->r.ModifyDNRequest.newrdn = - talloc_asprintf(msg, "%s=%s", rdn_name, - rdn_val->length > 0 ? ldb_dn_escape_value(msg, *rdn_val) : ""); - } else { - msg->r.ModifyDNRequest.newrdn = talloc_strdup(msg, ""); - } - if (msg->r.ModifyDNRequest.newrdn == NULL) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->r.ModifyDNRequest.newsuperior = - ldb_dn_alloc_linearized(msg, ldb_dn_get_parent(msg, req->op.rename.newdn)); - if (msg->r.ModifyDNRequest.newsuperior == NULL) { - talloc_free(msg); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - msg->r.ModifyDNRequest.deleteolddn = true; - msg->controls = req->controls; - - return ildb_request_send(ac, msg); -} - -static int ildb_start_trans(struct ldb_module *module) -{ - /* TODO implement a local locking mechanism here */ - - return LDB_SUCCESS; -} - -static int ildb_end_trans(struct ldb_module *module) -{ - /* TODO implement a local transaction mechanism here */ - - return LDB_SUCCESS; -} - -static int ildb_del_trans(struct ldb_module *module) -{ - /* TODO implement a local locking mechanism here */ - - return LDB_SUCCESS; -} - -static bool ildb_dn_is_special(struct ldb_request *req) -{ - struct ldb_dn *dn = NULL; - - switch (req->operation) { - case LDB_ADD: - dn = req->op.add.message->dn; - break; - case LDB_MODIFY: - dn = req->op.mod.message->dn; - break; - case LDB_DELETE: - dn = req->op.del.dn; - break; - case LDB_RENAME: - dn = req->op.rename.olddn; - break; - default: - break; - } - - if (dn && ldb_dn_is_special(dn)) { - return true; - } - return false; -} - -static int ildb_handle_request(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - struct ildb_private *ildb; - struct ildb_context *ac; - struct tevent_timer *te; - int ret; - - ildb = talloc_get_type(ldb_module_get_private(module), struct ildb_private); - ldb = ldb_module_get_ctx(module); - - if (req->starttime == 0 || req->timeout == 0) { - ldb_set_errstring(ldb, "Invalid timeout settings"); - return LDB_ERR_TIME_LIMIT_EXCEEDED; - } - - ac = talloc_zero(req, struct ildb_context); - if (ac == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - ac->ildb = ildb; - - if (ildb_dn_is_special(req)) { - - te = tevent_add_timer(ac->ildb->event_ctx, - ac, timeval_zero(), - ildb_auto_done_callback, ac); - if (NULL == te) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return LDB_SUCCESS; - } - - switch (ac->req->operation) { - case LDB_SEARCH: - ret = ildb_search(ac); - break; - case LDB_ADD: - ret = ildb_add(ac); - break; - case LDB_MODIFY: - ret = ildb_modify(ac); - break; - case LDB_DELETE: - ret = ildb_delete(ac); - break; - case LDB_RENAME: - ret = ildb_rename(ac); - break; - default: - /* no other op supported */ - ret = LDB_ERR_PROTOCOL_ERROR; - break; - } - - return ret; -} - -static const struct ldb_module_ops ildb_ops = { - .name = "ldap", - .search = ildb_handle_request, - .add = ildb_handle_request, - .modify = ildb_handle_request, - .del = ildb_handle_request, - .rename = ildb_handle_request, -/* .request = ildb_handle_request, */ - .start_transaction = ildb_start_trans, - .end_transaction = ildb_end_trans, - .del_transaction = ildb_del_trans, -}; - -/* - connect to the database -*/ -static int ildb_connect(struct ldb_context *ldb, const char *url, - unsigned int flags, const char *options[], - struct ldb_module **_module) -{ - struct ldb_module *module; - struct ildb_private *ildb; - NTSTATUS status; - struct cli_credentials *creds; - struct loadparm_context *lp_ctx; - - module = ldb_module_new(ldb, ldb, "ldb_ildap backend", &ildb_ops); - if (!module) return LDB_ERR_OPERATIONS_ERROR; - - ildb = talloc(module, struct ildb_private); - if (!ildb) { - ldb_oom(ldb); - goto failed; - } - ldb_module_set_private(module, ildb); - - ildb->event_ctx = ldb_get_event_context(ldb); - - lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"), - struct loadparm_context); - - ildb->ldap = ldap4_new_connection(ildb, lp_ctx, - ildb->event_ctx); - if (!ildb->ldap) { - ldb_oom(ldb); - goto failed; - } - - if (flags & LDB_FLG_RECONNECT) { - ldap_set_reconn_params(ildb->ldap, 10); - } - - status = ldap_connect(ildb->ldap, url); - if (!NT_STATUS_IS_OK(status)) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to ldap URL '%s' - %s", - url, ldap_errstr(ildb->ldap, module, status)); - goto failed; - } - - /* caller can optionally setup credentials using the opaque token 'credentials' */ - creds = talloc_get_type(ldb_get_opaque(ldb, "credentials"), struct cli_credentials); - if (creds == NULL) { - struct auth_session_info *session_info = talloc_get_type(ldb_get_opaque(ldb, "sessionInfo"), struct auth_session_info); - if (session_info) { - creds = session_info->credentials; - } - } - - if (creds != NULL && cli_credentials_authentication_requested(creds)) { - const char *bind_dn = cli_credentials_get_bind_dn(creds); - if (bind_dn) { - const char *password = cli_credentials_get_password(creds); - status = ldap_bind_simple(ildb->ldap, bind_dn, password); - if (!NT_STATUS_IS_OK(status)) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s", - ldap_errstr(ildb->ldap, module, status)); - goto failed; - } - } else { - status = ldap_bind_sasl(ildb->ldap, creds, lp_ctx); - if (!NT_STATUS_IS_OK(status)) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s", - ldap_errstr(ildb->ldap, module, status)); - goto failed; - } - } - } - - *_module = module; - return LDB_SUCCESS; - -failed: - talloc_free(module); - return LDB_ERR_OPERATIONS_ERROR; -} - -/* - initialise the module - */ -_PUBLIC_ int ldb_ildap_init(const char *ldb_version) -{ - int ret, i; - const char *names[] = { "ldap", "ldaps", "ldapi", NULL }; - for (i=0; names[i]; i++) { - ret = ldb_register_backend(names[i], ildb_connect, true); - if (ret != LDB_SUCCESS) { - return ret; - } - } - return LDB_SUCCESS; -} diff --git a/source4/lib/ldb-samba/ldb_wrap.c b/source4/lib/ldb-samba/ldb_wrap.c deleted file mode 100644 index 66213bf288..0000000000 --- a/source4/lib/ldb-samba/ldb_wrap.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - LDB wrap functions - - Copyright (C) Andrew Tridgell 2004-2009 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -/* - the stupidity of the unix fcntl locking design forces us to never - allow a database file to be opened twice in the same process. These - wrappers provide convenient access to a tdb or ldb, taking advantage - of talloc destructors to ensure that only a single open is done -*/ - -#include "includes.h" -#include "lib/events/events.h" -#include <ldb.h> -#include <ldb_errors.h> -#include "lib/ldb-samba/ldif_handlers.h" -#include "ldb_wrap.h" -#include "dsdb/samdb/samdb.h" -#include "param/param.h" -#include "../lib/util/dlinklist.h" -#include "../lib/tdb_compat/tdb_compat.h" - -/* - this is used to catch debug messages from ldb -*/ -static void ldb_wrap_debug(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); - -static void ldb_wrap_debug(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap) -{ - int samba_level = -1; - char *s = NULL; - switch (level) { - case LDB_DEBUG_FATAL: - samba_level = 0; - break; - case LDB_DEBUG_ERROR: - samba_level = 1; - break; - case LDB_DEBUG_WARNING: - samba_level = 2; - break; - case LDB_DEBUG_TRACE: - samba_level = 5; - break; - - }; - vasprintf(&s, fmt, ap); - if (!s) return; - DEBUG(samba_level, ("ldb: %s\n", s)); - free(s); -} - - -/* - connecting to a ldb can be a relatively expensive operation because - of the schema and partition loads. We keep a list of open ldb - contexts here, and try to re-use when possible. - - This means callers of ldb_wrap_connect() must use talloc_unlink() or - the free of a parent to destroy the context - */ -static struct ldb_wrap { - struct ldb_wrap *next, *prev; - struct ldb_wrap_context { - /* the context is what we use to tell if two ldb - * connections are exactly equivalent - */ - const char *url; - struct tevent_context *ev; - struct loadparm_context *lp_ctx; - struct auth_session_info *session_info; - struct cli_credentials *credentials; - unsigned int flags; - } context; - struct ldb_context *ldb; -} *ldb_wrap_list; - -/* - free a ldb_wrap structure - */ -static int ldb_wrap_destructor(struct ldb_wrap *w) -{ - DLIST_REMOVE(ldb_wrap_list, w); - return 0; -} - -/* - * The casefolder for s4's LDB databases - Unicode-safe - */ -char *wrap_casefold(void *context, void *mem_ctx, const char *s, size_t n) -{ - return strupper_talloc_n(mem_ctx, s, n); -} - - - struct ldb_context *samba_ldb_init(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct loadparm_context *lp_ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials) -{ - struct ldb_context *ldb; - int ret; - - ldb = ldb_init(mem_ctx, ev); - if (ldb == NULL) { - return NULL; - } - - ldb_set_modules_dir(ldb, modules_path(ldb, "ldb")); - - ldb_set_debug(ldb, ldb_wrap_debug, NULL); - - ldb_set_utf8_fns(ldb, NULL, wrap_casefold); - - if (session_info) { - if (ldb_set_opaque(ldb, "sessionInfo", session_info)) { - talloc_free(ldb); - return NULL; - } - } - - if (credentials) { - if (ldb_set_opaque(ldb, "credentials", credentials)) { - talloc_free(ldb); - return NULL; - } - } - - if (ldb_set_opaque(ldb, "loadparm", lp_ctx)) { - talloc_free(ldb); - return NULL; - } - - /* This must be done before we load the schema, as these - * handlers for objectSid and objectGUID etc must take - * precedence over the 'binary attribute' declaration in the - * schema */ - ret = ldb_register_samba_handlers(ldb); - if (ret != LDB_SUCCESS) { - talloc_free(ldb); - return NULL; - } - - /* we usually want Samba databases to be private. If we later - find we need one public, we will need to add a parameter to - ldb_wrap_connect() */ - ldb_set_create_perms(ldb, 0600); - - return ldb; -} - - struct ldb_context *ldb_wrap_find(const char *url, - struct tevent_context *ev, - struct loadparm_context *lp_ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - unsigned int flags) -{ - struct ldb_wrap *w; - /* see if we can re-use an existing ldb */ - for (w=ldb_wrap_list; w; w=w->next) { - if (w->context.ev == ev && - w->context.lp_ctx == lp_ctx && - w->context.session_info == session_info && - w->context.credentials == credentials && - w->context.flags == flags && - (w->context.url == url || strcmp(w->context.url, url) == 0)) - return w->ldb; - } - - return NULL; -} - -int samba_ldb_connect(struct ldb_context *ldb, struct loadparm_context *lp_ctx, - const char *url, unsigned int flags) -{ - int ret; - char *real_url = NULL; - - /* allow admins to force non-sync ldb for all databases */ - if (lpcfg_parm_bool(lp_ctx, NULL, "ldb", "nosync", false)) { - flags |= LDB_FLG_NOSYNC; - } - - if (DEBUGLVL(10)) { - flags |= LDB_FLG_ENABLE_TRACING; - } - - real_url = lpcfg_private_path(ldb, lp_ctx, url); - if (real_url == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_connect(ldb, real_url, flags, NULL); - - if (ret != LDB_SUCCESS) { - return ret; - } - - /* setup for leak detection */ - ldb_set_opaque(ldb, "wrap_url", real_url); - - return LDB_SUCCESS; -} - - bool ldb_wrap_add(const char *url, struct tevent_context *ev, - struct loadparm_context *lp_ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - unsigned int flags, - struct ldb_context *ldb) -{ - struct ldb_wrap *w; - struct ldb_wrap_context c; - - /* add to the list of open ldb contexts */ - w = talloc(ldb, struct ldb_wrap); - if (w == NULL) { - return false; - } - - c.url = url; - c.ev = ev; - c.lp_ctx = lp_ctx; - c.session_info = session_info; - c.credentials = credentials; - c.flags = flags; - - w->context = c; - w->context.url = talloc_strdup(w, url); - if (w->context.url == NULL) { - return false; - } - - if (session_info) { - /* take a reference to the session_info, as it is - * possible for the ldb to live longer than the - * session_info. This happens when a DRS DsBind call - * reuses a handle, but the original connection is - * shutdown. The token for the new connection is still - * valid, so we need the session_info to remain valid for - * ldb modules to use - */ - if (talloc_reference(w, session_info) == NULL) { - return false; - } - } - - w->ldb = ldb; - - DLIST_ADD(ldb_wrap_list, w); - - talloc_set_destructor(w, ldb_wrap_destructor); - - return true; -} - - -/* - wrapped connection to a ldb database - to close just talloc_free() the returned ldb_context - - TODO: We need an error_string parameter - */ - struct ldb_context *ldb_wrap_connect(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct loadparm_context *lp_ctx, - const char *url, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - unsigned int flags) -{ - struct ldb_context *ldb; - int ret; - - ldb = ldb_wrap_find(url, ev, lp_ctx, session_info, credentials, flags); - if (ldb != NULL) - return talloc_reference(mem_ctx, ldb); - - ldb = samba_ldb_init(mem_ctx, ev, lp_ctx, session_info, credentials); - - if (ldb == NULL) - return NULL; - - ret = samba_ldb_connect(ldb, lp_ctx, url, flags); - if (ret != LDB_SUCCESS) { - talloc_free(ldb); - return NULL; - } - - if (!ldb_wrap_add(url, ev, lp_ctx, session_info, credentials, flags, ldb)) { - talloc_free(ldb); - return NULL; - } - - DEBUG(3,("ldb_wrap open of %s\n", url)); - - return ldb; -} - -/* - when we fork() we need to make sure that any open ldb contexts have - any open transactions cancelled - */ - void ldb_wrap_fork_hook(void) -{ - struct ldb_wrap *w; - - for (w=ldb_wrap_list; w; w=w->next) { - if (ldb_transaction_cancel_noerr(w->ldb) != LDB_SUCCESS) { - smb_panic("Failed to cancel child transactions\n"); - } - } - - if (tdb_reopen_all(1) == -1) { - smb_panic("tdb_reopen_all failed\n"); - } -} - - char *ldb_relative_path(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const char *name) -{ - const char *base_url = - (const char *)ldb_get_opaque(ldb, "ldb_url"); - char *path, *p, *full_name; - if (name == NULL) { - return NULL; - } - if (strncmp("tdb://", base_url, 6) == 0) { - base_url = base_url+6; - } - path = talloc_strdup(mem_ctx, base_url); - if (path == NULL) { - return NULL; - } - if ( (p = strrchr(path, '/')) != NULL) { - p[0] = '\0'; - full_name = talloc_asprintf(mem_ctx, "%s/%s", path, name); - } else { - full_name = talloc_asprintf(mem_ctx, "./%s", name); - } - talloc_free(path); - return full_name; -} diff --git a/source4/lib/ldb-samba/ldb_wrap.h b/source4/lib/ldb-samba/ldb_wrap.h deleted file mode 100644 index aa7ccb3a23..0000000000 --- a/source4/lib/ldb-samba/ldb_wrap.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - database wrap headers - - Copyright (C) Andrew Tridgell 2004 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef _LDB_WRAP_H_ -#define _LDB_WRAP_H_ - -#include <talloc.h> - -struct auth_session_info; -struct ldb_message; -struct ldb_dn; -struct cli_credentials; -struct loadparm_context; -struct tevent_context; - -char *wrap_casefold(void *context, void *mem_ctx, const char *s, size_t n); - -struct ldb_context *ldb_wrap_connect(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct loadparm_context *lp_ctx, - const char *url, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - unsigned int flags); - -void ldb_wrap_fork_hook(void); - -struct ldb_context *samba_ldb_init(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct loadparm_context *lp_ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials); -struct ldb_context *ldb_wrap_find(const char *url, - struct tevent_context *ev, - struct loadparm_context *lp_ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - unsigned int flags); -bool ldb_wrap_add(const char *url, struct tevent_context *ev, - struct loadparm_context *lp_ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - unsigned int flags, - struct ldb_context *ldb); -char *ldb_relative_path(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const char *name); - -int samba_ldb_connect(struct ldb_context *ldb, struct loadparm_context *lp_ctx, - const char *url, unsigned int flags); - -#endif /* _LDB_WRAP_H_ */ diff --git a/source4/lib/ldb-samba/ldif_handlers.c b/source4/lib/ldb-samba/ldif_handlers.c deleted file mode 100644 index af3c4b46e1..0000000000 --- a/source4/lib/ldb-samba/ldif_handlers.c +++ /dev/null @@ -1,1416 +0,0 @@ -/* - ldb database library - ldif handlers for Samba - - Copyright (C) Andrew Tridgell 2005 - Copyright (C) Andrew Bartlett 2006-2009 - Copyright (C) Matthias Dieter Wallnöfer 2009 - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include <ldb.h> -#include <ldb_module.h> -#include "ldb_handlers.h" -#include "dsdb/samdb/samdb.h" -#include "librpc/gen_ndr/ndr_security.h" -#include "librpc/gen_ndr/ndr_misc.h" -#include "librpc/gen_ndr/ndr_drsblobs.h" -#include "librpc/gen_ndr/ndr_dnsp.h" -#include "librpc/ndr/libndr.h" -#include "libcli/security/security.h" -#include "param/param.h" -#include "../lib/util/asn1.h" - -/* - use ndr_print_* to convert a NDR formatted blob to a ldif formatted blob - - If mask_errors is true, then function succeeds but out data - is set to "<Unable to decode binary data>" message - - \return 0 on success; -1 on error -*/ -static int ldif_write_NDR(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out, - size_t struct_size, - ndr_pull_flags_fn_t pull_fn, - ndr_print_fn_t print_fn, - bool mask_errors) -{ - uint8_t *p; - enum ndr_err_code err; - if (!(ldb_get_flags(ldb) & LDB_FLG_SHOW_BINARY)) { - return ldb_handler_copy(ldb, mem_ctx, in, out); - } - p = talloc_size(mem_ctx, struct_size); - err = ndr_pull_struct_blob(in, mem_ctx, - p, pull_fn); - if (err != NDR_ERR_SUCCESS) { - /* fail in not in mask_error mode */ - if (!mask_errors) { - return -1; - } - talloc_free(p); - out->data = (uint8_t *)talloc_strdup(mem_ctx, "<Unable to decode binary data>"); - out->length = strlen((const char *)out->data); - return 0; - } - out->data = (uint8_t *)ndr_print_struct_string(mem_ctx, print_fn, "NDR", p); - talloc_free(p); - if (out->data == NULL) { - return ldb_handler_copy(ldb, mem_ctx, in, out); - } - out->length = strlen((char *)out->data); - return 0; -} - -/* - convert a ldif formatted objectSid to a NDR formatted blob -*/ -static int ldif_read_objectSid(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - enum ndr_err_code ndr_err; - struct dom_sid *sid; - sid = dom_sid_parse_length(mem_ctx, in); - if (sid == NULL) { - return -1; - } - ndr_err = ndr_push_struct_blob(out, mem_ctx, sid, - (ndr_push_flags_fn_t)ndr_push_dom_sid); - talloc_free(sid); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return -1; - } - return 0; -} - -/* - convert a NDR formatted blob to a ldif formatted objectSid -*/ -int ldif_write_objectSid(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct dom_sid *sid; - enum ndr_err_code ndr_err; - - sid = talloc(mem_ctx, struct dom_sid); - if (sid == NULL) { - return -1; - } - ndr_err = ndr_pull_struct_blob_all(in, sid, sid, - (ndr_pull_flags_fn_t)ndr_pull_dom_sid); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(sid); - return -1; - } - *out = data_blob_string_const(dom_sid_string(mem_ctx, sid)); - talloc_free(sid); - if (out->data == NULL) { - return -1; - } - return 0; -} - -bool ldif_comparision_objectSid_isString(const struct ldb_val *v) -{ - if (v->length < 3) { - return false; - } - - if (strncmp("S-", (const char *)v->data, 2) != 0) return false; - - return true; -} - -/* - compare two objectSids -*/ -static int ldif_comparison_objectSid(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - if (ldif_comparision_objectSid_isString(v1) && ldif_comparision_objectSid_isString(v2)) { - return ldb_comparison_binary(ldb, mem_ctx, v1, v2); - } else if (ldif_comparision_objectSid_isString(v1) - && !ldif_comparision_objectSid_isString(v2)) { - struct ldb_val v; - int ret; - if (ldif_read_objectSid(ldb, mem_ctx, v1, &v) != 0) { - /* Perhaps not a string after all */ - return ldb_comparison_binary(ldb, mem_ctx, v1, v2); - } - ret = ldb_comparison_binary(ldb, mem_ctx, &v, v2); - talloc_free(v.data); - return ret; - } else if (!ldif_comparision_objectSid_isString(v1) - && ldif_comparision_objectSid_isString(v2)) { - struct ldb_val v; - int ret; - if (ldif_read_objectSid(ldb, mem_ctx, v2, &v) != 0) { - /* Perhaps not a string after all */ - return ldb_comparison_binary(ldb, mem_ctx, v1, v2); - } - ret = ldb_comparison_binary(ldb, mem_ctx, v1, &v); - talloc_free(v.data); - return ret; - } - return ldb_comparison_binary(ldb, mem_ctx, v1, v2); -} - -/* - canonicalise a objectSid -*/ -static int ldif_canonicalise_objectSid(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - if (ldif_comparision_objectSid_isString(in)) { - if (ldif_read_objectSid(ldb, mem_ctx, in, out) != 0) { - /* Perhaps not a string after all */ - return ldb_handler_copy(ldb, mem_ctx, in, out); - } - return 0; - } - return ldb_handler_copy(ldb, mem_ctx, in, out); -} - -static int extended_dn_read_SID(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct dom_sid sid; - enum ndr_err_code ndr_err; - if (ldif_comparision_objectSid_isString(in)) { - if (ldif_read_objectSid(ldb, mem_ctx, in, out) == 0) { - return 0; - } - } - - /* Perhaps not a string after all */ - *out = data_blob_talloc(mem_ctx, NULL, in->length/2+1); - - if (!out->data) { - return -1; - } - - (*out).length = strhex_to_str((char *)out->data, out->length, - (const char *)in->data, in->length); - - /* Check it looks like a SID */ - ndr_err = ndr_pull_struct_blob_all(out, mem_ctx, &sid, - (ndr_pull_flags_fn_t)ndr_pull_dom_sid); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return -1; - } - return 0; -} - -/* - convert a ldif formatted objectGUID to a NDR formatted blob -*/ -static int ldif_read_objectGUID(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct GUID guid; - NTSTATUS status; - - status = GUID_from_data_blob(in, &guid); - if (!NT_STATUS_IS_OK(status)) { - return -1; - } - - status = GUID_to_ndr_blob(&guid, mem_ctx, out); - if (!NT_STATUS_IS_OK(status)) { - return -1; - } - return 0; -} - -/* - convert a NDR formatted blob to a ldif formatted objectGUID -*/ -static int ldif_write_objectGUID(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct GUID guid; - NTSTATUS status; - - status = GUID_from_ndr_blob(in, &guid); - if (!NT_STATUS_IS_OK(status)) { - return -1; - } - out->data = (uint8_t *)GUID_string(mem_ctx, &guid); - if (out->data == NULL) { - return -1; - } - out->length = strlen((const char *)out->data); - return 0; -} - -static bool ldif_comparision_objectGUID_isString(const struct ldb_val *v) -{ - if (v->length != 36 && v->length != 38) return false; - - /* Might be a GUID string, can't be a binary GUID (fixed 16 bytes) */ - return true; -} - -static int extended_dn_read_GUID(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct GUID guid; - NTSTATUS status; - - if (in->length == 36 && ldif_read_objectGUID(ldb, mem_ctx, in, out) == 0) { - return 0; - } - - /* Try as 'hex' form */ - if (in->length != 32) { - return -1; - } - - *out = data_blob_talloc(mem_ctx, NULL, in->length/2+1); - - if (!out->data) { - return -1; - } - - (*out).length = strhex_to_str((char *)out->data, out->length, - (const char *)in->data, in->length); - - /* Check it looks like a GUID */ - status = GUID_from_ndr_blob(out, &guid); - if (!NT_STATUS_IS_OK(status)) { - data_blob_free(out); - return -1; - } - return 0; -} - -/* - compare two objectGUIDs -*/ -static int ldif_comparison_objectGUID(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - if (ldif_comparision_objectGUID_isString(v1) && ldif_comparision_objectGUID_isString(v2)) { - return ldb_comparison_binary(ldb, mem_ctx, v1, v2); - } else if (ldif_comparision_objectGUID_isString(v1) - && !ldif_comparision_objectGUID_isString(v2)) { - struct ldb_val v; - int ret; - if (ldif_read_objectGUID(ldb, mem_ctx, v1, &v) != 0) { - /* Perhaps it wasn't a valid string after all */ - return ldb_comparison_binary(ldb, mem_ctx, v1, v2); - } - ret = ldb_comparison_binary(ldb, mem_ctx, &v, v2); - talloc_free(v.data); - return ret; - } else if (!ldif_comparision_objectGUID_isString(v1) - && ldif_comparision_objectGUID_isString(v2)) { - struct ldb_val v; - int ret; - if (ldif_read_objectGUID(ldb, mem_ctx, v2, &v) != 0) { - /* Perhaps it wasn't a valid string after all */ - return ldb_comparison_binary(ldb, mem_ctx, v1, v2); - } - ret = ldb_comparison_binary(ldb, mem_ctx, v1, &v); - talloc_free(v.data); - return ret; - } - return ldb_comparison_binary(ldb, mem_ctx, v1, v2); -} - -/* - canonicalise a objectGUID -*/ -static int ldif_canonicalise_objectGUID(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - if (ldif_comparision_objectGUID_isString(in)) { - if (ldif_read_objectGUID(ldb, mem_ctx, in, out) != 0) { - /* Perhaps it wasn't a valid string after all */ - return ldb_handler_copy(ldb, mem_ctx, in, out); - } - return 0; - } - return ldb_handler_copy(ldb, mem_ctx, in, out); -} - - -/* - convert a ldif (SDDL) formatted ntSecurityDescriptor to a NDR formatted blob -*/ -static int ldif_read_ntSecurityDescriptor(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct security_descriptor *sd; - enum ndr_err_code ndr_err; - - sd = talloc(mem_ctx, struct security_descriptor); - if (sd == NULL) { - return -1; - } - - ndr_err = ndr_pull_struct_blob(in, sd, sd, - (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - /* If this does not parse, then it is probably SDDL, and we should try it that way */ - - const struct dom_sid *sid = samdb_domain_sid(ldb); - talloc_free(sd); - sd = sddl_decode(mem_ctx, (const char *)in->data, sid); - if (sd == NULL) { - return -1; - } - } - - ndr_err = ndr_push_struct_blob(out, mem_ctx, sd, - (ndr_push_flags_fn_t)ndr_push_security_descriptor); - talloc_free(sd); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return -1; - } - - return 0; -} - -/* - convert a NDR formatted blob to a ldif formatted ntSecurityDescriptor (SDDL format) -*/ -static int ldif_write_ntSecurityDescriptor(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct security_descriptor *sd; - enum ndr_err_code ndr_err; - - if (ldb_get_flags(ldb) & LDB_FLG_SHOW_BINARY) { - return ldif_write_NDR(ldb, mem_ctx, in, out, - sizeof(struct security_descriptor), - (ndr_pull_flags_fn_t)ndr_pull_security_descriptor, - (ndr_print_fn_t)ndr_print_security_descriptor, - true); - - } - - sd = talloc(mem_ctx, struct security_descriptor); - if (sd == NULL) { - return -1; - } - /* We can't use ndr_pull_struct_blob_all because this contains relative pointers */ - ndr_err = ndr_pull_struct_blob(in, sd, sd, - (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(sd); - return -1; - } - out->data = (uint8_t *)sddl_encode(mem_ctx, sd, samdb_domain_sid_cache_only(ldb)); - talloc_free(sd); - if (out->data == NULL) { - return -1; - } - out->length = strlen((const char *)out->data); - return 0; -} - -/* - canonicalise an objectCategory. We use the short form as the canonical form: - cn=Person,cn=Schema,cn=Configuration,<basedn> becomes 'person' -*/ - -static int ldif_canonicalise_objectCategory(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct ldb_dn *dn1 = NULL; - const struct dsdb_schema *schema = dsdb_get_schema(ldb, NULL); - const struct dsdb_class *sclass; - TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); - if (!tmp_ctx) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (!schema) { - talloc_free(tmp_ctx); - *out = data_blob_talloc(mem_ctx, in->data, in->length); - if (in->data && !out->data) { - return LDB_ERR_OPERATIONS_ERROR; - } - return LDB_SUCCESS; - } - dn1 = ldb_dn_from_ldb_val(tmp_ctx, ldb, in); - if ( ! ldb_dn_validate(dn1)) { - const char *lDAPDisplayName = talloc_strndup(tmp_ctx, (char *)in->data, in->length); - sclass = dsdb_class_by_lDAPDisplayName(schema, lDAPDisplayName); - if (sclass) { - struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, - sclass->defaultObjectCategory); - *out = data_blob_string_const(ldb_dn_alloc_casefold(mem_ctx, dn)); - talloc_free(tmp_ctx); - - if (!out->data) { - return LDB_ERR_OPERATIONS_ERROR; - } - return LDB_SUCCESS; - } else { - *out = data_blob_talloc(mem_ctx, in->data, in->length); - talloc_free(tmp_ctx); - - if (in->data && !out->data) { - return LDB_ERR_OPERATIONS_ERROR; - } - return LDB_SUCCESS; - } - } - *out = data_blob_string_const(ldb_dn_alloc_casefold(mem_ctx, dn1)); - talloc_free(tmp_ctx); - - if (!out->data) { - return LDB_ERR_OPERATIONS_ERROR; - } - return LDB_SUCCESS; -} - -static int ldif_comparison_objectCategory(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, - const struct ldb_val *v2) -{ - return ldb_any_comparison(ldb, mem_ctx, ldif_canonicalise_objectCategory, - v1, v2); -} - -/* - convert a NDR formatted blob to a ldif formatted schemaInfo -*/ -static int ldif_write_schemaInfo(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - return ldif_write_NDR(ldb, mem_ctx, in, out, - sizeof(struct repsFromToBlob), - (ndr_pull_flags_fn_t)ndr_pull_schemaInfoBlob, - (ndr_print_fn_t)ndr_print_schemaInfoBlob, - true); -} - -/* - convert a ldif formatted prefixMap to a NDR formatted blob -*/ -static int ldif_read_prefixMap(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct prefixMapBlob *blob; - enum ndr_err_code ndr_err; - char *string, *line, *p, *oid; - DATA_BLOB oid_blob; - - TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); - - if (tmp_ctx == NULL) { - return -1; - } - - blob = talloc_zero(tmp_ctx, struct prefixMapBlob); - if (blob == NULL) { - talloc_free(tmp_ctx); - return -1; - } - - /* use the switch value to detect if this is in the binary - * format - */ - if (in->length >= 4 && IVAL(in->data, 0) == PREFIX_MAP_VERSION_DSDB) { - ndr_err = ndr_pull_struct_blob(in, tmp_ctx, blob, - (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob); - if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - ndr_err = ndr_push_struct_blob(out, mem_ctx, - blob, - (ndr_push_flags_fn_t)ndr_push_prefixMapBlob); - talloc_free(tmp_ctx); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return -1; - } - return 0; - } - } - - /* If this does not parse, then it is probably the text version, and we should try it that way */ - blob->version = PREFIX_MAP_VERSION_DSDB; - - string = talloc_strndup(mem_ctx, (const char *)in->data, in->length); - if (string == NULL) { - talloc_free(blob); - return -1; - } - - line = string; - while (line && line[0]) { - p=strchr(line, ';'); - if (p) { - p[0] = '\0'; - } else { - p=strchr(line, '\n'); - if (p) { - p[0] = '\0'; - } - } - /* allow a trailing separator */ - if (line == p) { - break; - } - - blob->ctr.dsdb.mappings = talloc_realloc(blob, - blob->ctr.dsdb.mappings, - struct drsuapi_DsReplicaOIDMapping, - blob->ctr.dsdb.num_mappings+1); - if (!blob->ctr.dsdb.mappings) { - talloc_free(tmp_ctx); - return -1; - } - - blob->ctr.dsdb.mappings[blob->ctr.dsdb.num_mappings].id_prefix = strtoul(line, &oid, 10); - - if (oid[0] != ':') { - talloc_free(tmp_ctx); - return -1; - } - - /* we know there must be at least ":" */ - oid++; - - if (!ber_write_partial_OID_String(blob->ctr.dsdb.mappings, &oid_blob, oid)) { - talloc_free(tmp_ctx); - return -1; - } - blob->ctr.dsdb.mappings[blob->ctr.dsdb.num_mappings].oid.length = oid_blob.length; - blob->ctr.dsdb.mappings[blob->ctr.dsdb.num_mappings].oid.binary_oid = oid_blob.data; - - blob->ctr.dsdb.num_mappings++; - - /* Now look past the terminator we added above */ - if (p) { - line = p + 1; - } else { - line = NULL; - } - } - - ndr_err = ndr_push_struct_blob(out, mem_ctx, - blob, - (ndr_push_flags_fn_t)ndr_push_prefixMapBlob); - talloc_free(tmp_ctx); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return -1; - } - return 0; -} - -/* - convert a NDR formatted blob to a ldif formatted prefixMap -*/ -static int ldif_write_prefixMap(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct prefixMapBlob *blob; - enum ndr_err_code ndr_err; - char *string; - uint32_t i; - - if (ldb_get_flags(ldb) & LDB_FLG_SHOW_BINARY) { - int err; - /* try to decode the blob as S4 prefixMap */ - err = ldif_write_NDR(ldb, mem_ctx, in, out, - sizeof(struct prefixMapBlob), - (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob, - (ndr_print_fn_t)ndr_print_prefixMapBlob, - false); - if (0 == err) { - return err; - } - /* try parsing it as Windows PrefixMap value */ - return ldif_write_NDR(ldb, mem_ctx, in, out, - sizeof(struct drsuapi_MSPrefixMap_Ctr), - (ndr_pull_flags_fn_t)ndr_pull_drsuapi_MSPrefixMap_Ctr, - (ndr_print_fn_t)ndr_print_drsuapi_MSPrefixMap_Ctr, - true); - } - - blob = talloc(mem_ctx, struct prefixMapBlob); - if (blob == NULL) { - return -1; - } - ndr_err = ndr_pull_struct_blob_all(in, blob, - blob, - (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - goto failed; - } - if (blob->version != PREFIX_MAP_VERSION_DSDB) { - goto failed; - } - string = talloc_strdup(mem_ctx, ""); - if (string == NULL) { - goto failed; - } - - for (i=0; i < blob->ctr.dsdb.num_mappings; i++) { - DATA_BLOB oid_blob; - char *partial_oid = NULL; - - if (i > 0) { - string = talloc_asprintf_append(string, ";"); - } - - oid_blob = data_blob_const(blob->ctr.dsdb.mappings[i].oid.binary_oid, - blob->ctr.dsdb.mappings[i].oid.length); - if (!ber_read_partial_OID_String(blob, oid_blob, &partial_oid)) { - DEBUG(0, ("ber_read_partial_OID failed on prefixMap item with id: 0x%X", - blob->ctr.dsdb.mappings[i].id_prefix)); - goto failed; - } - string = talloc_asprintf_append(string, "%u:%s", - blob->ctr.dsdb.mappings[i].id_prefix, - partial_oid); - talloc_free(discard_const(partial_oid)); - if (string == NULL) { - goto failed; - } - } - - talloc_free(blob); - *out = data_blob_string_const(string); - return 0; - -failed: - talloc_free(blob); - return -1; -} - -static bool ldif_comparision_prefixMap_isString(const struct ldb_val *v) -{ - if (v->length < 4) { - return true; - } - - if (IVAL(v->data, 0) == PREFIX_MAP_VERSION_DSDB) { - return false; - } - - return true; -} - -/* - canonicalise a prefixMap -*/ -static int ldif_canonicalise_prefixMap(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - if (ldif_comparision_prefixMap_isString(in)) { - return ldif_read_prefixMap(ldb, mem_ctx, in, out); - } - return ldb_handler_copy(ldb, mem_ctx, in, out); -} - -static int ldif_comparison_prefixMap(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, - const struct ldb_val *v2) -{ - return ldb_any_comparison(ldb, mem_ctx, ldif_canonicalise_prefixMap, - v1, v2); -} - -/* length limited conversion of a ldb_val to a int32_t */ -static int val_to_int32(const struct ldb_val *in, int32_t *v) -{ - char *end; - char buf[64]; - - /* make sure we don't read past the end of the data */ - if (in->length > sizeof(buf)-1) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - strncpy(buf, (char *)in->data, in->length); - buf[in->length] = 0; - - /* We've to use "strtoll" here to have the intended overflows. - * Otherwise we may get "LONG_MAX" and the conversion is wrong. */ - *v = (int32_t) strtoll(buf, &end, 0); - if (*end != 0) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - return LDB_SUCCESS; -} - -/* length limited conversion of a ldb_val to a int64_t */ -static int val_to_int64(const struct ldb_val *in, int64_t *v) -{ - char *end; - char buf[64]; - - /* make sure we don't read past the end of the data */ - if (in->length > sizeof(buf)-1) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - strncpy(buf, (char *)in->data, in->length); - buf[in->length] = 0; - - *v = (int64_t) strtoll(buf, &end, 0); - if (*end != 0) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - return LDB_SUCCESS; -} - -/* Canonicalisation of two 32-bit integers */ -static int ldif_canonicalise_int32(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - int32_t i; - int ret; - - ret = val_to_int32(in, &i); - if (ret != LDB_SUCCESS) { - return ret; - } - out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%d", i); - if (out->data == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - out->length = strlen((char *)out->data); - return 0; -} - -/* Comparison of two 32-bit integers */ -static int ldif_comparison_int32(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - int32_t i1=0, i2=0; - val_to_int32(v1, &i1); - val_to_int32(v2, &i2); - if (i1 == i2) return 0; - return i1 > i2? 1 : -1; -} - -/* Canonicalisation of two 64-bit integers */ -static int ldif_canonicalise_int64(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - int64_t i; - int ret; - - ret = val_to_int64(in, &i); - if (ret != LDB_SUCCESS) { - return ret; - } - out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%lld", (long long)i); - if (out->data == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - out->length = strlen((char *)out->data); - return 0; -} - -/* Comparison of two 64-bit integers */ -static int ldif_comparison_int64(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - int64_t i1=0, i2=0; - val_to_int64(v1, &i1); - val_to_int64(v2, &i2); - if (i1 == i2) return 0; - return i1 > i2? 1 : -1; -} - -/* - convert a NDR formatted blob to a ldif formatted repsFromTo -*/ -static int ldif_write_repsFromTo(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - return ldif_write_NDR(ldb, mem_ctx, in, out, - sizeof(struct repsFromToBlob), - (ndr_pull_flags_fn_t)ndr_pull_repsFromToBlob, - (ndr_print_fn_t)ndr_print_repsFromToBlob, - true); -} - -/* - convert a NDR formatted blob to a ldif formatted replPropertyMetaData -*/ -static int ldif_write_replPropertyMetaData(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - return ldif_write_NDR(ldb, mem_ctx, in, out, - sizeof(struct replPropertyMetaDataBlob), - (ndr_pull_flags_fn_t)ndr_pull_replPropertyMetaDataBlob, - (ndr_print_fn_t)ndr_print_replPropertyMetaDataBlob, - true); -} - -/* - convert a NDR formatted blob to a ldif formatted replUpToDateVector -*/ -static int ldif_write_replUpToDateVector(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - return ldif_write_NDR(ldb, mem_ctx, in, out, - sizeof(struct replUpToDateVectorBlob), - (ndr_pull_flags_fn_t)ndr_pull_replUpToDateVectorBlob, - (ndr_print_fn_t)ndr_print_replUpToDateVectorBlob, - true); -} - - -/* - convert a NDR formatted blob to a ldif formatted dnsRecord -*/ -static int ldif_write_dnsRecord(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - return ldif_write_NDR(ldb, mem_ctx, in, out, - sizeof(struct dnsp_DnssrvRpcRecord), - (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord, - (ndr_print_fn_t)ndr_print_dnsp_DnssrvRpcRecord, - true); -} - -/* - convert a NDR formatted blob of a supplementalCredentials into text -*/ -static int ldif_write_supplementalCredentialsBlob(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - return ldif_write_NDR(ldb, mem_ctx, in, out, - sizeof(struct supplementalCredentialsBlob), - (ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob, - (ndr_print_fn_t)ndr_print_supplementalCredentialsBlob, - true); -} - - -static int extended_dn_write_hex(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - *out = data_blob_string_const(data_blob_hex_string_lower(mem_ctx, in)); - if (!out->data) { - return -1; - } - return 0; -} - -/* - compare two dns -*/ -static int samba_ldb_dn_link_comparison(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - struct ldb_dn *dn1 = NULL, *dn2 = NULL; - int ret; - - if (dsdb_dn_is_deleted_val(v1)) { - /* If the DN is deleted, then we can't search for it */ - return -1; - } - - if (dsdb_dn_is_deleted_val(v2)) { - /* If the DN is deleted, then we can't search for it */ - return -1; - } - - dn1 = ldb_dn_from_ldb_val(mem_ctx, ldb, v1); - if ( ! ldb_dn_validate(dn1)) return -1; - - dn2 = ldb_dn_from_ldb_val(mem_ctx, ldb, v2); - if ( ! ldb_dn_validate(dn2)) { - talloc_free(dn1); - return -1; - } - - ret = ldb_dn_compare(dn1, dn2); - - talloc_free(dn1); - talloc_free(dn2); - return ret; -} - -static int samba_ldb_dn_link_canonicalise(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct ldb_dn *dn; - int ret = -1; - - out->length = 0; - out->data = NULL; - - dn = ldb_dn_from_ldb_val(mem_ctx, ldb, in); - if ( ! ldb_dn_validate(dn)) { - return LDB_ERR_INVALID_DN_SYNTAX; - } - - /* By including the RMD_FLAGS of a deleted DN, we ensure it - * does not casually match a not deleted DN */ - if (dsdb_dn_is_deleted_val(in)) { - out->data = (uint8_t *)talloc_asprintf(mem_ctx, - "<RMD_FLAGS=%u>%s", - dsdb_dn_val_rmd_flags(in), - ldb_dn_get_casefold(dn)); - } else { - out->data = (uint8_t *)ldb_dn_alloc_casefold(mem_ctx, dn); - } - - if (out->data == NULL) { - goto done; - } - out->length = strlen((char *)out->data); - - ret = 0; - -done: - talloc_free(dn); - - return ret; -} - - -/* - write a 64 bit 2-part range -*/ -static int ldif_write_range64(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - int64_t v; - int ret; - ret = val_to_int64(in, &v); - if (ret != LDB_SUCCESS) { - return ret; - } - out->data = (uint8_t *)talloc_asprintf(mem_ctx, "%lu-%lu", - (unsigned long)(v&0xFFFFFFFF), - (unsigned long)(v>>32)); - if (out->data == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - out->length = strlen((char *)out->data); - return LDB_SUCCESS; -} - -/* - read a 64 bit 2-part range -*/ -static int ldif_read_range64(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - unsigned long high, low; - char buf[64]; - - if (memchr(in->data, '-', in->length) == NULL) { - return ldb_handler_copy(ldb, mem_ctx, in, out); - } - - if (in->length > sizeof(buf)-1) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - strncpy(buf, (const char *)in->data, in->length); - buf[in->length] = 0; - - if (sscanf(buf, "%lu-%lu", &low, &high) != 2) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - - out->data = (uint8_t *)talloc_asprintf(mem_ctx, "%llu", - (unsigned long long)(((uint64_t)high)<<32) | (low)); - - if (out->data == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - out->length = strlen((char *)out->data); - return LDB_SUCCESS; -} - -/* - when this operator_fn is set for a syntax, the backend calls is in - preference to the comparison function. We are told the exact - comparison operation that is needed, and we can return errors - */ -static int samba_syntax_operator_fn(struct ldb_context *ldb, enum ldb_parse_op operation, - const struct ldb_schema_attribute *a, - const struct ldb_val *v1, const struct ldb_val *v2, bool *matched) -{ - switch (operation) { - case LDB_OP_AND: - case LDB_OP_OR: - case LDB_OP_NOT: - case LDB_OP_SUBSTRING: - case LDB_OP_APPROX: - case LDB_OP_EXTENDED: - /* handled in the backends */ - return LDB_ERR_INAPPROPRIATE_MATCHING; - - case LDB_OP_GREATER: - case LDB_OP_LESS: - case LDB_OP_EQUALITY: - { - TALLOC_CTX *tmp_ctx = talloc_new(ldb); - int ret; - if (tmp_ctx == NULL) { - return ldb_oom(ldb); - } - ret = a->syntax->comparison_fn(ldb, tmp_ctx, v1, v2); - talloc_free(tmp_ctx); - if (operation == LDB_OP_GREATER) { - *matched = (ret > 0); - } else if (operation == LDB_OP_LESS) { - *matched = (ret < 0); - } else { - *matched = (ret == 0); - } - return LDB_SUCCESS; - } - - case LDB_OP_PRESENT: - *matched = true; - return LDB_SUCCESS; - } - - /* we shouldn't get here */ - return LDB_ERR_INAPPROPRIATE_MATCHING; -} - -/* - special operation for DNs, to take account of the RMD_FLAGS deleted bit - */ -static int samba_syntax_operator_dn(struct ldb_context *ldb, enum ldb_parse_op operation, - const struct ldb_schema_attribute *a, - const struct ldb_val *v1, const struct ldb_val *v2, bool *matched) -{ - if (operation == LDB_OP_PRESENT && dsdb_dn_is_deleted_val(v1)) { - /* If the DN is deleted, then we can't search for it */ - *matched = false; - return LDB_SUCCESS; - } - return samba_syntax_operator_fn(ldb, operation, a, v1, v2, matched); -} - - -static const struct ldb_schema_syntax samba_syntaxes[] = { - { - .name = LDB_SYNTAX_SAMBA_SID, - .ldif_read_fn = ldif_read_objectSid, - .ldif_write_fn = ldif_write_objectSid, - .canonicalise_fn = ldif_canonicalise_objectSid, - .comparison_fn = ldif_comparison_objectSid, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR, - .ldif_read_fn = ldif_read_ntSecurityDescriptor, - .ldif_write_fn = ldif_write_ntSecurityDescriptor, - .canonicalise_fn = ldb_handler_copy, - .comparison_fn = ldb_comparison_binary, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_SAMBA_GUID, - .ldif_read_fn = ldif_read_objectGUID, - .ldif_write_fn = ldif_write_objectGUID, - .canonicalise_fn = ldif_canonicalise_objectGUID, - .comparison_fn = ldif_comparison_objectGUID, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_SAMBA_OBJECT_CATEGORY, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldif_canonicalise_objectCategory, - .comparison_fn = ldif_comparison_objectCategory, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_SAMBA_SCHEMAINFO, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldif_write_schemaInfo, - .canonicalise_fn = ldb_handler_copy, - .comparison_fn = ldb_comparison_binary, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_SAMBA_PREFIX_MAP, - .ldif_read_fn = ldif_read_prefixMap, - .ldif_write_fn = ldif_write_prefixMap, - .canonicalise_fn = ldif_canonicalise_prefixMap, - .comparison_fn = ldif_comparison_prefixMap, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_SAMBA_INT32, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldif_canonicalise_int32, - .comparison_fn = ldif_comparison_int32, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_SAMBA_REPSFROMTO, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldif_write_repsFromTo, - .canonicalise_fn = ldb_handler_copy, - .comparison_fn = ldb_comparison_binary, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldif_write_replPropertyMetaData, - .canonicalise_fn = ldb_handler_copy, - .comparison_fn = ldb_comparison_binary, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldif_write_replUpToDateVector, - .canonicalise_fn = ldb_handler_copy, - .comparison_fn = ldb_comparison_binary, - .operator_fn = samba_syntax_operator_fn - },{ - .name = DSDB_SYNTAX_BINARY_DN, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = dsdb_dn_binary_canonicalise, - .comparison_fn = dsdb_dn_binary_comparison, - .operator_fn = samba_syntax_operator_fn - },{ - .name = DSDB_SYNTAX_STRING_DN, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = dsdb_dn_string_canonicalise, - .comparison_fn = dsdb_dn_string_comparison, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_DN, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = samba_ldb_dn_link_canonicalise, - .comparison_fn = samba_ldb_dn_link_comparison, - .operator_fn = samba_syntax_operator_dn - },{ - .name = LDB_SYNTAX_SAMBA_RANGE64, - .ldif_read_fn = ldif_read_range64, - .ldif_write_fn = ldif_write_range64, - .canonicalise_fn = ldif_canonicalise_int64, - .comparison_fn = ldif_comparison_int64, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_SAMBA_DNSRECORD, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldif_write_dnsRecord, - .canonicalise_fn = ldb_handler_copy, - .comparison_fn = ldb_comparison_binary, - .operator_fn = samba_syntax_operator_fn - },{ - .name = LDB_SYNTAX_SAMBA_SUPPLEMENTALCREDENTIALS, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldif_write_supplementalCredentialsBlob, - .canonicalise_fn = ldb_handler_copy, - .comparison_fn = ldb_comparison_binary, - .operator_fn = samba_syntax_operator_fn - } -}; - -static const struct ldb_dn_extended_syntax samba_dn_syntax[] = { - { - .name = "SID", - .read_fn = extended_dn_read_SID, - .write_clear_fn = ldif_write_objectSid, - .write_hex_fn = extended_dn_write_hex - },{ - .name = "GUID", - .read_fn = extended_dn_read_GUID, - .write_clear_fn = ldif_write_objectGUID, - .write_hex_fn = extended_dn_write_hex - },{ - .name = "WKGUID", - .read_fn = ldb_handler_copy, - .write_clear_fn = ldb_handler_copy, - .write_hex_fn = ldb_handler_copy - },{ - .name = "RMD_INVOCID", - .read_fn = extended_dn_read_GUID, - .write_clear_fn = ldif_write_objectGUID, - .write_hex_fn = extended_dn_write_hex - },{ - .name = "RMD_FLAGS", - .read_fn = ldb_handler_copy, - .write_clear_fn = ldb_handler_copy, - .write_hex_fn = ldb_handler_copy - },{ - .name = "RMD_ADDTIME", - .read_fn = ldb_handler_copy, - .write_clear_fn = ldb_handler_copy, - .write_hex_fn = ldb_handler_copy - },{ - .name = "RMD_CHANGETIME", - .read_fn = ldb_handler_copy, - .write_clear_fn = ldb_handler_copy, - .write_hex_fn = ldb_handler_copy - },{ - .name = "RMD_LOCAL_USN", - .read_fn = ldb_handler_copy, - .write_clear_fn = ldb_handler_copy, - .write_hex_fn = ldb_handler_copy - },{ - .name = "RMD_ORIGINATING_USN", - .read_fn = ldb_handler_copy, - .write_clear_fn = ldb_handler_copy, - .write_hex_fn = ldb_handler_copy - },{ - .name = "RMD_VERSION", - .read_fn = ldb_handler_copy, - .write_clear_fn = ldb_handler_copy, - .write_hex_fn = ldb_handler_copy - } -}; - -/* TODO: Should be dynamic at some point */ -static const struct { - const char *name; - const char *syntax; -} samba_attributes[] = { - { "objectSid", LDB_SYNTAX_SAMBA_SID }, - { "securityIdentifier", LDB_SYNTAX_SAMBA_SID }, - { "tokenGroups", LDB_SYNTAX_SAMBA_SID }, - { "ntSecurityDescriptor", LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR }, - { "oMSyntax", LDB_SYNTAX_SAMBA_INT32 }, - { "objectCategory", LDB_SYNTAX_SAMBA_OBJECT_CATEGORY }, - { "schemaInfo", LDB_SYNTAX_SAMBA_SCHEMAINFO }, - { "prefixMap", LDB_SYNTAX_SAMBA_PREFIX_MAP }, - { "repsFrom", LDB_SYNTAX_SAMBA_REPSFROMTO }, - { "repsTo", LDB_SYNTAX_SAMBA_REPSFROMTO }, - { "replPropertyMetaData", LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA }, - { "replUpToDateVector", LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR }, - { "rIDAllocationPool", LDB_SYNTAX_SAMBA_RANGE64 }, - { "rIDPreviousAllocationPool", LDB_SYNTAX_SAMBA_RANGE64 }, - { "rIDAvailablePool", LDB_SYNTAX_SAMBA_RANGE64 }, - - /* - * these are extracted by searching - * (&(attributeSyntax=2.5.5.10)(rangeLower=16)(rangeUpper=16)(omSyntax=4)) - */ - { "attributeSecurityGUID", LDB_SYNTAX_SAMBA_GUID }, - { "categoryId", LDB_SYNTAX_SAMBA_GUID }, - { "controlAccessRights", LDB_SYNTAX_SAMBA_GUID }, - { "currMachineId", LDB_SYNTAX_SAMBA_GUID }, - { "fRSReplicaSetGUID", LDB_SYNTAX_SAMBA_GUID }, - { "fRSVersionGUID", LDB_SYNTAX_SAMBA_GUID }, - { "implementedCategories", LDB_SYNTAX_SAMBA_GUID }, - { "msDS-AzObjectGuid", LDB_SYNTAX_SAMBA_GUID }, - { "msDFSR-ContentSetGuid", LDB_SYNTAX_SAMBA_GUID }, - { "msDFSR-ReplicationGroupGuid", LDB_SYNTAX_SAMBA_GUID }, - { "mSMQDigests", LDB_SYNTAX_SAMBA_GUID }, - { "mSMQOwnerID", LDB_SYNTAX_SAMBA_GUID }, - { "mSMQQMID", LDB_SYNTAX_SAMBA_GUID }, - { "mSMQQueueType", LDB_SYNTAX_SAMBA_GUID }, - { "mSMQSites", LDB_SYNTAX_SAMBA_GUID }, - { "netbootGUID", LDB_SYNTAX_SAMBA_GUID }, - { "objectGUID", LDB_SYNTAX_SAMBA_GUID }, - { "pKTGuid", LDB_SYNTAX_SAMBA_GUID }, - { "requiredCategories", LDB_SYNTAX_SAMBA_GUID }, - { "schemaIDGUID", LDB_SYNTAX_SAMBA_GUID }, - { "siteGUID", LDB_SYNTAX_SAMBA_GUID }, - { "msDFS-GenerationGUIDv2", LDB_SYNTAX_SAMBA_GUID }, - { "msDFS-LinkIdentityGUIDv2", LDB_SYNTAX_SAMBA_GUID }, - { "msDFS-NamespaceIdentityGUIDv2", LDB_SYNTAX_SAMBA_GUID }, - - /* - * these are known to be GUIDs - */ - { "invocationId", LDB_SYNTAX_SAMBA_GUID }, - { "parentGUID", LDB_SYNTAX_SAMBA_GUID }, - { "msDS-OptionalFeatureGUID", LDB_SYNTAX_SAMBA_GUID }, - - /* These NDR encoded things we want to be able to read with --show-binary */ - { "dnsRecord", LDB_SYNTAX_SAMBA_DNSRECORD }, - { "supplementalCredentials", LDB_SYNTAX_SAMBA_SUPPLEMENTALCREDENTIALS} -}; - -const struct ldb_schema_syntax *ldb_samba_syntax_by_name(struct ldb_context *ldb, const char *name) -{ - unsigned int j; - const struct ldb_schema_syntax *s = NULL; - - for (j=0; j < ARRAY_SIZE(samba_syntaxes); j++) { - if (strcmp(name, samba_syntaxes[j].name) == 0) { - s = &samba_syntaxes[j]; - break; - } - } - return s; -} - -const struct ldb_schema_syntax *ldb_samba_syntax_by_lDAPDisplayName(struct ldb_context *ldb, const char *name) -{ - unsigned int j; - const struct ldb_schema_syntax *s = NULL; - - for (j=0; j < ARRAY_SIZE(samba_attributes); j++) { - if (strcmp(samba_attributes[j].name, name) == 0) { - s = ldb_samba_syntax_by_name(ldb, samba_attributes[j].syntax); - break; - } - } - - return s; -} - -/* - register the samba ldif handlers -*/ -int ldb_register_samba_handlers(struct ldb_context *ldb) -{ - unsigned int i; - int ret; - - if (ldb_get_opaque(ldb, "SAMBA_HANDLERS_REGISTERED") != NULL) { - return LDB_SUCCESS; - } - - for (i=0; i < ARRAY_SIZE(samba_attributes); i++) { - const struct ldb_schema_syntax *s = NULL; - - s = ldb_samba_syntax_by_name(ldb, samba_attributes[i].syntax); - - if (!s) { - s = ldb_standard_syntax_by_name(ldb, samba_attributes[i].syntax); - } - - if (!s) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_schema_attribute_add_with_syntax(ldb, samba_attributes[i].name, LDB_ATTR_FLAG_FIXED, s); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - for (i=0; i < ARRAY_SIZE(samba_dn_syntax); i++) { - ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &samba_dn_syntax[i]); - if (ret != LDB_SUCCESS) { - return ret; - } - - } - - ret = ldb_set_opaque(ldb, "SAMBA_HANDLERS_REGISTERED", (void*)1); - if (ret != LDB_SUCCESS) { - return ret; - } - - return LDB_SUCCESS; -} diff --git a/source4/lib/ldb-samba/ldif_handlers.h b/source4/lib/ldb-samba/ldif_handlers.h deleted file mode 100644 index 62903c4a96..0000000000 --- a/source4/lib/ldb-samba/ldif_handlers.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __LIB_LDB_SAMBA_LDIF_HANDLERS_H__ -#define __LIB_LDB_SAMBA_LDIF_HANDLERS_H__ - -#define LDB_SYNTAX_SAMBA_SID "LDB_SYNTAX_SAMBA_SID" -#define LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR "1.2.840.113556.1.4.907" -#define LDB_SYNTAX_SAMBA_GUID "LDB_SYNTAX_SAMBA_GUID" -#define LDB_SYNTAX_SAMBA_OBJECT_CATEGORY "LDB_SYNTAX_SAMBA_OBJECT_CATEGORY" -#define LDB_SYNTAX_SAMBA_SCHEMAINFO "LDB_SYNTAX_SAMBA_SCHEMAINFO" -#define LDB_SYNTAX_SAMBA_PREFIX_MAP "LDB_SYNTAX_SAMBA_PREFIX_MAP" -#define LDB_SYNTAX_SAMBA_INT32 "LDB_SYNTAX_SAMBA_INT32" -#define LDB_SYNTAX_SAMBA_REPSFROMTO "LDB_SYNTAX_SAMBA_REPSFROMTO" -#define LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA "LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA" -#define LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR "LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR" -#define LDB_SYNTAX_SAMBA_RANGE64 "LDB_SYNTAX_SAMBA_RANGE64" -#define LDB_SYNTAX_SAMBA_DNSRECORD "LDB_SYNTAX_SAMBA_DNSRECORD" -#define LDB_SYNTAX_SAMBA_SUPPLEMENTALCREDENTIALS "LDB_SYNTAX_SAMBA_SUPPLEMENTALCREDENTIALS" -#include "lib/ldb-samba/ldif_handlers_proto.h" - -#undef _PRINTF_ATTRIBUTE -#define _PRINTF_ATTRIBUTE(a1, a2) - -#endif /* __LIB_LDB_SAMBA_LDIF_HANDLERS_H__ */ - diff --git a/source4/lib/ldb-samba/pyldb.c b/source4/lib/ldb-samba/pyldb.c deleted file mode 100644 index ff48a3bb04..0000000000 --- a/source4/lib/ldb-samba/pyldb.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Python interface to ldb, Samba-specific functions - - Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -#include <Python.h> -#include "includes.h" -#include <ldb.h> -#include <pyldb.h> -#include "param/pyparam.h" -#include "auth/credentials/pycredentials.h" -#include "ldb_wrap.h" -#include "lib/ldb-samba/ldif_handlers.h" -#include "auth/pyauth.h" - -void init_ldb(void); - -static PyObject *pyldb_module; -static PyObject *py_ldb_error; -staticforward PyTypeObject PySambaLdb; - -static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx) -{ - if (ret == LDB_ERR_PYTHON_EXCEPTION) - return; /* Python exception should already be set, just keep that */ - - PyErr_SetObject(error, - Py_BuildValue(discard_const_p(char, "(i,s)"), ret, - ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx))); -} - -static PyObject *py_ldb_set_loadparm(PyObject *self, PyObject *args) -{ - PyObject *py_lp_ctx; - struct loadparm_context *lp_ctx; - struct ldb_context *ldb; - - if (!PyArg_ParseTuple(args, "O", &py_lp_ctx)) - return NULL; - - ldb = PyLdb_AsLdbContext(self); - - lp_ctx = lpcfg_from_py_object(ldb, py_lp_ctx); - if (lp_ctx == NULL) { - PyErr_SetString(PyExc_TypeError, "Expected loadparm object"); - return NULL; - } - - ldb_set_opaque(ldb, "loadparm", lp_ctx); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_set_credentials(PyObject *self, PyObject *args) -{ - PyObject *py_creds; - struct cli_credentials *creds; - struct ldb_context *ldb; - - if (!PyArg_ParseTuple(args, "O", &py_creds)) - return NULL; - - creds = cli_credentials_from_py_object(py_creds); - if (creds == NULL) { - PyErr_SetString(PyExc_TypeError, "Expected credentials object"); - return NULL; - } - - ldb = PyLdb_AsLdbContext(self); - - ldb_set_opaque(ldb, "credentials", creds); - - Py_RETURN_NONE; -} - -/* XXX: This function really should be in libldb's pyldb.c */ -static PyObject *py_ldb_set_opaque_integer(PyObject *self, PyObject *args) -{ - int value; - int *old_val, *new_val; - char *py_opaque_name, *opaque_name_talloc; - struct ldb_context *ldb; - int ret; - TALLOC_CTX *tmp_ctx; - - if (!PyArg_ParseTuple(args, "si", &py_opaque_name, &value)) - return NULL; - - ldb = PyLdb_AsLdbContext(self); - - /* see if we have a cached copy */ - old_val = (int *)ldb_get_opaque(ldb, py_opaque_name); - /* XXX: We shouldn't just blindly assume that the value that is - * already present has the size of an int and is not shared - * with other code that may rely on it not changing. - * JRV 20100403 */ - - if (old_val) { - *old_val = value; - Py_RETURN_NONE; - } - - tmp_ctx = talloc_new(ldb); - if (tmp_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - - new_val = talloc(tmp_ctx, int); - if (new_val == NULL) { - talloc_free(tmp_ctx); - PyErr_NoMemory(); - return NULL; - } - - opaque_name_talloc = talloc_strdup(tmp_ctx, py_opaque_name); - if (opaque_name_talloc == NULL) { - talloc_free(tmp_ctx); - PyErr_NoMemory(); - return NULL; - } - - *new_val = value; - - /* cache the domain_sid in the ldb */ - ret = ldb_set_opaque(ldb, opaque_name_talloc, new_val); - - if (ret != LDB_SUCCESS) { - talloc_free(tmp_ctx); - PyErr_SetLdbError(py_ldb_error, ret, ldb); - return NULL; - } - - talloc_steal(ldb, new_val); - talloc_steal(ldb, opaque_name_talloc); - talloc_free(tmp_ctx); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_set_utf8_casefold(PyObject *self) -{ - struct ldb_context *ldb; - - ldb = PyLdb_AsLdbContext(self); - - ldb_set_utf8_fns(ldb, NULL, wrap_casefold); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_set_session_info(PyObject *self, PyObject *args) -{ - PyObject *py_session_info; - struct auth_session_info *info; - struct ldb_context *ldb; - PyObject *mod_samba_auth; - PyObject *PyAuthSession_Type; - bool ret; - - mod_samba_auth = PyImport_ImportModule("samba.dcerpc.auth"); - if (mod_samba_auth == NULL) - return NULL; - - PyAuthSession_Type = PyObject_GetAttrString(mod_samba_auth, "session_info"); - if (PyAuthSession_Type == NULL) - return NULL; - - ret = PyArg_ParseTuple(args, "O!", PyAuthSession_Type, &py_session_info); - - Py_DECREF(PyAuthSession_Type); - Py_DECREF(mod_samba_auth); - - if (!ret) - return NULL; - - ldb = PyLdb_AsLdbContext(self); - - info = PyAuthSession_AsSession(py_session_info); - - ldb_set_opaque(ldb, "sessionInfo", info); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_register_samba_handlers(PyObject *self) -{ - struct ldb_context *ldb; - int ret; - - /* XXX: Perhaps call this from PySambaLdb's init function ? */ - - ldb = PyLdb_AsLdbContext(self); - ret = ldb_register_samba_handlers(ldb); - - PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_error, ret, ldb); - - Py_RETURN_NONE; -} - -static PyMethodDef py_samba_ldb_methods[] = { - { "set_loadparm", (PyCFunction)py_ldb_set_loadparm, METH_VARARGS, - "ldb_set_loadparm(session_info)\n" - "Set loadparm context to use when connecting." }, - { "set_credentials", (PyCFunction)py_ldb_set_credentials, METH_VARARGS, - "ldb_set_credentials(credentials)\n" - "Set credentials to use when connecting." }, - { "set_opaque_integer", (PyCFunction)py_ldb_set_opaque_integer, - METH_VARARGS, NULL }, - { "set_utf8_casefold", (PyCFunction)py_ldb_set_utf8_casefold, - METH_NOARGS, - "ldb_set_utf8_casefold()\n" - "Set the right Samba casefolding function for UTF8 charset." }, - { "register_samba_handlers", (PyCFunction)py_ldb_register_samba_handlers, - METH_NOARGS, - "register_samba_handlers()\n" - "Register Samba-specific LDB modules and schemas." }, - { "set_session_info", (PyCFunction)py_ldb_set_session_info, METH_VARARGS, - "set_session_info(session_info)\n" - "Set session info to use when connecting." }, - { NULL }, -}; - -static PyTypeObject PySambaLdb = { - .tp_name = "samba._ldb.Ldb", - .tp_doc = "Connection to a LDB database.", - .tp_methods = py_samba_ldb_methods, - .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, -}; - -void init_ldb(void) -{ - PyObject *m; - - pyldb_module = PyImport_ImportModule("ldb"); - if (pyldb_module == NULL) - return; - - PySambaLdb.tp_base = (PyTypeObject *)PyObject_GetAttrString(pyldb_module, "Ldb"); - if (PySambaLdb.tp_base == NULL) - return; - - py_ldb_error = PyObject_GetAttrString(pyldb_module, "LdbError"); - - if (PyType_Ready(&PySambaLdb) < 0) - return; - - m = Py_InitModule3("_ldb", NULL, "Samba-specific LDB python bindings"); - if (m == NULL) - return; - - Py_INCREF(&PySambaLdb); - PyModule_AddObject(m, "Ldb", (PyObject *)&PySambaLdb); -} diff --git a/source4/lib/ldb-samba/samba_extensions.c b/source4/lib/ldb-samba/samba_extensions.c deleted file mode 100644 index be9f36a5a7..0000000000 --- a/source4/lib/ldb-samba/samba_extensions.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - ldb database library - samba extensions - - Copyright (C) Andrew Tridgell 2010 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - - -#include "includes.h" -#include "ldb_module.h" -#include "lib/cmdline/popt_common.h" -#include "auth/gensec/gensec.h" -#include "auth/auth.h" -#include "param/param.h" -#include "dsdb/samdb/samdb.h" -#include "ldb_wrap.h" -#include "popt.h" - - - -/* - work out the length of a popt array - */ -static unsigned calculate_popt_array_length(struct poptOption *opts) -{ - unsigned i; - struct poptOption zero_opt = { NULL }; - for (i=0; memcmp(&zero_opt, &opts[i], sizeof(zero_opt)) != 0; i++) ; - return i; -} - -static struct poptOption cmdline_extensions[] = { - POPT_COMMON_SAMBA - POPT_COMMON_CREDENTIALS - POPT_COMMON_CONNECTION - POPT_COMMON_VERSION - { NULL } -}; - -/* - called to register additional command line options - */ -static int extensions_hook(struct ldb_context *ldb, enum ldb_module_hook_type t) -{ - switch (t) { - case LDB_MODULE_HOOK_CMDLINE_OPTIONS: { - unsigned len1, len2; - struct poptOption **popt_options = ldb_module_popt_options(ldb); - struct poptOption *new_array; - - len1 = calculate_popt_array_length(*popt_options); - len2 = calculate_popt_array_length(cmdline_extensions); - new_array = talloc_array(NULL, struct poptOption, len1+len2+1); - if (NULL == new_array) { - return ldb_oom(ldb); - } - - memcpy(new_array, *popt_options, len1*sizeof(struct poptOption)); - memcpy(new_array+len1, cmdline_extensions, (1+len2)*sizeof(struct poptOption)); - (*popt_options) = new_array; - return LDB_SUCCESS; - } - - case LDB_MODULE_HOOK_CMDLINE_PRECONNECT: { - int r = ldb_register_samba_handlers(ldb); - if (r != LDB_SUCCESS) { - return ldb_operr(ldb); - } - gensec_init(); - - if (ldb_set_opaque(ldb, "sessionInfo", system_session(cmdline_lp_ctx))) { - return ldb_operr(ldb); - } - if (ldb_set_opaque(ldb, "credentials", cmdline_credentials)) { - return ldb_operr(ldb); - } - if (ldb_set_opaque(ldb, "loadparm", cmdline_lp_ctx)) { - return ldb_operr(ldb); - } - - ldb_set_utf8_fns(ldb, NULL, wrap_casefold); - break; - } - - case LDB_MODULE_HOOK_CMDLINE_POSTCONNECT: - /* get the domain SID into the cache for SDDL processing */ - samdb_domain_sid(ldb); - break; - } - - return LDB_SUCCESS; -} - - -/* - initialise the module - */ -_PUBLIC_ int ldb_samba_extensions_init(const char *ldb_version) -{ - ldb_register_hook(extensions_hook); - - return LDB_SUCCESS; -} diff --git a/source4/lib/ldb-samba/wscript_build b/source4/lib/ldb-samba/wscript_build deleted file mode 100644 index 2e1cacba64..0000000000 --- a/source4/lib/ldb-samba/wscript_build +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env python - -# LDBSAMBA gets included in the ldb build when we are building ldb_ildap -# as a built-in module and this delutes the symbols in the ldb library with -# the symbols of all of ldb_ildap's dependencies. - -bld.SAMBA_LIBRARY('ldbsamba', - source='ldif_handlers.c', - autoproto='ldif_handlers_proto.h', - public_deps='ldb', - deps='security ndr NDR_DRSBLOBS NDR_DNSP ldbwrap samdb-common SAMDB_SCHEMA tdb_compat pyldb-util errors', - private_library=True - ) - -bld.SAMBA_SUBSYSTEM('ldbwrap', - source='ldb_wrap.c', - public_headers='ldb_wrap.h', - deps='ldb samba-util ldbsamba samba-hostconfig' - ) - - -bld.SAMBA_PYTHON('python_samba__ldb', 'pyldb.c', - deps='ldbsamba pyparam_util ldbwrap', - realname='samba/_ldb.so') - -bld.SAMBA_MODULE('ldbsamba_extensions', - source='samba_extensions.c', - init_function='ldb_samba_extensions_init', - module_init_name='ldb_init_module', - subsystem='ldb', - deps='ldb ldbsamba POPT_SAMBA POPT_CREDENTIALS cmdline-credentials gensec', - internal_module=False) - - -# the s4-internal ldap backend -bld.SAMBA_MODULE('ldb_ildap', - source='ldb_ildap.c', - init_function='ldb_ildap_init', - module_init_name='ldb_init_module', - deps='talloc cli-ldap credentials auth_system_session', - internal_module=False, - subsystem='ldb') |