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_ldap/ldb_ldap.h"
40 we don't need this right now, but will once we add more 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;
76 if (ldap_unbind(lldb->ldap) != LDAP_SUCCESS) {
81 for (i=0;lldb->options[i];i++) {
82 free(lldb->options[i]);
95 static int lldb_delete(struct ldb_context *ldb, const char *dn)
97 struct lldb_private *lldb = ldb->private;
100 lldb->last_rc = ldap_delete_s(lldb->ldap, dn);
101 if (lldb->last_rc != LDAP_SUCCESS) {
109 free a search message
111 static int lldb_msg_free(struct ldb_context *ldb, struct ldb_message *msg)
115 for (i=0;i<msg->num_elements;i++) {
116 free(msg->elements[i].name);
117 if (msg->elements[i].value.data) {
118 free(msg->elements[i].value.data);
121 if (msg->elements) free(msg->elements);
129 static int lldb_search_free(struct ldb_context *ldb, struct ldb_message **res)
132 for (i=0;res[i];i++) {
133 if (lldb_msg_free(ldb, res[i]) != 0) {
143 add a single set of ldap message values to a ldb_message
145 static int lldb_add_msg_attr(struct ldb_message *msg,
146 const char *attr, struct berval **bval)
149 struct ldb_message_element *el;
151 count = ldap_count_values_len(bval);
157 el = realloc_p(msg->elements, struct ldb_message_element,
158 msg->num_elements + count);
166 for (i=0;i<count;i++) {
167 msg->elements[msg->num_elements].name = strdup(attr);
168 if (!msg->elements[msg->num_elements].name) {
171 msg->elements[msg->num_elements].value.data = malloc(bval[i]->bv_len);
172 if (!msg->elements[msg->num_elements].value.data) {
173 free(msg->elements[msg->num_elements].name);
176 memcpy(msg->elements[msg->num_elements].value.data,
177 bval[i]->bv_val, bval[i]->bv_len);
178 msg->elements[msg->num_elements].value.length = bval[i]->bv_len;
186 search for matching records
188 static int lldb_search(struct ldb_context *ldb, const char *base,
189 enum ldb_scope scope, const char *expression,
190 const char **attrs, struct ldb_message ***res)
192 struct lldb_private *lldb = ldb->private;
193 int count, msg_count;
194 LDAPMessage *ldapres, *msg;
196 lldb->last_rc = ldap_search_s(lldb->ldap, base, (int)scope,
197 expression, attrs, 0, &ldapres);
198 if (lldb->last_rc != LDAP_SUCCESS) {
202 count = ldap_count_entries(lldb->ldap, ldapres);
203 if (count == -1 || count == 0) {
204 ldap_msgfree(ldapres);
208 (*res) = malloc_array_p(struct ldb_message *, count+1);
210 ldap_msgfree(ldapres);
219 /* loop over all messages */
220 for (msg=ldap_first_entry(lldb->ldap, ldapres);
222 msg=ldap_next_entry(lldb->ldap, msg)) {
223 BerElement *berptr = NULL;
226 if (msg_count == count) {
227 /* hmm, got too many? */
228 fprintf(stderr,"Too many messages?!\n");
232 (*res)[msg_count] = malloc_p(struct ldb_message);
233 if (!(*res)[msg_count]) {
236 (*res)[msg_count+1] = NULL;
238 dn = ldap_get_dn(lldb->ldap, msg);
243 (*res)[msg_count]->dn = strdup(dn);
245 if (!(*res)[msg_count]->dn) {
250 (*res)[msg_count]->num_elements = 0;
251 (*res)[msg_count]->elements = NULL;
252 (*res)[msg_count]->private = NULL;
254 /* loop over all attributes */
255 for (attr=ldap_first_attribute(lldb->ldap, msg, &berptr);
257 attr=ldap_next_attribute(lldb->ldap, msg, berptr)) {
258 struct berval **bval;
259 bval = ldap_get_values_len(lldb->ldap, msg, attr);
262 lldb_add_msg_attr((*res)[msg_count], attr, bval);
263 ldap_value_free_len(bval);
268 if (berptr) ber_free(berptr, 0);
273 ldap_msgfree(ldapres);
278 if (*res) lldb_search_free(ldb, *res);
284 free a set of mods from lldb_msg_to_mods()
286 static void lldb_mods_free(LDAPMod **mods)
292 for (i=0;mods[i];i++) {
293 if (mods[i]->mod_vals.modv_bvals) {
294 for (j=0;mods[i]->mod_vals.modv_bvals[j];j++) {
295 free(mods[i]->mod_vals.modv_bvals[j]);
297 free(mods[i]->mod_vals.modv_bvals);
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(const struct ldb_message *msg, int use_flags)
312 int i, num_vals, num_mods = 0;
314 /* allocate maximum number of elements needed */
315 mods = malloc_array_p(LDAPMod *, msg->num_elements+1);
322 for (i=0;i<msg->num_elements;i++) {
326 (msg->elements[i].flags == msg->elements[i-1].flags)) &&
327 strcmp(msg->elements[i].name, msg->elements[i-1].name) == 0) {
329 /* when attributes are repeated we need to extend the
330 existing bvals array */
331 b = realloc_p(mods[num_mods-1]->mod_vals.modv_bvals,
332 struct berval *, num_vals+2);
336 mods[num_mods-1]->mod_vals.modv_bvals = b;
337 b[num_vals+1] = NULL;
338 b[num_vals] = malloc_p(struct berval);
339 if (!b[num_vals]) goto failed;
340 b[num_vals]->bv_val = msg->elements[i].value.data;
341 b[num_vals]->bv_len = msg->elements[i].value.length;
348 mods[num_mods] = malloc_p(LDAPMod);
349 if (!mods[num_mods]) {
352 mods[num_mods+1] = NULL;
353 mods[num_mods]->mod_op = LDAP_MOD_BVALUES;
355 switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
356 case LDB_FLAG_MOD_ADD:
357 mods[num_mods]->mod_op |= LDAP_MOD_ADD;
359 case LDB_FLAG_MOD_DELETE:
360 mods[num_mods]->mod_op |= LDAP_MOD_DELETE;
362 case LDB_FLAG_MOD_REPLACE:
363 mods[num_mods]->mod_op |= LDAP_MOD_REPLACE;
367 mods[num_mods]->mod_type = msg->elements[i].name;
368 mods[num_mods]->mod_vals.modv_bvals = malloc_array_p(struct berval *, 2);
369 if (!mods[num_mods]->mod_vals.modv_bvals) {
372 mods[num_mods]->mod_vals.modv_bvals[0] = malloc_p(struct berval);
373 if (!mods[num_mods]->mod_vals.modv_bvals[0]) {
376 mods[num_mods]->mod_vals.modv_bvals[0]->bv_val = msg->elements[i].value.data;
377 mods[num_mods]->mod_vals.modv_bvals[0]->bv_len = msg->elements[i].value.length;
378 mods[num_mods]->mod_vals.modv_bvals[1] = NULL;
385 lldb_mods_free(mods);
393 static int lldb_add(struct ldb_context *ldb, const struct ldb_message *msg)
395 struct lldb_private *lldb = ldb->private;
399 mods = lldb_msg_to_mods(msg, 0);
401 lldb->last_rc = ldap_add_s(lldb->ldap, msg->dn, mods);
402 if (lldb->last_rc != LDAP_SUCCESS) {
406 lldb_mods_free(mods);
415 static int lldb_modify(struct ldb_context *ldb, const struct ldb_message *msg)
417 struct lldb_private *lldb = ldb->private;
421 mods = lldb_msg_to_mods(msg, 1);
423 lldb->last_rc = ldap_modify_s(lldb->ldap, msg->dn, mods);
424 if (lldb->last_rc != LDAP_SUCCESS) {
428 lldb_mods_free(mods);
435 return extended error information
437 static const char *lldb_errstring(struct ldb_context *ldb)
439 struct lldb_private *lldb = ldb->private;
440 return ldap_err2string(lldb->last_rc);
444 static const struct ldb_backend_ops lldb_ops = {
456 connect to the database
458 struct ldb_context *lldb_connect(const char *url,
460 const char *options[])
462 struct ldb_context *ldb = NULL;
463 struct lldb_private *lldb = NULL;
466 ldb = malloc_p(struct ldb_context);
472 lldb = malloc_p(struct lldb_private);
480 lldb->options = NULL;
482 lldb->last_rc = ldap_initialize(&lldb->ldap, url);
483 if (lldb->last_rc != LDAP_SUCCESS) {
487 ldb->ops = &lldb_ops;
491 /* take a copy of the options array, so we don't have to rely
492 on the caller keeping it around (it might be dynamic) */
493 for (i=0;options[i];i++) ;
495 lldb->options = malloc_array_p(char *, i+1);
496 if (!lldb->options) {
500 for (i=0;options[i];i++) {
501 lldb->options[i+1] = NULL;
502 lldb->options[i] = strdup(options[i]);
503 if (!lldb->options[i]) {
512 if (lldb && lldb->options) {
513 for (i=0;lldb->options[i];i++) {
514 free(lldb->options[i]);
518 if (lldb && lldb->ldap) {
519 ldap_unbind(lldb->ldap);
521 if (lldb) free(lldb);