2 Unix SMB/CIFS implementation.
6 Copyright (C) Tim Potter 2000
7 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
8 Copyright (C) Simo Sorce 2003
9 Copyright (C) Gerald Carter 2003
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.
29 #define DBGC_CLASS DBGC_IDMAP
37 struct ldap_idmap_state
{
38 struct smbldap_state
*smbldap_state
;
42 static struct ldap_idmap_state ldap_state
;
44 /* number tries while allocating new id */
45 #define LDAP_MAX_ALLOC_ID 128
48 /***********************************************************************
49 This function cannot be called to modify a mapping, only set a new one
50 ***********************************************************************/
52 static NTSTATUS
ldap_set_mapping(const DOM_SID
*sid
, unid_t id
, int id_type
)
57 LDAPMod
**mods
= NULL
;
61 LDAPMessage
*entry
= NULL
;
63 sid_to_string( sid_string
, sid
);
65 ldap_op
= LDAP_MOD_ADD
;
66 pstr_sprintf(dn
, "%s=%s,%s", get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_SID
),
67 sid_string
, lp_ldap_idmap_suffix());
69 if ( id_type
& ID_USERID
)
70 fstrcpy( type
, get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_UIDNUMBER
) );
72 fstrcpy( type
, get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_GIDNUMBER
) );
74 pstr_sprintf(id_str
, "%lu", ((id_type
& ID_USERID
) ? (unsigned long)id
.uid
:
75 (unsigned long)id
.gid
));
77 smbldap_set_mod( &mods
, LDAP_MOD_ADD
, "objectClass", LDAP_OBJ_IDMAP_ENTRY
);
79 smbldap_make_mod( ldap_state
.smbldap_state
->ldap_struct
,
80 entry
, &mods
, type
, id_str
);
82 smbldap_make_mod( ldap_state
.smbldap_state
->ldap_struct
,
84 get_attr_key2string(sidmap_attr_list
, LDAP_ATTR_SID
),
87 /* There may well be nothing at all to do */
90 smbldap_set_mod( &mods
, LDAP_MOD_ADD
, "objectClass", LDAP_OBJ_SID_ENTRY
);
91 rc
= smbldap_add(ldap_state
.smbldap_state
, dn
, mods
);
92 ldap_mods_free( mods
, True
);
97 if (rc
!= LDAP_SUCCESS
) {
98 char *ld_error
= NULL
;
99 ldap_get_option(ldap_state
.smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
101 DEBUG(0,("ldap_set_mapping_internals: Failed to %s mapping from %s to %lu [%s]\n",
102 (ldap_op
== LDAP_MOD_ADD
) ? "add" : "replace",
103 sid_string
, (unsigned long)((id_type
& ID_USERID
) ? id
.uid
: id
.gid
), type
));
104 DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n",
105 ld_error
? ld_error
: "(NULL)", ldap_err2string (rc
)));
106 return NT_STATUS_UNSUCCESSFUL
;
109 DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to %lu [%s]\n",
110 sid_string
, ((id_type
& ID_USERID
) ? (unsigned long)id
.uid
:
111 (unsigned long)id
.gid
), type
));
116 /**********************************************************************
117 Even if the sambaDomain attribute in LDAP tells us that this RID is
118 safe to use, always check before use.
119 *********************************************************************/
121 static BOOL
sid_in_use(struct ldap_idmap_state
*state
,
122 const DOM_SID
*sid
, int *error
)
126 LDAPMessage
*result
= NULL
;
129 char *sid_attr
[] = {LDAP_ATTRIBUTE_SID
, NULL
};
131 slprintf(filter
, sizeof(filter
)-1, "(%s=%s)", LDAP_ATTRIBUTE_SID
, sid_to_string(sid_string
, sid
));
133 rc
= smbldap_search_suffix(state
->smbldap_state
,
134 filter
, sid_attr
, &result
);
136 if (rc
!= LDAP_SUCCESS
) {
137 char *ld_error
= NULL
;
138 ldap_get_option(state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
, &ld_error
);
139 DEBUG(2, ("Failed to check if sid %s is alredy in use: %s\n",
140 sid_string
, ld_error
));
147 if ((count
= ldap_count_entries(state
->smbldap_state
->ldap_struct
, result
)) > 0) {
148 DEBUG(3, ("Sid %s already in use - trying next RID\n",
150 ldap_msgfree(result
);
154 ldap_msgfree(result
);
156 /* good, sid is not in use */
160 /**********************************************************************
161 Set the new nextRid attribute, and return one we can use.
163 This also checks that this RID is actually free - in case the admin
164 manually stole it :-).
165 *********************************************************************/
167 static NTSTATUS
ldap_next_rid(struct ldap_idmap_state
*state
, uint32
*rid
,
170 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
172 LDAPMessage
*domain_result
= NULL
;
173 LDAPMessage
*entry
= NULL
;
175 LDAPMod
**mods
= NULL
;
176 fstring old_rid_string
;
177 fstring next_rid_string
;
178 fstring algorithmic_rid_base_string
;
182 char *ld_error
= NULL
;
184 while (attempts
< 10) {
185 if (!NT_STATUS_IS_OK(ret
= smbldap_search_domain_info(state
->smbldap_state
,
186 &domain_result
, get_global_sam_name(), True
))) {
190 entry
= ldap_first_entry(state
->smbldap_state
->ldap_struct
, domain_result
);
192 DEBUG(0, ("Could not get domain info entry\n"));
193 ldap_msgfree(domain_result
);
197 if ((dn
= smbldap_get_dn(state
->smbldap_state
->ldap_struct
, entry
)) == NULL
) {
198 DEBUG(0, ("Could not get domain info DN\n"));
199 ldap_msgfree(domain_result
);
203 /* yes, we keep 3 seperate counters, one for rids between 1000 (BASE_RID) and
204 algorithmic_rid_base. The other two are to avoid stomping on the
205 different sets of algorithmic RIDs */
207 if (smbldap_get_single_attribute(state
->smbldap_state
->ldap_struct
, entry
,
208 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_ALGORITHMIC_RID_BASE
),
209 algorithmic_rid_base_string
)) {
211 alg_rid_base
= (uint32
)atol(algorithmic_rid_base_string
);
213 alg_rid_base
= algorithmic_rid_base();
214 /* Try to make the modification atomically by enforcing the
215 old value in the delete mod. */
216 slprintf(algorithmic_rid_base_string
, sizeof(algorithmic_rid_base_string
)-1, "%d", alg_rid_base
);
217 smbldap_make_mod(state
->smbldap_state
->ldap_struct
, entry
, &mods
,
218 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_ALGORITHMIC_RID_BASE
),
219 algorithmic_rid_base_string
);
224 if (alg_rid_base
> BASE_RID
) {
225 /* we have a non-default 'algorithmic rid base', so we have 'low' rids that we
226 can allocate to new users */
227 if (smbldap_get_single_attribute(state
->smbldap_state
->ldap_struct
, entry
,
228 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_RID
),
230 *rid
= (uint32
)atol(old_rid_string
);
236 if (next_rid
>= alg_rid_base
) {
237 ldap_msgfree(domain_result
);
238 return NT_STATUS_UNSUCCESSFUL
;
241 slprintf(next_rid_string
, sizeof(next_rid_string
)-1, "%d", next_rid
);
243 /* Try to make the modification atomically by enforcing the
244 old value in the delete mod. */
245 smbldap_make_mod(state
->smbldap_state
->ldap_struct
, entry
, &mods
,
246 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_RID
),
250 if (!next_rid
) { /* not got one already */
253 if (smbldap_get_single_attribute(state
->smbldap_state
->ldap_struct
, entry
,
254 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_USERRID
),
256 *rid
= (uint32
)atol(old_rid_string
);
260 if (smbldap_get_single_attribute(state
->smbldap_state
->ldap_struct
, entry
,
261 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_GROUPRID
),
263 *rid
= (uint32
)atol(old_rid_string
);
268 /* This is the core of the whole routine. If we had
269 scheme-style closures, there would be a *lot* less code
272 next_rid
= *rid
+RID_MULTIPLIER
;
273 slprintf(next_rid_string
, sizeof(next_rid_string
)-1, "%d", next_rid
);
277 /* Try to make the modification atomically by enforcing the
278 old value in the delete mod. */
279 smbldap_make_mod(state
->smbldap_state
->ldap_struct
, entry
, &mods
,
280 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_USERRID
),
285 /* Try to make the modification atomically by enforcing the
286 old value in the delete mod. */
287 smbldap_make_mod(state
->smbldap_state
->ldap_struct
, entry
, &mods
,
288 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_GROUPRID
),
294 if ((rc
= smbldap_modify(state
->smbldap_state
, dn
, mods
)) == LDAP_SUCCESS
) {
297 pstring domain_sid_string
;
300 if (!smbldap_get_single_attribute(state
->smbldap_state
->ldap_struct
, domain_result
,
301 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_DOM_SID
),
302 domain_sid_string
)) {
303 ldap_mods_free(mods
, True
);
305 ldap_msgfree(domain_result
);
309 if (!string_to_sid(&dom_sid
, domain_sid_string
)) {
310 ldap_mods_free(mods
, True
);
312 ldap_msgfree(domain_result
);
316 ldap_mods_free(mods
, True
);
319 ldap_msgfree(domain_result
);
321 sid_copy(&sid
, &dom_sid
);
322 sid_append_rid(&sid
, *rid
);
324 /* check RID is not in use */
325 if (sid_in_use(state
, &sid
, &error
)) {
336 ldap_get_option(state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
, &ld_error
);
337 DEBUG(2, ("Failed to modify rid: %s\n", ld_error
? ld_error
: "(NULL"));
340 ldap_mods_free(mods
, True
);
345 ldap_msgfree(domain_result
);
346 domain_result
= NULL
;
349 /* Sleep for a random timeout */
350 unsigned sleeptime
= (sys_random()*sys_getpid()*attempts
);
358 DEBUG(0, ("Failed to set new RID\n"));
363 /*****************************************************************************
365 *****************************************************************************/
367 static NTSTATUS
ldap_allocate_rid(uint32
*rid
, int rid_type
)
369 return ldap_next_rid( &ldap_state
, rid
, rid_type
);
372 /*****************************************************************************
373 Allocate a new uid or gid
374 *****************************************************************************/
376 static NTSTATUS
ldap_allocate_id(unid_t
*id
, int id_type
)
378 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
379 int rc
= LDAP_SERVER_DOWN
;
381 LDAPMessage
*result
= NULL
;
382 LDAPMessage
*entry
= NULL
;
383 pstring id_str
, new_id_str
;
384 LDAPMod
**mods
= NULL
;
393 type
= (id_type
& ID_USERID
) ?
394 get_attr_key2string( idpool_attr_list
, LDAP_ATTR_UIDNUMBER
) :
395 get_attr_key2string( idpool_attr_list
, LDAP_ATTR_GIDNUMBER
);
397 pstr_sprintf(filter
, "(objectClass=%s)", LDAP_OBJ_IDPOOL
);
399 attr_list
= get_attr_list( idpool_attr_list
);
401 rc
= smbldap_search(ldap_state
.smbldap_state
, lp_ldap_idmap_suffix(),
402 LDAP_SCOPE_SUBTREE
, filter
,
403 attr_list
, 0, &result
);
404 free_attr_list( attr_list
);
406 if (rc
!= LDAP_SUCCESS
) {
407 DEBUG(0,("ldap_allocate_id: %s object not found\n", LDAP_OBJ_IDPOOL
));
411 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
413 DEBUG(0,("ldap_allocate_id: single %s object not found\n", LDAP_OBJ_IDPOOL
));
417 dn
= smbldap_get_dn(ldap_state
.smbldap_state
->ldap_struct
, result
);
421 entry
= ldap_first_entry(ldap_state
.smbldap_state
->ldap_struct
, result
);
423 if (!smbldap_get_single_attribute(ldap_state
.smbldap_state
->ldap_struct
, entry
, type
, id_str
)) {
424 DEBUG(0,("ldap_allocate_id: %s attribute not found\n",
429 /* this must succeed or else we wouldn't have initialized */
431 lp_idmap_uid( &luid
, &huid
);
432 lp_idmap_gid( &lgid
, &hgid
);
434 /* make sure we still have room to grow */
436 if (id_type
& ID_USERID
) {
437 id
->uid
= strtoul(id_str
, NULL
, 10);
438 if (id
->uid
> huid
) {
439 DEBUG(0,("ldap_allocate_id: Cannot allocate uid above %lu!\n",
440 (unsigned long)huid
));
445 id
->gid
= strtoul(id_str
, NULL
, 10);
446 if (id
->gid
> hgid
) {
447 DEBUG(0,("ldap_allocate_id: Cannot allocate gid above %lu!\n",
448 (unsigned long)hgid
));
453 pstr_sprintf(new_id_str
, "%lu",
454 ((id_type
& ID_USERID
) ? (unsigned long)id
->uid
:
455 (unsigned long)id
->gid
) + 1);
457 smbldap_set_mod( &mods
, LDAP_MOD_DELETE
, type
, id_str
);
458 smbldap_set_mod( &mods
, LDAP_MOD_ADD
, type
, new_id_str
);
461 DEBUG(0,("ldap_allocate_id: smbldap_set_mod() failed.\n"));
465 rc
= smbldap_modify(ldap_state
.smbldap_state
, dn
, mods
);
467 ldap_mods_free( mods
, True
);
468 if (rc
!= LDAP_SUCCESS
) {
469 DEBUG(0,("ldap_allocate_id: Failed to allocate new %s. ldap_modify() failed.\n",
478 ldap_msgfree(result
);
483 /*****************************************************************************
485 *****************************************************************************/
487 static NTSTATUS
ldap_get_sid_from_id(DOM_SID
*sid
, unid_t id
, int id_type
)
489 LDAPMessage
*result
= NULL
;
490 LDAPMessage
*entry
= NULL
;
497 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
500 if ( id_type
& ID_USERID
)
501 type
= get_attr_key2string( idpool_attr_list
, LDAP_ATTR_UIDNUMBER
);
503 type
= get_attr_key2string( idpool_attr_list
, LDAP_ATTR_GIDNUMBER
);
505 pstrcpy( suffix
, lp_ldap_idmap_suffix() );
506 pstr_sprintf(filter
, "(&(objectClass=%s)(%s=%lu))",
507 LDAP_OBJ_IDMAP_ENTRY
, type
,
508 ((id_type
& ID_USERID
) ? (unsigned long)id
.uid
: (unsigned long)id
.gid
));
511 DEBUG(5,("ldap_get_sid_from_id: Searching \"%s\"\n", filter
));
513 attr_list
= get_attr_list( sidmap_attr_list
);
514 rc
= smbldap_search(ldap_state
.smbldap_state
, suffix
, LDAP_SCOPE_SUBTREE
,
515 filter
, attr_list
, 0, &result
);
517 if (rc
!= LDAP_SUCCESS
) {
518 DEBUG(3,("ldap_get_isd_from_id: Failure looking up entry (%s)\n",
519 ldap_err2string(rc
) ));
523 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
526 DEBUG(0,("ldap_get_sid_from_id: mapping not found for %s: %lu\n",
527 type
, ((id_type
& ID_USERID
) ? (unsigned long)id
.uid
:
528 (unsigned long)id
.gid
)));
532 entry
= ldap_first_entry(ldap_state
.smbldap_state
->ldap_struct
, result
);
534 if ( !smbldap_get_single_attribute(ldap_state
.smbldap_state
->ldap_struct
, entry
, LDAP_ATTRIBUTE_SID
, sid_str
) )
537 if (!string_to_sid(sid
, sid_str
))
542 free_attr_list( attr_list
);
545 ldap_msgfree(result
);
550 /***********************************************************************
552 ***********************************************************************/
554 static NTSTATUS
ldap_get_id_from_sid(unid_t
*id
, int *id_type
, const DOM_SID
*sid
)
556 LDAPMessage
*result
= NULL
;
557 LDAPMessage
*entry
= NULL
;
567 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
569 sid_to_string(sid_str
, sid
);
571 DEBUG(8,("ldap_get_id_from_sid: %s (%s)\n", sid_str
,
572 (*id_type
& ID_GROUPID
? "group" : "user") ));
574 suffix
= lp_ldap_idmap_suffix();
575 pstr_sprintf(filter
, "(&(objectClass=%s)(%s=%s))",
576 LDAP_OBJ_IDMAP_ENTRY
, LDAP_ATTRIBUTE_SID
, sid_str
);
578 if ( *id_type
& ID_GROUPID
)
579 type
= get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_GIDNUMBER
);
581 type
= get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_UIDNUMBER
);
583 DEBUG(10,("ldap_get_id_from_sid: Searching for \"%s\"\n", filter
));
585 /* do the search and check for errors */
587 attr_list
= get_attr_list( sidmap_attr_list
);
588 rc
= smbldap_search(ldap_state
.smbldap_state
, suffix
, LDAP_SCOPE_SUBTREE
,
589 filter
, attr_list
, 0, &result
);
591 if (rc
!= LDAP_SUCCESS
) {
592 DEBUG(3,("ldap_get_id_from_sid: Failure looking up idmap entry (%s)\n",
593 ldap_err2string(rc
) ));
597 /* check for the number of entries returned */
599 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
602 DEBUG(0, ("ldap_get_id_from_sid: (2nd) search %s returned [%d] entries!\n",
607 /* try to allocate a new id if we still haven't found one */
612 if (*id_type
& ID_QUERY_ONLY
) {
613 DEBUG(5,("ldap_get_id_from_sid: No matching entry found and QUERY_ONLY flag set\n"));
617 DEBUG(8,("ldap_get_id_from_sid: Allocating new id\n"));
619 for (i
= 0; i
< LDAP_MAX_ALLOC_ID
; i
++) {
620 ret
= ldap_allocate_id(id
, *id_type
);
621 if ( NT_STATUS_IS_OK(ret
) )
625 if ( !NT_STATUS_IS_OK(ret
) ) {
626 DEBUG(0,("ldap_allocate_id: cannot acquire id lock!\n"));
630 DEBUG(10,("ldap_get_id_from_sid: Allocated new %cid [%ul]\n",
631 (*id_type
& ID_GROUPID
? 'g' : 'u'), (uint32
)id
->uid
));
633 ret
= ldap_set_mapping(sid
, *id
, *id_type
);
640 DEBUG(10,("ldap_get_id_from_sid: success\n"));
642 entry
= ldap_first_entry(ldap_state
.smbldap_state
->ldap_struct
, result
);
644 dn
= smbldap_get_dn(ldap_state
.smbldap_state
->ldap_struct
, result
);
648 DEBUG(10, ("Found mapping entry at dn=%s, looking for %s\n", dn
, type
));
650 if ( smbldap_get_single_attribute(ldap_state
.smbldap_state
->ldap_struct
, entry
, type
, id_str
) ) {
651 if ( (*id_type
& ID_USERID
) )
652 id
->uid
= strtoul(id_str
, NULL
, 10);
654 id
->gid
= strtoul(id_str
, NULL
, 10);
661 free_attr_list( attr_list
);
663 ldap_msgfree(result
);
669 /**********************************************************************
670 Verify the sambaUnixIdPool entry in the directiry.
671 **********************************************************************/
673 static NTSTATUS
verify_idpool( void )
678 LDAPMessage
*result
= NULL
;
679 LDAPMod
**mods
= NULL
;
682 fstr_sprintf( filter
, "(objectclass=%s)", LDAP_OBJ_IDPOOL
);
684 attr_list
= get_attr_list( idpool_attr_list
);
685 rc
= smbldap_search(ldap_state
.smbldap_state
, lp_ldap_idmap_suffix(),
686 LDAP_SCOPE_SUBTREE
, filter
, attr_list
, 0, &result
);
687 free_attr_list ( attr_list
);
689 if (rc
!= LDAP_SUCCESS
)
690 return NT_STATUS_UNSUCCESSFUL
;
692 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
694 ldap_msgfree(result
);
697 DEBUG(0,("ldap_idmap_init: multiple entries returned from %s (base == %s)\n",
698 filter
, lp_ldap_idmap_suffix() ));
699 return NT_STATUS_UNSUCCESSFUL
;
701 else if (count
== 0) {
704 fstring uid_str
, gid_str
;
706 if ( !lp_idmap_uid(&luid
, &huid
) || !lp_idmap_gid( &lgid
, &hgid
) ) {
707 DEBUG(0,("ldap_idmap_init: idmap uid/gid parameters not specified\n"));
708 return NT_STATUS_UNSUCCESSFUL
;
711 fstr_sprintf( uid_str
, "%lu", (unsigned long)luid
);
712 fstr_sprintf( gid_str
, "%lu", (unsigned long)lgid
);
714 smbldap_set_mod( &mods
, LDAP_MOD_ADD
, "objectClass", LDAP_OBJ_IDPOOL
);
715 smbldap_set_mod( &mods
, LDAP_MOD_ADD
,
716 get_attr_key2string(idpool_attr_list
, LDAP_ATTR_UIDNUMBER
), uid_str
);
717 smbldap_set_mod( &mods
, LDAP_MOD_ADD
,
718 get_attr_key2string(idpool_attr_list
, LDAP_ATTR_GIDNUMBER
), gid_str
);
720 rc
= smbldap_modify(ldap_state
.smbldap_state
, lp_ldap_idmap_suffix(), mods
);
723 return ( rc
==LDAP_SUCCESS
? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
);
726 /*****************************************************************************
727 Initialise idmap database.
728 *****************************************************************************/
730 static NTSTATUS
ldap_idmap_init( char *params
)
734 ldap_state
.mem_ctx
= talloc_init("idmap_ldap");
735 if (!ldap_state
.mem_ctx
) {
736 return NT_STATUS_NO_MEMORY
;
739 /* assume location is the only parameter */
740 if (!NT_STATUS_IS_OK(nt_status
=
741 smbldap_init(ldap_state
.mem_ctx
, params
,
742 &ldap_state
.smbldap_state
))) {
743 talloc_destroy(ldap_state
.mem_ctx
);
747 /* see if the idmap suffix and sub entries exists */
749 nt_status
= verify_idpool();
750 if ( !NT_STATUS_IS_OK(nt_status
) )
756 /*****************************************************************************
758 *****************************************************************************/
760 static NTSTATUS
ldap_idmap_close(void)
763 smbldap_free_struct(&(ldap_state
).smbldap_state
);
764 talloc_destroy(ldap_state
.mem_ctx
);
766 DEBUG(5,("The connection to the LDAP server was closed\n"));
767 /* maybe free the results here --metze */
773 /* This function doesn't make as much sense in an LDAP world since the calling
774 node doesn't really control the ID ranges */
775 static void ldap_idmap_status(void)
777 DEBUG(0, ("LDAP IDMAP Status not available\n"));
780 static struct idmap_methods ldap_methods
= {
784 ldap_get_sid_from_id
,
785 ldap_get_id_from_sid
,
792 NTSTATUS
idmap_ldap_init(void)
794 return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION
, "ldap", &ldap_methods
);