s4:torture Make the RPC-SAMR-PWDLASTET more efficient
authorAndrew Bartlett <abartlet@samba.org>
Thu, 28 May 2009 00:42:28 +0000 (10:42 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 29 May 2009 01:56:24 +0000 (11:56 +1000)
By using SamLogonEx we avoid setting up the credentials chain for each
request.

(Needs to be pushed further up the stack, to only connect to NETLOGON once).

Andrew Bartlett

source4/torture/rpc/samr.c

index 92ce66fef270db36bac062f2ec50cccac2fc8bf0..d13c547a2b7c618a8bea13d55bf6b2836dde6221 100644 (file)
@@ -2673,21 +2673,20 @@ static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
        return true;
 }
 
-static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *tctx,
-                               struct cli_credentials *machine_credentials,
-                               struct cli_credentials *test_credentials,
-                               struct netlogon_creds_CredentialState *creds,
-                               NTSTATUS expected_result)
+static bool test_SamLogon(struct torture_context *tctx,
+                         struct dcerpc_pipe *p, 
+                         struct cli_credentials *test_credentials,
+                         NTSTATUS expected_result)
 {
        NTSTATUS status;
-       struct netr_LogonSamLogon r;
-       struct netr_Authenticator auth, auth2;
+       struct netr_LogonSamLogonEx r;
        union netr_LogonLevel logon;
        union netr_Validation validation;
        uint8_t authoritative;
        struct netr_NetworkInfo ninfo;
        DATA_BLOB names_blob, chal, lm_resp, nt_resp;
        int flags = CLI_CRED_NTLM_AUTH;
+       uint32_t samlogon_flags = 0;
 
        if (lp_client_lanman_auth(tctx->lp_ctx)) {
                flags |= CLI_CRED_LANMAN_AUTH;
@@ -2706,8 +2705,8 @@ static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *t
        chal = data_blob_const(ninfo.challenge,
                               sizeof(ninfo.challenge));
 
-       names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(machine_credentials),
-                                               cli_credentials_get_domain(machine_credentials));
+       names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
+                                               cli_credentials_get_domain(test_credentials));
 
        status = cli_credentials_get_ntlm_response(test_credentials, tctx,
                                                   &flags,
@@ -2728,56 +2727,34 @@ static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *t
                MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
        ninfo.identity_info.logon_id_low = 0;
        ninfo.identity_info.logon_id_high = 0;
-       ninfo.identity_info.workstation.string = cli_credentials_get_workstation(machine_credentials);
+       ninfo.identity_info.workstation.string = cli_credentials_get_workstation(test_credentials);
 
        logon.network = &ninfo;
 
        r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
-       r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
-       r.in.credential = &auth;
-       r.in.return_authenticator = &auth2;
-       r.in.logon_level = 2;
+       r.in.computer_name = cli_credentials_get_workstation(test_credentials);
+       r.in.logon_level = NetlogonNetworkInformation;
        r.in.logon = &logon;
+       r.in.flags = &samlogon_flags;
+       r.out.flags = &samlogon_flags;
        r.out.validation = &validation;
        r.out.authoritative = &authoritative;
 
        d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
 
-       ZERO_STRUCT(auth2);
-       netlogon_creds_client_authenticator(creds, &auth);
-
-       r.in.validation_level = 2;
+       r.in.validation_level = 6;
 
-       status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
+       status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogon failed");
+               torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogonEx failed");
                return true;
        } else {
-               torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
+               torture_assert_ntstatus_ok(tctx, status, "LogonSamLogonEx failed");
        }
 
-       torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred),
-                       "Credential chaining failed");
-
        return true;
 }
 
-static bool test_SamLogon(struct torture_context *tctx,
-                         struct dcerpc_pipe *p,
-                         struct cli_credentials *machine_credentials,
-                         struct cli_credentials *test_credentials,
-                         NTSTATUS expected_result)
-{
-       struct netlogon_creds_CredentialState *creds;
-
-       if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
-               return false;
-       }
-
-       return test_SamLogon_Creds(p, tctx, machine_credentials, test_credentials,
-                                  creds, expected_result);
-}
-
 static bool test_SamLogon_with_creds(struct torture_context *tctx,
                                     struct dcerpc_pipe *p,
                                     struct cli_credentials *machine_creds,
@@ -2791,19 +2768,18 @@ static bool test_SamLogon_with_creds(struct torture_context *tctx,
        test_credentials = cli_credentials_init(tctx);
 
        cli_credentials_set_workstation(test_credentials,
-                                       TEST_ACCOUNT_NAME_PWD, CRED_SPECIFIED);
+                                       cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
        cli_credentials_set_domain(test_credentials,
-                                  lp_workgroup(tctx->lp_ctx), CRED_SPECIFIED);
+                                  cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
        cli_credentials_set_username(test_credentials,
                                     acct_name, CRED_SPECIFIED);
        cli_credentials_set_password(test_credentials,
                                     password, CRED_SPECIFIED);
-       cli_credentials_set_secure_channel_type(test_credentials, SEC_CHAN_BDC);
 
-       printf("testing samlogon as %s@%s password: %s\n",
-               acct_name, TEST_ACCOUNT_NAME_PWD, password);
+       printf("testing samlogon as %s password: %s\n",
+               acct_name, password);
 
-       if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
+       if (!test_SamLogon(tctx, p, test_credentials,
                           expected_samlogon_result)) {
                torture_warning(tctx, "new password did not work\n");
                ret = false;
@@ -2886,8 +2862,9 @@ static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
                                        struct cli_credentials *machine_credentials)
 {
        int s = 0, q = 0, f = 0, l = 0, z = 0;
+       struct dcerpc_binding *b;
        bool ret = true;
-       int delay = 500000;
+       int delay = 50000;
        bool set_levels[] = { false, true };
        bool query_levels[] = { false, true };
        uint32_t levels[] = { 18, 21, 23, 24, 25, 26 };
@@ -2915,9 +2892,26 @@ static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
                        delay);
        }
 
-       status = torture_rpc_connection(tctx, &np, &ndr_table_netlogon);
+       status = torture_rpc_binding(tctx, &b);
        if (!NT_STATUS_IS_OK(status)) {
-               return false;
+               ret = false;
+               return ret;
+       }
+
+       /* We have to use schannel, otherwise the SamLogonEx fails
+        * with INTERNAL_ERROR */
+
+       b->flags &= ~DCERPC_AUTH_OPTIONS;
+       b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
+
+       status = dcerpc_pipe_connect_b(tctx, &np, b, 
+                                      &ndr_table_netlogon,
+                                      machine_credentials, tctx->ev, tctx->lp_ctx);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               d_printf("RPC pipe connect as domain member failed: %s\n", nt_errstr(status));
+               ret = false;
+               return ret;
        }
 
        /* set to 1 to enable testing for all possible opcode