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
41 we don't need this right now, but will once we add some backend
46 find an option in an option list (a null terminated list of strings)
48 this assumes the list is short. If it ever gets long then we really
49 should do this in some smarter way
51 static const char *lldb_option_find(const struct lldb_private
*lldb
, const char *name
)
54 size_t len
= strlen(name
);
56 if (!lldb
->options
) return NULL
;
58 for (i
=0;lldb
->options
[i
];i
++) {
59 if (strncmp(lldb
->options
[i
], name
, len
) == 0 &&
60 lldb
->options
[i
][len
] == '=') {
61 return &lldb
->options
[i
][len
+1];
70 close/free the connection
72 static int lldb_close(struct ldb_context
*ldb
)
75 struct lldb_private
*lldb
= ldb
->private;
77 if (ldap_unbind(lldb
->ldap
) != LDAP_SUCCESS
) {
82 for (i
=0;lldb
->options
[i
];i
++) {
83 free(lldb
->options
[i
]);
96 static int lldb_delete(struct ldb_context
*ldb
, const char *dn
)
98 struct lldb_private
*lldb
= ldb
->private;
101 lldb
->last_rc
= ldap_delete_s(lldb
->ldap
, dn
);
102 if (lldb
->last_rc
!= LDAP_SUCCESS
) {
110 free a search message
112 static int lldb_msg_free(struct ldb_context
*ldb
, struct ldb_message
*msg
)
116 for (i
=0;i
<msg
->num_elements
;i
++) {
117 free(msg
->elements
[i
].name
);
118 for (j
=0;j
<msg
->elements
[i
].num_values
;j
++) {
119 if (msg
->elements
[i
].values
[j
].data
) {
120 free(msg
->elements
[i
].values
[j
].data
);
123 free(msg
->elements
[i
].values
);
125 if (msg
->elements
) free(msg
->elements
);
133 static int lldb_search_free(struct ldb_context
*ldb
, struct ldb_message
**res
)
136 for (i
=0;res
[i
];i
++) {
137 if (lldb_msg_free(ldb
, res
[i
]) != 0) {
147 add a single set of ldap message values to a ldb_message
149 static int lldb_add_msg_attr(struct ldb_message
*msg
,
150 const char *attr
, struct berval
**bval
)
153 struct ldb_message_element
*el
;
155 count
= ldap_count_values_len(bval
);
161 el
= realloc_p(msg
->elements
, struct ldb_message_element
,
162 msg
->num_elements
+ 1);
170 el
= &msg
->elements
[msg
->num_elements
];
172 el
->name
= strdup(attr
);
180 el
->values
= malloc_array_p(struct ldb_val
, count
);
186 for (i
=0;i
<count
;i
++) {
187 el
->values
[i
].data
= malloc(bval
[i
]->bv_len
);
188 if (!el
->values
[i
].data
) {
191 memcpy(el
->values
[i
].data
, bval
[i
]->bv_val
, bval
[i
]->bv_len
);
192 el
->values
[i
].length
= bval
[i
]->bv_len
;
202 search for matching records
204 static int lldb_search(struct ldb_context
*ldb
, const char *base
,
205 enum ldb_scope scope
, const char *expression
,
206 const char **attrs
, struct ldb_message
***res
)
208 struct lldb_private
*lldb
= ldb
->private;
209 int count
, msg_count
;
210 LDAPMessage
*ldapres
, *msg
;
212 lldb
->last_rc
= ldap_search_s(lldb
->ldap
, base
, (int)scope
,
213 expression
, attrs
, 0, &ldapres
);
214 if (lldb
->last_rc
!= LDAP_SUCCESS
) {
218 count
= ldap_count_entries(lldb
->ldap
, ldapres
);
219 if (count
== -1 || count
== 0) {
220 ldap_msgfree(ldapres
);
224 (*res
) = malloc_array_p(struct ldb_message
*, count
+1);
226 ldap_msgfree(ldapres
);
235 /* loop over all messages */
236 for (msg
=ldap_first_entry(lldb
->ldap
, ldapres
);
238 msg
=ldap_next_entry(lldb
->ldap
, msg
)) {
239 BerElement
*berptr
= NULL
;
242 if (msg_count
== count
) {
243 /* hmm, got too many? */
244 fprintf(stderr
,"Too many messages?!\n");
248 (*res
)[msg_count
] = malloc_p(struct ldb_message
);
249 if (!(*res
)[msg_count
]) {
252 (*res
)[msg_count
+1] = NULL
;
254 dn
= ldap_get_dn(lldb
->ldap
, msg
);
259 (*res
)[msg_count
]->dn
= strdup(dn
);
261 if (!(*res
)[msg_count
]->dn
) {
266 (*res
)[msg_count
]->num_elements
= 0;
267 (*res
)[msg_count
]->elements
= NULL
;
268 (*res
)[msg_count
]->private = NULL
;
270 /* loop over all attributes */
271 for (attr
=ldap_first_attribute(lldb
->ldap
, msg
, &berptr
);
273 attr
=ldap_next_attribute(lldb
->ldap
, msg
, berptr
)) {
274 struct berval
**bval
;
275 bval
= ldap_get_values_len(lldb
->ldap
, msg
, attr
);
278 lldb_add_msg_attr((*res
)[msg_count
], attr
, bval
);
279 ldap_value_free_len(bval
);
284 if (berptr
) ber_free(berptr
, 0);
289 ldap_msgfree(ldapres
);
294 if (*res
) lldb_search_free(ldb
, *res
);
300 free a set of mods from lldb_msg_to_mods()
302 static void lldb_mods_free(LDAPMod
**mods
)
308 for (i
=0;mods
[i
];i
++) {
309 if (mods
[i
]->mod_vals
.modv_bvals
) {
310 for (j
=0;mods
[i
]->mod_vals
.modv_bvals
[j
];j
++) {
311 free(mods
[i
]->mod_vals
.modv_bvals
[j
]);
313 free(mods
[i
]->mod_vals
.modv_bvals
);
322 convert a ldb_message structure to a list of LDAPMod structures
323 ready for ldap_add() or ldap_modify()
325 static LDAPMod
**lldb_msg_to_mods(const struct ldb_message
*msg
, int use_flags
)
328 int i
, j
, num_mods
= 0;
330 /* allocate maximum number of elements needed */
331 mods
= malloc_array_p(LDAPMod
*, msg
->num_elements
+1);
338 for (i
=0;i
<msg
->num_elements
;i
++) {
339 const struct ldb_message_element
*el
= &msg
->elements
[i
];
341 mods
[num_mods
] = malloc_p(LDAPMod
);
342 if (!mods
[num_mods
]) {
345 mods
[num_mods
+1] = NULL
;
346 mods
[num_mods
]->mod_op
= LDAP_MOD_BVALUES
;
348 switch (el
->flags
& LDB_FLAG_MOD_MASK
) {
349 case LDB_FLAG_MOD_ADD
:
350 mods
[num_mods
]->mod_op
|= LDAP_MOD_ADD
;
352 case LDB_FLAG_MOD_DELETE
:
353 mods
[num_mods
]->mod_op
|= LDAP_MOD_DELETE
;
355 case LDB_FLAG_MOD_REPLACE
:
356 mods
[num_mods
]->mod_op
|= LDAP_MOD_REPLACE
;
360 mods
[num_mods
]->mod_type
= el
->name
;
361 mods
[num_mods
]->mod_vals
.modv_bvals
= malloc_array_p(struct berval
*,
363 if (!mods
[num_mods
]->mod_vals
.modv_bvals
) {
367 for (j
=0;j
<el
->num_values
;j
++) {
368 mods
[num_mods
]->mod_vals
.modv_bvals
[j
] = malloc_p(struct berval
);
369 if (!mods
[num_mods
]->mod_vals
.modv_bvals
[j
]) {
372 mods
[num_mods
]->mod_vals
.modv_bvals
[j
]->bv_val
= el
->values
[j
].data
;
373 mods
[num_mods
]->mod_vals
.modv_bvals
[j
]->bv_len
= el
->values
[j
].length
;
375 mods
[num_mods
]->mod_vals
.modv_bvals
[j
] = NULL
;
382 lldb_mods_free(mods
);
390 static int lldb_add(struct ldb_context
*ldb
, const struct ldb_message
*msg
)
392 struct lldb_private
*lldb
= ldb
->private;
396 mods
= lldb_msg_to_mods(msg
, 0);
398 lldb
->last_rc
= ldap_add_s(lldb
->ldap
, msg
->dn
, mods
);
399 if (lldb
->last_rc
!= LDAP_SUCCESS
) {
403 lldb_mods_free(mods
);
412 static int lldb_modify(struct ldb_context
*ldb
, const struct ldb_message
*msg
)
414 struct lldb_private
*lldb
= ldb
->private;
418 mods
= lldb_msg_to_mods(msg
, 1);
420 lldb
->last_rc
= ldap_modify_s(lldb
->ldap
, msg
->dn
, mods
);
421 if (lldb
->last_rc
!= LDAP_SUCCESS
) {
425 lldb_mods_free(mods
);
432 return extended error information
434 static const char *lldb_errstring(struct ldb_context
*ldb
)
436 struct lldb_private
*lldb
= ldb
->private;
437 return ldap_err2string(lldb
->last_rc
);
441 static const struct ldb_backend_ops lldb_ops
= {
453 connect to the database
455 struct ldb_context
*lldb_connect(const char *url
,
457 const char *options
[])
459 struct ldb_context
*ldb
= NULL
;
460 struct lldb_private
*lldb
= NULL
;
463 ldb
= malloc_p(struct ldb_context
);
469 lldb
= malloc_p(struct lldb_private
);
477 lldb
->options
= NULL
;
479 lldb
->last_rc
= ldap_initialize(&lldb
->ldap
, url
);
480 if (lldb
->last_rc
!= LDAP_SUCCESS
) {
484 ldb
->ops
= &lldb_ops
;
488 /* take a copy of the options array, so we don't have to rely
489 on the caller keeping it around (it might be dynamic) */
490 for (i
=0;options
[i
];i
++) ;
492 lldb
->options
= malloc_array_p(char *, i
+1);
493 if (!lldb
->options
) {
497 for (i
=0;options
[i
];i
++) {
498 lldb
->options
[i
+1] = NULL
;
499 lldb
->options
[i
] = strdup(options
[i
]);
500 if (!lldb
->options
[i
]) {
509 if (lldb
&& lldb
->options
) {
510 for (i
=0;lldb
->options
[i
];i
++) {
511 free(lldb
->options
[i
]);
515 if (lldb
&& lldb
->ldap
) {
516 ldap_unbind(lldb
->ldap
);
518 if (lldb
) free(lldb
);