r19507: Merge my DSO fixes branch. Building Samba's libraries as shared libraries
[samba.git] / source4 / torture / rap / rap.c
index e9cb45e3b0146eb450b1f7b8cbd779a2dfc0a1af..682bfdb0eb0c8feb9c3a9ee69cc9adee76de1a03 100644 (file)
 */
 
 #include "includes.h"
+#include "libcli/libcli.h"
 #include "torture/torture.h"
-#include "rap.h"
+#include "torture/util.h"
+#include "libcli/rap/rap.h"
 #include "libcli/raw/libcliraw.h"
 #include "libcli/libcli.h"
+#include "librpc/ndr/libndr.h"
 
 struct rap_call {
        uint16_t callno;
@@ -76,7 +79,7 @@ static void rap_cli_push_paramdesc(struct rap_call *call, char desc)
 
        call->paramdesc = talloc_realloc(call,
                                         call->paramdesc,
-                                        uint8_t,
+                                        char,
                                         len+2);
 
        call->paramdesc[len] = desc;
@@ -110,6 +113,12 @@ static void rap_cli_expect_multiple_entries(struct rap_call *call)
        call->rcv_paramlen += 4; /* uint16_t entry count, uint16_t total */
 }
 
+static void rap_cli_expect_word(struct rap_call *call)
+{
+       rap_cli_push_paramdesc(call, 'h');
+       call->rcv_paramlen += 2;
+}
+
 static void rap_cli_push_string(struct rap_call *call, const char *str)
 {
        if (str == NULL) {
@@ -148,12 +157,12 @@ static NTSTATUS rap_pull_string(TALLOC_CTX *mem_ctx, struct ndr_pull *ndr,
                return NT_STATUS_INVALID_PARAMETER;
 
        *dest = talloc_zero_size(mem_ctx, len+1);
-       pull_ascii(*dest, p, len+1, len, 0);
+       pull_string(*dest, p, len+1, len, STR_ASCII);
 
        return NT_STATUS_OK;
 }
 
-static NTSTATUS rap_cli_do_call(struct smbcli_state *cli, struct rap_call *call)
+static NTSTATUS rap_cli_do_call(struct smbcli_tree *tree, struct rap_call *call)
 {
        NTSTATUS result;
        DATA_BLOB param_blob;
@@ -168,7 +177,7 @@ static NTSTATUS rap_cli_do_call(struct smbcli_state *cli, struct rap_call *call)
        params->flags = RAPNDR_FLAGS;
 
        trans.in.max_param = call->rcv_paramlen;
-       trans.in.max_data = smb_raw_max_trans_data(cli->tree, call->rcv_paramlen);
+       trans.in.max_data = smb_raw_max_trans_data(tree, call->rcv_paramlen);
        trans.in.max_setup = 0;
        trans.in.flags = 0;
        trans.in.timeout = 0;
@@ -189,7 +198,7 @@ static NTSTATUS rap_cli_do_call(struct smbcli_state *cli, struct rap_call *call)
        trans.in.params = ndr_push_blob(params);
        trans.in.data = data_blob(NULL, 0);
 
-       result = smb_raw_trans(cli->tree, call, &trans);
+       result = smb_raw_trans(tree, call, &trans);
 
        if (!NT_STATUS_IS_OK(result))
                return result;
@@ -209,7 +218,7 @@ static NTSTATUS rap_cli_do_call(struct smbcli_state *cli, struct rap_call *call)
                                goto done; \
                         } while (0)
 
-static NTSTATUS smbcli_rap_netshareenum(struct smbcli_state *cli,
+static NTSTATUS smbcli_rap_netshareenum(struct smbcli_tree *tree,
                                        TALLOC_CTX *mem_ctx,
                                        struct rap_NetShareEnum *r)
 {
@@ -217,7 +226,7 @@ static NTSTATUS smbcli_rap_netshareenum(struct smbcli_state *cli,
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        int i;
 
-       call = new_rap_cli_call(NULL, RAP_WshareEnum);
+       call = new_rap_cli_call(tree, RAP_WshareEnum);
 
        if (call == NULL)
                return NT_STATUS_NO_MEMORY;
@@ -235,7 +244,7 @@ static NTSTATUS smbcli_rap_netshareenum(struct smbcli_state *cli,
                break;
        }
 
-       result = rap_cli_do_call(cli, call);
+       result = rap_cli_do_call(tree, call);
 
        if (!NT_STATUS_IS_OK(result))
                goto done;
@@ -279,16 +288,16 @@ static NTSTATUS smbcli_rap_netshareenum(struct smbcli_state *cli,
        return result;
 }
 
-static BOOL test_netshareenum(struct smbcli_state *cli)
+static BOOL test_netshareenum(struct smbcli_tree *tree)
 {
        struct rap_NetShareEnum r;
        int i;
-       TALLOC_CTX *tmp_ctx = talloc_new(cli);
+       TALLOC_CTX *tmp_ctx = talloc_new(tree);
 
        r.in.level = 1;
        r.in.bufsize = 8192;
 
-       if (!NT_STATUS_IS_OK(smbcli_rap_netshareenum(cli, tmp_ctx, &r)))
+       if (!NT_STATUS_IS_OK(smbcli_rap_netshareenum(tree, tmp_ctx, &r)))
                return False;
 
        for (i=0; i<r.out.count; i++) {
@@ -302,7 +311,7 @@ static BOOL test_netshareenum(struct smbcli_state *cli)
        return True;
 }
 
-static NTSTATUS smbcli_rap_netserverenum2(struct smbcli_state *cli,
+static NTSTATUS smbcli_rap_netserverenum2(struct smbcli_tree *tree,
                                          TALLOC_CTX *mem_ctx,
                                          struct rap_NetServerEnum2 *r)
 {
@@ -310,7 +319,7 @@ static NTSTATUS smbcli_rap_netserverenum2(struct smbcli_state *cli,
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        int i;
 
-       call = new_rap_cli_call(NULL, RAP_NetServerEnum2);
+       call = new_rap_cli_call(mem_ctx, RAP_NetServerEnum2);
 
        if (call == NULL)
                return NT_STATUS_NO_MEMORY;
@@ -330,7 +339,7 @@ static NTSTATUS smbcli_rap_netserverenum2(struct smbcli_state *cli,
                break;
        }
 
-       result = rap_cli_do_call(cli, call);
+       result = rap_cli_do_call(tree, call);
 
        if (!NT_STATUS_IS_OK(result))
                goto done;
@@ -377,11 +386,11 @@ static NTSTATUS smbcli_rap_netserverenum2(struct smbcli_state *cli,
        return result;
 }
 
-static BOOL test_netserverenum(struct smbcli_state *cli)
+static BOOL test_netserverenum(struct smbcli_tree *tree)
 {
        struct rap_NetServerEnum2 r;
        int i;
-       TALLOC_CTX *tmp_ctx = talloc_new(cli);
+       TALLOC_CTX *tmp_ctx = talloc_new(tree);
 
        r.in.level = 0;
        r.in.bufsize = 8192;
@@ -389,7 +398,7 @@ static BOOL test_netserverenum(struct smbcli_state *cli)
        r.in.servertype = 0x80000000;
        r.in.domain = NULL;
 
-       if (!NT_STATUS_IS_OK(smbcli_rap_netserverenum2(cli, tmp_ctx, &r)))
+       if (!NT_STATUS_IS_OK(smbcli_rap_netserverenum2(tree, tmp_ctx, &r)))
                return False;
 
        for (i=0; i<r.out.count; i++) {
@@ -410,34 +419,110 @@ static BOOL test_netserverenum(struct smbcli_state *cli)
        return True;
 }
 
+_PUBLIC_ NTSTATUS smbcli_rap_netservergetinfo(struct smbcli_tree *tree,
+                                    TALLOC_CTX *mem_ctx,
+                                    struct rap_WserverGetInfo *r)
+{
+       struct rap_call *call;
+       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+       if (!(call = new_rap_cli_call(mem_ctx, RAP_WserverGetInfo))) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       rap_cli_push_word(call, r->in.level);
+       rap_cli_push_rcvbuf(call, r->in.bufsize);
+       rap_cli_expect_word(call);
+
+       switch(r->in.level) {
+       case 0:
+               rap_cli_expect_format(call, "B16");
+               break;
+       case 1:
+               rap_cli_expect_format(call, "B16BBDz");
+               break;
+       default:
+               result = NT_STATUS_INVALID_PARAMETER;
+               goto done;
+       }
+
+       result = rap_cli_do_call(tree, call);
+
+       if (!NT_STATUS_IS_OK(result))
+               goto done;
 
+       NDR_OK(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
+       NDR_OK(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
+       NDR_OK(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.available));
 
-static BOOL test_rap(struct smbcli_state *cli)
+       switch(r->in.level) {
+       case 0:
+               NDR_OK(ndr_pull_bytes(call->ndr_pull_data,
+                                     (uint8_t *)r->out.info.info0.name, 16));
+               break;
+       case 1:
+               NDR_OK(ndr_pull_bytes(call->ndr_pull_data,
+                                     (uint8_t *)r->out.info.info1.name, 16));
+               NDR_OK(ndr_pull_bytes(call->ndr_pull_data,
+                                     &r->out.info.info1.version_major, 1));
+               NDR_OK(ndr_pull_bytes(call->ndr_pull_data,
+                                     &r->out.info.info1.version_minor, 1));
+               NDR_OK(ndr_pull_uint32(call->ndr_pull_data,
+                                      NDR_SCALARS, &r->out.info.info1.servertype));
+               NDR_OK(rap_pull_string(mem_ctx, call->ndr_pull_data,
+                                      r->out.convert,
+                                      &r->out.info.info1.comment));
+       }
+ done:
+       talloc_free(call);
+       return result;
+}
+
+static BOOL test_netservergetinfo(struct smbcli_tree *tree)
 {
+       struct rap_WserverGetInfo r;
        BOOL res = True;
+       TALLOC_CTX *mem_ctx;
+
+       if (!(mem_ctx = talloc_new(tree))) {
+               return False;
+       }
 
-       if (!test_netserverenum(cli))
-               res = False;
+       r.in.bufsize = 0xffff;
 
-       if (!test_netshareenum(cli))
-               res = False;
+       r.in.level = 0;
+       res &= NT_STATUS_IS_OK(smbcli_rap_netservergetinfo(tree, mem_ctx, &r));
+       r.in.level = 1;
+       res &= NT_STATUS_IS_OK(smbcli_rap_netservergetinfo(tree, mem_ctx, &r));
 
+       talloc_free(mem_ctx);
        return res;
 }
 
-BOOL torture_raw_rap(void)
+static BOOL test_rap(struct smbcli_tree *tree)
+{
+       BOOL res = True;
+
+       res &= test_netserverenum(tree);
+       res &= test_netshareenum(tree);
+       res &= test_netservergetinfo(tree);
+
+       return res;
+}
+
+BOOL torture_rap_basic(struct torture_context *torture)
 {
        struct smbcli_state *cli;
        BOOL ret = True;
        TALLOC_CTX *mem_ctx;
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
-       mem_ctx = talloc_init("torture_raw_rap");
+       mem_ctx = talloc_init("torture_rap_basic");
 
-       if (!test_rap(cli)) {
+       if (!test_rap(cli->tree)) {
                ret = False;
        }
 
@@ -447,7 +532,7 @@ BOOL torture_raw_rap(void)
        return ret;
 }
 
-BOOL torture_rap_scan(void)
+BOOL torture_rap_scan(struct torture_context *torture)
 {
        TALLOC_CTX *mem_ctx;
        struct smbcli_state *cli;
@@ -455,7 +540,7 @@ BOOL torture_rap_scan(void)
 
        mem_ctx = talloc_init("torture_rap_scan");
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
        
@@ -463,7 +548,7 @@ BOOL torture_rap_scan(void)
                struct rap_call *call = new_rap_cli_call(mem_ctx, callno);
                NTSTATUS result;
 
-               result = rap_cli_do_call(cli, call);
+               result = rap_cli_do_call(cli->tree, call);
 
                if (!NT_STATUS_EQUAL(result, NT_STATUS_INVALID_PARAMETER))
                        continue;
@@ -475,3 +560,20 @@ BOOL torture_rap_scan(void)
 
        return True;
 }
+
+NTSTATUS torture_rap_init(void)
+{
+       struct torture_suite *suite = torture_suite_create(
+                                                                       talloc_autofree_context(),
+                                                                       "RAP");
+
+       torture_suite_add_simple_test(suite, "BASIC", torture_rap_basic);
+       torture_suite_add_simple_test(suite, "SCAN", torture_rap_scan);
+
+       suite->description = talloc_strdup(suite, 
+                                               "Remote Administration Protocol tests");
+
+       torture_register_suite(suite);
+
+       return NT_STATUS_OK;
+}