VERSION: Raise version number up to 3.0.36.
[Samba.git] / source / nsswitch / idmap_ldap.c
blobd1639c07721b684f0ad2d3842dc2e71b57f40293
1 /*
2 Unix SMB/CIFS implementation.
4 idmap LDAP backend
6 Copyright (C) Tim Potter 2000
7 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
8 Copyright (C) Gerald Carter 2003
9 Copyright (C) Simo Sorce 2003-2007
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include "includes.h"
28 #undef DBGC_CLASS
29 #define DBGC_CLASS DBGC_IDMAP
31 #include <lber.h>
32 #include <ldap.h>
34 #include "smbldap.h"
36 struct idmap_ldap_context {
37 struct smbldap_state *smbldap_state;
38 char *url;
39 char *suffix;
40 char *user_dn;
41 uint32_t filter_low_id, filter_high_id; /* Filter range */
42 BOOL anon;
45 struct idmap_ldap_alloc_context {
46 struct smbldap_state *smbldap_state;
47 char *url;
48 char *suffix;
49 char *user_dn;
50 uid_t low_uid, high_uid; /* Range of uids */
51 gid_t low_gid, high_gid; /* Range of gids */
55 #define CHECK_ALLOC_DONE(mem) do { \
56 if (!mem) { \
57 DEBUG(0, ("Out of memory!\n")); \
58 ret = NT_STATUS_NO_MEMORY; \
59 goto done; \
60 } } while (0)
62 /**********************************************************************
63 IDMAP ALLOC TDB BACKEND
64 **********************************************************************/
66 static struct idmap_ldap_alloc_context *idmap_alloc_ldap;
68 /*********************************************************************
69 ********************************************************************/
71 static NTSTATUS get_credentials( TALLOC_CTX *mem_ctx,
72 struct smbldap_state *ldap_state,
73 const char *config_option,
74 struct idmap_domain *dom,
75 char **dn )
77 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
78 char *secret = NULL;
79 const char *tmp = NULL;
80 char *user_dn = NULL;
81 BOOL anon = False;
83 /* assume anonymous if we don't have a specified user */
85 tmp = lp_parm_const_string(-1, config_option, "ldap_user_dn", NULL);
87 if ( tmp ) {
88 if (!dom) {
89 /* only the alloc backend can pass in a NULL dom */
90 secret = idmap_fetch_secret("ldap", True,
91 NULL, tmp);
92 } else {
93 secret = idmap_fetch_secret("ldap", False,
94 dom->name, tmp);
97 if (!secret) {
98 DEBUG(0, ("get_credentials: Unable to fetch "
99 "auth credentials for %s in %s\n",
100 tmp, (dom==NULL)?"ALLOC":dom->name));
101 ret = NT_STATUS_ACCESS_DENIED;
102 goto done;
104 *dn = talloc_strdup(mem_ctx, tmp);
105 CHECK_ALLOC_DONE(*dn);
106 } else {
107 if (!fetch_ldap_pw(&user_dn, &secret)) {
108 DEBUG(2, ("get_credentials: Failed to lookup ldap "
109 "bind creds. Using anonymous connection.\n"));
110 anon = True;
111 } else {
112 *dn = talloc_strdup(mem_ctx, user_dn);
113 SAFE_FREE( user_dn );
114 CHECK_ALLOC_DONE(*dn);
118 smbldap_set_creds(ldap_state, anon, *dn, secret);
119 ret = NT_STATUS_OK;
121 done:
122 SAFE_FREE(secret);
124 return ret;
128 /**********************************************************************
129 Verify the sambaUnixIdPool entry in the directory.
130 **********************************************************************/
132 static NTSTATUS verify_idpool(void)
134 NTSTATUS ret;
135 TALLOC_CTX *ctx;
136 LDAPMessage *result = NULL;
137 LDAPMod **mods = NULL;
138 const char **attr_list;
139 char *filter;
140 int count;
141 int rc;
143 if ( ! idmap_alloc_ldap) {
144 return NT_STATUS_UNSUCCESSFUL;
147 ctx = talloc_new(idmap_alloc_ldap);
148 if ( ! ctx) {
149 DEBUG(0, ("Out of memory!\n"));
150 return NT_STATUS_NO_MEMORY;
153 filter = talloc_asprintf(ctx, "(objectclass=%s)", LDAP_OBJ_IDPOOL);
154 CHECK_ALLOC_DONE(filter);
156 attr_list = get_attr_list(ctx, idpool_attr_list);
157 CHECK_ALLOC_DONE(attr_list);
159 rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
160 idmap_alloc_ldap->suffix,
161 LDAP_SCOPE_SUBTREE,
162 filter,
163 attr_list,
165 &result);
167 if (rc != LDAP_SUCCESS) {
168 DEBUG(1, ("Unable to verify the idpool, "
169 "cannot continue initialization!\n"));
170 return NT_STATUS_UNSUCCESSFUL;
173 count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
174 result);
176 ldap_msgfree(result);
178 if ( count > 1 ) {
179 DEBUG(0,("Multiple entries returned from %s (base == %s)\n",
180 filter, idmap_alloc_ldap->suffix));
181 ret = NT_STATUS_UNSUCCESSFUL;
182 goto done;
184 else if (count == 0) {
185 char *uid_str, *gid_str;
187 uid_str = talloc_asprintf(ctx, "%lu",
188 (unsigned long)idmap_alloc_ldap->low_uid);
189 gid_str = talloc_asprintf(ctx, "%lu",
190 (unsigned long)idmap_alloc_ldap->low_gid);
192 smbldap_set_mod(&mods, LDAP_MOD_ADD,
193 "objectClass", LDAP_OBJ_IDPOOL);
194 smbldap_set_mod(&mods, LDAP_MOD_ADD,
195 get_attr_key2string(idpool_attr_list,
196 LDAP_ATTR_UIDNUMBER),
197 uid_str);
198 smbldap_set_mod(&mods, LDAP_MOD_ADD,
199 get_attr_key2string(idpool_attr_list,
200 LDAP_ATTR_GIDNUMBER),
201 gid_str);
202 if (mods) {
203 rc = smbldap_modify(idmap_alloc_ldap->smbldap_state,
204 idmap_alloc_ldap->suffix,
205 mods);
206 ldap_mods_free(mods, True);
207 } else {
208 ret = NT_STATUS_UNSUCCESSFUL;
209 goto done;
213 ret = (rc == LDAP_SUCCESS)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL;
214 done:
215 talloc_free(ctx);
216 return ret;
219 /*****************************************************************************
220 Initialise idmap database.
221 *****************************************************************************/
223 static NTSTATUS idmap_ldap_alloc_init(const char *params)
225 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
226 const char *range;
227 const char *tmp;
228 uid_t low_uid = 0;
229 uid_t high_uid = 0;
230 gid_t low_gid = 0;
231 gid_t high_gid = 0;
233 /* Only do init if we are online */
234 if (idmap_is_offline()) {
235 return NT_STATUS_FILE_IS_OFFLINE;
238 idmap_alloc_ldap = TALLOC_ZERO_P(NULL, struct idmap_ldap_alloc_context);
239 CHECK_ALLOC_DONE( idmap_alloc_ldap );
241 /* load ranges */
243 idmap_alloc_ldap->low_uid = 0;
244 idmap_alloc_ldap->high_uid = 0;
245 idmap_alloc_ldap->low_gid = 0;
246 idmap_alloc_ldap->high_gid = 0;
248 range = lp_parm_const_string(-1, "idmap alloc config", "range", NULL);
249 if (range && range[0]) {
250 unsigned low_id, high_id;
252 if (sscanf(range, "%u - %u", &low_id, &high_id) == 2) {
253 if (low_id < high_id) {
254 idmap_alloc_ldap->low_gid = low_id;
255 idmap_alloc_ldap->low_uid = low_id;
256 idmap_alloc_ldap->high_gid = high_id;
257 idmap_alloc_ldap->high_uid = high_id;
258 } else {
259 DEBUG(1, ("ERROR: invalid idmap alloc range "
260 "[%s]", range));
262 } else {
263 DEBUG(1, ("ERROR: invalid syntax for idmap alloc "
264 "config:range [%s]", range));
268 if (lp_idmap_uid(&low_uid, &high_uid)) {
269 idmap_alloc_ldap->low_uid = low_uid;
270 idmap_alloc_ldap->high_uid = high_uid;
273 if (lp_idmap_gid(&low_gid, &high_gid)) {
274 idmap_alloc_ldap->low_gid = low_gid;
275 idmap_alloc_ldap->high_gid= high_gid;
278 if (idmap_alloc_ldap->high_uid <= idmap_alloc_ldap->low_uid) {
279 DEBUG(1, ("idmap uid range missing or invalid\n"));
280 DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
281 ret = NT_STATUS_UNSUCCESSFUL;
282 goto done;
285 if (idmap_alloc_ldap->high_gid <= idmap_alloc_ldap->low_gid) {
286 DEBUG(1, ("idmap gid range missing or invalid\n"));
287 DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
288 ret = NT_STATUS_UNSUCCESSFUL;
289 goto done;
292 if (params && *params) {
293 /* assume location is the only parameter */
294 idmap_alloc_ldap->url = talloc_strdup(idmap_alloc_ldap, params);
295 } else {
296 tmp = lp_parm_const_string(-1, "idmap alloc config",
297 "ldap_url", NULL);
299 if ( ! tmp) {
300 DEBUG(1, ("ERROR: missing idmap ldap url\n"));
301 ret = NT_STATUS_UNSUCCESSFUL;
302 goto done;
305 idmap_alloc_ldap->url = talloc_strdup(idmap_alloc_ldap, tmp);
307 CHECK_ALLOC_DONE( idmap_alloc_ldap->url );
309 tmp = lp_parm_const_string(-1, "idmap alloc config",
310 "ldap_base_dn", NULL);
311 if ( ! tmp || ! *tmp) {
312 tmp = lp_ldap_idmap_suffix();
313 if ( ! tmp) {
314 DEBUG(1, ("ERROR: missing idmap ldap suffix\n"));
315 ret = NT_STATUS_UNSUCCESSFUL;
316 goto done;
320 idmap_alloc_ldap->suffix = talloc_strdup(idmap_alloc_ldap, tmp);
321 CHECK_ALLOC_DONE( idmap_alloc_ldap->suffix );
323 ret = smbldap_init(idmap_alloc_ldap, idmap_alloc_ldap->url,
324 &idmap_alloc_ldap->smbldap_state);
325 if (!NT_STATUS_IS_OK(ret)) {
326 DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n",
327 idmap_alloc_ldap->url));
328 goto done;
331 ret = get_credentials( idmap_alloc_ldap,
332 idmap_alloc_ldap->smbldap_state,
333 "idmap alloc config", NULL,
334 &idmap_alloc_ldap->user_dn );
335 if ( !NT_STATUS_IS_OK(ret) ) {
336 DEBUG(1,("idmap_ldap_alloc_init: Failed to get connection "
337 "credentials (%s)\n", nt_errstr(ret)));
338 goto done;
341 /* see if the idmap suffix and sub entries exists */
343 ret = verify_idpool();
345 done:
346 if ( !NT_STATUS_IS_OK( ret ) )
347 TALLOC_FREE( idmap_alloc_ldap );
349 return ret;
352 /********************************
353 Allocate a new uid or gid
354 ********************************/
356 static NTSTATUS idmap_ldap_allocate_id(struct unixid *xid)
358 TALLOC_CTX *ctx;
359 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
360 int rc = LDAP_SERVER_DOWN;
361 int count = 0;
362 LDAPMessage *result = NULL;
363 LDAPMessage *entry = NULL;
364 LDAPMod **mods = NULL;
365 char *id_str;
366 char *new_id_str;
367 char *filter = NULL;
368 const char *dn = NULL;
369 const char **attr_list;
370 const char *type;
372 /* Only do query if we are online */
373 if (idmap_is_offline()) {
374 return NT_STATUS_FILE_IS_OFFLINE;
377 if ( ! idmap_alloc_ldap) {
378 return NT_STATUS_UNSUCCESSFUL;
381 ctx = talloc_new(idmap_alloc_ldap);
382 if ( ! ctx) {
383 DEBUG(0, ("Out of memory!\n"));
384 return NT_STATUS_NO_MEMORY;
387 /* get type */
388 switch (xid->type) {
390 case ID_TYPE_UID:
391 type = get_attr_key2string(idpool_attr_list,
392 LDAP_ATTR_UIDNUMBER);
393 break;
395 case ID_TYPE_GID:
396 type = get_attr_key2string(idpool_attr_list,
397 LDAP_ATTR_GIDNUMBER);
398 break;
400 default:
401 DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
402 return NT_STATUS_INVALID_PARAMETER;
405 filter = talloc_asprintf(ctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
406 CHECK_ALLOC_DONE(filter);
408 attr_list = get_attr_list(ctx, idpool_attr_list);
409 CHECK_ALLOC_DONE(attr_list);
411 DEBUG(10, ("Search of the id pool (filter: %s)\n", filter));
413 rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
414 idmap_alloc_ldap->suffix,
415 LDAP_SCOPE_SUBTREE, filter,
416 attr_list, 0, &result);
418 if (rc != LDAP_SUCCESS) {
419 DEBUG(0,("%s object not found\n", LDAP_OBJ_IDPOOL));
420 goto done;
423 talloc_autofree_ldapmsg(ctx, result);
425 count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
426 result);
427 if (count != 1) {
428 DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL));
429 goto done;
432 entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct,
433 result);
435 dn = smbldap_talloc_dn(ctx,
436 idmap_alloc_ldap->smbldap_state->ldap_struct,
437 entry);
438 if ( ! dn) {
439 goto done;
442 if ( ! (id_str = smbldap_talloc_single_attribute(idmap_alloc_ldap->smbldap_state->ldap_struct,
443 entry, type, ctx))) {
444 DEBUG(0,("%s attribute not found\n", type));
445 goto done;
447 if ( ! id_str) {
448 DEBUG(0,("Out of memory\n"));
449 ret = NT_STATUS_NO_MEMORY;
450 goto done;
453 xid->id = strtoul(id_str, NULL, 10);
455 /* make sure we still have room to grow */
457 switch (xid->type) {
458 case ID_TYPE_UID:
459 if (xid->id > idmap_alloc_ldap->high_uid) {
460 DEBUG(0,("Cannot allocate uid above %lu!\n",
461 (unsigned long)idmap_alloc_ldap->high_uid));
462 goto done;
464 break;
466 case ID_TYPE_GID:
467 if (xid->id > idmap_alloc_ldap->high_gid) {
468 DEBUG(0,("Cannot allocate gid above %lu!\n",
469 (unsigned long)idmap_alloc_ldap->high_uid));
470 goto done;
472 break;
474 default:
475 /* impossible */
476 goto done;
479 new_id_str = talloc_asprintf(ctx, "%lu", (unsigned long)xid->id + 1);
480 if ( ! new_id_str) {
481 DEBUG(0,("Out of memory\n"));
482 ret = NT_STATUS_NO_MEMORY;
483 goto done;
486 smbldap_set_mod(&mods, LDAP_MOD_DELETE, type, id_str);
487 smbldap_set_mod(&mods, LDAP_MOD_ADD, type, new_id_str);
489 if (mods == NULL) {
490 DEBUG(0,("smbldap_set_mod() failed.\n"));
491 goto done;
494 DEBUG(10, ("Try to atomically increment the id (%s -> %s)\n",
495 id_str, new_id_str));
497 rc = smbldap_modify(idmap_alloc_ldap->smbldap_state, dn, mods);
499 ldap_mods_free(mods, True);
501 if (rc != LDAP_SUCCESS) {
502 DEBUG(1,("Failed to allocate new %s. "
503 "smbldap_modify() failed.\n", type));
504 goto done;
507 ret = NT_STATUS_OK;
509 done:
510 talloc_free(ctx);
511 return ret;
514 /**********************************
515 Get current highest id.
516 **********************************/
518 static NTSTATUS idmap_ldap_get_hwm(struct unixid *xid)
520 TALLOC_CTX *memctx;
521 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
522 int rc = LDAP_SERVER_DOWN;
523 int count = 0;
524 LDAPMessage *result = NULL;
525 LDAPMessage *entry = NULL;
526 char *id_str;
527 char *filter = NULL;
528 const char **attr_list;
529 const char *type;
531 /* Only do query if we are online */
532 if (idmap_is_offline()) {
533 return NT_STATUS_FILE_IS_OFFLINE;
536 if ( ! idmap_alloc_ldap) {
537 return NT_STATUS_UNSUCCESSFUL;
540 memctx = talloc_new(idmap_alloc_ldap);
541 if ( ! memctx) {
542 DEBUG(0, ("Out of memory!\n"));
543 return NT_STATUS_NO_MEMORY;
546 /* get type */
547 switch (xid->type) {
549 case ID_TYPE_UID:
550 type = get_attr_key2string(idpool_attr_list,
551 LDAP_ATTR_UIDNUMBER);
552 break;
554 case ID_TYPE_GID:
555 type = get_attr_key2string(idpool_attr_list,
556 LDAP_ATTR_GIDNUMBER);
557 break;
559 default:
560 DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
561 return NT_STATUS_INVALID_PARAMETER;
564 filter = talloc_asprintf(memctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
565 CHECK_ALLOC_DONE(filter);
567 attr_list = get_attr_list(memctx, idpool_attr_list);
568 CHECK_ALLOC_DONE(attr_list);
570 rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
571 idmap_alloc_ldap->suffix,
572 LDAP_SCOPE_SUBTREE, filter,
573 attr_list, 0, &result);
575 if (rc != LDAP_SUCCESS) {
576 DEBUG(0,("%s object not found\n", LDAP_OBJ_IDPOOL));
577 goto done;
580 talloc_autofree_ldapmsg(memctx, result);
582 count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
583 result);
584 if (count != 1) {
585 DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL));
586 goto done;
589 entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct,
590 result);
592 id_str = smbldap_talloc_single_attribute(idmap_alloc_ldap->smbldap_state->ldap_struct,
593 entry, type, memctx);
594 if ( ! id_str) {
595 DEBUG(0,("%s attribute not found\n", type));
596 goto done;
598 if ( ! id_str) {
599 DEBUG(0,("Out of memory\n"));
600 ret = NT_STATUS_NO_MEMORY;
601 goto done;
604 xid->id = strtoul(id_str, NULL, 10);
606 ret = NT_STATUS_OK;
607 done:
608 talloc_free(memctx);
609 return ret;
611 /**********************************
612 Set highest id.
613 **********************************/
615 static NTSTATUS idmap_ldap_set_hwm(struct unixid *xid)
617 TALLOC_CTX *ctx;
618 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
619 int rc = LDAP_SERVER_DOWN;
620 int count = 0;
621 LDAPMessage *result = NULL;
622 LDAPMessage *entry = NULL;
623 LDAPMod **mods = NULL;
624 char *new_id_str;
625 char *filter = NULL;
626 const char *dn = NULL;
627 const char **attr_list;
628 const char *type;
630 /* Only do query if we are online */
631 if (idmap_is_offline()) {
632 return NT_STATUS_FILE_IS_OFFLINE;
635 if ( ! idmap_alloc_ldap) {
636 return NT_STATUS_UNSUCCESSFUL;
639 ctx = talloc_new(idmap_alloc_ldap);
640 if ( ! ctx) {
641 DEBUG(0, ("Out of memory!\n"));
642 return NT_STATUS_NO_MEMORY;
645 /* get type */
646 switch (xid->type) {
648 case ID_TYPE_UID:
649 type = get_attr_key2string(idpool_attr_list,
650 LDAP_ATTR_UIDNUMBER);
651 break;
653 case ID_TYPE_GID:
654 type = get_attr_key2string(idpool_attr_list,
655 LDAP_ATTR_GIDNUMBER);
656 break;
658 default:
659 DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
660 return NT_STATUS_INVALID_PARAMETER;
663 filter = talloc_asprintf(ctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
664 CHECK_ALLOC_DONE(filter);
666 attr_list = get_attr_list(ctx, idpool_attr_list);
667 CHECK_ALLOC_DONE(attr_list);
669 rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
670 idmap_alloc_ldap->suffix,
671 LDAP_SCOPE_SUBTREE, filter,
672 attr_list, 0, &result);
674 if (rc != LDAP_SUCCESS) {
675 DEBUG(0,("%s object not found\n", LDAP_OBJ_IDPOOL));
676 goto done;
679 talloc_autofree_ldapmsg(ctx, result);
681 count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
682 result);
683 if (count != 1) {
684 DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL));
685 goto done;
688 entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct,
689 result);
691 dn = smbldap_talloc_dn(ctx,
692 idmap_alloc_ldap->smbldap_state->ldap_struct,
693 entry);
694 if ( ! dn) {
695 goto done;
698 new_id_str = talloc_asprintf(ctx, "%lu", (unsigned long)xid->id);
699 if ( ! new_id_str) {
700 DEBUG(0,("Out of memory\n"));
701 ret = NT_STATUS_NO_MEMORY;
702 goto done;
705 smbldap_set_mod(&mods, LDAP_MOD_REPLACE, type, new_id_str);
707 if (mods == NULL) {
708 DEBUG(0,("smbldap_set_mod() failed.\n"));
709 goto done;
712 rc = smbldap_modify(idmap_alloc_ldap->smbldap_state, dn, mods);
714 ldap_mods_free(mods, True);
716 if (rc != LDAP_SUCCESS) {
717 DEBUG(1,("Failed to allocate new %s. "
718 "smbldap_modify() failed.\n", type));
719 goto done;
722 ret = NT_STATUS_OK;
724 done:
725 talloc_free(ctx);
726 return ret;
729 /**********************************
730 Close idmap ldap alloc
731 **********************************/
733 static NTSTATUS idmap_ldap_alloc_close(void)
735 if (idmap_alloc_ldap) {
736 smbldap_free_struct(&idmap_alloc_ldap->smbldap_state);
737 DEBUG(5,("The connection to the LDAP server was closed\n"));
738 /* maybe free the results here --metze */
739 TALLOC_FREE(idmap_alloc_ldap);
741 return NT_STATUS_OK;
745 /**********************************************************************
746 IDMAP MAPPING LDAP BACKEND
747 **********************************************************************/
749 static int idmap_ldap_close_destructor(struct idmap_ldap_context *ctx)
751 smbldap_free_struct(&ctx->smbldap_state);
752 DEBUG(5,("The connection to the LDAP server was closed\n"));
753 /* maybe free the results here --metze */
755 return 0;
758 /********************************
759 Initialise idmap database.
760 ********************************/
762 static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom)
764 NTSTATUS ret;
765 struct idmap_ldap_context *ctx = NULL;
766 char *config_option = NULL;
767 const char *range = NULL;
768 const char *tmp = NULL;
770 /* Only do init if we are online */
771 if (idmap_is_offline()) {
772 return NT_STATUS_FILE_IS_OFFLINE;
775 ctx = TALLOC_ZERO_P(dom, struct idmap_ldap_context);
776 if ( ! ctx) {
777 DEBUG(0, ("Out of memory!\n"));
778 return NT_STATUS_NO_MEMORY;
781 config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
782 if ( ! config_option) {
783 DEBUG(0, ("Out of memory!\n"));
784 ret = NT_STATUS_NO_MEMORY;
785 goto done;
788 /* load ranges */
789 range = lp_parm_const_string(-1, config_option, "range", NULL);
790 if (range && range[0]) {
791 if ((sscanf(range, "%u - %u", &ctx->filter_low_id,
792 &ctx->filter_high_id) != 2) ||
793 (ctx->filter_low_id > ctx->filter_high_id)) {
794 DEBUG(1, ("ERROR: invalid filter range [%s]", range));
795 ctx->filter_low_id = 0;
796 ctx->filter_high_id = 0;
800 if (dom->params && *(dom->params)) {
801 /* assume location is the only parameter */
802 ctx->url = talloc_strdup(ctx, dom->params);
803 } else {
804 tmp = lp_parm_const_string(-1, config_option, "ldap_url", NULL);
806 if ( ! tmp) {
807 DEBUG(1, ("ERROR: missing idmap ldap url\n"));
808 ret = NT_STATUS_UNSUCCESSFUL;
809 goto done;
812 ctx->url = talloc_strdup(ctx, tmp);
814 CHECK_ALLOC_DONE(ctx->url);
816 tmp = lp_parm_const_string(-1, config_option, "ldap_base_dn", NULL);
817 if ( ! tmp || ! *tmp) {
818 tmp = lp_ldap_idmap_suffix();
819 if ( ! tmp) {
820 DEBUG(1, ("ERROR: missing idmap ldap suffix\n"));
821 ret = NT_STATUS_UNSUCCESSFUL;
822 goto done;
826 ctx->suffix = talloc_strdup(ctx, tmp);
827 CHECK_ALLOC_DONE(ctx->suffix);
829 ret = smbldap_init(ctx, ctx->url, &ctx->smbldap_state);
830 if (!NT_STATUS_IS_OK(ret)) {
831 DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n", ctx->url));
832 goto done;
835 ret = get_credentials( ctx, ctx->smbldap_state, config_option,
836 dom, &ctx->user_dn );
837 if ( !NT_STATUS_IS_OK(ret) ) {
838 DEBUG(1,("idmap_ldap_db_init: Failed to get connection "
839 "credentials (%s)\n", nt_errstr(ret)));
840 goto done;
843 /* set the destructor on the context, so that resource are properly
844 freed if the contexts is released */
846 talloc_set_destructor(ctx, idmap_ldap_close_destructor);
848 dom->private_data = ctx;
849 dom->initialized = True;
851 talloc_free(config_option);
852 return NT_STATUS_OK;
854 /*failed */
855 done:
856 talloc_free(ctx);
857 return ret;
860 /* max number of ids requested per batch query */
861 #define IDMAP_LDAP_MAX_IDS 30
863 /**********************************
864 lookup a set of unix ids.
865 **********************************/
867 /* this function searches up to IDMAP_LDAP_MAX_IDS entries
868 * in maps for a match */
869 static struct id_map *find_map_by_id(struct id_map **maps,
870 enum id_type type,
871 uint32_t id)
873 int i;
875 for (i = 0; i < IDMAP_LDAP_MAX_IDS; i++) {
876 if (maps[i] == NULL) { /* end of the run */
877 return NULL;
879 if ((maps[i]->xid.type == type) && (maps[i]->xid.id == id)) {
880 return maps[i];
884 return NULL;
887 static NTSTATUS idmap_ldap_unixids_to_sids(struct idmap_domain *dom,
888 struct id_map **ids)
890 NTSTATUS ret;
891 TALLOC_CTX *memctx;
892 struct idmap_ldap_context *ctx;
893 LDAPMessage *result = NULL;
894 const char *uidNumber;
895 const char *gidNumber;
896 const char **attr_list;
897 char *filter = NULL;
898 BOOL multi = False;
899 int idx = 0;
900 int bidx = 0;
901 int count;
902 int rc;
903 int i;
905 /* Only do query if we are online */
906 if (idmap_is_offline()) {
907 return NT_STATUS_FILE_IS_OFFLINE;
910 /* Initilization my have been deferred because we were offline */
911 if ( ! dom->initialized) {
912 ret = idmap_ldap_db_init(dom);
913 if ( ! NT_STATUS_IS_OK(ret)) {
914 return ret;
918 ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
920 memctx = talloc_new(ctx);
921 if ( ! memctx) {
922 DEBUG(0, ("Out of memory!\n"));
923 return NT_STATUS_NO_MEMORY;
926 uidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_UIDNUMBER);
927 gidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_GIDNUMBER);
929 attr_list = get_attr_list(memctx, sidmap_attr_list);
931 if ( ! ids[1]) {
932 /* if we are requested just one mapping use the simple filter */
934 filter = talloc_asprintf(memctx, "(&(objectClass=%s)(%s=%lu))",
935 LDAP_OBJ_IDMAP_ENTRY,
936 (ids[0]->xid.type==ID_TYPE_UID)?uidNumber:gidNumber,
937 (unsigned long)ids[0]->xid.id);
938 CHECK_ALLOC_DONE(filter);
939 DEBUG(10, ("Filter: [%s]\n", filter));
940 } else {
941 /* multiple mappings */
942 multi = True;
945 again:
946 if (multi) {
948 talloc_free(filter);
949 filter = talloc_asprintf(memctx,
950 "(&(objectClass=%s)(|",
951 LDAP_OBJ_IDMAP_ENTRY);
952 CHECK_ALLOC_DONE(filter);
954 bidx = idx;
955 for (i = 0; (i < IDMAP_LDAP_MAX_IDS) && ids[idx]; i++, idx++) {
956 filter = talloc_asprintf_append(filter, "(%s=%lu)",
957 (ids[idx]->xid.type==ID_TYPE_UID)?uidNumber:gidNumber,
958 (unsigned long)ids[idx]->xid.id);
959 CHECK_ALLOC_DONE(filter);
961 filter = talloc_asprintf_append(filter, "))");
962 CHECK_ALLOC_DONE(filter);
963 DEBUG(10, ("Filter: [%s]\n", filter));
964 } else {
965 bidx = 0;
966 idx = 1;
969 rc = smbldap_search(ctx->smbldap_state, ctx->suffix, LDAP_SCOPE_SUBTREE,
970 filter, attr_list, 0, &result);
972 if (rc != LDAP_SUCCESS) {
973 DEBUG(3,("Failure looking up ids (%s)\n", ldap_err2string(rc)));
974 ret = NT_STATUS_UNSUCCESSFUL;
975 goto done;
978 count = ldap_count_entries(ctx->smbldap_state->ldap_struct, result);
980 if (count == 0) {
981 DEBUG(10, ("NO SIDs found\n"));
984 for (i = 0; i < count; i++) {
985 LDAPMessage *entry = NULL;
986 char *sidstr = NULL;
987 char *tmp = NULL;
988 enum id_type type;
989 struct id_map *map;
990 uint32_t id;
992 if (i == 0) { /* first entry */
993 entry = ldap_first_entry(ctx->smbldap_state->ldap_struct,
994 result);
995 } else { /* following ones */
996 entry = ldap_next_entry(ctx->smbldap_state->ldap_struct,
997 entry);
999 if ( ! entry) {
1000 DEBUG(2, ("ERROR: Unable to fetch ldap entries "
1001 "from results\n"));
1002 break;
1005 /* first check if the SID is present */
1006 sidstr = smbldap_talloc_single_attribute(
1007 ctx->smbldap_state->ldap_struct,
1008 entry, LDAP_ATTRIBUTE_SID, memctx);
1009 if ( ! sidstr) { /* no sid, skip entry */
1010 DEBUG(2, ("WARNING SID not found on entry\n"));
1011 continue;
1014 /* now try to see if it is a uid, if not try with a gid
1015 * (gid is more common, but in case both uidNumber and
1016 * gidNumber are returned the SID is mapped to the uid
1017 *not the gid) */
1018 type = ID_TYPE_UID;
1019 tmp = smbldap_talloc_single_attribute(
1020 ctx->smbldap_state->ldap_struct,
1021 entry, uidNumber, memctx);
1022 if ( ! tmp) {
1023 type = ID_TYPE_GID;
1024 tmp = smbldap_talloc_single_attribute(
1025 ctx->smbldap_state->ldap_struct,
1026 entry, gidNumber, memctx);
1028 if ( ! tmp) { /* wow very strange entry, how did it match ? */
1029 DEBUG(5, ("Unprobable match on (%s), no uidNumber, "
1030 "nor gidNumber returned\n", sidstr));
1031 TALLOC_FREE(sidstr);
1032 continue;
1035 id = strtoul(tmp, NULL, 10);
1036 if ((id == 0) ||
1037 (ctx->filter_low_id && (id < ctx->filter_low_id)) ||
1038 (ctx->filter_high_id && (id > ctx->filter_high_id))) {
1039 DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
1040 "Filtered!\n", id,
1041 ctx->filter_low_id, ctx->filter_high_id));
1042 TALLOC_FREE(sidstr);
1043 TALLOC_FREE(tmp);
1044 continue;
1046 TALLOC_FREE(tmp);
1048 map = find_map_by_id(&ids[bidx], type, id);
1049 if (!map) {
1050 DEBUG(2, ("WARNING: couldn't match sid (%s) "
1051 "with requested ids\n", sidstr));
1052 TALLOC_FREE(sidstr);
1053 continue;
1056 if ( ! string_to_sid(map->sid, sidstr)) {
1057 DEBUG(2, ("ERROR: Invalid SID on entry\n"));
1058 TALLOC_FREE(sidstr);
1059 continue;
1061 TALLOC_FREE(sidstr);
1063 /* mapped */
1064 map->status = ID_MAPPED;
1066 DEBUG(10, ("Mapped %s -> %lu (%d)\n",
1067 sid_string_static(map->sid),
1068 (unsigned long)map->xid.id, map->xid.type));
1071 /* free the ldap results */
1072 if (result) {
1073 ldap_msgfree(result);
1074 result = NULL;
1077 if (multi && ids[idx]) { /* still some values to map */
1078 goto again;
1081 ret = NT_STATUS_OK;
1083 /* mark all unknwon/expired ones as unmapped */
1084 for (i = 0; ids[i]; i++) {
1085 if (ids[i]->status != ID_MAPPED)
1086 ids[i]->status = ID_UNMAPPED;
1089 done:
1090 talloc_free(memctx);
1091 return ret;
1094 /**********************************
1095 lookup a set of sids.
1096 **********************************/
1098 /* this function searches up to IDMAP_LDAP_MAX_IDS entries
1099 * in maps for a match */
1100 static struct id_map *find_map_by_sid(struct id_map **maps, DOM_SID *sid)
1102 int i;
1104 for (i = 0; i < IDMAP_LDAP_MAX_IDS; i++) {
1105 if (maps[i] == NULL) { /* end of the run */
1106 return NULL;
1108 if (sid_equal(maps[i]->sid, sid)) {
1109 return maps[i];
1113 return NULL;
1116 static NTSTATUS idmap_ldap_sids_to_unixids(struct idmap_domain *dom,
1117 struct id_map **ids)
1119 LDAPMessage *entry = NULL;
1120 NTSTATUS ret;
1121 TALLOC_CTX *memctx;
1122 struct idmap_ldap_context *ctx;
1123 LDAPMessage *result = NULL;
1124 const char *uidNumber;
1125 const char *gidNumber;
1126 const char **attr_list;
1127 char *filter = NULL;
1128 BOOL multi = False;
1129 int idx = 0;
1130 int bidx = 0;
1131 int count;
1132 int rc;
1133 int i;
1135 /* Only do query if we are online */
1136 if (idmap_is_offline()) {
1137 return NT_STATUS_FILE_IS_OFFLINE;
1140 /* Initilization my have been deferred because we were offline */
1141 if ( ! dom->initialized) {
1142 ret = idmap_ldap_db_init(dom);
1143 if ( ! NT_STATUS_IS_OK(ret)) {
1144 return ret;
1148 ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
1150 memctx = talloc_new(ctx);
1151 if ( ! memctx) {
1152 DEBUG(0, ("Out of memory!\n"));
1153 return NT_STATUS_NO_MEMORY;
1156 uidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_UIDNUMBER);
1157 gidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_GIDNUMBER);
1159 attr_list = get_attr_list(memctx, sidmap_attr_list);
1161 if ( ! ids[1]) {
1162 /* if we are requested just one mapping use the simple filter */
1164 filter = talloc_asprintf(memctx, "(&(objectClass=%s)(%s=%s))",
1165 LDAP_OBJ_IDMAP_ENTRY,
1166 LDAP_ATTRIBUTE_SID,
1167 sid_string_static(ids[0]->sid));
1168 CHECK_ALLOC_DONE(filter);
1169 DEBUG(10, ("Filter: [%s]\n", filter));
1170 } else {
1171 /* multiple mappings */
1172 multi = True;
1175 again:
1176 if (multi) {
1178 TALLOC_FREE(filter);
1179 filter = talloc_asprintf(memctx,
1180 "(&(objectClass=%s)(|",
1181 LDAP_OBJ_IDMAP_ENTRY);
1182 CHECK_ALLOC_DONE(filter);
1184 bidx = idx;
1185 for (i = 0; (i < IDMAP_LDAP_MAX_IDS) && ids[idx]; i++, idx++) {
1186 filter = talloc_asprintf_append(filter, "(%s=%s)",
1187 LDAP_ATTRIBUTE_SID,
1188 sid_string_static(ids[idx]->sid));
1189 CHECK_ALLOC_DONE(filter);
1191 filter = talloc_asprintf_append(filter, "))");
1192 CHECK_ALLOC_DONE(filter);
1193 DEBUG(10, ("Filter: [%s]", filter));
1194 } else {
1195 bidx = 0;
1196 idx = 1;
1199 rc = smbldap_search(ctx->smbldap_state, ctx->suffix, LDAP_SCOPE_SUBTREE,
1200 filter, attr_list, 0, &result);
1202 if (rc != LDAP_SUCCESS) {
1203 DEBUG(3,("Failure looking up sids (%s)\n",
1204 ldap_err2string(rc)));
1205 ret = NT_STATUS_UNSUCCESSFUL;
1206 goto done;
1209 count = ldap_count_entries(ctx->smbldap_state->ldap_struct, result);
1211 if (count == 0) {
1212 DEBUG(10, ("NO SIDs found\n"));
1215 for (i = 0; i < count; i++) {
1216 char *sidstr = NULL;
1217 char *tmp = NULL;
1218 enum id_type type;
1219 struct id_map *map;
1220 DOM_SID sid;
1221 uint32_t id;
1223 if (i == 0) { /* first entry */
1224 entry = ldap_first_entry(ctx->smbldap_state->ldap_struct,
1225 result);
1226 } else { /* following ones */
1227 entry = ldap_next_entry(ctx->smbldap_state->ldap_struct,
1228 entry);
1230 if ( ! entry) {
1231 DEBUG(2, ("ERROR: Unable to fetch ldap entries "
1232 "from results\n"));
1233 break;
1236 /* first check if the SID is present */
1237 sidstr = smbldap_talloc_single_attribute(
1238 ctx->smbldap_state->ldap_struct,
1239 entry, LDAP_ATTRIBUTE_SID, memctx);
1240 if ( ! sidstr) { /* no sid ??, skip entry */
1241 DEBUG(2, ("WARNING SID not found on entry\n"));
1242 continue;
1245 if ( ! string_to_sid(&sid, sidstr)) {
1246 DEBUG(2, ("ERROR: Invalid SID on entry\n"));
1247 TALLOC_FREE(sidstr);
1248 continue;
1251 map = find_map_by_sid(&ids[bidx], &sid);
1252 if (!map) {
1253 DEBUG(2, ("WARNING: couldn't find entry sid (%s) "
1254 "in ids", sidstr));
1255 TALLOC_FREE(sidstr);
1256 continue;
1259 TALLOC_FREE(sidstr);
1261 /* now try to see if it is a uid, if not try with a gid
1262 * (gid is more common, but in case both uidNumber and
1263 * gidNumber are returned the SID is mapped to the uid
1264 * not the gid) */
1265 type = ID_TYPE_UID;
1266 tmp = smbldap_talloc_single_attribute(
1267 ctx->smbldap_state->ldap_struct,
1268 entry, uidNumber, memctx);
1269 if ( ! tmp) {
1270 type = ID_TYPE_GID;
1271 tmp = smbldap_talloc_single_attribute(
1272 ctx->smbldap_state->ldap_struct,
1273 entry, gidNumber, memctx);
1275 if ( ! tmp) { /* no ids ?? */
1276 DEBUG(5, ("no uidNumber, "
1277 "nor gidNumber attributes found\n"));
1278 continue;
1281 id = strtoul(tmp, NULL, 10);
1282 if ((id == 0) ||
1283 (ctx->filter_low_id && (id < ctx->filter_low_id)) ||
1284 (ctx->filter_high_id && (id > ctx->filter_high_id))) {
1285 DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
1286 "Filtered!\n", id,
1287 ctx->filter_low_id, ctx->filter_high_id));
1288 TALLOC_FREE(tmp);
1289 continue;
1291 TALLOC_FREE(tmp);
1293 /* mapped */
1294 map->xid.type = type;
1295 map->xid.id = id;
1296 map->status = ID_MAPPED;
1298 DEBUG(10, ("Mapped %s -> %lu (%d)\n",
1299 sid_string_static(map->sid),
1300 (unsigned long)map->xid.id, map->xid.type));
1303 /* free the ldap results */
1304 if (result) {
1305 ldap_msgfree(result);
1306 result = NULL;
1309 if (multi && ids[idx]) { /* still some values to map */
1310 goto again;
1313 ret = NT_STATUS_OK;
1315 /* mark all unknwon/expired ones as unmapped */
1316 for (i = 0; ids[i]; i++) {
1317 if (ids[i]->status != ID_MAPPED)
1318 ids[i]->status = ID_UNMAPPED;
1321 done:
1322 talloc_free(memctx);
1323 return ret;
1326 /**********************************
1327 set a mapping.
1328 **********************************/
1330 /* TODO: change this: This function cannot be called to modify a mapping,
1331 * only set a new one */
1333 static NTSTATUS idmap_ldap_set_mapping(struct idmap_domain *dom,
1334 const struct id_map *map)
1336 NTSTATUS ret;
1337 TALLOC_CTX *memctx;
1338 struct idmap_ldap_context *ctx;
1339 LDAPMessage *entry = NULL;
1340 LDAPMod **mods = NULL;
1341 const char *type;
1342 char *id_str;
1343 char *sid;
1344 char *dn;
1345 int rc = -1;
1347 /* Only do query if we are online */
1348 if (idmap_is_offline()) {
1349 return NT_STATUS_FILE_IS_OFFLINE;
1352 /* Initilization my have been deferred because we were offline */
1353 if ( ! dom->initialized) {
1354 ret = idmap_ldap_db_init(dom);
1355 if ( ! NT_STATUS_IS_OK(ret)) {
1356 return ret;
1360 ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
1362 switch(map->xid.type) {
1363 case ID_TYPE_UID:
1364 type = get_attr_key2string(sidmap_attr_list,
1365 LDAP_ATTR_UIDNUMBER);
1366 break;
1368 case ID_TYPE_GID:
1369 type = get_attr_key2string(sidmap_attr_list,
1370 LDAP_ATTR_GIDNUMBER);
1371 break;
1373 default:
1374 return NT_STATUS_INVALID_PARAMETER;
1377 memctx = talloc_new(ctx);
1378 if ( ! memctx) {
1379 DEBUG(0, ("Out of memory!\n"));
1380 return NT_STATUS_NO_MEMORY;
1383 id_str = talloc_asprintf(memctx, "%lu", (unsigned long)map->xid.id);
1384 CHECK_ALLOC_DONE(id_str);
1386 sid = talloc_strdup(memctx, sid_string_static(map->sid));
1387 CHECK_ALLOC_DONE(sid);
1389 dn = talloc_asprintf(memctx, "%s=%s,%s",
1390 get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
1391 sid,
1392 ctx->suffix);
1393 CHECK_ALLOC_DONE(dn);
1395 smbldap_set_mod(&mods, LDAP_MOD_ADD,
1396 "objectClass", LDAP_OBJ_IDMAP_ENTRY);
1398 smbldap_make_mod(ctx->smbldap_state->ldap_struct,
1399 entry, &mods, type, id_str);
1401 smbldap_make_mod(ctx->smbldap_state->ldap_struct, entry, &mods,
1402 get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
1403 sid);
1405 if ( ! mods) {
1406 DEBUG(2, ("ERROR: No mods?\n"));
1407 ret = NT_STATUS_UNSUCCESSFUL;
1408 goto done;
1411 /* TODO: remove conflicting mappings! */
1413 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SID_ENTRY);
1415 DEBUG(10, ("Set DN %s (%s -> %s)\n", dn, sid, id_str));
1417 rc = smbldap_add(ctx->smbldap_state, dn, mods);
1418 ldap_mods_free(mods, True);
1420 if (rc != LDAP_SUCCESS) {
1421 char *ld_error = NULL;
1422 ldap_get_option(ctx->smbldap_state->ldap_struct,
1423 LDAP_OPT_ERROR_STRING, &ld_error);
1424 DEBUG(0,("ldap_set_mapping_internals: Failed to add %s to %lu "
1425 "mapping [%s]\n", sid,
1426 (unsigned long)map->xid.id, type));
1427 DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n",
1428 ld_error ? ld_error : "(NULL)", ldap_err2string (rc)));
1429 if (ld_error) {
1430 ldap_memfree(ld_error);
1432 ret = NT_STATUS_UNSUCCESSFUL;
1433 goto done;
1436 DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to "
1437 "%lu [%s]\n", sid, (unsigned long)map->xid.id, type));
1439 ret = NT_STATUS_OK;
1441 done:
1442 talloc_free(memctx);
1443 return ret;
1446 /**********************************
1447 Close the idmap ldap instance
1448 **********************************/
1450 static NTSTATUS idmap_ldap_close(struct idmap_domain *dom)
1452 struct idmap_ldap_context *ctx;
1454 if (dom->private_data) {
1455 ctx = talloc_get_type(dom->private_data,
1456 struct idmap_ldap_context);
1458 talloc_free(ctx);
1459 dom->private_data = NULL;
1462 return NT_STATUS_OK;
1465 static struct idmap_methods idmap_ldap_methods = {
1467 .init = idmap_ldap_db_init,
1468 .unixids_to_sids = idmap_ldap_unixids_to_sids,
1469 .sids_to_unixids = idmap_ldap_sids_to_unixids,
1470 .set_mapping = idmap_ldap_set_mapping,
1471 .close_fn = idmap_ldap_close
1474 static struct idmap_alloc_methods idmap_ldap_alloc_methods = {
1476 .init = idmap_ldap_alloc_init,
1477 .allocate_id = idmap_ldap_allocate_id,
1478 .get_id_hwm = idmap_ldap_get_hwm,
1479 .set_id_hwm = idmap_ldap_set_hwm,
1480 .close_fn = idmap_ldap_alloc_close,
1481 /* .dump_data = TODO */
1484 NTSTATUS idmap_alloc_ldap_init(void)
1486 return smb_register_idmap_alloc(SMB_IDMAP_INTERFACE_VERSION, "ldap",
1487 &idmap_ldap_alloc_methods);
1490 NTSTATUS idmap_ldap_init(void)
1492 NTSTATUS ret;
1494 /* FIXME: bad hack to actually register also the alloc_ldap module
1495 * without changining configure.in */
1496 ret = idmap_alloc_ldap_init();
1497 if (! NT_STATUS_IS_OK(ret)) {
1498 return ret;
1500 return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "ldap",
1501 &idmap_ldap_methods);