r24890: Integrate more of the RPC-SECRETS tests.
[kai/samba.git] / source4 / torture / rpc / session_key.c
index 34cd06724d52a13139d065206306b9d3f12a0c72..d35d9fd4fc01083a34e689db3460af0f2d1cfaa1 100644 (file)
@@ -7,7 +7,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 #include "torture/torture.h"
-#include "librpc/gen_ndr/ndr_lsa.h"
 #include "librpc/gen_ndr/ndr_lsa_c.h"
 
 #include "libcli/auth/libcli_auth.h"
 #include "torture/rpc/rpc.h"
+#include "lib/cmdline/popt_common.h"
 
 static void init_lsa_String(struct lsa_String *name, const char *s)
 {
        name->string = s;
 }
 
-static BOOL test_CreateSecret_basic(struct dcerpc_pipe *p, 
-                                   TALLOC_CTX *mem_ctx, 
+static bool test_CreateSecret_basic(struct dcerpc_pipe *p, 
+                                   struct torture_context *tctx,
                                    struct policy_handle *handle)
 {
        NTSTATUS status;
@@ -46,7 +45,6 @@ static BOOL test_CreateSecret_basic(struct dcerpc_pipe *p,
        struct lsa_DATA_BUF buf1;
        struct lsa_DATA_BUF_PTR bufp1;
        DATA_BLOB enc_key;
-       BOOL ret = True;
        DATA_BLOB session_key;
        NTTIME old_mtime, new_mtime;
        DATA_BLOB blob1, blob2;
@@ -54,9 +52,9 @@ static BOOL test_CreateSecret_basic(struct dcerpc_pipe *p,
        char *secret2;
        char *secname;
 
-       secname = talloc_asprintf(mem_ctx, "torturesecret-%u", (uint_t)random());
+       secname = talloc_asprintf(tctx, "torturesecret-%u", (uint_t)random());
 
-       printf("Testing CreateSecret of %s\n", secname);
+       torture_comment(tctx, "Testing CreateSecret of %s\n", secname);
                
        init_lsa_String(&r.in.name, secname);
        
@@ -64,17 +62,11 @@ static BOOL test_CreateSecret_basic(struct dcerpc_pipe *p,
        r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
        r.out.sec_handle = &sec_handle;
        
-       status = dcerpc_lsa_CreateSecret(p, mem_ctx, &r);
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("CreateSecret failed - %s\n", nt_errstr(status));
-               return False;
-       }
+       status = dcerpc_lsa_CreateSecret(p, tctx, &r);
+       torture_assert_ntstatus_ok(tctx, status, "CreateSecret failed");
        
        status = dcerpc_fetch_session_key(p, &session_key);
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
-               ret = False;
-       }
+       torture_assert_ntstatus_ok(tctx, status, "dcerpc_fetch_session_key failed");
        
        enc_key = sess_encrypt_string(secret1, &session_key);
        
@@ -85,13 +77,10 @@ static BOOL test_CreateSecret_basic(struct dcerpc_pipe *p,
        r3.in.new_val->length = enc_key.length;
        r3.in.new_val->size = enc_key.length;
        
-       printf("Testing SetSecret\n");
+       torture_comment(tctx, "Testing SetSecret\n");
        
-       status = dcerpc_lsa_SetSecret(p, mem_ctx, &r3);
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("SetSecret failed - %s\n", nt_errstr(status));
-               ret = False;
-       }
+       status = dcerpc_lsa_SetSecret(p, tctx, &r3);
+       torture_assert_ntstatus_ok(tctx, status, "SetSecret failed");
                
        r3.in.sec_handle = &sec_handle;
        r3.in.new_val = &buf1;
@@ -103,13 +92,11 @@ static BOOL test_CreateSecret_basic(struct dcerpc_pipe *p,
        /* break the encrypted data */
        enc_key.data[0]++;
        
-       printf("Testing SetSecret with broken key\n");
+       torture_comment(tctx, "Testing SetSecret with broken key\n");
        
-       status = dcerpc_lsa_SetSecret(p, mem_ctx, &r3);
-       if (!NT_STATUS_EQUAL(status, NT_STATUS_UNKNOWN_REVISION)) {
-               printf("SetSecret should have failed UNKNOWN_REVISION - %s\n", nt_errstr(status));
-               ret = False;
-       }
+       status = dcerpc_lsa_SetSecret(p, tctx, &r3);
+       torture_assert_ntstatus_equal(tctx, status, NT_STATUS_UNKNOWN_REVISION, 
+               "SetSecret should have failed UNKNOWN_REVISION");
        
        data_blob_free(&enc_key);
        
@@ -125,70 +112,114 @@ static BOOL test_CreateSecret_basic(struct dcerpc_pipe *p,
        
        bufp1.buf = NULL;
        
-       printf("Testing QuerySecret\n");
-       status = dcerpc_lsa_QuerySecret(p, mem_ctx, &r4);
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("QuerySecret failed - %s\n", nt_errstr(status));
-               ret = False;
-       } else {
-               if (r4.out.new_val == NULL || r4.out.new_val->buf == NULL) {
-                       printf("No secret buffer returned\n");
-                       ret = False;
-               } else {
-                       blob1.data = r4.out.new_val->buf->data;
-                       blob1.length = r4.out.new_val->buf->size;
-                       
-                       blob2 = data_blob_talloc(mem_ctx, NULL, blob1.length);
-                       
-                       secret2 = sess_decrypt_string(&blob1, &session_key);
-                       
-                       if (strcmp(secret1, secret2) != 0) {
-                               printf("Returned secret '%s' doesn't match '%s'\n", 
-                                      secret2, secret1);
-                               ret = False;
-                       }
-               }
-       }
+       torture_comment(tctx, "Testing QuerySecret\n");
+       status = dcerpc_lsa_QuerySecret(p, tctx, &r4);
+       torture_assert_ntstatus_ok(tctx, status, "QuerySecret failed");
+       if (r4.out.new_val == NULL || r4.out.new_val->buf == NULL)
+               torture_fail(tctx, "No secret buffer returned");
+       blob1.data = r4.out.new_val->buf->data;
+       blob1.length = r4.out.new_val->buf->size;
+       
+       blob2 = data_blob_talloc(tctx, NULL, blob1.length);
+       
+       secret2 = sess_decrypt_string(tctx, &blob1, &session_key);
+       
+       torture_assert_str_equal(tctx, secret1, secret2, "Returned secret invalid");
 
        d.in.handle = &sec_handle;
-       status = dcerpc_lsa_Delete(p, mem_ctx, &d);
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("delete should have returned OKINVALID_HANDLE - %s\n", nt_errstr(status));
-               ret = False;
-       }
-       return ret;
+       status = dcerpc_lsa_Delete(p, tctx, &d);
+       torture_assert_ntstatus_ok(tctx, status, "delete should have returned OKINVALID_HANDLE");
+       return true;
 }
 
+struct secret_settings {
+       uint32_t bindoptions;
+       bool keyexchange;
+       bool ntlm2;
+       bool lm_key;
+};
 
-/* TEST session key correctness by pushing and pulling secrets */
-
-BOOL torture_rpc_lsa_secrets(void) 
+static bool test_secrets(struct torture_context *torture, const void *_data)
 {
-        NTSTATUS status;
         struct dcerpc_pipe *p;
-       TALLOC_CTX *mem_ctx;
-       BOOL ret = True;
        struct policy_handle *handle;
+       struct dcerpc_binding *binding;
+       const struct secret_settings *settings = _data;
 
-       mem_ctx = talloc_init("torture_rpc_lsa_secrets");
+       lp_set_cmdline("ntlmssp client:keyexchange", settings->keyexchange?"True":"False");
+       lp_set_cmdline("ntlmssp_client:ntlm2", settings->ntlm2?"True":"False");
+       lp_set_cmdline("ntlmssp_client:lm_key", settings->lm_key?"True":"False");
 
-       status = torture_rpc_connection(mem_ctx, 
-                                       &p, 
-                                       &dcerpc_table_lsarpc);
-       if (!NT_STATUS_IS_OK(status)) {
-               talloc_free(mem_ctx);
-               return False;
-       }
+       torture_assert_ntstatus_ok(torture, torture_rpc_binding(torture, &binding), 
+                                  "Getting bindoptions");
+
+       binding->flags |= settings->bindoptions;
 
-       if (!test_lsa_OpenPolicy2(p, mem_ctx, &handle)) {
-               ret = False;
+       torture_assert_ntstatus_ok(torture, 
+                                  dcerpc_pipe_connect_b(torture, &p, binding, &ndr_table_lsarpc, cmdline_credentials, NULL),
+                                  "connect");
+
+       if (!test_lsa_OpenPolicy2(p, torture, &handle)) {
+               return false;
        }
 
-       if (!test_CreateSecret_basic(p, mem_ctx, handle)) {
-               ret = False;
+       torture_assert(torture, handle, "OpenPolicy2 failed.  This test cannot run against this server");
+       
+       if (!test_CreateSecret_basic(p, torture, handle)) {
+               return false;
        }
 
-       talloc_free(mem_ctx);
+       return true;
+}
+
+static struct torture_tcase *add_test(struct torture_suite *suite, uint32_t bindoptions, 
+                                    bool keyexchange, bool ntlm2, bool lm_key)
+{
+       char *name = NULL;
+       struct secret_settings *settings;
+
+       settings = talloc_zero(suite, struct secret_settings);
+       settings->bindoptions = bindoptions;
+
+       if (bindoptions == DCERPC_PUSH_BIGENDIAN)
+               name = talloc_strdup(suite, "bigendian");
+       else if (bindoptions == DCERPC_SEAL)
+               name = talloc_strdup(suite, "seal");
+       else if (bindoptions == 0) 
+               name = talloc_strdup(suite, "none");
+       else
+               name = talloc_strdup(suite, "unknown");
+
+       name = talloc_asprintf_append(name, " keyexchange:%s", keyexchange?"yes":"no");
+       settings->keyexchange = keyexchange;
+
+       name = talloc_asprintf_append(name, " ntlm2:%s", ntlm2?"yes":"no");
+       settings->ntlm2 = ntlm2;
+
+       name = talloc_asprintf_append(name, " lm_key:%s", lm_key?"yes":"no");
+       settings->lm_key = lm_key;
+
+       return torture_suite_add_simple_tcase(suite, name, test_secrets, settings);
+}
+
+static const bool bool_vals[] = { true, false };
+
+/* TEST session key correctness by pushing and pulling secrets */
+struct torture_suite *torture_rpc_lsa_secrets(TALLOC_CTX *mem_ctx)
+{
+       struct torture_suite *suite = torture_suite_create(mem_ctx, "SECRETS");
+       int keyexchange, ntlm2, lm_key;
+
+       for (keyexchange = 0; keyexchange < ARRAY_SIZE(bool_vals); keyexchange++) {
+               for (ntlm2 = 0; ntlm2 < ARRAY_SIZE(bool_vals); ntlm2++) {
+                       for (lm_key = 0; lm_key < ARRAY_SIZE(bool_vals); lm_key++) {
+                               add_test(suite, DCERPC_PUSH_BIGENDIAN, bool_vals[keyexchange], bool_vals[ntlm2], 
+                                        bool_vals[lm_key]);
+                               add_test(suite, DCERPC_SEAL, bool_vals[keyexchange], bool_vals[ntlm2], bool_vals[lm_key]);
+                               add_test(suite, 0, bool_vals[keyexchange], bool_vals[ntlm2], bool_vals[lm_key]);
+                       }
+               }
+       }
 
-       return ret;
+       return suite;
 }