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 return NT_STATUS_UNSUCCESSFUL
;
240 slprintf(next_rid_string
, sizeof(next_rid_string
)-1, "%d", next_rid
);
242 /* Try to make the modification atomically by enforcing the
243 old value in the delete mod. */
244 smbldap_make_mod(state
->smbldap_state
->ldap_struct
, entry
, &mods
,
245 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_RID
),
249 if (!next_rid
) { /* not got one already */
252 if (smbldap_get_single_attribute(state
->smbldap_state
->ldap_struct
, entry
,
253 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_USERRID
),
255 *rid
= (uint32
)atol(old_rid_string
);
259 if (smbldap_get_single_attribute(state
->smbldap_state
->ldap_struct
, entry
,
260 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_GROUPRID
),
262 *rid
= (uint32
)atol(old_rid_string
);
267 /* This is the core of the whole routine. If we had
268 scheme-style closures, there would be a *lot* less code
271 next_rid
= *rid
+RID_MULTIPLIER
;
272 slprintf(next_rid_string
, sizeof(next_rid_string
)-1, "%d", next_rid
);
276 /* Try to make the modification atomically by enforcing the
277 old value in the delete mod. */
278 smbldap_make_mod(state
->smbldap_state
->ldap_struct
, entry
, &mods
,
279 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_USERRID
),
284 /* Try to make the modification atomically by enforcing the
285 old value in the delete mod. */
286 smbldap_make_mod(state
->smbldap_state
->ldap_struct
, entry
, &mods
,
287 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_GROUPRID
),
293 if ((rc
= smbldap_modify(state
->smbldap_state
, dn
, mods
)) == LDAP_SUCCESS
) {
296 pstring domain_sid_string
;
299 if (!smbldap_get_single_attribute(state
->smbldap_state
->ldap_struct
, domain_result
,
300 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_DOM_SID
),
301 domain_sid_string
)) {
302 ldap_mods_free(mods
, True
);
304 ldap_msgfree(domain_result
);
308 if (!string_to_sid(&dom_sid
, domain_sid_string
)) {
309 ldap_mods_free(mods
, True
);
311 ldap_msgfree(domain_result
);
315 ldap_mods_free(mods
, True
);
318 ldap_msgfree(domain_result
);
320 sid_copy(&sid
, &dom_sid
);
321 sid_append_rid(&sid
, *rid
);
323 /* check RID is not in use */
324 if (sid_in_use(state
, &sid
, &error
)) {
335 ldap_get_option(state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
, &ld_error
);
336 DEBUG(2, ("Failed to modify rid: %s\n", ld_error
? ld_error
: "(NULL"));
339 ldap_mods_free(mods
, True
);
344 ldap_msgfree(domain_result
);
345 domain_result
= NULL
;
348 /* Sleep for a random timeout */
349 unsigned sleeptime
= (sys_random()*sys_getpid()*attempts
);
357 DEBUG(0, ("Failed to set new RID\n"));
362 /*****************************************************************************
364 *****************************************************************************/
366 static NTSTATUS
ldap_allocate_rid(uint32
*rid
, int rid_type
)
368 return ldap_next_rid( &ldap_state
, rid
, rid_type
);
371 /*****************************************************************************
372 Allocate a new uid or gid
373 *****************************************************************************/
375 static NTSTATUS
ldap_allocate_id(unid_t
*id
, int id_type
)
377 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
378 int rc
= LDAP_SERVER_DOWN
;
380 LDAPMessage
*result
= NULL
;
381 LDAPMessage
*entry
= NULL
;
382 pstring id_str
, new_id_str
;
383 LDAPMod
**mods
= NULL
;
392 type
= (id_type
& ID_USERID
) ?
393 get_attr_key2string( idpool_attr_list
, LDAP_ATTR_UIDNUMBER
) :
394 get_attr_key2string( idpool_attr_list
, LDAP_ATTR_GIDNUMBER
);
396 pstr_sprintf(filter
, "(objectClass=%s)", LDAP_OBJ_IDPOOL
);
398 attr_list
= get_attr_list( idpool_attr_list
);
400 rc
= smbldap_search(ldap_state
.smbldap_state
, lp_ldap_idmap_suffix(),
401 LDAP_SCOPE_SUBTREE
, filter
,
402 attr_list
, 0, &result
);
403 free_attr_list( attr_list
);
405 if (rc
!= LDAP_SUCCESS
) {
406 DEBUG(0,("ldap_allocate_id: %s object not found\n", LDAP_OBJ_IDPOOL
));
410 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
412 DEBUG(0,("ldap_allocate_id: single %s object not found\n", LDAP_OBJ_IDPOOL
));
416 dn
= smbldap_get_dn(ldap_state
.smbldap_state
->ldap_struct
, result
);
420 entry
= ldap_first_entry(ldap_state
.smbldap_state
->ldap_struct
, result
);
422 if (!smbldap_get_single_attribute(ldap_state
.smbldap_state
->ldap_struct
, entry
, type
, id_str
)) {
423 DEBUG(0,("ldap_allocate_id: %s attribute not found\n",
428 /* this must succeed or else we wouldn't have initialized */
430 lp_idmap_uid( &luid
, &huid
);
431 lp_idmap_gid( &lgid
, &hgid
);
433 /* make sure we still have room to grow */
435 if (id_type
& ID_USERID
) {
436 id
->uid
= strtoul(id_str
, NULL
, 10);
437 if (id
->uid
> huid
) {
438 DEBUG(0,("ldap_allocate_id: Cannot allocate uid above %lu!\n",
439 (unsigned long)huid
));
444 id
->gid
= strtoul(id_str
, NULL
, 10);
445 if (id
->gid
> hgid
) {
446 DEBUG(0,("ldap_allocate_id: Cannot allocate gid above %lu!\n",
447 (unsigned long)hgid
));
452 pstr_sprintf(new_id_str
, "%lu",
453 ((id_type
& ID_USERID
) ? (unsigned long)id
->uid
:
454 (unsigned long)id
->gid
) + 1);
456 smbldap_set_mod( &mods
, LDAP_MOD_DELETE
, type
, id_str
);
457 smbldap_set_mod( &mods
, LDAP_MOD_ADD
, type
, new_id_str
);
459 rc
= smbldap_modify(ldap_state
.smbldap_state
, dn
, mods
);
462 ldap_mods_free( mods
, True
);
464 if (rc
!= LDAP_SUCCESS
) {
465 DEBUG(0,("ldap_allocate_id: Failed to allocate new %s. ldap_modify() failed.\n",
475 /*****************************************************************************
477 *****************************************************************************/
479 static NTSTATUS
ldap_get_sid_from_id(DOM_SID
*sid
, unid_t id
, int id_type
)
481 LDAPMessage
*result
= NULL
;
482 LDAPMessage
*entry
= NULL
;
489 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
492 if ( id_type
& ID_USERID
)
493 type
= get_attr_key2string( idpool_attr_list
, LDAP_ATTR_UIDNUMBER
);
495 type
= get_attr_key2string( idpool_attr_list
, LDAP_ATTR_GIDNUMBER
);
497 pstrcpy( suffix
, lp_ldap_idmap_suffix() );
498 pstr_sprintf(filter
, "(&(objectClass=%s)(%s=%lu))",
499 LDAP_OBJ_IDMAP_ENTRY
, type
,
500 ((id_type
& ID_USERID
) ? (unsigned long)id
.uid
: (unsigned long)id
.gid
));
503 DEBUG(5,("ldap_get_sid_from_id: Searching \"%s\"\n", filter
));
505 attr_list
= get_attr_list( sidmap_attr_list
);
506 rc
= smbldap_search(ldap_state
.smbldap_state
, suffix
, LDAP_SCOPE_SUBTREE
,
507 filter
, attr_list
, 0, &result
);
509 if (rc
!= LDAP_SUCCESS
) {
510 DEBUG(3,("ldap_get_isd_from_id: Failure looking up entry (%s)\n",
511 ldap_err2string(rc
) ));
515 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
518 DEBUG(0,("ldap_get_sid_from_id: mapping not found for %s: %lu\n",
519 type
, ((id_type
& ID_USERID
) ? (unsigned long)id
.uid
:
520 (unsigned long)id
.gid
)));
524 entry
= ldap_first_entry(ldap_state
.smbldap_state
->ldap_struct
, result
);
526 if ( !smbldap_get_single_attribute(ldap_state
.smbldap_state
->ldap_struct
, entry
, LDAP_ATTRIBUTE_SID
, sid_str
) )
529 if (!string_to_sid(sid
, sid_str
))
534 free_attr_list( attr_list
);
537 ldap_msgfree(result
);
542 /***********************************************************************
544 ***********************************************************************/
546 static NTSTATUS
ldap_get_id_from_sid(unid_t
*id
, int *id_type
, const DOM_SID
*sid
)
548 LDAPMessage
*result
= NULL
;
549 LDAPMessage
*entry
= NULL
;
559 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
561 sid_to_string(sid_str
, sid
);
563 DEBUG(8,("ldap_get_id_from_sid: %s (%s)\n", sid_str
,
564 (*id_type
& ID_GROUPID
? "group" : "user") ));
566 suffix
= lp_ldap_idmap_suffix();
567 pstr_sprintf(filter
, "(&(objectClass=%s)(%s=%s))",
568 LDAP_OBJ_IDMAP_ENTRY
, LDAP_ATTRIBUTE_SID
, sid_str
);
570 if ( *id_type
& ID_GROUPID
)
571 type
= get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_GIDNUMBER
);
573 type
= get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_UIDNUMBER
);
575 DEBUG(10,("ldap_get_id_from_sid: Searching for \"%s\"\n", filter
));
577 /* do the search and check for errors */
579 attr_list
= get_attr_list( sidmap_attr_list
);
580 rc
= smbldap_search(ldap_state
.smbldap_state
, suffix
, LDAP_SCOPE_SUBTREE
,
581 filter
, attr_list
, 0, &result
);
583 if (rc
!= LDAP_SUCCESS
) {
584 DEBUG(3,("ldap_get_id_from_sid: Failure looking up idmap entry (%s)\n",
585 ldap_err2string(rc
) ));
589 /* check for the number of entries returned */
591 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
594 DEBUG(0, ("ldap_get_id_from_sid: (2nd) search %s returned [%d] entries!\n",
599 /* try to allocate a new id if we still haven't found one */
604 if (*id_type
& ID_QUERY_ONLY
) {
605 DEBUG(5,("ldap_get_id_from_sid: No matching entry found and QUERY_ONLY flag set\n"));
609 DEBUG(8,("ldap_get_id_from_sid: Allocating new id\n"));
611 for (i
= 0; i
< LDAP_MAX_ALLOC_ID
; i
++) {
612 ret
= ldap_allocate_id(id
, *id_type
);
613 if ( NT_STATUS_IS_OK(ret
) )
617 if ( !NT_STATUS_IS_OK(ret
) ) {
618 DEBUG(0,("ldap_allocate_id: cannot acquire id lock!\n"));
622 DEBUG(10,("ldap_get_id_from_sid: Allocated new %cid [%ul]\n",
623 (*id_type
& ID_GROUPID
? 'g' : 'u'), (uint32
)id
->uid
));
625 ret
= ldap_set_mapping(sid
, *id
, *id_type
);
632 DEBUG(10,("ldap_get_id_from_sid: success\n"));
634 entry
= ldap_first_entry(ldap_state
.smbldap_state
->ldap_struct
, result
);
636 dn
= smbldap_get_dn(ldap_state
.smbldap_state
->ldap_struct
, result
);
640 DEBUG(10, ("Found mapping entry at dn=%s, looking for %s\n", dn
, type
));
642 if ( smbldap_get_single_attribute(ldap_state
.smbldap_state
->ldap_struct
, entry
, type
, id_str
) ) {
643 if ( (*id_type
& ID_USERID
) )
644 id
->uid
= strtoul(id_str
, NULL
, 10);
646 id
->gid
= strtoul(id_str
, NULL
, 10);
653 free_attr_list( attr_list
);
655 ldap_msgfree(result
);
661 /**********************************************************************
662 Verify the sambaUnixIdPool entry in the directiry.
663 **********************************************************************/
665 static NTSTATUS
verify_idpool( void )
670 LDAPMessage
*result
= NULL
;
671 LDAPMod
**mods
= NULL
;
674 fstr_sprintf( filter
, "(objectclass=%s)", LDAP_OBJ_IDPOOL
);
676 attr_list
= get_attr_list( idpool_attr_list
);
677 rc
= smbldap_search(ldap_state
.smbldap_state
, lp_ldap_idmap_suffix(),
678 LDAP_SCOPE_SUBTREE
, filter
, attr_list
, 0, &result
);
679 free_attr_list ( attr_list
);
681 if (rc
!= LDAP_SUCCESS
)
682 return NT_STATUS_UNSUCCESSFUL
;
684 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
687 DEBUG(0,("ldap_idmap_init: multiple entries returned from %s (base == %s)\n",
688 filter
, lp_ldap_idmap_suffix() ));
689 return NT_STATUS_UNSUCCESSFUL
;
691 else if (count
== 0) {
694 fstring uid_str
, gid_str
;
696 if ( !lp_idmap_uid(&luid
, &huid
) || !lp_idmap_gid( &lgid
, &hgid
) ) {
697 DEBUG(0,("ldap_idmap_init: idmap uid/gid parameters not specified\n"));
698 return NT_STATUS_UNSUCCESSFUL
;
701 fstr_sprintf( uid_str
, "%lu", (unsigned long)luid
);
702 fstr_sprintf( gid_str
, "%lu", (unsigned long)lgid
);
704 smbldap_set_mod( &mods
, LDAP_MOD_ADD
, "objectClass", LDAP_OBJ_IDPOOL
);
705 smbldap_set_mod( &mods
, LDAP_MOD_ADD
,
706 get_attr_key2string(idpool_attr_list
, LDAP_ATTR_UIDNUMBER
), uid_str
);
707 smbldap_set_mod( &mods
, LDAP_MOD_ADD
,
708 get_attr_key2string(idpool_attr_list
, LDAP_ATTR_GIDNUMBER
), gid_str
);
710 rc
= smbldap_modify(ldap_state
.smbldap_state
, lp_ldap_idmap_suffix(), mods
);
713 return ( rc
==LDAP_SUCCESS
? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
);
716 /*****************************************************************************
717 Initialise idmap database.
718 *****************************************************************************/
720 static NTSTATUS
ldap_idmap_init( char *params
)
724 ldap_state
.mem_ctx
= talloc_init("idmap_ldap");
725 if (!ldap_state
.mem_ctx
) {
726 return NT_STATUS_NO_MEMORY
;
729 /* assume location is the only parameter */
730 if (!NT_STATUS_IS_OK(nt_status
=
731 smbldap_init(ldap_state
.mem_ctx
, params
,
732 &ldap_state
.smbldap_state
))) {
733 talloc_destroy(ldap_state
.mem_ctx
);
737 /* see if the idmap suffix and sub entries exists */
739 nt_status
= verify_idpool();
740 if ( !NT_STATUS_IS_OK(nt_status
) )
746 /*****************************************************************************
748 *****************************************************************************/
750 static NTSTATUS
ldap_idmap_close(void)
753 smbldap_free_struct(&(ldap_state
).smbldap_state
);
754 talloc_destroy(ldap_state
.mem_ctx
);
756 DEBUG(5,("The connection to the LDAP server was closed\n"));
757 /* maybe free the results here --metze */
763 /* This function doesn't make as much sense in an LDAP world since the calling
764 node doesn't really control the ID ranges */
765 static void ldap_idmap_status(void)
767 DEBUG(0, ("LDAP IDMAP Status not available\n"));
770 static struct idmap_methods ldap_methods
= {
774 ldap_get_sid_from_id
,
775 ldap_get_id_from_sid
,
782 NTSTATUS
idmap_ldap_init(void)
784 return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION
, "ldap", &ldap_methods
);