s3:winbindd: factor winbindd_sids_to_xids into external and internal part
[samba.git] / source3 / winbindd / winbindd_sids_to_xids.c
index 7456d3a307156342c228a1700d37896e86486745..e4c7e3f0a9f0d3183954b0c9ca1d725ddb723554 100644 (file)
@@ -2,6 +2,7 @@
    Unix SMB/CIFS implementation.
    async implementation of WINBINDD_SIDS_TO_XIDS
    Copyright (C) Volker Lendecke 2011
+   Copyright (C) Michael Adam 2012
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 #include "includes.h"
 #include "winbindd.h"
 #include "../libcli/security/security.h"
-#include "librpc/gen_ndr/ndr_wbint_c.h"
-#include "idmap_cache.h"
+
 
 struct winbindd_sids_to_xids_state {
        struct tevent_context *ev;
        struct dom_sid *sids;
        uint32_t num_sids;
-
-       struct id_map *cached;
-
-       struct dom_sid *non_cached;
-       uint32_t num_non_cached;
-
-       struct lsa_RefDomainList *domains;
-       struct lsa_TransNameArray *names;
-
-       struct wbint_TransIDArray ids;
+       struct unixid *xids;
 };
 
-static bool winbindd_sids_to_xids_in_cache(struct dom_sid *sid,
-                                          struct id_map *map);
-static void winbindd_sids_to_xids_lookupsids_done(struct tevent_req *subreq);
 static void winbindd_sids_to_xids_done(struct tevent_req *subreq);
 
 struct tevent_req *winbindd_sids_to_xids_send(TALLOC_CTX *mem_ctx,
@@ -51,7 +39,6 @@ struct tevent_req *winbindd_sids_to_xids_send(TALLOC_CTX *mem_ctx,
 {
        struct tevent_req *req, *subreq;
        struct winbindd_sids_to_xids_state *state;
-       uint32_t i;
 
        req = tevent_req_create(mem_ctx, &state,
                                struct winbindd_sids_to_xids_state);
@@ -80,154 +67,31 @@ struct tevent_req *winbindd_sids_to_xids_send(TALLOC_CTX *mem_ctx,
 
        DEBUG(10, ("num_sids: %d\n", (int)state->num_sids));
 
-       state->cached = talloc_zero_array(state, struct id_map,
-                                         state->num_sids);
-       if (tevent_req_nomem(state->cached, req)) {
-               return tevent_req_post(req, ev);
-       }
-       state->non_cached = talloc_array(state, struct dom_sid,
-                                        state->num_sids);
-       if (tevent_req_nomem(state->non_cached, req)) {
-               return tevent_req_post(req, ev);
-       }
-
-       /*
-        * Extract those sids that can not be resolved from cache
-        * into a separate list to be handed to id mapping, keeping
-        * the same index.
-        */
-       for (i=0; i<state->num_sids; i++) {
-
-               DEBUG(10, ("SID %d: %s\n", (int)i,
-                          sid_string_dbg(&state->sids[i])));
-
-               if (winbindd_sids_to_xids_in_cache(&state->sids[i],
-                                                  &state->cached[i])) {
-                       continue;
-               }
-               sid_copy(&state->non_cached[state->num_non_cached],
-                        &state->sids[i]);
-               state->num_non_cached += 1;
-       }
-
-       if (state->num_non_cached == 0) {
-               tevent_req_done(req);
-               return tevent_req_post(req, ev);
-       }
-
-       subreq = wb_lookupsids_send(state, ev, state->non_cached,
-                                   state->num_non_cached);
+       subreq = wb_sids2xids_send(state, ev, state->sids, state->num_sids);
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
-       tevent_req_set_callback(subreq, winbindd_sids_to_xids_lookupsids_done,
-                               req);
-       return req;
-}
 
-static bool winbindd_sids_to_xids_in_cache(struct dom_sid *sid,
-                                          struct id_map *map)
-{
-       struct unixid id;
-       bool expired;
-
-       if (!winbindd_use_idmap_cache()) {
-               return false;
-       }
-       if (idmap_cache_find_sid2unixid(sid, &id, &expired)) {
-               if (expired && is_domain_online(find_our_domain())) {
-                       return false;
-               }
-               map->sid = sid;
-               map->xid = id;
-               map->status = ID_MAPPED;
-               return true;
-       }
-       return false;
+       tevent_req_set_callback(subreq, winbindd_sids_to_xids_done, req);
+       return req;
 }
 
-static enum id_type lsa_SidType_to_id_type(const enum lsa_SidType sid_type);
-
-static void winbindd_sids_to_xids_lookupsids_done(struct tevent_req *subreq)
+static void winbindd_sids_to_xids_done(struct tevent_req *subreq)
 {
        struct tevent_req *req = tevent_req_callback_data(
                subreq, struct tevent_req);
        struct winbindd_sids_to_xids_state *state = tevent_req_data(
                req, struct winbindd_sids_to_xids_state);
-       struct winbindd_child *child;
        NTSTATUS status;
-       int i;
-
-       status = wb_lookupsids_recv(subreq, state, &state->domains,
-                                   &state->names);
-       TALLOC_FREE(subreq);
-       if (tevent_req_nterror(req, status)) {
-               return;
-       }
-
-       state->ids.num_ids = state->num_non_cached;
-       state->ids.ids = talloc_array(state, struct wbint_TransID,
-                                     state->num_non_cached);
-       if (tevent_req_nomem(state->ids.ids, req)) {
-               return;
-       }
-
-       for (i=0; i<state->num_non_cached; i++) {
-               struct lsa_TranslatedName *n = &state->names->names[i];
-               struct wbint_TransID *t = &state->ids.ids[i];
-
-               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->unix_id = (uint64_t)-1;
-       }
-
-       child = idmap_child();
 
-       subreq = dcerpc_wbint_Sids2UnixIDs_send(
-               state, state->ev, child->binding_handle, state->domains,
-               &state->ids);
-       if (tevent_req_nomem(subreq, req)) {
+       state->xids = talloc_zero_array(state, struct unixid, state->num_sids);
+       if (tevent_req_nomem(state->xids, req)) {
                return;
        }
-       tevent_req_set_callback(subreq, winbindd_sids_to_xids_done, req);
-}
-
-static enum id_type lsa_SidType_to_id_type(const enum lsa_SidType sid_type)
-{
-       enum id_type type;
-
-       switch(sid_type) {
-       case SID_NAME_COMPUTER:
-       case SID_NAME_USER:
-               type = ID_TYPE_UID;
-               break;
-       case SID_NAME_DOM_GRP:
-       case SID_NAME_ALIAS:
-       case SID_NAME_WKN_GRP:
-               type = ID_TYPE_GID;
-               break;
-       default:
-               type = ID_TYPE_NOT_SPECIFIED;
-               break;
-       }
-
-       return type;
-}
 
-
-static void winbindd_sids_to_xids_done(struct tevent_req *subreq)
-{
-       struct tevent_req *req = tevent_req_callback_data(
-               subreq, struct tevent_req);
-       struct winbindd_sids_to_xids_state *state = tevent_req_data(
-               req, struct winbindd_sids_to_xids_state);
-       NTSTATUS status, result;
-
-       status = dcerpc_wbint_Sids2UnixIDs_recv(subreq, state, &result);
+       status = wb_sids2xids_recv(subreq, state->xids);
        TALLOC_FREE(subreq);
-       if (any_nt_status_not_ok(status, result, &status)) {
-               tevent_req_nterror(req, status);
+       if (tevent_req_nterror(req, status)) {
                return;
        }
        tevent_req_done(req);
@@ -240,10 +104,10 @@ NTSTATUS winbindd_sids_to_xids_recv(struct tevent_req *req,
                req, struct winbindd_sids_to_xids_state);
        NTSTATUS status;
        char *result = NULL;
-       uint32_t i, num_non_cached;
+       uint32_t i;
 
        if (tevent_req_is_nterror(req, &status)) {
-               DEBUG(5, ("wb_sids_to_xids failed: %s\n", nt_errstr(status)));
+               DEBUG(5, ("Could not convert sids: %s\n", nt_errstr(status)));
                return status;
        }
 
@@ -252,27 +116,12 @@ NTSTATUS winbindd_sids_to_xids_recv(struct tevent_req *req,
                return NT_STATUS_NO_MEMORY;
        }
 
-       num_non_cached = 0;
-
        for (i=0; i<state->num_sids; i++) {
                char type = '\0';
                bool found = true;
                struct unixid xid;
 
-               xid.id = UINT32_MAX;
-
-               if (state->cached[i].sid != NULL) {
-                       xid = state->cached[i].xid;
-               } else {
-                       xid.id = state->ids.ids[num_non_cached].unix_id;
-                       xid.type = state->ids.ids[num_non_cached].type;
-
-                       idmap_cache_set_sid2unixid(
-                               &state->non_cached[num_non_cached],
-                               &xid);
-
-                       num_non_cached += 1;
-               }
+               xid = state->xids[i];
 
                switch (xid.type) {
                case ID_TYPE_UID:
@@ -307,5 +156,6 @@ NTSTATUS winbindd_sids_to_xids_recv(struct tevent_req *req,
 
        response->extra_data.data = result;
        response->length += talloc_get_size(result);
+
        return NT_STATUS_OK;
 }