LCOV - code coverage report
Current view: top level - source3/winbindd - wb_lookupsids.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 172 254 67.7 %
Date: 2024-06-13 04:01:37 Functions: 9 10 90.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    async lookupsids
       4             :    Copyright (C) Volker Lendecke 2011
       5             : 
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include "includes.h"
      21             : #include "winbindd.h"
      22             : #include "lib/util_unixsids.h"
      23             : #include "librpc/gen_ndr/ndr_winbind_c.h"
      24             : #include "../libcli/security/security.h"
      25             : #include "passdb/machine_sid.h"
      26             : #include "lsa.h"
      27             : 
      28             : struct wb_lookupsids_domain {
      29             :         struct winbindd_domain *domain;
      30             : 
      31             :         /*
      32             :          * Array of sids to be passed into wbint_LookupSids. Preallocated with
      33             :          * num_sids.
      34             :          */
      35             :         struct lsa_SidArray sids;
      36             : 
      37             :         /*
      38             :          * Indexes into wb_lookupsids_state->sids and thus
      39             :          * wb_lookupsids_state->res_names. Preallocated with num_sids.
      40             :          */
      41             :         uint32_t *sid_indexes;
      42             : };
      43             : 
      44             : struct wb_translated_name {
      45             :         const char *domain_name;
      46             :         const char *name;
      47             :         enum lsa_SidType type;
      48             : };
      49             : 
      50             : static struct wb_lookupsids_domain *wb_lookupsids_get_domain(
      51             :         const struct dom_sid *sid, TALLOC_CTX *mem_ctx,
      52             :         struct wb_lookupsids_domain **domains, uint32_t num_sids);
      53             : 
      54             : struct wb_lookupsids_state {
      55             :         struct tevent_context *ev;
      56             : 
      57             :         /*
      58             :          * SIDs passed in
      59             :          */
      60             :         struct dom_sid *sids;
      61             :         uint32_t num_sids;
      62             : 
      63             :         /*
      64             :          * The domains we're using for bulk lookup via wbint_LookupRids or
      65             :          * wbint_LookupSids. We expect very few domains, so we do a
      66             :          * talloc_realloc and rely on talloc_array_length.
      67             :          */
      68             :         struct wb_lookupsids_domain *domains;
      69             :         uint32_t domains_done;
      70             : 
      71             :         /*
      72             :          * These SIDs are looked up individually via
      73             :          * wbint_LookupSid. Preallocated with num_sids.
      74             :          */
      75             :         uint32_t *single_sids;
      76             :         uint32_t num_single_sids;
      77             :         uint32_t single_sids_done;
      78             : 
      79             :         /*
      80             :          * Intermediate store for wbint_LookupRids to passdb. These are
      81             :          * spliced into res_domains/res_names in wb_lookupsids_move_name.
      82             :          */
      83             :         struct wbint_RidArray rids;
      84             :         const char *domain_name;
      85             :         struct wbint_Principals rid_names;
      86             : 
      87             :         /*
      88             :          * Intermediate results for wbint_LookupSids. These results are
      89             :          * spliced into res_domains/res_names in wb_lookupsids_move_name.
      90             :          */
      91             :         struct lsa_RefDomainList tmp_domains;
      92             :         struct lsa_TransNameArray tmp_names;
      93             : 
      94             :         /*
      95             :          * Results
      96             :          */
      97             :         struct lsa_RefDomainList *res_domains;
      98             :         /*
      99             :          * Indexed as "sids" in this structure
     100             :          */
     101             :         struct lsa_TransNameArray *res_names;
     102             : };
     103             : 
     104             : static bool wb_lookupsids_next(struct tevent_req *req,
     105             :                                struct wb_lookupsids_state *state);
     106             : static void wb_lookupsids_single_done(struct tevent_req *subreq);
     107             : static void wb_lookupsids_lookuprids_done(struct tevent_req *subreq);
     108             : static void wb_lookupsids_done(struct tevent_req *subreq);
     109             : 
     110         633 : struct tevent_req *wb_lookupsids_send(TALLOC_CTX *mem_ctx,
     111             :                                       struct tevent_context *ev,
     112             :                                       struct dom_sid *sids,
     113             :                                       uint32_t num_sids)
     114             : {
     115             :         struct tevent_req *req;
     116             :         struct wb_lookupsids_state *state;
     117             :         uint32_t i;
     118             : 
     119         633 :         D_INFO("WB command lookupsids start.\nLooking up %"PRIu32" SID(s)\n",
     120             :                num_sids);
     121         633 :         if (CHECK_DEBUGLVL(DBGLVL_INFO)) {
     122           0 :                 for (i = 0; i < num_sids; i++) {
     123             :                         struct dom_sid_buf buf;
     124           0 :                         D_INFO("%"PRIu32": %s\n",
     125             :                                i, dom_sid_str_buf(&sids[i], &buf));
     126             :                 }
     127             :         }
     128         633 :         req = tevent_req_create(mem_ctx, &state, struct wb_lookupsids_state);
     129         633 :         if (req == NULL) {
     130           0 :                 return NULL;
     131             :         }
     132         633 :         state->ev = ev;
     133         633 :         state->sids = sids;
     134         633 :         state->num_sids = num_sids;
     135             : 
     136         633 :         state->single_sids = talloc_zero_array(state, uint32_t, num_sids);
     137         633 :         if (tevent_req_nomem(state->single_sids, req)) {
     138           0 :                 return tevent_req_post(req, ev);
     139             :         }
     140             : 
     141         633 :         state->res_domains = talloc_zero(state, struct lsa_RefDomainList);
     142         633 :         if (tevent_req_nomem(state->res_domains, req)) {
     143           0 :                 return tevent_req_post(req, ev);
     144             :         }
     145         633 :         state->res_domains->domains = talloc_zero_array(
     146             :                 state->res_domains, struct lsa_DomainInfo, num_sids);
     147         633 :         if (tevent_req_nomem(state->res_domains->domains, req)) {
     148           0 :                 return tevent_req_post(req, ev);
     149             :         }
     150             : 
     151         633 :         state->res_names = talloc_zero(state, struct lsa_TransNameArray);
     152         633 :         if (tevent_req_nomem(state->res_names, req)) {
     153           0 :                 return tevent_req_post(req, ev);
     154             :         }
     155         633 :         state->res_names->names = talloc_zero_array(
     156             :                 state->res_names, struct lsa_TranslatedName, num_sids);
     157         633 :         if (tevent_req_nomem(state->res_names->names, req)) {
     158           0 :                 return tevent_req_post(req, ev);
     159             :         }
     160             : 
     161         633 :         if (num_sids == 0) {
     162           0 :                 tevent_req_done(req);
     163           0 :                 return tevent_req_post(req, ev);
     164             :         }
     165             : 
     166        1324 :         for (i=0; i<num_sids; i++) {
     167             :                 struct wb_lookupsids_domain *d;
     168             : 
     169         691 :                 d = wb_lookupsids_get_domain(&sids[i], state, &state->domains,
     170             :                                              num_sids);
     171         691 :                 if (d != NULL) {
     172         153 :                         d->sids.sids[d->sids.num_sids].sid = &sids[i];
     173         153 :                         d->sid_indexes[d->sids.num_sids] = i;
     174         153 :                         d->sids.num_sids += 1;
     175             :                 } else {
     176         538 :                         state->single_sids[state->num_single_sids] = i;
     177         538 :                         state->num_single_sids += 1;
     178             :                 }
     179             :         }
     180             : 
     181         633 :         if (!wb_lookupsids_next(req, state)) {
     182           0 :                 return tevent_req_post(req, ev);
     183             :         }
     184         633 :         return req;
     185             : }
     186             : 
     187         760 : static bool wb_lookupsids_next(struct tevent_req *req,
     188             :                                struct wb_lookupsids_state *state)
     189             : {
     190             :         struct tevent_req *subreq;
     191             : 
     192         760 :         if (state->domains_done < talloc_array_length(state->domains)) {
     193             :                 struct wb_lookupsids_domain *d;
     194             :                 uint32_t i;
     195             : 
     196         105 :                 d = &state->domains[state->domains_done];
     197             : 
     198         105 :                 if (d->domain->internal) {
     199             :                         /*
     200             :                          * This is only our local SAM,
     201             :                          * see wb_lookupsids_bulk() and
     202             :                          * wb_lookupsids_get_domain().
     203             :                          */
     204           0 :                         state->rids.num_rids = d->sids.num_sids;
     205           0 :                         state->rids.rids = talloc_array(state, uint32_t,
     206             :                                                         state->rids.num_rids);
     207           0 :                         if (tevent_req_nomem(state->rids.rids, req)) {
     208           0 :                                 return false;
     209             :                         }
     210           0 :                         for (i=0; i<state->rids.num_rids; i++) {
     211           0 :                                 sid_peek_rid(d->sids.sids[i].sid,
     212           0 :                                              &state->rids.rids[i]);
     213             :                         }
     214           0 :                         subreq = dcerpc_wbint_LookupRids_send(
     215             :                                 state, state->ev, dom_child_handle(d->domain),
     216           0 :                                 &d->domain->sid, &state->rids, &state->domain_name,
     217             :                                 &state->rid_names);
     218           0 :                         if (tevent_req_nomem(subreq, req)) {
     219           0 :                                 return false;
     220             :                         }
     221           0 :                         tevent_req_set_callback(
     222             :                                 subreq, wb_lookupsids_lookuprids_done, req);
     223           0 :                         return true;
     224             :                 }
     225             : 
     226         105 :                 subreq = dcerpc_wbint_LookupSids_send(
     227             :                         state, state->ev, dom_child_handle(d->domain),
     228             :                         &d->sids, &state->tmp_domains,    &state->tmp_names);
     229         105 :                 if (tevent_req_nomem(subreq, req)) {
     230           0 :                         return false;
     231             :                 }
     232         105 :                 tevent_req_set_callback(subreq, wb_lookupsids_done, req);
     233         105 :                 return true;
     234             :         }
     235             : 
     236         655 :         if (state->single_sids_done < state->num_single_sids) {
     237             :                 uint32_t sid_idx;
     238             :                 const struct dom_sid *sid;
     239             : 
     240         538 :                 sid_idx = state->single_sids[state->single_sids_done];
     241         538 :                 sid = &state->sids[sid_idx];
     242             : 
     243         538 :                 subreq = wb_lookupsid_send(state, state->ev, sid);
     244         538 :                 if (tevent_req_nomem(subreq, req)) {
     245           0 :                         return false;
     246             :                 }
     247         538 :                 tevent_req_set_callback(subreq, wb_lookupsids_single_done,
     248             :                                         req);
     249         538 :                 return true;
     250             :         }
     251             : 
     252         117 :         tevent_req_done(req);
     253         117 :         return false;
     254             : }
     255             : 
     256             : /*
     257             :  * Decide whether to do bulk lookupsids. We have optimizations for
     258             :  * passdb via lookuprids and to remote DCs via lookupsids.
     259             :  */
     260             : 
     261         691 : static bool wb_lookupsids_bulk(const struct dom_sid *sid)
     262             : {
     263             :         struct dom_sid_buf sidbuf;
     264             : 
     265         691 :         if (sid->num_auths != 5) {
     266             :                 /*
     267             :                  * Only do "S-1-5-21-x-y-z-rid" domains via bulk
     268             :                  * lookup
     269             :                  */
     270         538 :                 DBG_DEBUG("No bulk setup for SID %s with %"PRIi8" subauths\n",
     271             :                           dom_sid_str_buf(sid, &sidbuf),
     272             :                           sid->num_auths);
     273         538 :                 return false;
     274             :         }
     275             : 
     276         153 :         if (sid_check_is_in_our_sam(sid)) {
     277             :                 /*
     278             :                  * Passdb lookup via lookuprids
     279             :                  */
     280           0 :                 DBG_DEBUG("%s is in our domain\n",
     281             :                           dom_sid_str_buf(sid, &sidbuf));
     282           0 :                 return true;
     283             :         }
     284             : 
     285         153 :         if (IS_DC) {
     286             :                 /*
     287             :                  * Bulk lookups to trusted DCs
     288             :                  */
     289           9 :                 return (find_domain_from_sid_noinit(sid) != NULL);
     290             :         }
     291             : 
     292         144 :         if (lp_server_role() != ROLE_DOMAIN_MEMBER) {
     293             :                 /*
     294             :                  * Don't do bulk lookups as standalone, the only bulk
     295             :                  * lookup left is for domain members.
     296             :                  */
     297           0 :                 return false;
     298             :         }
     299             : 
     300         288 :         if (sid_check_is_in_unix_groups(sid) ||
     301         288 :             sid_check_is_unix_groups(sid) ||
     302         288 :             sid_check_is_in_unix_users(sid) ||
     303         288 :             sid_check_is_unix_users(sid) ||
     304         288 :             sid_check_is_in_builtin(sid) ||
     305         288 :             sid_check_is_builtin(sid) ||
     306         288 :             sid_check_is_wellknown_domain(sid, NULL) ||
     307         144 :             sid_check_is_in_wellknown_domain(sid))
     308             :         {
     309             :                 /*
     310             :                  * These are locally done piece by piece anyway, no
     311             :                  * need for bulk optimizations.
     312             :                  */
     313           0 :                 return false;
     314             :         }
     315             : 
     316             :         /*
     317             :          * All other SIDs are sent to the DC we're connected to as
     318             :          * member via a single lsa_lookupsids call.
     319             :          */
     320         144 :         return true;
     321             : }
     322             : 
     323         691 : static struct wb_lookupsids_domain *wb_lookupsids_get_domain(
     324             :         const struct dom_sid *sid, TALLOC_CTX *mem_ctx,
     325             :         struct wb_lookupsids_domain **pdomains, uint32_t num_sids)
     326             : {
     327             :         struct wb_lookupsids_domain *domains, *domain;
     328             :         struct winbindd_domain *wb_domain;
     329             :         uint32_t i, num_domains;
     330             : 
     331         691 :         if (!wb_lookupsids_bulk(sid)) {
     332         538 :                 D_DEBUG("wb_lookupsids_bulk() is FALSE\n");
     333         538 :                 return NULL;
     334             :         }
     335         153 :         D_DEBUG("wb_lookupsids_bulk() is TRUE\n");
     336             : 
     337         153 :         domains = *pdomains;
     338         153 :         num_domains = talloc_array_length(domains);
     339             : 
     340         153 :         wb_domain = find_lookup_domain_from_sid(sid);
     341         153 :         if (wb_domain == NULL) {
     342           0 :                 return NULL;
     343             :         }
     344             : 
     345         153 :         D_DEBUG("Searching %"PRIu32" domain(s) for domain '%s'\n",
     346             :                 num_domains, wb_domain->name);
     347         234 :         for (i=0; i<num_domains; i++) {
     348          48 :                 if (domains[i].domain != wb_domain) {
     349           0 :                         continue;
     350             :                 }
     351             : 
     352          48 :                 if (!domains[i].domain->internal) {
     353             :                         /*
     354             :                          * If it's not our local sam,
     355             :                          * we can re-use the domain without
     356             :                          * checking the sid.
     357             :                          *
     358             :                          * Note the wb_lookupsids_bulk() above
     359             :                          * already catched special SIDs,
     360             :                          * e.g. the unix and builtin domains.
     361             :                          */
     362          48 :                         return &domains[i];
     363             :                 }
     364             : 
     365           0 :                 if (dom_sid_compare_domain(sid, &domains[i].domain->sid) == 0) {
     366             :                         /*
     367             :                          * If it's out local sam we can also use it.
     368             :                          */
     369           0 :                         return &domains[i];
     370             :                 }
     371             : 
     372             :                 /*
     373             :                  * I'm not sure if this can be triggered,
     374             :                  * as wb_lookupsids_bulk() should also catch this,
     375             :                  * but we need to make sure that we don't use
     376             :                  * wbint_LookupRids() without a SID match.
     377             :                  */
     378           0 :                 return NULL;
     379             :         }
     380             : 
     381         105 :         domains = talloc_realloc(
     382             :                 mem_ctx, domains, struct wb_lookupsids_domain, num_domains+1);
     383         105 :         if (domains == NULL) {
     384           0 :                 return NULL;
     385             :         }
     386         105 :         *pdomains = domains;
     387             : 
     388         105 :         domain = &domains[num_domains];
     389         105 :         domain->domain = wb_domain;
     390             : 
     391         105 :         domain->sids.sids = talloc_zero_array(domains, struct lsa_SidPtr, num_sids);
     392         105 :         if (domains->sids.sids == NULL) {
     393           0 :                 goto fail;
     394             :         }
     395         105 :         domain->sids.num_sids = 0;
     396             : 
     397         105 :         domain->sid_indexes = talloc_zero_array(domains, uint32_t, num_sids);
     398         105 :         if (domain->sid_indexes == NULL) {
     399           0 :                 TALLOC_FREE(domain->sids.sids);
     400           0 :                 goto fail;
     401             :         }
     402         105 :         return domain;
     403             : 
     404           0 : fail:
     405             :         /*
     406             :          * Realloc to the state it was in before
     407             :          */
     408           0 :         *pdomains = talloc_realloc(
     409             :                 mem_ctx, domains, struct wb_lookupsids_domain, num_domains);
     410           0 :         return NULL;
     411             : }
     412             : 
     413         165 : static bool wb_lookupsids_find_dom_idx(struct lsa_DomainInfo *domain,
     414             :                                        struct lsa_RefDomainList *list,
     415             :                                        uint32_t *idx)
     416             : {
     417             :         uint32_t i;
     418             :         struct lsa_DomainInfo *new_domain;
     419             : 
     420         165 :         for (i=0; i<list->count; i++) {
     421          48 :                 if (dom_sid_equal(domain->sid, list->domains[i].sid)) {
     422          48 :                         *idx = i;
     423          48 :                         return true;
     424             :                 }
     425             :         }
     426             : 
     427         117 :         new_domain = &list->domains[list->count];
     428             : 
     429         234 :         new_domain->name.string = talloc_strdup(
     430         117 :                 list->domains, domain->name.string);
     431         117 :         if (new_domain->name.string == NULL) {
     432           0 :                 return false;
     433             :         }
     434             : 
     435         117 :         new_domain->sid = dom_sid_dup(list->domains, domain->sid);
     436         117 :         if (new_domain->sid == NULL) {
     437           0 :                 return false;
     438             :         }
     439             : 
     440         117 :         *idx = list->count;
     441         117 :         list->count += 1;
     442         117 :         return true;
     443             : }
     444             : 
     445         175 : static bool wb_lookupsids_move_name(struct lsa_RefDomainList *src_domains,
     446             :                                     struct lsa_TranslatedName *src_name,
     447             :                                     struct lsa_RefDomainList *dst_domains,
     448             :                                     struct lsa_TransNameArray *dst_names,
     449             :                                     uint32_t dst_name_index)
     450             : {
     451             :         struct lsa_TranslatedName *dst_name;
     452             :         struct lsa_DomainInfo *src_domain;
     453             :         uint32_t src_domain_index;
     454         175 :         uint32_t dst_domain_index = UINT32_MAX;
     455             :         bool ok;
     456             : 
     457         175 :         src_domain_index = src_name->sid_index;
     458         175 :         if ((src_domain_index != UINT32_MAX) && (src_domains != NULL)) {
     459         165 :                 if (src_domain_index >= src_domains->count) {
     460           0 :                         return false;
     461             :                 }
     462         165 :                 src_domain = &src_domains->domains[src_domain_index];
     463             : 
     464         165 :                 ok = wb_lookupsids_find_dom_idx(src_domain,
     465             :                                                 dst_domains,
     466             :                                                 &dst_domain_index);
     467         165 :                 if (!ok) {
     468           0 :                         return false;
     469             :                 }
     470             :         }
     471             : 
     472         175 :         dst_name = &dst_names->names[dst_name_index];
     473             : 
     474         175 :         dst_name->sid_type = src_name->sid_type;
     475         175 :         dst_name->name.string = talloc_move(dst_names->names,
     476             :                                             &src_name->name.string);
     477         175 :         dst_name->sid_index = dst_domain_index;
     478         175 :         dst_names->count += 1;
     479             : 
     480         175 :         return true;
     481             : }
     482             : 
     483         105 : static void wb_lookupsids_done(struct tevent_req *subreq)
     484             : {
     485         105 :         struct tevent_req *req = tevent_req_callback_data(
     486             :                 subreq, struct tevent_req);
     487         105 :         struct wb_lookupsids_state *state = tevent_req_data(
     488             :                 req, struct wb_lookupsids_state);
     489             :         struct wb_lookupsids_domain *d;
     490             :         uint32_t i;
     491             : 
     492             :         NTSTATUS status, result;
     493             : 
     494         105 :         status = dcerpc_wbint_LookupSids_recv(subreq, state, &result);
     495         105 :         TALLOC_FREE(subreq);
     496         105 :         if (tevent_req_nterror(req, status)) {
     497           0 :                 return;
     498             :         }
     499         105 :         if (NT_STATUS_LOOKUP_ERR(result)) {
     500           0 :                 tevent_req_nterror(req, result);
     501           0 :                 return;
     502             :         }
     503             : 
     504             :         /*
     505             :          * Look at the individual states in the translated names.
     506             :          */
     507             : 
     508         105 :         d = &state->domains[state->domains_done];
     509             : 
     510         258 :         for (i=0; i<state->tmp_names.count; i++) {
     511         153 :                 uint32_t res_sid_index = d->sid_indexes[i];
     512             : 
     513         234 :                 if (!wb_lookupsids_move_name(
     514         153 :                             &state->tmp_domains, &state->tmp_names.names[i],
     515             :                             state->res_domains, state->res_names,
     516             :                             res_sid_index)) {
     517           0 :                         tevent_req_oom(req);
     518           0 :                         return;
     519             :                 }
     520             :         }
     521         105 :         state->domains_done += 1;
     522         105 :         wb_lookupsids_next(req, state);
     523             : }
     524             : 
     525         538 : static void wb_lookupsids_single_done(struct tevent_req *subreq)
     526             : {
     527         538 :         struct tevent_req *req = tevent_req_callback_data(
     528             :                 subreq, struct tevent_req);
     529         538 :         struct wb_lookupsids_state *state = tevent_req_data(
     530             :                 req, struct wb_lookupsids_state);
     531         538 :         const char *domain_name = NULL;
     532         538 :         const char *name = NULL;
     533         538 :         enum lsa_SidType type = SID_NAME_UNKNOWN;
     534             :         uint32_t res_sid_index;
     535             :         uint32_t src_rid;
     536             : 
     537             :         struct dom_sid src_domain_sid;
     538             :         struct lsa_DomainInfo src_domain;
     539             :         struct lsa_RefDomainList src_domains;
     540         538 :         struct lsa_RefDomainList *psrc_domains = NULL;
     541             :         struct lsa_TranslatedName src_name;
     542             : 
     543         538 :         uint32_t domain_idx = UINT32_MAX;
     544             :         NTSTATUS status;
     545             :         bool ok;
     546             : 
     547         538 :         status = wb_lookupsid_recv(subreq, talloc_tos(), &type,
     548             :                                    &domain_name, &name);
     549         538 :         TALLOC_FREE(subreq);
     550         538 :         if (NT_STATUS_LOOKUP_ERR(status)) {
     551         516 :                 tevent_req_nterror(req, status);
     552         516 :                 return;
     553             :         }
     554             : 
     555          22 :         res_sid_index = state->single_sids[state->single_sids_done];
     556             : 
     557          22 :         if ((domain_name != NULL) && (domain_name[0] != '\0')) {
     558             :                 /*
     559             :                  * Build structs with the domain name for
     560             :                  * wb_lookupsids_move_name(). If we didn't get a name, we will
     561             :                  * pass NULL and UINT32_MAX.
     562             :                  */
     563             : 
     564          22 :                 sid_copy(&src_domain_sid, &state->sids[res_sid_index]);
     565          22 :                 if (type != SID_NAME_DOMAIN) {
     566           0 :                         sid_split_rid(&src_domain_sid, &src_rid);
     567             :                 }
     568             : 
     569          22 :                 src_domain.name.string = domain_name;
     570          22 :                 src_domain.sid = &src_domain_sid;
     571             : 
     572          22 :                 src_domains.count = 1;
     573          22 :                 src_domains.domains = &src_domain;
     574          22 :                 psrc_domains = &src_domains;
     575             : 
     576          22 :                 domain_idx = 0;
     577             :         }
     578             : 
     579          22 :         src_name.sid_type = type;
     580          22 :         src_name.name.string = name;
     581          22 :         src_name.sid_index = domain_idx;
     582             : 
     583          22 :         ok = wb_lookupsids_move_name(psrc_domains,
     584             :                                      &src_name,
     585             :                                      state->res_domains,
     586             :                                      state->res_names,
     587             :                                      res_sid_index);
     588          22 :         if (!ok) {
     589           0 :                 tevent_req_oom(req);
     590           0 :                 return;
     591             :         }
     592          22 :         state->single_sids_done += 1;
     593          22 :         wb_lookupsids_next(req, state);
     594             : }
     595             : 
     596           0 : static void wb_lookupsids_lookuprids_done(struct tevent_req *subreq)
     597             : {
     598           0 :         struct tevent_req *req = tevent_req_callback_data(
     599             :                 subreq, struct tevent_req);
     600           0 :         struct wb_lookupsids_state *state = tevent_req_data(
     601             :                 req, struct wb_lookupsids_state);
     602             :         struct dom_sid src_domain_sid;
     603             :         struct lsa_DomainInfo src_domain;
     604             :         struct lsa_RefDomainList src_domains;
     605             :         NTSTATUS status, result;
     606             :         struct wb_lookupsids_domain *d;
     607             :         uint32_t i;
     608             : 
     609           0 :         status = dcerpc_wbint_LookupRids_recv(subreq, state, &result);
     610           0 :         TALLOC_FREE(subreq);
     611           0 :         if (tevent_req_nterror(req, status)) {
     612           0 :                 return;
     613             :         }
     614           0 :         if (NT_STATUS_LOOKUP_ERR(result)) {
     615           0 :                 tevent_req_nterror(req, result);
     616           0 :                 return;
     617             :         }
     618             : 
     619             :         /*
     620             :          * Look at the individual states in the translated names.
     621             :          */
     622             : 
     623           0 :         d = &state->domains[state->domains_done];
     624             : 
     625           0 :         sid_copy(&src_domain_sid, get_global_sam_sid());
     626           0 :         src_domain.name.string = get_global_sam_name();
     627           0 :         src_domain.sid = &src_domain_sid;
     628           0 :         src_domains.count = 1;
     629           0 :         src_domains.domains = &src_domain;
     630             : 
     631           0 :         for (i=0; i<state->rid_names.num_principals; i++) {
     632             :                 struct lsa_TranslatedName src_name;
     633             :                 uint32_t res_sid_index;
     634             : 
     635             :                 /*
     636             :                  * Fake up structs for wb_lookupsids_move_name
     637             :                  */
     638           0 :                 res_sid_index = d->sid_indexes[i];
     639             : 
     640           0 :                 src_name.sid_type = state->rid_names.principals[i].type;
     641           0 :                 src_name.name.string = state->rid_names.principals[i].name;
     642           0 :                 src_name.sid_index = 0;
     643             : 
     644           0 :                 if (!wb_lookupsids_move_name(
     645             :                             &src_domains, &src_name,
     646             :                             state->res_domains, state->res_names,
     647             :                             res_sid_index)) {
     648           0 :                         tevent_req_oom(req);
     649           0 :                         return;
     650             :                 }
     651             :         }
     652             : 
     653           0 :         state->domains_done += 1;
     654           0 :         wb_lookupsids_next(req, state);
     655             : }
     656             : 
     657         633 : NTSTATUS wb_lookupsids_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
     658             :                             struct lsa_RefDomainList **domains,
     659             :                             struct lsa_TransNameArray **names)
     660             : {
     661         633 :         struct wb_lookupsids_state *state = tevent_req_data(
     662             :                 req, struct wb_lookupsids_state);
     663             :         NTSTATUS status;
     664             : 
     665         633 :         D_INFO("WB command lookupsids end.\n");
     666         633 :         if (tevent_req_is_nterror(req, &status)) {
     667         516 :                 D_WARNING("Failed with %s.\n", nt_errstr(status));
     668         516 :                 return status;
     669             :         }
     670             : 
     671             :         /*
     672             :          * The returned names need to match the given sids,
     673             :          * if not we have a bug in the code!
     674             :          */
     675         117 :         if (state->res_names->count != state->num_sids) {
     676           0 :                 D_WARNING("Got %"PRIu32" returned name(s), but expected %"PRIu32"!\n",
     677             :                           state->res_names->count, state->num_sids);
     678           0 :                 return NT_STATUS_INTERNAL_ERROR;
     679             :         }
     680             : 
     681             :         /*
     682             :          * Not strictly needed, but it might make debugging in the callers
     683             :          * easier in future, if the talloc_array_length() returns the
     684             :          * expected result...
     685             :          */
     686         117 :         state->res_domains->domains = talloc_realloc(state->res_domains,
     687             :                                                      state->res_domains->domains,
     688             :                                                      struct lsa_DomainInfo,
     689             :                                                      state->res_domains->count);
     690             : 
     691         117 :         *domains = talloc_move(mem_ctx, &state->res_domains);
     692         117 :         *names = talloc_move(mem_ctx, &state->res_names);
     693         117 :         D_INFO("Returning %"PRIu32" domain(s) and %"PRIu32" name(s).\n",
     694             :                (*domains)->count,
     695             :                (*names)->count);
     696         117 :         return NT_STATUS_OK;
     697             : }

Generated by: LCOV version 1.13