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

Generated by: LCOV version 1.14