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/ldb_ldap/ldb_ldap.h"
40 we don't need this right now, but will once we add some backend
45 find an option in an option list (a null terminated list of strings)
47 this assumes the list is short. If it ever gets long then we really
48 should do this in some smarter way
50 static const char *lldb_option_find(const struct lldb_private *lldb, const char *name)
53 size_t len = strlen(name);
55 if (!lldb->options) return NULL;
57 for (i=0;lldb->options[i];i++) {
58 if (strncmp(lldb->options[i], name, len) == 0 &&
59 lldb->options[i][len] == '=') {
60 return &lldb->options[i][len+1];
69 close/free the connection
71 static int lldb_close(struct ldb_context *ldb)
74 struct lldb_private *lldb = ldb->private_data;
76 if (ldap_unbind(lldb->ldap) != LDAP_SUCCESS) {
80 ldb_set_alloc(ldb, NULL, NULL);
83 for (i=0;lldb->options[i];i++) {
84 ldb_free(ldb, lldb->options[i]);
86 ldb_free(ldb, lldb->options);
97 static int lldb_delete(struct ldb_context *ldb, const char *dn)
99 struct lldb_private *lldb = ldb->private_data;
102 /* ignore ltdb specials */
107 lldb->last_rc = ldap_delete_s(lldb->ldap, dn);
108 if (lldb->last_rc != LDAP_SUCCESS) {
116 free a search message
118 static int lldb_msg_free(struct ldb_context *ldb, struct ldb_message *msg)
121 ldb_free(ldb, msg->dn);
122 for (i=0;i<msg->num_elements;i++) {
123 ldb_free(ldb, msg->elements[i].name);
124 for (j=0;j<msg->elements[i].num_values;j++) {
125 if (msg->elements[i].values[j].data) {
126 ldb_free(ldb, msg->elements[i].values[j].data);
129 ldb_free(ldb, msg->elements[i].values);
131 if (msg->elements) ldb_free(ldb, msg->elements);
139 static int lldb_search_free(struct ldb_context *ldb, struct ldb_message **res)
142 for (i=0;res[i];i++) {
143 if (lldb_msg_free(ldb, res[i]) != 0) {
153 add a single set of ldap message values to a ldb_message
155 static int lldb_add_msg_attr(struct ldb_context *ldb,
156 struct ldb_message *msg,
157 const char *attr, struct berval **bval)
160 struct ldb_message_element *el;
162 count = ldap_count_values_len(bval);
168 el = ldb_realloc_p(ldb, msg->elements, struct ldb_message_element,
169 msg->num_elements + 1);
177 el = &msg->elements[msg->num_elements];
179 el->name = ldb_strdup(ldb, attr);
187 el->values = ldb_malloc_array_p(ldb, struct ldb_val, count);
193 for (i=0;i<count;i++) {
194 el->values[i].data = ldb_malloc(ldb, bval[i]->bv_len);
195 if (!el->values[i].data) {
198 memcpy(el->values[i].data, bval[i]->bv_val, bval[i]->bv_len);
199 el->values[i].length = bval[i]->bv_len;
209 search for matching records
211 static int lldb_search(struct ldb_context *ldb, const char *base,
212 enum ldb_scope scope, const char *expression,
213 const char * const *attrs, struct ldb_message ***res)
215 struct lldb_private *lldb = ldb->private_data;
216 int count, msg_count;
217 LDAPMessage *ldapres, *msg;
219 lldb->last_rc = ldap_search_s(lldb->ldap, base, (int)scope,
220 expression, attrs, 0, &ldapres);
221 if (lldb->last_rc != LDAP_SUCCESS) {
225 count = ldap_count_entries(lldb->ldap, ldapres);
226 if (count == -1 || count == 0) {
227 ldap_msgfree(ldapres);
231 (*res) = ldb_malloc_array_p(ldb, struct ldb_message *, count+1);
233 ldap_msgfree(ldapres);
242 /* loop over all messages */
243 for (msg=ldap_first_entry(lldb->ldap, ldapres);
245 msg=ldap_next_entry(lldb->ldap, msg)) {
246 BerElement *berptr = NULL;
249 if (msg_count == count) {
250 /* hmm, got too many? */
251 ldb_debug(ldb, LDB_DEBUG_FATAL, "Fatal: ldap message count inconsistent\n");
255 (*res)[msg_count] = ldb_malloc_p(ldb, struct ldb_message);
256 if (!(*res)[msg_count]) {
259 (*res)[msg_count+1] = NULL;
261 dn = ldap_get_dn(lldb->ldap, msg);
266 (*res)[msg_count]->dn = ldb_strdup(ldb, dn);
268 if (!(*res)[msg_count]->dn) {
273 (*res)[msg_count]->num_elements = 0;
274 (*res)[msg_count]->elements = NULL;
275 (*res)[msg_count]->private_data = NULL;
277 /* loop over all attributes */
278 for (attr=ldap_first_attribute(lldb->ldap, msg, &berptr);
280 attr=ldap_next_attribute(lldb->ldap, msg, berptr)) {
281 struct berval **bval;
282 bval = ldap_get_values_len(lldb->ldap, msg, attr);
285 lldb_add_msg_attr(ldb, (*res)[msg_count], attr, bval);
286 ldap_value_free_len(bval);
291 if (berptr) ber_free(berptr, 0);
296 ldap_msgfree(ldapres);
301 if (*res) lldb_search_free(ldb, *res);
307 free a set of mods from lldb_msg_to_mods()
309 static void lldb_mods_free(struct ldb_context *ldb, LDAPMod **mods)
315 for (i=0;mods[i];i++) {
316 if (mods[i]->mod_vals.modv_bvals) {
317 for (j=0;mods[i]->mod_vals.modv_bvals[j];j++) {
318 ldb_free(ldb, mods[i]->mod_vals.modv_bvals[j]);
320 ldb_free(ldb, mods[i]->mod_vals.modv_bvals);
322 ldb_free(ldb, mods[i]);
329 convert a ldb_message structure to a list of LDAPMod structures
330 ready for ldap_add() or ldap_modify()
332 static LDAPMod **lldb_msg_to_mods(struct ldb_context *ldb,
333 const struct ldb_message *msg, int use_flags)
339 /* allocate maximum number of elements needed */
340 mods = ldb_malloc_array_p(ldb, LDAPMod *, msg->num_elements+1);
347 for (i=0;i<msg->num_elements;i++) {
348 const struct ldb_message_element *el = &msg->elements[i];
350 mods[num_mods] = ldb_malloc_p(ldb, LDAPMod);
351 if (!mods[num_mods]) {
354 mods[num_mods+1] = NULL;
355 mods[num_mods]->mod_op = LDAP_MOD_BVALUES;
357 switch (el->flags & LDB_FLAG_MOD_MASK) {
358 case LDB_FLAG_MOD_ADD:
359 mods[num_mods]->mod_op |= LDAP_MOD_ADD;
361 case LDB_FLAG_MOD_DELETE:
362 mods[num_mods]->mod_op |= LDAP_MOD_DELETE;
364 case LDB_FLAG_MOD_REPLACE:
365 mods[num_mods]->mod_op |= LDAP_MOD_REPLACE;
369 mods[num_mods]->mod_type = el->name;
370 mods[num_mods]->mod_vals.modv_bvals = ldb_malloc_array_p(ldb,
373 if (!mods[num_mods]->mod_vals.modv_bvals) {
377 for (j=0;j<el->num_values;j++) {
378 mods[num_mods]->mod_vals.modv_bvals[j] = ldb_malloc_p(ldb, struct berval);
379 if (!mods[num_mods]->mod_vals.modv_bvals[j]) {
382 mods[num_mods]->mod_vals.modv_bvals[j]->bv_val = el->values[j].data;
383 mods[num_mods]->mod_vals.modv_bvals[j]->bv_len = el->values[j].length;
385 mods[num_mods]->mod_vals.modv_bvals[j] = NULL;
392 lldb_mods_free(ldb, mods);
400 static int lldb_add(struct ldb_context *ldb, const struct ldb_message *msg)
402 struct lldb_private *lldb = ldb->private_data;
406 /* ignore ltdb specials */
407 if (msg->dn[0] == '@') {
411 mods = lldb_msg_to_mods(ldb, msg, 0);
413 lldb->last_rc = ldap_add_s(lldb->ldap, msg->dn, mods);
414 if (lldb->last_rc != LDAP_SUCCESS) {
418 lldb_mods_free(ldb, mods);
427 static int lldb_modify(struct ldb_context *ldb, const struct ldb_message *msg)
429 struct lldb_private *lldb = ldb->private_data;
433 /* ignore ltdb specials */
434 if (msg->dn[0] == '@') {
438 mods = lldb_msg_to_mods(ldb, msg, 1);
440 lldb->last_rc = ldap_modify_s(lldb->ldap, msg->dn, mods);
441 if (lldb->last_rc != LDAP_SUCCESS) {
445 lldb_mods_free(ldb, mods);
452 return extended error information
454 static const char *lldb_errstring(struct ldb_context *ldb)
456 struct lldb_private *lldb = ldb->private_data;
457 return ldap_err2string(lldb->last_rc);
461 static const struct ldb_backend_ops lldb_ops = {
473 connect to the database
475 struct ldb_context *lldb_connect(const char *url,
477 const char *options[])
479 struct ldb_context *ldb = NULL;
480 struct lldb_private *lldb = NULL;
483 ldb = calloc(1, sizeof(struct ldb_context));
489 lldb = ldb_malloc_p(ldb, struct lldb_private);
497 lldb->options = NULL;
499 lldb->last_rc = ldap_initialize(&lldb->ldap, url);
500 if (lldb->last_rc != LDAP_SUCCESS) {
504 ldb->ops = &lldb_ops;
505 ldb->private_data = lldb;
508 /* take a copy of the options array, so we don't have to rely
509 on the caller keeping it around (it might be dynamic) */
510 for (i=0;options[i];i++) ;
512 lldb->options = ldb_malloc_array_p(ldb, char *, i+1);
513 if (!lldb->options) {
517 for (i=0;options[i];i++) {
518 lldb->options[i+1] = NULL;
519 lldb->options[i] = ldb_strdup(ldb, options[i]);
520 if (!lldb->options[i]) {
529 if (lldb && lldb->options) {
530 for (i=0;lldb->options[i];i++) {
531 ldb_free(ldb, lldb->options[i]);
533 ldb_free(ldb, lldb->options);
535 if (lldb && lldb->ldap) {
536 ldap_unbind(lldb->ldap);