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_pstring(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_pstring(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_pstring(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_pstring(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_pstring(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
);
354 smb_msleep(sleeptime
);
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_pstring(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
));
510 attr_list
= get_attr_list( sidmap_attr_list
);
511 rc
= smbldap_search(ldap_state
.smbldap_state
, suffix
, LDAP_SCOPE_SUBTREE
,
512 filter
, attr_list
, 0, &result
);
514 if (rc
!= LDAP_SUCCESS
) {
515 DEBUG(3,("ldap_get_isd_from_id: Failure looking up entry (%s)\n",
516 ldap_err2string(rc
) ));
520 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
523 DEBUG(0,("ldap_get_sid_from_id: mapping not found for %s: %lu\n",
524 type
, ((id_type
& ID_USERID
) ? (unsigned long)id
.uid
:
525 (unsigned long)id
.gid
)));
529 entry
= ldap_first_entry(ldap_state
.smbldap_state
->ldap_struct
, result
);
531 if ( !smbldap_get_single_pstring(ldap_state
.smbldap_state
->ldap_struct
, entry
, LDAP_ATTRIBUTE_SID
, sid_str
) )
534 if (!string_to_sid(sid
, sid_str
))
539 free_attr_list( attr_list
);
542 ldap_msgfree(result
);
547 /***********************************************************************
549 ***********************************************************************/
551 static NTSTATUS
ldap_get_id_from_sid(unid_t
*id
, int *id_type
, const DOM_SID
*sid
)
553 LDAPMessage
*result
= NULL
;
554 LDAPMessage
*entry
= NULL
;
564 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
566 sid_to_string(sid_str
, sid
);
568 DEBUG(8,("ldap_get_id_from_sid: %s (%s)\n", sid_str
,
569 (*id_type
& ID_GROUPID
? "group" : "user") ));
571 suffix
= lp_ldap_idmap_suffix();
572 pstr_sprintf(filter
, "(&(objectClass=%s)(%s=%s))",
573 LDAP_OBJ_IDMAP_ENTRY
, LDAP_ATTRIBUTE_SID
, sid_str
);
575 if ( *id_type
& ID_GROUPID
)
576 type
= get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_GIDNUMBER
);
578 type
= get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_UIDNUMBER
);
580 /* do the search and check for errors */
582 attr_list
= get_attr_list( sidmap_attr_list
);
583 rc
= smbldap_search(ldap_state
.smbldap_state
, suffix
, LDAP_SCOPE_SUBTREE
,
584 filter
, attr_list
, 0, &result
);
586 if (rc
!= LDAP_SUCCESS
) {
587 DEBUG(3,("ldap_get_id_from_sid: Failure looking up idmap entry (%s)\n",
588 ldap_err2string(rc
) ));
592 /* check for the number of entries returned */
594 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
597 DEBUG(0, ("ldap_get_id_from_sid: (2nd) search %s returned [%d] entries!\n",
602 /* try to allocate a new id if we still haven't found one */
607 if (*id_type
& ID_QUERY_ONLY
) {
608 DEBUG(5,("ldap_get_id_from_sid: No matching entry found and QUERY_ONLY flag set\n"));
612 DEBUG(8,("ldap_get_id_from_sid: Allocating new id\n"));
614 for (i
= 0; i
< LDAP_MAX_ALLOC_ID
; i
++) {
615 ret
= ldap_allocate_id(id
, *id_type
);
616 if ( NT_STATUS_IS_OK(ret
) )
620 if ( !NT_STATUS_IS_OK(ret
) ) {
621 DEBUG(0,("ldap_allocate_id: cannot acquire id lock!\n"));
625 DEBUG(10,("ldap_get_id_from_sid: Allocated new %cid [%ul]\n",
626 (*id_type
& ID_GROUPID
? 'g' : 'u'), (uint32
)id
->uid
));
628 ret
= ldap_set_mapping(sid
, *id
, *id_type
);
635 DEBUG(10,("ldap_get_id_from_sid: success\n"));
637 entry
= ldap_first_entry(ldap_state
.smbldap_state
->ldap_struct
, result
);
639 dn
= smbldap_get_dn(ldap_state
.smbldap_state
->ldap_struct
, result
);
643 DEBUG(10, ("Found mapping entry at dn=%s, looking for %s\n", dn
, type
));
645 if ( smbldap_get_single_pstring(ldap_state
.smbldap_state
->ldap_struct
, entry
, type
, id_str
) ) {
646 if ( (*id_type
& ID_USERID
) )
647 id
->uid
= strtoul(id_str
, NULL
, 10);
649 id
->gid
= strtoul(id_str
, NULL
, 10);
656 free_attr_list( attr_list
);
658 ldap_msgfree(result
);
664 /**********************************************************************
665 Verify the sambaUnixIdPool entry in the directiry.
666 **********************************************************************/
668 static NTSTATUS
verify_idpool( void )
673 LDAPMessage
*result
= NULL
;
674 LDAPMod
**mods
= NULL
;
677 fstr_sprintf( filter
, "(objectclass=%s)", LDAP_OBJ_IDPOOL
);
679 attr_list
= get_attr_list( idpool_attr_list
);
680 rc
= smbldap_search(ldap_state
.smbldap_state
, lp_ldap_idmap_suffix(),
681 LDAP_SCOPE_SUBTREE
, filter
, attr_list
, 0, &result
);
682 free_attr_list ( attr_list
);
684 if (rc
!= LDAP_SUCCESS
)
685 return NT_STATUS_UNSUCCESSFUL
;
687 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
689 ldap_msgfree(result
);
692 DEBUG(0,("ldap_idmap_init: multiple entries returned from %s (base == %s)\n",
693 filter
, lp_ldap_idmap_suffix() ));
694 return NT_STATUS_UNSUCCESSFUL
;
696 else if (count
== 0) {
699 fstring uid_str
, gid_str
;
701 if ( !lp_idmap_uid(&luid
, &huid
) || !lp_idmap_gid( &lgid
, &hgid
) ) {
702 DEBUG(0,("ldap_idmap_init: idmap uid/gid parameters not specified\n"));
703 return NT_STATUS_UNSUCCESSFUL
;
706 fstr_sprintf( uid_str
, "%lu", (unsigned long)luid
);
707 fstr_sprintf( gid_str
, "%lu", (unsigned long)lgid
);
709 smbldap_set_mod( &mods
, LDAP_MOD_ADD
, "objectClass", LDAP_OBJ_IDPOOL
);
710 smbldap_set_mod( &mods
, LDAP_MOD_ADD
,
711 get_attr_key2string(idpool_attr_list
, LDAP_ATTR_UIDNUMBER
), uid_str
);
712 smbldap_set_mod( &mods
, LDAP_MOD_ADD
,
713 get_attr_key2string(idpool_attr_list
, LDAP_ATTR_GIDNUMBER
), gid_str
);
715 rc
= smbldap_modify(ldap_state
.smbldap_state
, lp_ldap_idmap_suffix(), mods
);
716 ldap_mods_free( mods
, True
);
718 return NT_STATUS_UNSUCCESSFUL
;
722 return ( rc
==LDAP_SUCCESS
? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
);
725 /*****************************************************************************
726 Initialise idmap database.
727 *****************************************************************************/
729 static NTSTATUS
ldap_idmap_init( char *params
)
733 ldap_state
.mem_ctx
= talloc_init("idmap_ldap");
734 if (!ldap_state
.mem_ctx
) {
735 return NT_STATUS_NO_MEMORY
;
738 /* assume location is the only parameter */
739 if (!NT_STATUS_IS_OK(nt_status
=
740 smbldap_init(ldap_state
.mem_ctx
, params
,
741 &ldap_state
.smbldap_state
))) {
742 talloc_destroy(ldap_state
.mem_ctx
);
746 /* see if the idmap suffix and sub entries exists */
748 nt_status
= verify_idpool();
749 if ( !NT_STATUS_IS_OK(nt_status
) )
755 /*****************************************************************************
757 *****************************************************************************/
759 static NTSTATUS
ldap_idmap_close(void)
762 smbldap_free_struct(&(ldap_state
).smbldap_state
);
763 talloc_destroy(ldap_state
.mem_ctx
);
765 DEBUG(5,("The connection to the LDAP server was closed\n"));
766 /* maybe free the results here --metze */
772 /* This function doesn't make as much sense in an LDAP world since the calling
773 node doesn't really control the ID ranges */
774 static void ldap_idmap_status(void)
776 DEBUG(0, ("LDAP IDMAP Status not available\n"));
779 static struct idmap_methods ldap_methods
= {
783 ldap_get_sid_from_id
,
784 ldap_get_id_from_sid
,
791 NTSTATUS
idmap_ldap_init(void)
793 return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION
, "ldap", &ldap_methods
);