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 #define IDMAP_GROUP_SUFFIX "ou=idmap group"
38 #define IDMAP_USER_SUFFIX "ou=idmap people"
41 struct ldap_idmap_state
{
42 struct smbldap_state
*smbldap_state
;
46 #define LDAP_MAX_ALLOC_ID 128 /* number tries while allocating
49 static struct ldap_idmap_state ldap_state
;
51 static NTSTATUS
ldap_set_mapping(const DOM_SID
*sid
, unid_t id
, int id_type
);
52 static NTSTATUS
ldap_set_mapping_internals(const DOM_SID
*sid
, unid_t id
, int id_type
,
53 const char *ldap_dn
, LDAPMessage
*entry
);
54 static NTSTATUS
ldap_idmap_close(void);
57 /**********************************************************************
58 Even if the sambaDomain attribute in LDAP tells us that this RID is
59 safe to use, always check before use.
60 *********************************************************************/
62 static BOOL
sid_in_use(struct ldap_idmap_state
*state
,
63 const DOM_SID
*sid
, int *error
)
67 LDAPMessage
*result
= NULL
;
70 char *sid_attr
[] = {LDAP_ATTRIBUTE_SID
, NULL
};
72 slprintf(filter
, sizeof(filter
)-1, "(%s=%s)", LDAP_ATTRIBUTE_SID
, sid_to_string(sid_string
, sid
));
74 rc
= smbldap_search_suffix(state
->smbldap_state
,
75 filter
, sid_attr
, &result
);
77 if (rc
!= LDAP_SUCCESS
) {
78 char *ld_error
= NULL
;
79 ldap_get_option(state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
, &ld_error
);
80 DEBUG(2, ("Failed to check if sid %s is alredy in use: %s\n",
81 sid_string
, ld_error
));
88 if ((count
= ldap_count_entries(state
->smbldap_state
->ldap_struct
, result
)) > 0) {
89 DEBUG(3, ("Sid %s already in use - trying next RID\n",
97 /* good, sid is not in use */
101 /**********************************************************************
102 Set the new nextRid attribute, and return one we can use.
104 This also checks that this RID is actually free - in case the admin
105 manually stole it :-).
106 *********************************************************************/
108 static NTSTATUS
ldap_next_rid(struct ldap_idmap_state
*state
, uint32
*rid
,
111 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
113 LDAPMessage
*domain_result
= NULL
;
114 LDAPMessage
*entry
= NULL
;
116 LDAPMod
**mods
= NULL
;
117 fstring old_rid_string
;
118 fstring next_rid_string
;
119 fstring algorithmic_rid_base_string
;
123 char *ld_error
= NULL
;
125 while (attempts
< 10) {
126 if (!NT_STATUS_IS_OK(ret
= smbldap_search_domain_info(state
->smbldap_state
,
127 &domain_result
, get_global_sam_name(), True
))) {
131 entry
= ldap_first_entry(state
->smbldap_state
->ldap_struct
, domain_result
);
133 DEBUG(0, ("Could not get domain info entry\n"));
134 ldap_msgfree(domain_result
);
138 if ((dn
= smbldap_get_dn(state
->smbldap_state
->ldap_struct
, entry
)) == NULL
) {
139 DEBUG(0, ("Could not get domain info DN\n"));
140 ldap_msgfree(domain_result
);
144 /* yes, we keep 3 seperate counters, one for rids between 1000 (BASE_RID) and
145 algorithmic_rid_base. The other two are to avoid stomping on the
146 different sets of algorithmic RIDs */
148 if (smbldap_get_single_attribute(state
->smbldap_state
->ldap_struct
, entry
,
149 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_ALGORITHMIC_RID_BASE
),
150 algorithmic_rid_base_string
)) {
152 alg_rid_base
= (uint32
)atol(algorithmic_rid_base_string
);
154 alg_rid_base
= algorithmic_rid_base();
155 /* Try to make the modification atomically by enforcing the
156 old value in the delete mod. */
157 slprintf(algorithmic_rid_base_string
, sizeof(algorithmic_rid_base_string
)-1, "%d", alg_rid_base
);
158 smbldap_make_mod(state
->smbldap_state
->ldap_struct
, entry
, &mods
,
159 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_ALGORITHMIC_RID_BASE
),
160 algorithmic_rid_base_string
);
165 if (alg_rid_base
> BASE_RID
) {
166 /* we have a non-default 'algorithmic rid base', so we have 'low' rids that we
167 can allocate to new users */
168 if (smbldap_get_single_attribute(state
->smbldap_state
->ldap_struct
, entry
,
169 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_RID
),
171 *rid
= (uint32
)atol(old_rid_string
);
177 if (next_rid
>= alg_rid_base
) {
178 return NT_STATUS_UNSUCCESSFUL
;
181 slprintf(next_rid_string
, sizeof(next_rid_string
)-1, "%d", next_rid
);
183 /* Try to make the modification atomically by enforcing the
184 old value in the delete mod. */
185 smbldap_make_mod(state
->smbldap_state
->ldap_struct
, entry
, &mods
,
186 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_RID
),
190 if (!next_rid
) { /* not got one already */
193 if (smbldap_get_single_attribute(state
->smbldap_state
->ldap_struct
, entry
,
194 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_USERRID
),
196 *rid
= (uint32
)atol(old_rid_string
);
200 if (smbldap_get_single_attribute(state
->smbldap_state
->ldap_struct
, entry
,
201 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_GROUPRID
),
203 *rid
= (uint32
)atol(old_rid_string
);
208 /* This is the core of the whole routine. If we had
209 scheme-style closures, there would be a *lot* less code
212 next_rid
= *rid
+RID_MULTIPLIER
;
213 slprintf(next_rid_string
, sizeof(next_rid_string
)-1, "%d", next_rid
);
217 /* Try to make the modification atomically by enforcing the
218 old value in the delete mod. */
219 smbldap_make_mod(state
->smbldap_state
->ldap_struct
, entry
, &mods
,
220 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_USERRID
),
225 /* Try to make the modification atomically by enforcing the
226 old value in the delete mod. */
227 smbldap_make_mod(state
->smbldap_state
->ldap_struct
, entry
, &mods
,
228 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_GROUPRID
),
234 if ((rc
= smbldap_modify(state
->smbldap_state
, dn
, mods
)) == LDAP_SUCCESS
) {
237 pstring domain_sid_string
;
240 if (!smbldap_get_single_attribute(state
->smbldap_state
->ldap_struct
, domain_result
,
241 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_DOM_SID
),
242 domain_sid_string
)) {
243 ldap_mods_free(mods
, True
);
245 ldap_msgfree(domain_result
);
249 if (!string_to_sid(&dom_sid
, domain_sid_string
)) {
250 ldap_mods_free(mods
, True
);
252 ldap_msgfree(domain_result
);
256 ldap_mods_free(mods
, True
);
259 ldap_msgfree(domain_result
);
261 sid_copy(&sid
, &dom_sid
);
262 sid_append_rid(&sid
, *rid
);
264 /* check RID is not in use */
265 if (sid_in_use(state
, &sid
, &error
)) {
276 ldap_get_option(state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
, &ld_error
);
277 DEBUG(2, ("Failed to modify rid: %s\n", ld_error
? ld_error
: "(NULL"));
280 ldap_mods_free(mods
, True
);
285 ldap_msgfree(domain_result
);
286 domain_result
= NULL
;
289 /* Sleep for a random timeout */
290 unsigned sleeptime
= (sys_random()*sys_getpid()*attempts
);
298 DEBUG(0, ("Failed to set new RID\n"));
303 /*****************************************************************************
305 *****************************************************************************/
307 static NTSTATUS
ldap_allocate_rid(uint32
*rid
, int rid_type
)
309 return ldap_next_rid( &ldap_state
, rid
, rid_type
);
312 /*****************************************************************************
313 Allocate a new uid or gid
314 *****************************************************************************/
316 static NTSTATUS
ldap_allocate_id(unid_t
*id
, int id_type
)
318 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
319 int rc
= LDAP_SERVER_DOWN
;
321 LDAPMessage
*result
= NULL
;
322 LDAPMessage
*entry
= NULL
;
323 pstring id_str
, new_id_str
;
324 LDAPMod
**mods
= NULL
;
333 type
= (id_type
& ID_USERID
) ?
334 get_attr_key2string( idpool_attr_list
, LDAP_ATTR_UIDNUMBER
) :
335 get_attr_key2string( idpool_attr_list
, LDAP_ATTR_GIDNUMBER
);
337 pstr_sprintf(filter
, "(objectClass=%s)", LDAP_OBJ_IDPOOL
);
339 attr_list
= get_attr_list( idpool_attr_list
);
341 rc
= smbldap_search(ldap_state
.smbldap_state
, lp_ldap_idmap_suffix(),
342 LDAP_SCOPE_SUBTREE
, filter
,
343 attr_list
, 0, &result
);
344 free_attr_list( attr_list
);
346 if (rc
!= LDAP_SUCCESS
) {
347 DEBUG(0,("ldap_allocate_id: %s object not found\n", LDAP_OBJ_IDPOOL
));
351 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
353 DEBUG(0,("ldap_allocate_id: single %s object not found\n", LDAP_OBJ_IDPOOL
));
357 dn
= smbldap_get_dn(ldap_state
.smbldap_state
->ldap_struct
, result
);
361 entry
= ldap_first_entry(ldap_state
.smbldap_state
->ldap_struct
, result
);
363 if (!smbldap_get_single_attribute(ldap_state
.smbldap_state
->ldap_struct
, entry
, type
, id_str
)) {
364 DEBUG(0,("ldap_allocate_id: %s attribute not found\n",
369 /* this must succeed or else we wouldn't have initialized */
371 lp_idmap_uid( &luid
, &huid
);
372 lp_idmap_gid( &lgid
, &hgid
);
374 /* make sure we still have room to grow */
376 if (id_type
& ID_USERID
) {
377 id
->uid
= strtoul(id_str
, NULL
, 10);
378 if (id
->uid
> huid
) {
379 DEBUG(0,("ldap_allocate_id: Cannot allocate uid above %lu!\n",
380 (unsigned long)huid
));
385 id
->gid
= strtoul(id_str
, NULL
, 10);
386 if (id
->gid
> hgid
) {
387 DEBUG(0,("ldap_allocate_id: Cannot allocate gid above %lu!\n",
388 (unsigned long)hgid
));
393 pstr_sprintf(new_id_str
, "%lu",
394 ((id_type
& ID_USERID
) ? (unsigned long)id
->uid
:
395 (unsigned long)id
->gid
) + 1);
397 smbldap_set_mod( &mods
, LDAP_MOD_DELETE
, type
, id_str
);
398 smbldap_set_mod( &mods
, LDAP_MOD_ADD
, type
, new_id_str
);
400 rc
= smbldap_modify(ldap_state
.smbldap_state
, dn
, mods
);
403 ldap_mods_free( mods
, True
);
405 if (rc
!= LDAP_SUCCESS
) {
406 DEBUG(0,("ldap_allocate_id: Failed to allocate new %s. ldap_modify() failed.\n",
416 /*****************************************************************************
418 *****************************************************************************/
420 static NTSTATUS
ldap_get_sid_from_id(DOM_SID
*sid
, unid_t id
, int id_type
)
422 LDAPMessage
*result
= NULL
;
423 LDAPMessage
*entry
= NULL
;
429 const char *obj_class
;
432 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
435 /* first we try for a samba user or group mapping */
437 if ( id_type
& ID_USERID
) {
438 type
= get_attr_key2string( idpool_attr_list
, LDAP_ATTR_UIDNUMBER
);
439 obj_class
= LDAP_OBJ_SAMBASAMACCOUNT
;
440 fstr_sprintf(id_str
, "%lu", (unsigned long)id
.uid
);
441 pstrcpy( suffix
, lp_ldap_suffix());
444 type
= get_attr_key2string( idpool_attr_list
, LDAP_ATTR_GIDNUMBER
);
445 obj_class
= LDAP_OBJ_GROUPMAP
;
446 fstr_sprintf(id_str
, "%lu", (unsigned long)id
.gid
);
447 pstrcpy( suffix
, lp_ldap_group_suffix() );
450 DEBUG(5,("ldap_get_sid_from_id: Searching \"%s\"\n", filter
));
452 attr_list
= get_attr_list( sidmap_attr_list
);
453 pstr_sprintf(filter
, "(&(|(objectClass=%s)(objectClass=%s))(%s=%s))",
454 LDAP_OBJ_IDMAP_ENTRY
, obj_class
, type
, id_str
);
456 rc
= smbldap_search(ldap_state
.smbldap_state
, suffix
, LDAP_SCOPE_SUBTREE
,
457 filter
, attr_list
, 0, &result
);
459 if (rc
!= LDAP_SUCCESS
) {
460 DEBUG(3,("ldap_get_isd_from_id: Failure looking up entry (%s)\n",
461 ldap_err2string(rc
) ));
465 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
468 DEBUG(0,("ldap_get_sid_from_id: mapping returned [%d] entries!\n",
473 /* fall back to looking up an idmap entry if we didn't find and
474 actual user or group */
477 ldap_msgfree(result
);
480 pstr_sprintf(filter
, "(&(objectClass=%s)(%s=%lu))",
481 LDAP_OBJ_IDMAP_ENTRY
, type
,
482 ((id_type
& ID_USERID
) ? (unsigned long)id
.uid
:
483 (unsigned long)id
.gid
));
485 pstrcpy( suffix
, lp_ldap_idmap_suffix() );
487 rc
= smbldap_search(ldap_state
.smbldap_state
, suffix
, LDAP_SCOPE_SUBTREE
,
488 filter
, attr_list
, 0, &result
);
490 if (rc
!= LDAP_SUCCESS
) {
491 DEBUG(3,("ldap_get_isd_from_id: Failure looking up entry (%s)\n",
492 ldap_err2string(rc
) ));
496 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
499 DEBUG(0,("ldap_get_sid_from_id: mapping not found for %s: %lu\n",
500 type
, ((id_type
& ID_USERID
) ? (unsigned long)id
.uid
:
501 (unsigned long)id
.gid
)));
506 entry
= ldap_first_entry(ldap_state
.smbldap_state
->ldap_struct
, result
);
508 if ( !smbldap_get_single_attribute(ldap_state
.smbldap_state
->ldap_struct
, entry
, LDAP_ATTRIBUTE_SID
, sid_str
) )
511 if (!string_to_sid(sid
, sid_str
))
516 free_attr_list( attr_list
);
519 ldap_msgfree(result
);
524 /***********************************************************************
526 ***********************************************************************/
528 static NTSTATUS
ldap_get_id_from_sid(unid_t
*id
, int *id_type
, const DOM_SID
*sid
)
530 LDAPMessage
*result
= NULL
;
531 LDAPMessage
*entry
= NULL
;
541 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
543 sid_to_string(sid_str
, sid
);
545 DEBUG(8,("ldap_get_id_from_sid: %s (%s)\n", sid_str
,
546 (*id_type
& ID_GROUPID
? "group" : "user") ));
548 /* ahhh.... ok. We have to check users and groups in places other
549 than idmap (hint: we're a domain member of a Samba domain) */
551 if ( *id_type
& ID_GROUPID
) {
553 type
= get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_GIDNUMBER
);
554 suffix
= lp_ldap_group_suffix();
555 pstr_sprintf(filter
, "(&(|(objectClass=%s)(objectClass=%s))(%s=%s))",
556 LDAP_OBJ_GROUPMAP
, LDAP_OBJ_IDMAP_ENTRY
,
557 get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_SID
),
563 type
= get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_UIDNUMBER
);
564 suffix
= lp_ldap_suffix();
565 pstr_sprintf(filter
, "(&(|(&(objectClass=%s)(objectClass=%s))(objectClass=%s))(%s=%s))",
566 LDAP_OBJ_SAMBASAMACCOUNT
, LDAP_OBJ_POSIXACCOUNT
, LDAP_OBJ_IDMAP_ENTRY
,
567 get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_SID
),
572 DEBUG(10,("ldap_get_id_from_sid: Searching for \"%s\"\n", filter
));
574 /* do the search and check for errors */
576 attr_list
= get_attr_list( sidmap_attr_list
);
577 rc
= smbldap_search(ldap_state
.smbldap_state
, suffix
, LDAP_SCOPE_SUBTREE
,
578 filter
, attr_list
, 0, &result
);
580 if ( rc
!= LDAP_SUCCESS
) {
581 DEBUG(3,("ldap_get_id_from_sid: Failure looking up group mapping (%s)\n",
582 ldap_err2string(rc
) ));
586 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
589 DEBUG(3,("ldap_get_id_from_sid: search \"%s\" returned [%d] entries. Bailing...\n",
594 /* see if we need to do a search here */
599 ldap_msgfree(result
);
603 /* look in idmap suffix */
605 suffix
= lp_ldap_idmap_suffix();
606 pstr_sprintf(filter
, "(&(objectClass=%s)(%s=%s))",
607 LDAP_OBJ_IDMAP_ENTRY
, LDAP_ATTRIBUTE_SID
, sid_str
);
609 rc
= smbldap_search(ldap_state
.smbldap_state
, suffix
, LDAP_SCOPE_SUBTREE
,
610 filter
, attr_list
, 0, &result
);
612 if (rc
!= LDAP_SUCCESS
) {
613 DEBUG(3,("ldap_get_id_from_sid: Failure looking up idmap entry (%s)\n",
614 ldap_err2string(rc
) ));
618 /* check for the number of entries returned */
620 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
623 DEBUG(0, ("ldap_get_id_from_sid: (2nd) search %s returned [%d] entries!\n",
629 /* try to allocate a new id if we still haven't found one */
631 if ( (count
==0) && !(*id_type
& ID_QUERY_ONLY
) ) {
634 DEBUG(8,("ldap_get_id_from_sid: Allocating new id\n"));
636 for (i
= 0; i
< LDAP_MAX_ALLOC_ID
; i
++) {
637 ret
= ldap_allocate_id(id
, *id_type
);
638 if ( NT_STATUS_IS_OK(ret
) )
642 if ( !NT_STATUS_IS_OK(ret
) ) {
643 DEBUG(0,("ldap_allocate_id: cannot acquire id lock!\n"));
647 DEBUG(10,("ldap_get_id_from_sid: Allocated new %cid [%ul]\n",
648 (*id_type
& ID_GROUPID
? 'g' : 'u'), (uint32
)id
->uid
));
650 ret
= ldap_set_mapping(sid
, *id
, *id_type
);
658 DEBUG(10,("ldap_get_id_from_sid: success\n"));
660 entry
= ldap_first_entry(ldap_state
.smbldap_state
->ldap_struct
, result
);
662 dn
= smbldap_get_dn(ldap_state
.smbldap_state
->ldap_struct
, result
);
666 DEBUG(10, ("Found mapping entry at dn=%s, looking for %s\n", dn
, type
));
668 if ( smbldap_get_single_attribute(ldap_state
.smbldap_state
->ldap_struct
, entry
, type
, id_str
) ) {
669 if ( (*id_type
& ID_USERID
) )
670 id
->uid
= strtoul(id_str
, NULL
, 10);
672 id
->gid
= strtoul(id_str
, NULL
, 10);
679 free_attr_list( attr_list
);
681 ldap_msgfree(result
);
687 /***********************************************************************
688 This function cannot be called to modify a mapping, only set a new one
690 This takes a possible pointer to the existing entry for the UID or SID
692 ***********************************************************************/
694 static NTSTATUS
ldap_set_mapping_internals(const DOM_SID
*sid
, unid_t id
,
695 int id_type
, const char *ldap_dn
,
701 LDAPMod
**mods
= NULL
;
705 char **values
= NULL
;
708 sid_to_string( sid_string
, sid
);
711 DEBUG(10, ("Adding new IDMAP mapping on DN: %s", ldap_dn
));
712 ldap_op
= LDAP_MOD_REPLACE
;
713 pstrcpy( dn
, ldap_dn
);
715 ldap_op
= LDAP_MOD_ADD
;
716 pstr_sprintf(dn
, "%s=%s,%s", get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_SID
),
717 sid_string
, lp_ldap_idmap_suffix());
720 if ( id_type
& ID_USERID
)
721 fstrcpy( type
, get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_UIDNUMBER
) );
723 fstrcpy( type
, get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_GIDNUMBER
) );
725 pstr_sprintf(id_str
, "%lu", ((id_type
& ID_USERID
) ? (unsigned long)id
.uid
:
726 (unsigned long)id
.gid
));
729 values
= ldap_get_values(ldap_state
.smbldap_state
->ldap_struct
, entry
, "objectClass");
732 BOOL found_idmap
= False
;
733 for (i
=0; values
[i
]; i
++) {
734 if (StrCaseCmp(values
[i
], LDAP_OBJ_IDMAP_ENTRY
) == 0) {
740 smbldap_set_mod( &mods
, LDAP_MOD_ADD
,
741 "objectClass", LDAP_OBJ_IDMAP_ENTRY
);
743 smbldap_set_mod( &mods
, LDAP_MOD_ADD
,
744 "objectClass", LDAP_OBJ_IDMAP_ENTRY
);
747 smbldap_make_mod( ldap_state
.smbldap_state
->ldap_struct
,
748 entry
, &mods
, type
, id_str
);
750 smbldap_make_mod( ldap_state
.smbldap_state
->ldap_struct
,
752 get_attr_key2string(sidmap_attr_list
, LDAP_ATTR_SID
),
755 /* There may well be nothing at all to do */
760 smbldap_set_mod( &mods
, LDAP_MOD_ADD
,
761 "objectClass", LDAP_OBJ_SID_ENTRY
);
762 rc
= smbldap_add(ldap_state
.smbldap_state
, dn
, mods
);
764 case LDAP_MOD_REPLACE
:
765 rc
= smbldap_modify(ldap_state
.smbldap_state
, dn
, mods
);
769 ldap_mods_free( mods
, True
);
774 if (rc
!= LDAP_SUCCESS
) {
775 char *ld_error
= NULL
;
776 ldap_get_option(ldap_state
.smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
778 DEBUG(0,("ldap_set_mapping_internals: Failed to %s mapping from %s to %lu [%s]\n",
779 (ldap_op
== LDAP_MOD_ADD
) ? "add" : "replace",
780 sid_string
, (unsigned long)((id_type
& ID_USERID
) ? id
.uid
: id
.gid
), type
));
781 DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n", ld_error
? ld_error
: "(NULL)", ldap_err2string (rc
)));
782 return NT_STATUS_UNSUCCESSFUL
;
785 DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to %lu [%s]\n",
786 sid_string
, ((id_type
& ID_USERID
) ? (unsigned long)id
.uid
:
787 (unsigned long)id
.gid
), type
));
792 /***********************************************************************
793 This function cannot be called to modify a mapping, only set a new one
794 ***********************************************************************/
796 static NTSTATUS
ldap_set_mapping(const DOM_SID
*sid
, unid_t id
, int id_type
)
798 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
800 LDAPMessage
*result
= NULL
;
801 LDAPMessage
*entry
= NULL
;
803 const char *obj_class
;
804 const char *posix_obj_class
;
813 /* try for a samba user or group mapping (looking for an entry with a SID) */
814 if ( id_type
& ID_USERID
) {
815 obj_class
= LDAP_OBJ_SAMBASAMACCOUNT
;
816 suffix
= lp_ldap_suffix();
817 type
= get_attr_key2string( idpool_attr_list
, LDAP_ATTR_UIDNUMBER
);
818 posix_obj_class
= LDAP_OBJ_POSIXACCOUNT
;
819 fstr_sprintf(id_str
, "%lu", (unsigned long)id
.uid
);
822 obj_class
= LDAP_OBJ_GROUPMAP
;
823 suffix
= lp_ldap_group_suffix();
824 type
= get_attr_key2string( idpool_attr_list
, LDAP_ATTR_GIDNUMBER
);
825 posix_obj_class
= LDAP_OBJ_POSIXGROUP
;
826 fstr_sprintf(id_str
, "%lu", (unsigned long)id
.gid
);
829 sid_to_string(sid_str
, sid
);
832 "(&(|(objectClass=%s)(|(objectClass=%s)(objectClass=%s)))(%s=%s))"
833 "(&(objectClass=%s)(%s=%s))"
835 /* objectClasses that might contain a SID */
836 LDAP_OBJ_SID_ENTRY
, LDAP_OBJ_IDMAP_ENTRY
, obj_class
,
837 get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_SID
),
840 /* objectClasses that might contain a Unix UID/GID */
842 /* Unix UID/GID specifier*/
847 attr_list
= get_attr_list( sidmap_attr_list
);
848 rc
= smbldap_search(ldap_state
.smbldap_state
, suffix
, LDAP_SCOPE_SUBTREE
,
849 filter
, attr_list
, 0, &result
);
850 free_attr_list( attr_list
);
852 if (rc
!= LDAP_SUCCESS
)
855 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
857 /* fall back to looking up an idmap entry if we didn't find anything under the idmap
858 user or group suffix */
861 entry
= ldap_first_entry(ldap_state
.smbldap_state
->ldap_struct
, result
);
863 dn
= smbldap_get_dn(ldap_state
.smbldap_state
->ldap_struct
, result
);
866 DEBUG(10, ("Found partial mapping entry at dn=%s, looking for %s\n", dn
, type
));
868 ret
= ldap_set_mapping_internals(sid
, id
, id_type
, dn
, entry
);
871 } else if (count
> 1) {
872 DEBUG(0, ("Too many entries trying to find DN to attach ldap \n"));
876 ret
= ldap_set_mapping_internals(sid
, id
, id_type
, NULL
, NULL
);
880 ldap_msgfree(result
);
887 /**********************************************************************
888 Verify the sambaUnixIdPool entry in the directiry.
889 **********************************************************************/
891 static NTSTATUS
verify_idpool( void )
896 LDAPMessage
*result
= NULL
;
897 LDAPMod
**mods
= NULL
;
900 fstr_sprintf( filter
, "(objectclass=%s)", LDAP_OBJ_IDPOOL
);
902 attr_list
= get_attr_list( idpool_attr_list
);
903 rc
= smbldap_search(ldap_state
.smbldap_state
, lp_ldap_idmap_suffix(),
904 LDAP_SCOPE_SUBTREE
, filter
, attr_list
, 0, &result
);
905 free_attr_list ( attr_list
);
907 if (rc
!= LDAP_SUCCESS
)
908 return NT_STATUS_UNSUCCESSFUL
;
910 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
913 DEBUG(0,("ldap_idmap_init: multiple entries returned from %s (base == %s)\n",
914 filter
, lp_ldap_idmap_suffix() ));
915 return NT_STATUS_UNSUCCESSFUL
;
917 else if (count
== 0) {
920 fstring uid_str
, gid_str
;
922 if ( !lp_idmap_uid(&luid
, &huid
) || !lp_idmap_gid( &lgid
, &hgid
) ) {
923 DEBUG(0,("ldap_idmap_init: idmap uid/gid parameters not specified\n"));
924 return NT_STATUS_UNSUCCESSFUL
;
927 fstr_sprintf( uid_str
, "%lu", (unsigned long)luid
);
928 fstr_sprintf( gid_str
, "%lu", (unsigned long)lgid
);
930 smbldap_set_mod( &mods
, LDAP_MOD_ADD
, "objectClass", LDAP_OBJ_IDPOOL
);
931 smbldap_set_mod( &mods
, LDAP_MOD_ADD
,
932 get_attr_key2string(idpool_attr_list
, LDAP_ATTR_UIDNUMBER
), uid_str
);
933 smbldap_set_mod( &mods
, LDAP_MOD_ADD
,
934 get_attr_key2string(idpool_attr_list
, LDAP_ATTR_GIDNUMBER
), gid_str
);
936 rc
= smbldap_modify(ldap_state
.smbldap_state
, lp_ldap_idmap_suffix(), mods
);
939 return ( rc
==LDAP_SUCCESS
? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
);
942 /*****************************************************************************
943 Initialise idmap database.
944 *****************************************************************************/
946 static NTSTATUS
ldap_idmap_init( char *params
)
950 ldap_state
.mem_ctx
= talloc_init("idmap_ldap");
951 if (!ldap_state
.mem_ctx
) {
952 return NT_STATUS_NO_MEMORY
;
955 /* assume location is the only parameter */
956 if (!NT_STATUS_IS_OK(nt_status
=
957 smbldap_init(ldap_state
.mem_ctx
, params
,
958 &ldap_state
.smbldap_state
))) {
959 talloc_destroy(ldap_state
.mem_ctx
);
963 /* see if the idmap suffix and sub entries exists */
965 nt_status
= verify_idpool();
966 if ( !NT_STATUS_IS_OK(nt_status
) )
972 /*****************************************************************************
974 *****************************************************************************/
976 static NTSTATUS
ldap_idmap_close(void)
979 smbldap_free_struct(&(ldap_state
).smbldap_state
);
980 talloc_destroy(ldap_state
.mem_ctx
);
982 DEBUG(5,("The connection to the LDAP server was closed\n"));
983 /* maybe free the results here --metze */
989 /* This function doesn't make as much sense in an LDAP world since the calling
990 node doesn't really control the ID ranges */
991 static void ldap_idmap_status(void)
993 DEBUG(0, ("LDAP IDMAP Status not available\n"));
996 static struct idmap_methods ldap_methods
= {
1000 ldap_get_sid_from_id
,
1001 ldap_get_id_from_sid
,
1008 NTSTATUS
idmap_ldap_init(void)
1010 return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION
, "ldap", &ldap_methods
);