LCOV - code coverage report
Current view: top level - source4/torture/rpc - samr_accessmask.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 183 590 31.0 %
Date: 2024-04-21 15:09:00 Functions: 14 21 66.7 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    test suite for accessmasks on the SAMR pipe
       4             : 
       5             :    Copyright (C) Ronnie Sahlberg 2007
       6             :    Copyright (C) Guenther Deschner 2009
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "librpc/gen_ndr/ndr_samr_c.h"
      24             : #include "torture/rpc/torture_rpc.h"
      25             : #include "param/param.h"
      26             : #include "libcli/security/security.h"
      27             : 
      28             : 
      29             : /* test user created to test the ACLs associated to SAMR objects */
      30             : #define TEST_USER_NAME "samr_testuser"
      31             : #define TEST_MACHINENAME "samrtestmach"
      32             : 
      33         708 : static NTSTATUS torture_samr_Close(struct torture_context *tctx,
      34             :                                    struct dcerpc_binding_handle *b,
      35             :                                    struct policy_handle *h)
      36             : {
      37           0 :         NTSTATUS status;
      38           0 :         struct samr_Close cl;
      39             : 
      40         708 :         cl.in.handle  = h;
      41         708 :         cl.out.handle = h;
      42         708 :         status = dcerpc_samr_Close_r(b, tctx, &cl);
      43         708 :         if (!NT_STATUS_IS_OK(status)) {
      44           0 :                 return status;
      45             :         }
      46             : 
      47         708 :         return cl.out.result;
      48             : }
      49             : 
      50           5 : static NTSTATUS torture_samr_Connect5(struct torture_context *tctx,
      51             :                                       struct dcerpc_binding_handle *b,
      52             :                                       uint32_t mask, struct policy_handle *h)
      53             : {
      54           0 :         NTSTATUS status;
      55           0 :         struct samr_Connect5 r5;
      56           0 :         union samr_ConnectInfo info;
      57           5 :         uint32_t level_out = 0;
      58             : 
      59           5 :         info.info1.client_version = 0;
      60           5 :         info.info1.supported_features = 0;
      61           5 :         r5.in.system_name = "";
      62           5 :         r5.in.level_in = 1;
      63           5 :         r5.in.info_in = &info;
      64           5 :         r5.out.info_out = &info;
      65           5 :         r5.out.level_out = &level_out;
      66           5 :         r5.out.connect_handle = h;
      67           5 :         r5.in.access_mask = mask;
      68             : 
      69           5 :         status = dcerpc_samr_Connect5_r(b, tctx, &r5);
      70           5 :         if (!NT_STATUS_IS_OK(status)) {
      71           0 :                 return status;
      72             :         }
      73             : 
      74           5 :         return r5.out.result;
      75             : }
      76             : 
      77             : /* check which bits in accessmask allows us to connect to the server */
      78           0 : static bool test_samr_accessmask_Connect5(struct torture_context *tctx,
      79             :                                           struct dcerpc_pipe *p)
      80             : {
      81           0 :         NTSTATUS status;
      82           0 :         struct policy_handle h;
      83           0 :         int i;
      84           0 :         uint32_t mask;
      85           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
      86             : 
      87           0 :         printf("Testing which bits in accessmask allows us to connect\n");
      88           0 :         mask = 1;
      89           0 :         for (i=0;i<33;i++) {
      90           0 :                 printf("Testing Connect5 with access mask 0x%08x", mask);
      91           0 :                 status = torture_samr_Connect5(tctx, b, mask, &h);
      92           0 :                 mask <<= 1;
      93             : 
      94           0 :                 switch (i) {
      95           0 :                 case 6:
      96             :                 case 7:
      97             :                 case 8:
      98             :                 case 9:
      99             :                 case 10:
     100             :                 case 11:
     101             :                 case 12:
     102             :                 case 13:
     103             :                 case 14:
     104             :                 case 15:
     105             :                 case 20:
     106             :                 case 21:
     107             :                 case 22:
     108             :                 case 23:
     109             :                 case 26:
     110             :                 case 27:
     111           0 :                         printf(" expecting to fail");
     112             :                         /* of only one of these bits are set we expect to
     113             :                            fail by default
     114             :                         */
     115           0 :                         if(!NT_STATUS_EQUAL(NT_STATUS_ACCESS_DENIED, status)) {
     116           0 :                                 printf("Connect5 failed - %s\n", nt_errstr(status));
     117           0 :                                 return false;
     118             :                         }
     119           0 :                         break;
     120           0 :                 default:
     121             :                         /* these bits set are expected to succeed by default */
     122           0 :                         if (!NT_STATUS_IS_OK(status)) {
     123           0 :                                 printf("Connect5 failed - %s\n", nt_errstr(status));
     124           0 :                                 return false;
     125             :                         }
     126             : 
     127           0 :                         status = torture_samr_Close(tctx, b, &h);
     128           0 :                         if (!NT_STATUS_IS_OK(status)) {
     129           0 :                                 printf("Close failed - %s\n", nt_errstr(status));
     130           0 :                                 return false;
     131             :                         }
     132           0 :                         break;
     133             :                 }
     134           0 :                 printf(" OK\n");
     135             :         }
     136             : 
     137           0 :         return true;
     138             : }
     139             : 
     140             : /* check which bits in accessmask allows us to EnumDomains()
     141             :    by default we must specify at least one of :
     142             :         SAMR/EnumDomains
     143             :         Maximum
     144             :         GenericAll
     145             :         GenericRead
     146             :    in the access mask to Connect5() in order to be allowed to perform
     147             :    EnumDomains() on the policy handle returned from Connect5()
     148             : */
     149           0 : static bool test_samr_accessmask_EnumDomains(struct torture_context *tctx,
     150             :                                              struct dcerpc_pipe *p)
     151             : {
     152           0 :         NTSTATUS status;
     153           0 :         struct samr_EnumDomains ed;
     154           0 :         struct policy_handle ch;
     155           0 :         int i;
     156           0 :         uint32_t mask;
     157           0 :         uint32_t resume_handle = 0;
     158           0 :         struct samr_SamArray *sam = NULL;
     159           0 :         uint32_t num_entries = 0;
     160           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     161             : 
     162           0 :         printf("Testing which bits in Connect5 accessmask allows us to EnumDomains\n");
     163           0 :         mask = 1;
     164           0 :         for (i=0;i<33;i++) {
     165           0 :                 printf("Testing Connect5/EnumDomains with access mask 0x%08x", mask);
     166           0 :                 status = torture_samr_Connect5(tctx, b, mask, &ch);
     167           0 :                 mask <<= 1;
     168             : 
     169           0 :                 switch (i) {
     170           0 :                 case 4:  /* SAMR/EnumDomains */
     171             :                 case 25: /* Maximum */
     172             :                 case 28: /* GenericAll */
     173             :                 case 31: /* GenericRead */
     174             :                         /* these bits set are expected to succeed by default */
     175           0 :                         if (!NT_STATUS_IS_OK(status)) {
     176           0 :                                 printf("Connect5 failed - %s\n", nt_errstr(status));
     177           0 :                                 return false;
     178             :                         }
     179             : 
     180           0 :                         ed.in.connect_handle = &ch;
     181           0 :                         ed.in.resume_handle = &resume_handle;
     182           0 :                         ed.in.buf_size = (uint32_t)-1;
     183           0 :                         ed.out.resume_handle = &resume_handle;
     184           0 :                         ed.out.num_entries = &num_entries;
     185           0 :                         ed.out.sam = &sam;
     186             : 
     187           0 :                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &ed),
     188             :                                 "EnumDomains failed");
     189           0 :                         if (!NT_STATUS_IS_OK(ed.out.result)) {
     190           0 :                                 printf("EnumDomains failed - %s\n", nt_errstr(ed.out.result));
     191           0 :                                 return false;
     192             :                         }
     193             : 
     194           0 :                         status = torture_samr_Close(tctx, b, &ch);
     195           0 :                         if (!NT_STATUS_IS_OK(status)) {
     196           0 :                                 printf("Close failed - %s\n", nt_errstr(status));
     197           0 :                                 return false;
     198             :                         }
     199           0 :                         break;
     200           0 :                 default:
     201           0 :                         printf(" expecting to fail");
     202             : 
     203           0 :                         if (!NT_STATUS_IS_OK(status)) {
     204           0 :                                 printf(" OK\n");
     205           0 :                                 continue;
     206             :                         }
     207             : 
     208           0 :                         ed.in.connect_handle = &ch;
     209           0 :                         ed.in.resume_handle = &resume_handle;
     210           0 :                         ed.in.buf_size = (uint32_t)-1;
     211           0 :                         ed.out.resume_handle = &resume_handle;
     212           0 :                         ed.out.num_entries = &num_entries;
     213           0 :                         ed.out.sam = &sam;
     214             : 
     215           0 :                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &ed),
     216             :                                 "EnumDomains failed");
     217           0 :                         if(!NT_STATUS_EQUAL(NT_STATUS_ACCESS_DENIED, ed.out.result)) {
     218           0 :                                 printf("EnumDomains failed - %s\n", nt_errstr(ed.out.result));
     219           0 :                                 return false;
     220             :                         }
     221             : 
     222           0 :                         status = torture_samr_Close(tctx, b, &ch);
     223           0 :                         if (!NT_STATUS_IS_OK(status)) {
     224           0 :                                 printf("Close failed - %s\n", nt_errstr(status));
     225           0 :                                 return false;
     226             :                         }
     227           0 :                         break;
     228             :                 }
     229           0 :                 printf(" OK\n");
     230             :         }
     231             : 
     232           0 :         return true;
     233             : }
     234             : 
     235             : 
     236             : /*
     237             :  * test how ACLs affect how/if a user can connect to the SAMR service
     238             :  *
     239             :  * samr_SetSecurity() returns SUCCESS when changing the ACL for
     240             :  * a policy handle got from Connect5()   but the ACL is not changed on
     241             :  * the server
     242             :  */
     243           0 : static bool test_samr_connect_user_acl(struct torture_context *tctx,
     244             :                                        struct dcerpc_binding_handle *b,
     245             :                                        struct cli_credentials *test_credentials,
     246             :                                        const struct dom_sid *test_sid)
     247             : 
     248             : {
     249           0 :         NTSTATUS status;
     250           0 :         struct policy_handle ch;
     251           0 :         struct policy_handle uch;
     252           0 :         struct samr_QuerySecurity qs;
     253           0 :         struct samr_SetSecurity ss;
     254           0 :         struct security_ace ace = {};
     255           0 :         struct security_descriptor *sd;
     256           0 :         struct sec_desc_buf sdb, *sdbuf = NULL;
     257           0 :         bool ret = true;
     258           0 :         int sd_size;
     259           0 :         struct dcerpc_pipe *test_p;
     260           0 :         struct dcerpc_binding_handle *test_b;
     261           0 :         const char *binding = torture_setting_string(tctx, "binding", NULL);
     262             : 
     263           0 :         printf("Testing ACLs to allow/prevent users to connect to SAMR");
     264             : 
     265             :         /* connect to SAMR */
     266           0 :         status = torture_samr_Connect5(tctx, b, SEC_FLAG_MAXIMUM_ALLOWED, &ch);
     267           0 :         if (!NT_STATUS_IS_OK(status)) {
     268           0 :                 printf("Connect5 failed - %s\n", nt_errstr(status));
     269           0 :                 return false;
     270             :         }
     271             : 
     272             : 
     273             :         /* get the current ACL for the SAMR policy handle */
     274           0 :         qs.in.handle = &ch;
     275           0 :         qs.in.sec_info = SECINFO_DACL;
     276           0 :         qs.out.sdbuf = &sdbuf;
     277           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QuerySecurity_r(b, tctx, &qs),
     278             :                 "QuerySecurity failed");
     279           0 :         if (!NT_STATUS_IS_OK(qs.out.result)) {
     280           0 :                 printf("QuerySecurity failed - %s\n", nt_errstr(qs.out.result));
     281           0 :                 ret = false;
     282             :         }
     283             : 
     284             :         /* how big is the security descriptor? */
     285           0 :         sd_size = sdbuf->sd_size;
     286             : 
     287             : 
     288             :         /* add an ACE to the security descriptor to deny the user the
     289             :          * 'connect to server' right
     290             :          */
     291           0 :         sd = sdbuf->sd;
     292           0 :         ace.type = SEC_ACE_TYPE_ACCESS_DENIED;
     293           0 :         ace.flags = 0;
     294           0 :         ace.access_mask = SAMR_ACCESS_CONNECT_TO_SERVER;
     295           0 :         ace.trustee = *test_sid;
     296           0 :         status = security_descriptor_dacl_add(sd, &ace);
     297           0 :         if (!NT_STATUS_IS_OK(status)) {
     298           0 :                 printf("Failed to add ACE to security descriptor\n");
     299           0 :                 ret = false;
     300             :         }
     301           0 :         ss.in.handle = &ch;
     302           0 :         ss.in.sec_info = SECINFO_DACL;
     303           0 :         ss.in.sdbuf = &sdb;
     304           0 :         sdb.sd = sd;
     305           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetSecurity_r(b, tctx, &ss),
     306             :                 "SetSecurity failed");
     307           0 :         if (!NT_STATUS_IS_OK(ss.out.result)) {
     308           0 :                 printf("SetSecurity failed - %s\n", nt_errstr(ss.out.result));
     309           0 :                 ret = false;
     310             :         }
     311             : 
     312             : 
     313             :         /* Try to connect as the test user */
     314           0 :         status = dcerpc_pipe_connect(tctx,
     315             :                              &test_p, binding, &ndr_table_samr,
     316             :                              test_credentials, tctx->ev, tctx->lp_ctx);
     317           0 :         if (!NT_STATUS_IS_OK(status)) {
     318           0 :                 printf("dcerpc_pipe_connect failed: %s\n", nt_errstr(status));
     319           0 :                 return false;
     320             :         }
     321           0 :         test_b = test_p->binding_handle;
     322             : 
     323             :         /* connect to SAMR as the user */
     324           0 :         status = torture_samr_Connect5(tctx, test_b, SEC_FLAG_MAXIMUM_ALLOWED, &uch);
     325           0 :         if (!NT_STATUS_IS_OK(status)) {
     326           0 :                 printf("Connect5 failed - %s\n", nt_errstr(status));
     327           0 :                 return false;
     328             :         }
     329             :         /* disconnect the user */
     330           0 :         talloc_free(test_p);
     331             : 
     332             : 
     333             :         /* read the sequrity descriptor back. it should not have changed
     334             :          * even though samr_SetSecurity returned SUCCESS
     335             :          */
     336           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QuerySecurity_r(b, tctx, &qs),
     337             :                 "QuerySecurity failed");
     338           0 :         if (!NT_STATUS_IS_OK(qs.out.result)) {
     339           0 :                 printf("QuerySecurity failed - %s\n", nt_errstr(qs.out.result));
     340           0 :                 ret = false;
     341             :         }
     342           0 :         if (sd_size != sdbuf->sd_size) {
     343           0 :                 printf("security descriptor changed\n");
     344           0 :                 ret = false;
     345             :         }
     346             : 
     347             : 
     348           0 :         status = torture_samr_Close(tctx, b, &ch);
     349           0 :         if (!NT_STATUS_IS_OK(status)) {
     350           0 :                 printf("Close failed - %s\n", nt_errstr(status));
     351           0 :                 ret = false;
     352             :         }
     353             : 
     354           0 :         if (ret == true) {
     355           0 :                 printf(" OK\n");
     356             :         }
     357           0 :         return ret;
     358             : }
     359             : 
     360             : /*
     361             :  * test if the ACLs are enforced for users.
     362             :  * a normal testuser only gets the rights provided in the ACL for
     363             :  * Everyone   which does not include the SAMR_ACCESS_SHUTDOWN_SERVER
     364             :  * right.  If the ACLs are checked when a user connects
     365             :  * a testuser that requests the accessmask with only this bit set
     366             :  * the connect should fail.
     367             :  */
     368           0 : static bool test_samr_connect_user_acl_enforced(struct torture_context *tctx,
     369             :                                                 struct dcerpc_binding_handle *b,
     370             :                                                 struct cli_credentials *test_credentials,
     371             :                                                 const struct dom_sid *test_sid)
     372             : 
     373             : {
     374           0 :         NTSTATUS status;
     375           0 :         struct policy_handle uch;
     376           0 :         bool ret = true;
     377           0 :         struct dcerpc_pipe *test_p;
     378           0 :         struct dcerpc_binding_handle *test_b;
     379           0 :         const char *binding = torture_setting_string(tctx, "binding", NULL);
     380             : 
     381           0 :         printf("Testing if ACLs are enforced for non domain admin users when connecting to SAMR");
     382             : 
     383             : 
     384           0 :         status = dcerpc_pipe_connect(tctx,
     385             :                              &test_p, binding, &ndr_table_samr,
     386             :                              test_credentials, tctx->ev, tctx->lp_ctx);
     387           0 :         if (!NT_STATUS_IS_OK(status)) {
     388           0 :                 printf("dcerpc_pipe_connect failed: %s\n", nt_errstr(status));
     389           0 :                 return false;
     390             :         }
     391           0 :         test_b = test_p->binding_handle;
     392             : 
     393             :         /* connect to SAMR as the user */
     394           0 :         status = torture_samr_Connect5(tctx, test_b, SAMR_ACCESS_SHUTDOWN_SERVER, &uch);
     395           0 :         if (NT_STATUS_IS_OK(status)) {
     396           0 :                 printf("Connect5 failed - %s\n", nt_errstr(status));
     397           0 :                 return false;
     398             :         }
     399           0 :         printf(" OK\n");
     400             : 
     401             :         /* disconnect the user */
     402           0 :         talloc_free(test_p);
     403             : 
     404           0 :         return ret;
     405             : }
     406             : 
     407             : /* check which bits in accessmask allows us to LookupDomain()
     408             :    by default we must specify at least one of :
     409             :    in the access mask to Connect5() in order to be allowed to perform
     410             :                 case 5:  samr/opendomain
     411             :                 case 25: Maximum
     412             :                 case 28: GenericAll
     413             :                 case 29: GenericExecute
     414             :    LookupDomain() on the policy handle returned from Connect5()
     415             : */
     416           0 : static bool test_samr_accessmask_LookupDomain(struct torture_context *tctx,
     417             :                                               struct dcerpc_pipe *p)
     418             : {
     419           0 :         NTSTATUS status;
     420           0 :         struct samr_LookupDomain ld;
     421           0 :         struct dom_sid2 *sid = NULL;
     422           0 :         struct policy_handle ch;
     423           0 :         struct lsa_String dn;
     424           0 :         int i;
     425           0 :         uint32_t mask;
     426           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     427             : 
     428           0 :         printf("Testing which bits in Connect5 accessmask allows us to LookupDomain\n");
     429           0 :         mask = 1;
     430           0 :         for (i=0;i<33;i++) {
     431           0 :                 printf("Testing Connect5/LookupDomain with access mask 0x%08x", mask);
     432           0 :                 status = torture_samr_Connect5(tctx, b, mask, &ch);
     433           0 :                 mask <<= 1;
     434             : 
     435           0 :                 switch (i) {
     436           0 :                 case 5:
     437             :                 case 25: /* Maximum */
     438             :                 case 28: /* GenericAll */
     439             :                 case 29: /* GenericExecute */
     440             :                         /* these bits set are expected to succeed by default */
     441           0 :                         if (!NT_STATUS_IS_OK(status)) {
     442           0 :                                 printf("Connect5 failed - %s\n", nt_errstr(status));
     443           0 :                                 return false;
     444             :                         }
     445             : 
     446           0 :                         ld.in.connect_handle = &ch;
     447           0 :                         ld.in.domain_name    = &dn;
     448           0 :                         ld.out.sid           = &sid;
     449           0 :                         dn.string            = lpcfg_workgroup(tctx->lp_ctx);
     450             : 
     451           0 :                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &ld),
     452             :                                 "LookupDomain failed");
     453           0 :                         if (!NT_STATUS_IS_OK(ld.out.result)) {
     454           0 :                                 printf("LookupDomain failed - %s\n", nt_errstr(ld.out.result));
     455           0 :                                 return false;
     456             :                         }
     457             : 
     458           0 :                         status = torture_samr_Close(tctx, b, &ch);
     459           0 :                         if (!NT_STATUS_IS_OK(status)) {
     460           0 :                                 printf("Close failed - %s\n", nt_errstr(status));
     461           0 :                                 return false;
     462             :                         }
     463           0 :                         break;
     464           0 :                 default:
     465           0 :                         printf(" expecting to fail");
     466             : 
     467           0 :                         if (!NT_STATUS_IS_OK(status)) {
     468           0 :                                 printf(" OK\n");
     469           0 :                                 continue;
     470             :                         }
     471             : 
     472           0 :                         ld.in.connect_handle = &ch;
     473           0 :                         ld.in.domain_name    = &dn;
     474           0 :                         ld.out.sid           = &sid;
     475           0 :                         dn.string            = lpcfg_workgroup(tctx->lp_ctx);
     476             : 
     477           0 :                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &ld),
     478             :                                 "LookupDomain failed");
     479           0 :                         if(!NT_STATUS_EQUAL(NT_STATUS_ACCESS_DENIED, ld.out.result)) {
     480           0 :                                 printf("LookupDomain failed - %s\n", nt_errstr(ld.out.result));
     481           0 :                                 return false;
     482             :                         }
     483             : 
     484           0 :                         status = torture_samr_Close(tctx, b, &ch);
     485           0 :                         if (!NT_STATUS_IS_OK(status)) {
     486           0 :                                 printf("Close failed - %s\n", nt_errstr(status));
     487           0 :                                 return false;
     488             :                         }
     489           0 :                         break;
     490             :                 }
     491           0 :                 printf(" OK\n");
     492             :         }
     493             : 
     494           0 :         return true;
     495             : }
     496             : 
     497             : /* check which bits in accessmask allows us to OpenDomain()
     498             :    by default we must specify at least one of :
     499             :         samr/opendomain
     500             :         Maximum
     501             :         GenericAll
     502             :         GenericExecute
     503             :    in the access mask to Connect5() in order to be allowed to perform
     504             :    OpenDomain() on the policy handle returned from Connect5()
     505             : */
     506           0 : static bool test_samr_accessmask_OpenDomain(struct torture_context *tctx,
     507             :                                             struct dcerpc_pipe *p)
     508             : {
     509           0 :         NTSTATUS status;
     510           0 :         struct samr_LookupDomain ld;
     511           0 :         struct dom_sid2 *sid = NULL;
     512           0 :         struct samr_OpenDomain od;
     513           0 :         struct policy_handle ch;
     514           0 :         struct policy_handle dh;
     515           0 :         struct lsa_String dn;
     516           0 :         int i;
     517           0 :         uint32_t mask;
     518           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     519             : 
     520             : 
     521             :         /* first we must grab the sid of the domain */
     522           0 :         status = torture_samr_Connect5(tctx, b, SEC_FLAG_MAXIMUM_ALLOWED, &ch);
     523           0 :         if (!NT_STATUS_IS_OK(status)) {
     524           0 :                 printf("Connect5 failed - %s\n", nt_errstr(status));
     525           0 :                 return false;
     526             :         }
     527             : 
     528           0 :         ld.in.connect_handle = &ch;
     529           0 :         ld.in.domain_name    = &dn;
     530           0 :         ld.out.sid           = &sid;
     531           0 :         dn.string            = lpcfg_workgroup(tctx->lp_ctx);
     532           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &ld),
     533             :                 "LookupDomain failed");
     534           0 :         if (!NT_STATUS_IS_OK(ld.out.result)) {
     535           0 :                 printf("LookupDomain failed - %s\n", nt_errstr(ld.out.result));
     536           0 :                 return false;
     537             :         }
     538             : 
     539             : 
     540             : 
     541           0 :         printf("Testing which bits in Connect5 accessmask allows us to OpenDomain\n");
     542           0 :         mask = 1;
     543           0 :         for (i=0;i<33;i++) {
     544           0 :                 printf("Testing Connect5/OpenDomain with access mask 0x%08x", mask);
     545           0 :                 status = torture_samr_Connect5(tctx, b, mask, &ch);
     546           0 :                 mask <<= 1;
     547             : 
     548           0 :                 switch (i) {
     549           0 :                 case 5:
     550             :                 case 25: /* Maximum */
     551             :                 case 28: /* GenericAll */
     552             :                 case 29: /* GenericExecute */
     553             :                         /* these bits set are expected to succeed by default */
     554           0 :                         if (!NT_STATUS_IS_OK(status)) {
     555           0 :                                 printf("Connect5 failed - %s\n", nt_errstr(status));
     556           0 :                                 return false;
     557             :                         }
     558             : 
     559           0 :                         od.in.connect_handle = &ch;
     560           0 :                         od.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
     561           0 :                         od.in.sid = sid;
     562           0 :                         od.out.domain_handle = &dh;
     563             : 
     564           0 :                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenDomain_r(b, tctx, &od),
     565             :                                 "OpenDomain failed");
     566           0 :                         if (!NT_STATUS_IS_OK(od.out.result)) {
     567           0 :                                 printf("OpenDomain failed - %s\n", nt_errstr(od.out.result));
     568           0 :                                 return false;
     569             :                         }
     570             : 
     571           0 :                         status = torture_samr_Close(tctx, b, &dh);
     572           0 :                         if (!NT_STATUS_IS_OK(status)) {
     573           0 :                                 printf("Close failed - %s\n", nt_errstr(status));
     574           0 :                                 return false;
     575             :                         }
     576             : 
     577           0 :                         status = torture_samr_Close(tctx, b, &ch);
     578           0 :                         if (!NT_STATUS_IS_OK(status)) {
     579           0 :                                 printf("Close failed - %s\n", nt_errstr(status));
     580           0 :                                 return false;
     581             :                         }
     582           0 :                         break;
     583           0 :                 default:
     584           0 :                         printf(" expecting to fail");
     585             : 
     586           0 :                         if (!NT_STATUS_IS_OK(status)) {
     587           0 :                                 printf(" OK\n");
     588           0 :                                 continue;
     589             :                         }
     590             : 
     591           0 :                         status = torture_samr_Close(tctx, b, &ch);
     592           0 :                         if (!NT_STATUS_IS_OK(status)) {
     593           0 :                                 printf("Close failed - %s\n", nt_errstr(status));
     594           0 :                                 return false;
     595             :                         }
     596           0 :                         break;
     597             :                 }
     598           0 :                 printf(" OK\n");
     599             :         }
     600             : 
     601           0 :         return true;
     602             : }
     603             : 
     604           0 : static bool test_samr_connect(struct torture_context *tctx,
     605             :                               struct dcerpc_pipe *p)
     606             : {
     607           0 :         void *testuser;
     608           0 :         const char *testuser_passwd;
     609           0 :         struct cli_credentials *test_credentials;
     610           0 :         bool ret = true;
     611           0 :         const struct dom_sid *test_sid;
     612           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     613             : 
     614           0 :         if (torture_setting_bool(tctx, "samba3", false)) {
     615           0 :                 torture_skip(tctx, "Skipping test against Samba 3");
     616             :         }
     617             : 
     618             :         /* create a test user */
     619           0 :         testuser = torture_create_testuser(tctx, TEST_USER_NAME, lpcfg_workgroup(tctx->lp_ctx),
     620             :                                            ACB_NORMAL, &testuser_passwd);
     621           0 :         if (!testuser) {
     622           0 :                 printf("Failed to create test user\n");
     623           0 :                 return false;
     624             :         }
     625           0 :         test_credentials = cli_credentials_init(tctx);
     626           0 :         cli_credentials_set_workstation(test_credentials, "localhost", CRED_SPECIFIED);
     627           0 :         cli_credentials_set_domain(test_credentials, lpcfg_workgroup(tctx->lp_ctx),
     628             :                                    CRED_SPECIFIED);
     629           0 :         cli_credentials_set_username(test_credentials, TEST_USER_NAME, CRED_SPECIFIED);
     630           0 :         cli_credentials_set_password(test_credentials, testuser_passwd, CRED_SPECIFIED);
     631           0 :         test_sid = torture_join_user_sid(testuser);
     632             : 
     633             : 
     634             :         /* test if ACLs can be changed for the policy handle
     635             :          * returned by Connect5
     636             :          */
     637           0 :         if (!test_samr_connect_user_acl(tctx, b, test_credentials, test_sid)) {
     638           0 :                 ret = false;
     639             :         }
     640             : 
     641             :         /* test if the ACLs that are reported from the Connect5
     642             :          * policy handle is enforced.
     643             :          * i.e. an ordinary user only has the same rights as Everybody
     644             :          *   ReadControl
     645             :          *   Samr/OpenDomain
     646             :          *   Samr/EnumDomains
     647             :          *   Samr/ConnectToServer
     648             :          * is granted and should therefore not be able to connect when
     649             :          * requesting SAMR_ACCESS_SHUTDOWN_SERVER
     650             :          */
     651           0 :         if (!test_samr_connect_user_acl_enforced(tctx, b, test_credentials, test_sid)) {
     652           0 :                 ret = false;
     653             :         }
     654             : 
     655             :         /* remove the test user */
     656           0 :         torture_leave_domain(tctx, testuser);
     657             : 
     658           0 :         return ret;
     659             : }
     660             : 
     661        2354 : struct torture_suite *torture_rpc_samr_accessmask(TALLOC_CTX *mem_ctx)
     662             : {
     663        2354 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.accessmask");
     664         125 :         struct torture_rpc_tcase *tcase;
     665             : 
     666        2354 :         tcase = torture_suite_add_rpc_iface_tcase(suite, "samr",
     667             :                                                   &ndr_table_samr);
     668             : 
     669        2354 :         torture_rpc_tcase_add_test(tcase, "connect", test_samr_connect);
     670             : 
     671             :         /* test which bits in the accessmask to Connect5 will allow
     672             :          * us to call OpenDomain() */
     673        2354 :         torture_rpc_tcase_add_test(tcase, "OpenDomain",
     674             :                                    test_samr_accessmask_OpenDomain);
     675             : 
     676             :         /* test which bits in the accessmask to Connect5 will allow
     677             :          * us to call LookupDomain() */
     678        2354 :         torture_rpc_tcase_add_test(tcase, "LookupDomain",
     679             :                                    test_samr_accessmask_LookupDomain);
     680             : 
     681             :         /* test which bits in the accessmask to Connect5 will allow
     682             :          * us to call EnumDomains() */
     683        2354 :         torture_rpc_tcase_add_test(tcase, "EnumDomains",
     684             :                                    test_samr_accessmask_EnumDomains);
     685             : 
     686             :         /* test which bits in the accessmask to Connect5
     687             :            will allow us to connect to the server */
     688        2354 :         torture_rpc_tcase_add_test(tcase, "Connect5",
     689             :                                    test_samr_accessmask_Connect5);
     690             : 
     691        2354 :         return suite;
     692             : }
     693             : 
     694        1013 : static bool test_LookupRids(struct torture_context *tctx,
     695             :                             struct dcerpc_binding_handle *b,
     696             :                             struct policy_handle *domain_handle,
     697             :                             uint32_t rid)
     698             : {
     699           0 :         struct samr_LookupRids r;
     700           0 :         struct lsa_Strings names;
     701           0 :         struct samr_Ids types;
     702             : 
     703        1013 :         torture_comment(tctx, "Testing LookupRids %d\n", rid);
     704             : 
     705        1013 :         r.in.domain_handle = domain_handle;
     706        1013 :         r.in.num_rids = 1;
     707        1013 :         r.in.rids = &rid;
     708        1013 :         r.out.names = &names;
     709        1013 :         r.out.types = &types;
     710             : 
     711        1013 :         torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupRids_r(b, tctx, &r),
     712             :                 "failed to call samr_LookupRids");
     713        1013 :         torture_assert_ntstatus_ok(tctx, r.out.result,
     714             :                 "failed to call samr_LookupRids");
     715             : 
     716        1013 :         return true;
     717             : }
     718             : 
     719             : 
     720         355 : static bool test_user(struct torture_context *tctx,
     721             :                       struct dcerpc_binding_handle *b,
     722             :                       struct policy_handle *domain_handle,
     723             :                       uint32_t access_mask,
     724             :                       struct samr_DispEntryGeneral *u)
     725             : {
     726           0 :         struct policy_handle user_handle;
     727             : 
     728         355 :         torture_comment(tctx, "Testing user %s (%d)\n", u->account_name.string, u->rid);
     729             : 
     730         355 :         torture_assert(tctx, test_LookupRids(tctx, b, domain_handle, u->rid),
     731             :                 "failed to call lookuprids");
     732             : 
     733             :         {
     734           0 :                 struct samr_OpenUser r;
     735             : 
     736         355 :                 r.in.domain_handle = domain_handle;
     737         355 :                 r.in.access_mask = access_mask;
     738         355 :                 r.in.rid = u->rid;
     739         355 :                 r.out.user_handle = &user_handle;
     740             : 
     741         355 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
     742             :                         "failed to open user");
     743         355 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
     744             :                         "failed to open user");
     745             :         }
     746             :         {
     747           0 :                 struct samr_QueryUserInfo r;
     748           0 :                 union samr_UserInfo *info;
     749         355 :                 uint32_t levels[] = { 16, 21 };
     750           0 :                 int i;
     751             : 
     752         355 :                 r.in.user_handle = &user_handle;
     753         355 :                 r.out.info = &info;
     754             : 
     755        1065 :                 for (i=0; i < ARRAY_SIZE(levels); i++) {
     756             : 
     757         710 :                         r.in.level = levels[i];
     758             : 
     759         710 :                         torture_comment(tctx, "Testing QueryUserInfo rid: %d level: %d\n",
     760         710 :                                 u->rid, r.in.level);
     761             : 
     762         710 :                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
     763             :                                 talloc_asprintf(tctx, "failed to query user info level %d", r.in.level));
     764         710 :                         torture_assert_ntstatus_ok(tctx, r.out.result,
     765             :                                 talloc_asprintf(tctx, "failed to query user info level %d", r.in.level));
     766             :                 }
     767             :         }
     768             :         {
     769           0 :                 struct samr_GetGroupsForUser r;
     770           0 :                 struct samr_RidWithAttributeArray *rids;
     771             : 
     772         355 :                 r.in.user_handle = &user_handle;
     773         355 :                 r.out.rids = &rids;
     774             : 
     775         355 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetGroupsForUser_r(b, tctx, &r),
     776             :                         "failed to query groups for user");
     777         355 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
     778             :                         "failed to query groups for user");
     779             :         }
     780             : 
     781         355 :         torture_assert_ntstatus_ok(tctx,
     782             :                 torture_samr_Close(tctx, b, &user_handle),
     783             :                 "failed to close user handle");
     784             : 
     785         355 :         return true;
     786             : }
     787             : 
     788         343 : static bool test_samr_group(struct torture_context *tctx,
     789             :                             struct dcerpc_binding_handle *b,
     790             :                             struct policy_handle *domain_handle,
     791             :                             uint32_t access_mask,
     792             :                             struct samr_SamEntry *g)
     793             : {
     794           0 :         struct policy_handle group_handle;
     795             : 
     796         343 :         torture_comment(tctx, "Testing group %s (%d)\n", g->name.string, g->idx);
     797             : 
     798         343 :         torture_assert(tctx, test_LookupRids(tctx, b, domain_handle, g->idx),
     799             :                 "failed to call lookuprids");
     800             :         {
     801           0 :                 struct samr_OpenGroup r;
     802             : 
     803         343 :                 r.in.domain_handle = domain_handle;
     804         343 :                 r.in.access_mask = access_mask;
     805         343 :                 r.in.rid = g->idx;
     806         343 :                 r.out.group_handle = &group_handle;
     807             : 
     808         343 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
     809             :                         "failed to open group");
     810         343 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
     811             :                         "failed to open group");
     812             :         }
     813             :         {
     814           0 :                 struct samr_QueryGroupMember r;
     815           0 :                 struct samr_RidAttrArray *rids;
     816             : 
     817         343 :                 r.in.group_handle = &group_handle;
     818         343 :                 r.out.rids = &rids;
     819             : 
     820         343 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &r),
     821             :                         "failed to query group member");
     822         343 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
     823             :                         "failed to query group member");
     824             : 
     825             :         }
     826             : 
     827         343 :         torture_assert_ntstatus_ok(tctx,
     828             :                 torture_samr_Close(tctx, b, &group_handle),
     829             :                 "failed to close group handle");
     830             : 
     831         343 :         return true;
     832             : }
     833             : 
     834         315 : static bool test_samr_alias(struct torture_context *tctx,
     835             :                             struct dcerpc_binding_handle *b,
     836             :                             struct policy_handle *domain_handle,
     837             :                             struct samr_SamEntry *a)
     838             : {
     839         315 :         torture_comment(tctx, "Testing alias %s (%d)\n", a->name.string, a->idx);
     840             : 
     841         315 :         torture_assert(tctx, test_LookupRids(tctx, b, domain_handle, a->idx),
     842             :                 "failed to call lookuprids");
     843             : 
     844             :         {
     845           0 :                 struct samr_GetAliasMembership r;
     846           0 :                 struct lsa_SidArray sids;
     847           0 :                 struct samr_Ids rids;
     848             : 
     849         315 :                 ZERO_STRUCT(sids);
     850             : 
     851         315 :                 r.in.domain_handle = domain_handle;
     852         315 :                 r.in.sids = &sids;
     853         315 :                 r.out.rids = &rids;
     854             : 
     855         315 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
     856             :                         "failed to get alias membership");
     857         315 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
     858             :                         "failed to get alias membership");
     859             :         }
     860             : 
     861             : 
     862         315 :         return true;
     863             : }
     864             : 
     865           5 : static bool test_samr_domain(struct torture_context *tctx,
     866             :                              struct dcerpc_binding_handle *b,
     867             :                              uint32_t access_mask,
     868             :                              const char *domain_name,
     869             :                              struct policy_handle *connect_handle,
     870             :                              struct policy_handle *domain_handle_p)
     871             : {
     872           0 :         struct policy_handle domain_handle;
     873           0 :         struct dom_sid *domain_sid;
     874             : 
     875           5 :         if (!domain_name) {
     876           0 :                 struct samr_EnumDomains r;
     877           0 :                 uint32_t resume_handle;
     878           0 :                 struct samr_SamArray *sam;
     879           0 :                 uint32_t num_entries;
     880           0 :                 int i;
     881             : 
     882           0 :                 r.in.connect_handle = connect_handle;
     883           0 :                 r.in.buf_size = 0xffff;
     884           0 :                 r.in.resume_handle = &resume_handle;
     885           0 :                 r.out.sam = &sam;
     886           0 :                 r.out.num_entries = &num_entries;
     887           0 :                 r.out.resume_handle = &resume_handle;
     888             : 
     889           0 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
     890             :                         "failed to enum domains");
     891           0 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
     892             :                         "failed to enum domains");
     893             : 
     894           0 :                 torture_assert_int_equal(tctx, num_entries, 2,
     895             :                         "unexpected number of domains");
     896             : 
     897           0 :                 torture_assert(tctx, sam,
     898             :                         "no domain pointer returned");
     899             : 
     900           0 :                 for (i=0; i < sam->count; i++) {
     901           0 :                         if (!strequal(sam->entries[i].name.string, "builtin")) {
     902           0 :                                 domain_name = sam->entries[i].name.string;
     903           0 :                                 break;
     904             :                         }
     905             :                 }
     906             : 
     907           0 :                 torture_assert(tctx, domain_name,
     908             :                         "no domain found other than builtin found");
     909             :         }
     910             : 
     911             :         {
     912           0 :                 struct samr_LookupDomain r;
     913           0 :                 struct dom_sid2 *sid;
     914           0 :                 struct lsa_String name;
     915             : 
     916           5 :                 name.string = talloc_strdup(tctx, domain_name);
     917             : 
     918           5 :                 r.in.connect_handle = connect_handle;
     919           5 :                 r.in.domain_name = &name;
     920           5 :                 r.out.sid = &sid;
     921             : 
     922           5 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
     923             :                         "failed to lookup domain");
     924           5 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
     925             :                         "failed to lookup domain");
     926             : 
     927           5 :                 domain_sid = dom_sid_dup(tctx, sid);
     928             :         }
     929             : 
     930             :         {
     931           0 :                 struct samr_OpenDomain r;
     932             : 
     933           5 :                 r.in.connect_handle = connect_handle;
     934           5 :                 r.in.access_mask = access_mask;
     935           5 :                 r.in.sid = domain_sid;
     936           5 :                 r.out.domain_handle = &domain_handle;
     937             : 
     938           5 :                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenDomain_r(b, tctx, &r),
     939             :                         "failed to open domain");
     940           5 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
     941             :                         "failed to open domain");
     942             : 
     943             :         }
     944             : 
     945             :         {
     946           0 :                 struct samr_QueryDomainInfo r;
     947           0 :                 union samr_DomainInfo *info;
     948           5 :                 uint32_t levels[] = { 1, 2, 8, 12 };
     949           0 :                 int i;
     950             : 
     951           5 :                 r.in.domain_handle = &domain_handle;
     952           5 :                 r.out.info = &info;
     953             : 
     954          25 :                 for (i=0; i < ARRAY_SIZE(levels); i++) {
     955             : 
     956          20 :                         r.in.level = levels[i];
     957             : 
     958          20 :                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
     959             :                                 talloc_asprintf(tctx, "failed to query domain info level %d", r.in.level));
     960          20 :                         torture_assert_ntstatus_ok(tctx, r.out.result,
     961             :                                 talloc_asprintf(tctx, "failed to query domain info level %d", r.in.level));
     962             :                 }
     963             : 
     964             :         }
     965             : 
     966           5 :         *domain_handle_p = domain_handle;
     967             : 
     968           5 :         return true;
     969             : }
     970             : 
     971           5 : static void get_query_dispinfo_params(int loop_count,
     972             :                                       uint32_t *max_entries,
     973             :                                       uint32_t *buf_size)
     974             : {
     975           5 :         switch(loop_count) {
     976           5 :         case 0:
     977           5 :                 *max_entries = 512;
     978           5 :                 *buf_size = 16383;
     979           5 :                 break;
     980           0 :         case 1:
     981           0 :                 *max_entries = 1024;
     982           0 :                 *buf_size = 32766;
     983           0 :                 break;
     984           0 :         case 2:
     985           0 :                 *max_entries = 2048;
     986           0 :                 *buf_size = 65532;
     987           0 :                 break;
     988           0 :         case 3:
     989           0 :                 *max_entries = 4096;
     990           0 :                 *buf_size = 131064;
     991           0 :                 break;
     992           0 :         default:              /* loop_count >= 4 */
     993           0 :                 *max_entries = 4096;
     994           0 :                 *buf_size = 131071;
     995           0 :                 break;
     996             :         }
     997           5 : }
     998             : 
     999             : 
    1000           5 : static bool test_samr_users(struct torture_context *tctx,
    1001             :                             struct dcerpc_binding_handle *b,
    1002             :                             uint32_t access_mask,
    1003             :                             struct policy_handle *domain_handle)
    1004             : {
    1005             :         {
    1006           0 :                 struct samr_QueryDisplayInfo r;
    1007           0 :                 uint32_t total_size;
    1008           0 :                 uint32_t returned_size;
    1009           0 :                 union samr_DispInfo info;
    1010           5 :                 int loop_count = 0;
    1011             : 
    1012           5 :                 r.in.domain_handle = domain_handle;
    1013           5 :                 r.in.level = 1;
    1014           5 :                 r.in.start_idx = 0;
    1015             : 
    1016           5 :                 r.out.total_size = &total_size;
    1017           5 :                 r.out.returned_size = &returned_size;
    1018           5 :                 r.out.info = &info;
    1019             : 
    1020           0 :                 do {
    1021           0 :                         int i;
    1022             : 
    1023           5 :                         r.in.max_entries = 0xffff;
    1024           5 :                         r.in.buf_size = 0xffff;
    1025             : 
    1026           5 :                         get_query_dispinfo_params(loop_count,
    1027             :                                                   &r.in.max_entries,
    1028             :                                                   &r.in.buf_size);
    1029             : 
    1030           5 :                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
    1031             :                                 "QueryDisplayInfo failed");
    1032           5 :                         if (NT_STATUS_IS_ERR(r.out.result)) {
    1033           0 :                                 torture_assert_ntstatus_ok(tctx, r.out.result,
    1034             :                                         "failed to call QueryDisplayInfo");
    1035             :                         }
    1036             : 
    1037         360 :                         for (i=0; i < info.info1.count; i++) {
    1038         355 :                                 torture_assert(tctx,
    1039             :                                         test_user(tctx, b, domain_handle, access_mask, &info.info1.entries[i]),
    1040             :                                                 "failed to test user");
    1041             :                         }
    1042           5 :                         loop_count++;
    1043           5 :                         r.in.start_idx += info.info1.count;
    1044             : 
    1045           5 :                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
    1046             :         }
    1047             : 
    1048           5 :         return true;
    1049             : }
    1050             : 
    1051           5 : static bool test_samr_groups(struct torture_context *tctx,
    1052             :                              struct dcerpc_binding_handle *b,
    1053             :                              uint32_t access_mask,
    1054             :                              struct policy_handle *domain_handle)
    1055             : {
    1056             :         {
    1057           0 :                 struct samr_EnumDomainGroups r;
    1058           5 :                 uint32_t resume_handle = 0;
    1059           0 :                 struct samr_SamArray *sam;
    1060           0 :                 uint32_t num_entries;
    1061             : 
    1062           5 :                 r.in.domain_handle = domain_handle;
    1063           5 :                 r.in.resume_handle = &resume_handle;
    1064           5 :                 r.in.max_size = 0xFFFF;
    1065             : 
    1066           5 :                 r.out.sam = &sam;
    1067           5 :                 r.out.num_entries = &num_entries;
    1068           5 :                 r.out.resume_handle = &resume_handle;
    1069             : 
    1070           0 :                 do {
    1071           0 :                         int i;
    1072             : 
    1073           5 :                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
    1074             :                                 "EnumDomainGroups failed");
    1075           5 :                         if (NT_STATUS_IS_ERR(r.out.result)) {
    1076           0 :                                 torture_assert_ntstatus_ok(tctx, r.out.result,
    1077             :                                         "failed to call EnumDomainGroups");
    1078             :                         }
    1079             : 
    1080         348 :                         for (i=0; i < num_entries; i++) {
    1081         343 :                                 torture_assert(tctx,
    1082             :                                         test_samr_group(tctx, b, domain_handle, access_mask, &sam->entries[i]),
    1083             :                                                 "failed to test group");
    1084             :                         }
    1085             : 
    1086           5 :                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
    1087             :         }
    1088             : 
    1089           5 :         return true;
    1090             : }
    1091             : 
    1092           5 : static bool test_samr_aliases(struct torture_context *tctx,
    1093             :                               struct dcerpc_binding_handle *b,
    1094             :                               uint32_t access_mask,
    1095             :                               struct policy_handle *domain_handle)
    1096             : {
    1097             :         {
    1098           0 :                 struct samr_EnumDomainAliases r;
    1099           5 :                 uint32_t resume_handle = 0;
    1100           0 :                 struct samr_SamArray *sam;
    1101           0 :                 uint32_t num_entries;
    1102             : 
    1103           5 :                 r.in.domain_handle = domain_handle;
    1104           5 :                 r.in.resume_handle = &resume_handle;
    1105           5 :                 r.in.max_size = 0xFFFF;
    1106             : 
    1107           5 :                 r.out.sam = &sam;
    1108           5 :                 r.out.num_entries = &num_entries;
    1109           5 :                 r.out.resume_handle = &resume_handle;
    1110             : 
    1111           0 :                 do {
    1112           0 :                         int i;
    1113             : 
    1114           5 :                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
    1115             :                                 "EnumDomainAliases failed");
    1116           5 :                         if (NT_STATUS_IS_ERR(r.out.result)) {
    1117           0 :                                 torture_assert_ntstatus_ok(tctx, r.out.result,
    1118             :                                         "failed to call EnumDomainAliases");
    1119             :                         }
    1120             : 
    1121         320 :                         for (i=0; i < num_entries; i++) {
    1122         315 :                                 torture_assert(tctx,
    1123             :                                         test_samr_alias(tctx, b, domain_handle, &sam->entries[i]),
    1124             :                                                 "failed to test alias");
    1125             :                         }
    1126             : 
    1127           5 :                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
    1128             :         }
    1129             : 
    1130           5 :         return true;
    1131             : }
    1132             : 
    1133           5 : static bool torture_rpc_samr_workstation_query(struct torture_context *tctx,
    1134             :                                                struct dcerpc_pipe *p,
    1135             :                                                struct cli_credentials *machine_credentials)
    1136             : {
    1137           0 :         struct policy_handle connect_handle;
    1138           0 :         struct policy_handle domain_handle;
    1139           5 :         struct dcerpc_binding_handle *b = p->binding_handle;
    1140             : 
    1141           5 :         torture_assert_ntstatus_ok(tctx,
    1142             :                 torture_samr_Connect5(tctx, b, SEC_FLAG_MAXIMUM_ALLOWED,
    1143             :                                       &connect_handle),
    1144             :                 "failed to connect to samr server");
    1145             : 
    1146           5 :         torture_assert(tctx,
    1147             :                 test_samr_domain(tctx, b, SEC_FLAG_MAXIMUM_ALLOWED,
    1148             :                                  lpcfg_workgroup(tctx->lp_ctx),
    1149             :                                  &connect_handle, &domain_handle),
    1150             :                 "failed to test domain");
    1151             : 
    1152           5 :         torture_assert(tctx,
    1153             :                 test_samr_users(tctx, b, SEC_FLAG_MAXIMUM_ALLOWED,
    1154             :                                 &domain_handle),
    1155             :                 "failed to test users");
    1156             : 
    1157           5 :         torture_assert(tctx,
    1158             :                 test_samr_groups(tctx, b, SEC_FLAG_MAXIMUM_ALLOWED,
    1159             :                                  &domain_handle),
    1160             :                 "failed to test groups");
    1161             : 
    1162           5 :         torture_assert(tctx,
    1163             :                 test_samr_aliases(tctx, b, SEC_FLAG_MAXIMUM_ALLOWED,
    1164             :                                   &domain_handle),
    1165             :                 "failed to test aliases");
    1166             : 
    1167           5 :         torture_assert_ntstatus_ok(tctx,
    1168             :                 torture_samr_Close(tctx, b, &domain_handle),
    1169             :                 "failed to close domain handle");
    1170             : 
    1171           5 :         torture_assert_ntstatus_ok(tctx,
    1172             :                 torture_samr_Close(tctx, b, &connect_handle),
    1173             :                 "failed to close connect handle");
    1174             : 
    1175           5 :         return true;
    1176             : }
    1177             : 
    1178             : /* The purpose of this test is to verify that an account authenticated as a
    1179             :  * domain member workstation can query a DC for various remote read calls all
    1180             :  * opening objects while requesting SEC_FLAG_MAXIMUM_ALLOWED access rights on
    1181             :  * the object open calls. This is the behavior of winbind (and most of samba's
    1182             :  * client code) - gd */
    1183             : 
    1184        2354 : struct torture_suite *torture_rpc_samr_workstation_auth(TALLOC_CTX *mem_ctx)
    1185             : {
    1186        2354 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.machine.auth");
    1187         125 :         struct torture_rpc_tcase *tcase;
    1188             : 
    1189        2354 :         tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "samr",
    1190             :                                                                       &ndr_table_samr,
    1191             :                                                                       TEST_MACHINENAME);
    1192             : 
    1193        2354 :         torture_rpc_tcase_add_test_creds(tcase, "workstation_query",
    1194             :                                          torture_rpc_samr_workstation_query);
    1195             : 
    1196        2354 :         return suite;
    1197             : }

Generated by: LCOV version 1.14