LCOV - code coverage report
Current view: top level - source4/torture/rpc - netlogon.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 2620 2895 90.5 %
Date: 2024-02-28 12:06:22 Functions: 75 77 97.4 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    test suite for netlogon rpc operations
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2003
       7             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2004
       8             :    Copyright (C) Tim Potter      2003
       9             :    Copyright (C) Matthias Dieter Wallnöfer            2009-2010
      10             : 
      11             :    This program is free software; you can redistribute it and/or modify
      12             :    it under the terms of the GNU General Public License as published by
      13             :    the Free Software Foundation; either version 3 of the License, or
      14             :    (at your option) any later version.
      15             : 
      16             :    This program is distributed in the hope that it will be useful,
      17             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      18             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19             :    GNU General Public License for more details.
      20             : 
      21             :    You should have received a copy of the GNU General Public License
      22             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      23             : */
      24             : 
      25             : #include "includes.h"
      26             : #include "lib/events/events.h"
      27             : #include "lib/cmdline/cmdline.h"
      28             : #include "torture/rpc/torture_rpc.h"
      29             : #include "../lib/crypto/crypto.h"
      30             : #include "libcli/auth/libcli_auth.h"
      31             : #include "librpc/gen_ndr/ndr_netlogon_c.h"
      32             : #include "librpc/gen_ndr/ndr_lsa_c.h"
      33             : #include "param/param.h"
      34             : #include "libcli/security/security.h"
      35             : #include <ldb.h>
      36             : #include "lib/util/util_ldb.h"
      37             : #include "ldb_wrap.h"
      38             : #include "lib/replace/system/network.h"
      39             : #include "dsdb/samdb/samdb.h"
      40             : 
      41             : #undef strcasecmp
      42             : 
      43             : #define TEST_MACHINE_NAME "torturetest"
      44             : 
      45          18 : static bool test_netr_broken_binding_handle(struct torture_context *tctx,
      46             :                                             struct dcerpc_pipe *p)
      47             : {
      48           3 :         NTSTATUS status;
      49           3 :         struct netr_DsRGetSiteName r;
      50          18 :         const char *site = NULL;
      51          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
      52             : 
      53          18 :         r.in.computer_name      = talloc_asprintf(tctx, "\\\\%s",
      54             :                                                   dcerpc_server_name(p));
      55          18 :         r.out.site              = &site;
      56             : 
      57          18 :         torture_comment(tctx,
      58             :                         "Testing netlogon request with correct binding handle: %s\n",
      59             :                         r.in.computer_name);
      60             : 
      61          18 :         status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
      62          18 :         torture_assert_ntstatus_ok(tctx, status,
      63             :                                    "Netlogon request with broken binding handle");
      64          18 :         torture_assert_werr_ok(tctx, r.out.result,
      65             :                                "Netlogon request with broken binding handle");
      66             : 
      67          36 :         if (torture_setting_bool(tctx, "samba3", false) ||
      68          18 :             torture_setting_bool(tctx, "samba4", false)) {
      69          18 :                 torture_skip(tctx,
      70             :                              "Skipping broken binding handle check against Samba");
      71             :         }
      72             : 
      73           0 :         r.in.computer_name      = talloc_asprintf(tctx, "\\\\\\\\%s",
      74             :                                                   dcerpc_server_name(p));
      75             : 
      76           0 :         torture_comment(tctx,
      77             :                         "Testing netlogon request with broken binding handle: %s\n",
      78             :                         r.in.computer_name);
      79             : 
      80           0 :         status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
      81           0 :         torture_assert_ntstatus_ok(tctx, status,
      82             :                                    "Netlogon request with broken binding handle");
      83           0 :         torture_assert_werr_equal(tctx, r.out.result,
      84             :                                   WERR_INVALID_COMPUTERNAME,
      85             :                                   "Netlogon request with broken binding handle");
      86             : 
      87           0 :         r.in.computer_name      = "\\\\\\\\THIS_IS_NOT_VALID";
      88             : 
      89           0 :         torture_comment(tctx,
      90             :                         "Testing netlogon request with broken binding handle: %s\n",
      91             :                         r.in.computer_name);
      92             : 
      93           0 :         status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
      94           0 :         torture_assert_ntstatus_ok(tctx, status,
      95             :                                    "Netlogon request with broken binding handle");
      96           0 :         torture_assert_werr_equal(tctx, r.out.result,
      97             :                                   WERR_INVALID_COMPUTERNAME,
      98             :                                   "Netlogon request with broken binding handle");
      99             : 
     100           0 :         return true;
     101             : }
     102             : 
     103          18 : static bool test_LogonUasLogon(struct torture_context *tctx,
     104             :                                struct dcerpc_pipe *p)
     105             : {
     106           3 :         NTSTATUS status;
     107           3 :         struct netr_LogonUasLogon r;
     108          18 :         struct netr_UasInfo *info = NULL;
     109          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
     110             : 
     111          18 :         r.in.server_name = NULL;
     112          18 :         r.in.account_name = cli_credentials_get_username(
     113             :                                 samba_cmdline_get_creds());
     114          18 :         r.in.workstation = TEST_MACHINE_NAME;
     115          18 :         r.out.info = &info;
     116             : 
     117          18 :         status = dcerpc_netr_LogonUasLogon_r(b, tctx, &r);
     118          18 :         torture_assert_ntstatus_ok(tctx, status, "LogonUasLogon");
     119             : 
     120           0 :         return true;
     121             : }
     122             : 
     123          18 : static bool test_LogonUasLogoff(struct torture_context *tctx,
     124             :                                 struct dcerpc_pipe *p)
     125             : {
     126           3 :         NTSTATUS status;
     127           3 :         struct netr_LogonUasLogoff r;
     128           3 :         struct netr_UasLogoffInfo info;
     129          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
     130             : 
     131          18 :         r.in.server_name = NULL;
     132          18 :         r.in.account_name = cli_credentials_get_username(
     133             :                                 samba_cmdline_get_creds());
     134          18 :         r.in.workstation = TEST_MACHINE_NAME;
     135          18 :         r.out.info = &info;
     136             : 
     137          18 :         status = dcerpc_netr_LogonUasLogoff_r(b, tctx, &r);
     138          18 :         torture_assert_ntstatus_ok(tctx, status, "LogonUasLogoff");
     139             : 
     140           0 :         return true;
     141             : }
     142             : 
     143         276 : bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
     144             :                                   struct cli_credentials *credentials,
     145             :                                   struct netlogon_creds_CredentialState **creds_out)
     146             : {
     147          42 :         struct netr_ServerReqChallenge r;
     148          42 :         struct netr_ServerAuthenticate a;
     149          42 :         struct netr_Credential credentials1, credentials2, credentials3;
     150          42 :         struct netlogon_creds_CredentialState *creds;
     151          42 :         const struct samr_Password *mach_password;
     152          42 :         const char *machine_name;
     153         276 :         struct dcerpc_binding_handle *b = p->binding_handle;
     154             : 
     155         276 :         mach_password = cli_credentials_get_nt_hash(credentials, tctx);
     156         276 :         machine_name = cli_credentials_get_workstation(credentials);
     157             : 
     158         276 :         torture_comment(tctx, "Testing ServerReqChallenge\n");
     159             : 
     160         276 :         r.in.server_name = NULL;
     161         276 :         r.in.computer_name = machine_name;
     162         276 :         r.in.credentials = &credentials1;
     163         276 :         r.out.return_credentials = &credentials2;
     164             : 
     165         276 :         netlogon_creds_random_challenge(&credentials1);
     166             : 
     167         276 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
     168             :                 "ServerReqChallenge failed");
     169         276 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
     170             : 
     171         276 :         a.in.server_name = NULL;
     172         276 :         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
     173         276 :         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(credentials);
     174         276 :         a.in.computer_name = machine_name;
     175         276 :         a.in.credentials = &credentials3;
     176         276 :         a.out.return_credentials = &credentials3;
     177             : 
     178         276 :         creds = netlogon_creds_client_init(tctx, a.in.account_name,
     179             :                                            a.in.computer_name,
     180         234 :                                            a.in.secure_channel_type,
     181             :                                            &credentials1, &credentials2,
     182             :                                            mach_password, &credentials3,
     183             :                                            0);
     184         276 :         torture_assert(tctx, creds != NULL, "memory allocation");
     185             : 
     186             : 
     187         276 :         torture_comment(tctx, "Testing ServerAuthenticate\n");
     188             : 
     189         276 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate_r(b, tctx, &a),
     190             :                 "ServerAuthenticate failed");
     191             : 
     192             :         /* This allows the tests to continue against the more fussy windows 2008 */
     193         276 :         if (NT_STATUS_EQUAL(a.out.result, NT_STATUS_DOWNGRADE_DETECTED)) {
     194         150 :                 return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
     195             :                                               credentials,
     196             :                                               cli_credentials_get_secure_channel_type(credentials),
     197             :                                               creds_out);
     198             :         }
     199             : 
     200         126 :         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate");
     201             : 
     202         126 :         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
     203             :                        "Credential chaining failed");
     204             : 
     205         126 :         *creds_out = creds;
     206         126 :         return true;
     207             : }
     208             : 
     209         370 : bool test_SetupCredentials2ex(struct dcerpc_pipe *p, struct torture_context *tctx,
     210             :                               uint32_t negotiate_flags,
     211             :                               struct cli_credentials *machine_credentials,
     212             :                               const char *computer_name,
     213             :                               enum netr_SchannelType sec_chan_type,
     214             :                               NTSTATUS expected_result,
     215             :                               struct netlogon_creds_CredentialState **creds_out)
     216             : {
     217          63 :         struct netr_ServerReqChallenge r;
     218          63 :         struct netr_ServerAuthenticate2 a;
     219          63 :         struct netr_Credential credentials1, credentials2, credentials3;
     220          63 :         struct netlogon_creds_CredentialState *creds;
     221          63 :         const struct samr_Password *mach_password;
     222         370 :         struct dcerpc_binding_handle *b = p->binding_handle;
     223         370 :         const char *account_name = cli_credentials_get_username(machine_credentials);
     224             : 
     225         370 :         mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
     226             : 
     227         370 :         torture_comment(tctx, "Testing ServerReqChallenge\n");
     228             : 
     229         370 :         r.in.server_name = NULL;
     230         370 :         r.in.computer_name = computer_name;
     231         370 :         r.in.credentials = &credentials1;
     232         370 :         r.out.return_credentials = &credentials2;
     233             : 
     234         370 :         netlogon_creds_random_challenge(&credentials1);
     235             : 
     236         370 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
     237             :                 "ServerReqChallenge failed");
     238         370 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
     239             : 
     240         370 :         a.in.server_name = NULL;
     241         370 :         a.in.account_name = account_name;
     242         370 :         a.in.secure_channel_type = sec_chan_type;
     243         370 :         a.in.computer_name = computer_name;
     244         370 :         a.in.negotiate_flags = &negotiate_flags;
     245         370 :         a.out.negotiate_flags = &negotiate_flags;
     246         370 :         a.in.credentials = &credentials3;
     247         370 :         a.out.return_credentials = &credentials3;
     248             : 
     249         370 :         creds = netlogon_creds_client_init(tctx, a.in.account_name,
     250             :                                            a.in.computer_name,
     251         307 :                                            a.in.secure_channel_type,
     252             :                                            &credentials1, &credentials2,
     253             :                                            mach_password, &credentials3,
     254             :                                            negotiate_flags);
     255             : 
     256         370 :         torture_assert(tctx, creds != NULL, "memory allocation");
     257             : 
     258         370 :         torture_comment(tctx, "Testing ServerAuthenticate2\n");
     259             : 
     260         370 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
     261             :                 "ServerAuthenticate2 failed");
     262         370 :         torture_assert_ntstatus_equal(tctx, a.out.result, expected_result,
     263             :                                       "ServerAuthenticate2 unexpected");
     264             : 
     265         358 :         if (NT_STATUS_IS_OK(expected_result)) {
     266         340 :                 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
     267             :                                "Credential chaining failed");
     268             :         } else {
     269          18 :                 torture_assert(tctx, !netlogon_creds_client_check(creds, &credentials3),
     270             :                                "Credential chaining passed unexpected");
     271             :         }
     272             : 
     273         358 :         torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
     274             : 
     275         358 :         *creds_out = creds;
     276         358 :         return true;
     277             : }
     278             : 
     279         334 : bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx,
     280             :                             uint32_t negotiate_flags,
     281             :                             struct cli_credentials *machine_credentials,
     282             :                             enum netr_SchannelType sec_chan_type,
     283             :                             struct netlogon_creds_CredentialState **creds_out)
     284             : {
     285          57 :         const char *computer_name =
     286         334 :                 cli_credentials_get_workstation(machine_credentials);
     287             : 
     288         668 :         return test_SetupCredentials2ex(p, tctx, negotiate_flags,
     289             :                                         machine_credentials,
     290             :                                         computer_name,
     291             :                                         sec_chan_type,
     292         334 :                                         NT_STATUS_OK,
     293             :                                         creds_out);
     294             : }
     295             : 
     296          75 : bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx,
     297             :                             uint32_t negotiate_flags,
     298             :                             struct cli_credentials *machine_credentials,
     299             :                             struct netlogon_creds_CredentialState **creds_out)
     300             : {
     301          12 :         struct netr_ServerReqChallenge r;
     302          12 :         struct netr_ServerAuthenticate3 a;
     303          12 :         struct netr_Credential credentials1, credentials2, credentials3;
     304          12 :         struct netlogon_creds_CredentialState *creds;
     305          12 :         struct samr_Password mach_password;
     306          12 :         uint32_t rid;
     307          12 :         const char *machine_name;
     308          12 :         const char *plain_pass;
     309          75 :         struct dcerpc_binding_handle *b = NULL;
     310             : 
     311          75 :         if (p == NULL) {
     312           0 :                 return false;
     313             :         }
     314             : 
     315          75 :         b = p->binding_handle;
     316             : 
     317          75 :         machine_name = cli_credentials_get_workstation(machine_credentials);
     318          75 :         torture_assert(tctx, machine_name != NULL, "machine_name");
     319          75 :         plain_pass = cli_credentials_get_password(machine_credentials);
     320          75 :         torture_assert(tctx, plain_pass != NULL, "plain_pass");
     321             : 
     322          75 :         torture_comment(tctx, "Testing ServerReqChallenge\n");
     323             : 
     324          75 :         r.in.server_name = NULL;
     325          75 :         r.in.computer_name = machine_name;
     326          75 :         r.in.credentials = &credentials1;
     327          75 :         r.out.return_credentials = &credentials2;
     328             : 
     329          75 :         netlogon_creds_random_challenge(&credentials1);
     330             : 
     331          75 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
     332             :                 "ServerReqChallenge failed");
     333          75 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
     334             : 
     335          75 :         E_md4hash(plain_pass, mach_password.hash);
     336             : 
     337          75 :         a.in.server_name = NULL;
     338          75 :         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
     339          75 :         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
     340          75 :         a.in.computer_name = machine_name;
     341          75 :         a.in.negotiate_flags = &negotiate_flags;
     342          75 :         a.in.credentials = &credentials3;
     343          75 :         a.out.return_credentials = &credentials3;
     344          75 :         a.out.negotiate_flags = &negotiate_flags;
     345          75 :         a.out.rid = &rid;
     346             : 
     347          75 :         creds = netlogon_creds_client_init(tctx, a.in.account_name,
     348             :                                            a.in.computer_name,
     349          63 :                                            a.in.secure_channel_type,
     350             :                                            &credentials1, &credentials2,
     351             :                                            &mach_password, &credentials3,
     352             :                                            negotiate_flags);
     353             : 
     354          75 :         torture_assert(tctx, creds != NULL, "memory allocation");
     355             : 
     356          75 :         torture_comment(tctx, "Testing ServerAuthenticate3\n");
     357             : 
     358          75 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
     359             :                 "ServerAuthenticate3 failed");
     360          75 :         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed");
     361          75 :         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
     362             : 
     363          75 :         torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
     364             : 
     365             :         /* Prove that requesting a challenge again won't break it */
     366          75 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
     367             :                 "ServerReqChallenge failed");
     368          75 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
     369             : 
     370          75 :         *creds_out = creds;
     371          75 :         return true;
     372             : }
     373             : 
     374          18 : bool test_SetupCredentialsDowngrade(struct torture_context *tctx,
     375             :                                         struct dcerpc_pipe *p,
     376             :                                         struct cli_credentials *machine_credentials)
     377             : {
     378           3 :         struct netr_ServerReqChallenge r;
     379           3 :         struct netr_ServerAuthenticate3 a;
     380           3 :         struct netr_Credential credentials1, credentials2, credentials3;
     381           3 :         struct netlogon_creds_CredentialState *creds;
     382           3 :         struct samr_Password mach_password;
     383           3 :         uint32_t rid;
     384           3 :         const char *machine_name;
     385           3 :         const char *plain_pass;
     386          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
     387          18 :         uint32_t negotiate_flags = 0;
     388             : 
     389          18 :         machine_name = cli_credentials_get_workstation(machine_credentials);
     390          18 :         torture_assert(tctx, machine_name != NULL, "machine_name");
     391          18 :         plain_pass = cli_credentials_get_password(machine_credentials);
     392          18 :         torture_assert(tctx, plain_pass != NULL, "plain_pass");
     393             : 
     394          18 :         torture_comment(tctx, "Testing ServerReqChallenge\n");
     395             : 
     396          18 :         r.in.server_name = NULL;
     397          18 :         r.in.computer_name = machine_name;
     398          18 :         r.in.credentials = &credentials1;
     399          18 :         r.out.return_credentials = &credentials2;
     400             : 
     401          18 :         netlogon_creds_random_challenge(&credentials1);
     402             : 
     403          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
     404             :                 "ServerReqChallenge failed");
     405          18 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
     406             : 
     407          18 :         E_md4hash(plain_pass, mach_password.hash);
     408             : 
     409          18 :         a.in.server_name = NULL;
     410          18 :         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
     411          18 :         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
     412          18 :         a.in.computer_name = machine_name;
     413          18 :         a.in.negotiate_flags = &negotiate_flags;
     414          18 :         a.in.credentials = &credentials3;
     415          18 :         a.out.return_credentials = &credentials3;
     416          18 :         a.out.negotiate_flags = &negotiate_flags;
     417          18 :         a.out.rid = &rid;
     418             : 
     419          18 :         creds = netlogon_creds_client_init(tctx, a.in.account_name,
     420             :                                            a.in.computer_name,
     421          15 :                                            a.in.secure_channel_type,
     422             :                                            &credentials1, &credentials2,
     423             :                                            &mach_password, &credentials3,
     424             :                                            negotiate_flags);
     425             : 
     426          18 :         torture_assert(tctx, creds != NULL, "memory allocation");
     427             : 
     428          18 :         torture_comment(tctx, "Testing ServerAuthenticate3\n");
     429             : 
     430          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
     431             :                 "ServerAuthenticate3 failed");
     432          18 :         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_DOWNGRADE_DETECTED, "ServerAuthenticate3 should have failed");
     433             : 
     434           9 :         negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
     435          12 :         creds = netlogon_creds_client_init(tctx, a.in.account_name,
     436             :                                            a.in.computer_name,
     437           9 :                                            a.in.secure_channel_type,
     438             :                                            &credentials1, &credentials2,
     439             :                                            &mach_password, &credentials3,
     440             :                                            negotiate_flags);
     441             : 
     442           9 :         torture_assert(tctx, creds != NULL, "memory allocation");
     443             : 
     444           9 :         torture_comment(tctx, "Testing ServerAuthenticate3\n");
     445             : 
     446           9 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
     447             :                 "ServerAuthenticate3 failed");
     448           9 :         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 should succeed");
     449             : 
     450           9 :         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
     451             : 
     452           9 :         torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
     453             : 
     454             :         /* Prove that requesting a challenge again won't break it */
     455           9 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
     456             :                 "ServerReqChallenge failed");
     457           9 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
     458             : 
     459           6 :         return true;
     460             : }
     461             : 
     462         307 : bool test_SetupCredentialsPipe(const struct dcerpc_pipe *p1,
     463             :                                struct torture_context *tctx,
     464             :                                struct cli_credentials *machine_credentials,
     465             :                                struct netlogon_creds_CredentialState *creds,
     466             :                                uint32_t additional_flags,
     467             :                                struct dcerpc_pipe **_p2)
     468             : {
     469          24 :         NTSTATUS status;
     470         307 :         struct dcerpc_binding *b2 = NULL;
     471         307 :         struct dcerpc_pipe *p2 = NULL;
     472             : 
     473         307 :         b2 = dcerpc_binding_dup(tctx, p1->binding);
     474         307 :         torture_assert(tctx, b2 != NULL, "dcerpc_binding_dup");
     475         307 :         dcerpc_binding_set_flags(b2,
     476             :                                  DCERPC_SCHANNEL | additional_flags,
     477             :                                  DCERPC_AUTH_OPTIONS);
     478             : 
     479         307 :         cli_credentials_set_netlogon_creds(machine_credentials, creds);
     480         307 :         status = dcerpc_pipe_connect_b(tctx, &p2, b2,
     481             :                                        &ndr_table_netlogon,
     482             :                                        machine_credentials,
     483             :                                        tctx->ev, tctx->lp_ctx);
     484         307 :         cli_credentials_set_netlogon_creds(machine_credentials, NULL);
     485         307 :         torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b schannel");
     486             : 
     487         307 :         *_p2 = p2;
     488         307 :         return true;
     489             : }
     490             : 
     491          11 : static bool test_ServerReqChallenge(
     492             :         struct torture_context *tctx,
     493             :         struct dcerpc_pipe *p,
     494             :         struct cli_credentials *credentials)
     495             : {
     496           1 :         struct netr_ServerReqChallenge r;
     497           1 :         struct netr_Credential credentials1, credentials2, credentials3;
     498           1 :         const char *machine_name;
     499          11 :         struct dcerpc_binding_handle *b = p->binding_handle;
     500           1 :         struct netr_ServerAuthenticate2 a;
     501          11 :         uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
     502          11 :         uint32_t out_negotiate_flags = 0;
     503          11 :         const struct samr_Password *mach_password = NULL;
     504          11 :         enum netr_SchannelType sec_chan_type = 0;
     505          11 :         struct netlogon_creds_CredentialState *creds = NULL;
     506          11 :         const char *account_name = NULL;
     507             : 
     508          11 :         machine_name = cli_credentials_get_workstation(credentials);
     509          11 :         mach_password = cli_credentials_get_nt_hash(credentials, tctx);
     510          11 :         account_name = cli_credentials_get_username(credentials);
     511          11 :         sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
     512             : 
     513          11 :         torture_comment(tctx, "Testing ServerReqChallenge\n");
     514             : 
     515          11 :         r.in.server_name = NULL;
     516          11 :         r.in.computer_name = machine_name;
     517          11 :         r.in.credentials = &credentials1;
     518          11 :         r.out.return_credentials = &credentials2;
     519             : 
     520          11 :         netlogon_creds_random_challenge(&credentials1);
     521             : 
     522          11 :         torture_assert_ntstatus_ok(
     523             :                 tctx,
     524             :                 dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
     525             :                 "ServerReqChallenge failed");
     526          11 :         torture_assert_ntstatus_ok(
     527             :                 tctx,
     528             :                 r.out.result,
     529             :                 "ServerReqChallenge failed");
     530          11 :         a.in.server_name = NULL;
     531          11 :         a.in.account_name = account_name;
     532          11 :         a.in.secure_channel_type = sec_chan_type;
     533          11 :         a.in.computer_name = machine_name;
     534          11 :         a.in.negotiate_flags = &in_negotiate_flags;
     535          11 :         a.out.negotiate_flags = &out_negotiate_flags;
     536          11 :         a.in.credentials = &credentials3;
     537          11 :         a.out.return_credentials = &credentials3;
     538             : 
     539          11 :         creds = netlogon_creds_client_init(tctx, a.in.account_name,
     540             :                                            a.in.computer_name,
     541          10 :                                            a.in.secure_channel_type,
     542             :                                            &credentials1, &credentials2,
     543             :                                            mach_password, &credentials3,
     544             :                                            in_negotiate_flags);
     545             : 
     546          11 :         torture_assert(tctx, creds != NULL, "memory allocation");
     547             : 
     548          11 :         torture_comment(tctx, "Testing ServerAuthenticate2\n");
     549             : 
     550          11 :         torture_assert_ntstatus_ok(
     551             :                 tctx,
     552             :                 dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
     553             :                 "ServerAuthenticate2 failed");
     554          11 :         torture_assert_ntstatus_equal(
     555             :                 tctx,
     556             :                 a.out.result,
     557             :                 NT_STATUS_OK,
     558             :                 "ServerAuthenticate2 unexpected");
     559             : 
     560          10 :         return true;
     561             : }
     562             : 
     563          11 : static bool test_ServerReqChallenge_zero_challenge(
     564             :         struct torture_context *tctx,
     565             :         struct dcerpc_pipe *p,
     566             :         struct cli_credentials *credentials)
     567             : {
     568           1 :         struct netr_ServerReqChallenge r;
     569           1 :         struct netr_Credential credentials1, credentials2, credentials3;
     570           1 :         const char *machine_name;
     571          11 :         struct dcerpc_binding_handle *b = p->binding_handle;
     572           1 :         struct netr_ServerAuthenticate2 a;
     573          11 :         uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
     574          11 :         uint32_t out_negotiate_flags = 0;
     575          11 :         const struct samr_Password *mach_password = NULL;
     576          11 :         enum netr_SchannelType sec_chan_type = 0;
     577          11 :         struct netlogon_creds_CredentialState *creds = NULL;
     578          11 :         const char *account_name = NULL;
     579             : 
     580          11 :         machine_name = cli_credentials_get_workstation(credentials);
     581          11 :         mach_password = cli_credentials_get_nt_hash(credentials, tctx);
     582          11 :         account_name = cli_credentials_get_username(credentials);
     583          11 :         sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
     584             : 
     585          11 :         torture_comment(tctx, "Testing ServerReqChallenge\n");
     586             : 
     587          11 :         r.in.server_name = NULL;
     588          11 :         r.in.computer_name = machine_name;
     589          11 :         r.in.credentials = &credentials1;
     590          11 :         r.out.return_credentials = &credentials2;
     591             : 
     592             :         /*
     593             :          * Set the client challenge to zero, this should fail
     594             :          * CVE-2020-1472(ZeroLogon)
     595             :          * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
     596             :          */
     597          11 :         ZERO_STRUCT(credentials1);
     598             : 
     599          11 :         torture_assert_ntstatus_ok(
     600             :                 tctx,
     601             :                 dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
     602             :                 "ServerReqChallenge failed");
     603          11 :         torture_assert_ntstatus_ok(
     604             :                 tctx,
     605             :                 r.out.result,
     606             :                 "ServerReqChallenge failed");
     607          11 :         a.in.server_name = NULL;
     608          11 :         a.in.account_name = account_name;
     609          11 :         a.in.secure_channel_type = sec_chan_type;
     610          11 :         a.in.computer_name = machine_name;
     611          11 :         a.in.negotiate_flags = &in_negotiate_flags;
     612          11 :         a.out.negotiate_flags = &out_negotiate_flags;
     613          11 :         a.in.credentials = &credentials3;
     614          11 :         a.out.return_credentials = &credentials3;
     615             : 
     616          11 :         creds = netlogon_creds_client_init(tctx, a.in.account_name,
     617             :                                            a.in.computer_name,
     618          10 :                                            a.in.secure_channel_type,
     619             :                                            &credentials1, &credentials2,
     620             :                                            mach_password, &credentials3,
     621             :                                            in_negotiate_flags);
     622             : 
     623          11 :         torture_assert(tctx, creds != NULL, "memory allocation");
     624             : 
     625          11 :         torture_comment(tctx, "Testing ServerAuthenticate2\n");
     626             : 
     627          11 :         torture_assert_ntstatus_ok(
     628             :                 tctx,
     629             :                 dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
     630             :                 "ServerAuthenticate2 failed");
     631          11 :         torture_assert_ntstatus_equal(
     632             :                 tctx,
     633             :                 a.out.result,
     634             :                 NT_STATUS_ACCESS_DENIED,
     635             :                 "ServerAuthenticate2 unexpected");
     636             : 
     637          10 :         return true;
     638             : }
     639             : 
     640          11 : static bool test_ServerReqChallenge_5_repeats(
     641             :         struct torture_context *tctx,
     642             :         struct dcerpc_pipe *p,
     643             :         struct cli_credentials *credentials)
     644             : {
     645           1 :         struct netr_ServerReqChallenge r;
     646           1 :         struct netr_Credential credentials1, credentials2, credentials3;
     647           1 :         const char *machine_name;
     648          11 :         struct dcerpc_binding_handle *b = p->binding_handle;
     649           1 :         struct netr_ServerAuthenticate2 a;
     650          11 :         uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
     651          11 :         uint32_t out_negotiate_flags = 0;
     652          11 :         const struct samr_Password *mach_password = NULL;
     653          11 :         enum netr_SchannelType sec_chan_type = 0;
     654          11 :         struct netlogon_creds_CredentialState *creds = NULL;
     655          11 :         const char *account_name = NULL;
     656             : 
     657          11 :         machine_name = cli_credentials_get_workstation(credentials);
     658          11 :         mach_password = cli_credentials_get_nt_hash(credentials, tctx);
     659          11 :         account_name = cli_credentials_get_username(credentials);
     660          11 :         sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
     661             : 
     662          11 :         torture_comment(tctx, "Testing ServerReqChallenge\n");
     663             : 
     664          11 :         r.in.server_name = NULL;
     665          11 :         r.in.computer_name = machine_name;
     666          11 :         r.in.credentials = &credentials1;
     667          11 :         r.out.return_credentials = &credentials2;
     668             : 
     669             :         /*
     670             :          * Set the first 5 bytes of the client challenge to the same value,
     671             :          * this should fail CVE-2020-1472(ZeroLogon)
     672             :          * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
     673             :          */
     674          11 :         credentials1.data[0] = 'A';
     675          11 :         credentials1.data[1] = 'A';
     676          11 :         credentials1.data[2] = 'A';
     677          11 :         credentials1.data[3] = 'A';
     678          11 :         credentials1.data[4] = 'A';
     679          11 :         credentials1.data[5] = 'B';
     680          11 :         credentials1.data[6] = 'C';
     681          11 :         credentials1.data[7] = 'D';
     682             : 
     683          11 :         torture_assert_ntstatus_ok(
     684             :                 tctx,
     685             :                 dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
     686             :                 "ServerReqChallenge failed");
     687          11 :         torture_assert_ntstatus_ok(
     688             :                 tctx,
     689             :                 r.out.result,
     690             :                 "ServerReqChallenge failed");
     691          11 :         a.in.server_name = NULL;
     692          11 :         a.in.account_name = account_name;
     693          11 :         a.in.secure_channel_type = sec_chan_type;
     694          11 :         a.in.computer_name = machine_name;
     695          11 :         a.in.negotiate_flags = &in_negotiate_flags;
     696          11 :         a.out.negotiate_flags = &out_negotiate_flags;
     697          11 :         a.in.credentials = &credentials3;
     698          11 :         a.out.return_credentials = &credentials3;
     699             : 
     700          11 :         creds = netlogon_creds_client_init(tctx, a.in.account_name,
     701             :                                            a.in.computer_name,
     702          10 :                                            a.in.secure_channel_type,
     703             :                                            &credentials1, &credentials2,
     704             :                                            mach_password, &credentials3,
     705             :                                            in_negotiate_flags);
     706             : 
     707          11 :         torture_assert(tctx, creds != NULL, "memory allocation");
     708             : 
     709          11 :         torture_comment(tctx, "Testing ServerAuthenticate2\n");
     710             : 
     711          11 :         torture_assert_ntstatus_ok(
     712             :                 tctx,
     713             :                 dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
     714             :                 "ServerAuthenticate2 failed");
     715          11 :         torture_assert_ntstatus_equal(
     716             :                 tctx,
     717             :                 a.out.result,
     718             :                 NT_STATUS_ACCESS_DENIED,
     719             :                 "ServerAuthenticate2 unexpected");
     720             : 
     721          10 :         return true;
     722             : }
     723             : 
     724          11 : static bool test_ServerReqChallenge_4_repeats(
     725             :         struct torture_context *tctx,
     726             :         struct dcerpc_pipe *p,
     727             :         struct cli_credentials *credentials)
     728             : {
     729           1 :         struct netr_ServerReqChallenge r;
     730           1 :         struct netr_Credential credentials1, credentials2, credentials3;
     731           1 :         const char *machine_name;
     732          11 :         struct dcerpc_binding_handle *b = p->binding_handle;
     733           1 :         struct netr_ServerAuthenticate2 a;
     734          11 :         uint32_t in_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
     735          11 :         uint32_t out_negotiate_flags = 0;
     736          11 :         const struct samr_Password *mach_password = NULL;
     737          11 :         enum netr_SchannelType sec_chan_type = 0;
     738          11 :         struct netlogon_creds_CredentialState *creds = NULL;
     739          11 :         const char *account_name = NULL;
     740             : 
     741          11 :         machine_name = cli_credentials_get_workstation(credentials);
     742          11 :         mach_password = cli_credentials_get_nt_hash(credentials, tctx);
     743          11 :         account_name = cli_credentials_get_username(credentials);
     744          11 :         sec_chan_type = cli_credentials_get_secure_channel_type(credentials);
     745             : 
     746          11 :         torture_comment(tctx, "Testing ServerReqChallenge\n");
     747             : 
     748          11 :         r.in.server_name = NULL;
     749          11 :         r.in.computer_name = machine_name;
     750          11 :         r.in.credentials = &credentials1;
     751          11 :         r.out.return_credentials = &credentials2;
     752             : 
     753             :         /*
     754             :          * Set the first 4 bytes of the client challenge to the same
     755             :          * value, this should pass as 5 bytes identical are needed to
     756             :          * fail for CVE-2020-1472(ZeroLogon)
     757             :          *
     758             :          * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14497
     759             :          */
     760          11 :         credentials1.data[0] = 'A';
     761          11 :         credentials1.data[1] = 'A';
     762          11 :         credentials1.data[2] = 'A';
     763          11 :         credentials1.data[3] = 'A';
     764          11 :         credentials1.data[4] = 'B';
     765          11 :         credentials1.data[5] = 'C';
     766          11 :         credentials1.data[6] = 'D';
     767          11 :         credentials1.data[7] = 'E';
     768             : 
     769          11 :         torture_assert_ntstatus_ok(
     770             :                 tctx,
     771             :                 dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
     772             :                 "ServerReqChallenge failed");
     773          11 :         torture_assert_ntstatus_ok(
     774             :                 tctx,
     775             :                 r.out.result,
     776             :                 "ServerReqChallenge failed");
     777          11 :         a.in.server_name = NULL;
     778          11 :         a.in.account_name = account_name;
     779          11 :         a.in.secure_channel_type = sec_chan_type;
     780          11 :         a.in.computer_name = machine_name;
     781          11 :         a.in.negotiate_flags = &in_negotiate_flags;
     782          11 :         a.out.negotiate_flags = &out_negotiate_flags;
     783          11 :         a.in.credentials = &credentials3;
     784          11 :         a.out.return_credentials = &credentials3;
     785             : 
     786          11 :         creds = netlogon_creds_client_init(tctx, a.in.account_name,
     787             :                                            a.in.computer_name,
     788          10 :                                            a.in.secure_channel_type,
     789             :                                            &credentials1, &credentials2,
     790             :                                            mach_password, &credentials3,
     791             :                                            in_negotiate_flags);
     792             : 
     793          11 :         torture_assert(tctx, creds != NULL, "memory allocation");
     794             : 
     795          11 :         torture_comment(tctx, "Testing ServerAuthenticate2\n");
     796             : 
     797          11 :         torture_assert_ntstatus_ok(
     798             :                 tctx,
     799             :                 dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
     800             :                 "ServerAuthenticate2 failed");
     801          11 :         torture_assert_ntstatus_equal(
     802             :                 tctx,
     803             :                 a.out.result,
     804             :                 NT_STATUS_OK,
     805             :                 "ServerAuthenticate2 unexpected");
     806             : 
     807          10 :         return true;
     808             : }
     809             : 
     810             : /*
     811             :  * Establish a NetLogon session, using a session key that encrypts the
     812             :  * target character to zero
     813             :  */
     814          33 : static bool test_ServerAuthenticate2_encrypts_to_zero(
     815             :         struct torture_context *tctx,
     816             :         struct dcerpc_pipe *p,
     817             :         struct cli_credentials *machine_credentials,
     818             :         const char target,
     819             :         struct netlogon_creds_CredentialState **creds_out)
     820             : {
     821           3 :         const char *computer_name =
     822          33 :                 cli_credentials_get_workstation(machine_credentials);
     823           3 :         struct netr_ServerReqChallenge r;
     824           3 :         struct netr_ServerAuthenticate2 a;
     825           3 :         struct netr_Credential credentials1, credentials2, credentials3;
     826          33 :         struct netlogon_creds_CredentialState *creds  = NULL;
     827           3 :         const struct samr_Password *mach_password;
     828          33 :         struct dcerpc_binding_handle *b = p->binding_handle;
     829          33 :         const char *account_name = cli_credentials_get_username(
     830             :                 machine_credentials);
     831          33 :         uint32_t flags =
     832             :                 NETLOGON_NEG_AUTH2_ADS_FLAGS |
     833             :                 NETLOGON_NEG_SUPPORTS_AES;
     834           3 :         enum netr_SchannelType sec_chan_type =
     835          33 :                 cli_credentials_get_secure_channel_type(machine_credentials);
     836             :         /*
     837             :          * Limit the number of attempts to generate a suitable session key.
     838             :          */
     839          33 :         const unsigned MAX_ITER = 4096;
     840          33 :         unsigned i = 0;
     841             : 
     842          33 :         mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
     843             : 
     844          33 :         r.in.server_name = NULL;
     845          33 :         r.in.computer_name = computer_name;
     846          33 :         r.in.credentials = &credentials1;
     847          33 :         r.out.return_credentials = &credentials2;
     848             : 
     849          33 :         netlogon_creds_random_challenge(&credentials1);
     850          33 :         credentials1.data[0] = target;
     851          33 :         i = 0;
     852          33 :         torture_comment(tctx, "Generating candidate session keys\n");
     853         782 :         do {
     854        9821 :                 TALLOC_FREE(creds);
     855        9821 :                 i++;
     856             : 
     857        9821 :                 torture_assert_ntstatus_ok(
     858             :                         tctx,
     859             :                         dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
     860             :                         "ServerReqChallenge failed");
     861        9821 :                 torture_assert_ntstatus_ok(
     862             :                         tctx,
     863             :                         r.out.result,
     864             :                         "ServerReqChallenge failed");
     865             : 
     866        9821 :                 a.in.server_name = NULL;
     867        9821 :                 a.in.account_name = account_name;
     868        9821 :                 a.in.secure_channel_type = sec_chan_type;
     869        9821 :                 a.in.computer_name = computer_name;
     870        9821 :                 a.in.negotiate_flags = &flags;
     871        9821 :                 a.out.negotiate_flags = &flags;
     872        9821 :                 a.in.credentials = &credentials3;
     873        9821 :                 a.out.return_credentials = &credentials3;
     874             : 
     875        9821 :                 creds = netlogon_creds_client_init(
     876             :                         tctx,
     877             :                         a.in.account_name,
     878             :                         a.in.computer_name,
     879        9039 :                         a.in.secure_channel_type,
     880             :                         &credentials1,
     881             :                         &credentials2,
     882             :                         mach_password,
     883             :                         &credentials3,
     884             :                         flags);
     885             : 
     886        9821 :                 torture_assert(tctx, creds != NULL, "memory allocation");
     887        9821 :         } while (credentials3.data[0] != 0 && i < MAX_ITER);
     888             : 
     889          33 :         if (i >= MAX_ITER) {
     890           0 :                 torture_comment(
     891             :                         tctx,
     892             :                         "Unable to obtain a suitable session key, "
     893             :                         "after [%u] attempts\n",
     894             :                         i);
     895           0 :                 torture_fail(tctx, "Unable to obtain suitable session key");
     896             :         }
     897             : 
     898          33 :         torture_assert_ntstatus_ok(
     899             :                 tctx,
     900             :                 dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
     901             :                 "ServerAuthenticate2 failed");
     902          33 :         torture_assert_ntstatus_equal(
     903             :                 tctx,
     904             :                 a.out.result,
     905             :                 NT_STATUS_OK,
     906             :                 "ServerAuthenticate2 unexpected result code");
     907             : 
     908          33 :         *creds_out = creds;
     909          33 :         return true;
     910             : }
     911             : 
     912             : /*
     913             :   try a change password for our machine account
     914             : */
     915          21 : static bool test_SetPassword(struct torture_context *tctx,
     916             :                              struct dcerpc_pipe *p,
     917             :                              struct cli_credentials *machine_credentials)
     918             : {
     919           3 :         struct netr_ServerPasswordSet r;
     920           3 :         const char *password;
     921           3 :         struct netlogon_creds_CredentialState *creds;
     922           3 :         struct netr_Authenticator credential, return_authenticator;
     923           3 :         struct samr_Password new_password;
     924          21 :         struct dcerpc_binding_handle *b = p->binding_handle;
     925             : 
     926          21 :         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
     927           0 :                 return false;
     928             :         }
     929             : 
     930          21 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
     931          21 :         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
     932          21 :         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
     933          21 :         r.in.computer_name = TEST_MACHINE_NAME;
     934          21 :         r.in.credential = &credential;
     935          21 :         r.in.new_password = &new_password;
     936          21 :         r.out.return_authenticator = &return_authenticator;
     937             : 
     938          21 :         password = generate_random_password(tctx, 8, 255);
     939          21 :         E_md4hash(password, new_password.hash);
     940             : 
     941          21 :         netlogon_creds_des_encrypt(creds, &new_password);
     942             : 
     943          21 :         torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
     944          21 :         torture_comment(tctx, "Changing machine account password to '%s'\n",
     945             :                         password);
     946             : 
     947          21 :         netlogon_creds_client_authenticator(creds, &credential);
     948             : 
     949          21 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
     950             :                 "ServerPasswordSet failed");
     951          21 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
     952             : 
     953          21 :         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
     954           0 :                 torture_comment(tctx, "Credential chaining failed\n");
     955             :         }
     956             : 
     957             :         /* by changing the machine password twice we test the
     958             :            credentials chaining fully, and we verify that the server
     959             :            allows the password to be set to the same value twice in a
     960             :            row (match win2k3) */
     961          21 :         torture_comment(tctx,
     962             :                 "Testing a second ServerPasswordSet on machine account\n");
     963          21 :         torture_comment(tctx,
     964             :                 "Changing machine account password to '%s' (same as previous run)\n", password);
     965             : 
     966          21 :         netlogon_creds_client_authenticator(creds, &credential);
     967             : 
     968          21 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
     969             :                 "ServerPasswordSet (2) failed");
     970          21 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
     971             : 
     972          21 :         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
     973           0 :                 torture_comment(tctx, "Credential chaining failed\n");
     974             :         }
     975             : 
     976          21 :         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
     977             : 
     978          21 :         torture_assert(tctx,
     979             :                 test_SetupCredentials(p, tctx, machine_credentials, &creds),
     980             :                 "ServerPasswordSet failed to actually change the password");
     981             : 
     982          18 :         return true;
     983             : }
     984             : 
     985             : /*
     986             :   try a change password for our machine account
     987             : */
     988           0 : static bool test_SetPassword_flags(struct torture_context *tctx,
     989             :                                    struct dcerpc_pipe *p1,
     990             :                                    struct cli_credentials *machine_credentials,
     991             :                                    uint32_t negotiate_flags)
     992             : {
     993           0 :         struct netr_ServerPasswordSet r;
     994           0 :         const char *password;
     995           0 :         struct netlogon_creds_CredentialState *creds;
     996           0 :         struct netr_Authenticator credential, return_authenticator;
     997           0 :         struct samr_Password new_password;
     998           0 :         struct dcerpc_pipe *p = NULL;
     999           0 :         struct dcerpc_binding_handle *b = NULL;
    1000             : 
    1001           0 :         if (!test_SetupCredentials2(p1, tctx, negotiate_flags,
    1002             :                                     machine_credentials,
    1003             :                                     cli_credentials_get_secure_channel_type(machine_credentials),
    1004             :                                     &creds)) {
    1005           0 :                 return false;
    1006             :         }
    1007           0 :         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
    1008             :                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
    1009           0 :                 return false;
    1010             :         }
    1011           0 :         b = p->binding_handle;
    1012             : 
    1013           0 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    1014           0 :         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
    1015           0 :         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
    1016           0 :         r.in.computer_name = TEST_MACHINE_NAME;
    1017           0 :         r.in.credential = &credential;
    1018           0 :         r.in.new_password = &new_password;
    1019           0 :         r.out.return_authenticator = &return_authenticator;
    1020             : 
    1021           0 :         password = generate_random_password(tctx, 8, 255);
    1022           0 :         E_md4hash(password, new_password.hash);
    1023             : 
    1024           0 :         netlogon_creds_des_encrypt(creds, &new_password);
    1025             : 
    1026           0 :         torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
    1027           0 :         torture_comment(tctx, "Changing machine account password to '%s'\n",
    1028             :                         password);
    1029             : 
    1030           0 :         netlogon_creds_client_authenticator(creds, &credential);
    1031             : 
    1032           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
    1033             :                 "ServerPasswordSet failed");
    1034           0 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
    1035             : 
    1036           0 :         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
    1037           0 :                 torture_comment(tctx, "Credential chaining failed\n");
    1038             :         }
    1039             : 
    1040             :         /* by changing the machine password twice we test the
    1041             :            credentials chaining fully, and we verify that the server
    1042             :            allows the password to be set to the same value twice in a
    1043             :            row (match win2k3) */
    1044           0 :         torture_comment(tctx,
    1045             :                 "Testing a second ServerPasswordSet on machine account\n");
    1046           0 :         torture_comment(tctx,
    1047             :                 "Changing machine account password to '%s' (same as previous run)\n", password);
    1048             : 
    1049           0 :         netlogon_creds_client_authenticator(creds, &credential);
    1050             : 
    1051           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
    1052             :                 "ServerPasswordSet (2) failed");
    1053           0 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
    1054             : 
    1055           0 :         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
    1056           0 :                 torture_comment(tctx, "Credential chaining failed\n");
    1057             :         }
    1058             : 
    1059           0 :         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
    1060             : 
    1061           0 :         torture_assert(tctx,
    1062             :                 test_SetupCredentials(p, tctx, machine_credentials, &creds),
    1063             :                 "ServerPasswordSet failed to actually change the password");
    1064             : 
    1065           0 :         return true;
    1066             : }
    1067             : 
    1068             : 
    1069             : /*
    1070             :   generate a random password for password change tests
    1071             : */
    1072          53 : static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
    1073             : {
    1074           7 :         int i;
    1075          53 :         DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
    1076          53 :         generate_random_buffer(password.data, password.length);
    1077             : 
    1078        8252 :         for (i=0; i < len; i++) {
    1079        8192 :                 if (((uint16_t *)password.data)[i] == 0) {
    1080           0 :                         ((uint16_t *)password.data)[i] = 1;
    1081             :                 }
    1082             :         }
    1083             : 
    1084          53 :         return password;
    1085             : }
    1086             : 
    1087             : /*
    1088             :   try a change password for our machine account
    1089             : */
    1090          42 : static bool test_SetPassword2_with_flags(struct torture_context *tctx,
    1091             :                                          struct dcerpc_pipe *p1,
    1092             :                                          struct cli_credentials *machine_credentials,
    1093             :                                          uint32_t flags)
    1094             : {
    1095           6 :         struct netr_ServerPasswordSet2 r;
    1096           6 :         const char *password;
    1097           6 :         DATA_BLOB new_random_pass;
    1098           6 :         struct netlogon_creds_CredentialState *creds;
    1099           6 :         struct samr_CryptPassword password_buf;
    1100           6 :         struct samr_Password nt_hash;
    1101           6 :         struct netr_Authenticator credential, return_authenticator;
    1102           6 :         struct netr_CryptPassword new_password;
    1103          42 :         struct dcerpc_pipe *p = NULL;
    1104          42 :         struct dcerpc_binding_handle *b = NULL;
    1105             : 
    1106          42 :         if (!test_SetupCredentials2(p1, tctx, flags, machine_credentials,
    1107             :                                     cli_credentials_get_secure_channel_type(machine_credentials),
    1108             :                                     &creds)) {
    1109           0 :                 return false;
    1110             :         }
    1111          42 :         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
    1112             :                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
    1113           0 :                 return false;
    1114             :         }
    1115          42 :         b = p->binding_handle;
    1116             : 
    1117          42 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    1118          42 :         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
    1119          42 :         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
    1120          42 :         r.in.computer_name = TEST_MACHINE_NAME;
    1121          42 :         r.in.credential = &credential;
    1122          42 :         r.in.new_password = &new_password;
    1123          42 :         r.out.return_authenticator = &return_authenticator;
    1124             : 
    1125          42 :         password = generate_random_password(tctx, 8, 255);
    1126          42 :         encode_pw_buffer(password_buf.data, password, STR_UNICODE);
    1127          42 :         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
    1128          21 :                 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
    1129             :         } else {
    1130          21 :                 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
    1131             :         }
    1132             : 
    1133          42 :         memcpy(new_password.data, password_buf.data, 512);
    1134          42 :         new_password.length = IVAL(password_buf.data, 512);
    1135             : 
    1136          42 :         torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
    1137          42 :         torture_comment(tctx, "Changing machine account password to '%s'\n", password);
    1138             : 
    1139          42 :         netlogon_creds_client_authenticator(creds, &credential);
    1140             : 
    1141          42 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
    1142             :                 "ServerPasswordSet2 failed");
    1143          42 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
    1144             : 
    1145          42 :         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
    1146           0 :                 torture_comment(tctx, "Credential chaining failed\n");
    1147             :         }
    1148             : 
    1149          42 :         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
    1150             : 
    1151             :         /*
    1152             :          * As a consequence of CVE-2020-1472(ZeroLogon)
    1153             :          * Samba explicitly disallows the setting of an empty machine account
    1154             :          * password.
    1155             :          *
    1156             :          * Note that this may fail against Windows, and leave a machine account
    1157             :          * with an empty password.
    1158             :          */
    1159          42 :         password = "";
    1160          42 :         encode_pw_buffer(password_buf.data, password, STR_UNICODE);
    1161          42 :         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
    1162          21 :                 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
    1163             :         } else {
    1164          21 :                 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
    1165             :         }
    1166          42 :         memcpy(new_password.data, password_buf.data, 512);
    1167          42 :         new_password.length = IVAL(password_buf.data, 512);
    1168             : 
    1169          42 :         torture_comment(tctx,
    1170             :                 "Testing ServerPasswordSet2 on machine account\n");
    1171          42 :         torture_comment(tctx,
    1172             :                 "Changing machine account password to '%s'\n", password);
    1173             : 
    1174          42 :         netlogon_creds_client_authenticator(creds, &credential);
    1175             : 
    1176          42 :         torture_assert_ntstatus_ok(
    1177             :                 tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
    1178             :                 "ServerPasswordSet2 failed");
    1179          42 :         torture_assert_ntstatus_equal(
    1180             :                 tctx,
    1181             :                 r.out.result,
    1182             :                 NT_STATUS_WRONG_PASSWORD,
    1183             :                 "ServerPasswordSet2 did not return NT_STATUS_WRONG_PASSWORD");
    1184             : 
    1185             :         /* now try a random password */
    1186          42 :         password = generate_random_password(tctx, 8, 255);
    1187          42 :         encode_pw_buffer(password_buf.data, password, STR_UNICODE);
    1188          42 :         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
    1189          21 :                 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
    1190             :         } else {
    1191          21 :                 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
    1192             :         }
    1193          42 :         memcpy(new_password.data, password_buf.data, 512);
    1194          42 :         new_password.length = IVAL(password_buf.data, 512);
    1195             : 
    1196          42 :         torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
    1197          42 :         torture_comment(tctx, "Changing machine account password to '%s'\n", password);
    1198             : 
    1199          42 :         netlogon_creds_client_authenticator(creds, &credential);
    1200             : 
    1201          42 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
    1202             :                 "ServerPasswordSet2 (2) failed");
    1203          42 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 (2) failed");
    1204             : 
    1205          42 :         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
    1206           0 :                 torture_comment(tctx, "Credential chaining failed\n");
    1207             :         }
    1208             : 
    1209             :         /* by changing the machine password twice we test the
    1210             :            credentials chaining fully, and we verify that the server
    1211             :            allows the password to be set to the same value twice in a
    1212             :            row (match win2k3) */
    1213          42 :         torture_comment(tctx,
    1214             :                 "Testing a second ServerPasswordSet2 on machine account\n");
    1215          42 :         torture_comment(tctx,
    1216             :                 "Changing machine account password to '%s' (same as previous run)\n", password);
    1217             : 
    1218          42 :         netlogon_creds_client_authenticator(creds, &credential);
    1219             : 
    1220          42 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
    1221             :                 "ServerPasswordSet (3) failed");
    1222          42 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
    1223             : 
    1224          42 :         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
    1225           0 :                 torture_comment(tctx, "Credential chaining failed\n");
    1226             :         }
    1227             : 
    1228          42 :         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
    1229             : 
    1230          42 :         torture_assert (tctx,
    1231             :                 test_SetupCredentials(p, tctx, machine_credentials, &creds),
    1232             :                 "ServerPasswordSet failed to actually change the password");
    1233             : 
    1234          42 :         new_random_pass = netlogon_very_rand_pass(tctx, 128);
    1235             : 
    1236             :         /* now try a random stream of bytes for a password */
    1237          42 :         set_pw_in_buffer(password_buf.data, &new_random_pass);
    1238             : 
    1239          42 :         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
    1240          24 :                 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
    1241             :         } else {
    1242          18 :                 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
    1243             :         }
    1244             : 
    1245          42 :         memcpy(new_password.data, password_buf.data, 512);
    1246          42 :         new_password.length = IVAL(password_buf.data, 512);
    1247             : 
    1248          42 :         torture_comment(tctx,
    1249             :                 "Testing a third ServerPasswordSet2 on machine account, with a completely random password\n");
    1250             : 
    1251          42 :         netlogon_creds_client_authenticator(creds, &credential);
    1252             : 
    1253          42 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
    1254             :                 "ServerPasswordSet (3) failed");
    1255          42 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
    1256             : 
    1257          42 :         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
    1258           0 :                 torture_comment(tctx, "Credential chaining failed\n");
    1259             :         }
    1260             : 
    1261          42 :         mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
    1262             : 
    1263          42 :         cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
    1264          42 :         cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
    1265             : 
    1266          42 :         torture_assert (tctx,
    1267             :                 test_SetupCredentials(p, tctx, machine_credentials, &creds),
    1268             :                 "ServerPasswordSet failed to actually change the password");
    1269             : 
    1270          36 :         return true;
    1271             : }
    1272             : 
    1273             : /*
    1274             :   try to change the password of our machine account using a buffer of all zeros,
    1275             :   and a session key that encrypts that to all zeros.
    1276             : 
    1277             : Note: The test does use sign and seal, it's purpose is to exercise
    1278             :       the detection code in dcesrv_netr_ServerPasswordSet2
    1279             : */
    1280          11 : static bool test_SetPassword2_encrypted_to_all_zeros(
    1281             :         struct torture_context *tctx,
    1282             :         struct dcerpc_pipe *p1,
    1283             :         struct cli_credentials *machine_credentials)
    1284             : {
    1285           1 :         struct netr_ServerPasswordSet2 r;
    1286           1 :         struct netlogon_creds_CredentialState *creds;
    1287           1 :         struct samr_CryptPassword password_buf;
    1288           1 :         struct netr_Authenticator credential, return_authenticator;
    1289           1 :         struct netr_CryptPassword new_password;
    1290          11 :         struct dcerpc_pipe *p = NULL;
    1291          11 :         struct dcerpc_binding_handle *b = NULL;
    1292             : 
    1293          11 :         if (!test_ServerAuthenticate2_encrypts_to_zero(
    1294             :                 tctx,
    1295             :                 p1,
    1296             :                 machine_credentials,
    1297             :                 '\0',
    1298             :                 &creds)) {
    1299             : 
    1300           0 :                 return false;
    1301             :         }
    1302             : 
    1303          11 :         if (!test_SetupCredentialsPipe(
    1304             :                 p1,
    1305             :                 tctx,
    1306             :                 machine_credentials,
    1307             :                 creds,
    1308             :                 DCERPC_SIGN | DCERPC_SEAL,
    1309             :                 &p))
    1310             :         {
    1311           0 :                 return false;
    1312             :         }
    1313          11 :         b = p->binding_handle;
    1314             : 
    1315          11 :         r.in.server_name = talloc_asprintf(
    1316             :                 tctx,
    1317             :                 "\\\\%s", dcerpc_server_name(p));
    1318          11 :         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
    1319          12 :         r.in.secure_channel_type =
    1320          11 :                 cli_credentials_get_secure_channel_type(machine_credentials);
    1321          11 :         r.in.computer_name = TEST_MACHINE_NAME;
    1322          11 :         r.in.credential = &credential;
    1323          11 :         r.in.new_password = &new_password;
    1324          11 :         r.out.return_authenticator = &return_authenticator;
    1325             : 
    1326          11 :         ZERO_STRUCT(password_buf);
    1327             : 
    1328          11 :         if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
    1329           0 :                 torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES not set");
    1330             :         }
    1331          11 :         netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
    1332          11 :         if(!all_zero(password_buf.data, 516)) {
    1333           0 :                 torture_fail(tctx, "Password did not encrypt to all zeros\n");
    1334             :         }
    1335             : 
    1336          11 :         memcpy(new_password.data, password_buf.data, 512);
    1337          11 :         new_password.length = IVAL(password_buf.data, 512);
    1338          11 :         torture_assert_int_equal(
    1339             :                 tctx,
    1340             :                 new_password.length,
    1341             :                 0,
    1342             :                 "Length should have encrypted to 0");
    1343             : 
    1344          11 :         netlogon_creds_client_authenticator(creds, &credential);
    1345             : 
    1346          11 :         torture_assert_ntstatus_ok(
    1347             :                 tctx,
    1348             :                 dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
    1349             :                 "ServerPasswordSet2 zero length check failed");
    1350          11 :         torture_assert_ntstatus_equal(
    1351             :                 tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
    1352             : 
    1353          10 :         return true;
    1354             : }
    1355             : 
    1356             : /*
    1357             :  * Choose a session key that encrypts a password of all zeros to all zeros.
    1358             :  * Then try to set the password, using a zeroed buffer, with a non zero
    1359             :  * length.
    1360             :  *
    1361             :  * This exercises the password self encryption check.
    1362             :  *
    1363             :  * Note: The test does use sign and seal, it's purpose is to exercise
    1364             :  *     the detection code in dcesrv_netr_ServerPasswordSet2
    1365             : */
    1366          11 : static bool test_SetPassword2_password_encrypts_to_zero(
    1367             :         struct torture_context *tctx,
    1368             :         struct dcerpc_pipe *p1,
    1369             :         struct cli_credentials *machine_credentials)
    1370             : {
    1371           1 :         struct netr_ServerPasswordSet2 r;
    1372           1 :         struct netlogon_creds_CredentialState *creds;
    1373           1 :         struct samr_CryptPassword password_buf;
    1374           1 :         struct netr_Authenticator credential, return_authenticator;
    1375           1 :         struct netr_CryptPassword new_password;
    1376          11 :         struct dcerpc_pipe *p = NULL;
    1377          11 :         struct dcerpc_binding_handle *b = NULL;
    1378             : 
    1379          11 :         if (!test_ServerAuthenticate2_encrypts_to_zero(
    1380             :                 tctx,
    1381             :                 p1,
    1382             :                 machine_credentials,
    1383             :                 0x00,
    1384             :                 &creds)) {
    1385             : 
    1386           0 :                 return false;
    1387             :         }
    1388             : 
    1389          11 :         if (!test_SetupCredentialsPipe(
    1390             :                 p1,
    1391             :                 tctx,
    1392             :                 machine_credentials,
    1393             :                 creds,
    1394             :                 DCERPC_SIGN | DCERPC_SEAL,
    1395             :                 &p))
    1396             :         {
    1397           0 :                 return false;
    1398             :         }
    1399          11 :         b = p->binding_handle;
    1400             : 
    1401          11 :         r.in.server_name = talloc_asprintf(
    1402             :                 tctx,
    1403             :                 "\\\\%s", dcerpc_server_name(p));
    1404          11 :         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
    1405          12 :         r.in.secure_channel_type =
    1406          11 :                 cli_credentials_get_secure_channel_type(machine_credentials);
    1407          11 :         r.in.computer_name = TEST_MACHINE_NAME;
    1408          11 :         r.in.credential = &credential;
    1409          11 :         r.in.new_password = &new_password;
    1410          11 :         r.out.return_authenticator = &return_authenticator;
    1411             : 
    1412          11 :         ZERO_STRUCT(password_buf);
    1413          11 :         SIVAL(password_buf.data, 512, 512);
    1414             : 
    1415          11 :         if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
    1416           0 :                 torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES not set");
    1417             :         }
    1418          11 :         netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
    1419             : 
    1420          11 :         memcpy(new_password.data, password_buf.data, 512);
    1421          11 :         new_password.length = IVAL(password_buf.data, 512);
    1422             : 
    1423          11 :         netlogon_creds_client_authenticator(creds, &credential);
    1424             : 
    1425          11 :         torture_assert_ntstatus_ok(
    1426             :                 tctx,
    1427             :                 dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
    1428             :                 "ServerPasswordSet2 password encrypts to zero check failed");
    1429          11 :         torture_assert_ntstatus_equal(
    1430             :                 tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
    1431             : 
    1432          10 :         return true;
    1433             : }
    1434             : 
    1435             : /*
    1436             :  * Check that an all zero confounder, that encrypts to all zeros is
    1437             :  * rejected.
    1438             :  *
    1439             :  * Note: The test does use sign and seal, it's purpose is to exercise
    1440             :  *       the detection code in dcesrv_netr_ServerPasswordSet2
    1441             :  */
    1442          11 : static bool test_SetPassword2_confounder(
    1443             :         struct torture_context *tctx,
    1444             :         struct dcerpc_pipe *p1,
    1445             :         struct cli_credentials *machine_credentials)
    1446             : {
    1447           1 :         struct netr_ServerPasswordSet2 r;
    1448           1 :         struct netlogon_creds_CredentialState *creds;
    1449           1 :         struct samr_CryptPassword password_buf;
    1450           1 :         struct netr_Authenticator credential, return_authenticator;
    1451           1 :         struct netr_CryptPassword new_password;
    1452          11 :         struct dcerpc_pipe *p = NULL;
    1453          11 :         struct dcerpc_binding_handle *b = NULL;
    1454             : 
    1455          11 :         if (!test_ServerAuthenticate2_encrypts_to_zero(
    1456             :                 tctx,
    1457             :                 p1,
    1458             :                 machine_credentials,
    1459             :                 '\0',
    1460             :                 &creds)) {
    1461             : 
    1462           0 :                 return false;
    1463             :         }
    1464             : 
    1465          11 :         if (!test_SetupCredentialsPipe(
    1466             :                 p1,
    1467             :                 tctx,
    1468             :                 machine_credentials,
    1469             :                 creds,
    1470             :                 DCERPC_SIGN | DCERPC_SEAL,
    1471             :                 &p))
    1472             :         {
    1473           0 :                 return false;
    1474             :         }
    1475          11 :         b = p->binding_handle;
    1476             : 
    1477          11 :         r.in.server_name = talloc_asprintf(
    1478             :                 tctx,
    1479             :                 "\\\\%s", dcerpc_server_name(p));
    1480          11 :         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
    1481          12 :         r.in.secure_channel_type =
    1482          11 :                 cli_credentials_get_secure_channel_type(machine_credentials);
    1483          11 :         r.in.computer_name = TEST_MACHINE_NAME;
    1484          11 :         r.in.credential = &credential;
    1485          11 :         r.in.new_password = &new_password;
    1486          11 :         r.out.return_authenticator = &return_authenticator;
    1487             : 
    1488          11 :         ZERO_STRUCT(password_buf);
    1489          11 :         password_buf.data[511] = 'A';
    1490          11 :         SIVAL(password_buf.data, 512, 2);
    1491             : 
    1492          11 :         if (!(creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES)) {
    1493           0 :                 torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES not set");
    1494             :         }
    1495          11 :         netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
    1496             : 
    1497          11 :         memcpy(new_password.data, password_buf.data, 512);
    1498          11 :         new_password.length = IVAL(password_buf.data, 512);
    1499             : 
    1500          11 :         netlogon_creds_client_authenticator(creds, &credential);
    1501             : 
    1502          11 :         torture_assert_ntstatus_ok(
    1503             :                 tctx,
    1504             :                 dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
    1505             :                 "ServerPasswordSet2 confounder check failed");
    1506          11 :         torture_assert_ntstatus_equal(
    1507             :                 tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
    1508             : 
    1509          10 :         return true;
    1510             : }
    1511             : 
    1512             : /*
    1513             :  * try a change password for our machine account, using an all zero
    1514             :  *  request. This should fail on the zero length check.
    1515             :  *
    1516             :  * Note: This test uses ARC4 encryption to exercise the desired check.
    1517             :  */
    1518          11 : static bool test_SetPassword2_all_zeros(
    1519             :         struct torture_context *tctx,
    1520             :         struct dcerpc_pipe *p1,
    1521             :         struct cli_credentials *machine_credentials)
    1522             : {
    1523           1 :         struct netr_ServerPasswordSet2 r;
    1524           1 :         struct netlogon_creds_CredentialState *creds;
    1525           1 :         struct samr_CryptPassword password_buf;
    1526           1 :         struct netr_Authenticator credential, return_authenticator;
    1527           1 :         struct netr_CryptPassword new_password;
    1528          11 :         struct dcerpc_pipe *p = NULL;
    1529          11 :         struct dcerpc_binding_handle *b = NULL;
    1530          11 :         uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; /* no AES desired here */
    1531             : 
    1532          11 :         if (!test_SetupCredentials2(
    1533             :                 p1,
    1534             :                 tctx,
    1535             :                 flags,
    1536             :                 machine_credentials,
    1537             :                 cli_credentials_get_secure_channel_type(machine_credentials),
    1538             :                 &creds))
    1539             :         {
    1540           0 :                 return false;
    1541             :         }
    1542          11 :         if (!test_SetupCredentialsPipe(
    1543             :                 p1,
    1544             :                 tctx,
    1545             :                 machine_credentials,
    1546             :                 creds,
    1547             :                 DCERPC_SIGN | DCERPC_SEAL,
    1548             :                 &p))
    1549             :         {
    1550           0 :                 return false;
    1551             :         }
    1552          11 :         b = p->binding_handle;
    1553             : 
    1554          11 :         r.in.server_name = talloc_asprintf(
    1555             :                 tctx,
    1556             :                 "\\\\%s", dcerpc_server_name(p));
    1557          11 :         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
    1558          12 :         r.in.secure_channel_type =
    1559          11 :                 cli_credentials_get_secure_channel_type(machine_credentials);
    1560          11 :         r.in.computer_name = TEST_MACHINE_NAME;
    1561          11 :         r.in.credential = &credential;
    1562          11 :         r.in.new_password = &new_password;
    1563          11 :         r.out.return_authenticator = &return_authenticator;
    1564             : 
    1565          11 :         ZERO_STRUCT(password_buf.data);
    1566          11 :         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
    1567           0 :                 torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES enabled\n");
    1568             :         }
    1569          11 :         netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
    1570             : 
    1571          11 :         memcpy(new_password.data, password_buf.data, 512);
    1572          11 :         new_password.length = IVAL(password_buf.data, 512);
    1573             : 
    1574          11 :         torture_comment(
    1575             :                 tctx,
    1576             :                 "Testing ServerPasswordSet2 on machine account\n");
    1577             : 
    1578          11 :         netlogon_creds_client_authenticator(creds, &credential);
    1579             : 
    1580          11 :         torture_assert_ntstatus_ok(
    1581             :                 tctx,
    1582             :                 dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
    1583             :                 "ServerPasswordSet2 zero length check failed");
    1584          11 :         torture_assert_ntstatus_equal(
    1585             :                 tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
    1586             : 
    1587          10 :         return true;
    1588             : }
    1589             : 
    1590             : /*
    1591             :   try a change password for our machine account, using a maximum length
    1592             :   password
    1593             : */
    1594          11 : static bool test_SetPassword2_maximum_length_password(
    1595             :         struct torture_context *tctx,
    1596             :         struct dcerpc_pipe *p1,
    1597             :         struct cli_credentials *machine_credentials)
    1598             : {
    1599           1 :         struct netr_ServerPasswordSet2 r;
    1600           1 :         struct netlogon_creds_CredentialState *creds;
    1601           1 :         struct samr_CryptPassword password_buf;
    1602           1 :         struct netr_Authenticator credential, return_authenticator;
    1603           1 :         struct netr_CryptPassword new_password;
    1604          11 :         struct dcerpc_pipe *p = NULL;
    1605          11 :         struct dcerpc_binding_handle *b = NULL;
    1606          11 :         uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
    1607          11 :         DATA_BLOB new_random_pass = data_blob_null;
    1608             : 
    1609          11 :         if (!test_SetupCredentials2(
    1610             :                 p1,
    1611             :                 tctx,
    1612             :                 flags,
    1613             :                 machine_credentials,
    1614             :                 cli_credentials_get_secure_channel_type(machine_credentials),
    1615             :                 &creds))
    1616             :         {
    1617           0 :                 return false;
    1618             :         }
    1619          11 :         if (!test_SetupCredentialsPipe(
    1620             :                 p1,
    1621             :                 tctx,
    1622             :                 machine_credentials,
    1623             :                 creds,
    1624             :                 DCERPC_SIGN | DCERPC_SEAL,
    1625             :                 &p))
    1626             :         {
    1627           0 :                 return false;
    1628             :         }
    1629          11 :         b = p->binding_handle;
    1630             : 
    1631          11 :         r.in.server_name = talloc_asprintf(
    1632             :                 tctx,
    1633             :                 "\\\\%s", dcerpc_server_name(p));
    1634          11 :         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
    1635          12 :         r.in.secure_channel_type =
    1636          11 :                 cli_credentials_get_secure_channel_type(machine_credentials);
    1637          11 :         r.in.computer_name = TEST_MACHINE_NAME;
    1638          11 :         r.in.credential = &credential;
    1639          11 :         r.in.new_password = &new_password;
    1640          11 :         r.out.return_authenticator = &return_authenticator;
    1641             : 
    1642          11 :         new_random_pass = netlogon_very_rand_pass(tctx, 256);
    1643          11 :         set_pw_in_buffer(password_buf.data, &new_random_pass);
    1644          11 :         SIVAL(password_buf.data, 512, 512);
    1645          11 :         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
    1646          11 :                 netlogon_creds_aes_encrypt(creds, password_buf.data, 516);
    1647             :         } else {
    1648           0 :                 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
    1649             :         }
    1650             : 
    1651          11 :         memcpy(new_password.data, password_buf.data, 512);
    1652          11 :         new_password.length = IVAL(password_buf.data, 512);
    1653             : 
    1654          11 :         torture_comment(
    1655             :                 tctx,
    1656             :                 "Testing ServerPasswordSet2 on machine account\n");
    1657             : 
    1658          11 :         netlogon_creds_client_authenticator(creds, &credential);
    1659             : 
    1660          11 :         torture_assert_ntstatus_ok(
    1661             :                 tctx,
    1662             :                 dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
    1663             :                 "ServerPasswordSet2 zero length check failed");
    1664          11 :         torture_assert_ntstatus_equal(
    1665             :                 tctx, r.out.result, NT_STATUS_OK, "");
    1666             : 
    1667           8 :         return true;
    1668             : }
    1669             : 
    1670             : /*
    1671             :   try a change password for our machine account, using a password of
    1672             :   all zeros, and a non zero password length.
    1673             : 
    1674             :   This test relies on the buffer being encrypted with ARC4, to
    1675             :   trigger the appropriate check in the rpc server code
    1676             : */
    1677          11 : static bool test_SetPassword2_all_zero_password(
    1678             :         struct torture_context *tctx,
    1679             :         struct dcerpc_pipe *p1,
    1680             :         struct cli_credentials *machine_credentials)
    1681             : {
    1682           1 :         struct netr_ServerPasswordSet2 r;
    1683           1 :         struct netlogon_creds_CredentialState *creds;
    1684           1 :         struct samr_CryptPassword password_buf;
    1685           1 :         struct netr_Authenticator credential, return_authenticator;
    1686           1 :         struct netr_CryptPassword new_password;
    1687          11 :         struct dcerpc_pipe *p = NULL;
    1688          11 :         struct dcerpc_binding_handle *b = NULL;
    1689          11 :         uint32_t flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; /* no AES desired here */
    1690             : 
    1691          11 :         if (!test_SetupCredentials2(
    1692             :                 p1,
    1693             :                 tctx,
    1694             :                 flags,
    1695             :                 machine_credentials,
    1696             :                 cli_credentials_get_secure_channel_type(machine_credentials),
    1697             :                 &creds))
    1698             :         {
    1699           0 :                 return false;
    1700             :         }
    1701          11 :         if (!test_SetupCredentialsPipe(
    1702             :                 p1,
    1703             :                 tctx,
    1704             :                 machine_credentials,
    1705             :                 creds,
    1706             :                 DCERPC_SIGN | DCERPC_SEAL,
    1707             :                 &p))
    1708             :         {
    1709           0 :                 return false;
    1710             :         }
    1711          11 :         b = p->binding_handle;
    1712             : 
    1713          11 :         r.in.server_name = talloc_asprintf(
    1714             :                 tctx,
    1715             :                 "\\\\%s", dcerpc_server_name(p));
    1716          11 :         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
    1717          12 :         r.in.secure_channel_type =
    1718          11 :                 cli_credentials_get_secure_channel_type(machine_credentials);
    1719          11 :         r.in.computer_name = TEST_MACHINE_NAME;
    1720          11 :         r.in.credential = &credential;
    1721          11 :         r.in.new_password = &new_password;
    1722          11 :         r.out.return_authenticator = &return_authenticator;
    1723             : 
    1724          11 :         ZERO_STRUCT(password_buf.data);
    1725          11 :         SIVAL(password_buf.data, 512, 128);
    1726          11 :         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
    1727           0 :                 torture_fail(tctx, "NETLOGON_NEG_SUPPORTS_AES set");
    1728             :         }
    1729          11 :         netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
    1730             : 
    1731          11 :         memcpy(new_password.data, password_buf.data, 512);
    1732          11 :         new_password.length = IVAL(password_buf.data, 512);
    1733             : 
    1734          11 :         torture_comment(
    1735             :                 tctx,
    1736             :                 "Testing ServerPasswordSet2 on machine account\n");
    1737             : 
    1738          11 :         netlogon_creds_client_authenticator(creds, &credential);
    1739             : 
    1740          11 :         torture_assert_ntstatus_ok(
    1741             :                 tctx,
    1742             :                 dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
    1743             :                 "ServerPasswordSet2 all zero password check failed");
    1744          11 :         torture_assert_ntstatus_equal(
    1745             :                 tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, "");
    1746             : 
    1747          10 :         return true;
    1748             : }
    1749             : 
    1750             : 
    1751          21 : static bool test_SetPassword2(struct torture_context *tctx,
    1752             :                               struct dcerpc_pipe *p,
    1753             :                               struct cli_credentials *machine_credentials)
    1754             : {
    1755          21 :         return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS);
    1756             : }
    1757             : 
    1758          21 : static bool test_SetPassword2_AES(struct torture_context *tctx,
    1759             :                                   struct dcerpc_pipe *p,
    1760             :                                   struct cli_credentials *machine_credentials)
    1761             : {
    1762          21 :         return test_SetPassword2_with_flags(tctx, p, machine_credentials, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
    1763             : }
    1764             : 
    1765          18 : static bool test_GetPassword(struct torture_context *tctx,
    1766             :                              struct dcerpc_pipe *p,
    1767             :                              struct cli_credentials *machine_credentials)
    1768             : {
    1769           3 :         struct netr_ServerPasswordGet r;
    1770           3 :         struct netlogon_creds_CredentialState *creds;
    1771           3 :         struct netr_Authenticator credential;
    1772           3 :         NTSTATUS status;
    1773           3 :         struct netr_Authenticator return_authenticator;
    1774           3 :         struct samr_Password password;
    1775          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
    1776             : 
    1777          18 :         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
    1778           0 :                 return false;
    1779             :         }
    1780             : 
    1781          18 :         netlogon_creds_client_authenticator(creds, &credential);
    1782             : 
    1783          18 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    1784          18 :         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
    1785          18 :         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
    1786          18 :         r.in.computer_name = TEST_MACHINE_NAME;
    1787          18 :         r.in.credential = &credential;
    1788          18 :         r.out.return_authenticator = &return_authenticator;
    1789          18 :         r.out.password = &password;
    1790             : 
    1791          18 :         status = dcerpc_netr_ServerPasswordGet_r(b, tctx, &r);
    1792          18 :         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
    1793           0 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordGet");
    1794             : 
    1795           0 :         return true;
    1796             : }
    1797             : 
    1798          18 : static bool test_GetTrustPasswords(struct torture_context *tctx,
    1799             :                                    struct dcerpc_pipe *p,
    1800             :                                    struct cli_credentials *machine_credentials)
    1801             : {
    1802           3 :         struct netr_ServerTrustPasswordsGet r;
    1803           3 :         struct netlogon_creds_CredentialState *creds;
    1804           3 :         struct netr_Authenticator credential;
    1805           3 :         struct netr_Authenticator return_authenticator;
    1806           3 :         struct samr_Password password, password2;
    1807          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
    1808             : 
    1809          18 :         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
    1810           0 :                 return false;
    1811             :         }
    1812             : 
    1813          18 :         netlogon_creds_client_authenticator(creds, &credential);
    1814             : 
    1815          18 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    1816          18 :         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
    1817          18 :         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
    1818          18 :         r.in.computer_name = TEST_MACHINE_NAME;
    1819          18 :         r.in.credential = &credential;
    1820          18 :         r.out.return_authenticator = &return_authenticator;
    1821          18 :         r.out.new_owf_password = &password;
    1822          18 :         r.out.old_owf_password = &password2;
    1823             : 
    1824          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerTrustPasswordsGet_r(b, tctx, &r),
    1825             :                 "ServerTrustPasswordsGet failed");
    1826          18 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerTrustPasswordsGet failed");
    1827             : 
    1828          15 :         return true;
    1829             : }
    1830             : 
    1831             : /*
    1832             :   try a netlogon SamLogon
    1833             : */
    1834         852 : static bool test_netlogon_ops_args(struct dcerpc_pipe *p, struct torture_context *tctx,
    1835             :                                    struct cli_credentials *credentials,
    1836             :                                    struct netlogon_creds_CredentialState *creds,
    1837             :                                    bool null_domain)
    1838             : {
    1839         147 :         NTSTATUS status;
    1840         147 :         struct netr_LogonSamLogon r;
    1841         147 :         struct netr_Authenticator auth, auth2;
    1842         147 :         union netr_LogonLevel logon;
    1843         147 :         union netr_Validation validation;
    1844         147 :         uint8_t authoritative;
    1845         147 :         struct netr_NetworkInfo ninfo;
    1846         147 :         DATA_BLOB names_blob, chal, lm_resp, nt_resp;
    1847         147 :         int i;
    1848         852 :         struct dcerpc_binding_handle *b = p->binding_handle;
    1849         852 :         int flags = CLI_CRED_NTLM_AUTH;
    1850         852 :         if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
    1851         741 :                 flags |= CLI_CRED_LANMAN_AUTH;
    1852             :         }
    1853             : 
    1854         852 :         if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx) && !null_domain) {
    1855         849 :                 flags |= CLI_CRED_NTLMv2_AUTH;
    1856             :         }
    1857             : 
    1858         852 :         cli_credentials_get_ntlm_username_domain(samba_cmdline_get_creds(),
    1859             :                                                  tctx,
    1860             :                                                  &ninfo.identity_info.account_name.string,
    1861             :                                                  &ninfo.identity_info.domain_name.string);
    1862             : 
    1863         852 :         if (null_domain) {
    1864           3 :                 ninfo.identity_info.domain_name.string = NULL;
    1865             :         }
    1866             : 
    1867         852 :         generate_random_buffer(ninfo.challenge,
    1868             :                                sizeof(ninfo.challenge));
    1869         852 :         chal = data_blob_const(ninfo.challenge,
    1870             :                                sizeof(ninfo.challenge));
    1871             : 
    1872         852 :         names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials),
    1873             :                                                 cli_credentials_get_domain(credentials));
    1874             : 
    1875         852 :         status = cli_credentials_get_ntlm_response(
    1876             :                                 samba_cmdline_get_creds(), tctx,
    1877             :                                 &flags,
    1878             :                                 chal,
    1879             :                                 NULL, /* server_timestamp */
    1880             :                                 names_blob,
    1881             :                                 &lm_resp, &nt_resp,
    1882             :                                 NULL, NULL);
    1883         852 :         torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
    1884             : 
    1885         852 :         ninfo.lm.data = lm_resp.data;
    1886         852 :         ninfo.lm.length = lm_resp.length;
    1887             : 
    1888         852 :         ninfo.nt.data = nt_resp.data;
    1889         852 :         ninfo.nt.length = nt_resp.length;
    1890             : 
    1891         852 :         ninfo.identity_info.parameter_control = 0;
    1892         852 :         ninfo.identity_info.logon_id = 0;
    1893         852 :         ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
    1894             : 
    1895         852 :         logon.network = &ninfo;
    1896             : 
    1897         852 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    1898         852 :         r.in.computer_name = cli_credentials_get_workstation(credentials);
    1899         852 :         r.in.credential = &auth;
    1900         852 :         r.in.return_authenticator = &auth2;
    1901         852 :         r.in.logon_level = NetlogonNetworkInformation;
    1902         852 :         r.in.logon = &logon;
    1903         852 :         r.out.validation = &validation;
    1904         852 :         r.out.authoritative = &authoritative;
    1905             : 
    1906         852 :         d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
    1907             : 
    1908        2703 :         for (i=2;i<=3;i++) {
    1909        1704 :                 ZERO_STRUCT(auth2);
    1910        1704 :                 netlogon_creds_client_authenticator(creds, &auth);
    1911             : 
    1912        1704 :                 r.in.validation_level = i;
    1913             : 
    1914        1704 :                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
    1915             :                         "LogonSamLogon failed");
    1916        1704 :                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
    1917             : 
    1918        1704 :                 torture_assert(tctx, netlogon_creds_client_check(creds,
    1919             :                                                                  &r.out.return_authenticator->cred),
    1920             :                         "Credential chaining failed");
    1921        1704 :                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
    1922             :                                          "LogonSamLogon invalid  *r.out.authoritative");
    1923             :         }
    1924             : 
    1925             :         /* this makes sure we get the unmarshalling right for invalid levels */
    1926        1704 :         for (i=52;i<53;i++) {
    1927         852 :                 ZERO_STRUCT(auth2);
    1928             :                 /* the authenticator should be ignored by the server */
    1929         852 :                 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
    1930             : 
    1931         852 :                 r.in.validation_level = i;
    1932             : 
    1933         852 :                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
    1934             :                                            "LogonSamLogon failed");
    1935         852 :                 torture_assert_ntstatus_equal(tctx, r.out.result,
    1936             :                                               NT_STATUS_INVALID_INFO_CLASS,
    1937             :                                               "LogonSamLogon failed");
    1938             : 
    1939         852 :                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
    1940             :                                          "LogonSamLogon invalid  *r.out.authoritative");
    1941         852 :                 torture_assert(tctx,
    1942             :                                all_zero((uint8_t *)&auth2, sizeof(auth2)),
    1943             :                                "Return authenticator non zero");
    1944             :         }
    1945             : 
    1946        2556 :         for (i=2;i<=3;i++) {
    1947        1704 :                 ZERO_STRUCT(auth2);
    1948        1704 :                 netlogon_creds_client_authenticator(creds, &auth);
    1949             : 
    1950        1704 :                 r.in.validation_level = i;
    1951             : 
    1952        1704 :                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
    1953             :                         "LogonSamLogon failed");
    1954        1704 :                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
    1955             : 
    1956        1704 :                 torture_assert(tctx, netlogon_creds_client_check(creds,
    1957             :                                                                  &r.out.return_authenticator->cred),
    1958             :                         "Credential chaining failed");
    1959        1704 :                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
    1960             :                                          "LogonSamLogon invalid  *r.out.authoritative");
    1961             :         }
    1962             : 
    1963         852 :         r.in.logon_level = 52;
    1964             : 
    1965        2556 :         for (i=2;i<=3;i++) {
    1966        1704 :                 ZERO_STRUCT(auth2);
    1967             :                 /* the authenticator should be ignored by the server */
    1968        1704 :                 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
    1969             : 
    1970        1704 :                 r.in.validation_level = i;
    1971             : 
    1972        1704 :                 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
    1973             : 
    1974        1704 :                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
    1975             :                         "LogonSamLogon failed");
    1976        1704 :                 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
    1977             :                         "LogonSamLogon expected INVALID_PARAMETER");
    1978             : 
    1979        1704 :                 torture_assert(tctx,
    1980             :                                all_zero((uint8_t *)&auth2, sizeof(auth2)),
    1981             :                                "Return authenticator non zero");
    1982        1704 :                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
    1983             :                                          "LogonSamLogon invalid  *r.out.authoritative");
    1984             :         }
    1985             : 
    1986         852 :         r.in.credential = NULL;
    1987             : 
    1988        2556 :         for (i=2;i<=3;i++) {
    1989        1704 :                 ZERO_STRUCT(auth2);
    1990             : 
    1991        1704 :                 r.in.validation_level = i;
    1992             : 
    1993        1704 :                 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
    1994             : 
    1995        1704 :                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
    1996             :                         "LogonSamLogon failed");
    1997        1704 :                 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
    1998             :                         "LogonSamLogon expected INVALID_PARAMETER");
    1999             : 
    2000        1704 :                 torture_assert(tctx,
    2001             :                                all_zero((uint8_t *)&auth2, sizeof(auth2)),
    2002             :                                "Return authenticator non zero");
    2003        1704 :                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
    2004             :                                          "LogonSamLogon invalid  *r.out.authoritative");
    2005             :         }
    2006             : 
    2007         852 :         r.in.logon_level = NetlogonNetworkInformation;
    2008         852 :         r.in.credential = &auth;
    2009             : 
    2010        2556 :         for (i=2;i<=3;i++) {
    2011        1704 :                 ZERO_STRUCT(auth2);
    2012        1704 :                 netlogon_creds_client_authenticator(creds, &auth);
    2013             : 
    2014        1704 :                 r.in.validation_level = i;
    2015             : 
    2016        1704 :                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
    2017             :                         "LogonSamLogon failed");
    2018        1704 :                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
    2019             : 
    2020        1704 :                 torture_assert(tctx, netlogon_creds_client_check(creds,
    2021             :                                                                  &r.out.return_authenticator->cred),
    2022             :                         "Credential chaining failed");
    2023        1704 :                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
    2024             :                                          "LogonSamLogon invalid  *r.out.authoritative");
    2025             :         }
    2026             : 
    2027         705 :         return true;
    2028             : }
    2029             : 
    2030         849 : bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
    2031             :                        struct cli_credentials *credentials,
    2032             :                        struct netlogon_creds_CredentialState *creds)
    2033             : {
    2034         849 :         return test_netlogon_ops_args(p, tctx, credentials, creds, false);
    2035             : }
    2036             : 
    2037             : /*
    2038             :   try a netlogon GetCapabilities
    2039             : */
    2040         552 : bool test_netlogon_capabilities(struct dcerpc_pipe *p, struct torture_context *tctx,
    2041             :                                 struct cli_credentials *credentials,
    2042             :                                 struct netlogon_creds_CredentialState *creds)
    2043             : {
    2044          96 :         NTSTATUS status;
    2045          96 :         struct netr_LogonGetCapabilities r;
    2046          96 :         union netr_Capabilities capabilities;
    2047          96 :         struct netr_Authenticator auth, return_auth;
    2048          96 :         struct netlogon_creds_CredentialState tmp_creds;
    2049         552 :         struct dcerpc_binding_handle *b = p->binding_handle;
    2050             : 
    2051         552 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    2052         552 :         r.in.computer_name = cli_credentials_get_workstation(credentials);
    2053         552 :         r.in.credential = &auth;
    2054         552 :         r.in.return_authenticator = &return_auth;
    2055         552 :         r.in.query_level = 1;
    2056         552 :         r.out.capabilities = &capabilities;
    2057         552 :         r.out.return_authenticator = &return_auth;
    2058             : 
    2059         552 :         torture_comment(tctx, "Testing LogonGetCapabilities with query_level=0\n");
    2060             : 
    2061         552 :         r.in.query_level = 0;
    2062         552 :         ZERO_STRUCT(return_auth);
    2063             : 
    2064             :         /*
    2065             :          * we need to operate on a temporary copy of creds
    2066             :          * because dcerpc_netr_LogonGetCapabilities with
    2067             :          * an unknown query level returns DCERPC_NCA_S_FAULT_INVALID_TAG
    2068             :          * => NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
    2069             :          * without looking at the authenticator.
    2070             :          */
    2071         552 :         tmp_creds = *creds;
    2072         552 :         netlogon_creds_client_authenticator(&tmp_creds, &auth);
    2073             : 
    2074         552 :         status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
    2075         552 :         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE,
    2076             :                                       "LogonGetCapabilities query_level=0 failed");
    2077             : 
    2078         552 :         torture_comment(tctx, "Testing LogonGetCapabilities with query_level=3\n");
    2079             : 
    2080         552 :         r.in.query_level = 3;
    2081         552 :         ZERO_STRUCT(return_auth);
    2082             : 
    2083             :         /*
    2084             :          * we need to operate on a temporary copy of creds
    2085             :          * because dcerpc_netr_LogonGetCapabilities with
    2086             :          * an unknown query level returns DCERPC_NCA_S_FAULT_INVALID_TAG
    2087             :          * => NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
    2088             :          * without looking at the authenticator.
    2089             :          */
    2090         552 :         tmp_creds = *creds;
    2091         552 :         netlogon_creds_client_authenticator(&tmp_creds, &auth);
    2092             : 
    2093         552 :         status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
    2094         552 :         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE,
    2095             :                                       "LogonGetCapabilities query_level=0 failed");
    2096             : 
    2097         552 :         torture_comment(tctx, "Testing LogonGetCapabilities with query_level=1\n");
    2098             : 
    2099         552 :         r.in.query_level = 1;
    2100         552 :         ZERO_STRUCT(return_auth);
    2101             : 
    2102             :         /*
    2103             :          * we need to operate on a temporary copy of creds
    2104             :          * because dcerpc_netr_LogonGetCapabilities was
    2105             :          * dcerpc_netr_DummyFunction and returns NT_STATUS_NOT_IMPLEMENTED
    2106             :          * without looking at the authenticator.
    2107             :          */
    2108         552 :         tmp_creds = *creds;
    2109         552 :         netlogon_creds_client_authenticator(&tmp_creds, &auth);
    2110             : 
    2111         552 :         status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
    2112         552 :         torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities failed");
    2113         552 :         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
    2114           0 :                 return true;
    2115             :         }
    2116             : 
    2117         552 :         *creds = tmp_creds;
    2118             : 
    2119         552 :         torture_assert(tctx, netlogon_creds_client_check(creds,
    2120             :                                                          &r.out.return_authenticator->cred),
    2121             :                        "Credential chaining failed");
    2122             : 
    2123         552 :         torture_assert_int_equal(tctx, creds->negotiate_flags,
    2124             :                                  capabilities.server_capabilities,
    2125             :                                  "negotiate flags");
    2126             : 
    2127         552 :         torture_comment(tctx, "Testing LogonGetCapabilities with query_level=2\n");
    2128             : 
    2129         552 :         r.in.query_level = 2;
    2130         552 :         ZERO_STRUCT(return_auth);
    2131             : 
    2132             :         /*
    2133             :          * we need to operate on a temporary copy of creds
    2134             :          * because dcerpc_netr_LogonGetCapabilities with
    2135             :          * an query level 2 may returns DCERPC_NCA_S_FAULT_INVALID_TAG
    2136             :          * => NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
    2137             :          * without looking at the authenticator.
    2138             :          */
    2139         552 :         tmp_creds = *creds;
    2140         552 :         netlogon_creds_client_authenticator(&tmp_creds, &auth);
    2141             : 
    2142         552 :         status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
    2143         552 :         if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE)) {
    2144             :                 /*
    2145             :                  * an server without KB5028166 returns
    2146             :                  * DCERPC_NCA_S_FAULT_INVALID_TAG =>
    2147             :                  * NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
    2148             :                  */
    2149         456 :                 return true;
    2150             :         }
    2151           0 :         torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities query_level=2 failed");
    2152             : 
    2153           0 :         *creds = tmp_creds;
    2154             : 
    2155           0 :         torture_assert(tctx, netlogon_creds_client_check(creds,
    2156             :                                                          &r.out.return_authenticator->cred),
    2157             :                        "Credential chaining failed");
    2158             : 
    2159           0 :         torture_assert_int_equal(tctx, creds->negotiate_flags,
    2160             :                                  capabilities.server_capabilities,
    2161             :                                  "negotiate flags");
    2162             : 
    2163           0 :         return true;
    2164             : }
    2165             : 
    2166             : /*
    2167             :   try a netlogon SamLogon
    2168             : */
    2169          21 : static bool test_SamLogon(struct torture_context *tctx,
    2170             :                           struct dcerpc_pipe *p,
    2171             :                           struct cli_credentials *credentials)
    2172             : {
    2173           3 :         struct netlogon_creds_CredentialState *creds;
    2174             : 
    2175          21 :         if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
    2176           0 :                 return false;
    2177             :         }
    2178             : 
    2179          21 :         return test_netlogon_ops(p, tctx, credentials, creds);
    2180             : }
    2181             : 
    2182          18 : static bool test_invalidAuthenticate2(struct torture_context *tctx,
    2183             :                                       struct dcerpc_pipe *p,
    2184             :                                       struct cli_credentials *credentials)
    2185             : {
    2186           3 :         struct netlogon_creds_CredentialState *creds;
    2187          18 :         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
    2188             : 
    2189          18 :         torture_comment(tctx, "Testing invalidAuthenticate2\n");
    2190             : 
    2191          18 :         if (!test_SetupCredentials2(p, tctx, flags,
    2192             :                                     credentials,
    2193             :                                     cli_credentials_get_secure_channel_type(credentials),
    2194             :                                     &creds)) {
    2195           0 :                 return false;
    2196             :         }
    2197             : 
    2198          18 :         if (!test_SetupCredentials2ex(p, tctx, flags,
    2199             :                                       credentials,
    2200             :                                       "1234567890123456",
    2201             :                                       cli_credentials_get_secure_channel_type(credentials),
    2202          18 :                                       STATUS_BUFFER_OVERFLOW,
    2203             :                                       &creds)) {
    2204           0 :                 return false;
    2205             :         }
    2206             : 
    2207          18 :         if (!test_SetupCredentials2ex(p, tctx, flags,
    2208             :                                       credentials,
    2209             :                                       "123456789012345",
    2210             :                                       cli_credentials_get_secure_channel_type(credentials),
    2211          18 :                                       NT_STATUS_OK,
    2212             :                                       &creds)) {
    2213           0 :                 return false;
    2214             :         }
    2215             : 
    2216          18 :         return true;
    2217             : }
    2218             : 
    2219          18 : static bool test_ServerReqChallengeGlobal(struct torture_context *tctx,
    2220             :                                           struct dcerpc_pipe *p1,
    2221             :                                           struct cli_credentials *machine_credentials)
    2222             : {
    2223          18 :         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
    2224           3 :         struct netr_ServerReqChallenge r;
    2225           3 :         struct netr_ServerAuthenticate3 a;
    2226           3 :         struct netr_Credential credentials1, credentials2, credentials3;
    2227           3 :         struct netlogon_creds_CredentialState *creds;
    2228           3 :         struct samr_Password mach_password;
    2229           3 :         uint32_t rid;
    2230           3 :         const char *machine_name;
    2231           3 :         const char *plain_pass;
    2232          18 :         struct dcerpc_binding_handle *b1 = p1->binding_handle;
    2233          18 :         struct dcerpc_pipe *p2 = NULL;
    2234          18 :         struct dcerpc_binding_handle *b2 = NULL;
    2235             : 
    2236          18 :         machine_name = cli_credentials_get_workstation(machine_credentials);
    2237          18 :         torture_assert(tctx, machine_name != NULL, "machine_name");
    2238          18 :         plain_pass = cli_credentials_get_password(machine_credentials);
    2239          18 :         torture_assert(tctx, plain_pass != NULL, "plain_pass");
    2240             : 
    2241          18 :         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
    2242             : 
    2243          18 :         torture_assert_ntstatus_ok(tctx,
    2244             :                 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
    2245             :                                       &ndr_table_netlogon,
    2246             :                                       machine_credentials,
    2247             :                                       tctx->ev, tctx->lp_ctx),
    2248             :                 "dcerpc_pipe_connect_b failed");
    2249          18 :         b2 = p2->binding_handle;
    2250             : 
    2251          18 :         r.in.server_name = NULL;
    2252          18 :         r.in.computer_name = machine_name;
    2253          18 :         r.in.credentials = &credentials1;
    2254          18 :         r.out.return_credentials = &credentials2;
    2255             : 
    2256          18 :         netlogon_creds_random_challenge(&credentials1);
    2257             : 
    2258          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
    2259             :                 "ServerReqChallenge failed on b1");
    2260          18 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
    2261             : 
    2262          18 :         E_md4hash(plain_pass, mach_password.hash);
    2263             : 
    2264          18 :         a.in.server_name = NULL;
    2265          18 :         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
    2266          18 :         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
    2267          18 :         a.in.computer_name = machine_name;
    2268          18 :         a.in.negotiate_flags = &flags;
    2269          18 :         a.in.credentials = &credentials3;
    2270          18 :         a.out.return_credentials = &credentials3;
    2271          18 :         a.out.negotiate_flags = &flags;
    2272          18 :         a.out.rid = &rid;
    2273             : 
    2274          18 :         creds = netlogon_creds_client_init(tctx, a.in.account_name,
    2275             :                                            a.in.computer_name,
    2276          15 :                                            a.in.secure_channel_type,
    2277             :                                            &credentials1, &credentials2,
    2278             :                                            &mach_password, &credentials3,
    2279             :                                            flags);
    2280             : 
    2281          18 :         torture_assert(tctx, creds != NULL, "memory allocation");
    2282             : 
    2283          18 :         torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
    2284             : 
    2285          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
    2286             :                 "ServerAuthenticate3 failed on b2");
    2287          18 :         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
    2288          18 :         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
    2289             : 
    2290          15 :         return true;
    2291             : }
    2292             : 
    2293             : /*
    2294             :  * Test the re-use of the challenge is not possible on a third
    2295             :  * connection, after first using it second one.
    2296             :  */
    2297             : 
    2298          18 : static bool test_ServerReqChallengeReuseGlobal(struct torture_context *tctx,
    2299             :                                           struct dcerpc_pipe *p1,
    2300             :                                           struct cli_credentials *machine_credentials)
    2301             : {
    2302          18 :         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
    2303           3 :         struct netr_ServerReqChallenge r;
    2304           3 :         struct netr_ServerAuthenticate3 a;
    2305           3 :         struct netr_Credential credentials1, credentials2, credentials3;
    2306           3 :         struct netlogon_creds_CredentialState *creds;
    2307           3 :         struct samr_Password mach_password;
    2308           3 :         uint32_t rid;
    2309           3 :         const char *machine_name;
    2310           3 :         const char *plain_pass;
    2311          18 :         struct dcerpc_binding_handle *b1 = p1->binding_handle;
    2312          18 :         struct dcerpc_pipe *p2 = NULL;
    2313          18 :         struct dcerpc_binding_handle *b2 = NULL;
    2314          18 :         struct dcerpc_pipe *p3 = NULL;
    2315          18 :         struct dcerpc_binding_handle *b3 = NULL;
    2316             : 
    2317          18 :         machine_name = cli_credentials_get_workstation(machine_credentials);
    2318          18 :         torture_assert(tctx, machine_name != NULL, "machine_name");
    2319          18 :         plain_pass = cli_credentials_get_password(machine_credentials);
    2320          18 :         torture_assert(tctx, plain_pass != NULL, "plain_pass");
    2321             : 
    2322          18 :         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
    2323             : 
    2324          18 :         torture_assert_ntstatus_ok(tctx,
    2325             :                 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
    2326             :                                       &ndr_table_netlogon,
    2327             :                                       machine_credentials,
    2328             :                                       tctx->ev, tctx->lp_ctx),
    2329             :                 "dcerpc_pipe_connect_b failed");
    2330          18 :         b2 = p2->binding_handle;
    2331             : 
    2332          18 :         torture_assert_ntstatus_ok(tctx,
    2333             :                 dcerpc_pipe_connect_b(tctx, &p3, p1->binding,
    2334             :                                       &ndr_table_netlogon,
    2335             :                                       machine_credentials,
    2336             :                                       tctx->ev, tctx->lp_ctx),
    2337             :                 "dcerpc_pipe_connect_b failed");
    2338          18 :         b3 = p3->binding_handle;
    2339             : 
    2340          18 :         r.in.server_name = NULL;
    2341          18 :         r.in.computer_name = machine_name;
    2342          18 :         r.in.credentials = &credentials1;
    2343          18 :         r.out.return_credentials = &credentials2;
    2344             : 
    2345          18 :         netlogon_creds_random_challenge(&credentials1);
    2346             : 
    2347          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
    2348             :                 "ServerReqChallenge failed on b1");
    2349          18 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
    2350             : 
    2351          18 :         E_md4hash(plain_pass, mach_password.hash);
    2352             : 
    2353          18 :         a.in.server_name = NULL;
    2354          18 :         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
    2355          18 :         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
    2356          18 :         a.in.computer_name = machine_name;
    2357          18 :         a.in.negotiate_flags = &flags;
    2358          18 :         a.in.credentials = &credentials3;
    2359          18 :         a.out.return_credentials = &credentials3;
    2360          18 :         a.out.negotiate_flags = &flags;
    2361          18 :         a.out.rid = &rid;
    2362             : 
    2363          18 :         creds = netlogon_creds_client_init(tctx, a.in.account_name,
    2364             :                                            a.in.computer_name,
    2365          15 :                                            a.in.secure_channel_type,
    2366             :                                            &credentials1, &credentials2,
    2367             :                                            &mach_password, &credentials3,
    2368             :                                            flags);
    2369             : 
    2370          18 :         torture_assert(tctx, creds != NULL, "memory allocation");
    2371             : 
    2372          18 :         torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
    2373             : 
    2374          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
    2375             :                 "ServerAuthenticate3 failed on b2");
    2376          18 :         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
    2377          18 :         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
    2378             : 
    2379             :         /* We have to re-run this part */
    2380          21 :         creds = netlogon_creds_client_init(tctx, a.in.account_name,
    2381             :                                            a.in.computer_name,
    2382          18 :                                            a.in.secure_channel_type,
    2383             :                                            &credentials1, &credentials2,
    2384             :                                            &mach_password, &credentials3,
    2385             :                                            flags);
    2386             : 
    2387          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b3, tctx, &a),
    2388             :                 "ServerAuthenticate3 failed on b3");
    2389          18 :         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
    2390             :                                       "ServerAuthenticate3 should have failed on b3, due to credential reuse");
    2391          15 :         return true;
    2392             : }
    2393             : 
    2394             : /*
    2395             :  * Test if use of the per-pipe challenge will wipe out the globally cached challenge
    2396             :  */
    2397          18 : static bool test_ServerReqChallengeReuseGlobal2(struct torture_context *tctx,
    2398             :                                                 struct dcerpc_pipe *p1,
    2399             :                                                 struct cli_credentials *machine_credentials)
    2400             : {
    2401          18 :         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
    2402           3 :         struct netr_ServerReqChallenge r;
    2403           3 :         struct netr_ServerAuthenticate3 a;
    2404           3 :         struct netr_Credential credentials1, credentials2, credentials3;
    2405           3 :         struct netlogon_creds_CredentialState *creds;
    2406           3 :         struct samr_Password mach_password;
    2407           3 :         uint32_t rid;
    2408           3 :         const char *machine_name;
    2409           3 :         const char *plain_pass;
    2410          18 :         struct dcerpc_binding_handle *b1 = p1->binding_handle;
    2411          18 :         struct dcerpc_pipe *p2 = NULL;
    2412          18 :         struct dcerpc_binding_handle *b2 = NULL;
    2413             : 
    2414          18 :         machine_name = cli_credentials_get_workstation(machine_credentials);
    2415          18 :         torture_assert(tctx, machine_name != NULL, "machine_name");
    2416          18 :         plain_pass = cli_credentials_get_password(machine_credentials);
    2417          18 :         torture_assert(tctx, plain_pass != NULL, "plain_pass");
    2418             : 
    2419          18 :         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
    2420             : 
    2421          18 :         torture_assert_ntstatus_ok(tctx,
    2422             :                 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
    2423             :                                       &ndr_table_netlogon,
    2424             :                                       machine_credentials,
    2425             :                                       tctx->ev, tctx->lp_ctx),
    2426             :                 "dcerpc_pipe_connect_b failed");
    2427          18 :         b2 = p2->binding_handle;
    2428             : 
    2429          18 :         r.in.server_name = NULL;
    2430          18 :         r.in.computer_name = machine_name;
    2431          18 :         r.in.credentials = &credentials1;
    2432          18 :         r.out.return_credentials = &credentials2;
    2433             : 
    2434          18 :         netlogon_creds_random_challenge(&credentials1);
    2435             : 
    2436          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
    2437             :                 "ServerReqChallenge failed on b1");
    2438          18 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
    2439             : 
    2440          18 :         E_md4hash(plain_pass, mach_password.hash);
    2441             : 
    2442          18 :         a.in.server_name = NULL;
    2443          18 :         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
    2444          18 :         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
    2445          18 :         a.in.computer_name = machine_name;
    2446          18 :         a.in.negotiate_flags = &flags;
    2447          18 :         a.in.credentials = &credentials3;
    2448          18 :         a.out.return_credentials = &credentials3;
    2449          18 :         a.out.negotiate_flags = &flags;
    2450          18 :         a.out.rid = &rid;
    2451             : 
    2452          18 :         creds = netlogon_creds_client_init(tctx, a.in.account_name,
    2453             :                                            a.in.computer_name,
    2454          15 :                                            a.in.secure_channel_type,
    2455             :                                            &credentials1, &credentials2,
    2456             :                                            &mach_password, &credentials3,
    2457             :                                            flags);
    2458             : 
    2459          18 :         torture_assert(tctx, creds != NULL, "memory allocation");
    2460             : 
    2461          18 :         torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
    2462             : 
    2463          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
    2464             :                 "ServerAuthenticate3 failed on b");
    2465          18 :         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b");
    2466          18 :         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
    2467             : 
    2468             :         /* We have to re-run this part */
    2469          21 :         creds = netlogon_creds_client_init(tctx, a.in.account_name,
    2470             :                                            a.in.computer_name,
    2471          18 :                                            a.in.secure_channel_type,
    2472             :                                            &credentials1, &credentials2,
    2473             :                                            &mach_password, &credentials3,
    2474             :                                            flags);
    2475             : 
    2476          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
    2477             :                 "ServerAuthenticate3 failed on b2");
    2478          18 :         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
    2479             :                                       "ServerAuthenticate3 should have failed on b2, due to credential reuse");
    2480          15 :         return true;
    2481             : }
    2482             : 
    2483             : /*
    2484             :  * Test if use of the globally cached challenge will wipe out the
    2485             :  * per-pipe challenge
    2486             :  */
    2487          18 : static bool test_ServerReqChallengeReuseGlobal3(struct torture_context *tctx,
    2488             :                                                 struct dcerpc_pipe *p1,
    2489             :                                                 struct cli_credentials *machine_credentials)
    2490             : {
    2491          18 :         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
    2492           3 :         struct netr_ServerReqChallenge r;
    2493           3 :         struct netr_ServerAuthenticate3 a;
    2494           3 :         struct netr_Credential credentials1, credentials2, credentials3;
    2495           3 :         struct netlogon_creds_CredentialState *creds;
    2496           3 :         struct samr_Password mach_password;
    2497           3 :         uint32_t rid;
    2498           3 :         const char *machine_name;
    2499           3 :         const char *plain_pass;
    2500          18 :         struct dcerpc_binding_handle *b1 = p1->binding_handle;
    2501          18 :         struct dcerpc_pipe *p2 = NULL;
    2502          18 :         struct dcerpc_binding_handle *b2 = NULL;
    2503             : 
    2504          18 :         machine_name = cli_credentials_get_workstation(machine_credentials);
    2505          18 :         torture_assert(tctx, machine_name != NULL, "machine_name");
    2506          18 :         plain_pass = cli_credentials_get_password(machine_credentials);
    2507          18 :         torture_assert(tctx, plain_pass != NULL, "plain_pass");
    2508             : 
    2509          18 :         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
    2510             : 
    2511          18 :         torture_assert_ntstatus_ok(tctx,
    2512             :                 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
    2513             :                                       &ndr_table_netlogon,
    2514             :                                       machine_credentials,
    2515             :                                       tctx->ev, tctx->lp_ctx),
    2516             :                 "dcerpc_pipe_connect_b failed");
    2517          18 :         b2 = p2->binding_handle;
    2518             : 
    2519          18 :         r.in.server_name = NULL;
    2520          18 :         r.in.computer_name = machine_name;
    2521          18 :         r.in.credentials = &credentials1;
    2522          18 :         r.out.return_credentials = &credentials2;
    2523             : 
    2524          18 :         netlogon_creds_random_challenge(&credentials1);
    2525             : 
    2526          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
    2527             :                 "ServerReqChallenge failed on b1");
    2528          18 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
    2529             : 
    2530          18 :         E_md4hash(plain_pass, mach_password.hash);
    2531             : 
    2532          18 :         a.in.server_name = NULL;
    2533          18 :         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
    2534          18 :         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
    2535          18 :         a.in.computer_name = machine_name;
    2536          18 :         a.in.negotiate_flags = &flags;
    2537          18 :         a.in.credentials = &credentials3;
    2538          18 :         a.out.return_credentials = &credentials3;
    2539          18 :         a.out.negotiate_flags = &flags;
    2540          18 :         a.out.rid = &rid;
    2541             : 
    2542          18 :         creds = netlogon_creds_client_init(tctx, a.in.account_name,
    2543             :                                            a.in.computer_name,
    2544          15 :                                            a.in.secure_channel_type,
    2545             :                                            &credentials1, &credentials2,
    2546             :                                            &mach_password, &credentials3,
    2547             :                                            flags);
    2548             : 
    2549          18 :         torture_assert(tctx, creds != NULL, "memory allocation");
    2550             : 
    2551          18 :         torture_comment(tctx, "Testing ServerAuthenticate3 on b2\n");
    2552             : 
    2553          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
    2554             :                 "ServerAuthenticate3 failed on b2");
    2555          18 :         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b");
    2556          18 :         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
    2557             : 
    2558             :         /* We have to re-run this part */
    2559          21 :         creds = netlogon_creds_client_init(tctx, a.in.account_name,
    2560             :                                            a.in.computer_name,
    2561          18 :                                            a.in.secure_channel_type,
    2562             :                                            &credentials1, &credentials2,
    2563             :                                            &mach_password, &credentials3,
    2564             :                                            flags);
    2565             : 
    2566          18 :         torture_assert(tctx, creds != NULL, "memory allocation");
    2567             : 
    2568          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
    2569             :                 "ServerAuthenticate3 failed on b1");
    2570          18 :         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
    2571             :                                       "ServerAuthenticate3 should have failed on b1, due to credential reuse");
    2572           0 :         return true;
    2573             : }
    2574             : 
    2575             : /*
    2576             :  * Test if more than one globally cached challenge works
    2577             :  */
    2578          18 : static bool test_ServerReqChallengeReuseGlobal4(struct torture_context *tctx,
    2579             :                                                 struct dcerpc_pipe *p1,
    2580             :                                                 struct cli_credentials *machine_credentials)
    2581             : {
    2582          18 :         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
    2583           3 :         struct netr_ServerReqChallenge r;
    2584           3 :         struct netr_ServerAuthenticate3 a;
    2585           3 :         struct netr_Credential credentials1, credentials1_random,
    2586             :                 credentials2, credentials3, credentials_discard;
    2587           3 :         struct netlogon_creds_CredentialState *creds;
    2588           3 :         struct samr_Password mach_password;
    2589           3 :         uint32_t rid;
    2590           3 :         const char *machine_name;
    2591           3 :         const char *plain_pass;
    2592          18 :         struct dcerpc_binding_handle *b1 = p1->binding_handle;
    2593          18 :         struct dcerpc_pipe *p2 = NULL;
    2594          18 :         struct dcerpc_binding_handle *b2 = NULL;
    2595             : 
    2596          18 :         machine_name = cli_credentials_get_workstation(machine_credentials);
    2597          18 :         torture_assert(tctx, machine_name != NULL, "machine_name");
    2598          18 :         plain_pass = cli_credentials_get_password(machine_credentials);
    2599          18 :         torture_assert(tctx, plain_pass != NULL, "plain_pass");
    2600             : 
    2601          18 :         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
    2602             : 
    2603          18 :         torture_assert_ntstatus_ok(tctx,
    2604             :                 dcerpc_pipe_connect_b(tctx, &p2, p1->binding,
    2605             :                                       &ndr_table_netlogon,
    2606             :                                       machine_credentials,
    2607             :                                       tctx->ev, tctx->lp_ctx),
    2608             :                 "dcerpc_pipe_connect_b failed");
    2609          18 :         b2 = p2->binding_handle;
    2610             : 
    2611          18 :         r.in.server_name = NULL;
    2612          18 :         r.in.computer_name = "CHALTEST1";
    2613          18 :         r.in.credentials = &credentials1_random;
    2614          18 :         r.out.return_credentials = &credentials_discard;
    2615             : 
    2616          18 :         netlogon_creds_random_challenge(&credentials1_random);
    2617             : 
    2618          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
    2619             :                 "ServerReqChallenge failed on b1");
    2620          18 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
    2621             : 
    2622             :         /* Now ask for the actual client name */
    2623          18 :         r.in.server_name = NULL;
    2624          18 :         r.in.computer_name = machine_name;
    2625          18 :         r.in.credentials = &credentials1;
    2626          18 :         r.out.return_credentials = &credentials2;
    2627             : 
    2628          18 :         netlogon_creds_random_challenge(&credentials1);
    2629             : 
    2630          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
    2631             :                 "ServerReqChallenge failed on b1");
    2632          18 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
    2633             : 
    2634          18 :         r.in.server_name = NULL;
    2635          18 :         r.in.computer_name = "CHALTEST2";
    2636          18 :         r.in.credentials = &credentials1_random;
    2637          18 :         r.out.return_credentials = &credentials_discard;
    2638             : 
    2639          18 :         netlogon_creds_random_challenge(&credentials1_random);
    2640             : 
    2641          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b1, tctx, &r),
    2642             :                 "ServerReqChallenge failed on b1");
    2643          18 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
    2644             : 
    2645          18 :         E_md4hash(plain_pass, mach_password.hash);
    2646             : 
    2647          18 :         a.in.server_name = NULL;
    2648          18 :         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
    2649          18 :         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
    2650          18 :         a.in.computer_name = machine_name;
    2651          18 :         a.in.negotiate_flags = &flags;
    2652          18 :         a.in.credentials = &credentials3;
    2653          18 :         a.out.return_credentials = &credentials3;
    2654          18 :         a.out.negotiate_flags = &flags;
    2655          18 :         a.out.rid = &rid;
    2656             : 
    2657          18 :         creds = netlogon_creds_client_init(tctx, a.in.account_name,
    2658             :                                            a.in.computer_name,
    2659          15 :                                            a.in.secure_channel_type,
    2660             :                                            &credentials1, &credentials2,
    2661             :                                            &mach_password, &credentials3,
    2662             :                                            flags);
    2663             : 
    2664          18 :         torture_assert(tctx, creds != NULL, "memory allocation");
    2665             : 
    2666          18 :         torture_comment(tctx, "Testing ServerAuthenticate3 on b2 (must use global credentials)\n");
    2667             : 
    2668          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b2, tctx, &a),
    2669             :                 "ServerAuthenticate3 failed on b2");
    2670          18 :         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed on b2");
    2671          18 :         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
    2672             : 
    2673             :         /* We have to re-run this part */
    2674          21 :         creds = netlogon_creds_client_init(tctx, a.in.account_name,
    2675             :                                            a.in.computer_name,
    2676          18 :                                            a.in.secure_channel_type,
    2677             :                                            &credentials1, &credentials2,
    2678             :                                            &mach_password, &credentials3,
    2679             :                                            flags);
    2680             : 
    2681          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b1, tctx, &a),
    2682             :                 "ServerAuthenticate3 failed on b1");
    2683          18 :         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
    2684             :                                       "ServerAuthenticate3 should have failed on b1, due to credential reuse");
    2685          15 :         return true;
    2686             : }
    2687             : 
    2688          18 : static bool test_ServerReqChallengeReuse(struct torture_context *tctx,
    2689             :                                          struct dcerpc_pipe *p,
    2690             :                                          struct cli_credentials *machine_credentials)
    2691             : {
    2692          18 :         uint32_t flags = NETLOGON_NEG_AUTH2_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
    2693           3 :         struct netr_ServerReqChallenge r;
    2694           3 :         struct netr_ServerAuthenticate3 a;
    2695           3 :         struct netr_Credential credentials1, credentials2, credentials3;
    2696           3 :         struct netlogon_creds_CredentialState *creds;
    2697           3 :         struct samr_Password mach_password;
    2698           3 :         uint32_t rid;
    2699           3 :         const char *machine_name;
    2700           3 :         const char *plain_pass;
    2701          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
    2702             : 
    2703          18 :         machine_name = cli_credentials_get_workstation(machine_credentials);
    2704          18 :         torture_assert(tctx, machine_name != NULL, "machine_name");
    2705          18 :         plain_pass = cli_credentials_get_password(machine_credentials);
    2706          18 :         torture_assert(tctx, plain_pass != NULL, "plain_pass");
    2707             : 
    2708          18 :         torture_comment(tctx, "Testing ServerReqChallenge on b1\n");
    2709             : 
    2710          18 :         r.in.server_name = NULL;
    2711          18 :         r.in.computer_name = machine_name;
    2712          18 :         r.in.credentials = &credentials1;
    2713          18 :         r.out.return_credentials = &credentials2;
    2714             : 
    2715          18 :         netlogon_creds_random_challenge(&credentials1);
    2716             : 
    2717          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
    2718             :                 "ServerReqChallenge");
    2719          18 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed on b1");
    2720             : 
    2721          18 :         E_md4hash(plain_pass, mach_password.hash);
    2722             : 
    2723          18 :         a.in.server_name = NULL;
    2724          18 :         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
    2725          18 :         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
    2726          18 :         a.in.computer_name = machine_name;
    2727          18 :         a.in.negotiate_flags = &flags;
    2728          18 :         a.in.credentials = &credentials3;
    2729          18 :         a.out.return_credentials = &credentials3;
    2730          18 :         a.out.negotiate_flags = &flags;
    2731          18 :         a.out.rid = &rid;
    2732             : 
    2733          18 :         creds = netlogon_creds_client_init(tctx, a.in.account_name,
    2734             :                                            a.in.computer_name,
    2735          15 :                                            a.in.secure_channel_type,
    2736             :                                            &credentials1, &credentials2,
    2737             :                                            &mach_password, &credentials3,
    2738             :                                            flags);
    2739             : 
    2740          18 :         torture_assert(tctx, creds != NULL, "memory allocation");
    2741             : 
    2742          18 :         torture_comment(tctx, "Testing ServerAuthenticate3\n");
    2743             : 
    2744          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
    2745             :                 "ServerAuthenticate3 failed");
    2746          18 :         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed");
    2747          18 :         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
    2748             : 
    2749             :         /* We have to re-run this part */
    2750          21 :         creds = netlogon_creds_client_init(tctx, a.in.account_name,
    2751             :                                            a.in.computer_name,
    2752          18 :                                            a.in.secure_channel_type,
    2753             :                                            &credentials1, &credentials2,
    2754             :                                            &mach_password, &credentials3,
    2755             :                                            flags);
    2756             : 
    2757          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
    2758             :                 "ServerAuthenticate3 failed");
    2759          18 :         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
    2760             :                                       "ServerAuthenticate3 should have failed on b3, due to credential reuse");
    2761             : 
    2762          18 :         ZERO_STRUCT(credentials1.data);
    2763          18 :         ZERO_STRUCT(credentials2.data);
    2764          21 :         creds = netlogon_creds_client_init(tctx, a.in.account_name,
    2765             :                                            a.in.computer_name,
    2766          18 :                                            a.in.secure_channel_type,
    2767             :                                            &credentials1, &credentials2,
    2768             :                                            &mach_password, &credentials3,
    2769             :                                            flags);
    2770             : 
    2771          18 :         torture_assert(tctx, creds != NULL, "memory allocation");
    2772             : 
    2773          18 :         torture_comment(tctx, "Testing ServerAuthenticate3 with zero'ed challenge\n");
    2774             : 
    2775          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
    2776             :                 "ServerAuthenticate3 failed");
    2777          18 :         torture_assert_ntstatus_equal(tctx, a.out.result, NT_STATUS_ACCESS_DENIED,
    2778             :                                       "ServerAuthenticate3 should have failed on b3, due to credential reuse");
    2779          15 :         return true;
    2780             : }
    2781             : 
    2782           3 : static bool test_SamLogon_NULL_domain(struct torture_context *tctx,
    2783             :                                       struct dcerpc_pipe *p,
    2784             :                                       struct cli_credentials *credentials)
    2785             : {
    2786           0 :         struct netlogon_creds_CredentialState *creds;
    2787             : 
    2788           3 :         if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
    2789           0 :                 return false;
    2790             :         }
    2791             : 
    2792           3 :         return test_netlogon_ops_args(p, tctx, credentials, creds, true);
    2793             : }
    2794             : 
    2795             : /* we remember the sequence numbers so we can easily do a DatabaseDelta */
    2796             : static uint64_t sequence_nums[3];
    2797             : 
    2798             : /*
    2799             :   try a netlogon DatabaseSync
    2800             : */
    2801          18 : static bool test_DatabaseSync(struct torture_context *tctx,
    2802             :                               struct dcerpc_pipe *p,
    2803             :                               struct cli_credentials *machine_credentials)
    2804             : {
    2805           3 :         struct netr_DatabaseSync r;
    2806           3 :         struct netlogon_creds_CredentialState *creds;
    2807          18 :         const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
    2808           3 :         int i;
    2809          18 :         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
    2810           3 :         struct netr_Authenticator credential, return_authenticator;
    2811          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
    2812             : 
    2813          18 :         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
    2814           0 :                 return false;
    2815             :         }
    2816             : 
    2817          18 :         ZERO_STRUCT(return_authenticator);
    2818             : 
    2819          18 :         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    2820          18 :         r.in.computername = TEST_MACHINE_NAME;
    2821          18 :         r.in.preferredmaximumlength = (uint32_t)-1;
    2822          18 :         r.in.return_authenticator = &return_authenticator;
    2823          18 :         r.out.delta_enum_array = &delta_enum_array;
    2824          18 :         r.out.return_authenticator = &return_authenticator;
    2825             : 
    2826          18 :         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
    2827             : 
    2828          18 :                 uint32_t sync_context = 0;
    2829             : 
    2830          18 :                 r.in.database_id = database_ids[i];
    2831          18 :                 r.in.sync_context = &sync_context;
    2832          18 :                 r.out.sync_context = &sync_context;
    2833             : 
    2834          18 :                 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
    2835             : 
    2836           3 :                 do {
    2837          18 :                         netlogon_creds_client_authenticator(creds, &credential);
    2838             : 
    2839          18 :                         r.in.credential = &credential;
    2840             : 
    2841          18 :                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync_r(b, tctx, &r),
    2842             :                                 "DatabaseSync failed");
    2843          18 :                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
    2844           0 :                             break;
    2845             : 
    2846             :                         /* Native mode servers don't do this */
    2847          18 :                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
    2848           0 :                                 return true;
    2849             :                         }
    2850          18 :                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync");
    2851             : 
    2852           0 :                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
    2853           0 :                                 torture_comment(tctx, "Credential chaining failed\n");
    2854             :                         }
    2855             : 
    2856           0 :                         if (delta_enum_array &&
    2857           0 :                             delta_enum_array->num_deltas > 0 &&
    2858           0 :                             delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
    2859           0 :                             delta_enum_array->delta_enum[0].delta_union.domain) {
    2860           0 :                                 sequence_nums[r.in.database_id] =
    2861           0 :                                         delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
    2862           0 :                                 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
    2863           0 :                                        r.in.database_id,
    2864           0 :                                        (unsigned long long)sequence_nums[r.in.database_id]);
    2865             :                         }
    2866           0 :                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
    2867             :         }
    2868             : 
    2869           0 :         return true;
    2870             : }
    2871             : 
    2872             : 
    2873             : /*
    2874             :   try a netlogon DatabaseDeltas
    2875             : */
    2876          18 : static bool test_DatabaseDeltas(struct torture_context *tctx,
    2877             :                                 struct dcerpc_pipe *p,
    2878             :                                 struct cli_credentials *machine_credentials)
    2879             : {
    2880           3 :         struct netr_DatabaseDeltas r;
    2881           3 :         struct netlogon_creds_CredentialState *creds;
    2882           3 :         struct netr_Authenticator credential;
    2883           3 :         struct netr_Authenticator return_authenticator;
    2884          18 :         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
    2885          18 :         const uint32_t database_ids[] = {0, 1, 2};
    2886           3 :         int i;
    2887          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
    2888             : 
    2889          18 :         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
    2890           0 :                 return false;
    2891             :         }
    2892             : 
    2893          18 :         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    2894          18 :         r.in.computername = TEST_MACHINE_NAME;
    2895          18 :         r.in.preferredmaximumlength = (uint32_t)-1;
    2896          18 :         ZERO_STRUCT(r.in.return_authenticator);
    2897          18 :         r.out.return_authenticator = &return_authenticator;
    2898          18 :         r.out.delta_enum_array = &delta_enum_array;
    2899             : 
    2900          72 :         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
    2901          54 :                 r.in.database_id = database_ids[i];
    2902          54 :                 r.in.sequence_num = &sequence_nums[r.in.database_id];
    2903             : 
    2904          54 :                 if (*r.in.sequence_num == 0) continue;
    2905             : 
    2906           0 :                 *r.in.sequence_num -= 1;
    2907             : 
    2908           0 :                 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n",
    2909           0 :                        r.in.database_id, (unsigned long long)*r.in.sequence_num);
    2910             : 
    2911           0 :                 do {
    2912           0 :                         netlogon_creds_client_authenticator(creds, &credential);
    2913             : 
    2914           0 :                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseDeltas_r(b, tctx, &r),
    2915             :                                 "DatabaseDeltas failed");
    2916           0 :                         if (NT_STATUS_EQUAL(r.out.result,
    2917             :                                              NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
    2918           0 :                                 torture_comment(tctx, "not considering %s to be an error\n",
    2919             :                                        nt_errstr(r.out.result));
    2920           0 :                                 return true;
    2921             :                         }
    2922           0 :                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
    2923           0 :                             break;
    2924             : 
    2925           0 :                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseDeltas");
    2926             : 
    2927           0 :                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
    2928           0 :                                 torture_comment(tctx, "Credential chaining failed\n");
    2929             :                         }
    2930             : 
    2931           0 :                         (*r.in.sequence_num)++;
    2932           0 :                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
    2933             :         }
    2934             : 
    2935          15 :         return true;
    2936             : }
    2937             : 
    2938          18 : static bool test_DatabaseRedo(struct torture_context *tctx,
    2939             :                               struct dcerpc_pipe *p,
    2940             :                               struct cli_credentials *machine_credentials)
    2941             : {
    2942           3 :         struct netr_DatabaseRedo r;
    2943           3 :         struct netlogon_creds_CredentialState *creds;
    2944           3 :         struct netr_Authenticator credential;
    2945           3 :         struct netr_Authenticator return_authenticator;
    2946          18 :         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
    2947           3 :         struct netr_ChangeLogEntry e;
    2948           3 :         struct dom_sid null_sid, *sid;
    2949           3 :         int i,d;
    2950          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
    2951             : 
    2952          18 :         ZERO_STRUCT(null_sid);
    2953             : 
    2954          18 :         sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
    2955             : 
    2956             :         {
    2957             : 
    2958           3 :         struct {
    2959             :                 uint32_t rid;
    2960             :                 uint16_t flags;
    2961             :                 uint8_t db_index;
    2962             :                 uint8_t delta_type;
    2963             :                 struct dom_sid sid;
    2964             :                 const char *name;
    2965             :                 NTSTATUS expected_error;
    2966             :                 uint32_t expected_num_results;
    2967             :                 uint8_t expected_delta_type_1;
    2968             :                 uint8_t expected_delta_type_2;
    2969             :                 const char *comment;
    2970         144 :         } changes[] = {
    2971             : 
    2972             :                 /* SAM_DATABASE_DOMAIN */
    2973             : 
    2974             :                 {
    2975             :                         .rid                    = 0,
    2976             :                         .flags                  = 0,
    2977             :                         .db_index               = SAM_DATABASE_DOMAIN,
    2978             :                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
    2979             :                         .sid                    = null_sid,
    2980             :                         .name                   = NULL,
    2981             :                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
    2982             :                         .expected_num_results   = 0,
    2983             :                         .comment                = "NETR_DELTA_MODIFY_COUNT"
    2984             :                 },
    2985             :                 {
    2986             :                         .rid                    = 0,
    2987             :                         .flags                  = 0,
    2988             :                         .db_index               = SAM_DATABASE_DOMAIN,
    2989             :                         .delta_type             = 0,
    2990             :                         .sid                    = null_sid,
    2991             :                         .name                   = NULL,
    2992             :                         .expected_error         = NT_STATUS_OK,
    2993             :                         .expected_num_results   = 1,
    2994             :                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
    2995             :                         .comment                = "NULL DELTA"
    2996             :                 },
    2997             :                 {
    2998             :                         .rid                    = 0,
    2999             :                         .flags                  = 0,
    3000             :                         .db_index               = SAM_DATABASE_DOMAIN,
    3001             :                         .delta_type             = NETR_DELTA_DOMAIN,
    3002             :                         .sid                    = null_sid,
    3003             :                         .name                   = NULL,
    3004             :                         .expected_error         = NT_STATUS_OK,
    3005             :                         .expected_num_results   = 1,
    3006             :                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
    3007             :                         .comment                = "NETR_DELTA_DOMAIN"
    3008             :                 },
    3009             :                 {
    3010             :                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
    3011             :                         .flags                  = 0,
    3012             :                         .db_index               = SAM_DATABASE_DOMAIN,
    3013             :                         .delta_type             = NETR_DELTA_USER,
    3014             :                         .sid                    = null_sid,
    3015             :                         .name                   = NULL,
    3016             :                         .expected_error         = NT_STATUS_OK,
    3017             :                         .expected_num_results   = 1,
    3018             :                         .expected_delta_type_1  = NETR_DELTA_USER,
    3019             :                         .comment                = "NETR_DELTA_USER by rid 500"
    3020             :                 },
    3021             :                 {
    3022             :                         .rid                    = DOMAIN_RID_GUEST,
    3023             :                         .flags                  = 0,
    3024             :                         .db_index               = SAM_DATABASE_DOMAIN,
    3025             :                         .delta_type             = NETR_DELTA_USER,
    3026             :                         .sid                    = null_sid,
    3027             :                         .name                   = NULL,
    3028             :                         .expected_error         = NT_STATUS_OK,
    3029             :                         .expected_num_results   = 1,
    3030             :                         .expected_delta_type_1  = NETR_DELTA_USER,
    3031             :                         .comment                = "NETR_DELTA_USER by rid 501"
    3032             :                 },
    3033             :                 {
    3034             :                         .rid                    = 0,
    3035             :                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
    3036             :                         .db_index               = SAM_DATABASE_DOMAIN,
    3037             :                         .delta_type             = NETR_DELTA_USER,
    3038             :                         .sid                    = *sid,
    3039             :                         .name                   = NULL,
    3040             :                         .expected_error         = NT_STATUS_OK,
    3041             :                         .expected_num_results   = 1,
    3042             :                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
    3043             :                         .comment                = "NETR_DELTA_USER by sid and flags"
    3044             :                 },
    3045             :                 {
    3046             :                         .rid                    = 0,
    3047             :                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
    3048             :                         .db_index               = SAM_DATABASE_DOMAIN,
    3049             :                         .delta_type             = NETR_DELTA_USER,
    3050             :                         .sid                    = null_sid,
    3051             :                         .name                   = NULL,
    3052             :                         .expected_error         = NT_STATUS_OK,
    3053             :                         .expected_num_results   = 1,
    3054             :                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
    3055             :                         .comment                = "NETR_DELTA_USER by null_sid and flags"
    3056             :                 },
    3057             :                 {
    3058             :                         .rid                    = 0,
    3059             :                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
    3060             :                         .db_index               = SAM_DATABASE_DOMAIN,
    3061             :                         .delta_type             = NETR_DELTA_USER,
    3062             :                         .sid                    = null_sid,
    3063             :                         .name                   = "administrator",
    3064             :                         .expected_error         = NT_STATUS_OK,
    3065             :                         .expected_num_results   = 1,
    3066             :                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
    3067             :                         .comment                = "NETR_DELTA_USER by name 'administrator'"
    3068             :                 },
    3069             :                 {
    3070             :                         .rid                    = DOMAIN_RID_ADMINS,
    3071             :                         .flags                  = 0,
    3072             :                         .db_index               = SAM_DATABASE_DOMAIN,
    3073             :                         .delta_type             = NETR_DELTA_GROUP,
    3074             :                         .sid                    = null_sid,
    3075             :                         .name                   = NULL,
    3076             :                         .expected_error         = NT_STATUS_OK,
    3077             :                         .expected_num_results   = 2,
    3078             :                         .expected_delta_type_1  = NETR_DELTA_GROUP,
    3079             :                         .expected_delta_type_2  = NETR_DELTA_GROUP_MEMBER,
    3080             :                         .comment                = "NETR_DELTA_GROUP by rid 512"
    3081             :                 },
    3082             :                 {
    3083             :                         .rid                    = DOMAIN_RID_ADMINS,
    3084             :                         .flags                  = 0,
    3085             :                         .db_index               = SAM_DATABASE_DOMAIN,
    3086             :                         .delta_type             = NETR_DELTA_GROUP_MEMBER,
    3087             :                         .sid                    = null_sid,
    3088             :                         .name                   = NULL,
    3089             :                         .expected_error         = NT_STATUS_OK,
    3090             :                         .expected_num_results   = 2,
    3091             :                         .expected_delta_type_1  = NETR_DELTA_GROUP,
    3092             :                         .expected_delta_type_2  = NETR_DELTA_GROUP_MEMBER,
    3093             :                         .comment                = "NETR_DELTA_GROUP_MEMBER by rid 512"
    3094             :                 },
    3095             : 
    3096             : 
    3097             :                 /* SAM_DATABASE_BUILTIN */
    3098             : 
    3099             :                 {
    3100             :                         .rid                    = 0,
    3101             :                         .flags                  = 0,
    3102             :                         .db_index               = SAM_DATABASE_BUILTIN,
    3103             :                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
    3104             :                         .sid                    = null_sid,
    3105             :                         .name                   = NULL,
    3106             :                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
    3107             :                         .expected_num_results   = 0,
    3108             :                         .comment                = "NETR_DELTA_MODIFY_COUNT"
    3109             :                 },
    3110             :                 {
    3111             :                         .rid                    = 0,
    3112             :                         .flags                  = 0,
    3113             :                         .db_index               = SAM_DATABASE_BUILTIN,
    3114             :                         .delta_type             = NETR_DELTA_DOMAIN,
    3115             :                         .sid                    = null_sid,
    3116             :                         .name                   = NULL,
    3117             :                         .expected_error         = NT_STATUS_OK,
    3118             :                         .expected_num_results   = 1,
    3119             :                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
    3120             :                         .comment                = "NETR_DELTA_DOMAIN"
    3121             :                 },
    3122             :                 {
    3123             :                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
    3124             :                         .flags                  = 0,
    3125             :                         .db_index               = SAM_DATABASE_BUILTIN,
    3126             :                         .delta_type             = NETR_DELTA_USER,
    3127             :                         .sid                    = null_sid,
    3128             :                         .name                   = NULL,
    3129             :                         .expected_error         = NT_STATUS_OK,
    3130             :                         .expected_num_results   = 1,
    3131             :                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
    3132             :                         .comment                = "NETR_DELTA_USER by rid 500"
    3133             :                 },
    3134             :                 {
    3135             :                         .rid                    = 0,
    3136             :                         .flags                  = 0,
    3137             :                         .db_index               = SAM_DATABASE_BUILTIN,
    3138             :                         .delta_type             = NETR_DELTA_USER,
    3139             :                         .sid                    = null_sid,
    3140             :                         .name                   = NULL,
    3141             :                         .expected_error         = NT_STATUS_OK,
    3142             :                         .expected_num_results   = 1,
    3143             :                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
    3144             :                         .comment                = "NETR_DELTA_USER"
    3145             :                 },
    3146             :                 {
    3147             :                         .rid                    = 544,
    3148             :                         .flags                  = 0,
    3149             :                         .db_index               = SAM_DATABASE_BUILTIN,
    3150             :                         .delta_type             = NETR_DELTA_ALIAS,
    3151             :                         .sid                    = null_sid,
    3152             :                         .name                   = NULL,
    3153             :                         .expected_error         = NT_STATUS_OK,
    3154             :                         .expected_num_results   = 2,
    3155             :                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
    3156             :                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
    3157             :                         .comment                = "NETR_DELTA_ALIAS by rid 544"
    3158             :                 },
    3159             :                 {
    3160             :                         .rid                    = 544,
    3161             :                         .flags                  = 0,
    3162             :                         .db_index               = SAM_DATABASE_BUILTIN,
    3163             :                         .delta_type             = NETR_DELTA_ALIAS_MEMBER,
    3164             :                         .sid                    = null_sid,
    3165             :                         .name                   = NULL,
    3166             :                         .expected_error         = NT_STATUS_OK,
    3167             :                         .expected_num_results   = 2,
    3168             :                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
    3169             :                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
    3170             :                         .comment                = "NETR_DELTA_ALIAS_MEMBER by rid 544"
    3171             :                 },
    3172             :                 {
    3173             :                         .rid                    = 544,
    3174             :                         .flags                  = 0,
    3175             :                         .db_index               = SAM_DATABASE_BUILTIN,
    3176             :                         .delta_type             = 0,
    3177             :                         .sid                    = null_sid,
    3178             :                         .name                   = NULL,
    3179             :                         .expected_error         = NT_STATUS_OK,
    3180             :                         .expected_num_results   = 1,
    3181             :                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
    3182             :                         .comment                = "NULL DELTA by rid 544"
    3183             :                 },
    3184             :                 {
    3185             :                         .rid                    = 544,
    3186             :                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
    3187             :                         .db_index               = SAM_DATABASE_BUILTIN,
    3188             :                         .delta_type             = 0,
    3189          18 :                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
    3190             :                         .name                   = NULL,
    3191             :                         .expected_error         = NT_STATUS_OK,
    3192             :                         .expected_num_results   = 1,
    3193             :                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
    3194             :                         .comment                = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
    3195             :                 },
    3196             :                 {
    3197             :                         .rid                    = 544,
    3198             :                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
    3199             :                         .db_index               = SAM_DATABASE_BUILTIN,
    3200             :                         .delta_type             = NETR_DELTA_ALIAS,
    3201          18 :                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
    3202             :                         .name                   = NULL,
    3203             :                         .expected_error         = NT_STATUS_OK,
    3204             :                         .expected_num_results   = 2,
    3205             :                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
    3206             :                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
    3207             :                         .comment                = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
    3208             :                 },
    3209             :                 {
    3210             :                         .rid                    = 0,
    3211             :                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
    3212             :                         .db_index               = SAM_DATABASE_BUILTIN,
    3213             :                         .delta_type             = NETR_DELTA_ALIAS,
    3214          18 :                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
    3215             :                         .name                   = NULL,
    3216             :                         .expected_error         = NT_STATUS_OK,
    3217             :                         .expected_num_results   = 1,
    3218             :                         .expected_delta_type_1  = NETR_DELTA_DELETE_ALIAS,
    3219             :                         .comment                = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
    3220             :                 },
    3221             : 
    3222             :                 /* SAM_DATABASE_PRIVS */
    3223             : 
    3224             :                 {
    3225             :                         .rid                    = 0,
    3226             :                         .flags                  = 0,
    3227             :                         .db_index               = SAM_DATABASE_PRIVS,
    3228             :                         .delta_type             = 0,
    3229             :                         .sid                    = null_sid,
    3230             :                         .name                   = NULL,
    3231             :                         .expected_error         = NT_STATUS_ACCESS_DENIED,
    3232             :                         .expected_num_results   = 0,
    3233             :                         .comment                = "NULL DELTA"
    3234             :                 },
    3235             :                 {
    3236             :                         .rid                    = 0,
    3237             :                         .flags                  = 0,
    3238             :                         .db_index               = SAM_DATABASE_PRIVS,
    3239             :                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
    3240             :                         .sid                    = null_sid,
    3241             :                         .name                   = NULL,
    3242             :                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
    3243             :                         .expected_num_results   = 0,
    3244             :                         .comment                = "NETR_DELTA_MODIFY_COUNT"
    3245             :                 },
    3246             :                 {
    3247             :                         .rid                    = 0,
    3248             :                         .flags                  = 0,
    3249             :                         .db_index               = SAM_DATABASE_PRIVS,
    3250             :                         .delta_type             = NETR_DELTA_POLICY,
    3251             :                         .sid                    = null_sid,
    3252             :                         .name                   = NULL,
    3253             :                         .expected_error         = NT_STATUS_OK,
    3254             :                         .expected_num_results   = 1,
    3255             :                         .expected_delta_type_1  = NETR_DELTA_POLICY,
    3256             :                         .comment                = "NETR_DELTA_POLICY"
    3257             :                 },
    3258             :                 {
    3259             :                         .rid                    = 0,
    3260             :                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
    3261             :                         .db_index               = SAM_DATABASE_PRIVS,
    3262             :                         .delta_type             = NETR_DELTA_POLICY,
    3263             :                         .sid                    = null_sid,
    3264             :                         .name                   = NULL,
    3265             :                         .expected_error         = NT_STATUS_OK,
    3266             :                         .expected_num_results   = 1,
    3267             :                         .expected_delta_type_1  = NETR_DELTA_POLICY,
    3268             :                         .comment                = "NETR_DELTA_POLICY by null sid and flags"
    3269             :                 },
    3270             :                 {
    3271             :                         .rid                    = 0,
    3272             :                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
    3273             :                         .db_index               = SAM_DATABASE_PRIVS,
    3274             :                         .delta_type             = NETR_DELTA_POLICY,
    3275          18 :                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
    3276             :                         .name                   = NULL,
    3277             :                         .expected_error         = NT_STATUS_OK,
    3278             :                         .expected_num_results   = 1,
    3279             :                         .expected_delta_type_1  = NETR_DELTA_POLICY,
    3280             :                         .comment                = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
    3281             :                 },
    3282             :                 {
    3283             :                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
    3284             :                         .flags                  = 0,
    3285             :                         .db_index               = SAM_DATABASE_PRIVS,
    3286             :                         .delta_type             = NETR_DELTA_ACCOUNT,
    3287             :                         .sid                    = null_sid,
    3288             :                         .name                   = NULL,
    3289             :                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
    3290             :                         .expected_num_results   = 0,
    3291             :                         .comment                = "NETR_DELTA_ACCOUNT by rid 500"
    3292             :                 },
    3293             :                 {
    3294             :                         .rid                    = 0,
    3295             :                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
    3296             :                         .db_index               = SAM_DATABASE_PRIVS,
    3297             :                         .delta_type             = NETR_DELTA_ACCOUNT,
    3298          18 :                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
    3299             :                         .name                   = NULL,
    3300             :                         .expected_error         = NT_STATUS_OK,
    3301             :                         .expected_num_results   = 1,
    3302             :                         .expected_delta_type_1  = NETR_DELTA_ACCOUNT,
    3303             :                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
    3304             :                 },
    3305             :                 {
    3306             :                         .rid                    = 0,
    3307             :                         .flags                  = NETR_CHANGELOG_SID_INCLUDED |
    3308             :                                                   NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
    3309             :                         .db_index               = SAM_DATABASE_PRIVS,
    3310             :                         .delta_type             = NETR_DELTA_ACCOUNT,
    3311          18 :                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
    3312             :                         .name                   = NULL,
    3313             :                         .expected_error         = NT_STATUS_OK,
    3314             :                         .expected_num_results   = 1,
    3315             :                         .expected_delta_type_1  = NETR_DELTA_ACCOUNT,
    3316             :                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
    3317             :                 },
    3318             :                 {
    3319             :                         .rid                    = 0,
    3320             :                         .flags                  = NETR_CHANGELOG_SID_INCLUDED |
    3321             :                                                   NETR_CHANGELOG_NAME_INCLUDED,
    3322             :                         .db_index               = SAM_DATABASE_PRIVS,
    3323             :                         .delta_type             = NETR_DELTA_ACCOUNT,
    3324          18 :                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
    3325             :                         .name                   = NULL,
    3326             :                         .expected_error         = NT_STATUS_INVALID_PARAMETER,
    3327             :                         .expected_num_results   = 0,
    3328             :                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
    3329             :                 },
    3330             :                 {
    3331             :                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
    3332             :                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
    3333             :                         .db_index               = SAM_DATABASE_PRIVS,
    3334             :                         .delta_type             = NETR_DELTA_ACCOUNT,
    3335             :                         .sid                    = *sid,
    3336             :                         .name                   = NULL,
    3337             :                         .expected_error         = NT_STATUS_OK,
    3338             :                         .expected_num_results   = 1,
    3339             :                         .expected_delta_type_1  = NETR_DELTA_DELETE_ACCOUNT,
    3340             :                         .comment                = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
    3341             :                 },
    3342             :                 {
    3343             :                         .rid                    = 0,
    3344             :                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
    3345             :                         .db_index               = SAM_DATABASE_PRIVS,
    3346             :                         .delta_type             = NETR_DELTA_SECRET,
    3347             :                         .sid                    = null_sid,
    3348             :                         .name                   = "IsurelydontexistIhope",
    3349             :                         .expected_error         = NT_STATUS_OK,
    3350             :                         .expected_num_results   = 1,
    3351             :                         .expected_delta_type_1  = NETR_DELTA_DELETE_SECRET,
    3352             :                         .comment                = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
    3353             :                 },
    3354             :                 {
    3355             :                         .rid                    = 0,
    3356             :                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
    3357             :                         .db_index               = SAM_DATABASE_PRIVS,
    3358             :                         .delta_type             = NETR_DELTA_SECRET,
    3359             :                         .sid                    = null_sid,
    3360             :                         .name                   = "G$BCKUPKEY_P",
    3361             :                         .expected_error         = NT_STATUS_OK,
    3362             :                         .expected_num_results   = 1,
    3363             :                         .expected_delta_type_1  = NETR_DELTA_SECRET,
    3364             :                         .comment                = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
    3365             :                 }
    3366             :         };
    3367             : 
    3368          18 :         ZERO_STRUCT(return_authenticator);
    3369             : 
    3370          18 :         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    3371          18 :         r.in.computername = TEST_MACHINE_NAME;
    3372          18 :         r.in.return_authenticator = &return_authenticator;
    3373          18 :         r.out.return_authenticator = &return_authenticator;
    3374          18 :         r.out.delta_enum_array = &delta_enum_array;
    3375             : 
    3376          18 :         for (d=0; d<3; d++) {
    3377          18 :                 const char *database = NULL;
    3378             : 
    3379          18 :                 switch (d) {
    3380          15 :                 case 0:
    3381          15 :                         database = "SAM";
    3382          15 :                         break;
    3383           0 :                 case 1:
    3384           0 :                         database = "BUILTIN";
    3385           0 :                         break;
    3386           0 :                 case 2:
    3387           0 :                         database = "LSA";
    3388           0 :                         break;
    3389           0 :                 default:
    3390           0 :                         break;
    3391             :                 }
    3392             : 
    3393          18 :                 torture_comment(tctx, "Testing DatabaseRedo\n");
    3394             : 
    3395          18 :                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
    3396          18 :                         return false;
    3397             :                 }
    3398             : 
    3399          18 :                 for (i=0;i<ARRAY_SIZE(changes);i++) {
    3400             : 
    3401          18 :                         if (d != changes[i].db_index) {
    3402           0 :                                 continue;
    3403             :                         }
    3404             : 
    3405          18 :                         netlogon_creds_client_authenticator(creds, &credential);
    3406             : 
    3407          18 :                         r.in.credential = &credential;
    3408             : 
    3409          18 :                         e.serial_number1        = 0;
    3410          18 :                         e.serial_number2        = 0;
    3411          18 :                         e.object_rid            = changes[i].rid;
    3412          18 :                         e.flags                 = changes[i].flags;
    3413          18 :                         e.db_index              = changes[i].db_index;
    3414          18 :                         e.delta_type            = changes[i].delta_type;
    3415             : 
    3416          18 :                         switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
    3417           0 :                         case NETR_CHANGELOG_SID_INCLUDED:
    3418           0 :                                 e.object.object_sid             = changes[i].sid;
    3419           0 :                                 break;
    3420           0 :                         case NETR_CHANGELOG_NAME_INCLUDED:
    3421           0 :                                 e.object.object_name            = changes[i].name;
    3422           0 :                                 break;
    3423          15 :                         default:
    3424          15 :                                 break;
    3425             :                         }
    3426             : 
    3427          18 :                         r.in.change_log_entry = e;
    3428             : 
    3429          18 :                         torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
    3430             :                                 database, changes[i].comment);
    3431             : 
    3432          18 :                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseRedo_r(b, tctx, &r),
    3433             :                                 "DatabaseRedo failed");
    3434           0 :                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
    3435           0 :                                 return true;
    3436             :                         }
    3437             : 
    3438           0 :                         torture_assert_ntstatus_equal(tctx, r.out.result, changes[i].expected_error, changes[i].comment);
    3439           0 :                         if (delta_enum_array) {
    3440           0 :                                 torture_assert_int_equal(tctx,
    3441             :                                         delta_enum_array->num_deltas,
    3442             :                                         changes[i].expected_num_results,
    3443             :                                         changes[i].comment);
    3444           0 :                                 if (delta_enum_array->num_deltas > 0) {
    3445           0 :                                         torture_assert_int_equal(tctx,
    3446             :                                                 delta_enum_array->delta_enum[0].delta_type,
    3447             :                                                 changes[i].expected_delta_type_1,
    3448             :                                                 changes[i].comment);
    3449             :                                 }
    3450           0 :                                 if (delta_enum_array->num_deltas > 1) {
    3451           0 :                                         torture_assert_int_equal(tctx,
    3452             :                                                 delta_enum_array->delta_enum[1].delta_type,
    3453             :                                                 changes[i].expected_delta_type_2,
    3454             :                                                 changes[i].comment);
    3455             :                                 }
    3456             :                         }
    3457             : 
    3458           0 :                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
    3459           0 :                                 torture_comment(tctx, "Credential chaining failed\n");
    3460           0 :                                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
    3461           0 :                                         return false;
    3462             :                                 }
    3463             :                         }
    3464             :                 }
    3465             :         }
    3466             :         }
    3467             : 
    3468           0 :         return true;
    3469             : }
    3470             : 
    3471             : /*
    3472             :   try a netlogon AccountDeltas
    3473             : */
    3474          18 : static bool test_AccountDeltas(struct torture_context *tctx,
    3475             :                                struct dcerpc_pipe *p,
    3476             :                                struct cli_credentials *machine_credentials)
    3477             : {
    3478           3 :         struct netr_AccountDeltas r;
    3479           3 :         struct netlogon_creds_CredentialState *creds;
    3480             : 
    3481           3 :         struct netr_AccountBuffer buffer;
    3482          18 :         uint32_t count_returned = 0;
    3483          18 :         uint32_t total_entries = 0;
    3484           3 :         struct netr_UAS_INFO_0 recordid;
    3485           3 :         struct netr_Authenticator return_authenticator;
    3486          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
    3487             : 
    3488          18 :         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
    3489           0 :                 return false;
    3490             :         }
    3491             : 
    3492          18 :         ZERO_STRUCT(return_authenticator);
    3493             : 
    3494          18 :         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    3495          18 :         r.in.computername = TEST_MACHINE_NAME;
    3496          18 :         r.in.return_authenticator = &return_authenticator;
    3497          18 :         netlogon_creds_client_authenticator(creds, &r.in.credential);
    3498          18 :         ZERO_STRUCT(r.in.uas);
    3499          18 :         r.in.count=10;
    3500          18 :         r.in.level=0;
    3501          18 :         r.in.buffersize=100;
    3502          18 :         r.out.buffer = &buffer;
    3503          18 :         r.out.count_returned = &count_returned;
    3504          18 :         r.out.total_entries = &total_entries;
    3505          18 :         r.out.recordid = &recordid;
    3506          18 :         r.out.return_authenticator = &return_authenticator;
    3507             : 
    3508             :         /* w2k3 returns "NOT IMPLEMENTED" for this call */
    3509          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountDeltas_r(b, tctx, &r),
    3510             :                 "AccountDeltas failed");
    3511          18 :         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
    3512             : 
    3513          15 :         return true;
    3514             : }
    3515             : 
    3516             : /*
    3517             :   try a netlogon AccountSync
    3518             : */
    3519          18 : static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
    3520             :                              struct cli_credentials *machine_credentials)
    3521             : {
    3522           3 :         struct netr_AccountSync r;
    3523           3 :         struct netlogon_creds_CredentialState *creds;
    3524             : 
    3525           3 :         struct netr_AccountBuffer buffer;
    3526          18 :         uint32_t count_returned = 0;
    3527          18 :         uint32_t total_entries = 0;
    3528          18 :         uint32_t next_reference = 0;
    3529           3 :         struct netr_UAS_INFO_0 recordid;
    3530           3 :         struct netr_Authenticator return_authenticator;
    3531          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
    3532             : 
    3533          18 :         ZERO_STRUCT(recordid);
    3534          18 :         ZERO_STRUCT(return_authenticator);
    3535             : 
    3536          18 :         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
    3537           0 :                 return false;
    3538             :         }
    3539             : 
    3540          18 :         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    3541          18 :         r.in.computername = TEST_MACHINE_NAME;
    3542          18 :         r.in.return_authenticator = &return_authenticator;
    3543          18 :         netlogon_creds_client_authenticator(creds, &r.in.credential);
    3544          18 :         r.in.recordid = &recordid;
    3545          18 :         r.in.reference=0;
    3546          18 :         r.in.level=0;
    3547          18 :         r.in.buffersize=100;
    3548          18 :         r.out.buffer = &buffer;
    3549          18 :         r.out.count_returned = &count_returned;
    3550          18 :         r.out.total_entries = &total_entries;
    3551          18 :         r.out.next_reference = &next_reference;
    3552          18 :         r.out.recordid = &recordid;
    3553          18 :         r.out.return_authenticator = &return_authenticator;
    3554             : 
    3555             :         /* w2k3 returns "NOT IMPLEMENTED" for this call */
    3556          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountSync_r(b, tctx, &r),
    3557             :                 "AccountSync failed");
    3558          18 :         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
    3559             : 
    3560          15 :         return true;
    3561             : }
    3562             : 
    3563             : /*
    3564             :   try a netlogon GetDcName
    3565             : */
    3566          18 : static bool test_GetDcName(struct torture_context *tctx,
    3567             :                            struct dcerpc_pipe *p)
    3568             : {
    3569           3 :         struct netr_GetDcName r;
    3570          18 :         const char *dcname = NULL;
    3571          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
    3572             : 
    3573          18 :         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    3574          18 :         r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
    3575          18 :         r.out.dcname = &dcname;
    3576             : 
    3577          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_GetDcName_r(b, tctx, &r),
    3578             :                 "GetDcName failed");
    3579          18 :         torture_assert_werr_ok(tctx, r.out.result, "GetDcName failed");
    3580             : 
    3581          18 :         torture_comment(tctx, "\tDC is at '%s'\n", dcname);
    3582             : 
    3583          18 :         return true;
    3584             : }
    3585             : 
    3586        6417 : static const char *function_code_str(TALLOC_CTX *mem_ctx,
    3587             :                                      enum netr_LogonControlCode function_code)
    3588             : {
    3589        6417 :         switch (function_code) {
    3590         228 :         case NETLOGON_CONTROL_QUERY:
    3591         228 :                 return "NETLOGON_CONTROL_QUERY";
    3592         276 :         case NETLOGON_CONTROL_REPLICATE:
    3593         276 :                 return "NETLOGON_CONTROL_REPLICATE";
    3594         276 :         case NETLOGON_CONTROL_SYNCHRONIZE:
    3595         276 :                 return "NETLOGON_CONTROL_SYNCHRONIZE";
    3596         276 :         case NETLOGON_CONTROL_PDC_REPLICATE:
    3597         276 :                 return "NETLOGON_CONTROL_PDC_REPLICATE";
    3598         690 :         case NETLOGON_CONTROL_REDISCOVER:
    3599         690 :                 return "NETLOGON_CONTROL_REDISCOVER";
    3600         690 :         case NETLOGON_CONTROL_TC_QUERY:
    3601         690 :                 return "NETLOGON_CONTROL_TC_QUERY";
    3602         690 :         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
    3603         690 :                 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
    3604         276 :         case NETLOGON_CONTROL_FIND_USER:
    3605         276 :                 return "NETLOGON_CONTROL_FIND_USER";
    3606         276 :         case NETLOGON_CONTROL_CHANGE_PASSWORD:
    3607         276 :                 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
    3608         276 :         case NETLOGON_CONTROL_TC_VERIFY:
    3609         276 :                 return "NETLOGON_CONTROL_TC_VERIFY";
    3610         276 :         case NETLOGON_CONTROL_FORCE_DNS_REG:
    3611         276 :                 return "NETLOGON_CONTROL_FORCE_DNS_REG";
    3612         276 :         case NETLOGON_CONTROL_QUERY_DNS_REG:
    3613         276 :                 return "NETLOGON_CONTROL_QUERY_DNS_REG";
    3614         276 :         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
    3615         276 :                 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
    3616         276 :         case NETLOGON_CONTROL_TRUNCATE_LOG:
    3617         276 :                 return "NETLOGON_CONTROL_TRUNCATE_LOG";
    3618         828 :         case NETLOGON_CONTROL_SET_DBFLAG:
    3619         828 :                 return "NETLOGON_CONTROL_SET_DBFLAG";
    3620         345 :         case NETLOGON_CONTROL_BREAKPOINT:
    3621         345 :                 return "NETLOGON_CONTROL_BREAKPOINT";
    3622         138 :         default:
    3623         138 :                 return talloc_asprintf(mem_ctx, "unknown function code: %d",
    3624             :                                        function_code);
    3625             :         }
    3626             : }
    3627             : 
    3628             : 
    3629             : /*
    3630             :   try a netlogon LogonControl
    3631             : */
    3632          69 : static bool test_LogonControl(struct torture_context *tctx,
    3633             :                               struct dcerpc_pipe *p,
    3634             :                               struct cli_credentials *machine_credentials)
    3635             : 
    3636             : {
    3637          12 :         NTSTATUS status;
    3638          12 :         struct netr_LogonControl r;
    3639          12 :         union netr_CONTROL_QUERY_INFORMATION query;
    3640          12 :         int i,f;
    3641          69 :         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
    3642          69 :         struct dcerpc_binding_handle *b = p->binding_handle;
    3643             : 
    3644          69 :         uint32_t function_codes[] = {
    3645             :                 NETLOGON_CONTROL_QUERY,
    3646             :                 NETLOGON_CONTROL_REPLICATE,
    3647             :                 NETLOGON_CONTROL_SYNCHRONIZE,
    3648             :                 NETLOGON_CONTROL_PDC_REPLICATE,
    3649             :                 NETLOGON_CONTROL_REDISCOVER,
    3650             :                 NETLOGON_CONTROL_TC_QUERY,
    3651             :                 NETLOGON_CONTROL_TRANSPORT_NOTIFY,
    3652             :                 NETLOGON_CONTROL_FIND_USER,
    3653             :                 NETLOGON_CONTROL_CHANGE_PASSWORD,
    3654             :                 NETLOGON_CONTROL_TC_VERIFY,
    3655             :                 NETLOGON_CONTROL_FORCE_DNS_REG,
    3656             :                 NETLOGON_CONTROL_QUERY_DNS_REG,
    3657             :                 NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
    3658             :                 NETLOGON_CONTROL_TRUNCATE_LOG,
    3659             :                 NETLOGON_CONTROL_SET_DBFLAG,
    3660             :                 NETLOGON_CONTROL_BREAKPOINT
    3661             :         };
    3662             : 
    3663          69 :         if (machine_credentials) {
    3664          69 :                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
    3665             :         }
    3666             : 
    3667          69 :         torture_comment(tctx, "Testing LogonControl with secure channel type: %d\n",
    3668             :                 secure_channel_type);
    3669             : 
    3670          69 :         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    3671          69 :         r.in.function_code = 1;
    3672          69 :         r.out.query = &query;
    3673             : 
    3674        1173 :         for (f=0;f<ARRAY_SIZE(function_codes); f++) {
    3675        5520 :         for (i=1;i<5;i++) {
    3676             : 
    3677        4416 :                 r.in.function_code = function_codes[f];
    3678        4416 :                 r.in.level = i;
    3679             : 
    3680        4416 :                 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
    3681        3648 :                                 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
    3682             : 
    3683        4416 :                 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
    3684        4416 :                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
    3685             : 
    3686        4416 :                 switch (r.in.level) {
    3687        1104 :                 case 1:
    3688        1104 :                         switch (r.in.function_code) {
    3689         345 :                         case NETLOGON_CONTROL_REPLICATE:
    3690             :                         case NETLOGON_CONTROL_SYNCHRONIZE:
    3691             :                         case NETLOGON_CONTROL_PDC_REPLICATE:
    3692             :                         case NETLOGON_CONTROL_BREAKPOINT:
    3693             :                         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
    3694         345 :                                 if ((secure_channel_type == SEC_CHAN_BDC) ||
    3695          60 :                                     (secure_channel_type == SEC_CHAN_WKSTA)) {
    3696         230 :                                         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
    3697             :                                                 "LogonControl returned unexpected error code");
    3698             :                                 } else {
    3699         115 :                                         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
    3700             :                                                 "LogonControl returned unexpected error code");
    3701             :                                 }
    3702         285 :                                 break;
    3703             : 
    3704         621 :                         case NETLOGON_CONTROL_REDISCOVER:
    3705             :                         case NETLOGON_CONTROL_TC_QUERY:
    3706             :                         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
    3707             :                         case NETLOGON_CONTROL_FIND_USER:
    3708             :                         case NETLOGON_CONTROL_CHANGE_PASSWORD:
    3709             :                         case NETLOGON_CONTROL_TC_VERIFY:
    3710             :                         case NETLOGON_CONTROL_FORCE_DNS_REG:
    3711             :                         case NETLOGON_CONTROL_QUERY_DNS_REG:
    3712             :                         case NETLOGON_CONTROL_SET_DBFLAG:
    3713         621 :                                 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
    3714             :                                         "LogonControl returned unexpected error code");
    3715         513 :                                 break;
    3716          69 :                         case NETLOGON_CONTROL_TRUNCATE_LOG:
    3717          69 :                                 if ((secure_channel_type == SEC_CHAN_BDC) ||
    3718          12 :                                     (secure_channel_type == SEC_CHAN_WKSTA)) {
    3719          46 :                                         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
    3720             :                                                 "LogonControl returned unexpected error code");
    3721          23 :                                 } else if (!W_ERROR_EQUAL(r.out.result, WERR_NOT_SUPPORTED)) {
    3722           0 :                                         torture_assert_werr_ok(tctx, r.out.result,
    3723             :                                                 "LogonControl returned unexpected result");
    3724             :                                 }
    3725          57 :                                 break;
    3726          69 :                         default:
    3727          69 :                                 torture_assert_werr_ok(tctx, r.out.result,
    3728             :                                         "LogonControl returned unexpected result");
    3729          57 :                                 break;
    3730             :                         }
    3731         912 :                         break;
    3732        1104 :                 case 2:
    3733        1104 :                         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
    3734             :                                 "LogonControl returned unexpected error code");
    3735         912 :                         break;
    3736        2208 :                 default:
    3737        2208 :                         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL,
    3738             :                                 "LogonControl returned unexpected error code");
    3739        1824 :                         break;
    3740             :                 }
    3741             :         }
    3742             :         }
    3743             : 
    3744          69 :         r.in.level = 52;
    3745          69 :         torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
    3746          69 :                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
    3747          69 :         status = dcerpc_netr_LogonControl_r(b, tctx, &r);
    3748          69 :         torture_assert_ntstatus_ok(tctx, status, "LogonControl");
    3749          69 :         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl");
    3750             : 
    3751          57 :         return true;
    3752             : }
    3753             : 
    3754             : 
    3755             : /*
    3756             :   try a netlogon GetAnyDCName
    3757             : */
    3758          18 : static bool test_GetAnyDCName(struct torture_context *tctx,
    3759             :                               struct dcerpc_pipe *p)
    3760             : {
    3761           3 :         NTSTATUS status;
    3762           3 :         struct netr_GetAnyDCName r;
    3763          18 :         const char *dcname = NULL;
    3764          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
    3765             : 
    3766          18 :         r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
    3767          18 :         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    3768          18 :         r.out.dcname = &dcname;
    3769             : 
    3770          18 :         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
    3771          18 :         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
    3772          18 :         if ((!W_ERROR_IS_OK(r.out.result)) &&
    3773          15 :             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
    3774           0 :                 return false;
    3775             :         }
    3776             : 
    3777          18 :         if (dcname) {
    3778           0 :             torture_comment(tctx, "\tDC is at '%s'\n", dcname);
    3779             :         }
    3780             : 
    3781          18 :         r.in.domainname = NULL;
    3782             : 
    3783          18 :         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
    3784          18 :         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
    3785          18 :         if ((!W_ERROR_IS_OK(r.out.result)) &&
    3786          15 :             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
    3787           0 :                 return false;
    3788             :         }
    3789             : 
    3790          18 :         r.in.domainname = "";
    3791             : 
    3792          18 :         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
    3793          18 :         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
    3794          18 :         if ((!W_ERROR_IS_OK(r.out.result)) &&
    3795          15 :             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
    3796           0 :                 return false;
    3797             :         }
    3798             : 
    3799          15 :         return true;
    3800             : }
    3801             : 
    3802             : 
    3803             : /*
    3804             :   try a netlogon LogonControl2
    3805             : */
    3806          69 : static bool test_LogonControl2(struct torture_context *tctx,
    3807             :                                struct dcerpc_pipe *p,
    3808             :                                struct cli_credentials *machine_credentials)
    3809             : 
    3810             : {
    3811          12 :         NTSTATUS status;
    3812          12 :         struct netr_LogonControl2 r;
    3813          12 :         union netr_CONTROL_DATA_INFORMATION data;
    3814          12 :         union netr_CONTROL_QUERY_INFORMATION query;
    3815          69 :         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
    3816          12 :         int i;
    3817          69 :         struct dcerpc_binding_handle *b = p->binding_handle;
    3818             : 
    3819          69 :         data.domain = lpcfg_workgroup(tctx->lp_ctx);
    3820             : 
    3821          69 :         if (machine_credentials) {
    3822          69 :                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
    3823             :         }
    3824             : 
    3825          69 :         torture_comment(tctx, "Testing LogonControl2 with secure channel type: %d\n",
    3826             :                 secure_channel_type);
    3827             : 
    3828          69 :         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    3829             : 
    3830          69 :         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
    3831          69 :         r.in.data = &data;
    3832          69 :         r.out.query = &query;
    3833             : 
    3834         276 :         for (i=1;i<4;i++) {
    3835         207 :                 r.in.level = i;
    3836             : 
    3837         207 :                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
    3838         207 :                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
    3839             : 
    3840         207 :                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
    3841         207 :                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
    3842             :         }
    3843             : 
    3844          69 :         data.domain = lpcfg_workgroup(tctx->lp_ctx);
    3845             : 
    3846          69 :         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
    3847          69 :         r.in.data = &data;
    3848             : 
    3849         276 :         for (i=1;i<4;i++) {
    3850         207 :                 r.in.level = i;
    3851             : 
    3852         207 :                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
    3853         207 :                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
    3854             : 
    3855         207 :                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
    3856         207 :                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
    3857             :         }
    3858             : 
    3859          69 :         data.domain = lpcfg_workgroup(tctx->lp_ctx);
    3860             : 
    3861          69 :         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
    3862          69 :         r.in.data = &data;
    3863             : 
    3864         276 :         for (i=1;i<4;i++) {
    3865         207 :                 r.in.level = i;
    3866             : 
    3867         207 :                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
    3868         207 :                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
    3869             : 
    3870         207 :                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
    3871         207 :                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
    3872             :         }
    3873             : 
    3874          69 :         data.debug_level = ~0;
    3875             : 
    3876          69 :         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
    3877          69 :         r.in.data = &data;
    3878             : 
    3879         276 :         for (i=1;i<4;i++) {
    3880         207 :                 r.in.level = i;
    3881             : 
    3882         207 :                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
    3883         207 :                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
    3884             : 
    3885         207 :                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
    3886         207 :                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
    3887             :         }
    3888             : 
    3889          69 :         ZERO_STRUCT(data);
    3890          69 :         r.in.function_code = 52;
    3891          69 :         r.in.data = &data;
    3892             : 
    3893          69 :         torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
    3894          57 :                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
    3895             : 
    3896          69 :         status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
    3897          69 :         torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
    3898          69 :         switch (secure_channel_type) {
    3899          23 :         case SEC_CHAN_NULL:
    3900          23 :                 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2");
    3901          19 :                 break;
    3902          46 :         default:
    3903          46 :                 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2");
    3904          38 :                 break;
    3905             :         }
    3906          69 :         data.debug_level = ~0;
    3907             : 
    3908          69 :         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
    3909          69 :         r.in.data = &data;
    3910             : 
    3911          69 :         r.in.level = 52;
    3912          69 :         torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
    3913          57 :                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
    3914             : 
    3915          69 :         status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
    3916          69 :         torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
    3917          69 :         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl2");
    3918             : 
    3919          57 :         return true;
    3920             : }
    3921             : 
    3922             : /*
    3923             :   try a netlogon DatabaseSync2
    3924             : */
    3925          18 : static bool test_DatabaseSync2(struct torture_context *tctx,
    3926             :                                struct dcerpc_pipe *p,
    3927             :                                struct cli_credentials *machine_credentials)
    3928             : {
    3929           3 :         struct netr_DatabaseSync2 r;
    3930          18 :         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
    3931           3 :         struct netr_Authenticator return_authenticator, credential;
    3932             : 
    3933           3 :         struct netlogon_creds_CredentialState *creds;
    3934          18 :         const uint32_t database_ids[] = {0, 1, 2};
    3935           3 :         int i;
    3936          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
    3937             : 
    3938          18 :         if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
    3939             :                                     machine_credentials,
    3940             :                                     cli_credentials_get_secure_channel_type(machine_credentials),
    3941             :                                     &creds)) {
    3942           6 :                 return false;
    3943             :         }
    3944             : 
    3945           9 :         ZERO_STRUCT(return_authenticator);
    3946             : 
    3947           9 :         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    3948           9 :         r.in.computername = TEST_MACHINE_NAME;
    3949           9 :         r.in.preferredmaximumlength = (uint32_t)-1;
    3950           9 :         r.in.return_authenticator = &return_authenticator;
    3951           9 :         r.out.return_authenticator = &return_authenticator;
    3952           9 :         r.out.delta_enum_array = &delta_enum_array;
    3953             : 
    3954           9 :         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
    3955             : 
    3956           9 :                 uint32_t sync_context = 0;
    3957             : 
    3958           9 :                 r.in.database_id = database_ids[i];
    3959           9 :                 r.in.sync_context = &sync_context;
    3960           9 :                 r.out.sync_context = &sync_context;
    3961           9 :                 r.in.restart_state = 0;
    3962             : 
    3963           9 :                 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
    3964             : 
    3965           0 :                 do {
    3966           9 :                         netlogon_creds_client_authenticator(creds, &credential);
    3967             : 
    3968           9 :                         r.in.credential = &credential;
    3969             : 
    3970           9 :                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync2_r(b, tctx, &r),
    3971             :                                 "DatabaseSync2 failed");
    3972           9 :                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
    3973           0 :                             break;
    3974             : 
    3975             :                         /* Native mode servers don't do this */
    3976           9 :                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
    3977           0 :                                 return true;
    3978             :                         }
    3979             : 
    3980           9 :                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync2");
    3981             : 
    3982           0 :                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
    3983           0 :                                 torture_comment(tctx, "Credential chaining failed\n");
    3984             :                         }
    3985             : 
    3986           0 :                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
    3987             :         }
    3988             : 
    3989           0 :         return true;
    3990             : }
    3991             : 
    3992             : 
    3993             : /*
    3994             :   try a netlogon LogonControl2Ex
    3995             : */
    3996          69 : static bool test_LogonControl2Ex(struct torture_context *tctx,
    3997             :                                  struct dcerpc_pipe *p,
    3998             :                                  struct cli_credentials *machine_credentials)
    3999             : 
    4000             : {
    4001          12 :         NTSTATUS status;
    4002          12 :         struct netr_LogonControl2Ex r;
    4003          12 :         union netr_CONTROL_DATA_INFORMATION data;
    4004          12 :         union netr_CONTROL_QUERY_INFORMATION query;
    4005          69 :         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
    4006          12 :         int i;
    4007          69 :         struct dcerpc_binding_handle *b = p->binding_handle;
    4008             : 
    4009          69 :         data.domain = lpcfg_workgroup(tctx->lp_ctx);
    4010             : 
    4011          69 :         if (machine_credentials) {
    4012          69 :                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
    4013             :         }
    4014             : 
    4015          69 :         torture_comment(tctx, "Testing LogonControl2Ex with secure channel type: %d\n",
    4016             :                 secure_channel_type);
    4017             : 
    4018          69 :         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    4019             : 
    4020          69 :         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
    4021          69 :         r.in.data = &data;
    4022          69 :         r.out.query = &query;
    4023             : 
    4024         276 :         for (i=1;i<4;i++) {
    4025         207 :                 r.in.level = i;
    4026             : 
    4027         207 :                 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
    4028         207 :                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
    4029             : 
    4030         207 :                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
    4031         207 :                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
    4032             :         }
    4033             : 
    4034          69 :         data.domain = lpcfg_workgroup(tctx->lp_ctx);
    4035             : 
    4036          69 :         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
    4037          69 :         r.in.data = &data;
    4038             : 
    4039         276 :         for (i=1;i<4;i++) {
    4040         207 :                 r.in.level = i;
    4041             : 
    4042         207 :                 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
    4043         207 :                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
    4044             : 
    4045         207 :                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
    4046         207 :                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
    4047             :         }
    4048             : 
    4049          69 :         data.domain = lpcfg_workgroup(tctx->lp_ctx);
    4050             : 
    4051          69 :         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
    4052          69 :         r.in.data = &data;
    4053             : 
    4054         276 :         for (i=1;i<4;i++) {
    4055         207 :                 r.in.level = i;
    4056             : 
    4057         207 :                 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
    4058         207 :                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
    4059             : 
    4060         207 :                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
    4061         207 :                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
    4062             :         }
    4063             : 
    4064          69 :         data.debug_level = ~0;
    4065             : 
    4066          69 :         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
    4067          69 :         r.in.data = &data;
    4068             : 
    4069         276 :         for (i=1;i<4;i++) {
    4070         207 :                 r.in.level = i;
    4071             : 
    4072         207 :                 torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
    4073         207 :                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
    4074             : 
    4075         207 :                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
    4076         207 :                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
    4077             :         }
    4078             : 
    4079          69 :         ZERO_STRUCT(data);
    4080          69 :         r.in.function_code = 52;
    4081          69 :         r.in.data = &data;
    4082             : 
    4083          69 :         torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
    4084          57 :                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
    4085             : 
    4086          69 :         status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
    4087          69 :         torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
    4088          69 :         switch (secure_channel_type) {
    4089          23 :         case SEC_CHAN_NULL:
    4090          23 :                 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED, "LogonControl2Ex");
    4091          19 :                 break;
    4092          46 :         default:
    4093          46 :                 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED, "LogonControl2Ex");
    4094          38 :                 break;
    4095             :         }
    4096          69 :         data.debug_level = ~0;
    4097             : 
    4098          69 :         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
    4099          69 :         r.in.data = &data;
    4100             : 
    4101          69 :         r.in.level = 52;
    4102          69 :         torture_comment(tctx, "Testing LogonControl2Ex function code %s (%d) level %d\n",
    4103          57 :                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
    4104             : 
    4105          69 :         status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
    4106          69 :         torture_assert_ntstatus_ok(tctx, status, "LogonControl2Ex");
    4107          69 :         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl2Ex");
    4108             : 
    4109          57 :         return true;
    4110             : }
    4111             : 
    4112          18 : static bool test_netr_GetForestTrustInformation(struct torture_context *tctx,
    4113             :                                                 struct dcerpc_pipe *p1,
    4114             :                                                 struct cli_credentials *machine_credentials)
    4115             : {
    4116           3 :         struct netr_GetForestTrustInformation r;
    4117           3 :         struct netlogon_creds_CredentialState *creds;
    4118           3 :         struct netr_Authenticator a;
    4119           3 :         struct netr_Authenticator return_authenticator;
    4120           3 :         struct lsa_ForestTrustInformation *forest_trust_info;
    4121          18 :         struct dcerpc_pipe *p = NULL;
    4122          18 :         struct dcerpc_binding_handle *b = NULL;
    4123             : 
    4124          18 :         if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
    4125             :                                     machine_credentials, &creds)) {
    4126           0 :                 return false;
    4127             :         }
    4128          18 :         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
    4129             :                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
    4130           0 :                 return false;
    4131             :         }
    4132          18 :         b = p->binding_handle;
    4133             : 
    4134          18 :         netlogon_creds_client_authenticator(creds, &a);
    4135             : 
    4136          18 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    4137          18 :         r.in.computer_name = TEST_MACHINE_NAME;
    4138          18 :         r.in.credential = &a;
    4139          18 :         r.in.flags = 0;
    4140          18 :         r.out.return_authenticator = &return_authenticator;
    4141          18 :         r.out.forest_trust_info = &forest_trust_info;
    4142             : 
    4143          18 :         torture_assert_ntstatus_ok(tctx,
    4144             :                 dcerpc_netr_GetForestTrustInformation_r(b, tctx, &r),
    4145             :                 "netr_GetForestTrustInformation failed");
    4146          18 :         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
    4147          18 :                 torture_comment(tctx, "not considering NT_STATUS_NOT_IMPLEMENTED as an error\n");
    4148             :         } else {
    4149           0 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
    4150             :                         "netr_GetForestTrustInformation failed");
    4151             :         }
    4152             : 
    4153          18 :         torture_assert(tctx,
    4154             :                 netlogon_creds_client_check(creds, &return_authenticator.cred),
    4155             :                 "Credential chaining failed");
    4156             : 
    4157          15 :         return true;
    4158             : }
    4159             : 
    4160          18 : static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
    4161             :                                                    struct dcerpc_pipe *p, const char *trusted_domain_name)
    4162             : {
    4163           3 :         NTSTATUS status;
    4164           3 :         struct netr_DsRGetForestTrustInformation r;
    4165           3 :         struct lsa_ForestTrustInformation info, *info_ptr;
    4166          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
    4167             : 
    4168          18 :         info_ptr = &info;
    4169             : 
    4170          18 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    4171          18 :         r.in.trusted_domain_name = trusted_domain_name;
    4172          18 :         r.in.flags = 0;
    4173          18 :         r.out.forest_trust_info = &info_ptr;
    4174             : 
    4175          18 :         torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
    4176             : 
    4177          18 :         status = dcerpc_netr_DsRGetForestTrustInformation_r(b, tctx, &r);
    4178          18 :         torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
    4179          18 :         torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
    4180             : 
    4181          15 :         return true;
    4182             : }
    4183             : 
    4184             : /*
    4185             :   try a netlogon netr_DsrEnumerateDomainTrusts
    4186             : */
    4187          18 : static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
    4188             :                                           struct dcerpc_pipe *p)
    4189             : {
    4190           3 :         NTSTATUS status;
    4191           3 :         struct netr_DsrEnumerateDomainTrusts r;
    4192           3 :         struct netr_DomainTrustList trusts;
    4193           3 :         int i;
    4194          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
    4195             : 
    4196          18 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    4197          18 :         r.in.trust_flags = 0x3f;
    4198          18 :         r.out.trusts = &trusts;
    4199             : 
    4200          18 :         status = dcerpc_netr_DsrEnumerateDomainTrusts_r(b, tctx, &r);
    4201          18 :         torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
    4202          18 :         torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
    4203             : 
    4204             :         /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
    4205             :          * will show non-forest trusts and all UPN suffixes of the own forest
    4206             :          * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
    4207             : 
    4208          18 :         if (r.out.trusts->count) {
    4209          18 :                 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
    4210           0 :                         return false;
    4211             :                 }
    4212             :         }
    4213             : 
    4214          36 :         for (i=0; i<r.out.trusts->count; i++) {
    4215             : 
    4216             :                 /* get info for transitive forest trusts */
    4217             : 
    4218          18 :                 if (r.out.trusts->array[i].trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
    4219           0 :                         if (!test_netr_DsRGetForestTrustInformation(tctx, p,
    4220           0 :                                                                     r.out.trusts->array[i].dns_name)) {
    4221           0 :                                 return false;
    4222             :                         }
    4223             :                 }
    4224             :         }
    4225             : 
    4226          15 :         return true;
    4227             : }
    4228             : 
    4229          21 : static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
    4230             :                                                   struct dcerpc_pipe *p)
    4231             : {
    4232           3 :         NTSTATUS status;
    4233           3 :         struct netr_NetrEnumerateTrustedDomains r;
    4234           3 :         struct netr_Blob trusted_domains_blob;
    4235          21 :         struct dcerpc_binding_handle *b = p->binding_handle;
    4236             : 
    4237          21 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    4238          21 :         r.out.trusted_domains_blob = &trusted_domains_blob;
    4239             : 
    4240          21 :         status = dcerpc_netr_NetrEnumerateTrustedDomains_r(b, tctx, &r);
    4241          21 :         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
    4242           0 :         torture_assert_ntstatus_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
    4243             : 
    4244           0 :         return true;
    4245             : }
    4246             : 
    4247          18 : static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
    4248             :                                                     struct dcerpc_pipe *p)
    4249             : {
    4250           3 :         NTSTATUS status;
    4251           3 :         struct netr_NetrEnumerateTrustedDomainsEx r;
    4252           3 :         struct netr_DomainTrustList dom_trust_list;
    4253          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
    4254             : 
    4255          18 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    4256          18 :         r.out.dom_trust_list = &dom_trust_list;
    4257             : 
    4258          18 :         status = dcerpc_netr_NetrEnumerateTrustedDomainsEx_r(b, tctx, &r);
    4259          18 :         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
    4260           0 :         torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
    4261             : 
    4262           0 :         return true;
    4263             : }
    4264             : 
    4265             : 
    4266          54 : static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
    4267             :                                      const char *computer_name,
    4268             :                                      const char *expected_site)
    4269             : {
    4270           9 :         NTSTATUS status;
    4271           9 :         struct netr_DsRGetSiteName r;
    4272          54 :         const char *site = NULL;
    4273          54 :         struct dcerpc_binding_handle *b = p->binding_handle;
    4274             : 
    4275          54 :         r.in.computer_name              = computer_name;
    4276          54 :         r.out.site                      = &site;
    4277          54 :         torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
    4278             : 
    4279          54 :         status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
    4280          54 :         torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
    4281          54 :         torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
    4282          54 :         torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
    4283             : 
    4284          45 :         return true;
    4285             : }
    4286             : 
    4287             : /*
    4288             :   try a netlogon netr_DsRGetDCName
    4289             : */
    4290          18 : static bool test_netr_DsRGetDCName(struct torture_context *tctx,
    4291             :                                    struct dcerpc_pipe *p)
    4292             : {
    4293           3 :         NTSTATUS status;
    4294           3 :         struct netr_DsRGetDCName r;
    4295          18 :         struct netr_DsRGetDCNameInfo *info = NULL;
    4296          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
    4297             : 
    4298          18 :         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    4299          18 :         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
    4300          18 :         r.in.domain_guid        = NULL;
    4301          18 :         r.in.site_guid          = NULL;
    4302          18 :         r.in.flags              = DS_RETURN_DNS_NAME;
    4303          18 :         r.out.info              = &info;
    4304             : 
    4305          18 :         status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
    4306          18 :         torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
    4307          18 :         torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
    4308             : 
    4309          18 :         torture_assert_int_equal(tctx,
    4310             :                                  (info->dc_flags & (DS_DNS_CONTROLLER)),
    4311             :                                  DS_DNS_CONTROLLER,
    4312             :                                  "DsRGetDCName");
    4313          18 :         torture_assert_int_equal(tctx,
    4314             :                                  (info->dc_flags & (DS_DNS_DOMAIN)),
    4315             :                                  DS_DNS_DOMAIN,
    4316             :                                  "DsRGetDCName");
    4317          18 :         torture_assert_int_equal(tctx,
    4318             :                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
    4319             :                                  DS_DNS_FOREST_ROOT,
    4320             :                                  "DsRGetDCName");
    4321             : 
    4322          18 :         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
    4323          18 :         r.in.flags              = 0;
    4324             : 
    4325          18 :         status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
    4326          18 :         torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
    4327          18 :         torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
    4328             : 
    4329          18 :         torture_assert_int_equal(tctx,
    4330             :                                  (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
    4331             :                                  "DsRGetDCName");
    4332          18 :         torture_assert_int_equal(tctx,
    4333             :                                  (info->dc_flags & (DS_DNS_DOMAIN)), 0,
    4334             :                                  "DsRGetDCName");
    4335          18 :         torture_assert_int_equal(tctx,
    4336             :                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
    4337             :                                  DS_DNS_FOREST_ROOT,
    4338             :                                  "DsRGetDCName");
    4339             : 
    4340          18 :         if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
    4341          18 :                 torture_assert_int_equal(tctx,
    4342             :                                          (info->dc_flags & (DS_SERVER_CLOSEST)),
    4343             :                                          DS_SERVER_CLOSEST,
    4344             :                                          "DsRGetDCName");
    4345             :         }
    4346             : 
    4347          18 :         return test_netr_DsRGetSiteName(p, tctx,
    4348          15 :                                        info->dc_unc,
    4349          15 :                                        info->dc_site_name);
    4350             : }
    4351             : 
    4352             : /*
    4353             :   try a netlogon netr_DsRGetDCNameEx
    4354             : */
    4355          18 : static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
    4356             :                                      struct dcerpc_pipe *p)
    4357             : {
    4358           3 :         NTSTATUS status;
    4359           3 :         struct netr_DsRGetDCNameEx r;
    4360          18 :         struct netr_DsRGetDCNameInfo *info = NULL;
    4361          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
    4362             : 
    4363          18 :         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    4364          18 :         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
    4365          18 :         r.in.domain_guid        = NULL;
    4366          18 :         r.in.site_name          = NULL;
    4367          18 :         r.in.flags              = DS_RETURN_DNS_NAME;
    4368          18 :         r.out.info              = &info;
    4369             : 
    4370          18 :         status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
    4371          18 :         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
    4372          18 :         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
    4373             : 
    4374          18 :         torture_assert_int_equal(tctx,
    4375             :                                  (info->dc_flags & (DS_DNS_CONTROLLER)),
    4376             :                                  DS_DNS_CONTROLLER,
    4377             :                                  "DsRGetDCNameEx");
    4378          18 :         torture_assert_int_equal(tctx,
    4379             :                                  (info->dc_flags & (DS_DNS_DOMAIN)),
    4380             :                                  DS_DNS_DOMAIN,
    4381             :                                  "DsRGetDCNameEx");
    4382          18 :         torture_assert_int_equal(tctx,
    4383             :                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
    4384             :                                  DS_DNS_FOREST_ROOT,
    4385             :                                  "DsRGetDCNameEx");
    4386             : 
    4387          18 :         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
    4388          18 :         r.in.flags              = 0;
    4389             : 
    4390          18 :         status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
    4391          18 :         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
    4392          18 :         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
    4393             : 
    4394          18 :         torture_assert_int_equal(tctx,
    4395             :                                  (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
    4396             :                                  "DsRGetDCNameEx");
    4397          18 :         torture_assert_int_equal(tctx,
    4398             :                                  (info->dc_flags & (DS_DNS_DOMAIN)), 0,
    4399             :                                  "DsRGetDCNameEx");
    4400          18 :         torture_assert_int_equal(tctx,
    4401             :                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
    4402             :                                  DS_DNS_FOREST_ROOT,
    4403             :                                  "DsRGetDCNameEx");
    4404             : 
    4405          18 :         if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
    4406          18 :                 torture_assert_int_equal(tctx,
    4407             :                                          (info->dc_flags & (DS_SERVER_CLOSEST)),
    4408             :                                          DS_SERVER_CLOSEST,
    4409             :                                          "DsRGetDCNameEx");
    4410             :         }
    4411             : 
    4412          18 :         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
    4413          15 :                                         info->dc_site_name);
    4414             : }
    4415             : 
    4416             : /*
    4417             :   try a netlogon netr_DsRGetDCNameEx2
    4418             : */
    4419          18 : static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
    4420             :                                       struct dcerpc_pipe *p)
    4421             : {
    4422           3 :         NTSTATUS status;
    4423           3 :         struct netr_DsRGetDCNameEx2 r;
    4424          18 :         struct netr_DsRGetDCNameInfo *info = NULL;
    4425          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
    4426             : 
    4427          18 :         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with no inputs\n");
    4428          18 :         ZERO_STRUCT(r.in);
    4429          18 :         r.in.flags              = DS_RETURN_DNS_NAME;
    4430          18 :         r.out.info              = &info;
    4431             : 
    4432          18 :         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
    4433          18 :         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
    4434          18 :         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
    4435             : 
    4436          18 :         torture_assert_int_equal(tctx,
    4437             :                                  (info->dc_flags & (DS_DNS_CONTROLLER)),
    4438             :                                  DS_DNS_CONTROLLER,
    4439             :                                  "DsRGetDCNameEx2");
    4440          18 :         torture_assert_int_equal(tctx,
    4441             :                                  (info->dc_flags & (DS_DNS_DOMAIN)),
    4442             :                                  DS_DNS_DOMAIN,
    4443             :                                  "DsRGetDCNameEx2");
    4444          18 :         torture_assert_int_equal(tctx,
    4445             :                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
    4446             :                                  DS_DNS_FOREST_ROOT,
    4447             :                                  "DsRGetDCNameEx2");
    4448             : 
    4449          18 :         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    4450          18 :         r.in.client_account     = NULL;
    4451          18 :         r.in.mask               = 0x00000000;
    4452          18 :         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
    4453          18 :         r.in.domain_guid        = NULL;
    4454          18 :         r.in.site_name          = NULL;
    4455          18 :         r.in.flags              = DS_RETURN_DNS_NAME;
    4456          18 :         r.out.info              = &info;
    4457             : 
    4458          18 :         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
    4459             : 
    4460          18 :         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
    4461          18 :         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
    4462          18 :         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
    4463             : 
    4464          18 :         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
    4465          18 :         r.in.flags              = 0;
    4466             : 
    4467          18 :         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
    4468          18 :         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
    4469          18 :         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
    4470             : 
    4471          18 :         torture_assert_int_equal(tctx,
    4472             :                                  (info->dc_flags & (DS_DNS_CONTROLLER)), 0,
    4473             :                                  "DsRGetDCNameEx2");
    4474          18 :         torture_assert_int_equal(tctx,
    4475             :                                  (info->dc_flags & (DS_DNS_DOMAIN)), 0,
    4476             :                                  "DsRGetDCNameEx2");
    4477          18 :         torture_assert_int_equal(tctx,
    4478             :                                  (info->dc_flags & (DS_DNS_FOREST_ROOT)),
    4479             :                                  DS_DNS_FOREST_ROOT,
    4480             :                                  "DsRGetDCNameEx2");
    4481             : 
    4482          18 :         if (strcasecmp(info->dc_site_name, info->client_site_name) == 0) {
    4483          18 :                 torture_assert_int_equal(tctx,
    4484             :                                          (info->dc_flags & (DS_SERVER_CLOSEST)),
    4485             :                                          DS_SERVER_CLOSEST,
    4486             :                                          "DsRGetDCNameEx2");
    4487             :         }
    4488             : 
    4489          18 :         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client account\n");
    4490          18 :         r.in.client_account     = TEST_MACHINE_NAME"$";
    4491          18 :         r.in.mask               = ACB_SVRTRUST;
    4492          18 :         r.in.flags              = DS_RETURN_FLAT_NAME;
    4493          18 :         r.out.info              = &info;
    4494             : 
    4495          18 :         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
    4496          18 :         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
    4497          18 :         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
    4498             : 
    4499          18 :         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
    4500          18 :                                         info->dc_site_name);
    4501             : }
    4502             : 
    4503             : /* This is a substitution for "samdb_server_site_name" which relies on the
    4504             :  * correct "lp_ctx" and therefore can't be used here. */
    4505         195 : static const char *server_site_name(struct torture_context *tctx,
    4506             :                                     struct ldb_context *ldb)
    4507             : {
    4508          39 :         TALLOC_CTX *tmp_ctx;
    4509          39 :         struct ldb_dn *dn, *server_dn;
    4510          39 :         const struct ldb_val *site_name_val;
    4511          39 :         const char *server_dn_str, *site_name;
    4512             : 
    4513         195 :         tmp_ctx = talloc_new(ldb);
    4514         195 :         if (tmp_ctx == NULL) {
    4515           0 :                 goto failed;
    4516             :         }
    4517             : 
    4518         195 :         dn = ldb_dn_new(tmp_ctx, ldb, "");
    4519         195 :         if (dn == NULL) {
    4520           0 :                 goto failed;
    4521             :         }
    4522             : 
    4523         195 :         server_dn_str = samdb_search_string(ldb, tmp_ctx, dn, "serverName",
    4524             :                                             NULL);
    4525         195 :         if (server_dn_str == NULL) {
    4526           0 :                 goto failed;
    4527             :         }
    4528             : 
    4529         195 :         server_dn = ldb_dn_new(tmp_ctx, ldb, server_dn_str);
    4530         195 :         if (server_dn == NULL) {
    4531           0 :                 goto failed;
    4532             :         }
    4533             : 
    4534             :         /* CN=<Server name>, CN=Servers, CN=<Site name>, CN=Sites, ... */
    4535         195 :         site_name_val = ldb_dn_get_component_val(server_dn, 2);
    4536         195 :         if (site_name_val == NULL) {
    4537           0 :                 goto failed;
    4538             :         }
    4539             : 
    4540         195 :         site_name = (const char *) site_name_val->data;
    4541             : 
    4542         195 :         talloc_steal(tctx, site_name);
    4543         195 :         talloc_free(tmp_ctx);
    4544             : 
    4545         195 :         return site_name;
    4546             : 
    4547           0 : failed:
    4548           0 :         talloc_free(tmp_ctx);
    4549           0 :         return NULL;
    4550             : }
    4551             : 
    4552          18 : static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
    4553             :                                             struct dcerpc_pipe *p)
    4554             : {
    4555           3 :         char *url;
    4556          18 :         struct ldb_context *sam_ctx = NULL;
    4557           3 :         NTSTATUS status;
    4558           3 :         struct netr_DsrGetDcSiteCoverageW r;
    4559          18 :         struct DcSitesCtr *ctr = NULL;
    4560          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
    4561             : 
    4562          18 :         torture_comment(tctx, "This does only pass with the default site\n");
    4563             : 
    4564             :         /* We won't double-check this when we are over 'local' transports */
    4565          18 :         if (dcerpc_server_name(p)) {
    4566             :                 /* Set up connection to SAMDB on DC */
    4567          15 :                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
    4568          15 :                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
    4569             :                                            NULL,
    4570             :                                            samba_cmdline_get_creds(),
    4571             :                                            0);
    4572             : 
    4573          15 :                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
    4574             :         }
    4575             : 
    4576          18 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    4577          18 :         r.out.ctr = &ctr;
    4578             : 
    4579          18 :         status = dcerpc_netr_DsrGetDcSiteCoverageW_r(b, tctx, &r);
    4580          18 :         torture_assert_ntstatus_ok(tctx, status, "failed");
    4581          18 :         torture_assert_werr_ok(tctx, r.out.result, "failed");
    4582             : 
    4583          18 :         torture_assert(tctx, ctr->num_sites == 1,
    4584             :                        "we should per default only get the default site");
    4585          18 :         if (sam_ctx != NULL) {
    4586          15 :                 torture_assert_casestr_equal(tctx, ctr->sites[0].string,
    4587             :                                              server_site_name(tctx, sam_ctx),
    4588             :                                              "didn't return default site");
    4589             :         }
    4590             : 
    4591          15 :         return true;
    4592             : }
    4593             : 
    4594          18 : static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
    4595             :                                              struct dcerpc_pipe *p)
    4596             : {
    4597           3 :         char *url;
    4598          18 :         struct ldb_context *sam_ctx = NULL;
    4599           3 :         NTSTATUS status;
    4600           3 :         struct netr_DsRAddressToSitenamesW r;
    4601           3 :         struct netr_DsRAddress addrs[6];
    4602           3 :         struct sockaddr_in *addr;
    4603             : #ifdef HAVE_IPV6
    4604           3 :         struct sockaddr_in6 *addr6;
    4605             : #endif
    4606           3 :         struct netr_DsRAddressToSitenamesWCtr *ctr;
    4607          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
    4608           3 :         uint32_t i;
    4609           3 :         int ret;
    4610             : 
    4611          18 :         torture_comment(tctx, "This does only pass with the default site\n");
    4612             : 
    4613             :         /* We won't double-check this when we are over 'local' transports */
    4614          18 :         if (dcerpc_server_name(p)) {
    4615             :                 /* Set up connection to SAMDB on DC */
    4616          15 :                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
    4617          15 :                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
    4618             :                                            NULL,
    4619             :                                            samba_cmdline_get_creds(),
    4620             :                                            0);
    4621             : 
    4622          15 :                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
    4623             :         }
    4624             : 
    4625             :         /* First try valid IP addresses */
    4626             : 
    4627          18 :         addrs[0].size = sizeof(struct sockaddr_in);
    4628          18 :         addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
    4629          18 :         addr = (struct sockaddr_in *) addrs[0].buffer;
    4630          18 :         addrs[0].buffer[0] = AF_INET;
    4631          18 :         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
    4632          18 :         torture_assert(tctx, ret > 0, "inet_pton failed");
    4633             : 
    4634          18 :         addrs[1].size = sizeof(struct sockaddr_in);
    4635          18 :         addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
    4636          18 :         addr = (struct sockaddr_in *) addrs[1].buffer;
    4637          18 :         addrs[1].buffer[0] = AF_INET;
    4638          18 :         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
    4639          18 :         torture_assert(tctx, ret > 0, "inet_pton failed");
    4640             : 
    4641          18 :         addrs[2].size = sizeof(struct sockaddr_in);
    4642          18 :         addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
    4643          18 :         addr = (struct sockaddr_in *) addrs[2].buffer;
    4644          18 :         addrs[2].buffer[0] = AF_INET;
    4645          18 :         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
    4646          18 :         torture_assert(tctx, ret > 0, "inet_pton failed");
    4647             : 
    4648             : #ifdef HAVE_IPV6
    4649          18 :         addrs[3].size = sizeof(struct sockaddr_in6);
    4650          18 :         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
    4651          18 :         addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
    4652          18 :         addrs[3].buffer[0] = AF_INET6;
    4653          18 :         ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
    4654          18 :         torture_assert(tctx, ret > 0, "inet_pton failed");
    4655             : 
    4656          18 :         addrs[4].size = sizeof(struct sockaddr_in6);
    4657          18 :         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
    4658          18 :         addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
    4659          18 :         addrs[4].buffer[0] = AF_INET6;
    4660          18 :         ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
    4661          18 :         torture_assert(tctx, ret > 0, "inet_pton failed");
    4662             : 
    4663          18 :         addrs[5].size = sizeof(struct sockaddr_in6);
    4664          18 :         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
    4665          18 :         addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
    4666          18 :         addrs[5].buffer[0] = AF_INET6;
    4667          18 :         ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
    4668          18 :         torture_assert(tctx, ret > 0, "inet_pton failed");
    4669             : #else
    4670             :         /* the test cases are repeated to have exactly 6. This is for
    4671             :          * compatibility with IPv4-only machines */
    4672             :         addrs[3].size = sizeof(struct sockaddr_in);
    4673             :         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
    4674             :         addr = (struct sockaddr_in *) addrs[3].buffer;
    4675             :         addrs[3].buffer[0] = AF_INET;
    4676             :         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
    4677             :         torture_assert(tctx, ret > 0, "inet_pton failed");
    4678             : 
    4679             :         addrs[4].size = sizeof(struct sockaddr_in);
    4680             :         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
    4681             :         addr = (struct sockaddr_in *) addrs[4].buffer;
    4682             :         addrs[4].buffer[0] = AF_INET;
    4683             :         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
    4684             :         torture_assert(tctx, ret > 0, "inet_pton failed");
    4685             : 
    4686             :         addrs[5].size = sizeof(struct sockaddr_in);
    4687             :         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
    4688             :         addr = (struct sockaddr_in *) addrs[5].buffer;
    4689             :         addrs[5].buffer[0] = AF_INET;
    4690             :         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
    4691             :         torture_assert(tctx, ret > 0, "inet_pton failed");
    4692             : #endif
    4693             : 
    4694          18 :         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
    4695             : 
    4696          18 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    4697          18 :         r.in.count = 6;
    4698          18 :         r.in.addresses = addrs;
    4699          18 :         r.out.ctr = &ctr;
    4700             : 
    4701          18 :         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
    4702          18 :         torture_assert_ntstatus_ok(tctx, status, "failed");
    4703          18 :         torture_assert_werr_ok(tctx, r.out.result, "failed");
    4704             : 
    4705          18 :         if (sam_ctx != NULL) {
    4706          60 :                 for (i = 0; i < 3; i++) {
    4707          45 :                         torture_assert_casestr_equal(tctx,
    4708             :                                                      ctr->sitename[i].string,
    4709             :                                                      server_site_name(tctx, sam_ctx),
    4710             :                                                      "didn't return default site");
    4711             :                 }
    4712          60 :                 for (i = 3; i < 6; i++) {
    4713             :                         /* Windows returns "NULL" for the sitename if it isn't
    4714             :                          * IPv6 configured */
    4715          45 :                         if (torture_setting_bool(tctx, "samba4", false)) {
    4716          45 :                                 torture_assert_casestr_equal(tctx,
    4717             :                                                              ctr->sitename[i].string,
    4718             :                                                              server_site_name(tctx, sam_ctx),
    4719             :                                                              "didn't return default site");
    4720             :                         }
    4721             :                 }
    4722             :         }
    4723             : 
    4724             :         /* Now try invalid ones (too short buffers) */
    4725             : 
    4726          18 :         addrs[0].size = 0;
    4727          18 :         addrs[1].size = 1;
    4728          18 :         addrs[2].size = 4;
    4729             : 
    4730          18 :         addrs[3].size = 0;
    4731          18 :         addrs[4].size = 1;
    4732          18 :         addrs[5].size = 4;
    4733             : 
    4734          18 :         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
    4735          18 :         torture_assert_ntstatus_ok(tctx, status, "failed");
    4736          18 :         torture_assert_werr_ok(tctx, r.out.result, "failed");
    4737             : 
    4738         126 :         for (i = 0; i < 6; i++) {
    4739         108 :                 torture_assert(tctx, ctr->sitename[i].string == NULL,
    4740             :                                "sitename should be null");
    4741             :         }
    4742             : 
    4743             :         /* Now try invalid ones (wrong address types) */
    4744             : 
    4745          18 :         addrs[0].size = 10;
    4746          18 :         addrs[0].buffer[0] = AF_UNSPEC;
    4747          18 :         addrs[1].size = 10;
    4748          18 :         addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
    4749          18 :         addrs[2].size = 10;
    4750          18 :         addrs[2].buffer[0] = AF_UNIX;
    4751             : 
    4752          18 :         addrs[3].size = 10;
    4753          18 :         addrs[3].buffer[0] = 250;
    4754          18 :         addrs[4].size = 10;
    4755          18 :         addrs[4].buffer[0] = 251;
    4756          18 :         addrs[5].size = 10;
    4757          18 :         addrs[5].buffer[0] = 252;
    4758             : 
    4759          18 :         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
    4760          18 :         torture_assert_ntstatus_ok(tctx, status, "failed");
    4761          18 :         torture_assert_werr_ok(tctx, r.out.result, "failed");
    4762             : 
    4763         126 :         for (i = 0; i < 6; i++) {
    4764         108 :                 torture_assert(tctx, ctr->sitename[i].string == NULL,
    4765             :                                "sitename should be null");
    4766             :         }
    4767             : 
    4768          15 :         return true;
    4769             : }
    4770             : 
    4771          18 : static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
    4772             :                                                struct dcerpc_pipe *p)
    4773             : {
    4774           3 :         char *url;
    4775          18 :         struct ldb_context *sam_ctx = NULL;
    4776           3 :         NTSTATUS status;
    4777           3 :         struct netr_DsRAddressToSitenamesExW r;
    4778           3 :         struct netr_DsRAddress addrs[6];
    4779           3 :         struct sockaddr_in *addr;
    4780             : #ifdef HAVE_IPV6
    4781           3 :         struct sockaddr_in6 *addr6;
    4782             : #endif
    4783           3 :         struct netr_DsRAddressToSitenamesExWCtr *ctr;
    4784          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
    4785           3 :         uint32_t i;
    4786           3 :         int ret;
    4787             : 
    4788          18 :         torture_comment(tctx, "This does pass with the default site\n");
    4789             : 
    4790             :         /* We won't double-check this when we are over 'local' transports */
    4791          18 :         if (dcerpc_server_name(p)) {
    4792             :                 /* Set up connection to SAMDB on DC */
    4793          15 :                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
    4794          15 :                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
    4795             :                                            NULL,
    4796             :                                            samba_cmdline_get_creds(),
    4797             :                                            0);
    4798             : 
    4799          15 :                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
    4800             :         }
    4801             : 
    4802             :         /* First try valid IP addresses */
    4803             : 
    4804          18 :         addrs[0].size = sizeof(struct sockaddr_in);
    4805          18 :         addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
    4806          18 :         addr = (struct sockaddr_in *) addrs[0].buffer;
    4807          18 :         addrs[0].buffer[0] = AF_INET;
    4808          18 :         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
    4809          18 :         torture_assert(tctx, ret > 0, "inet_pton failed");
    4810             : 
    4811          18 :         addrs[1].size = sizeof(struct sockaddr_in);
    4812          18 :         addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
    4813          18 :         addr = (struct sockaddr_in *) addrs[1].buffer;
    4814          18 :         addrs[1].buffer[0] = AF_INET;
    4815          18 :         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
    4816          18 :         torture_assert(tctx, ret > 0, "inet_pton failed");
    4817             : 
    4818          18 :         addrs[2].size = sizeof(struct sockaddr_in);
    4819          18 :         addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
    4820          18 :         addr = (struct sockaddr_in *) addrs[2].buffer;
    4821          18 :         addrs[2].buffer[0] = AF_INET;
    4822          18 :         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
    4823          18 :         torture_assert(tctx, ret > 0, "inet_pton failed");
    4824             : 
    4825             : #ifdef HAVE_IPV6
    4826          18 :         addrs[3].size = sizeof(struct sockaddr_in6);
    4827          18 :         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
    4828          18 :         addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
    4829          18 :         addrs[3].buffer[0] = AF_INET6;
    4830          18 :         ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
    4831          18 :         torture_assert(tctx, ret > 0, "inet_pton failed");
    4832             : 
    4833          18 :         addrs[4].size = sizeof(struct sockaddr_in6);
    4834          18 :         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
    4835          18 :         addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
    4836          18 :         addrs[4].buffer[0] = AF_INET6;
    4837          18 :         ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
    4838          18 :         torture_assert(tctx, ret > 0, "inet_pton failed");
    4839             : 
    4840          18 :         addrs[5].size = sizeof(struct sockaddr_in6);
    4841          18 :         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
    4842          18 :         addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
    4843          18 :         addrs[5].buffer[0] = AF_INET6;
    4844          18 :         ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
    4845          18 :         torture_assert(tctx, ret > 0, "inet_pton failed");
    4846             : #else
    4847             :         /* the test cases are repeated to have exactly 6. This is for
    4848             :          * compatibility with IPv4-only machines */
    4849             :         addrs[3].size = sizeof(struct sockaddr_in);
    4850             :         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
    4851             :         addr = (struct sockaddr_in *) addrs[3].buffer;
    4852             :         addrs[3].buffer[0] = AF_INET;
    4853             :         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
    4854             :         torture_assert(tctx, ret > 0, "inet_pton failed");
    4855             : 
    4856             :         addrs[4].size = sizeof(struct sockaddr_in);
    4857             :         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
    4858             :         addr = (struct sockaddr_in *) addrs[4].buffer;
    4859             :         addrs[4].buffer[0] = AF_INET;
    4860             :         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
    4861             :         torture_assert(tctx, ret > 0, "inet_pton failed");
    4862             : 
    4863             :         addrs[5].size = sizeof(struct sockaddr_in);
    4864             :         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
    4865             :         addr = (struct sockaddr_in *) addrs[5].buffer;
    4866             :         addrs[5].buffer[0] = AF_INET;
    4867             :         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
    4868             :         torture_assert(tctx, ret > 0, "inet_pton failed");
    4869             : #endif
    4870             : 
    4871          18 :         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
    4872             : 
    4873          18 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    4874          18 :         r.in.count = 6;
    4875          18 :         r.in.addresses = addrs;
    4876          18 :         r.out.ctr = &ctr;
    4877             : 
    4878          18 :         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
    4879          18 :         torture_assert_ntstatus_ok(tctx, status, "failed");
    4880          18 :         torture_assert_werr_ok(tctx, r.out.result, "failed");
    4881             : 
    4882          18 :         if (sam_ctx != NULL) {
    4883          60 :                 for (i = 0; i < 3; i++) {
    4884          45 :                         torture_assert_casestr_equal(tctx,
    4885             :                                                      ctr->sitename[i].string,
    4886             :                                                      server_site_name(tctx, sam_ctx),
    4887             :                                                      "didn't return default site");
    4888          45 :                         torture_assert(tctx, ctr->subnetname[i].string == NULL,
    4889             :                                        "subnet should be null");
    4890             :                 }
    4891          60 :                 for (i = 3; i < 6; i++) {
    4892             :                         /* Windows returns "NULL" for the sitename if it isn't
    4893             :                          * IPv6 configured */
    4894          45 :                         if (torture_setting_bool(tctx, "samba4", false)) {
    4895          45 :                                 torture_assert_casestr_equal(tctx,
    4896             :                                                              ctr->sitename[i].string,
    4897             :                                                              server_site_name(tctx, sam_ctx),
    4898             :                                                              "didn't return default site");
    4899             :                         }
    4900          45 :                         torture_assert(tctx, ctr->subnetname[i].string == NULL,
    4901             :                                        "subnet should be null");
    4902             :                 }
    4903             :         }
    4904             : 
    4905             :         /* Now try invalid ones (too short buffers) */
    4906             : 
    4907          18 :         addrs[0].size = 0;
    4908          18 :         addrs[1].size = 1;
    4909          18 :         addrs[2].size = 4;
    4910             : 
    4911          18 :         addrs[3].size = 0;
    4912          18 :         addrs[4].size = 1;
    4913          18 :         addrs[5].size = 4;
    4914             : 
    4915          18 :         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
    4916          18 :         torture_assert_ntstatus_ok(tctx, status, "failed");
    4917          18 :         torture_assert_werr_ok(tctx, r.out.result, "failed");
    4918             : 
    4919         126 :         for (i = 0; i < 6; i++) {
    4920         108 :                 torture_assert(tctx, ctr->sitename[i].string == NULL,
    4921             :                                "sitename should be null");
    4922         108 :                 torture_assert(tctx, ctr->subnetname[i].string == NULL,
    4923             :                                "subnet should be null");
    4924             :         }
    4925             : 
    4926          18 :         addrs[0].size = 10;
    4927          18 :         addrs[0].buffer[0] = AF_UNSPEC;
    4928          18 :         addrs[1].size = 10;
    4929          18 :         addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
    4930          18 :         addrs[2].size = 10;
    4931          18 :         addrs[2].buffer[0] = AF_UNIX;
    4932             : 
    4933          18 :         addrs[3].size = 10;
    4934          18 :         addrs[3].buffer[0] = 250;
    4935          18 :         addrs[4].size = 10;
    4936          18 :         addrs[4].buffer[0] = 251;
    4937          18 :         addrs[5].size = 10;
    4938          18 :         addrs[5].buffer[0] = 252;
    4939             : 
    4940          18 :         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
    4941          18 :         torture_assert_ntstatus_ok(tctx, status, "failed");
    4942          18 :         torture_assert_werr_ok(tctx, r.out.result, "failed");
    4943             : 
    4944         126 :         for (i = 0; i < 6; i++) {
    4945         108 :                 torture_assert(tctx, ctr->sitename[i].string == NULL,
    4946             :                                "sitename should be null");
    4947         108 :                 torture_assert(tctx, ctr->subnetname[i].string == NULL,
    4948             :                                "subnet should be null");
    4949             :         }
    4950             : 
    4951          15 :         return true;
    4952             : }
    4953             : 
    4954          36 : static bool test_netr_ServerGetTrustInfo_flags(struct torture_context *tctx,
    4955             :                                                struct dcerpc_pipe *p1,
    4956             :                                                struct cli_credentials *machine_credentials,
    4957             :                                                uint32_t negotiate_flags)
    4958             : {
    4959           6 :         struct netr_ServerGetTrustInfo r;
    4960             : 
    4961           6 :         struct netr_Authenticator a;
    4962           6 :         struct netr_Authenticator return_authenticator;
    4963           6 :         struct samr_Password new_owf_password;
    4964           6 :         struct samr_Password old_owf_password;
    4965           6 :         struct netr_TrustInfo *trust_info;
    4966             : 
    4967           6 :         struct netlogon_creds_CredentialState *creds;
    4968          36 :         struct dcerpc_pipe *p = NULL;
    4969          36 :         struct dcerpc_binding_handle *b = NULL;
    4970             : 
    4971           6 :         struct samr_Password nt_hash;
    4972             : 
    4973          36 :         if (!test_SetupCredentials3(p1, tctx, negotiate_flags,
    4974             :                                     machine_credentials, &creds)) {
    4975           0 :                 return false;
    4976             :         }
    4977          36 :         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
    4978             :                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
    4979           0 :                 return false;
    4980             :         }
    4981          36 :         b = p->binding_handle;
    4982             : 
    4983          36 :         netlogon_creds_client_authenticator(creds, &a);
    4984             : 
    4985          36 :         r.in.server_name                = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    4986          36 :         r.in.account_name               = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
    4987          36 :         r.in.secure_channel_type        = cli_credentials_get_secure_channel_type(machine_credentials);
    4988          36 :         r.in.computer_name              = TEST_MACHINE_NAME;
    4989          36 :         r.in.credential                 = &a;
    4990             : 
    4991          36 :         r.out.return_authenticator      = &return_authenticator;
    4992          36 :         r.out.new_owf_password          = &new_owf_password;
    4993          36 :         r.out.old_owf_password          = &old_owf_password;
    4994          36 :         r.out.trust_info                = &trust_info;
    4995             : 
    4996          36 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerGetTrustInfo_r(b, tctx, &r),
    4997             :                 "ServerGetTrustInfo failed");
    4998          36 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerGetTrustInfo failed");
    4999          36 :         torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
    5000             : 
    5001          36 :         E_md4hash(cli_credentials_get_password(machine_credentials), nt_hash.hash);
    5002             : 
    5003          36 :         netlogon_creds_des_decrypt(creds, &new_owf_password);
    5004             : 
    5005          36 :         dump_data(1, new_owf_password.hash, 16);
    5006          36 :         dump_data(1, nt_hash.hash, 16);
    5007             : 
    5008          36 :         torture_assert_mem_equal(tctx, new_owf_password.hash, nt_hash.hash, 16,
    5009             :                 "received unexpected owf password\n");
    5010             : 
    5011          30 :         return true;
    5012             : }
    5013             : 
    5014          18 : static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
    5015             :                                          struct dcerpc_pipe *p,
    5016             :                                          struct cli_credentials *machine_credentials)
    5017             : {
    5018          18 :         return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
    5019             :                                                   NETLOGON_NEG_AUTH2_ADS_FLAGS);
    5020             : }
    5021             : 
    5022          18 : static bool test_netr_ServerGetTrustInfo_AES(struct torture_context *tctx,
    5023             :                                              struct dcerpc_pipe *p,
    5024             :                                              struct cli_credentials *machine_credentials)
    5025             : {
    5026          18 :         return test_netr_ServerGetTrustInfo_flags(tctx, p, machine_credentials,
    5027             :                                                   NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
    5028             : }
    5029             : 
    5030          18 : static bool test_GetDomainInfo(struct torture_context *tctx,
    5031             :                                struct dcerpc_pipe *p1,
    5032             :                                struct cli_credentials *machine_credentials)
    5033             : {
    5034           3 :         struct netr_LogonGetDomainInfo r;
    5035           3 :         struct netr_WorkstationInformation q1;
    5036           3 :         struct netr_Authenticator a;
    5037           3 :         struct netlogon_creds_CredentialState *creds;
    5038           3 :         struct netr_OsVersion os;
    5039           3 :         union netr_WorkstationInfo query;
    5040           3 :         union netr_DomainInfo info;
    5041          18 :         const char* const attrs[] = { "dNSHostName", "operatingSystem",
    5042             :                 "operatingSystemServicePack", "operatingSystemVersion",
    5043             :                 "servicePrincipalName", NULL };
    5044           3 :         char *url;
    5045          18 :         struct ldb_context *sam_ctx = NULL;
    5046           3 :         struct ldb_message **res;
    5047           3 :         struct ldb_message_element *spn_el;
    5048           3 :         int ret, i;
    5049           3 :         char *version_str;
    5050          18 :         const char *old_dnsname = NULL;
    5051          18 :         char **spns = NULL;
    5052          18 :         int num_spns = 0;
    5053          18 :         char *temp_str = NULL;
    5054          18 :         char *temp_str2 = NULL;
    5055          18 :         struct dcerpc_pipe *p = NULL;
    5056          18 :         struct dcerpc_binding_handle *b = NULL;
    5057          18 :         struct netr_OneDomainInfo *odi1 = NULL;
    5058          18 :         struct netr_OneDomainInfo *odi2 = NULL;
    5059          18 :         struct netr_trust_extension_info *tex2 = NULL;
    5060             : 
    5061          18 :         torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
    5062             : 
    5063          18 :         if (!test_SetupCredentials3(p1, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
    5064             :                                     machine_credentials, &creds)) {
    5065           0 :                 return false;
    5066             :         }
    5067          18 :         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
    5068             :                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
    5069           0 :                 return false;
    5070             :         }
    5071          18 :         b = p->binding_handle;
    5072             : 
    5073             :         /* We won't double-check this when we are over 'local' transports */
    5074          18 :         if (dcerpc_server_name(p)) {
    5075             :                 /* Set up connection to SAMDB on DC */
    5076          15 :                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
    5077          15 :                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
    5078             :                                            NULL,
    5079             :                                            samba_cmdline_get_creds(),
    5080             :                                            0);
    5081             : 
    5082          15 :                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
    5083             :         }
    5084             : 
    5085          18 :         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
    5086          18 :         netlogon_creds_client_authenticator(creds, &a);
    5087             : 
    5088          18 :         ZERO_STRUCT(r);
    5089          18 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    5090          18 :         r.in.computer_name = TEST_MACHINE_NAME;
    5091          18 :         r.in.credential = &a;
    5092          18 :         r.in.level = 1;
    5093          18 :         r.in.return_authenticator = &a;
    5094          18 :         r.in.query = &query;
    5095          18 :         r.out.return_authenticator = &a;
    5096          18 :         r.out.info = &info;
    5097             : 
    5098          18 :         ZERO_STRUCT(os);
    5099          18 :         os.os.MajorVersion = 123;
    5100          18 :         os.os.MinorVersion = 456;
    5101          18 :         os.os.BuildNumber = 789;
    5102          18 :         os.os.CSDVersion = "Service Pack 10";
    5103          18 :         os.os.ServicePackMajor = 10;
    5104          18 :         os.os.ServicePackMinor = 1;
    5105          18 :         os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
    5106          18 :         os.os.ProductType = NETR_VER_NT_SERVER;
    5107          18 :         os.os.Reserved = 0;
    5108             : 
    5109          18 :         version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
    5110             :                 os.os.MinorVersion, os.os.BuildNumber);
    5111             : 
    5112          18 :         ZERO_STRUCT(q1);
    5113          18 :         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
    5114             :                 lpcfg_dnsdomain(tctx->lp_ctx));
    5115          18 :         q1.sitename = "Default-First-Site-Name";
    5116          18 :         q1.os_version.os = &os;
    5117          18 :         q1.os_name.string = talloc_asprintf(tctx,
    5118             :                                             "Tortured by Samba4 RPC-NETLOGON: %s",
    5119             :                                             timestring(tctx, time(NULL)));
    5120             : 
    5121             :         /* The workstation handles the "servicePrincipalName" and DNS hostname
    5122             :            updates */
    5123          18 :         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
    5124             : 
    5125          18 :         query.workstation_info = &q1;
    5126             : 
    5127          18 :         if (sam_ctx) {
    5128             :                 /* Gets back the old DNS hostname in AD */
    5129          15 :                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
    5130             :                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
    5131           3 :                 old_dnsname =
    5132          15 :                         ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
    5133             : 
    5134             :                 /* Gets back the "servicePrincipalName"s in AD */
    5135          15 :                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
    5136          15 :                 if (spn_el != NULL) {
    5137          45 :                         for (i=0; i < spn_el->num_values; i++) {
    5138          30 :                                 spns = talloc_realloc(tctx, spns, char *, i + 1);
    5139          30 :                                 spns[i] = (char *) spn_el->values[i].data;
    5140             :                         }
    5141          12 :                         num_spns = i;
    5142             :                 }
    5143             :         }
    5144             : 
    5145          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
    5146             :                 "LogonGetDomainInfo failed");
    5147          18 :         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
    5148          18 :         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
    5149             : 
    5150          18 :         smb_msleep(250);
    5151             : 
    5152          18 :         if (sam_ctx) {
    5153             :                 /* AD workstation infos entry check */
    5154          15 :                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
    5155             :                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
    5156          15 :                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
    5157          15 :                 torture_assert_str_equal(tctx,
    5158             :                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
    5159             :                                          q1.os_name.string, "'operatingSystem' wrong!");
    5160          15 :                 torture_assert_str_equal(tctx,
    5161             :                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
    5162             :                                          os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
    5163          15 :                 torture_assert_str_equal(tctx,
    5164             :                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
    5165             :                                          version_str, "'operatingSystemVersion' wrong!");
    5166             : 
    5167          15 :                 if (old_dnsname != NULL) {
    5168             :                         /* If before a DNS hostname was set then it should remain
    5169             :                            the same in combination with the "servicePrincipalName"s.
    5170             :                            The DNS hostname should also be returned by our
    5171             :                            "LogonGetDomainInfo" call (in the domain info structure). */
    5172             : 
    5173          15 :                         torture_assert_str_equal(tctx,
    5174             :                                                  ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
    5175             :                                                  old_dnsname, "'DNS hostname' was not set!");
    5176             : 
    5177          15 :                         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
    5178          15 :                         torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
    5179             :                                        "'servicePrincipalName's not set!");
    5180          15 :                         torture_assert(tctx, spn_el->num_values == num_spns,
    5181             :                                        "'servicePrincipalName's incorrect!");
    5182          45 :                         for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
    5183          30 :                                 torture_assert_str_equal(tctx,
    5184             :                                                          (char *) spn_el->values[i].data,
    5185             :                                 spns[i], "'servicePrincipalName's incorrect!");
    5186             : 
    5187          15 :                         torture_assert_str_equal(tctx,
    5188             :                                                  info.domain_info->dns_hostname.string,
    5189             :                                                  old_dnsname,
    5190             :                                                  "Out 'DNS hostname' doesn't match the old one!");
    5191             :                 } else {
    5192             :                         /* If no DNS hostname was set then also now none should be set,
    5193             :                            the "servicePrincipalName"s should remain empty and no DNS
    5194             :                            hostname should be returned by our "LogonGetDomainInfo"
    5195             :                            call (in the domain info structure). */
    5196             : 
    5197           0 :                         torture_assert(tctx,
    5198             :                                        ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
    5199             :                                        "'DNS hostname' was set!");
    5200             : 
    5201           0 :                         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
    5202           0 :                         torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
    5203             :                                        "'servicePrincipalName's were set!");
    5204             : 
    5205           0 :                         torture_assert(tctx,
    5206             :                                        info.domain_info->dns_hostname.string == NULL,
    5207             :                                        "Out 'DNS host name' was set!");
    5208             :                 }
    5209             :         }
    5210             : 
    5211             :         /* Checks "workstation flags" */
    5212          18 :         torture_assert(tctx,
    5213             :                 info.domain_info->workstation_flags
    5214             :                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
    5215             :                 "Out 'workstation flags' don't match!");
    5216             : 
    5217             : 
    5218          18 :         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname doesn't work)\n");
    5219          18 :         netlogon_creds_client_authenticator(creds, &a);
    5220             : 
    5221             :         /* Wipe out the CSDVersion, and prove which values still 'stick' */
    5222          18 :         os.os.CSDVersion = "";
    5223             : 
    5224             :         /* Change also the DNS hostname to test differences in behaviour */
    5225          18 :         talloc_free(discard_const_p(char, q1.dns_hostname));
    5226          18 :         q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
    5227             :                 lpcfg_dnsdomain(tctx->lp_ctx));
    5228             : 
    5229             :         /* The workstation handles the "servicePrincipalName" and DNS hostname
    5230             :            updates */
    5231          18 :         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
    5232             : 
    5233          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
    5234             :                 "LogonGetDomainInfo failed");
    5235          18 :         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
    5236             : 
    5237          18 :         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
    5238             : 
    5239          18 :         smb_msleep(250);
    5240             : 
    5241          18 :         if (sam_ctx) {
    5242             :                 /* AD workstation infos entry check */
    5243          15 :                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
    5244             :                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
    5245          15 :                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
    5246             : 
    5247          15 :                 torture_assert_str_equal(tctx,
    5248             :                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
    5249             :                                          q1.os_name.string, "'operatingSystem' should stick!");
    5250          15 :                 torture_assert(tctx,
    5251             :                                ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
    5252             :                                "'operatingSystemServicePack' shouldn't stick!");
    5253          15 :                 torture_assert_str_equal(tctx,
    5254             :                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
    5255             :                                          version_str, "'operatingSystemVersion' wrong!");
    5256             : 
    5257             :                 /* The DNS host name shouldn't have been updated by the server */
    5258             : 
    5259          15 :                 torture_assert_str_equal(tctx,
    5260             :                                          ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
    5261             :                                          old_dnsname, "'DNS host name' did change!");
    5262             : 
    5263             :                 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
    5264             :                    updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
    5265             :                    3.5.4.3.9 */
    5266          15 :                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
    5267          15 :                 torture_assert(tctx, spn_el != NULL,
    5268             :                                "There should exist 'servicePrincipalName's in AD!");
    5269          15 :                 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
    5270          33 :                 for (i=0; i < spn_el->num_values; i++)
    5271          30 :                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
    5272          12 :                                 break;
    5273          15 :                 torture_assert(tctx, i != spn_el->num_values,
    5274             :                                "'servicePrincipalName' HOST/<Netbios name> not found!");
    5275          15 :                 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
    5276          18 :                 for (i=0; i < spn_el->num_values; i++)
    5277          15 :                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
    5278          12 :                                 break;
    5279          15 :                 torture_assert(tctx, i != spn_el->num_values,
    5280             :                                "'servicePrincipalName' HOST/<FQDN name> not found!");
    5281             : 
    5282             :                 /* Check that the out DNS hostname was set properly */
    5283          15 :                 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
    5284             :                                          old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
    5285             :         }
    5286             : 
    5287             :         /* Checks "workstation flags" */
    5288          18 :         torture_assert(tctx,
    5289             :                 info.domain_info->workstation_flags == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
    5290             :                 "Out 'workstation flags' don't match!");
    5291             : 
    5292             : 
    5293             :         /* Now try the same but the workstation flags set to 0 */
    5294             : 
    5295          18 :         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (variation of DNS hostname doesn't work)\n");
    5296          18 :         netlogon_creds_client_authenticator(creds, &a);
    5297             : 
    5298             :         /* Change also the DNS hostname to test differences in behaviour */
    5299          18 :         talloc_free(discard_const_p(char, q1.dns_hostname));
    5300          18 :         q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
    5301             :                 lpcfg_dnsdomain(tctx->lp_ctx));
    5302             : 
    5303             :         /* Wipe out the osVersion, and prove which values still 'stick' */
    5304          18 :         q1.os_version.os = NULL;
    5305             : 
    5306             :         /* Let the DC handle the "servicePrincipalName" and DNS hostname
    5307             :            updates */
    5308          18 :         q1.workstation_flags = 0;
    5309             : 
    5310          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
    5311             :                 "LogonGetDomainInfo failed");
    5312          18 :         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
    5313          18 :         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
    5314             : 
    5315          18 :         smb_msleep(250);
    5316             : 
    5317          18 :         if (sam_ctx) {
    5318             :                 /* AD workstation infos entry check */
    5319          15 :                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
    5320             :                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
    5321          15 :                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
    5322             : 
    5323          15 :                 torture_assert_str_equal(tctx,
    5324             :                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
    5325             :                                          q1.os_name.string, "'operatingSystem' should stick!");
    5326          15 :                 torture_assert(tctx,
    5327             :                                ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
    5328             :                                "'operatingSystemServicePack' shouldn't stick!");
    5329          15 :                 torture_assert_str_equal(tctx,
    5330             :                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
    5331             :                                          version_str, "'operatingSystemVersion' wrong!");
    5332             : 
    5333             :                 /* The DNS host name shouldn't have been updated by the server */
    5334             : 
    5335          15 :                 torture_assert_str_equal(tctx,
    5336             :                                          ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
    5337             :                                          old_dnsname, "'DNS host name' did change!");
    5338             : 
    5339             :                 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
    5340             :                    updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
    5341             :                    3.5.4.3.9 */
    5342          15 :                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
    5343          15 :                 torture_assert(tctx, spn_el != NULL,
    5344             :                                "There should exist 'servicePrincipalName's in AD!");
    5345          15 :                 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
    5346          33 :                 for (i=0; i < spn_el->num_values; i++)
    5347          30 :                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
    5348          12 :                                 break;
    5349          15 :                 torture_assert(tctx, i != spn_el->num_values,
    5350             :                                "'servicePrincipalName' HOST/<Netbios name> not found!");
    5351          15 :                 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
    5352          18 :                 for (i=0; i < spn_el->num_values; i++)
    5353          15 :                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
    5354          12 :                                 break;
    5355          15 :                 torture_assert(tctx, i != spn_el->num_values,
    5356             :                                "'servicePrincipalName' HOST/<FQDN name> not found!");
    5357             : 
    5358             :                 /* Here the server gives us NULL as the out DNS hostname */
    5359          15 :                 torture_assert(tctx, info.domain_info->dns_hostname.string == NULL,
    5360             :                                "Out 'DNS hostname' should be NULL!");
    5361             :         }
    5362             : 
    5363             :         /* Checks "workstation flags" */
    5364          18 :         torture_assert(tctx,
    5365             :                 info.domain_info->workstation_flags == 0,
    5366             :                 "Out 'workstation flags' don't match!");
    5367             : 
    5368             : 
    5369          18 :         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (verification of DNS hostname and check for trusted domains)\n");
    5370          18 :         netlogon_creds_client_authenticator(creds, &a);
    5371             : 
    5372             :         /* Put the DNS hostname back */
    5373          18 :         talloc_free(discard_const_p(char, q1.dns_hostname));
    5374          18 :         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
    5375             :                 lpcfg_dnsdomain(tctx->lp_ctx));
    5376             : 
    5377             :         /* The workstation handles the "servicePrincipalName" and DNS hostname
    5378             :            updates */
    5379          18 :         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
    5380             : 
    5381          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
    5382             :                 "LogonGetDomainInfo failed");
    5383          18 :         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
    5384          18 :         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
    5385             : 
    5386          18 :         smb_msleep(250);
    5387             : 
    5388             :         /* Now the in/out DNS hostnames should be the same */
    5389          18 :         torture_assert_str_equal(tctx,
    5390             :                 info.domain_info->dns_hostname.string,
    5391             :                 query.workstation_info->dns_hostname,
    5392             :                 "In/Out 'DNS hostnames' don't match!");
    5393          18 :         old_dnsname = info.domain_info->dns_hostname.string;
    5394             : 
    5395             :         /* Checks "workstation flags" */
    5396          18 :         torture_assert(tctx,
    5397             :                 info.domain_info->workstation_flags
    5398             :                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
    5399             :                 "Out 'workstation flags' don't match!");
    5400             : 
    5401             :         /* Checks for trusted domains */
    5402          18 :         torture_assert(tctx,
    5403             :                 (info.domain_info->trusted_domain_count != 0)
    5404             :                 && (info.domain_info->trusted_domains != NULL),
    5405             :                 "Trusted domains have been requested!");
    5406             : 
    5407             : 
    5408          18 :         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 5th call (check for trusted domains)\n");
    5409          18 :         netlogon_creds_client_authenticator(creds, &a);
    5410             : 
    5411             :         /* The workstation handles the "servicePrincipalName" and DNS hostname
    5412             :            updates and requests inbound trusts */
    5413          18 :         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
    5414             :                 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
    5415             : 
    5416          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
    5417             :                 "LogonGetDomainInfo failed");
    5418          18 :         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
    5419          18 :         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
    5420             : 
    5421          18 :         smb_msleep(250);
    5422             : 
    5423             :         /* Checks "workstation flags" */
    5424          18 :         torture_assert(tctx,
    5425             :                 info.domain_info->workstation_flags
    5426             :                 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
    5427             :                         | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
    5428             :                 "Out 'workstation flags' don't match!");
    5429             : 
    5430             :         /* Checks for trusted domains */
    5431          18 :         torture_assert(tctx,
    5432             :                 (info.domain_info->trusted_domain_count != 0)
    5433             :                 && (info.domain_info->trusted_domains != NULL),
    5434             :                 "Trusted domains have been requested!");
    5435             : 
    5436          18 :         odi1 = &info.domain_info->primary_domain;
    5437             : 
    5438          18 :         torture_assert(tctx, !GUID_all_zero(&odi1->domain_guid),
    5439             :                        "primary domain_guid needs to be valid");
    5440             : 
    5441          36 :         for (i=0; i < info.domain_info->trusted_domain_count; i++) {
    5442          18 :                 struct netr_OneDomainInfo *odiT =
    5443          18 :                         &info.domain_info->trusted_domains[i];
    5444          18 :                 struct netr_trust_extension_info *texT = NULL;
    5445             : 
    5446          18 :                 torture_assert_int_equal(tctx, odiT->trust_extension.length, 16,
    5447             :                                          "trust_list should have extension");
    5448          18 :                 torture_assert(tctx, odiT->trust_extension.info != NULL,
    5449             :                                "trust_list should have extension");
    5450          18 :                 texT = &odiT->trust_extension.info->info;
    5451             : 
    5452          18 :                 if (GUID_equal(&odiT->domain_guid, &odi1->domain_guid)) {
    5453          18 :                         odi2 = odiT;
    5454          18 :                         tex2 = texT;
    5455          18 :                         continue;
    5456             :                 }
    5457             : 
    5458           0 :                 torture_assert_int_equal(tctx,
    5459             :                                  texT->flags & NETR_TRUST_FLAG_PRIMARY,
    5460             :                                  0,
    5461             :                                  "trust_list flags should not have PRIMARY");
    5462             : 
    5463           0 :                 torture_assert(tctx, odiT->domainname.string != NULL,
    5464             :                                "trust_list domainname should be valid");
    5465           0 :                 if (texT->trust_type == LSA_TRUST_TYPE_DOWNLEVEL ||
    5466           0 :                     texT->trust_type == LSA_TRUST_TYPE_MIT)
    5467             :                 {
    5468           0 :                         torture_assert(tctx, odiT->dns_domainname.string == NULL,
    5469             :                                "trust_list dns_domainname should be NULL for downlevel or MIT");
    5470             :                 } else {
    5471           0 :                         torture_assert(tctx, odiT->dns_domainname.string != NULL,
    5472             :                                "trust_list dns_domainname should be valid for uplevel");
    5473             :                 }
    5474           0 :                 torture_assert(tctx, odiT->dns_forestname.string == NULL,
    5475             :                                "trust_list dns_forestname needs to be NULL");
    5476             : 
    5477           3 :                 torture_assert(tctx, odiT->domain_sid != NULL,
    5478             :                                "trust_list domain_sid needs to be valid");
    5479             :         }
    5480             : 
    5481          18 :         torture_assert(tctx, odi2 != NULL,
    5482             :                        "trust_list primary domain not found.");
    5483             : 
    5484          18 :         torture_assert_str_equal(tctx,
    5485             :                                  odi1->domainname.string,
    5486             :                                  odi2->domainname.string,
    5487             :                                  "netbios name should match");
    5488             : 
    5489          18 :         temp_str = talloc_strdup(tctx, odi1->dns_domainname.string);
    5490          18 :         torture_assert(tctx, temp_str != NULL,
    5491             :                        "primary_domain dns_domainname copy");
    5492          18 :         temp_str2 = strrchr(temp_str, '.');
    5493          18 :         torture_assert(tctx, temp_str2 != NULL && temp_str2[1] == '\0',
    5494             :                        "primary_domain dns_domainname needs trailing '.'");
    5495          18 :         temp_str2[0] = '\0';
    5496          18 :         torture_assert_str_equal(tctx,
    5497             :                                  temp_str,
    5498             :                                  odi2->dns_domainname.string,
    5499             :                                  "dns domainname should match "
    5500             :                                  "(without trailing '.')");
    5501             : 
    5502          18 :         temp_str = talloc_strdup(tctx, odi1->dns_forestname.string);
    5503          18 :         torture_assert(tctx, temp_str != NULL,
    5504             :                        "primary_domain dns_forestname copy");
    5505          18 :         temp_str2 = strrchr(temp_str, '.');
    5506          18 :         torture_assert(tctx, temp_str2 != NULL && temp_str2[1] == '\0',
    5507             :                        "primary_domain dns_forestname needs trailing '.'");
    5508          18 :         temp_str2[0] = '\0';
    5509          18 :         torture_assert(tctx, odi2->dns_forestname.string == NULL,
    5510             :                        "trust_list dns_forestname needs to be NULL");
    5511             : 
    5512          18 :         torture_assert_guid_equal(tctx, odi1->domain_guid, odi2->domain_guid,
    5513             :                                   "domain_guid should match");
    5514          18 :         torture_assert(tctx, odi1->domain_sid != NULL,
    5515             :                        "primary domain_sid needs to be valid");
    5516          18 :         torture_assert(tctx, odi2->domain_sid != NULL,
    5517             :                        "trust_list domain_sid needs to be valid");
    5518          18 :         torture_assert_sid_equal(tctx, odi1->domain_sid, odi2->domain_sid,
    5519             :                                  "domain_sid should match");
    5520             : 
    5521          18 :         torture_assert_int_equal(tctx, odi1->trust_extension.length, 0,
    5522             :                                  "primary_domain should not have extension");
    5523          18 :         torture_assert_int_equal(tctx, odi2->trust_extension.length, 16,
    5524             :                                  "trust_list should have extension");
    5525          18 :         torture_assert(tctx, odi2->trust_extension.info != NULL,
    5526             :                        "trust_list should have extension");
    5527          18 :         tex2 = &odi2->trust_extension.info->info;
    5528          18 :         torture_assert_int_equal(tctx,
    5529             :                                  tex2->flags & NETR_TRUST_FLAG_PRIMARY,
    5530             :                                  NETR_TRUST_FLAG_PRIMARY,
    5531             :                                  "trust_list flags should have PRIMARY");
    5532          18 :         torture_assert_int_equal(tctx,
    5533             :                                  tex2->flags & NETR_TRUST_FLAG_IN_FOREST,
    5534             :                                  NETR_TRUST_FLAG_IN_FOREST,
    5535             :                                  "trust_list flags should have IN_FOREST");
    5536          18 :         torture_assert_int_equal(tctx,
    5537             :                                  tex2->flags & NETR_TRUST_FLAG_NATIVE,
    5538             :                                  NETR_TRUST_FLAG_NATIVE,
    5539             :                                  "trust_list flags should have NATIVE");
    5540          18 :         torture_assert_int_equal(tctx,
    5541             :                                  tex2->flags & ~NETR_TRUST_FLAG_TREEROOT,
    5542             :                                  NETR_TRUST_FLAG_IN_FOREST |
    5543             :                                  NETR_TRUST_FLAG_PRIMARY |
    5544             :                                  NETR_TRUST_FLAG_NATIVE,
    5545             :                                  "trust_list flags IN_FOREST, PRIMARY, NATIVE "
    5546             :                                  "(TREEROOT optional)");
    5547          18 :         if (strcmp(odi1->dns_domainname.string, odi1->dns_forestname.string) == 0) {
    5548          18 :                 torture_assert_int_equal(tctx,
    5549             :                                          tex2->flags & NETR_TRUST_FLAG_TREEROOT,
    5550             :                                          NETR_TRUST_FLAG_TREEROOT,
    5551             :                                          "trust_list flags TREEROOT on forest root");
    5552          18 :                 torture_assert_int_equal(tctx,
    5553             :                                          tex2->parent_index, 0,
    5554             :                                          "trust_list no parent on forest root");
    5555             :         }
    5556          18 :         torture_assert_int_equal(tctx,
    5557             :                                  tex2->trust_type, LSA_TRUST_TYPE_UPLEVEL,
    5558             :                                  "trust_list uplevel");
    5559          18 :         torture_assert_int_equal(tctx,
    5560             :                                  tex2->trust_attributes, 0,
    5561             :                                  "trust_list no attributes");
    5562             : 
    5563          18 :         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
    5564          18 :         netlogon_creds_client_authenticator(creds, &a);
    5565             : 
    5566          18 :         query.workstation_info->dns_hostname = NULL;
    5567             : 
    5568          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
    5569             :                 "LogonGetDomainInfo failed");
    5570          18 :         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
    5571          18 :         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
    5572             : 
    5573             :         /* The old DNS hostname should stick */
    5574          18 :         torture_assert_str_equal(tctx,
    5575             :                 info.domain_info->dns_hostname.string,
    5576             :                 old_dnsname,
    5577             :                 "'DNS hostname' changed!");
    5578             : 
    5579          18 :         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (extra workstation flags)\n");
    5580          18 :         netlogon_creds_client_authenticator(creds, &a);
    5581             : 
    5582          18 :         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
    5583             :                 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | 0x4;
    5584             : 
    5585             :         /* Put the DNS hostname back */
    5586          18 :         talloc_free(discard_const_p(char, q1.dns_hostname));
    5587          18 :         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
    5588             :                 lpcfg_dnsdomain(tctx->lp_ctx));
    5589             : 
    5590          18 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
    5591             :                 "LogonGetDomainInfo failed");
    5592          18 :         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
    5593          18 :         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
    5594             : 
    5595             :         /* Checks "workstation flags" */
    5596          18 :         torture_assert(tctx,
    5597             :                 info.domain_info->workstation_flags
    5598             :                 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
    5599             :                         | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
    5600             :                 "Out 'workstation flags' don't match!");
    5601             : 
    5602          18 :         if (!torture_setting_bool(tctx, "dangerous", false)) {
    5603          18 :                 torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 8th call (no workstation info) - enable dangerous tests in order to do so\n");
    5604             :         } else {
    5605             :                 /* Try a call without the workstation information structure */
    5606             : 
    5607           0 :                 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 8th call (no workstation info)\n");
    5608           0 :                 netlogon_creds_client_authenticator(creds, &a);
    5609             : 
    5610           0 :                 query.workstation_info = NULL;
    5611             : 
    5612           0 :                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
    5613             :                         "LogonGetDomainInfo failed");
    5614           0 :                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
    5615           0 :                 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
    5616             :         }
    5617             : 
    5618          15 :         return true;
    5619             : }
    5620             : 
    5621           0 : static bool test_GetDomainInfo_async(struct torture_context *tctx,
    5622             :                                      struct dcerpc_pipe *p1,
    5623             :                                      struct cli_credentials *machine_credentials)
    5624             : {
    5625           0 :         NTSTATUS status;
    5626           0 :         struct netr_LogonGetDomainInfo r;
    5627           0 :         struct netr_WorkstationInformation q1;
    5628           0 :         struct netr_Authenticator a;
    5629             : #define ASYNC_COUNT 100
    5630           0 :         struct netlogon_creds_CredentialState *creds;
    5631           0 :         struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
    5632           0 :         struct tevent_req *req[ASYNC_COUNT];
    5633           0 :         int i;
    5634           0 :         union netr_WorkstationInfo query;
    5635           0 :         union netr_DomainInfo info;
    5636           0 :         struct dcerpc_pipe *p = NULL;
    5637             : 
    5638           0 :         torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
    5639             : 
    5640           0 :         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
    5641             :                                     machine_credentials, &creds)) {
    5642           0 :                 return false;
    5643             :         }
    5644           0 :         if (!test_SetupCredentialsPipe(p1, tctx, machine_credentials, creds,
    5645             :                                        DCERPC_SIGN | DCERPC_SEAL, &p)) {
    5646           0 :                 return false;
    5647             :         }
    5648             : 
    5649           0 :         ZERO_STRUCT(r);
    5650           0 :         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
    5651           0 :         r.in.computer_name = TEST_MACHINE_NAME;
    5652           0 :         r.in.credential = &a;
    5653           0 :         r.in.level = 1;
    5654           0 :         r.in.return_authenticator = &a;
    5655           0 :         r.in.query = &query;
    5656           0 :         r.out.return_authenticator = &a;
    5657           0 :         r.out.info = &info;
    5658             : 
    5659           0 :         ZERO_STRUCT(q1);
    5660           0 :         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
    5661             :                 lpcfg_dnsdomain(tctx->lp_ctx));
    5662           0 :         q1.sitename = "Default-First-Site-Name";
    5663           0 :         q1.os_name.string = "UNIX/Linux or similar";
    5664             : 
    5665           0 :         query.workstation_info = &q1;
    5666             : 
    5667           0 :         for (i=0;i<ASYNC_COUNT;i++) {
    5668           0 :                 netlogon_creds_client_authenticator(creds, &a);
    5669             : 
    5670           0 :                 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
    5671           0 :                 req[i] = dcerpc_netr_LogonGetDomainInfo_r_send(tctx, tctx->ev, p->binding_handle, &r);
    5672             : 
    5673             :                 /* even with this flush per request a w2k3 server seems to
    5674             :                    clag with multiple outstanding requests. bleergh. */
    5675           0 :                 torture_assert_int_equal(tctx, tevent_loop_once(tctx->ev), 0,
    5676             :                                          "tevent_loop_once failed");
    5677             :         }
    5678             : 
    5679           0 :         for (i=0;i<ASYNC_COUNT;i++) {
    5680           0 :                 torture_assert_int_equal(tctx, tevent_req_poll(req[i], tctx->ev), true,
    5681             :                                          "tevent_req_poll() failed");
    5682             : 
    5683           0 :                 status = dcerpc_netr_LogonGetDomainInfo_r_recv(req[i], tctx);
    5684             : 
    5685           0 :                 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
    5686           0 :                 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
    5687             : 
    5688           0 :                 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred),
    5689             :                         "Credential chaining failed at async");
    5690             :         }
    5691             : 
    5692           0 :         torture_comment(tctx,
    5693             :                         "Testing netr_LogonGetDomainInfo - async count %d OK\n", ASYNC_COUNT);
    5694             : 
    5695           0 :         return true;
    5696             : }
    5697             : 
    5698          18 : static bool test_ManyGetDCName(struct torture_context *tctx,
    5699             :                                struct dcerpc_pipe *p)
    5700             : {
    5701           3 :         NTSTATUS status;
    5702           3 :         struct cli_credentials *anon_creds;
    5703           3 :         struct dcerpc_binding *binding2;
    5704           3 :         struct dcerpc_pipe *p2;
    5705           3 :         struct lsa_ObjectAttribute attr;
    5706           3 :         struct lsa_QosInfo qos;
    5707           3 :         struct lsa_OpenPolicy2 o;
    5708           3 :         struct policy_handle lsa_handle;
    5709           3 :         struct lsa_DomainList domains;
    5710             : 
    5711           3 :         struct lsa_EnumTrustDom t;
    5712          18 :         uint32_t resume_handle = 0;
    5713           3 :         struct netr_GetAnyDCName d;
    5714          18 :         const char *dcname = NULL;
    5715          18 :         struct dcerpc_binding_handle *b = p->binding_handle;
    5716           3 :         struct dcerpc_binding_handle *b2;
    5717             : 
    5718           3 :         int i;
    5719             : 
    5720          18 :         if (p->conn->transport.transport != NCACN_NP) {
    5721           6 :                 torture_skip(tctx, "test_ManyGetDCName works only with NCACN_NP");
    5722             :         }
    5723             : 
    5724          12 :         torture_comment(tctx, "Torturing GetDCName\n");
    5725             : 
    5726          12 :         anon_creds = cli_credentials_init_anon(tctx);
    5727          12 :         torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed");
    5728             : 
    5729          12 :         binding2 = dcerpc_binding_dup(tctx, p->binding);
    5730             :         /* Swap the binding details from NETLOGON to LSA */
    5731          12 :         status = dcerpc_epm_map_binding(tctx, binding2, &ndr_table_lsarpc, tctx->ev, tctx->lp_ctx);
    5732          12 :         dcerpc_binding_set_assoc_group_id(binding2, 0);
    5733          12 :         torture_assert_ntstatus_ok(tctx, status, "epm map");
    5734             : 
    5735          12 :         status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_lsarpc,
    5736             :                                                   anon_creds, tctx->lp_ctx,
    5737             :                                                   tctx, &p2);
    5738          12 :         torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
    5739          12 :         b2 = p2->binding_handle;
    5740             : 
    5741          12 :         qos.len = 0;
    5742          12 :         qos.impersonation_level = 2;
    5743          12 :         qos.context_mode = 1;
    5744          12 :         qos.effective_only = 0;
    5745             : 
    5746          12 :         attr.len = 0;
    5747          12 :         attr.root_dir = NULL;
    5748          12 :         attr.object_name = NULL;
    5749          12 :         attr.attributes = 0;
    5750          12 :         attr.sec_desc = NULL;
    5751          12 :         attr.sec_qos = &qos;
    5752             : 
    5753          12 :         o.in.system_name = "\\";
    5754          12 :         o.in.attr = &attr;
    5755          12 :         o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    5756          12 :         o.out.handle = &lsa_handle;
    5757             : 
    5758          12 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
    5759             :                 "OpenPolicy2 failed");
    5760          12 :         torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
    5761             : 
    5762          12 :         t.in.handle = &lsa_handle;
    5763          12 :         t.in.resume_handle = &resume_handle;
    5764          12 :         t.in.max_size = 1000;
    5765          12 :         t.out.domains = &domains;
    5766          12 :         t.out.resume_handle = &resume_handle;
    5767             : 
    5768          12 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b2, tctx, &t),
    5769             :                 "EnumTrustDom failed");
    5770             : 
    5771          12 :         if ((!NT_STATUS_IS_OK(t.out.result) &&
    5772           9 :              (!NT_STATUS_EQUAL(t.out.result, NT_STATUS_NO_MORE_ENTRIES))))
    5773           0 :                 torture_fail(tctx, "Could not list domains");
    5774             : 
    5775          12 :         talloc_free(p2);
    5776             : 
    5777          12 :         d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
    5778             :                                             dcerpc_server_name(p));
    5779          12 :         d.out.dcname = &dcname;
    5780             : 
    5781          12 :         for (i=0; i<domains.count * 4; i++) {
    5782           0 :                 struct lsa_DomainInfo *info =
    5783           0 :                         &domains.domains[rand()%domains.count];
    5784             : 
    5785           0 :                 d.in.domainname = info->name.string;
    5786             : 
    5787           0 :                 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &d);
    5788           0 :                 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
    5789             : 
    5790           0 :                 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
    5791           0 :                        dcname ? dcname : "unknown");
    5792             :         }
    5793             : 
    5794           9 :         return true;
    5795             : }
    5796             : 
    5797          18 : static bool test_lsa_over_netlogon(struct torture_context *tctx,
    5798             :                                    struct dcerpc_pipe *p)
    5799             : {
    5800           3 :         NTSTATUS status;
    5801           3 :         struct cli_credentials *anon_creds;
    5802           3 :         const struct dcerpc_binding *binding2;
    5803           3 :         struct dcerpc_pipe *p2;
    5804           3 :         struct lsa_ObjectAttribute attr;
    5805           3 :         struct lsa_QosInfo qos;
    5806           3 :         struct lsa_OpenPolicy2 o;
    5807           3 :         struct policy_handle lsa_handle;
    5808             : 
    5809           3 :         struct dcerpc_binding_handle *b2;
    5810             : 
    5811             : 
    5812          18 :         if (p->conn->transport.transport != NCACN_NP) {
    5813           6 :                 torture_skip(tctx, "test_lsa_over_netlogon works only with NCACN_NP");
    5814             :         }
    5815             : 
    5816          12 :         torture_comment(tctx, "Testing if we can access the LSA server over\n"
    5817             :                         " \\\\pipe\\netlogon rather than \\\\pipe\\lsarpc\n");
    5818             : 
    5819          12 :         anon_creds = cli_credentials_init_anon(tctx);
    5820          12 :         torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed");
    5821             : 
    5822          12 :         binding2 = p->binding;
    5823             : 
    5824          12 :         status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_lsarpc,
    5825             :                                                   anon_creds, tctx->lp_ctx,
    5826             :                                                   tctx, &p2);
    5827          12 :         torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
    5828           3 :         b2 = p2->binding_handle;
    5829             : 
    5830           3 :         qos.len = 0;
    5831           3 :         qos.impersonation_level = 2;
    5832           3 :         qos.context_mode = 1;
    5833           3 :         qos.effective_only = 0;
    5834             : 
    5835           3 :         attr.len = 0;
    5836           3 :         attr.root_dir = NULL;
    5837           3 :         attr.object_name = NULL;
    5838           3 :         attr.attributes = 0;
    5839           3 :         attr.sec_desc = NULL;
    5840           3 :         attr.sec_qos = &qos;
    5841             : 
    5842           3 :         o.in.system_name = "\\";
    5843           3 :         o.in.attr = &attr;
    5844           3 :         o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    5845           3 :         o.out.handle = &lsa_handle;
    5846             : 
    5847           3 :         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
    5848             :                 "OpenPolicy2 failed");
    5849           3 :         torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
    5850             : 
    5851           3 :         talloc_free(p2);
    5852             : 
    5853           3 :         return true;
    5854             : }
    5855             : 
    5856           3 : static bool test_SetPassword_with_flags(struct torture_context *tctx,
    5857             :                                         struct dcerpc_pipe *p,
    5858             :                                         struct cli_credentials *machine_credentials)
    5859             : {
    5860           3 :         uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
    5861           0 :         struct netlogon_creds_CredentialState *creds;
    5862           0 :         int i;
    5863             : 
    5864           3 :         if (!test_SetupCredentials2(p, tctx, 0,
    5865             :                                     machine_credentials,
    5866             :                                     cli_credentials_get_secure_channel_type(machine_credentials),
    5867             :                                     &creds)) {
    5868           3 :                 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
    5869             :         }
    5870             : 
    5871           0 :         for (i=0; i < ARRAY_SIZE(flags); i++) {
    5872           0 :                 torture_assert(tctx,
    5873             :                         test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
    5874             :                         talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
    5875             :         }
    5876             : 
    5877           0 :         return true;
    5878             : }
    5879             : 
    5880        2379 : struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
    5881             : {
    5882        2379 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon");
    5883         125 :         struct torture_rpc_tcase *tcase;
    5884         125 :         struct torture_test *test;
    5885             : 
    5886        2379 :         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
    5887             :                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
    5888             : 
    5889        2379 :         torture_rpc_tcase_add_test_creds(tcase, "SetupCredentialsDowngrade", test_SetupCredentialsDowngrade);
    5890        2379 :         torture_rpc_tcase_add_test(tcase, "lsa_over_netlogon", test_lsa_over_netlogon);
    5891             : 
    5892        2379 :         torture_rpc_tcase_add_test_creds(tcase, "GetForestTrustInformation", test_netr_GetForestTrustInformation);
    5893        2379 :         torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo_AES", test_netr_ServerGetTrustInfo_AES);
    5894        2379 :         torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
    5895        2379 :         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
    5896        2379 :         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
    5897        2379 :         torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
    5898        2379 :         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
    5899        2379 :         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
    5900        2379 :         torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
    5901        2379 :         test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
    5902        2379 :         test->dangerous = true;
    5903        2379 :         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
    5904        2379 :         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
    5905        2379 :         torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
    5906        2379 :         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
    5907        2379 :         torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
    5908        2379 :         torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
    5909        2379 :         torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
    5910        2379 :         torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
    5911        2379 :         torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
    5912        2379 :         torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
    5913        2379 :         torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
    5914        2379 :         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
    5915        2379 :         torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
    5916        2379 :         torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
    5917        2379 :         torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
    5918        2379 :         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
    5919        2379 :         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
    5920        2379 :         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
    5921        2379 :         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuse", test_ServerReqChallengeReuse);
    5922        2379 :         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal4", test_ServerReqChallengeReuseGlobal4);
    5923        2379 :         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal3", test_ServerReqChallengeReuseGlobal3);
    5924        2379 :         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal2", test_ServerReqChallengeReuseGlobal2);
    5925        2379 :         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeReuseGlobal", test_ServerReqChallengeReuseGlobal);
    5926        2379 :         torture_rpc_tcase_add_test_creds(tcase, "ServerReqChallengeGlobal", test_ServerReqChallengeGlobal);
    5927        2379 :         torture_rpc_tcase_add_test_creds(tcase, "invalidAuthenticate2", test_invalidAuthenticate2);
    5928        2379 :         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
    5929        2379 :         torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
    5930        2379 :         torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
    5931             : 
    5932        2379 :         torture_rpc_tcase_add_test(tcase, "Broken RPC binding handle",
    5933             :                                    test_netr_broken_binding_handle);
    5934             : 
    5935        2379 :         return suite;
    5936             : }
    5937             : 
    5938        2379 : struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
    5939             : {
    5940        2379 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon-s3");
    5941         125 :         struct torture_rpc_tcase *tcase;
    5942             : 
    5943        2379 :         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
    5944             :                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
    5945             : 
    5946        2379 :         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
    5947        2379 :         torture_rpc_tcase_add_test_creds(tcase, "SamLogon_NULL_domain", test_SamLogon_NULL_domain);
    5948        2379 :         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
    5949        2379 :         torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
    5950        2379 :         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
    5951        2379 :         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2_AES", test_SetPassword2_AES);
    5952        2379 :         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
    5953             : 
    5954        2379 :         return suite;
    5955             : }
    5956             : 
    5957        2379 : struct torture_suite *torture_rpc_netlogon_zerologon(TALLOC_CTX *mem_ctx)
    5958             : {
    5959        2379 :         struct torture_suite *suite = torture_suite_create(
    5960             :                 mem_ctx,
    5961             :                 "netlogon.zerologon");
    5962         125 :         struct torture_rpc_tcase *tcase;
    5963             : 
    5964        2379 :         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(
    5965             :                 suite,
    5966             :                 "netlogon",
    5967             :                 &ndr_table_netlogon,
    5968             :                 TEST_MACHINE_NAME);
    5969             : 
    5970        2379 :         torture_rpc_tcase_add_test_creds(
    5971             :                 tcase,
    5972             :                 "ServerReqChallenge",
    5973             :                 test_ServerReqChallenge);
    5974        2379 :         torture_rpc_tcase_add_test_creds(
    5975             :                 tcase,
    5976             :                 "ServerReqChallenge_zero_challenge",
    5977             :                 test_ServerReqChallenge_zero_challenge);
    5978        2379 :         torture_rpc_tcase_add_test_creds(
    5979             :                 tcase,
    5980             :                 "ServerReqChallenge_5_repeats",
    5981             :                 test_ServerReqChallenge_5_repeats);
    5982        2379 :         torture_rpc_tcase_add_test_creds(
    5983             :                 tcase,
    5984             :                 "ServerReqChallenge_4_repeats",
    5985             :                 test_ServerReqChallenge_4_repeats);
    5986        2379 :         torture_rpc_tcase_add_test_creds(
    5987             :                 tcase,
    5988             :                 "test_SetPassword2_encrypted_to_all_zeros",
    5989             :                 test_SetPassword2_encrypted_to_all_zeros);
    5990        2379 :         torture_rpc_tcase_add_test_creds(
    5991             :                 tcase,
    5992             :                 "test_SetPassword2_password_encrypts_to_zero",
    5993             :                 test_SetPassword2_password_encrypts_to_zero);
    5994        2379 :         torture_rpc_tcase_add_test_creds(
    5995             :                 tcase,
    5996             :                 "test_SetPassword2_confounder",
    5997             :                 test_SetPassword2_confounder);
    5998        2379 :         torture_rpc_tcase_add_test_creds(
    5999             :                 tcase,
    6000             :                 "test_SetPassword2_all_zeros",
    6001             :                 test_SetPassword2_all_zeros);
    6002        2379 :         torture_rpc_tcase_add_test_creds(
    6003             :                 tcase,
    6004             :                 "test_SetPassword2_all_zero_password",
    6005             :                 test_SetPassword2_all_zero_password);
    6006        2379 :         torture_rpc_tcase_add_test_creds(
    6007             :                 tcase,
    6008             :                 "test_SetPassword2_maximum_length_password",
    6009             :                 test_SetPassword2_maximum_length_password);
    6010             : 
    6011        2379 :         return suite;
    6012             : }
    6013             : 
    6014        2379 : struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
    6015             : {
    6016        2379 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon.admin");
    6017         125 :         struct torture_rpc_tcase *tcase;
    6018             : 
    6019        2379 :         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "bdc",
    6020             :                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
    6021        2379 :         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
    6022        2379 :         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
    6023        2379 :         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
    6024             : 
    6025        2379 :         tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "wkst",
    6026             :                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
    6027        2379 :         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
    6028        2379 :         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
    6029        2379 :         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
    6030             : 
    6031        2379 :         tcase = torture_suite_add_rpc_iface_tcase(suite, "admin",
    6032             :                                                   &ndr_table_netlogon);
    6033        2379 :         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
    6034        2379 :         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
    6035        2379 :         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
    6036             : 
    6037        2379 :         return suite;
    6038             : }

Generated by: LCOV version 1.14