winbindd: only use the domain name from lookup sids if the domain matches
authorRalph Boehme <slow@samba.org>
Mon, 10 Apr 2017 12:28:18 +0000 (14:28 +0200)
committerUri Simchoni <uri@samba.org>
Wed, 12 Apr 2017 14:43:30 +0000 (16:43 +0200)
With the use of sIDHistory it happens that two sids map to the same name:
S-1-5-21-1387724271-3540671778-1971508351-1115 DOMAIN2\d1u1 (1)
S-1-5-21-3293503978-489118715-2763867031-1106 DOMAIN2\d1u1 (1)

On the net it looks like this:

     lsa_LookupSids: struct lsa_LookupSids
        in: struct lsa_LookupSids
            handle                   : *
                handle: struct policy_handle
                    handle_type              : 0x00000000 (0)
                    uuid                     : 344f3586-7de4-4e1d-96a9-8c6c23e4b2f0
            sids                     : *
                sids: struct lsa_SidArray
                    num_sids                 : 0x00000002 (2)
                    sids                     : *
                        sids: ARRAY(2)
                            sids: struct lsa_SidPtr
                                sid                      : *
                                    sid                      : S-1-5-21-1387724271-3540671778-1971508351-1115
                            sids: struct lsa_SidPtr
                                sid                      : *
                                    sid                      : S-1-5-21-3293503978-489118715-2763867031-1106
            names                    : *
                names: struct lsa_TransNameArray
                    count                    : 0x00000000 (0)
                    names                    : NULL
            level                    : LSA_LOOKUP_NAMES_ALL (1)
            count                    : *
                count                    : 0x00000000 (0)
     lsa_LookupSids: struct lsa_LookupSids
        out: struct lsa_LookupSids
            domains                  : *
                domains                  : *
                    domains: struct lsa_RefDomainList
                        count                    : 0x00000001 (1)
                        domains                  : *
                            domains: ARRAY(1)
                                domains: struct lsa_DomainInfo
                                    name: struct lsa_StringLarge
                                        length                   : 0x000e (14)
                                        size                     : 0x0010 (16)
                                        string                   : *
                                            string                   : 'DOMAIN2'
                                    sid                      : *
                                        sid                      : S-1-5-21-1387724271-3540671778-1971508351
                        max_size                 : 0x00000020 (32)
            names                    : *
                names: struct lsa_TransNameArray
                    count                    : 0x00000002 (2)
                    names                    : *
                        names: ARRAY(7)
                            names: struct lsa_TranslatedName
                                sid_type                 : SID_NAME_USER (1)
                                name: struct lsa_String
                                    length                   : 0x0008 (8)
                                    size                     : 0x0008 (8)
                                    string                   : *
                                        string                   : 'd1u1'
                                sid_index                : 0x00000000 (0)
                            names: struct lsa_TranslatedName
                                sid_type                 : SID_NAME_USER (1)
                                name: struct lsa_String
                                    length                   : 0x0008 (8)
                                    size                     : 0x0008 (8)
                                    string                   : *
                                        string                   : 'd1u1'
                                sid_index                : 0x00000000 (0)
            count                    : *
                count                    : 0x00000002 (2)
            result                   : NT_STATUS_OK

So the name for S-1-5-21-3293503978-489118715-2763867031-1106 has
S-1-5-21-1387724271-3540671778-1971508351 in referenced lsa_DomainInfo
structure. In that case we should not use the domain name from lsa_DomainInfo,
because we would use the wrong idmap backend.

For the case where the domain part of the sIDHistory sid is a still existing
domain, which can be found our internal list of trusted domains, we now use the
correct idmap backend: the idmap domain from the historic SID.

If the historic domain does no longer exist, we will fallback to the default
idmap domain.

The next step would be doing a lookup sid call for the domain sid, which may
help with one-way trusts.

The long term goal needs to be that idmap backends are based on sids only and
only the smb.conf allows names to be used which will be converted to sids on
startup.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12702

Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Uri Simchoni <uri@samba.org>
Autobuild-User(master): Uri Simchoni <uri@samba.org>
Autobuild-Date(master): Wed Apr 12 16:43:30 CEST 2017 on sn-devel-144

source3/winbindd/wb_sids2xids.c

index dc90bdf5ef756a84185266355d01f74e26aeeb2d..b8ad300ba3c80e1e82f5eccc1f87421d7ca963a7 100644 (file)
@@ -194,9 +194,13 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq)
 
                if (n->sid_index != UINT32_MAX) {
                        const struct lsa_DomainInfo *info;
+                       bool match;
 
                        info = &domains->domains[n->sid_index];
-                       domain_name = info->name.string;
+                       match = dom_sid_in_domain(info->sid, sid);
+                       if (match) {
+                               domain_name = info->name.string;
+                       }
                }
                if (domain_name == NULL) {
                        struct winbindd_domain *wb_domain = NULL;