LCOV - code coverage report
Current view: top level - source4/rpc_server/lsa - lsa_lookup.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 841 1003 83.8 %
Date: 2024-06-13 04:01:37 Functions: 28 28 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    endpoint server for the lsarpc pipe
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2004
       7             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2007
       8             :    
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             :    
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             :    
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "rpc_server/lsa/lsa.h"
      24             : #include "libds/common/roles.h"
      25             : #include "libds/common/flag_mapping.h"
      26             : #include "lib/messaging/irpc.h"
      27             : #include "librpc/gen_ndr/ndr_lsa_c.h"
      28             : 
      29             : struct dcesrv_lsa_TranslatedItem {
      30             :         enum lsa_SidType type;
      31             :         const struct dom_sid *sid;
      32             :         const char *name;
      33             :         const char *authority_name;
      34             :         const struct dom_sid *authority_sid;
      35             :         uint32_t flags;
      36             :         uint32_t wb_idx;
      37             :         bool done;
      38             :         struct {
      39             :                 const char *domain; /* only $DOMAIN\ */
      40             :                 const char *namespace; /* $NAMESPACE\ or @$NAMESPACE */
      41             :                 const char *principal; /* \$PRINCIPAL or $PRIN@IPAL */
      42             :                 const char *sid; /* "S-1-5-21-9000-8000-7000-6000" */
      43             :                 const char *rid; /* "00001770" */
      44             :         } hints;
      45             : };
      46             : 
      47             : struct dcesrv_lsa_LookupSids_base_state;
      48             : struct dcesrv_lsa_LookupNames_base_state;
      49             : 
      50             : struct dcesrv_lsa_Lookup_view {
      51             :         const char *name;
      52             :         NTSTATUS (*lookup_sid)(struct dcesrv_lsa_LookupSids_base_state *state,
      53             :                                struct dcesrv_lsa_TranslatedItem *item);
      54             :         NTSTATUS (*lookup_name)(struct dcesrv_lsa_LookupNames_base_state *state,
      55             :                                 struct dcesrv_lsa_TranslatedItem *item);
      56             : };
      57             : 
      58             : struct dcesrv_lsa_Lookup_view_table {
      59             :         const char *name;
      60             :         size_t count;
      61             :         const struct dcesrv_lsa_Lookup_view **array;
      62             : };
      63             : 
      64             : static const struct dcesrv_lsa_Lookup_view_table *dcesrv_lsa_view_table(
      65             :         enum lsa_LookupNamesLevel level);
      66             : 
      67             : /*
      68             :   lookup a SID for 1 name
      69             : */
      70       12356 : static NTSTATUS dcesrv_lsa_lookup_name(struct lsa_policy_state *state,
      71             :                                        TALLOC_CTX *mem_ctx,
      72             :                                        const char *domain_name,
      73             :                                        const struct dom_sid *domain_sid,
      74             :                                        struct ldb_dn *domain_dn,
      75             :                                        const char *principal,
      76             :                                        const struct dom_sid **p_sid,
      77             :                                        enum lsa_SidType *p_type)
      78             : {
      79       12356 :         const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
      80       12356 :         struct ldb_message **res = NULL;
      81       12356 :         const char *nt4_account = NULL;
      82       12356 :         char *encoded_account = NULL;
      83       12356 :         const char *at = NULL;
      84             :         NTSTATUS status;
      85       12356 :         const struct dom_sid *sid = NULL;
      86             :         uint32_t atype;
      87             :         enum lsa_SidType type;
      88       12356 :         bool match = false;
      89             :         int ret;
      90             : 
      91       12356 :         if ((principal == NULL) || (principal[0] == '\0')) {
      92           0 :                 return NT_STATUS_NONE_MAPPED;
      93             :         }
      94             : 
      95       12356 :         at = strchr(principal, '@');
      96       12356 :         if (at != NULL) {
      97         218 :                 const char *nt4_domain = NULL;
      98             : 
      99         218 :                 status = crack_name_to_nt4_name(mem_ctx,
     100             :                                                 state->sam_ldb,
     101             :                                                 DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
     102             :                                                 principal,
     103             :                                                 &nt4_domain,
     104             :                                                 &nt4_account);
     105         218 :                 if (!NT_STATUS_IS_OK(status)) {
     106           0 :                         DEBUG(3, ("Failed to crack name %s into an NT4 name: %s\n",
     107             :                                   principal, nt_errstr(status)));
     108          96 :                         return status;
     109             :                 }
     110             : 
     111         218 :                 match = strequal(nt4_domain, domain_name);
     112         218 :                 if (!match) {
     113             :                         /*
     114             :                          * TODO: handle multiple domains in a forest.
     115             :                          */
     116          96 :                         return NT_STATUS_NONE_MAPPED;
     117             :                 }
     118             :         } else {
     119       12138 :                 nt4_account = principal;
     120             :         }
     121             : 
     122       12260 :         encoded_account = ldb_binary_encode_string(mem_ctx, nt4_account);
     123       12260 :         if (encoded_account == NULL) {
     124           0 :                 return NT_STATUS_NO_MEMORY;
     125             :         }
     126             : 
     127       12260 :         ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs, 
     128             :                            "(&(sAMAccountName=%s)(objectSid=*))", 
     129             :                            encoded_account);
     130       12260 :         TALLOC_FREE(encoded_account);
     131       12260 :         if (ret < 0) {
     132           0 :                 return NT_STATUS_INTERNAL_DB_ERROR;
     133             :         }
     134       12260 :         if (ret == 0) {
     135         254 :                 return NT_STATUS_NONE_MAPPED;
     136             :         }
     137       12006 :         if (ret > 1) {
     138           0 :                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
     139           0 :                 DBG_ERR("nt4_account[%s] found %d times (principal[%s]) - %s\n",
     140             :                         nt4_account, ret, principal, nt_errstr(status));
     141           0 :                 return status;
     142             :         }
     143             : 
     144       12006 :         sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
     145       12006 :         if (sid == NULL) {
     146           0 :                 return NT_STATUS_NO_MEMORY;
     147             :         }
     148             : 
     149             :         /* Check that this is in the domain */
     150       12006 :         match = dom_sid_in_domain(domain_sid, sid);
     151       12006 :         if (!match) {
     152           0 :                 return NT_STATUS_NONE_MAPPED;
     153             :         }
     154             : 
     155       12006 :         atype = ldb_msg_find_attr_as_uint(res[0], "sAMAccountType", 0);
     156       12006 :         type = ds_atype_map(atype);
     157       12006 :         if (type == SID_NAME_UNKNOWN) {
     158           0 :                 return NT_STATUS_NONE_MAPPED;
     159             :         }
     160             : 
     161       12006 :         *p_sid = sid;
     162       12006 :         *p_type = type;
     163       12006 :         return NT_STATUS_OK;
     164             : }
     165             : 
     166             : 
     167             : /*
     168             :   add to the lsa_RefDomainList for LookupSids and LookupNames
     169             : */
     170       24388 : static NTSTATUS dcesrv_lsa_authority_list(const char *authority_name,
     171             :                                           const struct dom_sid *authority_sid,
     172             :                                           struct lsa_RefDomainList *domains,
     173             :                                           uint32_t *sid_index)
     174             : {
     175             :         uint32_t i;
     176             : 
     177       24388 :         *sid_index = UINT32_MAX;
     178             : 
     179       24388 :         if (authority_name == NULL) {
     180          38 :                 return NT_STATUS_OK;
     181             :         }
     182             : 
     183             :         /* see if we've already done this authority name */
     184       24350 :         for (i=0;i<domains->count;i++) {
     185       22995 :                 if (strcasecmp_m(authority_name, domains->domains[i].name.string) == 0) {
     186       22995 :                         *sid_index = i;
     187       22995 :                         return NT_STATUS_OK;
     188             :                 }
     189             :         }
     190             : 
     191        1355 :         domains->domains = talloc_realloc(domains, 
     192             :                                           domains->domains,
     193             :                                           struct lsa_DomainInfo,
     194             :                                           domains->count+1);
     195        1355 :         if (domains->domains == NULL) {
     196           0 :                 return NT_STATUS_NO_MEMORY;
     197             :         }
     198        1355 :         domains->domains[i].name.string = talloc_strdup(domains->domains,
     199             :                                                         authority_name);
     200        1355 :         if (domains->domains[i].name.string == NULL) {
     201           0 :                 return NT_STATUS_NO_MEMORY;
     202             :         }
     203        1355 :         domains->domains[i].sid         = dom_sid_dup(domains->domains,
     204             :                                                       authority_sid);
     205        1355 :         if (domains->domains[i].sid == NULL) {
     206           0 :                 return NT_STATUS_NO_MEMORY;
     207             :         }
     208        1355 :         domains->count++;
     209        1355 :         domains->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER * domains->count;
     210        1355 :         *sid_index = i;
     211             : 
     212        1355 :         return NT_STATUS_OK;
     213             : }
     214             : 
     215             : /*
     216             :   lookup a name for 1 SID
     217             : */
     218       12034 : static NTSTATUS dcesrv_lsa_lookup_sid(struct lsa_policy_state *state,
     219             :                                       TALLOC_CTX *mem_ctx,
     220             :                                       const char *domain_name,
     221             :                                       const struct dom_sid *domain_sid,
     222             :                                       struct ldb_dn *domain_dn,
     223             :                                       const struct dom_sid *sid,
     224             :                                       const char **p_name,
     225             :                                       enum lsa_SidType *p_type)
     226             : {
     227       12034 :         const char * const attrs[] = { "sAMAccountName", "sAMAccountType", NULL};
     228       12034 :         struct ldb_message **res = NULL;
     229       12034 :         char *encoded_sid = NULL;
     230       12034 :         const char *name = NULL;
     231             :         uint32_t atype;
     232             :         enum lsa_SidType type;
     233             :         int ret;
     234             : 
     235       12034 :         encoded_sid = ldap_encode_ndr_dom_sid(mem_ctx, sid);
     236       12034 :         if (encoded_sid == NULL) {
     237           0 :                 return NT_STATUS_NO_MEMORY;
     238             :         }
     239             : 
     240       12034 :         ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs, 
     241             :                            "(&(objectSid=%s)(sAMAccountName=*))", encoded_sid);
     242       12034 :         TALLOC_FREE(encoded_sid);
     243       12034 :         if (ret < 0) {
     244           0 :                 return NT_STATUS_INTERNAL_DB_ERROR;
     245             :         }
     246       12034 :         if (ret == 0) {
     247           6 :                 return NT_STATUS_NONE_MAPPED;
     248             :         }
     249       12028 :         if (ret > 1) {
     250           0 :                 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
     251           0 :                 DBG_ERR("sid[%s] found %d times - %s\n",
     252             :                         dom_sid_string(mem_ctx, sid), ret, nt_errstr(status));
     253           0 :                 return status;
     254             :         }
     255             : 
     256       12028 :         name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL);
     257       12028 :         if (name == NULL) {
     258           0 :                 return NT_STATUS_INTERNAL_ERROR;
     259             :         }
     260             : 
     261       12028 :         atype = ldb_msg_find_attr_as_uint(res[0], "sAMAccountType", 0);
     262       12028 :         type = ds_atype_map(atype);
     263       12028 :         if (type == SID_NAME_UNKNOWN) {
     264           0 :                 return NT_STATUS_NONE_MAPPED;
     265             :         }
     266             : 
     267       12028 :         *p_name = name;
     268       12028 :         *p_type = type;
     269       12028 :         return NT_STATUS_OK;
     270             : }
     271             : 
     272             : struct dcesrv_lsa_LookupSids_base_state {
     273             :         struct dcesrv_call_state *dce_call;
     274             : 
     275             :         TALLOC_CTX *mem_ctx;
     276             : 
     277             :         struct lsa_policy_state *policy_state;
     278             : 
     279             :         struct lsa_LookupSids3 r;
     280             : 
     281             :         const struct dcesrv_lsa_Lookup_view_table *view_table;
     282             :         struct dcesrv_lsa_TranslatedItem *items;
     283             : 
     284             :         struct dsdb_trust_routing_table *routing_table;
     285             : 
     286             :         struct {
     287             :                 struct dcerpc_binding_handle *irpc_handle;
     288             :                 struct lsa_SidArray sids;
     289             :                 struct lsa_RefDomainList *domains;
     290             :                 struct lsa_TransNameArray2 names;
     291             :                 uint32_t count;
     292             :                 NTSTATUS result;
     293             :         } wb;
     294             : 
     295             :         struct {
     296             :                 struct lsa_LookupSids *l;
     297             :                 struct lsa_LookupSids2 *l2;
     298             :                 struct lsa_LookupSids3 *l3;
     299             :         } _r;
     300             : };
     301             : 
     302             : static NTSTATUS dcesrv_lsa_LookupSids_base_finish(
     303             :         struct dcesrv_lsa_LookupSids_base_state *state);
     304             : static void dcesrv_lsa_LookupSids_base_map(
     305             :         struct dcesrv_lsa_LookupSids_base_state *state);
     306             : static void dcesrv_lsa_LookupSids_base_done(struct tevent_req *subreq);
     307             : 
     308        1313 : static NTSTATUS dcesrv_lsa_LookupSids_base_call(struct dcesrv_lsa_LookupSids_base_state *state)
     309             : {
     310        1313 :         struct lsa_LookupSids3 *r = &state->r;
     311        1313 :         struct tevent_req *subreq = NULL;
     312             :         uint32_t v;
     313             :         uint32_t i;
     314             : 
     315        1313 :         *r->out.domains = NULL;
     316        1313 :         r->out.names->count = 0;
     317        1313 :         r->out.names->names = NULL;
     318        1313 :         *r->out.count = 0;
     319             : 
     320        1313 :         state->view_table = dcesrv_lsa_view_table(r->in.level);
     321        1313 :         if (state->view_table == NULL) {
     322           0 :                 return NT_STATUS_INVALID_PARAMETER;
     323             :         }
     324             : 
     325        1313 :         *r->out.domains = talloc_zero(r->out.domains, struct lsa_RefDomainList);
     326        1313 :         if (*r->out.domains == NULL) {
     327           0 :                 return NT_STATUS_NO_MEMORY;
     328             :         }
     329             : 
     330        1313 :         r->out.names->names = talloc_zero_array(r->out.names,
     331             :                                                 struct lsa_TranslatedName2,
     332             :                                                 r->in.sids->num_sids);
     333        1313 :         if (r->out.names->names == NULL) {
     334           0 :                 return NT_STATUS_NO_MEMORY;
     335             :         }
     336             : 
     337        1313 :         state->items = talloc_zero_array(state,
     338             :                                          struct dcesrv_lsa_TranslatedItem,
     339             :                                          r->in.sids->num_sids);
     340        1313 :         if (state->items == NULL) {
     341           0 :                 return NT_STATUS_NO_MEMORY;
     342             :         }
     343             : 
     344       27053 :         for (i=0;i<r->in.sids->num_sids;i++) {
     345       12663 :                 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
     346       12663 :                 uint32_t rid = 0;
     347             : 
     348       12663 :                 if (r->in.sids->sids[i].sid == NULL) {
     349           0 :                         return NT_STATUS_INVALID_PARAMETER;
     350             :                 }
     351             : 
     352       12663 :                 item->type = SID_NAME_UNKNOWN;
     353       12663 :                 item->sid = r->in.sids->sids[i].sid;
     354             : 
     355       12663 :                 item->hints.sid = dom_sid_string(state->items, item->sid);
     356       12663 :                 if (item->hints.sid == NULL) {
     357           0 :                         return NT_STATUS_NO_MEMORY;
     358             :                 }
     359             : 
     360       12663 :                 dom_sid_split_rid(state->items, item->sid, NULL, &rid);
     361       12663 :                 item->hints.rid = talloc_asprintf(state->items,
     362             :                                                   "%08X", (unsigned)rid);
     363       12663 :                 if (item->hints.rid == NULL) {
     364           0 :                         return NT_STATUS_NO_MEMORY;
     365             :                 }
     366             :         }
     367             : 
     368        4433 :         for (v=0; v < state->view_table->count; v++) {
     369        3696 :                 const struct dcesrv_lsa_Lookup_view *view =
     370        3696 :                         state->view_table->array[v];
     371             : 
     372       52164 :                 for (i=0; i < r->in.sids->num_sids; i++) {
     373       49044 :                         struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
     374             :                         NTSTATUS status;
     375             : 
     376       49044 :                         if (item->done) {
     377       23806 :                                 continue;
     378             :                         }
     379             : 
     380       25238 :                         status = view->lookup_sid(state, item);
     381       25238 :                         if (NT_STATUS_IS_OK(status)) {
     382       12069 :                                 item->done = true;
     383       13169 :                         } else if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
     384       12593 :                                 status = NT_STATUS_OK;
     385         576 :                         } else if (NT_STATUS_EQUAL(status, NT_STATUS_SOME_NOT_MAPPED)) {
     386           0 :                                 status = NT_STATUS_OK;
     387             :                         }
     388       25238 :                         if (!NT_STATUS_IS_OK(status)) {
     389         576 :                                 return status;
     390             :                         }
     391             :                 }
     392             :         }
     393             : 
     394         737 :         if (state->wb.irpc_handle == NULL) {
     395         719 :                 return dcesrv_lsa_LookupSids_base_finish(state);
     396             :         }
     397             : 
     398          18 :         state->wb.sids.sids = talloc_zero_array(state, struct lsa_SidPtr,
     399             :                                                 r->in.sids->num_sids);
     400          18 :         if (state->wb.sids.sids == NULL) {
     401           0 :                 return NT_STATUS_NO_MEMORY;
     402             :         }
     403             : 
     404          36 :         for (i=0; i < r->in.sids->num_sids; i++) {
     405          18 :                 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
     406             : 
     407          18 :                 if (item->done) {
     408           0 :                         continue;
     409             :                 }
     410             : 
     411          18 :                 item->wb_idx = state->wb.sids.num_sids;
     412          18 :                 state->wb.sids.sids[item->wb_idx] = r->in.sids->sids[i];
     413          18 :                 state->wb.sids.num_sids++;
     414             :         }
     415             : 
     416          27 :         subreq = dcerpc_lsa_LookupSids3_send(state,
     417          18 :                                              state->dce_call->event_ctx,
     418             :                                              state->wb.irpc_handle,
     419             :                                              &state->wb.sids,
     420             :                                              &state->wb.domains,
     421             :                                              &state->wb.names,
     422             :                                              state->r.in.level,
     423             :                                              &state->wb.count,
     424             :                                              state->r.in.lookup_options,
     425             :                                              state->r.in.client_revision);
     426          18 :         if (subreq == NULL) {
     427           0 :                 return NT_STATUS_NO_MEMORY;;
     428             :         }
     429          18 :         state->dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
     430          18 :         tevent_req_set_callback(subreq,
     431             :                                 dcesrv_lsa_LookupSids_base_done,
     432             :                                 state);
     433             : 
     434          18 :         return NT_STATUS_OK;
     435             : }
     436             : 
     437         737 : static NTSTATUS dcesrv_lsa_LookupSids_base_finish(
     438             :         struct dcesrv_lsa_LookupSids_base_state *state)
     439             : {
     440         737 :         struct lsa_LookupSids3 *r = &state->r;
     441             :         uint32_t i;
     442             : 
     443       12824 :         for (i=0;i<r->in.sids->num_sids;i++) {
     444       12087 :                 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
     445             :                 NTSTATUS status;
     446       12087 :                 uint32_t sid_index = UINT32_MAX;
     447             : 
     448       12087 :                 status = dcesrv_lsa_authority_list(item->authority_name,
     449             :                                                    item->authority_sid,
     450       12087 :                                                    *r->out.domains,
     451             :                                                    &sid_index);
     452       12087 :                 if (!NT_STATUS_IS_OK(status)) {
     453           0 :                         return status;
     454             :                 }
     455             : 
     456       12087 :                 if (item->name == NULL && r->in.level == LSA_LOOKUP_NAMES_ALL) {
     457          13 :                         if (sid_index == UINT32_MAX) {
     458          13 :                                 item->name = item->hints.sid;
     459             :                         } else {
     460           0 :                                 item->name = item->hints.rid;
     461             :                         }
     462             :                 }
     463             : 
     464       12087 :                 r->out.names->names[i].sid_type    = item->type;
     465       12087 :                 r->out.names->names[i].name.string = item->name;
     466       12087 :                 r->out.names->names[i].sid_index   = sid_index;
     467       12087 :                 r->out.names->names[i].unknown     = item->flags;
     468             : 
     469       12087 :                 r->out.names->count++;
     470       12087 :                 if (item->type != SID_NAME_UNKNOWN) {
     471       12068 :                         (*r->out.count)++;
     472             :                 }
     473             :         }
     474             : 
     475         737 :         if (*r->out.count == 0) {
     476          19 :                 return NT_STATUS_NONE_MAPPED;
     477             :         }
     478         718 :         if (*r->out.count != r->in.sids->num_sids) {
     479           0 :                 return STATUS_SOME_UNMAPPED;
     480             :         }
     481             : 
     482         718 :         return NT_STATUS_OK;
     483             : }
     484             : 
     485        1313 : static void dcesrv_lsa_LookupSids_base_map(
     486             :         struct dcesrv_lsa_LookupSids_base_state *state)
     487             : {
     488        1313 :         if (state->_r.l3 != NULL) {
     489         997 :                 struct lsa_LookupSids3 *r = state->_r.l3;
     490             : 
     491         997 :                 r->out.result = state->r.out.result;
     492         997 :                 return;
     493             :         }
     494             : 
     495         316 :         if (state->_r.l2 != NULL) {
     496           3 :                 struct lsa_LookupSids2 *r = state->_r.l2;
     497             : 
     498           3 :                 r->out.result = state->r.out.result;
     499           3 :                 return;
     500             :         }
     501             : 
     502         313 :         if (state->_r.l != NULL) {
     503         313 :                 struct lsa_LookupSids *r = state->_r.l;
     504             :                 uint32_t i;
     505             : 
     506         313 :                 r->out.result = state->r.out.result;
     507             : 
     508         313 :                 SMB_ASSERT(state->r.out.names->count <= r->in.sids->num_sids);
     509        1235 :                 for (i = 0; i < state->r.out.names->count; i++) {
     510         922 :                         struct lsa_TranslatedName2 *n2 =
     511         922 :                                 &state->r.out.names->names[i];
     512         922 :                         struct lsa_TranslatedName *n =
     513         922 :                                 &r->out.names->names[i];
     514             : 
     515         922 :                         n->sid_type = n2->sid_type;
     516         922 :                         n->name = n2->name;
     517         922 :                         n->sid_index = n2->sid_index;
     518             :                 }
     519         313 :                 r->out.names->count = state->r.out.names->count;
     520         313 :                 return;
     521             :         }
     522             : }
     523             : 
     524          18 : static void dcesrv_lsa_LookupSids_base_done(struct tevent_req *subreq)
     525             : {
     526           9 :         struct dcesrv_lsa_LookupSids_base_state *state =
     527          18 :                 tevent_req_callback_data(subreq,
     528             :                 struct dcesrv_lsa_LookupSids_base_state);
     529          18 :         struct dcesrv_call_state *dce_call = state->dce_call;
     530             :         NTSTATUS status;
     531             :         uint32_t i;
     532             : 
     533          18 :         status = dcerpc_lsa_LookupSids3_recv(subreq, state->mem_ctx,
     534             :                                              &state->wb.result);
     535          18 :         TALLOC_FREE(subreq);
     536          18 :         TALLOC_FREE(state->wb.irpc_handle);
     537          18 :         if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
     538           0 :                 DEBUG(0,(__location__ ": IRPC callback failed %s\n",
     539             :                          nt_errstr(status)));
     540           0 :                 goto finished;
     541          18 :         } else if (!NT_STATUS_IS_OK(status)) {
     542           0 :                 state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
     543           0 :                 DEBUG(0,(__location__ ": IRPC callback failed %s\n",
     544             :                          nt_errstr(status)));
     545           0 :                 goto finished;
     546             :         }
     547             : 
     548          18 :         status = state->wb.result;
     549          18 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
     550           0 :                 status = NT_STATUS_OK;
     551          18 :         } else if (NT_STATUS_EQUAL(status, NT_STATUS_SOME_NOT_MAPPED)) {
     552           0 :                 status = NT_STATUS_OK;
     553             :         }
     554          18 :         if (!NT_STATUS_IS_OK(status)) {
     555           0 :                 goto finished;
     556             :         }
     557             : 
     558          36 :         for (i=0; i < state->r.in.sids->num_sids; i++) {
     559          18 :                 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
     560          18 :                 struct lsa_TranslatedName2 *s2 = NULL;
     561          18 :                 struct lsa_DomainInfo *d = NULL;
     562             : 
     563          18 :                 if (item->done) {
     564           0 :                         continue;
     565             :                 }
     566             : 
     567          18 :                 if (item->wb_idx >= state->wb.names.count) {
     568           0 :                         status = NT_STATUS_INTERNAL_ERROR;
     569           0 :                         goto finished;
     570             :                 }
     571             : 
     572          18 :                 s2 = &state->wb.names.names[item->wb_idx];
     573             : 
     574          18 :                 item->type = s2->sid_type;
     575          18 :                 item->name = s2->name.string;
     576          18 :                 item->flags = s2->unknown;
     577             : 
     578          18 :                 if (s2->sid_index == UINT32_MAX) {
     579           0 :                         continue;
     580             :                 }
     581             : 
     582          18 :                 if (state->wb.domains == NULL) {
     583           0 :                         status = NT_STATUS_INTERNAL_ERROR;
     584           0 :                         goto finished;
     585             :                 }
     586             : 
     587          18 :                 if (s2->sid_index >= state->wb.domains->count) {
     588           0 :                         status = NT_STATUS_INTERNAL_ERROR;
     589           0 :                         goto finished;
     590             :                 }
     591             : 
     592          18 :                 d = &state->wb.domains->domains[s2->sid_index];
     593             : 
     594          18 :                 item->authority_name = d->name.string;
     595          18 :                 item->authority_sid = d->sid;
     596             :         }
     597             : 
     598          18 :         status = dcesrv_lsa_LookupSids_base_finish(state);
     599          18 :  finished:
     600          18 :         state->r.out.result = status;
     601          18 :         dcesrv_lsa_LookupSids_base_map(state);
     602             : 
     603          18 :         status = dcesrv_reply(dce_call);
     604          18 :         if (!NT_STATUS_IS_OK(status)) {
     605           0 :                 DEBUG(0,(__location__ ": dcesrv_reply() failed - %s\n", nt_errstr(status)));
     606             :         }
     607          18 : }
     608             : 
     609             : /*
     610             :   lsa_LookupSids2
     611             : */
     612           3 : NTSTATUS dcesrv_lsa_LookupSids2(struct dcesrv_call_state *dce_call,
     613             :                                 TALLOC_CTX *mem_ctx,
     614             :                                 struct lsa_LookupSids2 *r)
     615             : {
     616           3 :         enum dcerpc_transport_t transport =
     617           3 :                 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
     618           3 :         struct dcesrv_lsa_LookupSids_base_state *state = NULL;
     619           3 :         struct dcesrv_handle *policy_handle = NULL;
     620             :         NTSTATUS status;
     621             : 
     622           3 :         if (transport != NCACN_NP && transport != NCALRPC) {
     623           0 :                 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
     624             :         }
     625             : 
     626           3 :         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
     627             : 
     628           3 :         *r->out.domains = NULL;
     629           3 :         r->out.names->count = 0;
     630           3 :         r->out.names->names = NULL;
     631           3 :         *r->out.count = 0;
     632             : 
     633           3 :         state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupSids_base_state);
     634           3 :         if (state == NULL) {
     635           0 :                 return NT_STATUS_NO_MEMORY;
     636             :         }
     637             : 
     638           3 :         state->dce_call = dce_call;
     639           3 :         state->mem_ctx = mem_ctx;
     640             : 
     641           3 :         state->policy_state = policy_handle->data;
     642             : 
     643           3 :         state->r.in.sids = r->in.sids;
     644           3 :         state->r.in.level = r->in.level;
     645           3 :         state->r.in.lookup_options = r->in.lookup_options;
     646           3 :         state->r.in.client_revision = r->in.client_revision;
     647           3 :         state->r.in.names = r->in.names;
     648           3 :         state->r.in.count = r->in.count;
     649           3 :         state->r.out.domains = r->out.domains;
     650           3 :         state->r.out.names = r->out.names;
     651           3 :         state->r.out.count = r->out.count;
     652             : 
     653           3 :         state->_r.l2 = r;
     654             : 
     655           3 :         status = dcesrv_lsa_LookupSids_base_call(state);
     656             : 
     657           3 :         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
     658           0 :                 return status;
     659             :         }
     660             : 
     661           3 :         state->r.out.result = status;
     662           3 :         dcesrv_lsa_LookupSids_base_map(state);
     663           3 :         return status;
     664             : }
     665             : 
     666             : /* A random hexidecimal number (honest!) */
     667             : #define LSA_SERVER_IMPLICIT_POLICY_STATE_MAGIC 0xc0c99e00
     668             : 
     669             : /*
     670             :   Ensure we're operating on an schannel connection,
     671             :   and use a lsa_policy_state cache on the connection.
     672             : */
     673        1532 : static NTSTATUS schannel_call_setup(struct dcesrv_call_state *dce_call,
     674             :                                     struct lsa_policy_state **_policy_state)
     675             : {
     676        1532 :         struct lsa_policy_state *policy_state = NULL;
     677         942 :         enum dcerpc_transport_t transport =
     678        1532 :                 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
     679        1532 :         enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
     680        1532 :         if (transport != NCACN_IP_TCP) {
     681             :                 /* We can't call DCESRV_FAULT() in the sub-function */
     682           7 :                 dce_call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
     683           7 :                 return NT_STATUS_ACCESS_DENIED;
     684             :         }
     685             : 
     686             :         /*
     687             :          * We don't have policy handles on this call. So this must be restricted
     688             :          * to crypto connections only.
     689             :          *
     690             :          * NB. gensec requires schannel connections to
     691             :          * have at least DCERPC_AUTH_LEVEL_INTEGRITY.
     692             :          */
     693        1525 :         dcesrv_call_auth_info(dce_call, &auth_type, NULL);
     694        1525 :         if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
     695             :                 /* We can't call DCESRV_FAULT() in the sub-function */
     696           7 :                 dce_call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
     697           7 :                 return NT_STATUS_ACCESS_DENIED;
     698             :         }
     699             : 
     700             :         /*
     701             :          * We don't have a policy handle on this call, so we want to
     702             :          * make a policy state and cache it for the life of the
     703             :          * connection, to avoid re-opening the DB each call.
     704             :          */
     705             :         policy_state
     706        1518 :                 = dcesrv_iface_state_find_conn(dce_call,
     707             :                                                LSA_SERVER_IMPLICIT_POLICY_STATE_MAGIC,
     708             :                                                struct lsa_policy_state);
     709             : 
     710        1518 :         if (policy_state == NULL) {
     711         140 :                 NTSTATUS status
     712          24 :                         = dcesrv_lsa_get_policy_state(dce_call,
     713             :                                                       dce_call /* mem_ctx */,
     714             :                                                       0, /* we skip access checks */
     715             :                                                       &policy_state);
     716         164 :                 if (!NT_STATUS_IS_OK(status)) {
     717           0 :                         return status;
     718             :                 }
     719             : 
     720             :                 /*
     721             :                  * This will talloc_steal() policy_state onto the
     722             :                  * connection, which has longer lifetime than the
     723             :                  * immidiate caller requires
     724             :                  */
     725         164 :                 status = dcesrv_iface_state_store_conn(dce_call,
     726             :                                                        LSA_SERVER_IMPLICIT_POLICY_STATE_MAGIC,
     727             :                                                        policy_state);
     728         164 :                 if (!NT_STATUS_IS_OK(status)) {
     729           0 :                         return status;
     730             :                 }
     731             :         }
     732        1518 :         *_policy_state = policy_state;
     733        1518 :         return NT_STATUS_OK;
     734             : }
     735             : 
     736             : /*
     737             :   lsa_LookupSids3
     738             : 
     739             :   Identical to LookupSids2, but doesn't take a policy handle
     740             : 
     741             : */
     742        1004 : NTSTATUS dcesrv_lsa_LookupSids3(struct dcesrv_call_state *dce_call,
     743             :                                 TALLOC_CTX *mem_ctx,
     744             :                                 struct lsa_LookupSids3 *r)
     745             : {
     746        1004 :         struct dcesrv_lsa_LookupSids_base_state *state = NULL;
     747             :         NTSTATUS status;
     748             : 
     749        1004 :         *r->out.domains = NULL;
     750        1004 :         r->out.names->count = 0;
     751        1004 :         r->out.names->names = NULL;
     752        1004 :         *r->out.count = 0;
     753             : 
     754        1004 :         state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupSids_base_state);
     755        1004 :         if (state == NULL) {
     756           0 :                 return NT_STATUS_NO_MEMORY;
     757             :         }
     758             : 
     759             :         /*
     760             :          * We don't have a policy handle on this call, so we want to
     761             :          * make a policy state and cache it for the life of the
     762             :          * connection, to avoid re-opening the DB each call.
     763             :          *
     764             :          * This also enforces that this is only available over
     765             :          * ncacn_ip_tcp and with SCHANNEL.
     766             :          *
     767             :          * schannel_call_setup may also set the fault state.
     768             :          *
     769             :          * state->policy_state is shared between all calls on this
     770             :          * connection and is moved with talloc_steal() under the
     771             :          * connection, not dce_call or state.
     772             :          */
     773        1004 :         status = schannel_call_setup(dce_call, &state->policy_state);
     774        1004 :         if (!NT_STATUS_IS_OK(status)) {
     775           7 :                 return status;
     776             :         }
     777             : 
     778         997 :         state->dce_call = dce_call;
     779         997 :         state->mem_ctx = mem_ctx;
     780         997 :         state->r.in.sids = r->in.sids;
     781         997 :         state->r.in.level = r->in.level;
     782         997 :         state->r.in.lookup_options = r->in.lookup_options;
     783         997 :         state->r.in.client_revision = r->in.client_revision;
     784         997 :         state->r.in.names = r->in.names;
     785         997 :         state->r.in.count = r->in.count;
     786         997 :         state->r.out.domains = r->out.domains;
     787         997 :         state->r.out.names = r->out.names;
     788         997 :         state->r.out.count = r->out.count;
     789             : 
     790         997 :         state->_r.l3 = r;
     791             : 
     792         997 :         status = dcesrv_lsa_LookupSids_base_call(state);
     793             : 
     794         997 :         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
     795          18 :                 return status;
     796             :         }
     797             : 
     798         979 :         state->r.out.result = status;
     799         979 :         dcesrv_lsa_LookupSids_base_map(state);
     800         979 :         return status;
     801             : }
     802             : 
     803             : 
     804             : /* 
     805             :   lsa_LookupSids 
     806             : */
     807         313 : NTSTATUS dcesrv_lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     808             :                                struct lsa_LookupSids *r)
     809             : {
     810         313 :         enum dcerpc_transport_t transport =
     811         313 :                 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
     812         313 :         struct dcesrv_lsa_LookupSids_base_state *state = NULL;
     813         313 :         struct dcesrv_handle *policy_handle = NULL;
     814             :         NTSTATUS status;
     815             : 
     816         313 :         if (transport != NCACN_NP && transport != NCALRPC) {
     817           0 :                 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
     818             :         }
     819             : 
     820         313 :         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
     821             : 
     822         313 :         *r->out.domains = NULL;
     823         313 :         r->out.names->count = 0;
     824         313 :         r->out.names->names = NULL;
     825         313 :         *r->out.count = 0;
     826             : 
     827         313 :         r->out.names->names = talloc_zero_array(r->out.names,
     828             :                                                 struct lsa_TranslatedName,
     829             :                                                 r->in.sids->num_sids);
     830         313 :         if (r->out.names->names == NULL) {
     831           0 :                 return NT_STATUS_NO_MEMORY;
     832             :         }
     833             : 
     834         313 :         state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupSids_base_state);
     835         313 :         if (state == NULL) {
     836           0 :                 return NT_STATUS_NO_MEMORY;
     837             :         }
     838             : 
     839         313 :         state->dce_call = dce_call;
     840         313 :         state->mem_ctx = mem_ctx;
     841             : 
     842         313 :         state->policy_state = policy_handle->data;
     843             : 
     844         313 :         state->r.in.sids = r->in.sids;
     845         313 :         state->r.in.level = r->in.level;
     846         313 :         state->r.in.lookup_options = LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES;
     847         313 :         state->r.in.client_revision = LSA_CLIENT_REVISION_1;
     848         313 :         state->r.in.names = talloc_zero(state, struct lsa_TransNameArray2);
     849         313 :         if (state->r.in.names == NULL) {
     850           0 :                 return NT_STATUS_NO_MEMORY;
     851             :         }
     852         313 :         state->r.in.count = r->in.count;
     853         313 :         state->r.out.domains = r->out.domains;
     854         313 :         state->r.out.names = talloc_zero(state, struct lsa_TransNameArray2);
     855         313 :         if (state->r.out.names == NULL) {
     856           0 :                 return NT_STATUS_NO_MEMORY;
     857             :         }
     858         313 :         state->r.out.count = r->out.count;
     859             : 
     860         313 :         state->_r.l = r;
     861             : 
     862         313 :         status = dcesrv_lsa_LookupSids_base_call(state);
     863             : 
     864         313 :         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
     865           0 :                 return status;
     866             :         }
     867             : 
     868         313 :         state->r.out.result = status;
     869         313 :         dcesrv_lsa_LookupSids_base_map(state);
     870         313 :         return status;
     871             : }
     872             : 
     873             : struct dcesrv_lsa_LookupNames_base_state {
     874             :         struct dcesrv_call_state *dce_call;
     875             : 
     876             :         TALLOC_CTX *mem_ctx;
     877             : 
     878             :         struct lsa_policy_state *policy_state;
     879             : 
     880             :         struct lsa_LookupNames4 r;
     881             : 
     882             :         const struct dcesrv_lsa_Lookup_view_table *view_table;
     883             :         struct dcesrv_lsa_TranslatedItem *items;
     884             : 
     885             :         struct dsdb_trust_routing_table *routing_table;
     886             : 
     887             :         struct {
     888             :                 struct dcerpc_binding_handle *irpc_handle;
     889             :                 uint32_t num_names;
     890             :                 struct lsa_String *names;
     891             :                 struct lsa_RefDomainList *domains;
     892             :                 struct lsa_TransSidArray3 sids;
     893             :                 uint32_t count;
     894             :                 NTSTATUS result;
     895             :         } wb;
     896             : 
     897             :         struct {
     898             :                 struct lsa_LookupNames *l;
     899             :                 struct lsa_LookupNames2 *l2;
     900             :                 struct lsa_LookupNames3 *l3;
     901             :                 struct lsa_LookupNames4 *l4;
     902             :         } _r;
     903             : };
     904             : 
     905             : static NTSTATUS dcesrv_lsa_LookupNames_base_finish(
     906             :         struct dcesrv_lsa_LookupNames_base_state *state);
     907             : static void dcesrv_lsa_LookupNames_base_map(
     908             :         struct dcesrv_lsa_LookupNames_base_state *state);
     909             : static void dcesrv_lsa_LookupNames_base_done(struct tevent_req *subreq);
     910             : 
     911         780 : static NTSTATUS dcesrv_lsa_LookupNames_base_call(struct dcesrv_lsa_LookupNames_base_state *state)
     912             : {
     913         780 :         struct lsa_LookupNames4 *r = &state->r;
     914         780 :         enum lsa_LookupOptions invalid_lookup_options = 0;
     915         780 :         struct tevent_req *subreq = NULL;
     916             :         uint32_t v;
     917             :         uint32_t i;
     918             : 
     919         780 :         *r->out.domains = NULL;
     920         780 :         r->out.sids->count = 0;
     921         780 :         r->out.sids->sids = NULL;
     922         780 :         *r->out.count = 0;
     923             : 
     924         780 :         if (r->in.level != LSA_LOOKUP_NAMES_ALL) {
     925         323 :                 invalid_lookup_options |=
     926             :                         LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES_LOCAL;
     927             :         }
     928         780 :         if (r->in.lookup_options & invalid_lookup_options) {
     929           0 :                 return NT_STATUS_INVALID_PARAMETER;
     930             :         }
     931             : 
     932         780 :         state->view_table = dcesrv_lsa_view_table(r->in.level);
     933         780 :         if (state->view_table == NULL) {
     934           0 :                 return NT_STATUS_INVALID_PARAMETER;
     935             :         }
     936             : 
     937         780 :         *r->out.domains = talloc_zero(r->out.domains, struct lsa_RefDomainList);
     938         780 :         if (*r->out.domains == NULL) {
     939           0 :                 return NT_STATUS_NO_MEMORY;
     940             :         }
     941             : 
     942         780 :         r->out.sids->sids = talloc_zero_array(r->out.sids,
     943             :                                               struct lsa_TranslatedSid3,
     944             :                                               r->in.num_names);
     945         780 :         if (r->out.sids->sids == NULL) {
     946           0 :                 return NT_STATUS_NO_MEMORY;
     947             :         }
     948             : 
     949         780 :         state->items = talloc_zero_array(state,
     950             :                                          struct dcesrv_lsa_TranslatedItem,
     951             :                                          r->in.num_names);
     952         780 :         if (state->items == NULL) {
     953           0 :                 return NT_STATUS_NO_MEMORY;
     954             :         }
     955             : 
     956       13097 :         for (i=0;i<r->in.num_names;i++) {
     957       12317 :                 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
     958       12317 :                 char *p = NULL;
     959             : 
     960       12317 :                 item->type = SID_NAME_UNKNOWN;
     961       12317 :                 item->name = r->in.names[i].string;
     962             :                 /*
     963             :                  * Note: that item->name can be NULL!
     964             :                  *
     965             :                  * See test_LookupNames_NULL() in
     966             :                  * source4/torture/rpc/lsa.c
     967             :                  *
     968             :                  * nt4 returns NT_STATUS_NONE_MAPPED with sid_type
     969             :                  * SID_NAME_UNKNOWN, rid 0, and sid_index -1;
     970             :                  *
     971             :                  * w2k3/w2k8 return NT_STATUS_OK with sid_type
     972             :                  * SID_NAME_DOMAIN, rid -1 and sid_index 0 and BUILTIN domain
     973             :                  */
     974       12317 :                 if (item->name == NULL) {
     975           3 :                         continue;
     976             :                 }
     977             : 
     978       12314 :                 item->hints.principal = item->name;
     979       12314 :                 p = strchr(item->name, '\\');
     980       12314 :                 if (p != NULL && p != item->name) {
     981         693 :                         item->hints.domain = talloc_strndup(state->items,
     982             :                                                             item->name,
     983         545 :                                                             p - item->name);
     984         545 :                         if (item->hints.domain == NULL) {
     985           0 :                                 return NT_STATUS_NO_MEMORY;
     986             :                         }
     987         545 :                         item->hints.namespace = item->hints.domain;
     988         545 :                         p++;
     989         545 :                         if (p[0] == '\0') {
     990             :                                 /*
     991             :                                  * This is just 'BUILTIN\'.
     992             :                                  */
     993          51 :                                 item->hints.principal = NULL;
     994             :                         } else {
     995         494 :                                 item->hints.principal = p;
     996             :                         }
     997             :                 }
     998       12314 :                 if (item->hints.domain == NULL) {
     999       11769 :                         p = strchr(item->name, '@');
    1000       11769 :                         if (p != NULL && p != item->name && p[1] != '\0') {
    1001         114 :                                 item->hints.namespace = p + 1;
    1002             :                         }
    1003             :                 }
    1004             :         }
    1005             : 
    1006        3226 :         for (v=0; v < state->view_table->count; v++) {
    1007        2446 :                 const struct dcesrv_lsa_Lookup_view *view =
    1008        2446 :                         state->view_table->array[v];
    1009             : 
    1010       51040 :                 for (i=0; i < r->in.num_names; i++) {
    1011       48594 :                         struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
    1012             :                         NTSTATUS status;
    1013             : 
    1014       48594 :                         if (item->done) {
    1015       23746 :                                 continue;
    1016             :                         }
    1017             : 
    1018       24848 :                         status = view->lookup_name(state, item);
    1019       24848 :                         if (NT_STATUS_IS_OK(status)) {
    1020       12269 :                                 item->done = true;
    1021       12579 :                         } else if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
    1022       12579 :                                 status = NT_STATUS_OK;
    1023           0 :                         } else if (NT_STATUS_EQUAL(status, NT_STATUS_SOME_NOT_MAPPED)) {
    1024           0 :                                 status = NT_STATUS_OK;
    1025             :                         }
    1026       24848 :                         if (!NT_STATUS_IS_OK(status)) {
    1027           0 :                                 return status;
    1028             :                         }
    1029             :                 }
    1030             :         }
    1031             : 
    1032         780 :         if (state->wb.irpc_handle == NULL) {
    1033         732 :                 return dcesrv_lsa_LookupNames_base_finish(state);
    1034             :         }
    1035             : 
    1036          48 :         state->wb.names = talloc_zero_array(state, struct lsa_String,
    1037             :                                             r->in.num_names);
    1038          48 :         if (state->wb.names == NULL) {
    1039           0 :                 return NT_STATUS_NO_MEMORY;
    1040             :         }
    1041             : 
    1042          96 :         for (i=0;i<r->in.num_names;i++) {
    1043          48 :                 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
    1044             : 
    1045          48 :                 if (item->done) {
    1046           0 :                         continue;
    1047             :                 }
    1048             : 
    1049          48 :                 item->wb_idx = state->wb.num_names;
    1050          48 :                 state->wb.names[item->wb_idx] = r->in.names[i];
    1051          48 :                 state->wb.num_names++;
    1052             :         }
    1053             : 
    1054          72 :         subreq = dcerpc_lsa_LookupNames4_send(state,
    1055          48 :                                               state->dce_call->event_ctx,
    1056             :                                               state->wb.irpc_handle,
    1057             :                                               state->wb.num_names,
    1058             :                                               state->wb.names,
    1059             :                                               &state->wb.domains,
    1060             :                                               &state->wb.sids,
    1061             :                                               state->r.in.level,
    1062             :                                               &state->wb.count,
    1063             :                                               state->r.in.lookup_options,
    1064             :                                               state->r.in.client_revision);
    1065          48 :         if (subreq == NULL) {
    1066           0 :                 return NT_STATUS_NO_MEMORY;
    1067             :         }
    1068          48 :         state->dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
    1069          48 :         tevent_req_set_callback(subreq,
    1070             :                                 dcesrv_lsa_LookupNames_base_done,
    1071             :                                 state);
    1072             : 
    1073          48 :         return NT_STATUS_OK;
    1074             : }
    1075             : 
    1076         764 : static NTSTATUS dcesrv_lsa_LookupNames_base_finish(
    1077             :         struct dcesrv_lsa_LookupNames_base_state *state)
    1078             : {
    1079         764 :         struct lsa_LookupNames4 *r = &state->r;
    1080             :         uint32_t i;
    1081             : 
    1082       13065 :         for (i=0;i<r->in.num_names;i++) {
    1083       12301 :                 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
    1084             :                 NTSTATUS status;
    1085       12301 :                 uint32_t sid_index = UINT32_MAX;
    1086             : 
    1087       12301 :                 status = dcesrv_lsa_authority_list(item->authority_name,
    1088             :                                                    item->authority_sid,
    1089       12301 :                                                    *r->out.domains,
    1090             :                                                    &sid_index);
    1091       12301 :                 if (!NT_STATUS_IS_OK(status)) {
    1092           0 :                         return status;
    1093             :                 }
    1094             : 
    1095       12301 :                 r->out.sids->sids[i].sid_type  = item->type;
    1096       12301 :                 r->out.sids->sids[i].sid       = discard_const_p(struct dom_sid,
    1097             :                                                                  item->sid);
    1098       12301 :                 r->out.sids->sids[i].sid_index = sid_index;
    1099       12301 :                 r->out.sids->sids[i].flags     = item->flags;
    1100             : 
    1101       12301 :                 r->out.sids->count++;
    1102       12301 :                 if (item->type != SID_NAME_UNKNOWN) {
    1103       12208 :                         (*r->out.count)++;
    1104             :                 }
    1105             :         }
    1106             : 
    1107         764 :         if (*r->out.count == 0) {
    1108         201 :                 return NT_STATUS_NONE_MAPPED;
    1109             :         }
    1110         563 :         if (*r->out.count != r->in.num_names) {
    1111           0 :                 return STATUS_SOME_UNMAPPED;
    1112             :         }
    1113             : 
    1114         563 :         return NT_STATUS_OK;
    1115             : }
    1116             : 
    1117         780 : static void dcesrv_lsa_LookupNames_base_map(
    1118             :         struct dcesrv_lsa_LookupNames_base_state *state)
    1119             : {
    1120         780 :         if (state->_r.l4 != NULL) {
    1121         521 :                 struct lsa_LookupNames4 *r = state->_r.l4;
    1122             : 
    1123         521 :                 r->out.result = state->r.out.result;
    1124         521 :                 return;
    1125             :         }
    1126             : 
    1127         259 :         if (state->_r.l3 != NULL) {
    1128           6 :                 struct lsa_LookupNames3 *r = state->_r.l3;
    1129             : 
    1130           6 :                 r->out.result = state->r.out.result;
    1131           6 :                 return;
    1132             :         }
    1133             : 
    1134         253 :         if (state->_r.l2 != NULL) {
    1135           6 :                 struct lsa_LookupNames2 *r = state->_r.l2;
    1136             :                 uint32_t i;
    1137             : 
    1138           6 :                 r->out.result = state->r.out.result;
    1139             : 
    1140           6 :                 SMB_ASSERT(state->r.out.sids->count <= r->in.num_names);
    1141          27 :                 for (i = 0; i < state->r.out.sids->count; i++) {
    1142          21 :                         const struct lsa_TranslatedSid3 *s3 =
    1143          21 :                                 &state->r.out.sids->sids[i];
    1144          21 :                         struct lsa_TranslatedSid2 *s2 =
    1145          21 :                                 &r->out.sids->sids[i];
    1146             : 
    1147          21 :                         s2->sid_type = s3->sid_type;
    1148          21 :                         if (s3->sid_type == SID_NAME_DOMAIN) {
    1149           3 :                                 s2->rid = UINT32_MAX;
    1150          18 :                         } else if (s3->flags & 0x00000004) {
    1151           0 :                                 s2->rid = UINT32_MAX;
    1152          18 :                         } else if (s3->sid == NULL) {
    1153             :                                 /*
    1154             :                                  * MS-LSAT 3.1.4.7 - rid zero is considered
    1155             :                                  * equivalent to sid NULL - so we should return
    1156             :                                  * 0 rid for unmapped entries
    1157             :                                  */
    1158           0 :                                 s2->rid = 0;
    1159             :                         } else {
    1160          18 :                                 s2->rid = 0;
    1161          18 :                                 dom_sid_split_rid(NULL, s3->sid,
    1162             :                                                   NULL, &s2->rid);
    1163             :                         }
    1164          21 :                         s2->sid_index = s3->sid_index;
    1165          21 :                         s2->unknown = s3->flags;
    1166             :                 }
    1167           6 :                 r->out.sids->count = state->r.out.sids->count;
    1168           6 :                 return;
    1169             :         }
    1170             : 
    1171         247 :         if (state->_r.l != NULL) {
    1172         247 :                 struct lsa_LookupNames *r = state->_r.l;
    1173             :                 uint32_t i;
    1174             : 
    1175         247 :                 r->out.result = state->r.out.result;
    1176             : 
    1177         247 :                 SMB_ASSERT(state->r.out.sids->count <= r->in.num_names);
    1178        1416 :                 for (i = 0; i < state->r.out.sids->count; i++) {
    1179        1169 :                         struct lsa_TranslatedSid3 *s3 =
    1180        1169 :                                 &state->r.out.sids->sids[i];
    1181        1169 :                         struct lsa_TranslatedSid *s =
    1182        1169 :                                 &r->out.sids->sids[i];
    1183             : 
    1184        1169 :                         s->sid_type = s3->sid_type;
    1185        1169 :                         if (s3->sid_type == SID_NAME_DOMAIN) {
    1186         129 :                                 s->rid = UINT32_MAX;
    1187        1040 :                         } else if (s3->flags & 0x00000004) {
    1188           0 :                                 s->rid = UINT32_MAX;
    1189        1040 :                         } else if (s3->sid == NULL) {
    1190             :                                 /*
    1191             :                                  * MS-LSAT 3.1.4.7 - rid zero is considered
    1192             :                                  * equivalent to sid NULL - so we should return
    1193             :                                  * 0 rid for unmapped entries
    1194             :                                  */
    1195          15 :                                 s->rid = 0;
    1196             :                         } else {
    1197        1025 :                                 s->rid = 0;
    1198        1025 :                                 dom_sid_split_rid(NULL, s3->sid,
    1199             :                                                   NULL, &s->rid);
    1200             :                         }
    1201        1169 :                         s->sid_index = s3->sid_index;
    1202             :                 }
    1203         247 :                 r->out.sids->count = state->r.out.sids->count;
    1204         247 :                 return;
    1205             :         }
    1206             : }
    1207             : 
    1208          48 : static void dcesrv_lsa_LookupNames_base_done(struct tevent_req *subreq)
    1209             : {
    1210          24 :         struct dcesrv_lsa_LookupNames_base_state *state =
    1211          48 :                 tevent_req_callback_data(subreq,
    1212             :                 struct dcesrv_lsa_LookupNames_base_state);
    1213          48 :         struct dcesrv_call_state *dce_call = state->dce_call;
    1214             :         NTSTATUS status;
    1215             :         uint32_t i;
    1216             : 
    1217          48 :         status = dcerpc_lsa_LookupNames4_recv(subreq, state->mem_ctx,
    1218             :                                               &state->wb.result);
    1219          48 :         TALLOC_FREE(subreq);
    1220          48 :         TALLOC_FREE(state->wb.irpc_handle);
    1221          48 :         if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
    1222           0 :                 DEBUG(0,(__location__ ": IRPC callback failed %s\n",
    1223             :                          nt_errstr(status)));
    1224           8 :                 goto finished;
    1225          48 :         } else if (!NT_STATUS_IS_OK(status)) {
    1226          16 :                 state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
    1227          16 :                 DEBUG(0,(__location__ ": IRPC callback failed %s\n",
    1228             :                          nt_errstr(status)));
    1229          16 :                 goto finished;
    1230             :         }
    1231             : 
    1232          32 :         status = state->wb.result;
    1233          32 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
    1234           0 :                 status = NT_STATUS_OK;
    1235          32 :         } else if (NT_STATUS_EQUAL(status, NT_STATUS_SOME_NOT_MAPPED)) {
    1236           0 :                 status = NT_STATUS_OK;
    1237             :         }
    1238          32 :         if (!NT_STATUS_IS_OK(status)) {
    1239           0 :                 goto finished;
    1240             :         }
    1241             : 
    1242          64 :         for (i=0; i < state->r.in.num_names;i++) {
    1243          32 :                 struct dcesrv_lsa_TranslatedItem *item = &state->items[i];
    1244          32 :                 struct lsa_TranslatedSid3 *s3 = NULL;
    1245          32 :                 struct lsa_DomainInfo *d = NULL;
    1246             : 
    1247          32 :                 if (item->done) {
    1248           0 :                         continue;
    1249             :                 }
    1250             : 
    1251          32 :                 if (item->wb_idx >= state->wb.sids.count) {
    1252           0 :                         status = NT_STATUS_INTERNAL_ERROR;
    1253           0 :                         goto finished;
    1254             :                 }
    1255             : 
    1256          32 :                 s3 = &state->wb.sids.sids[item->wb_idx];
    1257             : 
    1258          32 :                 item->type = s3->sid_type;
    1259          32 :                 item->sid = s3->sid;
    1260          32 :                 item->flags = s3->flags;
    1261             : 
    1262          32 :                 if (s3->sid_index == UINT32_MAX) {
    1263           0 :                         continue;
    1264             :                 }
    1265             : 
    1266          32 :                 if (state->wb.domains == NULL) {
    1267           0 :                         status = NT_STATUS_INTERNAL_ERROR;
    1268           0 :                         goto finished;
    1269             :                 }
    1270             : 
    1271          32 :                 if (s3->sid_index >= state->wb.domains->count) {
    1272           0 :                         status = NT_STATUS_INTERNAL_ERROR;
    1273           0 :                         goto finished;
    1274             :                 }
    1275             : 
    1276          32 :                 d = &state->wb.domains->domains[s3->sid_index];
    1277             : 
    1278          32 :                 item->authority_name = d->name.string;
    1279          32 :                 item->authority_sid = d->sid;
    1280             :         }
    1281             : 
    1282          32 :         status = dcesrv_lsa_LookupNames_base_finish(state);
    1283          48 :  finished:
    1284          48 :         state->r.out.result = status;
    1285          48 :         dcesrv_lsa_LookupNames_base_map(state);
    1286             : 
    1287          48 :         status = dcesrv_reply(dce_call);
    1288          48 :         if (!NT_STATUS_IS_OK(status)) {
    1289           0 :                 DEBUG(0,(__location__ ": dcesrv_reply() failed - %s\n", nt_errstr(status)));
    1290             :         }
    1291          48 : }
    1292             : 
    1293             : /*
    1294             :   lsa_LookupNames3
    1295             : */
    1296           6 : NTSTATUS dcesrv_lsa_LookupNames3(struct dcesrv_call_state *dce_call,
    1297             :                                  TALLOC_CTX *mem_ctx,
    1298             :                                  struct lsa_LookupNames3 *r)
    1299             : {
    1300           6 :         enum dcerpc_transport_t transport =
    1301           6 :                 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
    1302           6 :         struct dcesrv_lsa_LookupNames_base_state *state = NULL;
    1303           6 :         struct dcesrv_handle *policy_handle = NULL;
    1304             :         NTSTATUS status;
    1305             : 
    1306           6 :         if (transport != NCACN_NP && transport != NCALRPC) {
    1307           0 :                 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
    1308             :         }
    1309             : 
    1310           6 :         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
    1311             : 
    1312           6 :         *r->out.domains = NULL;
    1313           6 :         r->out.sids->count = 0;
    1314           6 :         r->out.sids->sids = NULL;
    1315           6 :         *r->out.count = 0;
    1316             : 
    1317           6 :         state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupNames_base_state);
    1318           6 :         if (state == NULL) {
    1319           0 :                 return NT_STATUS_NO_MEMORY;
    1320             :         }
    1321             : 
    1322           6 :         state->dce_call = dce_call;
    1323           6 :         state->mem_ctx = mem_ctx;
    1324             : 
    1325           6 :         state->policy_state = policy_handle->data;
    1326             : 
    1327           6 :         state->r.in.num_names = r->in.num_names;
    1328           6 :         state->r.in.names = r->in.names;
    1329           6 :         state->r.in.level = r->in.level;
    1330           6 :         state->r.in.lookup_options = r->in.lookup_options;
    1331           6 :         state->r.in.client_revision = r->in.client_revision;
    1332           6 :         state->r.in.sids = r->in.sids;
    1333           6 :         state->r.in.count = r->in.count;
    1334           6 :         state->r.out.domains = r->out.domains;
    1335           6 :         state->r.out.sids = r->out.sids;
    1336           6 :         state->r.out.count = r->out.count;
    1337             : 
    1338           6 :         state->_r.l3 = r;
    1339             : 
    1340           6 :         status = dcesrv_lsa_LookupNames_base_call(state);
    1341             : 
    1342           6 :         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
    1343           0 :                 return status;
    1344             :         }
    1345             : 
    1346           6 :         state->r.out.result = status;
    1347           6 :         dcesrv_lsa_LookupNames_base_map(state);
    1348           6 :         return status;
    1349             : }
    1350             : 
    1351             : /* 
    1352             :   lsa_LookupNames4
    1353             : 
    1354             :   Identical to LookupNames3, but doesn't take a policy handle
    1355             :   
    1356             : */
    1357         528 : NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    1358             :                                  struct lsa_LookupNames4 *r)
    1359             : {
    1360         528 :         struct dcesrv_lsa_LookupNames_base_state *state = NULL;
    1361             :         NTSTATUS status;
    1362             : 
    1363         528 :         *r->out.domains = NULL;
    1364         528 :         r->out.sids->count = 0;
    1365         528 :         r->out.sids->sids = NULL;
    1366         528 :         *r->out.count = 0;
    1367             : 
    1368         528 :         state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupNames_base_state);
    1369         528 :         if (state == NULL) {
    1370           0 :                 return NT_STATUS_NO_MEMORY;
    1371             :         }
    1372             : 
    1373         528 :         state->dce_call = dce_call;
    1374         528 :         state->mem_ctx = mem_ctx;
    1375             : 
    1376             :         /*
    1377             :          * We don't have a policy handle on this call, so we want to
    1378             :          * make a policy state and cache it for the life of the
    1379             :          * connection, to avoid re-opening the DB each call.
    1380             :          *
    1381             :          * This also enforces that this is only available over
    1382             :          * ncacn_ip_tcp and with SCHANNEL.
    1383             :          *
    1384             :          * schannel_call_setup may also set the fault state.
    1385             :          *
    1386             :          * state->policy_state is shared between all calls on this
    1387             :          * connection and is moved with talloc_steal() under the
    1388             :          * connection, not dce_call or state.
    1389             :          */
    1390         528 :         status = schannel_call_setup(dce_call, &state->policy_state);
    1391         528 :         if (!NT_STATUS_IS_OK(status)) {
    1392           7 :                 return status;
    1393             :         }
    1394             : 
    1395         521 :         state->r.in.num_names = r->in.num_names;
    1396         521 :         state->r.in.names = r->in.names;
    1397         521 :         state->r.in.level = r->in.level;
    1398         521 :         state->r.in.lookup_options = r->in.lookup_options;
    1399         521 :         state->r.in.client_revision = r->in.client_revision;
    1400         521 :         state->r.in.sids = r->in.sids;
    1401         521 :         state->r.in.count = r->in.count;
    1402         521 :         state->r.out.domains = r->out.domains;
    1403         521 :         state->r.out.sids = r->out.sids;
    1404         521 :         state->r.out.count = r->out.count;
    1405             : 
    1406         521 :         state->_r.l4 = r;
    1407             : 
    1408         521 :         status = dcesrv_lsa_LookupNames_base_call(state);
    1409             : 
    1410         521 :         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
    1411          36 :                 return status;
    1412             :         }
    1413             : 
    1414         485 :         state->r.out.result = status;
    1415         485 :         dcesrv_lsa_LookupNames_base_map(state);
    1416         485 :         return status;
    1417             : }
    1418             : 
    1419             : /*
    1420             :   lsa_LookupNames2
    1421             : */
    1422           6 : NTSTATUS dcesrv_lsa_LookupNames2(struct dcesrv_call_state *dce_call,
    1423             :                                  TALLOC_CTX *mem_ctx,
    1424             :                                  struct lsa_LookupNames2 *r)
    1425             : {
    1426           6 :         enum dcerpc_transport_t transport =
    1427           6 :                 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
    1428           6 :         struct dcesrv_lsa_LookupNames_base_state *state = NULL;
    1429           6 :         struct dcesrv_handle *policy_handle = NULL;
    1430             :         NTSTATUS status;
    1431             : 
    1432           6 :         if (transport != NCACN_NP && transport != NCALRPC) {
    1433           0 :                 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
    1434             :         }
    1435             : 
    1436           6 :         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
    1437             : 
    1438           6 :         *r->out.domains = NULL;
    1439           6 :         r->out.sids->count = 0;
    1440           6 :         r->out.sids->sids = NULL;
    1441           6 :         *r->out.count = 0;
    1442             : 
    1443           6 :         r->out.sids->sids = talloc_zero_array(r->out.sids,
    1444             :                                               struct lsa_TranslatedSid2,
    1445             :                                               r->in.num_names);
    1446           6 :         if (r->out.sids->sids == NULL) {
    1447           0 :                 return NT_STATUS_NO_MEMORY;
    1448             :         }
    1449             : 
    1450           6 :         state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupNames_base_state);
    1451           6 :         if (state == NULL) {
    1452           0 :                 return NT_STATUS_NO_MEMORY;
    1453             :         }
    1454             : 
    1455           6 :         state->dce_call = dce_call;
    1456           6 :         state->mem_ctx = mem_ctx;
    1457             : 
    1458           6 :         state->policy_state = policy_handle->data;
    1459             : 
    1460           6 :         state->r.in.num_names = r->in.num_names;
    1461           6 :         state->r.in.names = r->in.names;
    1462           6 :         state->r.in.level = r->in.level;
    1463             :         /*
    1464             :          * MS-LSAT 3.1.4.7:
    1465             :          *
    1466             :          * The LookupOptions and ClientRevision parameters MUST be ignored.
    1467             :          * Message processing MUST happen as if LookupOptions is set to
    1468             :          * 0x00000000 and ClientRevision is set to 0x00000002.
    1469             :          */
    1470           6 :         state->r.in.lookup_options = LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES;
    1471           6 :         state->r.in.client_revision = LSA_CLIENT_REVISION_2;
    1472           6 :         state->r.in.sids = talloc_zero(state, struct lsa_TransSidArray3);
    1473           6 :         if (state->r.in.sids == NULL) {
    1474           0 :                 return NT_STATUS_NO_MEMORY;
    1475             :         }
    1476           6 :         state->r.in.count = r->in.count;
    1477           6 :         state->r.out.domains = r->out.domains;
    1478           6 :         state->r.out.sids = talloc_zero(state, struct lsa_TransSidArray3);
    1479           6 :         if (state->r.out.sids == NULL) {
    1480           0 :                 return NT_STATUS_NO_MEMORY;
    1481             :         }
    1482           6 :         state->r.out.count = r->out.count;
    1483             : 
    1484           6 :         state->_r.l2 = r;
    1485             : 
    1486           6 :         status = dcesrv_lsa_LookupNames_base_call(state);
    1487             : 
    1488           6 :         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
    1489           0 :                 return status;
    1490             :         }
    1491             : 
    1492           6 :         state->r.out.result = status;
    1493           6 :         dcesrv_lsa_LookupNames_base_map(state);
    1494           6 :         return status;
    1495             : }
    1496             : 
    1497             : /* 
    1498             :   lsa_LookupNames 
    1499             : */
    1500         247 : NTSTATUS dcesrv_lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    1501             :                        struct lsa_LookupNames *r)
    1502             : {
    1503         181 :         enum dcerpc_transport_t transport =
    1504         247 :                 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
    1505         247 :         struct dcesrv_lsa_LookupNames_base_state *state = NULL;
    1506         247 :         struct dcesrv_handle *policy_handle = NULL;
    1507             :         NTSTATUS status;
    1508             : 
    1509         247 :         if (transport != NCACN_NP && transport != NCALRPC) {
    1510           0 :                 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
    1511             :         }
    1512             : 
    1513         247 :         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
    1514             : 
    1515         247 :         *r->out.domains = NULL;
    1516         247 :         r->out.sids->count = 0;
    1517         247 :         r->out.sids->sids = NULL;
    1518         247 :         *r->out.count = 0;
    1519             : 
    1520         247 :         r->out.sids->sids = talloc_zero_array(r->out.sids,
    1521             :                                               struct lsa_TranslatedSid,
    1522             :                                               r->in.num_names);
    1523         247 :         if (r->out.sids->sids == NULL) {
    1524           0 :                 return NT_STATUS_NO_MEMORY;
    1525             :         }
    1526             : 
    1527         247 :         state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupNames_base_state);
    1528         247 :         if (state == NULL) {
    1529           0 :                 return NT_STATUS_NO_MEMORY;
    1530             :         }
    1531             : 
    1532         247 :         state->dce_call = dce_call;
    1533         247 :         state->mem_ctx = mem_ctx;
    1534             : 
    1535         247 :         state->policy_state = policy_handle->data;
    1536             : 
    1537         247 :         state->r.in.num_names = r->in.num_names;
    1538         247 :         state->r.in.names = r->in.names;
    1539         247 :         state->r.in.level = r->in.level;
    1540         247 :         state->r.in.lookup_options = LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES;
    1541         247 :         state->r.in.client_revision = LSA_CLIENT_REVISION_1;
    1542         247 :         state->r.in.sids = talloc_zero(state, struct lsa_TransSidArray3);
    1543         247 :         if (state->r.in.sids == NULL) {
    1544           0 :                 return NT_STATUS_NO_MEMORY;
    1545             :         }
    1546         247 :         state->r.in.count = r->in.count;
    1547         247 :         state->r.out.domains = r->out.domains;
    1548         247 :         state->r.out.sids = talloc_zero(state, struct lsa_TransSidArray3);
    1549         247 :         if (state->r.out.sids == NULL) {
    1550           0 :                 return NT_STATUS_NO_MEMORY;
    1551             :         }
    1552         247 :         state->r.out.count = r->out.count;
    1553             : 
    1554         247 :         state->_r.l = r;
    1555             : 
    1556         247 :         status = dcesrv_lsa_LookupNames_base_call(state);
    1557             : 
    1558         247 :         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
    1559          12 :                 return status;
    1560             :         }
    1561             : 
    1562         235 :         state->r.out.result = status;
    1563         235 :         dcesrv_lsa_LookupNames_base_map(state);
    1564         235 :         return status;
    1565             : }
    1566             : 
    1567       11994 : static NTSTATUS dcesrv_lsa_lookup_name_predefined(
    1568             :                 struct dcesrv_lsa_LookupNames_base_state *state,
    1569             :                 struct dcesrv_lsa_TranslatedItem *item)
    1570             : {
    1571             :         NTSTATUS status;
    1572             : 
    1573       11994 :         status = dom_sid_lookup_predefined_name(item->name,
    1574             :                                                 &item->sid,
    1575             :                                                 &item->type,
    1576             :                                                 &item->authority_sid,
    1577             :                                                 &item->authority_name);
    1578       11994 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
    1579       11960 :                 return status;
    1580             :         }
    1581          34 :         if (!NT_STATUS_IS_OK(status)) {
    1582           0 :                 return status;
    1583             :         }
    1584             : 
    1585          34 :         return NT_STATUS_OK;
    1586             : }
    1587             : 
    1588       11862 : static NTSTATUS dcesrv_lsa_lookup_sid_predefined(
    1589             :                 struct dcesrv_lsa_LookupSids_base_state *state,
    1590             :                 struct dcesrv_lsa_TranslatedItem *item)
    1591             : {
    1592             :         NTSTATUS status;
    1593             : 
    1594       11862 :         status = dom_sid_lookup_predefined_sid(item->sid,
    1595             :                                                &item->name,
    1596             :                                                &item->type,
    1597             :                                                &item->authority_sid,
    1598             :                                                &item->authority_name);
    1599       11862 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
    1600       11852 :                 return status;
    1601             :         }
    1602          10 :         if (!NT_STATUS_IS_OK(status)) {
    1603           0 :                 return status;
    1604             :         }
    1605             : 
    1606          10 :         return NT_STATUS_OK;
    1607             : }
    1608             : 
    1609             : static const struct dcesrv_lsa_Lookup_view view_predefined = {
    1610             :         .name = "Predefined",
    1611             :         .lookup_sid = dcesrv_lsa_lookup_sid_predefined,
    1612             :         .lookup_name = dcesrv_lsa_lookup_name_predefined,
    1613             : };
    1614             : 
    1615       11960 : static NTSTATUS dcesrv_lsa_lookup_name_builtin(
    1616             :                 struct dcesrv_lsa_LookupNames_base_state *state,
    1617             :                 struct dcesrv_lsa_TranslatedItem *item)
    1618             : {
    1619       11960 :         struct lsa_policy_state *policy_state = state->policy_state;
    1620             :         NTSTATUS status;
    1621       11960 :         bool is_builtin = false;
    1622             : 
    1623       11960 :         if (item->name == NULL) {
    1624             :                 /*
    1625             :                  * This should not be mapped.
    1626             :                  */
    1627           0 :                 return NT_STATUS_OK;
    1628             :         }
    1629             : 
    1630             :         /*
    1631             :          * The predefined view already handled the BUILTIN domain.
    1632             :          *
    1633             :          * Now we just need to find the principal.
    1634             :          *
    1635             :          * We only allow 'BUILTIN\something' and
    1636             :          * not 'something@BUILTIN.
    1637             :          *
    1638             :          * And we try out best for just 'something'.
    1639             :          */
    1640       11960 :         is_builtin = strequal(item->hints.domain, NAME_BUILTIN);
    1641       11960 :         if (!is_builtin && item->hints.domain != NULL) {
    1642         241 :                 return NT_STATUS_NONE_MAPPED;
    1643             :         }
    1644             : 
    1645       23388 :         status = dcesrv_lsa_lookup_name(state->policy_state,
    1646             :                                         state->mem_ctx,
    1647             :                                         NAME_BUILTIN,
    1648       11719 :                                         policy_state->builtin_sid,
    1649             :                                         policy_state->builtin_dn,
    1650             :                                         item->hints.principal,
    1651             :                                         &item->sid,
    1652             :                                         &item->type);
    1653       11719 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
    1654         262 :                 if (!is_builtin) {
    1655         262 :                         return NT_STATUS_NONE_MAPPED;
    1656             :                 }
    1657             :                 /*
    1658             :                  * We know we're authoritative
    1659             :                  */
    1660           0 :                 status = NT_STATUS_OK;
    1661             :         }
    1662       11457 :         if (!NT_STATUS_IS_OK(status)) {
    1663           0 :                 return status;
    1664             :         }
    1665             : 
    1666       11457 :         item->authority_name = NAME_BUILTIN;
    1667       11457 :         item->authority_sid = policy_state->builtin_sid;
    1668       11457 :         return NT_STATUS_OK;
    1669             : }
    1670             : 
    1671       11852 : static NTSTATUS dcesrv_lsa_lookup_sid_builtin(
    1672             :                 struct dcesrv_lsa_LookupSids_base_state *state,
    1673             :                 struct dcesrv_lsa_TranslatedItem *item)
    1674             : {
    1675       11852 :         struct lsa_policy_state *policy_state = state->policy_state;
    1676             :         NTSTATUS status;
    1677       11852 :         bool is_builtin = false;
    1678             : 
    1679             :         /*
    1680             :          * The predefined view already handled the BUILTIN domain.
    1681             :          *
    1682             :          * Now we just need to find the principal.
    1683             :          */
    1684       11852 :         is_builtin = dom_sid_in_domain(policy_state->builtin_sid, item->sid);
    1685       11852 :         if (!is_builtin) {
    1686         116 :                 return NT_STATUS_NONE_MAPPED;
    1687             :         }
    1688             : 
    1689       23472 :         status = dcesrv_lsa_lookup_sid(state->policy_state,
    1690             :                                        state->mem_ctx,
    1691             :                                        NAME_BUILTIN,
    1692       11736 :                                        policy_state->builtin_sid,
    1693             :                                        policy_state->builtin_dn,
    1694             :                                        item->sid,
    1695             :                                        &item->name,
    1696             :                                        &item->type);
    1697       11736 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
    1698             :                 /*
    1699             :                  * We know we're authoritative
    1700             :                  */
    1701           0 :                 status = NT_STATUS_OK;
    1702             :         }
    1703       11736 :         if (!NT_STATUS_IS_OK(status)) {
    1704           0 :                 return status;
    1705             :         }
    1706             : 
    1707       11736 :         item->authority_name = NAME_BUILTIN;
    1708       11736 :         item->authority_sid = policy_state->builtin_sid;
    1709       11736 :         return NT_STATUS_OK;
    1710             : }
    1711             : 
    1712             : static const struct dcesrv_lsa_Lookup_view view_builtin = {
    1713             :         .name = "Builtin",
    1714             :         .lookup_sid = dcesrv_lsa_lookup_sid_builtin,
    1715             :         .lookup_name = dcesrv_lsa_lookup_name_builtin,
    1716             : };
    1717             : 
    1718         826 : static NTSTATUS dcesrv_lsa_lookup_name_account(
    1719             :                 struct dcesrv_lsa_LookupNames_base_state *state,
    1720             :                 struct dcesrv_lsa_TranslatedItem *item)
    1721             : {
    1722         826 :         struct lsa_policy_state *policy_state = state->policy_state;
    1723         826 :         struct loadparm_context *lp_ctx = state->dce_call->conn->dce_ctx->lp_ctx;
    1724         826 :         struct lsa_LookupNames4 *r = &state->r;
    1725             :         NTSTATUS status;
    1726             :         int role;
    1727         826 :         bool (*is_local_match_fn)(struct loadparm_context *, const char *) = NULL;
    1728         826 :         bool is_domain = false;
    1729         826 :         bool try_lookup = false;
    1730         826 :         const char *check_domain_name = NULL;
    1731             : 
    1732         826 :         role = lpcfg_server_role(lp_ctx);
    1733         826 :         if (role == ROLE_ACTIVE_DIRECTORY_DC) {
    1734         824 :                 is_local_match_fn = lpcfg_is_my_domain_or_realm;
    1735             :         } else {
    1736           2 :                 is_local_match_fn = lpcfg_is_myname;
    1737             :         }
    1738             : 
    1739         826 :         if (item->name == NULL) {
    1740             :                 /*
    1741             :                  * This should not be mapped.
    1742             :                  */
    1743           0 :                 return NT_STATUS_OK;
    1744             :         }
    1745             : 
    1746         826 :         if (item->hints.domain != NULL && item->hints.principal == NULL) {
    1747             :                 /*
    1748             :                  * This is 'DOMAIN\'.
    1749             :                  */
    1750          48 :                 check_domain_name = item->hints.domain;
    1751             :         } else {
    1752             :                 /*
    1753             :                  * This is just 'DOMAIN'.
    1754             :                  */
    1755         778 :                 check_domain_name = item->name;
    1756             :         }
    1757         826 :         is_domain = is_local_match_fn(lp_ctx, check_domain_name);
    1758         826 :         if (is_domain) {
    1759         122 :                 item->type = SID_NAME_DOMAIN;
    1760         122 :                 item->sid = policy_state->domain_sid;
    1761         122 :                 item->authority_name = policy_state->domain_name;
    1762         122 :                 item->authority_sid = policy_state->domain_sid;
    1763         122 :                 return NT_STATUS_OK;
    1764             :         }
    1765             : 
    1766         704 :         if (r->in.lookup_options & LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES_LOCAL) {
    1767           0 :                 if (item->hints.domain != item->hints.namespace) {
    1768             :                         /*
    1769             :                          * This means the client asked for an UPN,
    1770             :                          * and it should not be mapped.
    1771             :                          */
    1772           0 :                         return NT_STATUS_OK;
    1773             :                 }
    1774             :         }
    1775             : 
    1776         704 :         if (item->hints.namespace != NULL) {
    1777         596 :                 is_domain = is_local_match_fn(lp_ctx, item->hints.namespace);
    1778         596 :                 try_lookup = is_domain;
    1779             :         } else {
    1780         108 :                 try_lookup = true;
    1781             :         }
    1782             : 
    1783         704 :         if (!try_lookup) {
    1784             :                 struct dcesrv_lsa_TranslatedItem tmp;
    1785             : 
    1786          67 :                 tmp = *item;
    1787          67 :                 status = dom_sid_lookup_predefined_name(item->hints.namespace,
    1788             :                                                         &tmp.sid,
    1789             :                                                         &tmp.type,
    1790             :                                                         &tmp.authority_sid,
    1791             :                                                         &tmp.authority_name);
    1792          67 :                 if (NT_STATUS_IS_OK(status)) {
    1793             :                         /*
    1794             :                          * It should not be handled by us.
    1795             :                          */
    1796           0 :                         return NT_STATUS_NONE_MAPPED;
    1797             :                 }
    1798          67 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
    1799           0 :                         return status;
    1800             :                 }
    1801             :         }
    1802             : 
    1803         704 :         if (!try_lookup) {
    1804          67 :                 const struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
    1805          67 :                 const struct lsa_ForestTrustDomainInfo *di = NULL;
    1806             : 
    1807          67 :                 if (state->routing_table == NULL) {
    1808          67 :                         status = dsdb_trust_routing_table_load(policy_state->sam_ldb,
    1809             :                                                                state,
    1810             :                                                                &state->routing_table);
    1811          67 :                         if (!NT_STATUS_IS_OK(status)) {
    1812          67 :                                 return status;
    1813             :                         }
    1814             :                 }
    1815             : 
    1816          67 :                 tdo = dsdb_trust_domain_by_name(state->routing_table,
    1817             :                                                 item->hints.namespace,
    1818             :                                                 &di);
    1819          67 :                 if (tdo == NULL) {
    1820             :                         /*
    1821             :                          * The name is not resolvable at all...
    1822             :                          */
    1823          19 :                         return NT_STATUS_OK;
    1824             :                 }
    1825             : 
    1826          48 :                 if (!(tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST)) {
    1827             :                         /*
    1828             :                          * The name is not resolvable here
    1829             :                          */
    1830          48 :                         return NT_STATUS_NONE_MAPPED;
    1831             :                 }
    1832             : 
    1833             :                 /*
    1834             :                  * TODO: handle multiple domains in a forest together with
    1835             :                  * LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY
    1836             :                  */
    1837           0 :                 is_domain = true;
    1838           0 :                 try_lookup = true;
    1839             :         }
    1840             : 
    1841         637 :         if (!try_lookup) {
    1842             :                 /*
    1843             :                  * It should not be handled by us.
    1844             :                  */
    1845           0 :                 return NT_STATUS_NONE_MAPPED;
    1846             :         }
    1847             : 
    1848             :         /*
    1849             :          * TODO: handle multiple domains in our forest.
    1850             :          */
    1851             : 
    1852        1104 :         status = dcesrv_lsa_lookup_name(state->policy_state,
    1853             :                                         state->mem_ctx,
    1854             :                                         policy_state->domain_name,
    1855         637 :                                         policy_state->domain_sid,
    1856             :                                         policy_state->domain_dn,
    1857             :                                         item->hints.principal,
    1858             :                                         &item->sid,
    1859             :                                         &item->type);
    1860         637 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
    1861          88 :                 if (!is_domain) {
    1862          20 :                         return NT_STATUS_NONE_MAPPED;
    1863             :                 }
    1864             :                 /*
    1865             :                  * We know we're authoritative
    1866             :                  */
    1867          68 :                 status = NT_STATUS_OK;
    1868             :         }
    1869         617 :         if (!NT_STATUS_IS_OK(status)) {
    1870           0 :                 return status;
    1871             :         }
    1872             : 
    1873         617 :         item->authority_name = policy_state->domain_name;
    1874         617 :         item->authority_sid = policy_state->domain_sid;
    1875         617 :         return NT_STATUS_OK;
    1876             : }
    1877             : 
    1878         917 : static NTSTATUS dcesrv_lsa_lookup_sid_account(
    1879             :                 struct dcesrv_lsa_LookupSids_base_state *state,
    1880             :                 struct dcesrv_lsa_TranslatedItem *item)
    1881             : {
    1882         917 :         struct lsa_policy_state *policy_state = state->policy_state;
    1883             :         NTSTATUS status;
    1884             :         bool is_domain;
    1885             : 
    1886         917 :         is_domain = dom_sid_equal(policy_state->domain_sid, item->sid);
    1887         917 :         if (is_domain) {
    1888          12 :                 item->type = SID_NAME_DOMAIN;
    1889          12 :                 item->name = policy_state->domain_name;
    1890          12 :                 item->authority_name = policy_state->domain_name;
    1891          12 :                 item->authority_sid = policy_state->domain_sid;
    1892          12 :                 return NT_STATUS_OK;
    1893             :         }
    1894         905 :         is_domain = dom_sid_in_domain(policy_state->domain_sid, item->sid);
    1895         905 :         if (!is_domain) {
    1896         607 :                 return NT_STATUS_NONE_MAPPED;
    1897             :         }
    1898             : 
    1899         447 :         status = dcesrv_lsa_lookup_sid(state->policy_state,
    1900             :                                        state->mem_ctx,
    1901             :                                        policy_state->domain_name,
    1902         298 :                                        policy_state->domain_sid,
    1903             :                                        policy_state->domain_dn,
    1904             :                                        item->sid,
    1905             :                                        &item->name,
    1906             :                                        &item->type);
    1907         298 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
    1908             :                 /*
    1909             :                  * We know we're authoritative
    1910             :                  */
    1911           6 :                 status = NT_STATUS_OK;
    1912             :         }
    1913         298 :         if (!NT_STATUS_IS_OK(status)) {
    1914           0 :                 return status;
    1915             :         }
    1916             : 
    1917         298 :         item->authority_name = policy_state->domain_name;
    1918         298 :         item->authority_sid = policy_state->domain_sid;
    1919         298 :         return NT_STATUS_OK;
    1920             : }
    1921             : 
    1922             : static const struct dcesrv_lsa_Lookup_view view_account = {
    1923             :         .name = "Account",
    1924             :         .lookup_sid = dcesrv_lsa_lookup_sid_account,
    1925             :         .lookup_name = dcesrv_lsa_lookup_name_account,
    1926             : };
    1927             : 
    1928          68 : static NTSTATUS dcesrv_lsa_lookup_name_winbind(
    1929             :                 struct dcesrv_lsa_LookupNames_base_state *state,
    1930             :                 struct dcesrv_lsa_TranslatedItem *item)
    1931             : {
    1932          68 :         struct lsa_LookupNames4 *r = &state->r;
    1933          68 :         const struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
    1934          68 :         const struct lsa_ForestTrustDomainInfo *di = NULL;
    1935             :         NTSTATUS status;
    1936          68 :         const char *check_domain_name = NULL;
    1937          68 :         bool expect_domain = false;
    1938          34 :         struct imessaging_context *imsg_ctx =
    1939          68 :                 dcesrv_imessaging_context(state->dce_call->conn);
    1940             : 
    1941          68 :         if (item->name == NULL) {
    1942             :                 /*
    1943             :                  * This should not be mapped.
    1944             :                  */
    1945           0 :                 return NT_STATUS_OK;
    1946             :         }
    1947             : 
    1948          68 :         if (item->hints.domain != NULL && item->hints.principal == NULL) {
    1949             :                 /*
    1950             :                  * This is 'DOMAIN\'.
    1951             :                  */
    1952           0 :                 check_domain_name = item->hints.domain;
    1953           0 :                 expect_domain = true;
    1954          68 :         } else if (item->hints.namespace != NULL) {
    1955             :                 /*
    1956             :                  * This is 'DOMAIN\someone'
    1957             :                  * or 'someone@DOMAIN'
    1958             :                  */
    1959          48 :                 check_domain_name = item->hints.namespace;
    1960             :         } else {
    1961             :                 /*
    1962             :                  * This is just 'DOMAIN'.
    1963             :                  */
    1964          20 :                 check_domain_name = item->name;
    1965          20 :                 expect_domain = true;
    1966             :         }
    1967             : 
    1968          68 :         if (state->routing_table == NULL) {
    1969          20 :                 struct lsa_policy_state *policy_state = state->policy_state;
    1970             : 
    1971          20 :                 status = dsdb_trust_routing_table_load(policy_state->sam_ldb,
    1972             :                                                        state,
    1973             :                                                        &state->routing_table);
    1974          20 :                 if (!NT_STATUS_IS_OK(status)) {
    1975           0 :                         return status;
    1976             :                 }
    1977             :         }
    1978             : 
    1979          68 :         tdo = dsdb_trust_domain_by_name(state->routing_table,
    1980             :                                         check_domain_name,
    1981             :                                         &di);
    1982          68 :         if (tdo == NULL) {
    1983             :                 /*
    1984             :                  * The name is not resolvable at all...
    1985             :                  *
    1986             :                  * And for now we don't send unqualified names
    1987             :                  * to winbindd, as we don't handle them
    1988             :                  * there yet.
    1989             :                  *
    1990             :                  * TODO: how should that work within
    1991             :                  * winbindd?
    1992             :                  */
    1993           6 :                 return NT_STATUS_OK;
    1994             :         }
    1995             : 
    1996          62 :         if (tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) {
    1997             :                 /*
    1998             :                  * The name should have been resolved in the account view.
    1999             :                  *
    2000             :                  * TODO: handle multiple domains in a forest...
    2001             :                  */
    2002           0 :                 return NT_STATUS_OK;
    2003             :         }
    2004             : 
    2005          62 :         if (expect_domain) {
    2006          14 :                 const char *name = NULL;
    2007          14 :                 const struct dom_sid *sid = NULL;
    2008             : 
    2009          14 :                 name = talloc_strdup(state->mem_ctx,
    2010          14 :                                      di->netbios_domain_name.string);
    2011          14 :                 if (name == NULL) {
    2012           0 :                         return NT_STATUS_NO_MEMORY;
    2013             :                 }
    2014          14 :                 sid = dom_sid_dup(state->mem_ctx,
    2015          14 :                                   di->domain_sid);
    2016          14 :                 if (sid == NULL) {
    2017           0 :                         return NT_STATUS_NO_MEMORY;
    2018             :                 }
    2019          14 :                 item->type = SID_NAME_DOMAIN;
    2020          14 :                 item->sid = sid;
    2021          14 :                 item->authority_name = name;
    2022          14 :                 item->authority_sid = sid;
    2023          14 :                 return NT_STATUS_OK;
    2024             :         }
    2025             : 
    2026          48 :         if (r->in.lookup_options & LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES_LOCAL) {
    2027           0 :                 if (item->hints.namespace == NULL) {
    2028             :                         /*
    2029             :                          * We should not try to resolve isolated names
    2030             :                          * remotely.
    2031             :                          */
    2032           0 :                         return NT_STATUS_OK;
    2033             :                 }
    2034             :         }
    2035             : 
    2036             :         /*
    2037             :          * We know at least the domain part of the name exists.
    2038             :          *
    2039             :          * For now the rest handled within winbindd.
    2040             :          *
    2041             :          * In future we can optimize it based on
    2042             :          * r->in.level.
    2043             :          *
    2044             :          * We can also try to resolve SID_NAME_DOMAIN
    2045             :          * just based on the routing table.
    2046             :          */
    2047             : 
    2048          48 :         if (state->wb.irpc_handle != NULL) {
    2049             :                 /*
    2050             :                  * already called...
    2051             :                  */
    2052           0 :                 return NT_STATUS_NONE_MAPPED;
    2053             :         }
    2054             : 
    2055          48 :         state->wb.irpc_handle = irpc_binding_handle_by_name(state,
    2056             :                                                             imsg_ctx,
    2057             :                                                             "winbind_server",
    2058             :                                                             &ndr_table_lsarpc);
    2059          48 :         if (state->wb.irpc_handle == NULL) {
    2060           0 :                 DEBUG(0,("Failed to get binding_handle for winbind_server task\n"));
    2061           0 :                 state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
    2062           0 :                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
    2063             :         }
    2064             : 
    2065             :         /*
    2066             :          * 60 seconds timeout should be enough
    2067             :          */
    2068          48 :         dcerpc_binding_handle_set_timeout(state->wb.irpc_handle, 60);
    2069             : 
    2070          48 :         return NT_STATUS_NONE_MAPPED;
    2071             : }
    2072             : 
    2073         607 : static NTSTATUS dcesrv_lsa_lookup_sid_winbind(
    2074             :                 struct dcesrv_lsa_LookupSids_base_state *state,
    2075             :                 struct dcesrv_lsa_TranslatedItem *item)
    2076             : {
    2077         607 :         const struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
    2078         607 :         const struct lsa_ForestTrustDomainInfo *di = NULL;
    2079             :         struct dcesrv_lsa_TranslatedItem tmp;
    2080         607 :         struct dom_sid domain_sid = {0,};
    2081             :         NTSTATUS status;
    2082             :         bool match;
    2083         305 :         struct imessaging_context *imsg_ctx =
    2084         607 :                 dcesrv_imessaging_context(state->dce_call->conn);
    2085             : 
    2086             :         /*
    2087             :          * Verify the sid is not INVALID.
    2088             :          */
    2089         607 :         tmp = *item;
    2090         607 :         status = dom_sid_lookup_predefined_sid(tmp.sid,
    2091             :                                                &tmp.name,
    2092             :                                                &tmp.type,
    2093             :                                                &tmp.authority_sid,
    2094             :                                                &tmp.authority_name);
    2095         607 :         if (NT_STATUS_IS_OK(status)) {
    2096           0 :                 status = NT_STATUS_NONE_MAPPED;
    2097             :         }
    2098         607 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
    2099             :                 /*
    2100             :                  * Typically INVALID_SID
    2101             :                  */
    2102         576 :                 return status;
    2103             :         }
    2104             : 
    2105          31 :         if (state->routing_table == NULL) {
    2106          31 :                 struct lsa_policy_state *policy_state = state->policy_state;
    2107             : 
    2108          31 :                 status = dsdb_trust_routing_table_load(policy_state->sam_ldb,
    2109             :                                                        state,
    2110             :                                                        &state->routing_table);
    2111          31 :                 if (!NT_STATUS_IS_OK(status)) {
    2112           0 :                         return status;
    2113             :                 }
    2114             :         }
    2115             : 
    2116          31 :         domain_sid = *item->sid;
    2117          31 :         if (domain_sid.num_auths == 5) {
    2118          31 :                 sid_split_rid(&domain_sid, NULL);
    2119             :         }
    2120             : 
    2121          31 :         tdo = dsdb_trust_domain_by_sid(state->routing_table,
    2122             :                                        &domain_sid, &di);
    2123          31 :         if (tdo == NULL) {
    2124             :                 /*
    2125             :                  * The sid is not resolvable at all...
    2126             :                  */
    2127          13 :                 return NT_STATUS_OK;
    2128             :         }
    2129             : 
    2130          18 :         if (tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) {
    2131             :                 /*
    2132             :                  * The name should have been resolved in the account view.
    2133             :                  *
    2134             :                  * TODO: handle multiple domains in a forest...
    2135             :                  */
    2136           0 :                 return NT_STATUS_OK;
    2137             :         }
    2138             : 
    2139          18 :         match = dom_sid_equal(di->domain_sid, item->sid);
    2140          18 :         if (match) {
    2141           0 :                 const char *name = NULL;
    2142             : 
    2143           0 :                 name = talloc_strdup(state->mem_ctx,
    2144           0 :                                      di->netbios_domain_name.string);
    2145           0 :                 if (name == NULL) {
    2146           0 :                         return NT_STATUS_NO_MEMORY;
    2147             :                 }
    2148             : 
    2149           0 :                 item->type = SID_NAME_DOMAIN;
    2150           0 :                 item->name = name;
    2151           0 :                 item->authority_name = name;
    2152           0 :                 item->authority_sid = item->sid;
    2153           0 :                 return NT_STATUS_OK;
    2154             :         }
    2155             : 
    2156             :         /*
    2157             :          * We know at least the domain part of the sid exists.
    2158             :          *
    2159             :          * For now the rest handled within winbindd.
    2160             :          *
    2161             :          * In future we can optimize it based on
    2162             :          * r->in.level.
    2163             :          *
    2164             :          * We can also try to resolve SID_NAME_DOMAIN
    2165             :          * just based on the routing table.
    2166             :          */
    2167          18 :         if (state->wb.irpc_handle != NULL) {
    2168             :                 /*
    2169             :                  * already called...
    2170             :                  */
    2171           0 :                 return NT_STATUS_NONE_MAPPED;
    2172             :         }
    2173             : 
    2174          18 :         state->wb.irpc_handle = irpc_binding_handle_by_name(state,
    2175             :                                                             imsg_ctx,
    2176             :                                                             "winbind_server",
    2177             :                                                             &ndr_table_lsarpc);
    2178          18 :         if (state->wb.irpc_handle == NULL) {
    2179           0 :                 DEBUG(0,("Failed to get binding_handle for winbind_server task\n"));
    2180           0 :                 state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
    2181           0 :                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
    2182             :         }
    2183             : 
    2184             :         /*
    2185             :          * 60 seconds timeout should be enough
    2186             :          */
    2187          18 :         dcerpc_binding_handle_set_timeout(state->wb.irpc_handle, 60);
    2188             : 
    2189          18 :         return NT_STATUS_NONE_MAPPED;
    2190             : }
    2191             : 
    2192             : static const struct dcesrv_lsa_Lookup_view view_winbind = {
    2193             :         .name = "Winbind",
    2194             :         .lookup_sid = dcesrv_lsa_lookup_sid_winbind,
    2195             :         .lookup_name = dcesrv_lsa_lookup_name_winbind,
    2196             : };
    2197             : 
    2198             : static const struct dcesrv_lsa_Lookup_view *table_all_views[] = {
    2199             :         &view_predefined,
    2200             :         &view_builtin,
    2201             :         &view_account,
    2202             :         &view_winbind,
    2203             : };
    2204             : 
    2205             : static const struct dcesrv_lsa_Lookup_view_table table_all = {
    2206             :         .name = "LSA_LOOKUP_NAMES_ALL",
    2207             :         .count = ARRAY_SIZE(table_all_views),
    2208             :         .array = table_all_views,
    2209             : };
    2210             : 
    2211             : static const struct dcesrv_lsa_Lookup_view *table_domains_views[] = {
    2212             :         &view_account,
    2213             :         &view_winbind,
    2214             : };
    2215             : 
    2216             : static const struct dcesrv_lsa_Lookup_view_table table_domains = {
    2217             :         .name = "LSA_LOOKUP_NAMES_DOMAINS_ONLY",
    2218             :         .count = ARRAY_SIZE(table_domains_views),
    2219             :         .array = table_domains_views,
    2220             : };
    2221             : 
    2222             : static const struct dcesrv_lsa_Lookup_view *table_primary_views[] = {
    2223             :         &view_account,
    2224             : };
    2225             : 
    2226             : static const struct dcesrv_lsa_Lookup_view_table table_primary = {
    2227             :         .name = "LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY",
    2228             :         .count = ARRAY_SIZE(table_primary_views),
    2229             :         .array = table_primary_views,
    2230             : };
    2231             : 
    2232             : static const struct dcesrv_lsa_Lookup_view *table_remote_views[] = {
    2233             :         &view_winbind,
    2234             : };
    2235             : 
    2236             : static const struct dcesrv_lsa_Lookup_view_table table_gc = {
    2237             :         .name = "LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY",
    2238             :         .count = ARRAY_SIZE(table_domains_views),
    2239             :         .array = table_domains_views,
    2240             : };
    2241             : 
    2242             : static const struct dcesrv_lsa_Lookup_view_table table_xreferral = {
    2243             :         .name = "LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY",
    2244             :         .count = ARRAY_SIZE(table_remote_views),
    2245             :         .array = table_remote_views,
    2246             : };
    2247             : 
    2248             : static const struct dcesrv_lsa_Lookup_view_table table_xresolve = {
    2249             :         .name = "LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2",
    2250             :         .count = ARRAY_SIZE(table_domains_views),
    2251             :         .array = table_domains_views,
    2252             : };
    2253             : 
    2254             : static const struct dcesrv_lsa_Lookup_view_table table_rodc = {
    2255             :         .name = "LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC",
    2256             :         .count = ARRAY_SIZE(table_remote_views),
    2257             :         .array = table_remote_views,
    2258             : };
    2259             : 
    2260        2093 : static const struct dcesrv_lsa_Lookup_view_table *dcesrv_lsa_view_table(
    2261             :         enum lsa_LookupNamesLevel level)
    2262             : {
    2263        2093 :         switch (level) {
    2264         995 :         case LSA_LOOKUP_NAMES_ALL:
    2265         995 :                 return &table_all;
    2266         994 :         case LSA_LOOKUP_NAMES_DOMAINS_ONLY:
    2267         994 :                 return &table_domains;
    2268          34 :         case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY:
    2269          34 :                 return &table_primary;
    2270           0 :         case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY:
    2271           0 :                 return &table_gc;
    2272           0 :         case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY:
    2273           0 :                 return &table_xreferral;
    2274          70 :         case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2:
    2275          70 :                 return &table_xresolve;
    2276           0 :         case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC:
    2277           0 :                 return &table_rodc;
    2278             :         }
    2279             : 
    2280           0 :         return NULL;
    2281             : }

Generated by: LCOV version 1.13