r7899: fixed a crash bug in the RAW-CONTEXT test
[gd/samba-autobuild/.git] / source4 / torture / raw / context.c
index c19fea458d3df3a2fb4b5caa720809a61c8999d4..f7fe006917a8873e764fa854a4c9a2910193b5f4 100644 (file)
 */
 
 #include "includes.h"
+#include "libcli/raw/libcliraw.h"
+#include "librpc/gen_ndr/ndr_security.h"
+#include "libcli/composite/composite.h"
+#include "lib/cmdline/popt_common.h"
+#include "lib/events/events.h"
 
 #define BASEDIR "\\rawcontext"
 
 #define CHECK_STATUS(status, correct) do { \
        if (!NT_STATUS_EQUAL(status, correct)) { \
-               printf("(%d) Incorrect status %s - should be %s\n", \
-                      __LINE__, nt_errstr(status), nt_errstr(correct)); \
+               printf("(%s) Incorrect status %s - should be %s\n", \
+                      __location__, nt_errstr(status), nt_errstr(correct)); \
                ret = False; \
                goto done; \
        }} while (0)
 
 #define CHECK_VALUE(v, correct) do { \
        if ((v) != (correct)) { \
-               printf("(%d) Incorrect value %s=%d - should be %d\n", \
-                      __LINE__, #v, v, correct); \
+               printf("(%s) Incorrect value %s=%d - should be %d\n", \
+                      __location__, #v, v, correct); \
+               ret = False; \
+               goto done; \
+       }} while (0)
+
+#define CHECK_NOT_VALUE(v, correct) do { \
+       if ((v) == (correct)) { \
+               printf("(%s) Incorrect value %s=%d - should not be %d\n", \
+                      __location__, #v, v, correct); \
                ret = False; \
                goto done; \
        }} while (0)
 /*
   test session ops
 */
-static BOOL test_session(struct cli_state *cli, TALLOC_CTX *mem_ctx)
+static BOOL test_session(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 {
        NTSTATUS status;
        BOOL ret = True;
-       char *username, *domain, *password;
-       struct cli_session *session;
-       struct cli_tree *tree;
-       union smb_sesssetup setup;
+       struct smbcli_session *session;
+       struct smbcli_session *session2;
+       struct smbcli_session *session3;
+       struct smbcli_session *session4;
+       struct cli_credentials *anon_creds;
+       struct smbcli_session *sessions[15];
+       struct composite_context *composite_contexts[15];
+       struct smbcli_tree *tree;
+       struct smb_composite_sesssetup setup;
+       struct smb_composite_sesssetup setups[15];
        union smb_open io;
        union smb_write wr;
        union smb_close cl;
        int fnum;
        const char *fname = BASEDIR "\\test.txt";
-       char c = 1;
+       uint8_t c = 1;
+       int i;
 
        printf("TESTING SESSION HANDLING\n");
 
-       if (cli_deltree(cli, BASEDIR) == -1 ||
-           !cli_mkdir(cli, BASEDIR)) {
-               printf("Unable to setup %s - %s\n", BASEDIR, cli_errstr(cli));
+       if (!torture_setup_dir(cli, BASEDIR)) {
                return False;
        }
 
-       username = lp_parm_string(-1, "torture", "username");
-       password = lp_parm_string(-1, "torture", "password");
-       domain = lp_workgroup();
-
        printf("create a second security context on the same transport\n");
-       session = cli_session_init(cli->transport);
-       setup.generic.level = RAW_SESSSETUP_GENERIC;
-       setup.generic.in.sesskey = cli->transport->negotiate.sesskey;
-       setup.generic.in.capabilities = 0; /* ignored in secondary session setup */
-       setup.generic.in.password = password;
-       setup.generic.in.user = username;
-       setup.generic.in.domain = domain;
-
-       status = smb_raw_session_setup(session, mem_ctx, &setup);
+       session = smbcli_session_init(cli->transport, mem_ctx, False);
+
+       setup.in.sesskey = cli->transport->negotiate.sesskey;
+       setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
+       setup.in.workgroup = lp_workgroup();
+
+       setup.in.credentials = cmdline_credentials;
+
+       status = smb_composite_sesssetup(session, &setup);
        CHECK_STATUS(status, NT_STATUS_OK);
+       
+       session->vuid = setup.out.vuid;
+
+       printf("create a third security context on the same transport, with vuid set\n");
+       session2 = smbcli_session_init(cli->transport, mem_ctx, False);
+
+       session2->vuid = session->vuid;
+       setup.in.sesskey = cli->transport->negotiate.sesskey;
+       setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
+       setup.in.workgroup = lp_workgroup();
 
-       session->vuid = setup.generic.out.vuid;
+       setup.in.credentials = cmdline_credentials;
 
+       status = smb_composite_sesssetup(session2, &setup);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       session2->vuid = setup.out.vuid;
+       printf("vuid1=%d vuid2=%d vuid3=%d\n", cli->session->vuid, session->vuid, session2->vuid);
+       
+       if (cli->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) {
+               /* Samba4 currently fails this - we need to determine if this insane behaviour is important */
+               if (session2->vuid == session->vuid) {
+                       printf("server allows the user to re-use an existing vuid in session setup \n");
+               }
+       } else {
+               CHECK_NOT_VALUE(session2->vuid, session->vuid);
+       }
+       talloc_free(session2);
+
+       if (cli->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) {
+               printf("create a fourth security context on the same transport, without extended security\n");
+               session3 = smbcli_session_init(cli->transport, mem_ctx, False);
+
+               session3->vuid = session->vuid;
+               setup.in.sesskey = cli->transport->negotiate.sesskey;
+               setup.in.capabilities = 0; /* force a non extended security login (should fail) */
+               setup.in.workgroup = lp_workgroup();
+       
+               setup.in.credentials = cmdline_credentials;
+       
+
+               status = smb_composite_sesssetup(session3, &setup);
+               CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
+
+               printf("create a fouth anonymous security context on the same transport, without extended security\n");
+               session4 = smbcli_session_init(cli->transport, mem_ctx, False);
+
+               session4->vuid = session->vuid;
+               setup.in.sesskey = cli->transport->negotiate.sesskey;
+               setup.in.capabilities = 0; /* force a non extended security login (should fail) */
+               setup.in.workgroup = lp_workgroup();
+               
+               anon_creds = cli_credentials_init(mem_ctx);
+               cli_credentials_set_conf(anon_creds);
+               cli_credentials_set_anonymous(anon_creds);
+
+               setup.in.credentials = anon_creds;
+       
+               status = smb_composite_sesssetup(session3, &setup);
+               CHECK_STATUS(status, NT_STATUS_OK);
+
+               talloc_free(session4);
+       }
+               
        printf("use the same tree as the existing connection\n");
-       tree = cli_tree_init(session);
+       tree = smbcli_tree_init(session, mem_ctx, False);
        tree->tid = cli->tree->tid;
-       cli->tree->reference_count++;
-
-       printf("vuid1=%d vuid2=%d\n", cli->session->vuid, session->vuid);
 
        printf("create a file using the new vuid\n");
        io.generic.level = RAW_OPEN_NTCREATEX;
        io.ntcreatex.in.root_fid = 0;
        io.ntcreatex.in.flags = 0;
-       io.ntcreatex.in.access_mask = SEC_RIGHT_MAXIMUM_ALLOWED;
+       io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
        io.ntcreatex.in.create_options = 0;
        io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
        io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
@@ -132,6 +204,11 @@ static BOOL test_session(struct cli_state *cli, TALLOC_CTX *mem_ctx)
        status = smb_raw_write(tree, &wr);
        CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 
+       printf("second logoff for the new vuid should fail\n");
+       status = smb_raw_ulogoff(session);
+       CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
+       talloc_free(session);
+
        printf("the fnum should have been auto-closed\n");
        cl.close.level = RAW_CLOSE_CLOSE;
        cl.close.in.fnum = fnum;
@@ -139,9 +216,39 @@ static BOOL test_session(struct cli_state *cli, TALLOC_CTX *mem_ctx)
        status = smb_raw_close(cli->tree, &cl);
        CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 
-       /* close down the new tree, which will also close the session
-          as the reference count will be 0 */
-       cli_tree_close(tree);
+       printf("create %d secondary security contexts on the same transport\n", 
+              ARRAY_SIZE(sessions));
+       for (i=0; i <ARRAY_SIZE(sessions); i++) {
+               setups[i].in.sesskey = cli->transport->negotiate.sesskey;
+               setups[i].in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
+               setups[i].in.workgroup = lp_workgroup();
+               
+               setups[i].in.credentials = cmdline_credentials;
+
+               sessions[i] = smbcli_session_init(cli->transport, mem_ctx, False);
+               composite_contexts[i] = smb_composite_sesssetup_send(sessions[i], &setups[i]);
+
+       }
+
+
+       /* flush the queue */
+       for (i=0; i < ARRAY_SIZE(sessions); i++) {
+               event_loop_once(composite_contexts[0]->event_ctx);
+       }
+
+       printf("finishing %d secondary security contexts on the same transport\n", 
+              ARRAY_SIZE(sessions));
+       for (i=0; i< ARRAY_SIZE(sessions); i++) {
+               status = smb_composite_sesssetup_recv(composite_contexts[i]);
+               CHECK_STATUS(status, NT_STATUS_OK);
+               sessions[i]->vuid = setups[i].out.vuid;
+               printf("VUID: %d\n", sessions[i]->vuid);
+               status = smb_raw_ulogoff(sessions[i]);
+               CHECK_STATUS(status, NT_STATUS_OK);
+       }
+
+
+       talloc_free(tree);
        
 done:
        return ret;
@@ -151,32 +258,30 @@ done:
 /*
   test tree ops
 */
-static BOOL test_tree(struct cli_state *cli, TALLOC_CTX *mem_ctx)
+static BOOL test_tree(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 {
        NTSTATUS status;
        BOOL ret = True;
-       char *share;
-       struct cli_tree *tree;
+       const char *share;
+       struct smbcli_tree *tree;
        union smb_tcon tcon;
        union smb_open io;
        union smb_write wr;
        union smb_close cl;
        int fnum;
        const char *fname = BASEDIR "\\test.txt";
-       char c = 1;
+       uint8_t c = 1;
 
        printf("TESTING TREE HANDLING\n");
 
-       if (cli_deltree(cli, BASEDIR) == -1 ||
-           !cli_mkdir(cli, BASEDIR)) {
-               printf("Unable to setup %s - %s\n", BASEDIR, cli_errstr(cli));
+       if (!torture_setup_dir(cli, BASEDIR)) {
                return False;
        }
 
        share = lp_parm_string(-1, "torture", "share");
-
+       
        printf("create a second tree context on the same session\n");
-       tree = cli_tree_init(cli->session);
+       tree = smbcli_tree_init(cli->session, mem_ctx, False);
 
        tcon.generic.level = RAW_TCON_TCONX;
        tcon.tconx.in.flags = 0;
@@ -186,7 +291,7 @@ static BOOL test_tree(struct cli_state *cli, TALLOC_CTX *mem_ctx)
        status = smb_tree_connect(tree, mem_ctx, &tcon);
        CHECK_STATUS(status, NT_STATUS_OK);
 
-       tree->tid = tcon.tconx.out.cnum;
+       tree->tid = tcon.tconx.out.tid;
        printf("tid1=%d tid2=%d\n", cli->tree->tid, tree->tid);
 
        printf("try a tconx with a bad device type\n");
@@ -199,7 +304,7 @@ static BOOL test_tree(struct cli_state *cli, TALLOC_CTX *mem_ctx)
        io.generic.level = RAW_OPEN_NTCREATEX;
        io.ntcreatex.in.root_fid = 0;
        io.ntcreatex.in.flags = 0;
-       io.ntcreatex.in.access_mask = SEC_RIGHT_MAXIMUM_ALLOWED;
+       io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
        io.ntcreatex.in.create_options = 0;
        io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
        io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
@@ -245,7 +350,7 @@ static BOOL test_tree(struct cli_state *cli, TALLOC_CTX *mem_ctx)
        CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 
        /* close down the new tree */
-       cli_tree_close(tree);
+       talloc_free(tree);
        
 done:
        return ret;
@@ -255,7 +360,7 @@ done:
 /*
   test pid ops
 */
-static BOOL test_pid(struct cli_state *cli, TALLOC_CTX *mem_ctx)
+static BOOL test_pid(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 {
        NTSTATUS status;
        BOOL ret = True;
@@ -264,14 +369,12 @@ static BOOL test_pid(struct cli_state *cli, TALLOC_CTX *mem_ctx)
        union smb_close cl;
        int fnum;
        const char *fname = BASEDIR "\\test.txt";
-       char c = 1;
-       uint16 pid1, pid2;
+       uint8_t c = 1;
+       uint16_t pid1, pid2;
 
        printf("TESTING PID HANDLING\n");
 
-       if (cli_deltree(cli, BASEDIR) == -1 ||
-           !cli_mkdir(cli, BASEDIR)) {
-               printf("Unable to setup %s - %s\n", BASEDIR, cli_errstr(cli));
+       if (!torture_setup_dir(cli, BASEDIR)) {
                return False;
        }
 
@@ -286,7 +389,7 @@ static BOOL test_pid(struct cli_state *cli, TALLOC_CTX *mem_ctx)
        io.generic.level = RAW_OPEN_NTCREATEX;
        io.ntcreatex.in.root_fid = 0;
        io.ntcreatex.in.flags = 0;
-       io.ntcreatex.in.access_mask = SEC_RIGHT_MAXIMUM_ALLOWED;
+       io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
        io.ntcreatex.in.create_options = 0;
        io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
        io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
@@ -355,9 +458,9 @@ done:
 /* 
    basic testing of session/tree context calls
 */
-BOOL torture_raw_context(int dummy)
+static BOOL torture_raw_context_int(void)
 {
-       struct cli_state *cli;
+       struct smbcli_state *cli;
        BOOL ret = True;
        TALLOC_CTX *mem_ctx;
 
@@ -380,9 +483,25 @@ BOOL torture_raw_context(int dummy)
        }
 
        smb_raw_exit(cli->session);
-       cli_deltree(cli, BASEDIR);
+       smbcli_deltree(cli->tree, BASEDIR);
 
        torture_close_connection(cli);
-       talloc_destroy(mem_ctx);
+       talloc_free(mem_ctx);
+
+       return ret;
+}
+/* 
+   basic testing of session/tree context calls
+*/
+BOOL torture_raw_context(void)
+{
+       BOOL ret = True;
+       if (lp_use_spnego()) {
+               ret &= torture_raw_context_int();
+               lp_set_cmdline("use spnego", "False");
+       }
+
+       ret &= torture_raw_context_int();
+
        return ret;
 }