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) {
129 add a single set of ldap message values to a ldb_message
131 static int lldb_add_msg_attr(struct ldb_context *ldb,
132 struct ldb_message *msg,
133 const char *attr, struct berval **bval)
136 struct ldb_message_element *el;
138 count = ldap_count_values_len(bval);
144 el = talloc_realloc(msg, msg->elements, struct ldb_message_element,
145 msg->num_elements + 1);
153 el = &msg->elements[msg->num_elements];
155 el->name = talloc_strdup(msg->elements, attr);
163 el->values = talloc_array(msg->elements, struct ldb_val, count);
169 for (i=0;i<count;i++) {
170 el->values[i].data = talloc_memdup(el->values, bval[i]->bv_val, bval[i]->bv_len);
171 if (!el->values[i].data) {
174 el->values[i].length = bval[i]->bv_len;
184 search for matching records
186 static int lldb_search(struct ldb_module *module, const char *base,
187 enum ldb_scope scope, const char *expression,
188 const char * const *attrs, struct ldb_message ***res)
190 struct ldb_context *ldb = module->ldb;
191 struct lldb_private *lldb = module->private_data;
192 int count, msg_count;
193 LDAPMessage *ldapres, *msg;
199 lldb->last_rc = ldap_search_s(lldb->ldap, base, (int)scope,
201 discard_const_p(char *, attrs),
203 if (lldb->last_rc != LDAP_SUCCESS) {
207 count = ldap_count_entries(lldb->ldap, ldapres);
208 if (count == -1 || count == 0) {
209 ldap_msgfree(ldapres);
213 (*res) = talloc_array(lldb, struct ldb_message *, count+1);
215 ldap_msgfree(ldapres);
224 /* loop over all messages */
225 for (msg=ldap_first_entry(lldb->ldap, ldapres);
227 msg=ldap_next_entry(lldb->ldap, msg)) {
228 BerElement *berptr = NULL;
231 if (msg_count == count) {
232 /* hmm, got too many? */
233 ldb_debug(ldb, LDB_DEBUG_FATAL, "Fatal: ldap message count inconsistent\n");
237 (*res)[msg_count] = talloc(*res, struct ldb_message);
238 if (!(*res)[msg_count]) {
241 (*res)[msg_count+1] = NULL;
243 dn = ldap_get_dn(lldb->ldap, msg);
248 (*res)[msg_count]->dn = talloc_strdup((*res)[msg_count], dn);
250 if (!(*res)[msg_count]->dn) {
255 (*res)[msg_count]->num_elements = 0;
256 (*res)[msg_count]->elements = NULL;
257 (*res)[msg_count]->private_data = NULL;
259 /* loop over all attributes */
260 for (attr=ldap_first_attribute(lldb->ldap, msg, &berptr);
262 attr=ldap_next_attribute(lldb->ldap, msg, berptr)) {
263 struct berval **bval;
264 bval = ldap_get_values_len(lldb->ldap, msg, attr);
267 lldb_add_msg_attr(ldb, (*res)[msg_count], attr, bval);
268 ldap_value_free_len(bval);
273 if (berptr) ber_free(berptr, 0);
278 ldap_msgfree(ldapres);
283 if (*res) talloc_free(*res);
289 convert a ldb_message structure to a list of LDAPMod structures
290 ready for ldap_add() or ldap_modify()
292 static LDAPMod **lldb_msg_to_mods(struct ldb_context *ldb,
293 const struct ldb_message *msg, int use_flags)
299 /* allocate maximum number of elements needed */
300 mods = talloc_array(ldb, LDAPMod *, msg->num_elements+1);
307 for (i=0;i<msg->num_elements;i++) {
308 const struct ldb_message_element *el = &msg->elements[i];
310 mods[num_mods] = talloc(ldb, LDAPMod);
311 if (!mods[num_mods]) {
314 mods[num_mods+1] = NULL;
315 mods[num_mods]->mod_op = LDAP_MOD_BVALUES;
317 switch (el->flags & LDB_FLAG_MOD_MASK) {
318 case LDB_FLAG_MOD_ADD:
319 mods[num_mods]->mod_op |= LDAP_MOD_ADD;
321 case LDB_FLAG_MOD_DELETE:
322 mods[num_mods]->mod_op |= LDAP_MOD_DELETE;
324 case LDB_FLAG_MOD_REPLACE:
325 mods[num_mods]->mod_op |= LDAP_MOD_REPLACE;
329 mods[num_mods]->mod_type = el->name;
330 mods[num_mods]->mod_vals.modv_bvals = talloc_array(mods[num_mods],
333 if (!mods[num_mods]->mod_vals.modv_bvals) {
337 for (j=0;j<el->num_values;j++) {
338 mods[num_mods]->mod_vals.modv_bvals[j] = talloc(mods[num_mods]->mod_vals.modv_bvals,
340 if (!mods[num_mods]->mod_vals.modv_bvals[j]) {
343 mods[num_mods]->mod_vals.modv_bvals[j]->bv_val = el->values[j].data;
344 mods[num_mods]->mod_vals.modv_bvals[j]->bv_len = el->values[j].length;
346 mods[num_mods]->mod_vals.modv_bvals[j] = NULL;
361 static int lldb_add(struct ldb_module *module, const struct ldb_message *msg)
363 struct ldb_context *ldb = module->ldb;
364 struct lldb_private *lldb = module->private_data;
368 /* ignore ltdb specials */
369 if (msg->dn[0] == '@') {
373 mods = lldb_msg_to_mods(ldb, msg, 0);
375 lldb->last_rc = ldap_add_s(lldb->ldap, msg->dn, mods);
376 if (lldb->last_rc != LDAP_SUCCESS) {
389 static int lldb_modify(struct ldb_module *module, const struct ldb_message *msg)
391 struct ldb_context *ldb = module->ldb;
392 struct lldb_private *lldb = module->private_data;
396 /* ignore ltdb specials */
397 if (msg->dn[0] == '@') {
401 mods = lldb_msg_to_mods(ldb, msg, 1);
403 lldb->last_rc = ldap_modify_s(lldb->ldap, msg->dn, mods);
404 if (lldb->last_rc != LDAP_SUCCESS) {
413 static int lldb_lock(struct ldb_module *module, const char *lockname)
417 if (lockname == NULL) {
421 /* TODO implement a local locking mechanism here */
426 static int lldb_unlock(struct ldb_module *module, const char *lockname)
430 if (lockname == NULL) {
434 /* TODO implement a local unlocking mechanism here */
440 return extended error information
442 static const char *lldb_errstring(struct ldb_module *module)
444 struct lldb_private *lldb = module->private_data;
445 return ldap_err2string(lldb->last_rc);
449 static const struct ldb_module_ops lldb_ops = {
462 static int lldb_destructor(void *p)
464 struct lldb_private *lldb = p;
465 ldap_unbind(lldb->ldap);
470 connect to the database
472 struct ldb_context *lldb_connect(const char *url,
474 const char *options[])
476 struct ldb_context *ldb = NULL;
477 struct lldb_private *lldb = NULL;
480 ldb = talloc(NULL, struct ldb_context);
486 lldb = talloc(ldb, struct lldb_private);
493 lldb->options = NULL;
495 lldb->last_rc = ldap_initialize(&lldb->ldap, url);
496 if (lldb->last_rc != LDAP_SUCCESS) {
500 talloc_set_destructor(lldb, lldb_destructor);
502 lldb->last_rc = ldap_set_option(lldb->ldap, LDAP_OPT_PROTOCOL_VERSION, &version);
503 if (lldb->last_rc != LDAP_SUCCESS) {
507 ldb->modules = talloc(ldb, struct ldb_module);
512 ldb->modules->ldb = ldb;
513 ldb->modules->prev = ldb->modules->next = NULL;
514 ldb->modules->private_data = lldb;
515 ldb->modules->ops = &lldb_ops;
518 /* take a copy of the options array, so we don't have to rely
519 on the caller keeping it around (it might be dynamic) */
520 for (i=0;options[i];i++) ;
522 lldb->options = talloc_array(lldb, char *, i+1);
523 if (!lldb->options) {
527 for (i=0;options[i];i++) {
528 lldb->options[i+1] = NULL;
529 lldb->options[i] = talloc_strdup(lldb->options, options[i]);
530 if (!lldb->options[i]) {