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

Generated by: LCOV version 1.13