2 Unix SMB/CIFS implementation.
6 Copyright (C) Tim Potter 2000
7 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
8 Copyright (C) Gerald Carter 2003
9 Copyright (C) Simo Sorce 2003-2007
10 Copyright (C) Michael Adam 2010
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 3 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
31 #include "../libcli/security/security.h"
32 #include "lib/util/smb_strtox.h"
33 #include "lib/global_contexts.h"
36 #define DBGC_CLASS DBGC_IDMAP
42 #include "passdb/pdb_ldap_schema.h"
44 struct idmap_ldap_context
{
45 struct smbldap_state
*smbldap_state
;
50 struct idmap_rw_ops
*rw_ops
;
53 #define CHECK_ALLOC_DONE(mem) do { \
55 DEBUG(0, ("Out of memory!\n")); \
56 ret = NT_STATUS_NO_MEMORY; \
60 /**********************************************************************
61 IDMAP ALLOC TDB BACKEND
62 **********************************************************************/
64 /*********************************************************************
65 ********************************************************************/
67 static NTSTATUS
get_credentials( TALLOC_CTX
*mem_ctx
,
68 struct smbldap_state
*ldap_state
,
69 struct idmap_domain
*dom
,
72 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
74 const char *tmp
= NULL
;
78 /* assume anonymous if we don't have a specified user */
80 tmp
= idmap_config_const_string(dom
->name
, "ldap_user_dn", NULL
);
83 secret
= idmap_fetch_secret("ldap", dom
->name
, tmp
);
85 DEBUG(0, ("get_credentials: Unable to fetch "
86 "auth credentials for %s in %s\n",
87 tmp
, (dom
==NULL
)?"ALLOC":dom
->name
));
88 ret
= NT_STATUS_ACCESS_DENIED
;
91 *dn
= talloc_strdup(mem_ctx
, tmp
);
92 CHECK_ALLOC_DONE(*dn
);
94 if (!fetch_ldap_pw(&user_dn
, &secret
)) {
95 DEBUG(2, ("get_credentials: Failed to lookup ldap "
96 "bind creds. Using anonymous connection.\n"));
100 *dn
= talloc_strdup(mem_ctx
, user_dn
);
101 SAFE_FREE( user_dn
);
102 CHECK_ALLOC_DONE(*dn
);
106 smbldap_set_creds(ldap_state
, anon
, *dn
, secret
);
110 BURN_FREE_STR(secret
);
116 /**********************************************************************
117 Verify the sambaUnixIdPool entry in the directory.
118 **********************************************************************/
120 static NTSTATUS
verify_idpool(struct idmap_domain
*dom
)
124 LDAPMessage
*result
= NULL
;
125 LDAPMod
**mods
= NULL
;
126 const char **attr_list
;
130 struct idmap_ldap_context
*ctx
;
132 ctx
= talloc_get_type(dom
->private_data
, struct idmap_ldap_context
);
134 mem_ctx
= talloc_new(ctx
);
135 if (mem_ctx
== NULL
) {
136 DEBUG(0, ("Out of memory!\n"));
137 return NT_STATUS_NO_MEMORY
;
140 filter
= talloc_asprintf(mem_ctx
, "(objectclass=%s)", LDAP_OBJ_IDPOOL
);
141 CHECK_ALLOC_DONE(filter
);
143 attr_list
= get_attr_list(mem_ctx
, idpool_attr_list
);
144 CHECK_ALLOC_DONE(attr_list
);
146 rc
= smbldap_search(ctx
->smbldap_state
,
154 if (rc
!= LDAP_SUCCESS
) {
155 DEBUG(1, ("Unable to verify the idpool, "
156 "cannot continue initialization!\n"));
157 return NT_STATUS_UNSUCCESSFUL
;
160 count
= ldap_count_entries(smbldap_get_ldap(ctx
->smbldap_state
),
163 ldap_msgfree(result
);
166 DEBUG(0,("Multiple entries returned from %s (base == %s)\n",
167 filter
, ctx
->suffix
));
168 ret
= NT_STATUS_UNSUCCESSFUL
;
171 else if (count
== 0) {
172 char *uid_str
, *gid_str
;
174 uid_str
= talloc_asprintf(mem_ctx
, "%lu",
175 (unsigned long)dom
->low_id
);
176 gid_str
= talloc_asprintf(mem_ctx
, "%lu",
177 (unsigned long)dom
->low_id
);
179 smbldap_set_mod(&mods
, LDAP_MOD_ADD
,
180 "objectClass", LDAP_OBJ_IDPOOL
);
181 smbldap_set_mod(&mods
, LDAP_MOD_ADD
,
182 get_attr_key2string(idpool_attr_list
,
183 LDAP_ATTR_UIDNUMBER
),
185 smbldap_set_mod(&mods
, LDAP_MOD_ADD
,
186 get_attr_key2string(idpool_attr_list
,
187 LDAP_ATTR_GIDNUMBER
),
190 rc
= smbldap_modify(ctx
->smbldap_state
,
193 ldap_mods_free(mods
, True
);
195 ret
= NT_STATUS_UNSUCCESSFUL
;
200 ret
= (rc
== LDAP_SUCCESS
)?NT_STATUS_OK
:NT_STATUS_UNSUCCESSFUL
;
202 talloc_free(mem_ctx
);
206 /********************************
207 Allocate a new uid or gid
208 ********************************/
210 static NTSTATUS
idmap_ldap_allocate_id_internal(struct idmap_domain
*dom
,
214 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
215 int rc
= LDAP_SERVER_DOWN
;
217 LDAPMessage
*result
= NULL
;
218 LDAPMessage
*entry
= NULL
;
219 LDAPMod
**mods
= NULL
;
223 const char *dn
= NULL
;
224 const char **attr_list
;
226 struct idmap_ldap_context
*ctx
;
229 /* Only do query if we are online */
230 if (idmap_is_offline()) {
231 return NT_STATUS_FILE_IS_OFFLINE
;
234 ctx
= talloc_get_type(dom
->private_data
, struct idmap_ldap_context
);
236 mem_ctx
= talloc_new(ctx
);
238 DEBUG(0, ("Out of memory!\n"));
239 return NT_STATUS_NO_MEMORY
;
246 type
= get_attr_key2string(idpool_attr_list
,
247 LDAP_ATTR_UIDNUMBER
);
251 type
= get_attr_key2string(idpool_attr_list
,
252 LDAP_ATTR_GIDNUMBER
);
257 * This is not supported here yet and
258 * already handled in idmap_rw_new_mapping()
261 case ID_TYPE_NOT_SPECIFIED
:
263 * This is handled in idmap_rw_new_mapping()
267 DEBUG(2, ("Invalid ID type (0x%x)\n", xid
->type
));
268 return NT_STATUS_INVALID_PARAMETER
;
271 filter
= talloc_asprintf(mem_ctx
, "(objectClass=%s)", LDAP_OBJ_IDPOOL
);
272 CHECK_ALLOC_DONE(filter
);
274 attr_list
= get_attr_list(mem_ctx
, idpool_attr_list
);
275 CHECK_ALLOC_DONE(attr_list
);
277 DEBUG(10, ("Search of the id pool (filter: %s)\n", filter
));
279 rc
= smbldap_search(ctx
->smbldap_state
,
281 LDAP_SCOPE_SUBTREE
, filter
,
282 attr_list
, 0, &result
);
284 if (rc
!= LDAP_SUCCESS
) {
285 DEBUG(0,("%s object not found\n", LDAP_OBJ_IDPOOL
));
289 smbldap_talloc_autofree_ldapmsg(mem_ctx
, result
);
291 count
= ldap_count_entries(smbldap_get_ldap(ctx
->smbldap_state
),
294 DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL
));
298 entry
= ldap_first_entry(smbldap_get_ldap(ctx
->smbldap_state
), result
);
300 dn
= smbldap_talloc_dn(mem_ctx
,
301 smbldap_get_ldap(ctx
->smbldap_state
),
307 id_str
= smbldap_talloc_single_attribute(
308 smbldap_get_ldap(ctx
->smbldap_state
),
309 entry
, type
, mem_ctx
);
310 if (id_str
== NULL
) {
311 DEBUG(0,("%s attribute not found\n", type
));
312 ret
= NT_STATUS_UNSUCCESSFUL
;
316 xid
->id
= smb_strtoul(id_str
, NULL
, 10, &error
, SMB_STR_STANDARD
);
318 ret
= NT_STATUS_UNSUCCESSFUL
;
322 /* make sure we still have room to grow */
326 if (xid
->id
> dom
->high_id
) {
327 DEBUG(0,("Cannot allocate uid above %lu!\n",
328 (unsigned long)dom
->high_id
));
334 if (xid
->id
> dom
->high_id
) {
335 DEBUG(0,("Cannot allocate gid above %lu!\n",
336 (unsigned long)dom
->high_id
));
346 new_id_str
= talloc_asprintf(mem_ctx
, "%lu", (unsigned long)xid
->id
+ 1);
348 DEBUG(0,("Out of memory\n"));
349 ret
= NT_STATUS_NO_MEMORY
;
353 smbldap_set_mod(&mods
, LDAP_MOD_DELETE
, type
, id_str
);
354 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, type
, new_id_str
);
357 DEBUG(0,("smbldap_set_mod() failed.\n"));
361 DEBUG(10, ("Try to atomically increment the id (%s -> %s)\n",
362 id_str
, new_id_str
));
364 rc
= smbldap_modify(ctx
->smbldap_state
, dn
, mods
);
366 ldap_mods_free(mods
, True
);
368 if (rc
!= LDAP_SUCCESS
) {
369 DEBUG(1,("Failed to allocate new %s. "
370 "smbldap_modify() failed.\n", type
));
377 talloc_free(mem_ctx
);
382 * Allocate a new unix-ID.
383 * For now this is for the default idmap domain only.
384 * Should be extended later on.
386 static NTSTATUS
idmap_ldap_allocate_id(struct idmap_domain
*dom
,
391 if (!strequal(dom
->name
, "*")) {
392 DEBUG(3, ("idmap_ldap_allocate_id: "
393 "Refusing allocation of a new unixid for domain'%s'. "
394 "This is only supported for the default "
397 return NT_STATUS_NOT_IMPLEMENTED
;
400 ret
= idmap_ldap_allocate_id_internal(dom
, id
);
406 /**********************************************************************
407 IDMAP MAPPING LDAP BACKEND
408 **********************************************************************/
410 static int idmap_ldap_close_destructor(struct idmap_ldap_context
*ctx
)
412 smbldap_free_struct(&ctx
->smbldap_state
);
413 DEBUG(5,("The connection to the LDAP server was closed\n"));
414 /* maybe free the results here --metze */
419 /********************************
420 Initialise idmap database.
421 ********************************/
423 static NTSTATUS
idmap_ldap_set_mapping(struct idmap_domain
*dom
,
424 const struct id_map
*map
);
426 static NTSTATUS
idmap_ldap_db_init(struct idmap_domain
*dom
)
429 struct idmap_ldap_context
*ctx
= NULL
;
430 const char *tmp
= NULL
;
432 /* Only do init if we are online */
433 if (idmap_is_offline()) {
434 return NT_STATUS_FILE_IS_OFFLINE
;
437 ctx
= talloc_zero(dom
, struct idmap_ldap_context
);
439 DEBUG(0, ("Out of memory!\n"));
440 return NT_STATUS_NO_MEMORY
;
443 tmp
= idmap_config_const_string(dom
->name
, "ldap_url", NULL
);
446 DEBUG(1, ("ERROR: missing idmap ldap url\n"));
447 ret
= NT_STATUS_UNSUCCESSFUL
;
451 ctx
->url
= talloc_strdup(ctx
, tmp
);
453 trim_char(ctx
->url
, '\"', '\"');
455 tmp
= idmap_config_const_string(dom
->name
, "ldap_base_dn", NULL
);
456 if ( ! tmp
|| ! *tmp
) {
457 tmp
= lp_ldap_idmap_suffix(talloc_tos());
459 DEBUG(1, ("ERROR: missing idmap ldap suffix\n"));
460 ret
= NT_STATUS_UNSUCCESSFUL
;
465 ctx
->suffix
= talloc_strdup(ctx
, tmp
);
466 CHECK_ALLOC_DONE(ctx
->suffix
);
468 ctx
->rw_ops
= talloc_zero(ctx
, struct idmap_rw_ops
);
469 CHECK_ALLOC_DONE(ctx
->rw_ops
);
471 ctx
->rw_ops
->get_new_id
= idmap_ldap_allocate_id_internal
;
472 ctx
->rw_ops
->set_mapping
= idmap_ldap_set_mapping
;
474 /* get_credentials deals with setting up creds */
476 ret
= smbldap_init(ctx
, global_event_context(), ctx
->url
,
477 false, NULL
, NULL
, &ctx
->smbldap_state
);
478 if (!NT_STATUS_IS_OK(ret
)) {
479 DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n", ctx
->url
));
483 ret
= get_credentials( ctx
, ctx
->smbldap_state
,
484 dom
, &ctx
->user_dn
);
485 if ( !NT_STATUS_IS_OK(ret
) ) {
486 DEBUG(1,("idmap_ldap_db_init: Failed to get connection "
487 "credentials (%s)\n", nt_errstr(ret
)));
492 * Set the destructor on the context, so that resources are
493 * properly freed when the context is released.
495 talloc_set_destructor(ctx
, idmap_ldap_close_destructor
);
497 dom
->private_data
= ctx
;
499 ret
= verify_idpool(dom
);
500 if (!NT_STATUS_IS_OK(ret
)) {
501 DEBUG(1, ("idmap_ldap_db_init: failed to verify ID pool (%s)\n",
518 /* TODO: change this: This function cannot be called to modify a mapping,
519 * only set a new one */
521 static NTSTATUS
idmap_ldap_set_mapping(struct idmap_domain
*dom
,
522 const struct id_map
*map
)
526 struct idmap_ldap_context
*ctx
;
527 LDAPMessage
*entry
= NULL
;
528 LDAPMod
**mods
= NULL
;
531 struct dom_sid_buf sid
;
535 /* Only do query if we are online */
536 if (idmap_is_offline()) {
537 return NT_STATUS_FILE_IS_OFFLINE
;
540 ctx
= talloc_get_type(dom
->private_data
, struct idmap_ldap_context
);
542 switch(map
->xid
.type
) {
544 type
= get_attr_key2string(sidmap_attr_list
,
545 LDAP_ATTR_UIDNUMBER
);
549 type
= get_attr_key2string(sidmap_attr_list
,
550 LDAP_ATTR_GIDNUMBER
);
554 return NT_STATUS_INVALID_PARAMETER
;
557 memctx
= talloc_new(ctx
);
559 DEBUG(0, ("Out of memory!\n"));
560 return NT_STATUS_NO_MEMORY
;
563 id_str
= talloc_asprintf(memctx
, "%lu", (unsigned long)map
->xid
.id
);
564 CHECK_ALLOC_DONE(id_str
);
566 dn
= talloc_asprintf(memctx
, "%s=%s,%s",
567 get_attr_key2string(sidmap_attr_list
, LDAP_ATTR_SID
),
568 dom_sid_str_buf(map
->sid
, &sid
),
570 CHECK_ALLOC_DONE(dn
);
572 smbldap_set_mod(&mods
, LDAP_MOD_ADD
,
573 "objectClass", LDAP_OBJ_IDMAP_ENTRY
);
575 smbldap_make_mod(smbldap_get_ldap(ctx
->smbldap_state
),
576 entry
, &mods
, type
, id_str
);
578 smbldap_make_mod(smbldap_get_ldap(ctx
->smbldap_state
), entry
, &mods
,
579 get_attr_key2string(sidmap_attr_list
, LDAP_ATTR_SID
),
583 DEBUG(2, ("ERROR: No mods?\n"));
584 ret
= NT_STATUS_UNSUCCESSFUL
;
588 /* TODO: remove conflicting mappings! */
590 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "objectClass", LDAP_OBJ_SID_ENTRY
);
592 DEBUG(10, ("Set DN %s (%s -> %s)\n", dn
, sid
.buf
, id_str
));
594 rc
= smbldap_add(ctx
->smbldap_state
, dn
, mods
);
595 ldap_mods_free(mods
, True
);
597 if (rc
!= LDAP_SUCCESS
) {
598 char *ld_error
= NULL
;
599 ldap_get_option(smbldap_get_ldap(ctx
->smbldap_state
),
600 LDAP_OPT_ERROR_STRING
, &ld_error
);
601 DEBUG(0,("ldap_set_mapping_internals: Failed to add %s to %lu "
602 "mapping [%s]\n", sid
.buf
,
603 (unsigned long)map
->xid
.id
, type
));
604 DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n",
605 ld_error
? ld_error
: "(NULL)", ldap_err2string (rc
)));
607 ldap_memfree(ld_error
);
609 ret
= NT_STATUS_UNSUCCESSFUL
;
613 DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to "
614 "%lu [%s]\n", sid
.buf
, (unsigned long)map
->xid
.id
, type
));
624 * Create a new mapping for an unmapped SID, also allocating a new ID.
625 * If possible, this should be run inside a transaction to make the
628 static NTSTATUS
idmap_ldap_new_mapping(struct idmap_domain
*dom
, struct id_map
*map
)
631 struct idmap_ldap_context
*ctx
;
633 ctx
= talloc_get_type(dom
->private_data
, struct idmap_ldap_context
);
635 ret
= idmap_rw_new_mapping(dom
, ctx
->rw_ops
, map
);
640 /**********************************
641 lookup a set of unix ids.
642 **********************************/
644 static NTSTATUS
idmap_ldap_unixids_to_sids(struct idmap_domain
*dom
,
649 struct idmap_ldap_context
*ctx
;
650 LDAPMessage
*result
= NULL
;
651 LDAPMessage
*entry
= NULL
;
652 const char *uidNumber
;
653 const char *gidNumber
;
654 const char **attr_list
;
664 /* Only do query if we are online */
665 if (idmap_is_offline()) {
666 return NT_STATUS_FILE_IS_OFFLINE
;
669 ctx
= talloc_get_type(dom
->private_data
, struct idmap_ldap_context
);
671 memctx
= talloc_new(ctx
);
673 DEBUG(0, ("Out of memory!\n"));
674 return NT_STATUS_NO_MEMORY
;
677 uidNumber
= get_attr_key2string(idpool_attr_list
, LDAP_ATTR_UIDNUMBER
);
678 gidNumber
= get_attr_key2string(idpool_attr_list
, LDAP_ATTR_GIDNUMBER
);
680 attr_list
= get_attr_list(memctx
, sidmap_attr_list
);
683 /* if we are requested just one mapping use the simple filter */
685 filter
= talloc_asprintf(memctx
, "(&(objectClass=%s)(%s=%lu))",
686 LDAP_OBJ_IDMAP_ENTRY
,
687 (ids
[0]->xid
.type
==ID_TYPE_UID
)?uidNumber
:gidNumber
,
688 (unsigned long)ids
[0]->xid
.id
);
689 CHECK_ALLOC_DONE(filter
);
690 DEBUG(10, ("Filter: [%s]\n", filter
));
692 /* multiple mappings */
696 for (i
= 0; ids
[i
]; i
++) {
697 ids
[i
]->status
= ID_UNKNOWN
;
704 filter
= talloc_asprintf(memctx
,
705 "(&(objectClass=%s)(|",
706 LDAP_OBJ_IDMAP_ENTRY
);
707 CHECK_ALLOC_DONE(filter
);
710 for (i
= 0; (i
< IDMAP_LDAP_MAX_IDS
) && ids
[idx
]; i
++, idx
++) {
711 filter
= talloc_asprintf_append_buffer(filter
, "(%s=%lu)",
712 (ids
[idx
]->xid
.type
==ID_TYPE_UID
)?uidNumber
:gidNumber
,
713 (unsigned long)ids
[idx
]->xid
.id
);
714 CHECK_ALLOC_DONE(filter
);
716 filter
= talloc_asprintf_append_buffer(filter
, "))");
717 CHECK_ALLOC_DONE(filter
);
718 DEBUG(10, ("Filter: [%s]\n", filter
));
724 rc
= smbldap_search(ctx
->smbldap_state
, ctx
->suffix
, LDAP_SCOPE_SUBTREE
,
725 filter
, attr_list
, 0, &result
);
727 if (rc
!= LDAP_SUCCESS
) {
728 DEBUG(3,("Failure looking up ids (%s)\n", ldap_err2string(rc
)));
729 ret
= NT_STATUS_UNSUCCESSFUL
;
733 count
= ldap_count_entries(smbldap_get_ldap(ctx
->smbldap_state
),
737 DEBUG(10, ("NO SIDs found\n"));
740 for (i
= 0; i
< count
; i
++) {
746 struct dom_sid_buf buf
;
748 if (i
== 0) { /* first entry */
749 entry
= ldap_first_entry(
750 smbldap_get_ldap(ctx
->smbldap_state
), result
);
751 } else { /* following ones */
752 entry
= ldap_next_entry(
753 smbldap_get_ldap(ctx
->smbldap_state
), entry
);
756 DEBUG(2, ("ERROR: Unable to fetch ldap entries "
761 /* first check if the SID is present */
762 sidstr
= smbldap_talloc_single_attribute(
763 smbldap_get_ldap(ctx
->smbldap_state
),
764 entry
, LDAP_ATTRIBUTE_SID
, memctx
);
765 if ( ! sidstr
) { /* no sid, skip entry */
766 DEBUG(2, ("WARNING SID not found on entry\n"));
770 /* now try to see if it is a uid, if not try with a gid
771 * (gid is more common, but in case both uidNumber and
772 * gidNumber are returned the SID is mapped to the uid
775 tmp
= smbldap_talloc_single_attribute(
776 smbldap_get_ldap(ctx
->smbldap_state
),
777 entry
, uidNumber
, memctx
);
780 tmp
= smbldap_talloc_single_attribute(
781 smbldap_get_ldap(ctx
->smbldap_state
),
782 entry
, gidNumber
, memctx
);
784 if ( ! tmp
) { /* wow very strange entry, how did it match ? */
785 DEBUG(5, ("Improbable match on (%s), no uidNumber, "
786 "nor gidNumber returned\n", sidstr
));
791 id
= smb_strtoul(tmp
, NULL
, 10, &error
, SMB_STR_STANDARD
);
794 DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
796 dom
->low_id
, dom
->high_id
));
801 if (!idmap_unix_id_is_in_range(id
, dom
)) {
802 DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
804 dom
->low_id
, dom
->high_id
));
809 map
= idmap_find_map_by_id(&ids
[bidx
], type
, id
);
811 DEBUG(2, ("WARNING: couldn't match sid (%s) "
812 "with requested ids\n", sidstr
));
817 if ( ! string_to_sid(map
->sid
, sidstr
)) {
818 DEBUG(2, ("ERROR: Invalid SID on entry\n"));
823 if (map
->status
== ID_MAPPED
) {
824 DEBUG(1, ("WARNING: duplicate %s mapping in LDAP. "
825 "overwriting mapping %u -> %s with %u -> %s\n",
826 (type
== ID_TYPE_UID
) ? "UID" : "GID",
828 dom_sid_str_buf(map
->sid
, &buf
),
836 map
->status
= ID_MAPPED
;
838 DEBUG(10, ("Mapped %s -> %lu (%d)\n",
839 dom_sid_str_buf(map
->sid
, &buf
),
840 (unsigned long)map
->xid
.id
, map
->xid
.type
));
843 /* free the ldap results */
845 ldap_msgfree(result
);
849 if (multi
&& ids
[idx
]) { /* still some values to map */
855 /* mark all unknown/expired ones as unmapped */
856 for (i
= 0; ids
[i
]; i
++) {
857 if (ids
[i
]->status
!= ID_MAPPED
)
858 ids
[i
]->status
= ID_UNMAPPED
;
866 /**********************************
867 lookup a set of sids.
868 **********************************/
870 static NTSTATUS
idmap_ldap_sids_to_unixids(struct idmap_domain
*dom
,
873 LDAPMessage
*entry
= NULL
;
876 struct idmap_ldap_context
*ctx
;
877 LDAPMessage
*result
= NULL
;
878 const char *uidNumber
;
879 const char *gidNumber
;
880 const char **attr_list
;
883 size_t num_required
= 0;
890 /* Only do query if we are online */
891 if (idmap_is_offline()) {
892 return NT_STATUS_FILE_IS_OFFLINE
;
895 ctx
= talloc_get_type(dom
->private_data
, struct idmap_ldap_context
);
897 memctx
= talloc_new(ctx
);
899 DEBUG(0, ("Out of memory!\n"));
900 return NT_STATUS_NO_MEMORY
;
903 uidNumber
= get_attr_key2string(idpool_attr_list
, LDAP_ATTR_UIDNUMBER
);
904 gidNumber
= get_attr_key2string(idpool_attr_list
, LDAP_ATTR_GIDNUMBER
);
906 attr_list
= get_attr_list(memctx
, sidmap_attr_list
);
909 struct dom_sid_buf buf
;
910 /* if we are requested just one mapping use the simple filter */
912 filter
= talloc_asprintf(memctx
, "(&(objectClass=%s)(%s=%s))",
913 LDAP_OBJ_IDMAP_ENTRY
,
915 dom_sid_str_buf(ids
[0]->sid
, &buf
));
916 CHECK_ALLOC_DONE(filter
);
917 DEBUG(10, ("Filter: [%s]\n", filter
));
919 /* multiple mappings */
923 for (i
= 0; ids
[i
]; i
++) {
924 ids
[i
]->status
= ID_UNKNOWN
;
931 filter
= talloc_asprintf(memctx
,
932 "(&(objectClass=%s)(|",
933 LDAP_OBJ_IDMAP_ENTRY
);
934 CHECK_ALLOC_DONE(filter
);
937 for (i
= 0; (i
< IDMAP_LDAP_MAX_IDS
) && ids
[idx
]; i
++, idx
++) {
938 struct dom_sid_buf buf
;
939 filter
= talloc_asprintf_append_buffer(filter
, "("LDAP_ATTRIBUTE_SID
"=%s)",
940 dom_sid_str_buf(ids
[idx
]->sid
, &buf
));
941 CHECK_ALLOC_DONE(filter
);
943 filter
= talloc_asprintf_append_buffer(filter
, "))");
944 CHECK_ALLOC_DONE(filter
);
945 DEBUG(10, ("Filter: [%s]\n", filter
));
951 rc
= smbldap_search(ctx
->smbldap_state
, ctx
->suffix
, LDAP_SCOPE_SUBTREE
,
952 filter
, attr_list
, 0, &result
);
954 if (rc
!= LDAP_SUCCESS
) {
955 DEBUG(3,("Failure looking up sids (%s)\n",
956 ldap_err2string(rc
)));
957 ret
= NT_STATUS_UNSUCCESSFUL
;
961 count
= ldap_count_entries(smbldap_get_ldap(ctx
->smbldap_state
),
965 DEBUG(10, ("NO SIDs found\n"));
968 for (i
= 0; i
< count
; i
++) {
974 struct dom_sid_buf buf
;
978 if (i
== 0) { /* first entry */
979 entry
= ldap_first_entry(
980 smbldap_get_ldap(ctx
->smbldap_state
), result
);
981 } else { /* following ones */
982 entry
= ldap_next_entry(
983 smbldap_get_ldap(ctx
->smbldap_state
), entry
);
986 DEBUG(2, ("ERROR: Unable to fetch ldap entries "
991 /* first check if the SID is present */
992 sidstr
= smbldap_talloc_single_attribute(
993 smbldap_get_ldap(ctx
->smbldap_state
),
994 entry
, LDAP_ATTRIBUTE_SID
, memctx
);
995 if ( ! sidstr
) { /* no sid ??, skip entry */
996 DEBUG(2, ("WARNING SID not found on entry\n"));
1000 if ( ! string_to_sid(&sid
, sidstr
)) {
1001 DEBUG(2, ("ERROR: Invalid SID on entry\n"));
1002 TALLOC_FREE(sidstr
);
1006 map
= idmap_find_map_by_sid(&ids
[bidx
], &sid
);
1008 DEBUG(2, ("WARNING: couldn't find entry sid (%s) "
1009 "in ids\n", sidstr
));
1010 TALLOC_FREE(sidstr
);
1014 /* now try to see if it is a uid, if not try with a gid
1015 * (gid is more common, but in case both uidNumber and
1016 * gidNumber are returned the SID is mapped to the uid
1019 tmp
= smbldap_talloc_single_attribute(
1020 smbldap_get_ldap(ctx
->smbldap_state
),
1021 entry
, uidNumber
, memctx
);
1024 tmp
= smbldap_talloc_single_attribute(
1025 smbldap_get_ldap(ctx
->smbldap_state
),
1026 entry
, gidNumber
, memctx
);
1028 if ( ! tmp
) { /* no ids ?? */
1029 DEBUG(5, ("no uidNumber, "
1030 "nor gidNumber attributes found\n"));
1031 TALLOC_FREE(sidstr
);
1035 id
= smb_strtoul(tmp
, NULL
, 10, &error
, SMB_STR_STANDARD
);
1038 DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
1040 dom
->low_id
, dom
->high_id
));
1041 TALLOC_FREE(sidstr
);
1045 if (error
!= 0 || !idmap_unix_id_is_in_range(id
, dom
)) {
1046 DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
1048 dom
->low_id
, dom
->high_id
));
1049 TALLOC_FREE(sidstr
);
1053 if (map
->status
== ID_MAPPED
) {
1054 DEBUG(1, ("WARNING: duplicate %s mapping in LDAP. "
1055 "overwriting mapping %s -> %u with %s -> %u\n",
1056 (type
== ID_TYPE_UID
) ? "UID" : "GID",
1057 sidstr
, map
->xid
.id
, sidstr
, id
));
1060 TALLOC_FREE(sidstr
);
1063 map
->xid
.type
= type
;
1065 map
->status
= ID_MAPPED
;
1067 DEBUG(10, ("Mapped %s -> %lu (%d)\n",
1068 dom_sid_str_buf(map
->sid
, &buf
),
1069 (unsigned long)map
->xid
.id
,
1073 /* free the ldap results */
1075 ldap_msgfree(result
);
1079 if (multi
&& ids
[idx
]) { /* still some values to map */
1084 * try to create new mappings for unmapped sids
1086 for (i
= 0; ids
[i
]; i
++) {
1087 if (ids
[i
]->status
!= ID_MAPPED
) {
1088 ids
[i
]->status
= ID_UNMAPPED
;
1089 if (ids
[i
]->sid
!= NULL
) {
1090 ret
= idmap_ldap_new_mapping(dom
, ids
[i
]);
1091 DBG_DEBUG("idmap_ldap_new_mapping returned %s\n",
1093 if (NT_STATUS_EQUAL(ret
, STATUS_SOME_UNMAPPED
)) {
1094 if (ids
[i
]->status
== ID_REQUIRE_TYPE
) {
1099 if (!NT_STATUS_IS_OK(ret
)) {
1101 * If we can't create
1102 * a new mapping it's unlikely
1103 * that it will work for the
1113 if (num_required
> 0) {
1114 ret
= STATUS_SOME_UNMAPPED
;
1118 talloc_free(memctx
);
1122 /**********************************
1123 Close the idmap ldap instance
1124 **********************************/
1126 static const struct idmap_methods idmap_ldap_methods
= {
1128 .init
= idmap_ldap_db_init
,
1129 .unixids_to_sids
= idmap_ldap_unixids_to_sids
,
1130 .sids_to_unixids
= idmap_ldap_sids_to_unixids
,
1131 .allocate_id
= idmap_ldap_allocate_id
,
1134 NTSTATUS
idmap_ldap_init(TALLOC_CTX
*);
1135 NTSTATUS
idmap_ldap_init(TALLOC_CTX
*ctx
)
1137 return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION
, "ldap",
1138 &idmap_ldap_methods
);