From cc188cb6f8cf427d3a2d4ecaef7820cf83272e93 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 24 Jun 2016 18:31:45 +0200 Subject: [PATCH 1/4] winbindd/idmap_rfc2307: fix a crash map->map is NULL if lookupsid failed. Bug: https://bugzilla.samba.org/show_bug.cgi?id=11961 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher (cherry picked from commit 5e346af078847512e86755a4634583a8a5178c0e) --- source3/winbindd/idmap_rfc2307.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source3/winbindd/idmap_rfc2307.c b/source3/winbindd/idmap_rfc2307.c index e9d04c3..6fd89d7 100644 --- a/source3/winbindd/idmap_rfc2307.c +++ b/source3/winbindd/idmap_rfc2307.c @@ -689,9 +689,7 @@ again: break; default: - DEBUG(10, ("Nothing to do for SID %s, " - "previous name lookup failed\n", - sid_string_dbg(map->map->sid))); + break; } if (!fltr_usr || !fltr_grp) { -- 2.5.0 From 2d1893780924d9c408efdd1932c1af65688b646c Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 24 Jun 2016 15:16:42 +0200 Subject: [PATCH 2/4] winbindd: in wb_lookupsids return domain name if we have it When doing a SID to xid mapping for an unknown SID, the idmap child gets passed a lsa_RefDomainList with an empty domain name (ie ""). This is coming from LsaLookupSids() and causes the mapping request to end up in the default idmap domain. Example request with domain name "": wbint_Sids2UnixIDs: struct wbint_Sids2UnixIDs in: struct wbint_Sids2UnixIDs domains : * domains: struct lsa_RefDomainList count : 0x00000001 (1) domains : * domains: ARRAY(1) domains: struct lsa_DomainInfo name: struct lsa_StringLarge length : 0x0000 (0) size : 0x0002 (2) string : * string : '' sid : * sid : S-1-5-21-3152989960-574718769-2188965058 max_size : 0x00000020 (32) ids : * ids: struct wbint_TransIDArray num_ids : 0x00000001 (1) ids: ARRAY(1) ids: struct wbint_TransID type : ID_TYPE_NOT_SPECIFIED (0) domain_index : 0x00000000 (0) rid : 0x000029aa (66666) xid: struct unixid id : 0xffffffff (4294967295) type : ID_TYPE_NOT_SPECIFIED (0) In _wbint_Sids2UnixIDs() we call idmap_find_domain_with_sid() with the domain name "" and this triggers use of the default idmap domain which in case of idmap_autorid will allocate an id from a idmap_autorid range. If we know the domain, ensure we return it for SIDs were the SID was not found but the domain of the SID was found. Callers like sids2xids depend on the domain name and returning an empty string "" for valid domain can trigger unwanted idmap range allocations. Bug: https://bugzilla.samba.org/show_bug.cgi?id=11961 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher (cherry picked from commit 9be918116e356c358ef77cc2933e471090088293) --- source3/winbindd/wb_lookupsids.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/source3/winbindd/wb_lookupsids.c b/source3/winbindd/wb_lookupsids.c index 8c5f9db..2480547 100644 --- a/source3/winbindd/wb_lookupsids.c +++ b/source3/winbindd/wb_lookupsids.c @@ -72,6 +72,8 @@ struct wb_lookupsids_state { * wbint_LookupSid. Preallocated with num_sids. */ uint32_t *single_sids; + /* Pointer into the "domains" array above*/ + struct wb_lookupsids_domain **single_domains; uint32_t num_single_sids; uint32_t single_sids_done; @@ -127,6 +129,12 @@ struct tevent_req *wb_lookupsids_send(TALLOC_CTX *mem_ctx, if (tevent_req_nomem(state->single_sids, req)) { return tevent_req_post(req, ev); } + state->single_domains = talloc_zero_array(state, + struct wb_lookupsids_domain *, + num_sids); + if (tevent_req_nomem(state->single_domains, req)) { + return tevent_req_post(req, ev); + } state->res_domains = talloc_zero(state, struct lsa_RefDomainList); if (tevent_req_nomem(state->res_domains, req)) { @@ -455,6 +463,7 @@ static void wb_lookupsids_done(struct tevent_req *subreq) state->single_sids[state->num_single_sids] = res_sid_index; + state->single_domains[state->num_single_sids] = d; state->num_single_sids += 1; } state->domains_done += 1; @@ -514,9 +523,28 @@ static void wb_lookupsids_single_done(struct tevent_req *subreq) &domain_name, &name); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { + struct wb_lookupsids_domain *wb_domain; + const char *tmpname; + type = SID_NAME_UNKNOWN; - domain_name = talloc_strdup(talloc_tos(), ""); + wb_domain = state->single_domains[state->single_sids_done]; + if (wb_domain != NULL) { + /* + * If the lookupsid failed because the rid not + * found in a domain and we have a reference + * to the lookup domain, use the name from + * there. + * + * Callers like sid2xid will use the domain + * name in the idmap backend to figure out + * which domain to use in processing. + */ + tmpname = wb_domain->domain->name; + } else { + tmpname = ""; + } + domain_name = talloc_strdup(talloc_tos(), tmpname); if (tevent_req_nomem(domain_name, req)) { return; } -- 2.5.0 From 0dfe52b060ef339bf9910f9ec94c146c1e1b2df9 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 24 Jun 2016 18:33:01 +0200 Subject: [PATCH 3/4] selftest: make autorid the default idmap backend in admember_rfc2307 This is needed for a new test in the next commit. Exisiting tests aren't affected by this, at least a private autobuild passed with this change. Bug: https://bugzilla.samba.org/show_bug.cgi?id=11961 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher (cherry picked from commit aa54fa4e88cc80bc7841beba3a5561ad2c83dc80) --- selftest/target/Samba3.pm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 9e5d699..319d00b 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -460,6 +460,9 @@ sub setup_admember_rfc2307($$$$) server signing = on workgroup = $dcvars->{DOMAIN} realm = $dcvars->{REALM} + idmap config * : backend = autorid + idmap config * : range = 1000000-1999999 + idmap config * : rangesize = 100000 idmap config $dcvars->{DOMAIN} : backend = rfc2307 idmap config $dcvars->{DOMAIN} : range = 2000000-2999999 idmap config $dcvars->{DOMAIN} : ldap_server = ad -- 2.5.0 From a14306b3184c9dc9d3d1d13da0a84bf260190e30 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Sun, 12 Jun 2016 19:03:11 +0200 Subject: [PATCH 4/4] selftest: test idmap backend id allocation for unknown SIDS If an SID is is not found becaues the RID doesn't exist in a domain and the domain is configured to use a non-allocating idmap backend like idmap_ad or idmap_rfc2307, winbindd must not return a mapping for the SID. Bug: https://bugzilla.samba.org/show_bug.cgi?id=11961 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher (cherry picked from commit 2a322a7671c9ffd0dd600142dd76b5b51a67e185) --- nsswitch/tests/test_idmap_nss.sh | 41 ++++++++++++++++++++++++++++++++++++++++ source3/selftest/tests.py | 4 +++- 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100755 nsswitch/tests/test_idmap_nss.sh diff --git a/nsswitch/tests/test_idmap_nss.sh b/nsswitch/tests/test_idmap_nss.sh new file mode 100755 index 0000000..999bccb --- /dev/null +++ b/nsswitch/tests/test_idmap_nss.sh @@ -0,0 +1,41 @@ +#!/bin/sh +# Test id mapping with unknown SID and non-allocating idmap backend +if [ $# -lt 1 ]; then + echo Usage: $0 DOMAIN + exit 1 +fi + +DOMAIN="$1" + +wbinfo="$VALGRIND $BINDIR/wbinfo" + +failed=0 + +. `dirname $0`/../../testprogs/blackbox/subunit.sh + +testit "wbinfo returns domain SID" $wbinfo -n "@$DOMAIN" || exit 1 +DOMAIN_SID=$($wbinfo -n "@$DOMAIN" | cut -f 1 -d " ") +echo "Domain $DOMAIN has SID $DOMAIN_SID" + +# Find an unused uid and SID +RID=66666 +while true ; do + id $RID + if [ $? -ne 0 ] ; then + $wbinfo -s $DOMAIN_SID\\$RID + if [ $? -ne 0 ] ; then + break + fi + fi + RID=$(expr $RID + 1) +done + +echo "Using non-existing SID $DOMAIN_SID-$RID to check no id allocation is done by the backend" + +out="$($wbinfo --sids-to-unix-ids=$DOMAIN_SID-$RID)" +echo "wbinfo returned: $out" +test "$out" = "$DOMAIN_SID-$RID -> unmapped" +ret=$? +testit "wbinfo SID to xid returns unmapped for unknown SID" test $ret -eq 0 || failed=$(expr $failed + 1) + +exit $failed diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index f2babb1..850ee69 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -298,7 +298,7 @@ rpc = ["rpc.authcontext", "rpc.samba3.bind", "rpc.samba3.srvsvc", "rpc.samba3.sh local = ["local.nss", "local.ndr"] -idmap = [ "idmap.rfc2307" ] +idmap = ["idmap.rfc2307", "idmap.alloc"] rap = ["rap.basic", "rap.rpc", "rap.printing", "rap.sam"] @@ -363,6 +363,8 @@ for t in tests: plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD') elif t == "idmap.rfc2307": plantestsuite(t, "ad_member_rfc2307", [os.path.join(samba3srcdir, "../nsswitch/tests/test_idmap_rfc2307.sh"), '$DOMAIN', 'Administrator', '2000000', 'Guest', '2000001', '"Domain Users"', '2000002', 'DnsAdmins', '2000003', 'ou=idmap,dc=samba,dc=example,dc=com', '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD']) + elif t == "idmap.alloc": + plantestsuite(t, "ad_member_rfc2307", [os.path.join(samba3srcdir, "../nsswitch/tests/test_idmap_nss.sh"), '$DOMAIN']) elif t == "raw.acls": plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD') plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/nfs4acl_simple -U$USERNAME%$PASSWORD', description='nfs4acl_xattr-simple') -- 2.5.0