4 Copyright (C) Andrew Tridgell 2004
6 ** NOTE! The following LGPL license applies to the ldb
7 ** library. This does NOT imply that all of Samba is released
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2 of the License, or (at your option) any later version.
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 * Component: ldb ldap backend
30 * Description: core files for LDAP backend
32 * Author: Andrew Tridgell
36 #include "ldb/include/ldb.h"
37 #include "ldb/include/ldb_private.h"
38 #include "ldb/ldb_ldap/ldb_ldap.h"
43 static int lldb_rename(struct ldb_module *module, const struct ldb_dn *olddn, const struct ldb_dn *newdn)
45 TALLOC_CTX *local_ctx;
46 struct lldb_private *lldb = module->private_data;
50 const char *parentdn = "";
52 /* ignore ltdb specials */
53 if (ldb_dn_is_special(olddn) || ldb_dn_is_special(newdn)) {
57 local_ctx = talloc_named(lldb, 0, "lldb_rename local context");
58 if (local_ctx == NULL) {
62 old_dn = ldb_dn_linearize(local_ctx, olddn);
67 newrdn = talloc_asprintf(lldb, "%s=%s",
68 newdn->components[0].name,
69 ldb_dn_escape_value(lldb, newdn->components[0].value));
74 parentdn = ldb_dn_linearize(lldb, ldb_dn_get_parent(lldb, newdn));
79 lldb->last_rc = ldap_rename_s(lldb->ldap, old_dn, newrdn, parentdn, 1, NULL, NULL);
80 if (lldb->last_rc != LDAP_SUCCESS) {
81 ldb_set_errstring(module, talloc_strdup(module, ldap_err2string(lldb->last_rc)));
85 talloc_free(local_ctx);
89 talloc_free(local_ctx);
96 static int lldb_delete(struct ldb_module *module, const struct ldb_dn *edn)
98 struct lldb_private *lldb = module->private_data;
102 /* ignore ltdb specials */
103 if (ldb_dn_is_special(edn)) {
107 dn = ldb_dn_linearize(lldb, edn);
109 lldb->last_rc = ldap_delete_s(lldb->ldap, dn);
110 if (lldb->last_rc != LDAP_SUCCESS) {
111 ldb_set_errstring(module, talloc_strdup(module, ldap_err2string(lldb->last_rc)));
120 add a single set of ldap message values to a ldb_message
122 static int lldb_add_msg_attr(struct ldb_context *ldb,
123 struct ldb_message *msg,
124 const char *attr, struct berval **bval)
127 struct ldb_message_element *el;
129 count = ldap_count_values_len(bval);
135 el = talloc_realloc(msg, msg->elements, struct ldb_message_element,
136 msg->num_elements + 1);
144 el = &msg->elements[msg->num_elements];
146 el->name = talloc_strdup(msg->elements, attr);
154 el->values = talloc_array(msg->elements, struct ldb_val, count);
160 for (i=0;i<count;i++) {
161 el->values[i].data = talloc_memdup(el->values, bval[i]->bv_val, bval[i]->bv_len);
162 if (!el->values[i].data) {
165 el->values[i].length = bval[i]->bv_len;
175 search for matching records
177 static int lldb_search_bytree(struct ldb_module *module, const struct ldb_dn *base,
178 enum ldb_scope scope, struct ldb_parse_tree *tree,
179 const char * const *attrs, struct ldb_message ***res)
181 struct ldb_context *ldb = module->ldb;
182 struct lldb_private *lldb = module->private_data;
183 int count, msg_count, ldap_scope;
185 LDAPMessage *ldapres, *msg;
188 search_base = ldb_dn_linearize(ldb, base);
190 search_base = talloc_strdup(ldb, "");
192 if (search_base == NULL) {
196 expression = ldb_filter_from_tree(search_base, tree);
197 if (expression == NULL) {
198 talloc_free(search_base);
204 ldap_scope = LDAP_SCOPE_BASE;
206 case LDB_SCOPE_ONELEVEL:
207 ldap_scope = LDAP_SCOPE_ONELEVEL;
210 ldap_scope = LDAP_SCOPE_SUBTREE;
214 lldb->last_rc = ldap_search_s(lldb->ldap, search_base, ldap_scope,
216 discard_const_p(char *, attrs),
218 talloc_free(search_base);
219 if (lldb->last_rc != LDAP_SUCCESS) {
220 ldb_set_errstring(module, talloc_strdup(module, ldap_err2string(lldb->last_rc)));
224 count = ldap_count_entries(lldb->ldap, ldapres);
225 if (count == -1 || count == 0) {
226 ldap_msgfree(ldapres);
230 (*res) = talloc_array(lldb, struct ldb_message *, count+1);
232 ldap_msgfree(ldapres);
241 /* loop over all messages */
242 for (msg=ldap_first_entry(lldb->ldap, ldapres);
244 msg=ldap_next_entry(lldb->ldap, msg)) {
245 BerElement *berptr = NULL;
248 if (msg_count == count) {
249 /* hmm, got too many? */
250 ldb_debug(ldb, LDB_DEBUG_FATAL, "Fatal: ldap message count inconsistent\n");
254 (*res)[msg_count] = talloc(*res, struct ldb_message);
255 if (!(*res)[msg_count]) {
258 (*res)[msg_count+1] = NULL;
260 dn = ldap_get_dn(lldb->ldap, msg);
265 (*res)[msg_count]->dn = ldb_dn_explode((*res)[msg_count], dn);
267 if (!(*res)[msg_count]->dn) {
272 (*res)[msg_count]->num_elements = 0;
273 (*res)[msg_count]->elements = NULL;
274 (*res)[msg_count]->private_data = NULL;
276 /* loop over all attributes */
277 for (attr=ldap_first_attribute(lldb->ldap, msg, &berptr);
279 attr=ldap_next_attribute(lldb->ldap, msg, berptr)) {
280 struct berval **bval;
281 bval = ldap_get_values_len(lldb->ldap, msg, attr);
284 lldb_add_msg_attr(ldb, (*res)[msg_count], attr, bval);
285 ldap_value_free_len(bval);
290 if (berptr) ber_free(berptr, 0);
295 ldap_msgfree(ldapres);
300 if (*res) talloc_free(*res);
306 convert a ldb_message structure to a list of LDAPMod structures
307 ready for ldap_add() or ldap_modify()
309 static LDAPMod **lldb_msg_to_mods(struct ldb_context *ldb,
310 const struct ldb_message *msg, int use_flags)
316 /* allocate maximum number of elements needed */
317 mods = talloc_array(ldb, LDAPMod *, msg->num_elements+1);
324 for (i=0;i<msg->num_elements;i++) {
325 const struct ldb_message_element *el = &msg->elements[i];
327 mods[num_mods] = talloc(ldb, LDAPMod);
328 if (!mods[num_mods]) {
331 mods[num_mods+1] = NULL;
332 mods[num_mods]->mod_op = LDAP_MOD_BVALUES;
334 switch (el->flags & LDB_FLAG_MOD_MASK) {
335 case LDB_FLAG_MOD_ADD:
336 mods[num_mods]->mod_op |= LDAP_MOD_ADD;
338 case LDB_FLAG_MOD_DELETE:
339 mods[num_mods]->mod_op |= LDAP_MOD_DELETE;
341 case LDB_FLAG_MOD_REPLACE:
342 mods[num_mods]->mod_op |= LDAP_MOD_REPLACE;
346 mods[num_mods]->mod_type = discard_const_p(char, el->name);
347 mods[num_mods]->mod_vals.modv_bvals = talloc_array(mods[num_mods],
350 if (!mods[num_mods]->mod_vals.modv_bvals) {
354 for (j=0;j<el->num_values;j++) {
355 mods[num_mods]->mod_vals.modv_bvals[j] = talloc(mods[num_mods]->mod_vals.modv_bvals,
357 if (!mods[num_mods]->mod_vals.modv_bvals[j]) {
360 mods[num_mods]->mod_vals.modv_bvals[j]->bv_val = el->values[j].data;
361 mods[num_mods]->mod_vals.modv_bvals[j]->bv_len = el->values[j].length;
363 mods[num_mods]->mod_vals.modv_bvals[j] = NULL;
378 static int lldb_add(struct ldb_module *module, const struct ldb_message *msg)
380 struct ldb_context *ldb = module->ldb;
381 struct lldb_private *lldb = module->private_data;
386 /* ignore ltdb specials */
387 if (ldb_dn_is_special(msg->dn)) {
391 mods = lldb_msg_to_mods(ldb, msg, 0);
396 dn = ldb_dn_linearize(mods, msg->dn);
402 lldb->last_rc = ldap_add_s(lldb->ldap, dn, mods);
403 if (lldb->last_rc != LDAP_SUCCESS) {
404 ldb_set_errstring(module, talloc_strdup(module, ldap_err2string(lldb->last_rc)));
417 static int lldb_modify(struct ldb_module *module, const struct ldb_message *msg)
419 struct ldb_context *ldb = module->ldb;
420 struct lldb_private *lldb = module->private_data;
425 /* ignore ltdb specials */
426 if (ldb_dn_is_special(msg->dn)) {
430 mods = lldb_msg_to_mods(ldb, msg, 1);
435 dn = ldb_dn_linearize(mods, msg->dn);
441 lldb->last_rc = ldap_modify_s(lldb->ldap, dn, mods);
442 if (lldb->last_rc != LDAP_SUCCESS) {
443 ldb_set_errstring(module, talloc_strdup(module, ldap_err2string(lldb->last_rc)));
452 static int lldb_start_trans(struct ldb_module *module)
454 /* TODO implement a local transaction mechanism here */
459 static int lldb_end_trans(struct ldb_module *module)
461 /* TODO implement a local transaction mechanism here */
466 static int lldb_del_trans(struct ldb_module *module)
468 /* TODO implement a local transaction mechanism here */
473 static const struct ldb_module_ops lldb_ops = {
475 .search_bytree = lldb_search_bytree,
476 .add_record = lldb_add,
477 .modify_record = lldb_modify,
478 .delete_record = lldb_delete,
479 .rename_record = lldb_rename,
480 .start_transaction = lldb_start_trans,
481 .end_transaction = lldb_end_trans,
482 .del_transaction = lldb_del_trans
486 static int lldb_destructor(void *p)
488 struct lldb_private *lldb = p;
489 ldap_unbind(lldb->ldap);
494 connect to the database
496 int lldb_connect(struct ldb_context *ldb,
499 const char *options[])
501 struct lldb_private *lldb = NULL;
504 lldb = talloc(ldb, struct lldb_private);
511 lldb->options = NULL;
513 lldb->last_rc = ldap_initialize(&lldb->ldap, url);
514 if (lldb->last_rc != LDAP_SUCCESS) {
515 ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_initialize failed for URL '%s' - %s\n",
516 url, ldap_err2string(lldb->last_rc));
520 talloc_set_destructor(lldb, lldb_destructor);
522 lldb->last_rc = ldap_set_option(lldb->ldap, LDAP_OPT_PROTOCOL_VERSION, &version);
523 if (lldb->last_rc != LDAP_SUCCESS) {
524 ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_set_option failed - %s\n",
525 ldap_err2string(lldb->last_rc));
528 ldb->modules = talloc(ldb, struct ldb_module);
533 ldb->modules->ldb = ldb;
534 ldb->modules->prev = ldb->modules->next = NULL;
535 ldb->modules->private_data = lldb;
536 ldb->modules->ops = &lldb_ops;