LCOV - code coverage report
Current view: top level - source4/torture/rpc - lsa_lookup.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 101 222 45.5 %
Date: 2024-04-21 15:09:00 Functions: 6 8 75.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    test suite for lsa rpc lookup operations
       4             : 
       5             :    Copyright (C) Volker Lendecke 2006
       6             :    
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             :    
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             :    
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include "torture/rpc/torture_rpc.h"
      23             : #include "librpc/gen_ndr/ndr_lsa_c.h"
      24             : #include "libcli/security/security.h"
      25             : 
      26         167 : static bool open_policy(struct torture_context *tctx,
      27             :                         struct dcerpc_binding_handle *b,
      28             :                         struct policy_handle **handle)
      29             : {
      30           0 :         struct lsa_ObjectAttribute attr;
      31           0 :         struct lsa_QosInfo qos;
      32           0 :         struct lsa_OpenPolicy2 r;
      33             : 
      34         167 :         *handle = talloc(tctx, struct policy_handle);
      35         167 :         if (!*handle) {
      36           0 :                 return false;
      37             :         }
      38             : 
      39         167 :         qos.len = 0;
      40         167 :         qos.impersonation_level = 2;
      41         167 :         qos.context_mode = 1;
      42         167 :         qos.effective_only = 0;
      43             : 
      44         167 :         attr.len = 0;
      45         167 :         attr.root_dir = NULL;
      46         167 :         attr.object_name = NULL;
      47         167 :         attr.attributes = 0;
      48         167 :         attr.sec_desc = NULL;
      49         167 :         attr.sec_qos = &qos;
      50             : 
      51         167 :         r.in.system_name = "\\";
      52         167 :         r.in.attr = &attr;
      53         167 :         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
      54         167 :         r.out.handle = *handle;
      55             : 
      56         167 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b, tctx, &r),
      57             :                 "OpenPolicy2 failed");
      58             : 
      59         167 :         return NT_STATUS_IS_OK(r.out.result);
      60             : }
      61             : 
      62          12 : static bool get_domainsid(struct torture_context *tctx,
      63             :                           struct dcerpc_binding_handle *b,
      64             :                           struct policy_handle *handle,
      65             :                           struct dom_sid **sid)
      66             : {
      67           0 :         struct lsa_QueryInfoPolicy r;
      68          12 :         union lsa_PolicyInformation *info = NULL;
      69             : 
      70          12 :         r.in.level = LSA_POLICY_INFO_DOMAIN;
      71          12 :         r.in.handle = handle;
      72          12 :         r.out.info = &info;
      73             : 
      74          12 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy_r(b, tctx, &r),
      75             :                 "QueryInfoPolicy failed");
      76          12 :         torture_assert_ntstatus_ok(tctx, r.out.result, "QueryInfoPolicy failed");
      77             : 
      78          12 :         *sid = info->domain.sid;
      79          12 :         return true;
      80             : }
      81             : 
      82           0 : static NTSTATUS lookup_sids(struct torture_context *tctx,
      83             :                             uint16_t level,
      84             :                             struct dcerpc_binding_handle *b,
      85             :                             struct policy_handle *handle,
      86             :                             struct dom_sid **sids, uint32_t num_sids,
      87             :                             struct lsa_TransNameArray *names)
      88             : {
      89           0 :         struct lsa_LookupSids r;
      90           0 :         struct lsa_SidArray sidarray;
      91           0 :         struct lsa_RefDomainList *domains;
      92           0 :         uint32_t count = 0;
      93           0 :         uint32_t i;
      94           0 :         NTSTATUS status;
      95             : 
      96           0 :         names->count = 0;
      97           0 :         names->names = NULL;
      98             : 
      99           0 :         sidarray.num_sids = num_sids;
     100           0 :         sidarray.sids = talloc_array(tctx, struct lsa_SidPtr, num_sids);
     101             : 
     102           0 :         for (i=0; i<num_sids; i++) {
     103           0 :                 sidarray.sids[i].sid = sids[i];
     104             :         }
     105             : 
     106           0 :         r.in.handle = handle;
     107           0 :         r.in.sids = &sidarray;
     108           0 :         r.in.names = names;
     109           0 :         r.in.level = level;
     110           0 :         r.in.count = &count;
     111           0 :         r.out.names = names;
     112           0 :         r.out.count = &count;
     113           0 :         r.out.domains = &domains;
     114             : 
     115           0 :         status = dcerpc_lsa_LookupSids_r(b, tctx, &r);
     116           0 :         if (!NT_STATUS_IS_OK(status)) {
     117           0 :                 return status;
     118             :         }
     119           0 :         return r.out.result;
     120             : }
     121             : 
     122           0 : static bool test_lookupsids(struct torture_context *tctx,
     123             :                             struct dcerpc_binding_handle *b,
     124             :                             struct policy_handle *handle,
     125             :                             struct dom_sid **sids, uint32_t num_sids,
     126             :                             int level, NTSTATUS expected_result, 
     127             :                             enum lsa_SidType *types)
     128             : {
     129           0 :         struct lsa_TransNameArray names;
     130           0 :         NTSTATUS status;
     131           0 :         uint32_t i;
     132           0 :         bool ret = true;
     133             : 
     134           0 :         status = lookup_sids(tctx, level, b, handle, sids, num_sids,
     135             :                              &names);
     136           0 :         if (!NT_STATUS_EQUAL(status, expected_result)) {
     137           0 :                 printf("For level %d expected %s, got %s\n",
     138             :                        level, nt_errstr(expected_result),
     139             :                        nt_errstr(status));
     140           0 :                 return false;
     141             :         }
     142             : 
     143           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OK) &&
     144           0 :             !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
     145           0 :                 return true;
     146             :         }
     147             : 
     148           0 :         for (i=0; i<num_sids; i++) {
     149           0 :                 if (names.names[i].sid_type != types[i]) {
     150           0 :                         printf("In level %d, for sid %s expected %s, "
     151             :                                "got %s\n", level,
     152           0 :                                dom_sid_string(tctx, sids[i]),
     153           0 :                                sid_type_lookup(types[i]),
     154           0 :                                sid_type_lookup(names.names[i].sid_type));
     155           0 :                         ret = false;
     156             :                 }
     157             :         }
     158           0 :         return ret;
     159             : }
     160             : 
     161          12 : static bool get_downleveltrust(struct torture_context *tctx, struct dcerpc_binding_handle *b,
     162             :                                struct policy_handle *handle,
     163             :                                struct dom_sid **sid)
     164             : {
     165           0 :         struct lsa_EnumTrustDom r;
     166          12 :         uint32_t resume_handle = 0;
     167           0 :         struct lsa_DomainList domains;
     168           0 :         int i;
     169             : 
     170          12 :         r.in.handle = handle;
     171          12 :         r.in.resume_handle = &resume_handle;
     172          12 :         r.in.max_size = 1000;
     173          12 :         r.out.domains = &domains;
     174          12 :         r.out.resume_handle = &resume_handle;
     175             : 
     176          12 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b, tctx, &r),
     177             :                 "EnumTrustDom failed");
     178             : 
     179          12 :         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES))
     180          12 :                 torture_fail(tctx, "no trusts");
     181             : 
     182           0 :         if (domains.count == 0) {
     183           0 :                 torture_fail(tctx, "no trusts");
     184             :         }
     185             : 
     186           0 :         for (i=0; i<domains.count; i++) {
     187           0 :                 struct lsa_QueryTrustedDomainInfoBySid q;
     188           0 :                 union lsa_TrustedDomainInfo *info = NULL;
     189             : 
     190           0 :                 if (domains.domains[i].sid == NULL)
     191           0 :                         continue;
     192             : 
     193           0 :                 q.in.handle = handle;
     194           0 :                 q.in.dom_sid = domains.domains[i].sid;
     195           0 :                 q.in.level = 6;
     196           0 :                 q.out.info = &info;
     197             : 
     198           0 :                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfoBySid_r(b, tctx, &q),
     199             :                         "QueryTrustedDomainInfoBySid failed");
     200           0 :                 if (!NT_STATUS_IS_OK(q.out.result)) continue;
     201             : 
     202           0 :                 if ((info->info_ex.trust_direction & 2) &&
     203           0 :                     (info->info_ex.trust_type == 1)) {
     204           0 :                         *sid = domains.domains[i].sid;
     205           0 :                         return true;
     206             :                 }
     207             :         }
     208             : 
     209           0 :         torture_fail(tctx, "I need a AD DC with an outgoing trust to NT4");
     210             : }
     211             : 
     212             : #define NUM_SIDS 8
     213             : 
     214          15 : bool torture_rpc_lsa_lookup(struct torture_context *torture)
     215             : {
     216           0 :         NTSTATUS status;
     217           0 :         struct dcerpc_pipe *p;
     218          15 :         bool ret = true;
     219           0 :         struct policy_handle *handle;
     220          15 :         struct dom_sid *dom_sid = NULL;
     221          15 :         struct dom_sid *trusted_sid = NULL;
     222           0 :         struct dom_sid *sids[NUM_SIDS];
     223           0 :         struct dcerpc_binding_handle *b;
     224           0 :         enum dcerpc_transport_t transport;
     225             : 
     226          15 :         status = torture_rpc_connection(torture, &p, &ndr_table_lsarpc);
     227          15 :         if (!NT_STATUS_IS_OK(status)) {
     228           0 :                 torture_fail(torture, "unable to connect to table");
     229             :         }
     230          15 :         b = p->binding_handle;
     231          15 :         transport = dcerpc_binding_get_transport(p->binding);
     232             : 
     233          15 :         if (transport != NCACN_NP && transport != NCALRPC) {
     234           3 :                 torture_comment(torture,
     235             :                                 "torture_rpc_lsa_lookup is only available "
     236             :                                 "over NCACN_NP or NCALRPC");
     237           3 :                 return true;
     238             :         }
     239             : 
     240          12 :         ret &= open_policy(torture, b, &handle);
     241          12 :         if (!ret) return false;
     242             : 
     243          12 :         ret &= get_domainsid(torture, b, handle, &dom_sid);
     244          12 :         if (!ret) return false;
     245             : 
     246          12 :         ret &= get_downleveltrust(torture, b, handle, &trusted_sid);
     247          12 :         if (!ret) return false;
     248             : 
     249           0 :         torture_comment(torture, "domain sid: %s\n", 
     250             :                                         dom_sid_string(torture, dom_sid));
     251             : 
     252           0 :         sids[0] = dom_sid_parse_talloc(torture, "S-1-1-0");
     253           0 :         sids[1] = dom_sid_parse_talloc(torture, "S-1-5-4");
     254           0 :         sids[2] = dom_sid_parse_talloc(torture, "S-1-5-32");
     255           0 :         sids[3] = dom_sid_parse_talloc(torture, "S-1-5-32-545");
     256           0 :         sids[4] = dom_sid_dup(torture, dom_sid);
     257           0 :         sids[5] = dom_sid_add_rid(torture, dom_sid, 512);
     258           0 :         sids[6] = dom_sid_dup(torture, trusted_sid);
     259           0 :         sids[7] = dom_sid_add_rid(torture, trusted_sid, 512);
     260             : 
     261           0 :         ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 0,
     262           0 :                                NT_STATUS_INVALID_PARAMETER, NULL);
     263             : 
     264             :         {
     265           0 :                 enum lsa_SidType types[NUM_SIDS] =
     266             :                         { SID_NAME_WKN_GRP, SID_NAME_WKN_GRP, SID_NAME_DOMAIN,
     267             :                           SID_NAME_ALIAS, SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
     268             :                           SID_NAME_DOMAIN, SID_NAME_DOM_GRP };
     269             : 
     270           0 :                 ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 1,
     271           0 :                                        NT_STATUS_OK, types);
     272             :         }
     273             : 
     274             :         {
     275           0 :                 enum lsa_SidType types[NUM_SIDS] =
     276             :                         { SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
     277             :                           SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
     278             :                           SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
     279             :                           SID_NAME_DOMAIN, SID_NAME_DOM_GRP };
     280           0 :                 ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 2,
     281           0 :                                        STATUS_SOME_UNMAPPED, types);
     282             :         }
     283             : 
     284             :         {
     285           0 :                 enum lsa_SidType types[NUM_SIDS] =
     286             :                         { SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
     287             :                           SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
     288             :                           SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
     289             :                           SID_NAME_UNKNOWN, SID_NAME_UNKNOWN };
     290           0 :                 ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 3,
     291           0 :                                        STATUS_SOME_UNMAPPED, types);
     292             :         }
     293             : 
     294             :         {
     295           0 :                 enum lsa_SidType types[NUM_SIDS] =
     296             :                         { SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
     297             :                           SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
     298             :                           SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
     299             :                           SID_NAME_UNKNOWN, SID_NAME_UNKNOWN };
     300           0 :                 ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 4,
     301           0 :                                        STATUS_SOME_UNMAPPED, types);
     302             :         }
     303             : 
     304           0 :         ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 5,
     305           0 :                                NT_STATUS_NONE_MAPPED, NULL);
     306             : 
     307             :         {
     308           0 :                 enum lsa_SidType types[NUM_SIDS] =
     309             :                         { SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
     310             :                           SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
     311             :                           SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
     312             :                           SID_NAME_UNKNOWN, SID_NAME_UNKNOWN };
     313           0 :                 ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 6,
     314           0 :                                        STATUS_SOME_UNMAPPED, types);
     315             :         }
     316             : 
     317           0 :         ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 7,
     318           0 :                                NT_STATUS_INVALID_PARAMETER, NULL);
     319           0 :         ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 8,
     320           0 :                                NT_STATUS_INVALID_PARAMETER, NULL);
     321           0 :         ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 9,
     322           0 :                                NT_STATUS_INVALID_PARAMETER, NULL);
     323           0 :         ret &= test_lookupsids(torture, b, handle, sids, NUM_SIDS, 10,
     324           0 :                                NT_STATUS_INVALID_PARAMETER, NULL);
     325             : 
     326           0 :         return ret;
     327             : }
     328             : 
     329         275 : static bool test_LookupSidsReply(struct torture_context *tctx,
     330             :                                  struct dcerpc_pipe *p)
     331             : {
     332         275 :         struct policy_handle *handle = NULL;
     333             : 
     334         275 :         struct dom_sid **sids = NULL;
     335         275 :         uint32_t num_sids = 1;
     336             : 
     337           0 :         struct lsa_LookupSids r;
     338           0 :         struct lsa_SidArray sidarray;
     339         275 :         struct lsa_RefDomainList *domains = NULL;
     340           0 :         struct lsa_TransNameArray names;
     341         275 :         uint32_t count = 0;
     342             : 
     343           0 :         uint32_t i;
     344         275 :         const char *dom_sid = "S-1-5-21-1111111111-2222222222-3333333333";
     345           0 :         const char *dom_admin_sid;
     346         275 :         struct dcerpc_binding_handle *b = p->binding_handle;
     347         275 :         enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
     348             : 
     349         275 :         ZERO_STRUCT(r);
     350         275 :         ZERO_STRUCT(sidarray);
     351         275 :         ZERO_STRUCT(names);
     352             : 
     353         275 :         if (transport != NCACN_NP && transport != NCALRPC) {
     354         120 :                 torture_comment(tctx,
     355             :                                 "test_LookupSidsReply is only available "
     356             :                                 "over NCACN_NP or NCALRPC");
     357         120 :                 return true;
     358             :         }
     359             : 
     360         155 :         if (!open_policy(tctx, b, &handle)) {
     361           0 :                 return false;
     362             :         }
     363             : 
     364         155 :         dom_admin_sid = talloc_asprintf(tctx, "%s-%d", dom_sid, 512);
     365             : 
     366         155 :         sids = talloc_zero_array(tctx, struct dom_sid *, num_sids);
     367             : 
     368         155 :         sids[0] = dom_sid_parse_talloc(tctx, dom_admin_sid);
     369             : 
     370         155 :         names.count = 0;
     371         155 :         names.names = NULL;
     372             : 
     373         155 :         sidarray.num_sids = num_sids;
     374         155 :         sidarray.sids = talloc_zero_array(tctx, struct lsa_SidPtr, num_sids);
     375             : 
     376         310 :         for (i=0; i<num_sids; i++) {
     377         155 :                 sidarray.sids[i].sid = sids[i];
     378             :         }
     379             : 
     380         155 :         r.in.handle     = handle;
     381         155 :         r.in.sids       = &sidarray;
     382         155 :         r.in.names      = &names;
     383         155 :         r.in.level      = LSA_LOOKUP_NAMES_ALL;
     384         155 :         r.in.count      = &count;
     385         155 :         r.out.names     = &names;
     386         155 :         r.out.count     = &count;
     387         155 :         r.out.domains   = &domains;
     388             : 
     389         155 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids_r(b, tctx, &r),
     390             :                 "LookupSids failed");
     391             : 
     392         155 :         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NONE_MAPPED,
     393             :                 "unexpected error code");
     394             : 
     395         155 :         torture_assert_int_equal(tctx, names.count, num_sids,
     396             :                 "unexpected names count");
     397         155 :         torture_assert(tctx, names.names,
     398             :                 "unexpected names pointer");
     399         155 :         torture_assert_str_equal(tctx, names.names[0].name.string, dom_admin_sid,
     400             :                 "unexpected names[0].string");
     401             : 
     402             : #if 0
     403             :         /* vista sp1 passes, w2k3 sp2 fails */
     404             :         torture_assert_int_equal(tctx, domains->count, num_sids,
     405             :                 "unexpected domains count");
     406             :         torture_assert(tctx, domains->domains,
     407             :                 "unexpected domains pointer");
     408             :         torture_assert_str_equal(tctx, dom_sid_string(tctx, domains->domains[0].sid), dom_sid,
     409             :                 "unexpected domain sid");
     410             : #endif
     411             : 
     412         155 :         return true;
     413             : }
     414             : 
     415             : /* check for lookup sids results */
     416        2354 : struct torture_suite *torture_rpc_lsa_lookup_sids(TALLOC_CTX *mem_ctx)
     417             : {
     418         125 :         struct torture_suite *suite;
     419         125 :         struct torture_rpc_tcase *tcase;
     420             : 
     421        2354 :         suite = torture_suite_create(mem_ctx, "lsa.lookupsids");
     422        2354 :         tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
     423             :                                                   &ndr_table_lsarpc);
     424             : 
     425        2354 :         torture_rpc_tcase_add_test(tcase, "LookupSidsReply", test_LookupSidsReply);
     426             : 
     427        2354 :         return suite;
     428             : }

Generated by: LCOV version 1.14