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"
42 we don't need this right now, but will once we add some backend
47 find an option in an option list (a null terminated list of strings)
49 this assumes the list is short. If it ever gets long then we really
50 should do this in some smarter way
52 static const char *lldb_option_find(const struct lldb_private *lldb, const char *name)
55 size_t len = strlen(name);
57 if (!lldb->options) return NULL;
59 for (i=0;lldb->options[i];i++) {
60 if (strncmp(lldb->options[i], name, len) == 0 &&
61 lldb->options[i][len] == '=') {
62 return &lldb->options[i][len+1];
73 static int lldb_rename(struct ldb_module *module, const char *olddn, const char *newdn)
75 struct lldb_private *lldb = module->private_data;
78 const char *parentdn = "";
79 TALLOC_CTX *mem_ctx = talloc_new(lldb);
81 /* ignore ltdb specials */
82 if (olddn[0] == '@' ||newdn[0] == '@') {
86 newrdn = talloc_strdup(mem_ctx, newdn);
91 p = strchr(newrdn, ',');
97 lldb->last_rc = ldap_rename_s(lldb->ldap, olddn, newrdn, parentdn, 1, NULL, NULL);
98 if (lldb->last_rc != LDAP_SUCCESS) {
102 talloc_free(mem_ctx);
110 static int lldb_delete(struct ldb_module *module, const char *dn)
112 struct lldb_private *lldb = module->private_data;
115 /* ignore ltdb specials */
120 lldb->last_rc = ldap_delete_s(lldb->ldap, dn);
121 if (lldb->last_rc != LDAP_SUCCESS) {
131 static int lldb_search_free(struct ldb_module *module, struct ldb_message **res)
139 add a single set of ldap message values to a ldb_message
141 static int lldb_add_msg_attr(struct ldb_context *ldb,
142 struct ldb_message *msg,
143 const char *attr, struct berval **bval)
146 struct ldb_message_element *el;
148 count = ldap_count_values_len(bval);
154 el = talloc_realloc(msg, msg->elements, struct ldb_message_element,
155 msg->num_elements + 1);
163 el = &msg->elements[msg->num_elements];
165 el->name = talloc_strdup(msg->elements, attr);
173 el->values = talloc_array(msg->elements, struct ldb_val, count);
179 for (i=0;i<count;i++) {
180 el->values[i].data = talloc_memdup(el->values, bval[i]->bv_val, bval[i]->bv_len);
181 if (!el->values[i].data) {
184 el->values[i].length = bval[i]->bv_len;
194 search for matching records
196 static int lldb_search(struct ldb_module *module, const char *base,
197 enum ldb_scope scope, const char *expression,
198 const char * const *attrs, struct ldb_message ***res)
200 struct ldb_context *ldb = module->ldb;
201 struct lldb_private *lldb = module->private_data;
202 int count, msg_count;
203 LDAPMessage *ldapres, *msg;
209 lldb->last_rc = ldap_search_s(lldb->ldap, base, (int)scope,
211 discard_const_p(char *, attrs),
213 if (lldb->last_rc != LDAP_SUCCESS) {
217 count = ldap_count_entries(lldb->ldap, ldapres);
218 if (count == -1 || count == 0) {
219 ldap_msgfree(ldapres);
223 (*res) = talloc_array(lldb, struct ldb_message *, count+1);
225 ldap_msgfree(ldapres);
234 /* loop over all messages */
235 for (msg=ldap_first_entry(lldb->ldap, ldapres);
237 msg=ldap_next_entry(lldb->ldap, msg)) {
238 BerElement *berptr = NULL;
241 if (msg_count == count) {
242 /* hmm, got too many? */
243 ldb_debug(ldb, LDB_DEBUG_FATAL, "Fatal: ldap message count inconsistent\n");
247 (*res)[msg_count] = talloc(*res, struct ldb_message);
248 if (!(*res)[msg_count]) {
251 (*res)[msg_count+1] = NULL;
253 dn = ldap_get_dn(lldb->ldap, msg);
258 (*res)[msg_count]->dn = talloc_strdup((*res)[msg_count], dn);
260 if (!(*res)[msg_count]->dn) {
265 (*res)[msg_count]->num_elements = 0;
266 (*res)[msg_count]->elements = NULL;
267 (*res)[msg_count]->private_data = NULL;
269 /* loop over all attributes */
270 for (attr=ldap_first_attribute(lldb->ldap, msg, &berptr);
272 attr=ldap_next_attribute(lldb->ldap, msg, berptr)) {
273 struct berval **bval;
274 bval = ldap_get_values_len(lldb->ldap, msg, attr);
277 lldb_add_msg_attr(ldb, (*res)[msg_count], attr, bval);
278 ldap_value_free_len(bval);
283 if (berptr) ber_free(berptr, 0);
288 ldap_msgfree(ldapres);
293 if (*res) lldb_search_free(module, *res);
299 convert a ldb_message structure to a list of LDAPMod structures
300 ready for ldap_add() or ldap_modify()
302 static LDAPMod **lldb_msg_to_mods(struct ldb_context *ldb,
303 const struct ldb_message *msg, int use_flags)
309 /* allocate maximum number of elements needed */
310 mods = talloc_array(ldb, LDAPMod *, msg->num_elements+1);
317 for (i=0;i<msg->num_elements;i++) {
318 const struct ldb_message_element *el = &msg->elements[i];
320 mods[num_mods] = talloc(ldb, LDAPMod);
321 if (!mods[num_mods]) {
324 mods[num_mods+1] = NULL;
325 mods[num_mods]->mod_op = LDAP_MOD_BVALUES;
327 switch (el->flags & LDB_FLAG_MOD_MASK) {
328 case LDB_FLAG_MOD_ADD:
329 mods[num_mods]->mod_op |= LDAP_MOD_ADD;
331 case LDB_FLAG_MOD_DELETE:
332 mods[num_mods]->mod_op |= LDAP_MOD_DELETE;
334 case LDB_FLAG_MOD_REPLACE:
335 mods[num_mods]->mod_op |= LDAP_MOD_REPLACE;
339 mods[num_mods]->mod_type = el->name;
340 mods[num_mods]->mod_vals.modv_bvals = talloc_array(mods[num_mods],
343 if (!mods[num_mods]->mod_vals.modv_bvals) {
347 for (j=0;j<el->num_values;j++) {
348 mods[num_mods]->mod_vals.modv_bvals[j] = talloc(mods[num_mods]->mod_vals.modv_bvals,
350 if (!mods[num_mods]->mod_vals.modv_bvals[j]) {
353 mods[num_mods]->mod_vals.modv_bvals[j]->bv_val = el->values[j].data;
354 mods[num_mods]->mod_vals.modv_bvals[j]->bv_len = el->values[j].length;
356 mods[num_mods]->mod_vals.modv_bvals[j] = NULL;
371 static int lldb_add(struct ldb_module *module, const struct ldb_message *msg)
373 struct ldb_context *ldb = module->ldb;
374 struct lldb_private *lldb = module->private_data;
378 /* ignore ltdb specials */
379 if (msg->dn[0] == '@') {
383 mods = lldb_msg_to_mods(ldb, msg, 0);
385 lldb->last_rc = ldap_add_s(lldb->ldap, msg->dn, mods);
386 if (lldb->last_rc != LDAP_SUCCESS) {
399 static int lldb_modify(struct ldb_module *module, const struct ldb_message *msg)
401 struct ldb_context *ldb = module->ldb;
402 struct lldb_private *lldb = module->private_data;
406 /* ignore ltdb specials */
407 if (msg->dn[0] == '@') {
411 mods = lldb_msg_to_mods(ldb, msg, 1);
413 lldb->last_rc = ldap_modify_s(lldb->ldap, msg->dn, mods);
414 if (lldb->last_rc != LDAP_SUCCESS) {
423 static int lldb_lock(struct ldb_module *module, const char *lockname)
427 if (lockname == NULL) {
431 /* TODO implement a local locking mechanism here */
436 static int lldb_unlock(struct ldb_module *module, const char *lockname)
440 if (lockname == NULL) {
444 /* TODO implement a local unlocking mechanism here */
450 return extended error information
452 static const char *lldb_errstring(struct ldb_module *module)
454 struct lldb_private *lldb = module->private_data;
455 return ldap_err2string(lldb->last_rc);
459 static const struct ldb_module_ops lldb_ops = {
473 static int lldb_destructor(void *p)
475 struct lldb_private *lldb = p;
476 ldap_unbind(lldb->ldap);
481 connect to the database
483 struct ldb_context *lldb_connect(const char *url,
485 const char *options[])
487 struct ldb_context *ldb = NULL;
488 struct lldb_private *lldb = NULL;
491 ldb = talloc(NULL, struct ldb_context);
497 lldb = talloc(ldb, struct lldb_private);
504 lldb->options = NULL;
506 lldb->last_rc = ldap_initialize(&lldb->ldap, url);
507 if (lldb->last_rc != LDAP_SUCCESS) {
511 talloc_set_destructor(lldb, lldb_destructor);
513 lldb->last_rc = ldap_set_option(lldb->ldap, LDAP_OPT_PROTOCOL_VERSION, &version);
514 if (lldb->last_rc != LDAP_SUCCESS) {
518 ldb->modules = talloc(ldb, struct ldb_module);
523 ldb->modules->ldb = ldb;
524 ldb->modules->prev = ldb->modules->next = NULL;
525 ldb->modules->private_data = lldb;
526 ldb->modules->ops = &lldb_ops;
529 /* take a copy of the options array, so we don't have to rely
530 on the caller keeping it around (it might be dynamic) */
531 for (i=0;options[i];i++) ;
533 lldb->options = talloc_array(lldb, char *, i+1);
534 if (!lldb->options) {
538 for (i=0;options[i];i++) {
539 lldb->options[i+1] = NULL;
540 lldb->options[i] = talloc_strdup(lldb->options, options[i]);
541 if (!lldb->options[i]) {