s3-winbindd: Do not use domain SID from LookupSids for Sids2UnixIDs call
authorChristof Schmitt <cs@samba.org>
Thu, 11 Sep 2014 23:39:21 +0000 (16:39 -0700)
committerKarolin Seeger <kseeger@samba.org>
Thu, 9 Oct 2014 19:10:04 +0000 (21:10 +0200)
Create a new lsa_RefDomainList and populate it with the domain SID from
the original query. That avoids the problem that for migrated objects,
LookupSids returns the SID of the new domain, and combining that with
the RID from the input results in an invalid SID.

A better fix would be querying the RID of the user in the new domain,
but the approach here at least avoids id mappings entries for invalid
SIDs.

Signed-off-by: Christof Schmitt <cs@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
Autobuild-User(master): Volker Lendecke <vl@samba.org>
Autobuild-Date(master): Mon Sep 29 13:15:18 CEST 2014 on sn-devel-104

(cherry picked from commit 9c9216410faf707edc4ba05f2b715d45f7f51ca4)

Bug: https://bugzilla.samba.org/show_bug.cgi?id=10838
Invalid id mappings for users/groups migrated from another domain

source3/winbindd/wb_sids2xids.c

index cbd4444566f2e10ddeb9b6ba8ba47c6a190ff5e2..5b0dbbbebe0763519513c960123d02acd5571767 100644 (file)
@@ -23,6 +23,7 @@
 #include "../libcli/security/security.h"
 #include "idmap_cache.h"
 #include "librpc/gen_ndr/ndr_wbint_c.h"
+#include "lsa.h"
 
 struct wb_sids2xids_state {
        struct tevent_context *ev;
@@ -38,6 +39,19 @@ struct wb_sids2xids_state {
        struct lsa_RefDomainList *domains;
        struct lsa_TransNameArray *names;
 
+       /*
+        * Domain array to use for the idmap call. The output from
+        * lookupsids cannot be used directly since for migrated
+        * objects the returned domain SID can be different that the
+        * original one. The new domain SID cannot be combined with
+        * the RID from the previous domain.
+        *
+        * The proper way would be asking for the correct RID in the
+        * new domain, but this approach avoids id mappings for
+        * invalid SIDs.
+        */
+       struct lsa_RefDomainList *idmap_doms;
+
        struct wbint_TransIDArray ids;
 };
 
@@ -162,13 +176,26 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq)
                return;
        }
 
+       state->idmap_doms = talloc_zero(state, struct lsa_RefDomainList);
+       if (tevent_req_nomem(state->idmap_doms, req)) {
+               return;
+       }
+
        for (i=0; i<state->num_non_cached; i++) {
+               struct dom_sid dom_sid;
+               struct lsa_DomainInfo *info;
                struct lsa_TranslatedName *n = &state->names->names[i];
                struct wbint_TransID *t = &state->ids.ids[i];
 
+               sid_copy(&dom_sid, &state->non_cached[i]);
+               sid_split_rid(&dom_sid, &t->rid);
+
+               info = &state->domains->domains[n->sid_index];
                t->type = lsa_SidType_to_id_type(n->sid_type);
-               t->domain_index = n->sid_index;
-               sid_peek_rid(&state->non_cached[i], &t->rid);
+               t->domain_index = init_lsa_ref_domain_list(state,
+                                                          state->idmap_doms,
+                                                          info->name.string,
+                                                          &dom_sid);
                t->xid.id = UINT32_MAX;
                t->xid.type = t->type;
        }
@@ -176,7 +203,7 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq)
        child = idmap_child();
 
        subreq = dcerpc_wbint_Sids2UnixIDs_send(
-               state, state->ev, child->binding_handle, state->domains,
+               state, state->ev, child->binding_handle, state->idmap_doms,
                &state->ids);
        if (tevent_req_nomem(subreq, req)) {
                return;