LCOV - code coverage report
Current view: top level - source3/winbindd - wb_lookupsids.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 209 294 71.1 %
Date: 2024-04-21 15:09:00 Functions: 10 10 100.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        2094 : 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           0 :         struct tevent_req *req;
     116           0 :         struct wb_lookupsids_state *state;
     117           0 :         uint32_t i;
     118             : 
     119        2094 :         req = tevent_req_create(mem_ctx, &state, struct wb_lookupsids_state);
     120        2094 :         if (req == NULL) {
     121           0 :                 return NULL;
     122             :         }
     123             : 
     124        2094 :         D_INFO("WB command lookupsids start.\nLooking up %"PRIu32" SID(s)\n",
     125             :                num_sids);
     126        2094 :         if (CHECK_DEBUGLVL(DBGLVL_INFO)) {
     127           0 :                 for (i = 0; i < num_sids; i++) {
     128           0 :                         struct dom_sid_buf buf;
     129           0 :                         D_INFO("%"PRIu32": %s\n",
     130             :                                i, dom_sid_str_buf(&sids[i], &buf));
     131             :                 }
     132             :         }
     133             : 
     134        2094 :         state->ev = ev;
     135        2094 :         state->sids = sids;
     136        2094 :         state->num_sids = num_sids;
     137             : 
     138        2094 :         state->single_sids = talloc_zero_array(state, uint32_t, num_sids);
     139        2094 :         if (tevent_req_nomem(state->single_sids, req)) {
     140           0 :                 return tevent_req_post(req, ev);
     141             :         }
     142             : 
     143        2094 :         state->res_domains = talloc_zero(state, struct lsa_RefDomainList);
     144        2094 :         if (tevent_req_nomem(state->res_domains, req)) {
     145           0 :                 return tevent_req_post(req, ev);
     146             :         }
     147        2094 :         state->res_domains->domains = talloc_zero_array(
     148             :                 state->res_domains, struct lsa_DomainInfo, num_sids);
     149        2094 :         if (tevent_req_nomem(state->res_domains->domains, req)) {
     150           0 :                 return tevent_req_post(req, ev);
     151             :         }
     152             : 
     153        2094 :         state->res_names = talloc_zero(state, struct lsa_TransNameArray);
     154        2094 :         if (tevent_req_nomem(state->res_names, req)) {
     155           0 :                 return tevent_req_post(req, ev);
     156             :         }
     157        2094 :         state->res_names->names = talloc_zero_array(
     158             :                 state->res_names, struct lsa_TranslatedName, num_sids);
     159        2094 :         if (tevent_req_nomem(state->res_names->names, req)) {
     160           0 :                 return tevent_req_post(req, ev);
     161             :         }
     162             : 
     163        2094 :         if (num_sids == 0) {
     164         638 :                 tevent_req_done(req);
     165         638 :                 return tevent_req_post(req, ev);
     166             :         }
     167             : 
     168        3426 :         for (i=0; i<num_sids; i++) {
     169           0 :                 struct wb_lookupsids_domain *d;
     170             : 
     171        1970 :                 d = wb_lookupsids_get_domain(&sids[i], state, &state->domains,
     172             :                                              num_sids);
     173        1970 :                 if (d != NULL) {
     174        1234 :                         d->sids.sids[d->sids.num_sids].sid = &sids[i];
     175        1234 :                         d->sid_indexes[d->sids.num_sids] = i;
     176        1234 :                         d->sids.num_sids += 1;
     177             :                 } else {
     178         736 :                         state->single_sids[state->num_single_sids] = i;
     179         736 :                         state->num_single_sids += 1;
     180             :                 }
     181             :         }
     182             : 
     183        1456 :         if (!wb_lookupsids_next(req, state)) {
     184           0 :                 return tevent_req_post(req, ev);
     185             :         }
     186        1456 :         return req;
     187             : }
     188             : 
     189        2626 : static bool wb_lookupsids_next(struct tevent_req *req,
     190             :                                struct wb_lookupsids_state *state)
     191             : {
     192           0 :         struct tevent_req *subreq;
     193             : 
     194        2626 :         if (state->domains_done < talloc_array_length(state->domains)) {
     195           0 :                 struct wb_lookupsids_domain *d;
     196           0 :                 uint32_t i;
     197             : 
     198        1162 :                 d = &state->domains[state->domains_done];
     199             : 
     200        1162 :                 if (d->domain->internal) {
     201             :                         /*
     202             :                          * This is only our local SAM,
     203             :                          * see wb_lookupsids_bulk() and
     204             :                          * wb_lookupsids_get_domain().
     205             :                          */
     206           2 :                         state->rids.num_rids = d->sids.num_sids;
     207           2 :                         state->rids.rids = talloc_array(state, uint32_t,
     208             :                                                         state->rids.num_rids);
     209           2 :                         if (tevent_req_nomem(state->rids.rids, req)) {
     210           0 :                                 return false;
     211             :                         }
     212           4 :                         for (i=0; i<state->rids.num_rids; i++) {
     213           2 :                                 sid_peek_rid(d->sids.sids[i].sid,
     214           2 :                                              &state->rids.rids[i]);
     215             :                         }
     216           2 :                         subreq = dcerpc_wbint_LookupRids_send(
     217             :                                 state, state->ev, dom_child_handle(d->domain),
     218           2 :                                 &d->domain->sid, &state->rids, &state->domain_name,
     219             :                                 &state->rid_names);
     220           2 :                         if (tevent_req_nomem(subreq, req)) {
     221           0 :                                 return false;
     222             :                         }
     223           2 :                         tevent_req_set_callback(
     224             :                                 subreq, wb_lookupsids_lookuprids_done, req);
     225           2 :                         return true;
     226             :                 }
     227             : 
     228        1160 :                 subreq = dcerpc_wbint_LookupSids_send(
     229             :                         state, state->ev, dom_child_handle(d->domain),
     230             :                         &d->sids, &state->tmp_domains,    &state->tmp_names);
     231        1160 :                 if (tevent_req_nomem(subreq, req)) {
     232           0 :                         return false;
     233             :                 }
     234        1160 :                 tevent_req_set_callback(subreq, wb_lookupsids_done, req);
     235        1160 :                 return true;
     236             :         }
     237             : 
     238        1464 :         if (state->single_sids_done < state->num_single_sids) {
     239           0 :                 uint32_t sid_idx;
     240           0 :                 const struct dom_sid *sid;
     241             : 
     242         736 :                 sid_idx = state->single_sids[state->single_sids_done];
     243         736 :                 sid = &state->sids[sid_idx];
     244             : 
     245         736 :                 subreq = wb_lookupsid_send(state, state->ev, sid);
     246         736 :                 if (tevent_req_nomem(subreq, req)) {
     247           0 :                         return false;
     248             :                 }
     249         736 :                 tevent_req_set_callback(subreq, wb_lookupsids_single_done,
     250             :                                         req);
     251         736 :                 return true;
     252             :         }
     253             : 
     254         728 :         tevent_req_done(req);
     255         728 :         return false;
     256             : }
     257             : 
     258             : /*
     259             :  * Decide whether to do bulk lookupsids. We have optimizations for
     260             :  * passdb via lookuprids and to remote DCs via lookupsids.
     261             :  */
     262             : 
     263        1970 : static bool wb_lookupsids_bulk(const struct dom_sid *sid)
     264             : {
     265           0 :         struct dom_sid_buf sidbuf;
     266             : 
     267        1970 :         if (sid->num_auths != 5) {
     268             :                 /*
     269             :                  * Only do "S-1-5-21-x-y-z-rid" domains via bulk
     270             :                  * lookup
     271             :                  */
     272         736 :                 DBG_DEBUG("No bulk setup for SID %s with %"PRIi8" subauths\n",
     273             :                           dom_sid_str_buf(sid, &sidbuf),
     274             :                           sid->num_auths);
     275         736 :                 return false;
     276             :         }
     277             : 
     278        1234 :         if (sid_check_is_in_our_sam(sid)) {
     279             :                 /*
     280             :                  * Passdb lookup via lookuprids
     281             :                  */
     282           2 :                 DBG_DEBUG("%s is in our domain\n",
     283             :                           dom_sid_str_buf(sid, &sidbuf));
     284           2 :                 return true;
     285             :         }
     286             : 
     287        1232 :         if (IS_DC) {
     288             :                 /*
     289             :                  * Bulk lookups to trusted DCs
     290             :                  */
     291           4 :                 return (find_domain_from_sid_noinit(sid) != NULL);
     292             :         }
     293             : 
     294        1228 :         if (lp_server_role() != ROLE_DOMAIN_MEMBER) {
     295             :                 /*
     296             :                  * Don't do bulk lookups as standalone, the only bulk
     297             :                  * lookup left is for domain members.
     298             :                  */
     299           0 :                 return false;
     300             :         }
     301             : 
     302        2456 :         if (sid_check_is_in_unix_groups(sid) ||
     303        2456 :             sid_check_is_unix_groups(sid) ||
     304        2456 :             sid_check_is_in_unix_users(sid) ||
     305        2456 :             sid_check_is_unix_users(sid) ||
     306        2456 :             sid_check_is_in_builtin(sid) ||
     307        2456 :             sid_check_is_builtin(sid) ||
     308        2456 :             sid_check_is_wellknown_domain(sid, NULL) ||
     309        1228 :             sid_check_is_in_wellknown_domain(sid))
     310             :         {
     311             :                 /*
     312             :                  * These are locally done piece by piece anyway, no
     313             :                  * need for bulk optimizations.
     314             :                  */
     315           0 :                 return false;
     316             :         }
     317             : 
     318             :         /*
     319             :          * All other SIDs are sent to the DC we're connected to as
     320             :          * member via a single lsa_lookupsids call.
     321             :          */
     322        1228 :         return true;
     323             : }
     324             : 
     325        1970 : static struct wb_lookupsids_domain *wb_lookupsids_get_domain(
     326             :         const struct dom_sid *sid, TALLOC_CTX *mem_ctx,
     327             :         struct wb_lookupsids_domain **pdomains, uint32_t num_sids)
     328             : {
     329           0 :         struct wb_lookupsids_domain *domains, *domain;
     330           0 :         struct winbindd_domain *wb_domain;
     331           0 :         uint32_t i, num_domains;
     332             : 
     333        1970 :         if (!wb_lookupsids_bulk(sid)) {
     334         736 :                 D_DEBUG("wb_lookupsids_bulk() is FALSE\n");
     335         736 :                 return NULL;
     336             :         }
     337        1234 :         D_DEBUG("wb_lookupsids_bulk() is TRUE\n");
     338             : 
     339        1234 :         domains = *pdomains;
     340        1234 :         num_domains = talloc_array_length(domains);
     341             : 
     342        1234 :         wb_domain = find_lookup_domain_from_sid(sid);
     343        1234 :         if (wb_domain == NULL) {
     344           0 :                 return NULL;
     345             :         }
     346             : 
     347        1234 :         D_DEBUG("Searching %"PRIu32" domain(s) for domain '%s'\n",
     348             :                 num_domains, wb_domain->name);
     349        1239 :         for (i=0; i<num_domains; i++) {
     350          77 :                 if (domains[i].domain != wb_domain) {
     351           5 :                         continue;
     352             :                 }
     353             : 
     354          72 :                 if (!domains[i].domain->internal) {
     355             :                         /*
     356             :                          * If it's not our local sam,
     357             :                          * we can re-use the domain without
     358             :                          * checking the sid.
     359             :                          *
     360             :                          * Note the wb_lookupsids_bulk() above
     361             :                          * already caught special SIDs,
     362             :                          * e.g. the unix and builtin domains.
     363             :                          */
     364          72 :                         return &domains[i];
     365             :                 }
     366             : 
     367           0 :                 if (dom_sid_compare_domain(sid, &domains[i].domain->sid) == 0) {
     368             :                         /*
     369             :                          * If it's out local sam we can also use it.
     370             :                          */
     371           0 :                         return &domains[i];
     372             :                 }
     373             : 
     374             :                 /*
     375             :                  * I'm not sure if this can be triggered,
     376             :                  * as wb_lookupsids_bulk() should also catch this,
     377             :                  * but we need to make sure that we don't use
     378             :                  * wbint_LookupRids() without a SID match.
     379             :                  */
     380           0 :                 return NULL;
     381             :         }
     382             : 
     383        1162 :         domains = talloc_realloc(
     384             :                 mem_ctx, domains, struct wb_lookupsids_domain, num_domains+1);
     385        1162 :         if (domains == NULL) {
     386           0 :                 return NULL;
     387             :         }
     388        1162 :         *pdomains = domains;
     389             : 
     390        1162 :         domain = &domains[num_domains];
     391        1162 :         domain->domain = wb_domain;
     392             : 
     393        1162 :         domain->sids.sids = talloc_zero_array(domains, struct lsa_SidPtr, num_sids);
     394        1162 :         if (domains->sids.sids == NULL) {
     395           0 :                 goto fail;
     396             :         }
     397        1162 :         domain->sids.num_sids = 0;
     398             : 
     399        1162 :         domain->sid_indexes = talloc_zero_array(domains, uint32_t, num_sids);
     400        1162 :         if (domain->sid_indexes == NULL) {
     401           0 :                 TALLOC_FREE(domain->sids.sids);
     402           0 :                 goto fail;
     403             :         }
     404        1162 :         return domain;
     405             : 
     406           0 : fail:
     407             :         /*
     408             :          * Realloc to the state it was in before
     409             :          */
     410           0 :         *pdomains = talloc_realloc(
     411             :                 mem_ctx, domains, struct wb_lookupsids_domain, num_domains);
     412           0 :         return NULL;
     413             : }
     414             : 
     415         788 : static bool wb_lookupsids_find_dom_idx(struct lsa_DomainInfo *domain,
     416             :                                        struct lsa_RefDomainList *list,
     417             :                                        uint32_t *idx)
     418             : {
     419           0 :         uint32_t i;
     420           0 :         struct lsa_DomainInfo *new_domain;
     421             : 
     422         793 :         for (i=0; i<list->count; i++) {
     423          65 :                 if (dom_sid_equal(domain->sid, list->domains[i].sid)) {
     424          60 :                         *idx = i;
     425          60 :                         return true;
     426             :                 }
     427             :         }
     428             : 
     429         728 :         new_domain = &list->domains[list->count];
     430             : 
     431        1456 :         new_domain->name.string = talloc_strdup(
     432         728 :                 list->domains, domain->name.string);
     433         728 :         if (new_domain->name.string == NULL) {
     434           0 :                 return false;
     435             :         }
     436             : 
     437         728 :         new_domain->sid = dom_sid_dup(list->domains, domain->sid);
     438         728 :         if (new_domain->sid == NULL) {
     439           0 :                 return false;
     440             :         }
     441             : 
     442         728 :         *idx = list->count;
     443         728 :         list->count += 1;
     444         728 :         return true;
     445             : }
     446             : 
     447        1242 : static bool wb_lookupsids_move_name(struct lsa_RefDomainList *src_domains,
     448             :                                     struct lsa_TranslatedName *src_name,
     449             :                                     struct lsa_RefDomainList *dst_domains,
     450             :                                     struct lsa_TransNameArray *dst_names,
     451             :                                     uint32_t dst_name_index)
     452             : {
     453           0 :         struct lsa_TranslatedName *dst_name;
     454           0 :         struct lsa_DomainInfo *src_domain;
     455           0 :         uint32_t src_domain_index;
     456        1242 :         uint32_t dst_domain_index = UINT32_MAX;
     457           0 :         bool ok;
     458             : 
     459        1242 :         src_domain_index = src_name->sid_index;
     460        1242 :         if ((src_domain_index != UINT32_MAX) && (src_domains != NULL)) {
     461         788 :                 if (src_domain_index >= src_domains->count) {
     462           0 :                         return false;
     463             :                 }
     464         788 :                 src_domain = &src_domains->domains[src_domain_index];
     465             : 
     466         788 :                 ok = wb_lookupsids_find_dom_idx(src_domain,
     467             :                                                 dst_domains,
     468             :                                                 &dst_domain_index);
     469         788 :                 if (!ok) {
     470           0 :                         return false;
     471             :                 }
     472             :         }
     473             : 
     474        1242 :         dst_name = &dst_names->names[dst_name_index];
     475             : 
     476        1242 :         dst_name->sid_type = src_name->sid_type;
     477        1242 :         dst_name->name.string = talloc_move(dst_names->names,
     478             :                                             &src_name->name.string);
     479        1242 :         dst_name->sid_index = dst_domain_index;
     480        1242 :         dst_names->count += 1;
     481             : 
     482        1242 :         return true;
     483             : }
     484             : 
     485        1160 : static void wb_lookupsids_done(struct tevent_req *subreq)
     486             : {
     487        1160 :         struct tevent_req *req = tevent_req_callback_data(
     488             :                 subreq, struct tevent_req);
     489        1160 :         struct wb_lookupsids_state *state = tevent_req_data(
     490             :                 req, struct wb_lookupsids_state);
     491           0 :         struct wb_lookupsids_domain *d;
     492           0 :         uint32_t i;
     493             : 
     494           0 :         NTSTATUS status, result;
     495             : 
     496        1160 :         status = dcerpc_wbint_LookupSids_recv(subreq, state, &result);
     497        1160 :         TALLOC_FREE(subreq);
     498        1160 :         if (tevent_req_nterror(req, status)) {
     499           0 :                 return;
     500             :         }
     501        1160 :         if (NT_STATUS_LOOKUP_ERR(result)) {
     502           0 :                 tevent_req_nterror(req, result);
     503           0 :                 return;
     504             :         }
     505             : 
     506             :         /*
     507             :          * Look at the individual states in the translated names.
     508             :          */
     509             : 
     510        1160 :         d = &state->domains[state->domains_done];
     511             : 
     512        2392 :         for (i=0; i<state->tmp_names.count; i++) {
     513        1232 :                 uint32_t res_sid_index = d->sid_indexes[i];
     514             : 
     515        1232 :                 if (!wb_lookupsids_move_name(
     516        1232 :                             &state->tmp_domains, &state->tmp_names.names[i],
     517             :                             state->res_domains, state->res_names,
     518             :                             res_sid_index)) {
     519           0 :                         tevent_req_oom(req);
     520           0 :                         return;
     521             :                 }
     522             :         }
     523        1160 :         state->domains_done += 1;
     524        1160 :         wb_lookupsids_next(req, state);
     525             : }
     526             : 
     527         736 : static void wb_lookupsids_single_done(struct tevent_req *subreq)
     528             : {
     529         736 :         struct tevent_req *req = tevent_req_callback_data(
     530             :                 subreq, struct tevent_req);
     531         736 :         struct wb_lookupsids_state *state = tevent_req_data(
     532             :                 req, struct wb_lookupsids_state);
     533         736 :         const char *domain_name = NULL;
     534         736 :         const char *name = NULL;
     535         736 :         enum lsa_SidType type = SID_NAME_UNKNOWN;
     536           0 :         uint32_t res_sid_index;
     537           0 :         uint32_t src_rid;
     538             : 
     539           0 :         struct dom_sid src_domain_sid;
     540           0 :         struct lsa_DomainInfo src_domain;
     541           0 :         struct lsa_RefDomainList src_domains;
     542         736 :         struct lsa_RefDomainList *psrc_domains = NULL;
     543           0 :         struct lsa_TranslatedName src_name;
     544             : 
     545         736 :         uint32_t domain_idx = UINT32_MAX;
     546           0 :         NTSTATUS status;
     547           0 :         bool ok;
     548             : 
     549         736 :         status = wb_lookupsid_recv(subreq, talloc_tos(), &type,
     550             :                                    &domain_name, &name);
     551         736 :         TALLOC_FREE(subreq);
     552         736 :         if (NT_STATUS_LOOKUP_ERR(status)) {
     553         728 :                 tevent_req_nterror(req, status);
     554         728 :                 return;
     555             :         }
     556             : 
     557           8 :         res_sid_index = state->single_sids[state->single_sids_done];
     558             : 
     559           8 :         if ((domain_name != NULL) && (domain_name[0] != '\0')) {
     560             :                 /*
     561             :                  * Build structs with the domain name for
     562             :                  * wb_lookupsids_move_name(). If we didn't get a name, we will
     563             :                  * pass NULL and UINT32_MAX.
     564             :                  */
     565             : 
     566           6 :                 sid_copy(&src_domain_sid, &state->sids[res_sid_index]);
     567           6 :                 if (type != SID_NAME_DOMAIN) {
     568           0 :                         sid_split_rid(&src_domain_sid, &src_rid);
     569             :                 }
     570             : 
     571           6 :                 src_domain.name.string = domain_name;
     572           6 :                 src_domain.sid = &src_domain_sid;
     573             : 
     574           6 :                 src_domains.count = 1;
     575           6 :                 src_domains.domains = &src_domain;
     576           6 :                 psrc_domains = &src_domains;
     577             : 
     578           6 :                 domain_idx = 0;
     579             :         }
     580             : 
     581           8 :         src_name.sid_type = type;
     582           8 :         src_name.name.string = name;
     583           8 :         src_name.sid_index = domain_idx;
     584             : 
     585           8 :         ok = wb_lookupsids_move_name(psrc_domains,
     586             :                                      &src_name,
     587             :                                      state->res_domains,
     588             :                                      state->res_names,
     589             :                                      res_sid_index);
     590           8 :         if (!ok) {
     591           0 :                 tevent_req_oom(req);
     592           0 :                 return;
     593             :         }
     594           8 :         state->single_sids_done += 1;
     595           8 :         wb_lookupsids_next(req, state);
     596             : }
     597             : 
     598           2 : static void wb_lookupsids_lookuprids_done(struct tevent_req *subreq)
     599             : {
     600           2 :         struct tevent_req *req = tevent_req_callback_data(
     601             :                 subreq, struct tevent_req);
     602           2 :         struct wb_lookupsids_state *state = tevent_req_data(
     603             :                 req, struct wb_lookupsids_state);
     604           0 :         struct dom_sid src_domain_sid;
     605           0 :         struct lsa_DomainInfo src_domain;
     606           0 :         struct lsa_RefDomainList src_domains;
     607           0 :         NTSTATUS status, result;
     608           0 :         struct wb_lookupsids_domain *d;
     609           0 :         uint32_t i;
     610             : 
     611           2 :         status = dcerpc_wbint_LookupRids_recv(subreq, state, &result);
     612           2 :         TALLOC_FREE(subreq);
     613           2 :         if (tevent_req_nterror(req, status)) {
     614           0 :                 return;
     615             :         }
     616           2 :         if (NT_STATUS_LOOKUP_ERR(result)) {
     617           0 :                 tevent_req_nterror(req, result);
     618           0 :                 return;
     619             :         }
     620             : 
     621             :         /*
     622             :          * Look at the individual states in the translated names.
     623             :          */
     624             : 
     625           2 :         d = &state->domains[state->domains_done];
     626             : 
     627           2 :         sid_copy(&src_domain_sid, get_global_sam_sid());
     628           2 :         src_domain.name.string = get_global_sam_name();
     629           2 :         src_domain.sid = &src_domain_sid;
     630           2 :         src_domains.count = 1;
     631           2 :         src_domains.domains = &src_domain;
     632             : 
     633           4 :         for (i=0; i<state->rid_names.num_principals; i++) {
     634           0 :                 struct lsa_TranslatedName src_name;
     635           0 :                 uint32_t res_sid_index;
     636             : 
     637             :                 /*
     638             :                  * Fake up structs for wb_lookupsids_move_name
     639             :                  */
     640           2 :                 res_sid_index = d->sid_indexes[i];
     641             : 
     642           2 :                 src_name.sid_type = state->rid_names.principals[i].type;
     643           2 :                 src_name.name.string = state->rid_names.principals[i].name;
     644           2 :                 src_name.sid_index = 0;
     645             : 
     646           2 :                 if (!wb_lookupsids_move_name(
     647             :                             &src_domains, &src_name,
     648             :                             state->res_domains, state->res_names,
     649             :                             res_sid_index)) {
     650           0 :                         tevent_req_oom(req);
     651           0 :                         return;
     652             :                 }
     653             :         }
     654             : 
     655           2 :         state->domains_done += 1;
     656           2 :         wb_lookupsids_next(req, state);
     657             : }
     658             : 
     659        2094 : NTSTATUS wb_lookupsids_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
     660             :                             struct lsa_RefDomainList **domains,
     661             :                             struct lsa_TransNameArray **names)
     662             : {
     663        2094 :         struct wb_lookupsids_state *state = tevent_req_data(
     664             :                 req, struct wb_lookupsids_state);
     665           0 :         NTSTATUS status;
     666             : 
     667        2094 :         D_INFO("WB command lookupsids end.\n");
     668        2094 :         if (tevent_req_is_nterror(req, &status)) {
     669         728 :                 D_WARNING("Failed with %s.\n", nt_errstr(status));
     670         728 :                 return status;
     671             :         }
     672             : 
     673             :         /*
     674             :          * The returned names need to match the given sids,
     675             :          * if not we have a bug in the code!
     676             :          */
     677        1366 :         if (state->res_names->count != state->num_sids) {
     678           0 :                 D_WARNING("Got %"PRIu32" returned name(s), but expected %"PRIu32"!\n",
     679             :                           state->res_names->count, state->num_sids);
     680           0 :                 return NT_STATUS_INTERNAL_ERROR;
     681             :         }
     682             : 
     683             :         /*
     684             :          * Not strictly needed, but it might make debugging in the callers
     685             :          * easier in future, if the talloc_array_length() returns the
     686             :          * expected result...
     687             :          */
     688        1366 :         state->res_domains->domains = talloc_realloc(state->res_domains,
     689             :                                                      state->res_domains->domains,
     690             :                                                      struct lsa_DomainInfo,
     691             :                                                      state->res_domains->count);
     692             : 
     693        1366 :         *domains = talloc_move(mem_ctx, &state->res_domains);
     694        1366 :         *names = talloc_move(mem_ctx, &state->res_names);
     695        1366 :         D_INFO("Returning %"PRIu32" domain(s) and %"PRIu32" name(s).\n",
     696             :                (*domains)->count,
     697             :                (*names)->count);
     698        1366 :         return NT_STATUS_OK;
     699             : }

Generated by: LCOV version 1.14