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 *********************************************************************/
107 static NTSTATUS
ldap_next_rid(struct ldap_idmap_state
*state
, uint32
*rid
,
110 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
112 LDAPMessage
*domain_result
= NULL
;
113 LDAPMessage
*entry
= NULL
;
115 LDAPMod
**mods
= NULL
;
116 fstring old_rid_string
;
117 fstring next_rid_string
;
118 fstring algorithmic_rid_base_string
;
122 char *ld_error
= NULL
;
124 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
)))
132 entry
= ldap_first_entry(state
->smbldap_state
->ldap_struct
, domain_result
);
134 DEBUG(0, ("Could not get domain info entry\n"));
135 ldap_msgfree(domain_result
);
139 if ((dn
= ldap_get_dn(state
->smbldap_state
->ldap_struct
, entry
)) == NULL
) {
140 DEBUG(0, ("Could not get domain info DN\n"));
141 ldap_msgfree(domain_result
);
145 /* yes, we keep 3 seperate counters, one for rids between 1000 (BASE_RID) and
146 algorithmic_rid_base. The other two are to avoid stomping on the
147 different sets of algorithmic RIDs */
149 if (smbldap_get_single_attribute(state
->smbldap_state
->ldap_struct
, entry
,
150 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_ALGORITHMIC_RID_BASE
),
151 algorithmic_rid_base_string
))
154 alg_rid_base
= (uint32
)atol(algorithmic_rid_base_string
);
156 alg_rid_base
= algorithmic_rid_base();
157 /* Try to make the modification atomically by enforcing the
158 old value in the delete mod. */
159 slprintf(algorithmic_rid_base_string
, sizeof(algorithmic_rid_base_string
)-1, "%d", alg_rid_base
);
160 smbldap_make_mod(state
->smbldap_state
->ldap_struct
, entry
, &mods
,
161 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_ALGORITHMIC_RID_BASE
),
162 algorithmic_rid_base_string
);
167 if (alg_rid_base
> BASE_RID
) {
168 /* we have a non-default 'algorithmic rid base', so we have 'low' rids that we
169 can allocate to new users */
170 if (smbldap_get_single_attribute(state
->smbldap_state
->ldap_struct
, entry
,
171 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_RID
),
174 *rid
= (uint32
)atol(old_rid_string
);
180 if (next_rid
>= alg_rid_base
) {
181 return NT_STATUS_UNSUCCESSFUL
;
184 slprintf(next_rid_string
, sizeof(next_rid_string
)-1, "%d", next_rid
);
186 /* Try to make the modification atomically by enforcing the
187 old value in the delete mod. */
188 smbldap_make_mod(state
->smbldap_state
->ldap_struct
, entry
, &mods
,
189 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_RID
),
193 if (!next_rid
) { /* not got one already */
196 if (smbldap_get_single_attribute(state
->smbldap_state
->ldap_struct
, entry
,
197 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_USERRID
),
200 *rid
= (uint32
)atol(old_rid_string
);
204 if (smbldap_get_single_attribute(state
->smbldap_state
->ldap_struct
, entry
,
205 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_GROUPRID
),
208 *rid
= (uint32
)atol(old_rid_string
);
213 /* This is the core of the whole routine. If we had
214 scheme-style closures, there would be a *lot* less code
217 next_rid
= *rid
+RID_MULTIPLIER
;
218 slprintf(next_rid_string
, sizeof(next_rid_string
)-1, "%d", next_rid
);
222 /* Try to make the modification atomically by enforcing the
223 old value in the delete mod. */
224 smbldap_make_mod(state
->smbldap_state
->ldap_struct
, entry
, &mods
,
225 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_USERRID
),
230 /* Try to make the modification atomically by enforcing the
231 old value in the delete mod. */
232 smbldap_make_mod(state
->smbldap_state
->ldap_struct
, entry
, &mods
,
233 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_NEXT_GROUPRID
),
239 if ((rc
= ldap_modify_s(state
->smbldap_state
->ldap_struct
, dn
, mods
)) == LDAP_SUCCESS
) {
242 pstring domain_sid_string
;
245 if (!smbldap_get_single_attribute(state
->smbldap_state
->ldap_struct
, domain_result
,
246 get_attr_key2string(dominfo_attr_list
, LDAP_ATTR_DOM_SID
),
249 ldap_mods_free(mods
, True
);
251 ldap_msgfree(domain_result
);
255 if (!string_to_sid(&dom_sid
, domain_sid_string
)) {
256 ldap_mods_free(mods
, True
);
258 ldap_msgfree(domain_result
);
262 ldap_mods_free(mods
, True
);
265 ldap_msgfree(domain_result
);
267 sid_copy(&sid
, &dom_sid
);
268 sid_append_rid(&sid
, *rid
);
270 /* check RID is not in use */
271 if (sid_in_use(state
, &sid
, &error
)) {
282 ldap_get_option(state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
, &ld_error
);
283 DEBUG(2, ("Failed to modify rid: %s\n", ld_error
? ld_error
: "(NULL"));
286 ldap_mods_free(mods
, True
);
292 ldap_msgfree(domain_result
);
293 domain_result
= NULL
;
296 /* Sleep for a random timeout */
297 unsigned sleeptime
= (sys_random()*sys_getpid()*attempts
);
305 DEBUG(0, ("Failed to set new RID\n"));
310 /*****************************************************************************
312 *****************************************************************************/
314 static NTSTATUS
ldap_allocate_rid(uint32
*rid
, int rid_type
)
316 return ldap_next_rid( &ldap_state
, rid
, rid_type
);
319 /*****************************************************************************
320 Allocate a new uid or gid
321 *****************************************************************************/
323 static NTSTATUS
ldap_allocate_id(unid_t
*id
, int id_type
)
325 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
326 int rc
= LDAP_SERVER_DOWN
;
328 LDAPMessage
*result
= NULL
;
329 LDAPMessage
*entry
= NULL
;
330 pstring id_str
, new_id_str
;
331 LDAPMod
**mods
= NULL
;
340 type
= (id_type
& ID_USERID
) ?
341 get_attr_key2string( idpool_attr_list
, LDAP_ATTR_UIDNUMBER
) :
342 get_attr_key2string( idpool_attr_list
, LDAP_ATTR_GIDNUMBER
);
344 pstr_sprintf(filter
, "(objectClass=%s)", LDAP_OBJ_IDPOOL
);
346 attr_list
= get_attr_list( idpool_attr_list
);
348 rc
= smbldap_search(ldap_state
.smbldap_state
, lp_ldap_idmap_suffix(),
349 LDAP_SCOPE_SUBTREE
, filter
,
350 attr_list
, 0, &result
);
351 free_attr_list( attr_list
);
353 if (rc
!= LDAP_SUCCESS
) {
354 DEBUG(0,("ldap_allocate_id: %s object not found\n", LDAP_OBJ_IDPOOL
));
358 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
360 DEBUG(0,("ldap_allocate_id: single %s object not found\n", LDAP_OBJ_IDPOOL
));
364 dn
= ldap_get_dn(ldap_state
.smbldap_state
->ldap_struct
, result
);
365 entry
= ldap_first_entry(ldap_state
.smbldap_state
->ldap_struct
, result
);
367 if (!smbldap_get_single_attribute(ldap_state
.smbldap_state
->ldap_struct
, entry
, type
, id_str
)) {
368 DEBUG(0,("ldap_allocate_id: %s attribute not found\n",
373 /* this must succeed or else we wouldn't have initialized */
375 lp_idmap_uid( &luid
, &huid
);
376 lp_idmap_gid( &lgid
, &hgid
);
378 /* make sure we still have room to grow */
380 if (id_type
& ID_USERID
) {
381 id
->uid
= strtoul(id_str
, NULL
, 10);
382 if (id
->uid
> huid
) {
383 DEBUG(0,("ldap_allocate_id: Cannot allocate uid above %lu!\n",
384 (unsigned long)huid
));
389 id
->gid
= strtoul(id_str
, NULL
, 10);
390 if (id
->gid
> hgid
) {
391 DEBUG(0,("ldap_allocate_id: Cannot allocate gid above %lu!\n",
392 (unsigned long)hgid
));
397 pstr_sprintf(new_id_str
, "%lu",
398 ((id_type
& ID_USERID
) ? (unsigned long)id
->uid
:
399 (unsigned long)id
->gid
) + 1);
401 smbldap_set_mod( &mods
, LDAP_MOD_DELETE
, type
, id_str
);
402 smbldap_set_mod( &mods
, LDAP_MOD_ADD
, type
, new_id_str
);
404 rc
= ldap_modify_s(ldap_state
.smbldap_state
->ldap_struct
, dn
, mods
);
407 ldap_mods_free( mods
, True
);
409 if (rc
!= LDAP_SUCCESS
) {
410 DEBUG(0,("ldap_allocate_id: Failed to allocate new %s. ldap_modify() failed.\n",
420 /*****************************************************************************
422 *****************************************************************************/
424 static NTSTATUS
ldap_get_sid_from_id(DOM_SID
*sid
, unid_t id
, int id_type
)
426 LDAPMessage
*result
= NULL
;
427 LDAPMessage
*entry
= NULL
;
433 const char *obj_class
;
436 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
439 /* first we try for a samba user or group mapping */
441 if ( id_type
& ID_USERID
) {
442 type
= get_attr_key2string( idpool_attr_list
, LDAP_ATTR_UIDNUMBER
);
443 obj_class
= LDAP_OBJ_SAMBASAMACCOUNT
;
444 fstr_sprintf(id_str
, "%lu", (unsigned long)id
.uid
);
445 pstrcpy( suffix
, lp_ldap_suffix());
448 type
= get_attr_key2string( idpool_attr_list
, LDAP_ATTR_GIDNUMBER
);
449 obj_class
= LDAP_OBJ_GROUPMAP
;
450 fstr_sprintf(id_str
, "%lu", (unsigned long)id
.gid
);
451 pstrcpy( suffix
, lp_ldap_group_suffix() );
454 DEBUG(5,("ldap_get_sid_from_id: Searching \"%s\"\n", filter
));
456 attr_list
= get_attr_list( sidmap_attr_list
);
457 pstr_sprintf(filter
, "(&(|(objectClass=%s)(objectClass=%s))(%s=%s))",
458 LDAP_OBJ_IDMAP_ENTRY
, obj_class
, type
, id_str
);
460 rc
= smbldap_search(ldap_state
.smbldap_state
, suffix
, LDAP_SCOPE_SUBTREE
,
461 filter
, attr_list
, 0, &result
);
463 if (rc
!= LDAP_SUCCESS
) {
464 DEBUG(3,("ldap_get_isd_from_id: Failure looking up entry (%s)\n",
465 ldap_err2string(rc
) ));
469 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
472 DEBUG(0,("ldap_get_sid_from_id: mapping returned [%d] entries!\n",
477 /* fall back to looking up an idmap entry if we didn't find and
478 actual user or group */
481 ldap_msgfree(result
);
484 pstr_sprintf(filter
, "(&(objectClass=%s)(%s=%lu))",
485 LDAP_OBJ_IDMAP_ENTRY
, type
,
486 ((id_type
& ID_USERID
) ? (unsigned long)id
.uid
:
487 (unsigned long)id
.gid
));
489 pstrcpy( suffix
, lp_ldap_idmap_suffix() );
491 rc
= smbldap_search(ldap_state
.smbldap_state
, suffix
, LDAP_SCOPE_SUBTREE
,
492 filter
, attr_list
, 0, &result
);
494 if (rc
!= LDAP_SUCCESS
) {
495 DEBUG(3,("ldap_get_isd_from_id: Failure looking up entry (%s)\n",
496 ldap_err2string(rc
) ));
500 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
503 DEBUG(0,("ldap_get_sid_from_id: mapping not found for %s: %lu\n",
504 type
, ((id_type
& ID_USERID
) ? (unsigned long)id
.uid
:
505 (unsigned long)id
.gid
)));
510 entry
= ldap_first_entry(ldap_state
.smbldap_state
->ldap_struct
, result
);
512 if ( !smbldap_get_single_attribute(ldap_state
.smbldap_state
->ldap_struct
, entry
, LDAP_ATTRIBUTE_SID
, sid_str
) )
515 if (!string_to_sid(sid
, sid_str
))
520 free_attr_list( attr_list
);
523 ldap_msgfree(result
);
528 /***********************************************************************
530 ***********************************************************************/
532 static NTSTATUS
ldap_get_id_from_sid(unid_t
*id
, int *id_type
, const DOM_SID
*sid
)
534 LDAPMessage
*result
= NULL
;
535 LDAPMessage
*entry
= NULL
;
545 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
547 sid_to_string(sid_str
, sid
);
549 DEBUG(8,("ldap_get_id_from_sid: %s (%s)\n", sid_str
,
550 (*id_type
& ID_GROUPID
? "group" : "user") ));
552 /* ahhh.... ok. We have to check users and groups in places other
553 than idmap (hint: we're a domain member of a Samba domain) */
555 if ( *id_type
& ID_GROUPID
) {
557 type
= get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_GIDNUMBER
);
558 suffix
= lp_ldap_group_suffix();
559 pstr_sprintf(filter
, "(&(|(objectClass=%s)(objectClass=%s))(%s=%s))",
560 LDAP_OBJ_GROUPMAP
, LDAP_OBJ_IDMAP_ENTRY
,
561 get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_SID
),
567 type
= get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_UIDNUMBER
);
568 suffix
= lp_ldap_suffix();
569 pstr_sprintf(filter
, "(&(|(&(objectClass=%s)(objectClass=%s))(objectClass=%s))(%s=%s))",
570 LDAP_OBJ_SAMBASAMACCOUNT
, LDAP_OBJ_POSIXACCOUNT
, LDAP_OBJ_IDMAP_ENTRY
,
571 get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_SID
),
576 DEBUG(10,("ldap_get_id_from_sid: Searching for \"%s\"\n", filter
));
578 /* do the search and check for errors */
580 attr_list
= get_attr_list( sidmap_attr_list
);
581 rc
= smbldap_search(ldap_state
.smbldap_state
, suffix
, LDAP_SCOPE_SUBTREE
,
582 filter
, attr_list
, 0, &result
);
584 if ( rc
!= LDAP_SUCCESS
) {
585 DEBUG(3,("ldap_get_id_from_sid: Failure looking up group mapping (%s)\n",
586 ldap_err2string(rc
) ));
590 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
593 DEBUG(3,("ldap_get_id_from_sid: search \"%s\" returned [%d] entries. Bailing...\n",
598 /* see if we need to do a search here */
603 ldap_msgfree(result
);
607 /* look in idmap suffix */
609 suffix
= lp_ldap_idmap_suffix();
610 pstr_sprintf(filter
, "(&(objectClass=%s)(%s=%s))",
611 LDAP_OBJ_IDMAP_ENTRY
, LDAP_ATTRIBUTE_SID
, sid_str
);
613 rc
= smbldap_search(ldap_state
.smbldap_state
, suffix
, LDAP_SCOPE_SUBTREE
,
614 filter
, attr_list
, 0, &result
);
616 if (rc
!= LDAP_SUCCESS
) {
617 DEBUG(3,("ldap_get_id_from_sid: Failure looking up idmap entry (%s)\n",
618 ldap_err2string(rc
) ));
622 /* check for the number of entries returned */
624 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
627 DEBUG(0, ("ldap_get_id_from_sid: (2nd) search %s returned [%d] entries!\n",
633 /* try to allocate a new id if we still haven't found one */
635 if ( (count
==0) && !(*id_type
& ID_QUERY_ONLY
) ) {
638 DEBUG(8,("ldap_get_id_from_sid: Allocating new id\n"));
640 for (i
= 0; i
< LDAP_MAX_ALLOC_ID
; i
++) {
641 ret
= ldap_allocate_id(id
, *id_type
);
642 if ( NT_STATUS_IS_OK(ret
) )
646 if ( !NT_STATUS_IS_OK(ret
) ) {
647 DEBUG(0,("ldap_allocate_id: cannot acquire id lock!\n"));
651 DEBUG(10,("ldap_get_id_from_sid: Allocated new %cid [%ul]\n",
652 (*id_type
& ID_GROUPID
? 'g' : 'u'), (uint32
)id
->uid
));
654 ret
= ldap_set_mapping(sid
, *id
, *id_type
);
662 DEBUG(10,("ldap_get_id_from_sid: success\n"));
664 entry
= ldap_first_entry(ldap_state
.smbldap_state
->ldap_struct
, result
);
666 dn
= ldap_get_dn(ldap_state
.smbldap_state
->ldap_struct
, result
);
668 DEBUG(10, ("Found mapping entry at dn=%s, looking for %s\n", dn
, type
));
670 if ( smbldap_get_single_attribute(ldap_state
.smbldap_state
->ldap_struct
, entry
, type
, id_str
) )
672 if ( (*id_type
& ID_USERID
) )
673 id
->uid
= strtoul(id_str
, NULL
, 10);
675 id
->gid
= strtoul(id_str
, NULL
, 10);
682 free_attr_list( attr_list
);
684 ldap_msgfree(result
);
691 /***********************************************************************
692 This function cannot be called to modify a mapping, only set a new one
694 This takes a possible pointer to the existing entry for the UID or SID
696 ***********************************************************************/
698 static NTSTATUS
ldap_set_mapping_internals(const DOM_SID
*sid
, unid_t id
,
699 int id_type
, const char *ldap_dn
,
705 LDAPMod
**mods
= NULL
;
709 char **values
= NULL
;
712 sid_to_string( sid_string
, sid
);
715 DEBUG(10, ("Adding new IDMAP mapping on DN: %s", ldap_dn
));
716 ldap_op
= LDAP_MOD_REPLACE
;
717 pstrcpy( dn
, ldap_dn
);
719 ldap_op
= LDAP_MOD_ADD
;
720 pstr_sprintf(dn
, "%s=%s,%s", get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_SID
),
721 sid_string
, lp_ldap_idmap_suffix());
724 if ( id_type
& ID_USERID
)
725 fstrcpy( type
, get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_UIDNUMBER
) );
727 fstrcpy( type
, get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_GIDNUMBER
) );
729 pstr_sprintf(id_str
, "%lu", ((id_type
& ID_USERID
) ? (unsigned long)id
.uid
:
730 (unsigned long)id
.gid
));
733 values
= ldap_get_values(ldap_state
.smbldap_state
->ldap_struct
, entry
, "objectClass");
736 BOOL found_idmap
= False
;
737 for (i
=0; values
[i
]; i
++) {
738 if (StrCaseCmp(values
[i
], LDAP_OBJ_IDMAP_ENTRY
) == 0) {
744 smbldap_set_mod( &mods
, LDAP_MOD_ADD
,
745 "objectClass", LDAP_OBJ_IDMAP_ENTRY
);
747 smbldap_set_mod( &mods
, LDAP_MOD_ADD
,
748 "objectClass", LDAP_OBJ_IDMAP_ENTRY
);
751 smbldap_make_mod( ldap_state
.smbldap_state
->ldap_struct
,
752 entry
, &mods
, type
, id_str
);
754 smbldap_make_mod( ldap_state
.smbldap_state
->ldap_struct
,
756 get_attr_key2string(sidmap_attr_list
, LDAP_ATTR_SID
),
759 /* There may well be nothing at all to do */
764 smbldap_set_mod( &mods
, LDAP_MOD_ADD
,
765 "objectClass", LDAP_OBJ_SID_ENTRY
);
766 rc
= smbldap_add(ldap_state
.smbldap_state
, dn
, mods
);
768 case LDAP_MOD_REPLACE
:
769 rc
= smbldap_modify(ldap_state
.smbldap_state
, dn
, mods
);
773 ldap_mods_free( mods
, True
);
778 if (rc
!= LDAP_SUCCESS
) {
779 char *ld_error
= NULL
;
780 ldap_get_option(ldap_state
.smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
782 DEBUG(0,("ldap_set_mapping_internals: Failed to %s mapping from %s to %lu [%s]\n",
783 (ldap_op
== LDAP_MOD_ADD
) ? "add" : "replace",
784 sid_string
, (unsigned long)((id_type
& ID_USERID
) ? id
.uid
: id
.gid
), type
));
785 DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n", ld_error
? ld_error
: "(NULL)", ldap_err2string (rc
)));
786 return NT_STATUS_UNSUCCESSFUL
;
789 DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to %lu [%s]\n",
790 sid_string
, ((id_type
& ID_USERID
) ? (unsigned long)id
.uid
:
791 (unsigned long)id
.gid
), type
));
796 /***********************************************************************
797 This function cannot be called to modify a mapping, only set a new one
798 ***********************************************************************/
800 static NTSTATUS
ldap_set_mapping(const DOM_SID
*sid
, unid_t id
, int id_type
)
802 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
804 LDAPMessage
*result
= NULL
;
805 LDAPMessage
*entry
= NULL
;
807 const char *obj_class
;
808 const char *posix_obj_class
;
817 /* try for a samba user or group mapping (looking for an entry with a SID) */
818 if ( id_type
& ID_USERID
) {
819 obj_class
= LDAP_OBJ_SAMBASAMACCOUNT
;
820 suffix
= lp_ldap_suffix();
821 type
= get_attr_key2string( idpool_attr_list
, LDAP_ATTR_UIDNUMBER
);
822 posix_obj_class
= LDAP_OBJ_POSIXACCOUNT
;
823 fstr_sprintf(id_str
, "%lu", (unsigned long)id
.uid
);
826 obj_class
= LDAP_OBJ_GROUPMAP
;
827 suffix
= lp_ldap_group_suffix();
828 type
= get_attr_key2string( idpool_attr_list
, LDAP_ATTR_GIDNUMBER
);
829 posix_obj_class
= LDAP_OBJ_POSIXGROUP
;
830 fstr_sprintf(id_str
, "%lu", (unsigned long)id
.gid
);
833 sid_to_string(sid_str
, sid
);
836 "(&(|(objectClass=%s)(|(objectClass=%s)(objectClass=%s)))(%s=%s))"
837 "(&(objectClass=%s)(%s=%s))"
839 /* objectClasses that might contain a SID */
840 LDAP_OBJ_SID_ENTRY
, LDAP_OBJ_IDMAP_ENTRY
, obj_class
,
841 get_attr_key2string( sidmap_attr_list
, LDAP_ATTR_SID
),
844 /* objectClasses that might contain a Unix UID/GID */
846 /* Unix UID/GID specifier*/
851 attr_list
= get_attr_list( sidmap_attr_list
);
852 rc
= smbldap_search(ldap_state
.smbldap_state
, suffix
, LDAP_SCOPE_SUBTREE
,
853 filter
, attr_list
, 0, &result
);
854 free_attr_list( attr_list
);
856 if (rc
!= LDAP_SUCCESS
)
859 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
861 /* fall back to looking up an idmap entry if we didn't find anything under the idmap
862 user or group suffix */
865 entry
= ldap_first_entry(ldap_state
.smbldap_state
->ldap_struct
, result
);
867 dn
= ldap_get_dn(ldap_state
.smbldap_state
->ldap_struct
, result
);
868 DEBUG(10, ("Found partial mapping entry at dn=%s, looking for %s\n", dn
, type
));
870 ret
= ldap_set_mapping_internals(sid
, id
, id_type
, dn
, entry
);
873 } else if (count
> 1) {
874 DEBUG(0, ("Too many entries trying to find DN to attach ldap \n"));
878 ret
= ldap_set_mapping_internals(sid
, id
, id_type
, NULL
, NULL
);
882 ldap_msgfree(result
);
890 /**********************************************************************
891 Verify the sambaUnixIdPool entry in the directiry.
892 **********************************************************************/
894 static NTSTATUS
verify_idpool( void )
899 LDAPMessage
*result
= NULL
;
900 LDAPMod
**mods
= NULL
;
903 fstr_sprintf( filter
, "(objectclass=%s)", LDAP_OBJ_IDPOOL
);
905 attr_list
= get_attr_list( idpool_attr_list
);
906 rc
= smbldap_search(ldap_state
.smbldap_state
, lp_ldap_idmap_suffix(),
907 LDAP_SCOPE_SUBTREE
, filter
, attr_list
, 0, &result
);
908 free_attr_list ( attr_list
);
910 if (rc
!= LDAP_SUCCESS
)
911 return NT_STATUS_UNSUCCESSFUL
;
913 count
= ldap_count_entries(ldap_state
.smbldap_state
->ldap_struct
, result
);
916 DEBUG(0,("ldap_idmap_init: multiple entries returned from %s (base == %s)\n",
917 filter
, lp_ldap_idmap_suffix() ));
918 return NT_STATUS_UNSUCCESSFUL
;
920 else if (count
== 0) {
923 fstring uid_str
, gid_str
;
925 if ( !lp_idmap_uid(&luid
, &huid
) || !lp_idmap_gid( &lgid
, &hgid
) ) {
926 DEBUG(0,("ldap_idmap_init: idmap uid/gid parameters not specified\n"));
927 return NT_STATUS_UNSUCCESSFUL
;
930 fstr_sprintf( uid_str
, "%lu", (unsigned long)luid
);
931 fstr_sprintf( gid_str
, "%lu", (unsigned long)lgid
);
933 smbldap_set_mod( &mods
, LDAP_MOD_ADD
, "objectClass", LDAP_OBJ_IDPOOL
);
934 smbldap_set_mod( &mods
, LDAP_MOD_ADD
,
935 get_attr_key2string(idpool_attr_list
, LDAP_ATTR_UIDNUMBER
), uid_str
);
936 smbldap_set_mod( &mods
, LDAP_MOD_ADD
,
937 get_attr_key2string(idpool_attr_list
, LDAP_ATTR_GIDNUMBER
), gid_str
);
939 rc
= smbldap_modify(ldap_state
.smbldap_state
, lp_ldap_idmap_suffix(), mods
);
942 return ( rc
==LDAP_SUCCESS
? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
);
945 /*****************************************************************************
946 Initialise idmap database.
947 *****************************************************************************/
948 static NTSTATUS
ldap_idmap_init( char *params
)
952 ldap_state
.mem_ctx
= talloc_init("idmap_ldap");
953 if (!ldap_state
.mem_ctx
) {
954 return NT_STATUS_NO_MEMORY
;
957 /* assume location is the only parameter */
958 if (!NT_STATUS_IS_OK(nt_status
=
959 smbldap_init(ldap_state
.mem_ctx
, params
,
960 &ldap_state
.smbldap_state
))) {
961 talloc_destroy(ldap_state
.mem_ctx
);
965 /* see if the idmap suffix and sub entries exists */
967 nt_status
= verify_idpool();
968 if ( !NT_STATUS_IS_OK(nt_status
) )
974 /*****************************************************************************
976 *****************************************************************************/
978 static NTSTATUS
ldap_idmap_close(void)
981 smbldap_free_struct(&(ldap_state
).smbldap_state
);
982 talloc_destroy(ldap_state
.mem_ctx
);
984 DEBUG(5,("The connection to the LDAP server was closed\n"));
985 /* maybe free the results here --metze */
991 /* This function doesn't make as much sense in an LDAP world since the calling
992 node doesn't really control the ID ranges */
993 static void ldap_idmap_status(void)
995 DEBUG(0, ("LDAP IDMAP Status not available\n"));
998 static struct idmap_methods ldap_methods
= {
1002 ldap_get_sid_from_id
,
1003 ldap_get_id_from_sid
,
1010 NTSTATUS
idmap_ldap_init(void)
1012 return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION
, "ldap", &ldap_methods
);