diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2009-03-20 01:30:36 +0100 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2009-03-20 01:30:36 +0100 |
commit | 5fe2b28f45289dc5578cdd536600f0d30a14d820 (patch) | |
tree | 4bdf36d0d4d8bdddcb3d618b4b01839370ed57c3 /source4/torture | |
parent | ec9aeeab00584f4d3dfe9afb83dc1a77b8463b81 (diff) | |
parent | 3a4638db0351368d3b148bf547546f28fa0b1479 (diff) | |
download | samba-5fe2b28f45289dc5578cdd536600f0d30a14d820.tar.gz samba-5fe2b28f45289dc5578cdd536600f0d30a14d820.tar.bz2 samba-5fe2b28f45289dc5578cdd536600f0d30a14d820.zip |
Merge branch 'master' of git://git.samba.org/samba into minschema
Diffstat (limited to 'source4/torture')
-rw-r--r-- | source4/torture/ldap/cldap.c | 75 | ||||
-rw-r--r-- | source4/torture/ldap/cldapbench.c | 113 | ||||
-rw-r--r-- | source4/torture/local/config.mk | 2 | ||||
-rw-r--r-- | source4/torture/raw/notify.c | 169 | ||||
-rw-r--r-- | source4/torture/rpc/dssync.c | 9 | ||||
-rw-r--r-- | source4/torture/rpc/samba3rpc.c | 2 | ||||
-rw-r--r-- | source4/torture/rpc/spoolss.c | 122 | ||||
-rw-r--r-- | source4/torture/rpc/spoolss_notify.c | 12 | ||||
-rw-r--r-- | source4/torture/rpc/spoolss_win.c | 61 | ||||
-rw-r--r-- | source4/torture/smb2/create.c | 8 | ||||
-rw-r--r-- | source4/torture/smb2/lock.c | 39 |
11 files changed, 489 insertions, 123 deletions
diff --git a/source4/torture/ldap/cldap.c b/source4/torture/ldap/cldap.c index 1ddc628a5c..98669288a8 100644 --- a/source4/torture/ldap/cldap.c +++ b/source4/torture/ldap/cldap.c @@ -28,6 +28,7 @@ #include "torture/torture.h" #include "lib/ldb/include/ldb.h" #include "param/param.h" +#include "../lib/tsocket/tsocket.h" #define CHECK_STATUS(status, correct) torture_assert_ntstatus_equal(tctx, status, correct, "incorrect status") @@ -45,12 +46,21 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) struct netlogon_samlogon_response n1; struct GUID guid; int i; + struct smb_iconv_convenience *iconv_convenience = lp_iconv_convenience(tctx->lp_ctx); + struct tsocket_address *dest_addr; + int ret; - cldap = cldap_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx)); + ret = tsocket_address_inet_from_strings(tctx, "ip", + dest, + lp_cldap_port(tctx->lp_ctx), + &dest_addr); + + status = cldap_socket_init(tctx, NULL, NULL, dest_addr, &cldap); + CHECK_STATUS(status, NT_STATUS_OK); ZERO_STRUCT(search); - search.in.dest_address = dest; - search.in.dest_port = lp_cldap_port(tctx->lp_ctx); + search.in.dest_address = NULL;//dest; + search.in.dest_port = 0;//lp_cldap_port(tctx->lp_ctx); search.in.acct_control = -1; search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX; search.in.map_response = true; @@ -59,7 +69,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) printf("Trying without any attributes\n"); search = empty_search; - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); n1 = search.out.netlogon; @@ -72,7 +82,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) for (i=0;i<256;i++) { search.in.version = i; printf("Trying netlogon level %d\n", i); - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); } @@ -80,19 +90,19 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) for (i=0;i<31;i++) { search.in.version = (1<<i); printf("Trying netlogon level 0x%x\n", i); - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); } search.in.version = NETLOGON_NT_VERSION_5|NETLOGON_NT_VERSION_5EX|NETLOGON_NT_VERSION_IP; - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); printf("Trying with User=NULL\n"); search.in.user = NULL; - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, ""); CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX); @@ -100,20 +110,20 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) printf("Trying with User=Administrator\n"); search.in.user = "Administrator"; - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user); CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX); search.in.version = NETLOGON_NT_VERSION_5; - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); printf("Trying with User=NULL\n"); search.in.user = NULL; - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, ""); CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE); @@ -121,7 +131,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) printf("Trying with User=Administrator\n"); search.in.user = "Administrator"; - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user); @@ -132,7 +142,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) printf("Trying with a GUID\n"); search.in.realm = NULL; search.in.domain_guid = GUID_string(tctx, &n1.data.nt5_ex.domain_uuid); - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX); CHECK_STRING(GUID_string(tctx, &search.out.netlogon.data.nt5_ex.domain_uuid), search.in.domain_guid); @@ -141,13 +151,13 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) guid = GUID_random(); search.in.user = NULL; search.in.domain_guid = GUID_string(tctx, &guid); - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_NOT_FOUND); printf("Trying with a AAC\n"); search.in.acct_control = ACB_WSTRUST|ACB_SVRTRUST; search.in.realm = n1.data.nt5_ex.dns_domain; - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX); CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, ""); @@ -155,7 +165,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) printf("Trying with a zero AAC\n"); search.in.acct_control = 0x0; search.in.realm = n1.data.nt5_ex.dns_domain; - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX); CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, ""); @@ -164,7 +174,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) search.in.acct_control = 0x0; search.in.user = "Administrator"; search.in.realm = n1.data.nt5_ex.dns_domain; - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX); CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "Administrator"); @@ -173,7 +183,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) search.in.user = NULL; search.in.acct_control = 0xFF00FF00; search.in.realm = n1.data.nt5_ex.dns_domain; - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX); CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, ""); @@ -181,14 +191,14 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) printf("Trying with a user only\n"); search = empty_search; search.in.user = "Administrator"; - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain); CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user); printf("Trying with just a bad username\n"); search.in.user = "___no_such_user___"; - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user); CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain); @@ -197,12 +207,12 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) printf("Trying with just a bad domain\n"); search = empty_search; search.in.realm = "___no_such_domain___"; - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_NOT_FOUND); printf("Trying with a incorrect domain and correct guid\n"); search.in.domain_guid = GUID_string(tctx, &n1.data.nt5_ex.domain_uuid); - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain); CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, ""); @@ -210,7 +220,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) printf("Trying with a incorrect domain and incorrect guid\n"); search.in.domain_guid = GUID_string(tctx, &guid); - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_NOT_FOUND); CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain); CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, ""); @@ -219,7 +229,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) printf("Trying with a incorrect GUID and correct domain\n"); search.in.domain_guid = GUID_string(tctx, &guid); search.in.realm = n1.data.nt5_ex.dns_domain; - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain); CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, ""); @@ -239,10 +249,12 @@ static bool test_cldap_netlogon_flags(struct torture_context *tctx, struct cldap_netlogon search; struct netlogon_samlogon_response n1; uint32_t server_type; + struct smb_iconv_convenience *iconv_convenience = lp_iconv_convenience(tctx->lp_ctx); - cldap = cldap_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx)); + status = cldap_socket_init(tctx, NULL, NULL, NULL, &cldap); + CHECK_STATUS(status, NT_STATUS_OK); - printf("Printing out netlogon server type flags:\n"); + printf("Printing out netlogon server type flags: %s\n", dest); ZERO_STRUCT(search); search.in.dest_address = dest; @@ -251,7 +263,7 @@ static bool test_cldap_netlogon_flags(struct torture_context *tctx, search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX; search.in.map_response = true; - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); n1 = search.out.netlogon; @@ -348,10 +360,12 @@ static bool test_cldap_netlogon_flag_ds_dns_forest(struct torture_context *tctx, struct cldap_netlogon search; uint32_t server_type; struct netlogon_samlogon_response n1; + struct smb_iconv_convenience *iconv_convenience = lp_iconv_convenience(tctx->lp_ctx); bool result = true; - cldap = cldap_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx)); + status = cldap_socket_init(tctx, NULL, NULL, NULL, &cldap); + CHECK_STATUS(status, NT_STATUS_OK); printf("Testing netlogon server type flag NBT_SERVER_DS_DNS_FOREST: "); @@ -362,7 +376,7 @@ static bool test_cldap_netlogon_flag_ds_dns_forest(struct torture_context *tctx, search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX; search.in.map_response = true; - status = cldap_netlogon(cldap, tctx, &search); + status = cldap_netlogon(cldap, iconv_convenience, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); n1 = search.out.netlogon; @@ -423,7 +437,8 @@ static bool test_cldap_generic(struct torture_context *tctx, const char *dest) const char *attrs2[] = { "currentTime", "highestCommittedUSN", "netlogon", NULL }; const char *attrs3[] = { "netlogon", NULL }; - cldap = cldap_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx)); + status = cldap_socket_init(tctx, NULL, NULL, NULL, &cldap); + CHECK_STATUS(status, NT_STATUS_OK); ZERO_STRUCT(search); search.in.dest_address = dest; diff --git a/source4/torture/ldap/cldapbench.c b/source4/torture/ldap/cldapbench.c index 1fcfe5a050..a422732b03 100644 --- a/source4/torture/ldap/cldapbench.c +++ b/source4/torture/ldap/cldapbench.c @@ -20,24 +20,28 @@ */ #include "includes.h" -#include "lib/events/events.h" +#include <tevent.h> #include "libcli/cldap/cldap.h" #include "libcli/resolve/resolve.h" #include "torture/torture.h" #include "param/param.h" struct bench_state { + struct torture_context *tctx; int pass_count, fail_count; }; -static void request_handler(struct cldap_request *req) +static void request_netlogon_handler(struct tevent_req *req) { struct cldap_netlogon io; - struct bench_state *state = talloc_get_type(req->async.private_data, struct bench_state); + struct bench_state *state = tevent_req_callback_data(req, struct bench_state); NTSTATUS status; TALLOC_CTX *tmp_ctx = talloc_new(NULL); io.in.version = 6; - status = cldap_netlogon_recv(req, tmp_ctx, &io); + status = cldap_netlogon_recv(req, + lp_iconv_convenience(state->tctx->lp_ctx), + tmp_ctx, &io); + talloc_free(req); if (NT_STATUS_IS_OK(status)) { state->pass_count++; } else { @@ -47,9 +51,9 @@ static void request_handler(struct cldap_request *req) } /* - benchmark cldap calls + benchmark cldap netlogon calls */ -static bool bench_cldap(struct torture_context *tctx, const char *address) +static bool bench_cldap_netlogon(struct torture_context *tctx, const char *address) { struct cldap_socket *cldap; int num_sent=0; @@ -58,10 +62,13 @@ static bool bench_cldap(struct torture_context *tctx, const char *address) int timelimit = torture_setting_int(tctx, "timelimit", 10); struct cldap_netlogon search; struct bench_state *state; + NTSTATUS status; - cldap = cldap_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx)); + status = cldap_socket_init(tctx, tctx->ev, NULL, NULL, &cldap); + torture_assert_ntstatus_ok(tctx, status, "cldap_socket_init"); state = talloc_zero(tctx, struct bench_state); + state->tctx = tctx; ZERO_STRUCT(search); search.in.dest_address = address; @@ -69,14 +76,14 @@ static bool bench_cldap(struct torture_context *tctx, const char *address) search.in.acct_control = -1; search.in.version = 6; - printf("Running for %d seconds\n", timelimit); + printf("Running CLDAP/netlogon for %d seconds\n", timelimit); while (timeval_elapsed(&tv) < timelimit) { while (num_sent - (state->pass_count+state->fail_count) < 10) { - struct cldap_request *req; - req = cldap_netlogon_send(cldap, &search); + struct tevent_req *req; + req = cldap_netlogon_send(state, cldap, &search); + + tevent_req_set_callback(req, request_netlogon_handler, state); - req->async.private_data = state; - req->async.fn = request_handler; num_sent++; if (num_sent % 50 == 0) { if (torture_setting_bool(tctx, "progress", true)) { @@ -88,11 +95,11 @@ static bool bench_cldap(struct torture_context *tctx, const char *address) } } - event_loop_once(cldap->event_ctx); + tevent_loop_once(tctx->ev); } while (num_sent != (state->pass_count + state->fail_count)) { - event_loop_once(cldap->event_ctx); + tevent_loop_once(tctx->ev); } printf("%.1f queries per second (%d failures) \n", @@ -103,6 +110,81 @@ static bool bench_cldap(struct torture_context *tctx, const char *address) return ret; } +static void request_rootdse_handler(struct tevent_req *req) +{ + struct cldap_search io; + struct bench_state *state = tevent_req_callback_data(req, struct bench_state); + NTSTATUS status; + TALLOC_CTX *tmp_ctx = talloc_new(NULL); + status = cldap_search_recv(req, tmp_ctx, &io); + talloc_free(req); + if (NT_STATUS_IS_OK(status)) { + state->pass_count++; + } else { + state->fail_count++; + } + talloc_free(tmp_ctx); +} + +/* + benchmark cldap netlogon calls +*/ +static bool bench_cldap_rootdse(struct torture_context *tctx, const char *address) +{ + struct cldap_socket *cldap; + int num_sent=0; + struct timeval tv = timeval_current(); + bool ret = true; + int timelimit = torture_setting_int(tctx, "timelimit", 10); + struct cldap_search search; + struct bench_state *state; + NTSTATUS status; + + status = cldap_socket_init(tctx, tctx->ev, NULL, NULL, &cldap); + torture_assert_ntstatus_ok(tctx, status, "cldap_socket_init"); + + state = talloc_zero(tctx, struct bench_state); + + ZERO_STRUCT(search); + search.in.dest_address = address; + search.in.dest_port = lp_cldap_port(tctx->lp_ctx); + search.in.filter = "(objectClass=*)"; + search.in.timeout = 2; + search.in.retries = 1; + + printf("Running CLDAP/rootdse for %d seconds\n", timelimit); + while (timeval_elapsed(&tv) < timelimit) { + while (num_sent - (state->pass_count+state->fail_count) < 10) { + struct tevent_req *req; + req = cldap_search_send(state, cldap, &search); + + tevent_req_set_callback(req, request_rootdse_handler, state); + + num_sent++; + if (num_sent % 50 == 0) { + if (torture_setting_bool(tctx, "progress", true)) { + printf("%.1f queries per second (%d failures) \r", + state->pass_count / timeval_elapsed(&tv), + state->fail_count); + fflush(stdout); + } + } + } + + tevent_loop_once(tctx->ev); + } + + while (num_sent != (state->pass_count + state->fail_count)) { + tevent_loop_once(tctx->ev); + } + + printf("%.1f queries per second (%d failures) \n", + state->pass_count / timeval_elapsed(&tv), + state->fail_count); + + talloc_free(cldap); + return ret; +} /* benchmark how fast a CLDAP server can respond to a series of parallel @@ -125,7 +207,8 @@ bool torture_bench_cldap(struct torture_context *torture) return false; } - ret &= bench_cldap(torture, address); + ret &= bench_cldap_netlogon(torture, address); + ret &= bench_cldap_rootdse(torture, address); return ret; } diff --git a/source4/torture/local/config.mk b/source4/torture/local/config.mk index 36f4f08072..967e545225 100644 --- a/source4/torture/local/config.mk +++ b/source4/torture/local/config.mk @@ -44,7 +44,7 @@ TORTURE_LOCAL_OBJ_FILES = \ $(torturesrcdir)/../../lib/compression/testsuite.o \ $(torturesrcdir)/../../lib/util/charset/tests/charset.o \ $(torturesrcdir)/../libcli/security/tests/sddl.o \ - $(torturesrcdir)/../lib/tdr/testsuite.o \ + $(libtdrsrcdir)/testsuite.o \ $(torturesrcdir)/../../lib/tevent/testsuite.o \ $(torturesrcdir)/../param/tests/share.o \ $(torturesrcdir)/../param/tests/loadparm.o \ diff --git a/source4/torture/raw/notify.c b/source4/torture/raw/notify.c index 3ffc58dbe6..c92170cf61 100644 --- a/source4/torture/raw/notify.c +++ b/source4/torture/raw/notify.c @@ -1429,6 +1429,174 @@ done: return ret; } + +/* + create a secondary tree connect - used to test for a bug in Samba3 messaging + with change notify +*/ +static struct smbcli_tree *secondary_tcon(struct smbcli_state *cli, + struct torture_context *tctx) +{ + NTSTATUS status; + const char *share, *host; + struct smbcli_tree *tree; + union smb_tcon tcon; + + share = torture_setting_string(tctx, "share", NULL); + host = torture_setting_string(tctx, "host", NULL); + + printf("create a second tree context on the same session\n"); + tree = smbcli_tree_init(cli->session, tctx, false); + + tcon.generic.level = RAW_TCON_TCONX; + tcon.tconx.in.flags = 0; + tcon.tconx.in.password = data_blob(NULL, 0); + tcon.tconx.in.path = talloc_asprintf(tctx, "\\\\%s\\%s", host, share); + tcon.tconx.in.device = "A:"; + status = smb_raw_tcon(tree, tctx, &tcon); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tree); + printf("Failed to create secondary tree\n"); + return NULL; + } + + tree->tid = tcon.tconx.out.tid; + printf("tid1=%d tid2=%d\n", cli->tree->tid, tree->tid); + + return tree; +} + + +/* + very simple change notify test +*/ +static bool test_notify_tcon(struct smbcli_state *cli, struct torture_context *torture) +{ + bool ret = true; + NTSTATUS status; + union smb_notify notify; + union smb_open io; + int fnum, fnum2; + struct smbcli_request *req; + extern int torture_numops; + struct smbcli_tree *tree = NULL; + + printf("TESTING SIMPLE CHANGE NOTIFY\n"); + + /* + get a handle on the directory + */ + io.generic.level = RAW_OPEN_NTCREATEX; + io.ntcreatex.in.root_fid = 0; + io.ntcreatex.in.flags = 0; + io.ntcreatex.in.access_mask = SEC_FILE_ALL; + io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; + io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; + io.ntcreatex.in.alloc_size = 0; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; + io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + io.ntcreatex.in.security_flags = 0; + io.ntcreatex.in.fname = BASEDIR; + + status = smb_raw_open(cli->tree, torture, &io); + CHECK_STATUS(status, NT_STATUS_OK); + fnum = io.ntcreatex.out.file.fnum; + + status = smb_raw_open(cli->tree, torture, &io); + CHECK_STATUS(status, NT_STATUS_OK); + fnum2 = io.ntcreatex.out.file.fnum; + + /* ask for a change notify, + on file or directory name changes */ + notify.nttrans.level = RAW_NOTIFY_NTTRANS; + notify.nttrans.in.buffer_size = 1000; + notify.nttrans.in.completion_filter = FILE_NOTIFY_CHANGE_NAME; + notify.nttrans.in.file.fnum = fnum; + notify.nttrans.in.recursive = true; + + printf("testing notify mkdir\n"); + req = smb_raw_changenotify_send(cli->tree, ¬ify); + smbcli_mkdir(cli->tree, BASEDIR "\\subdir-name"); + + status = smb_raw_changenotify_recv(req, torture, ¬ify); + CHECK_STATUS(status, NT_STATUS_OK); + + CHECK_VAL(notify.nttrans.out.num_changes, 1); + CHECK_VAL(notify.nttrans.out.changes[0].action, NOTIFY_ACTION_ADDED); + CHECK_WSTR(notify.nttrans.out.changes[0].name, "subdir-name", STR_UNICODE); + + printf("testing notify rmdir\n"); + req = smb_raw_changenotify_send(cli->tree, ¬ify); + smbcli_rmdir(cli->tree, BASEDIR "\\subdir-name"); + + status = smb_raw_changenotify_recv(req, torture, ¬ify); + CHECK_STATUS(status, NT_STATUS_OK); + CHECK_VAL(notify.nttrans.out.num_changes, 1); + CHECK_VAL(notify.nttrans.out.changes[0].action, NOTIFY_ACTION_REMOVED); + CHECK_WSTR(notify.nttrans.out.changes[0].name, "subdir-name", STR_UNICODE); + + printf("SIMPLE CHANGE NOTIFY OK\n"); + + printf("TESTING WITH SECONDARY TCON\n"); + tree = secondary_tcon(cli, torture); + + printf("testing notify mkdir\n"); + req = smb_raw_changenotify_send(cli->tree, ¬ify); + smbcli_mkdir(cli->tree, BASEDIR "\\subdir-name"); + + status = smb_raw_changenotify_recv(req, torture, ¬ify); + CHECK_STATUS(status, NT_STATUS_OK); + + CHECK_VAL(notify.nttrans.out.num_changes, 1); + CHECK_VAL(notify.nttrans.out.changes[0].action, NOTIFY_ACTION_ADDED); + CHECK_WSTR(notify.nttrans.out.changes[0].name, "subdir-name", STR_UNICODE); + + printf("testing notify rmdir\n"); + req = smb_raw_changenotify_send(cli->tree, ¬ify); + smbcli_rmdir(cli->tree, BASEDIR "\\subdir-name"); + + status = smb_raw_changenotify_recv(req, torture, ¬ify); + CHECK_STATUS(status, NT_STATUS_OK); + CHECK_VAL(notify.nttrans.out.num_changes, 1); + CHECK_VAL(notify.nttrans.out.changes[0].action, NOTIFY_ACTION_REMOVED); + CHECK_WSTR(notify.nttrans.out.changes[0].name, "subdir-name", STR_UNICODE); + + printf("CHANGE NOTIFY WITH TCON OK\n"); + + printf("Disconnecting secondary tree\n"); + status = smb_tree_disconnect(tree); + CHECK_STATUS(status, NT_STATUS_OK); + talloc_free(tree); + + printf("testing notify mkdir\n"); + req = smb_raw_changenotify_send(cli->tree, ¬ify); + smbcli_mkdir(cli->tree, BASEDIR "\\subdir-name"); + + status = smb_raw_changenotify_recv(req, torture, ¬ify); + CHECK_STATUS(status, NT_STATUS_OK); + + CHECK_VAL(notify.nttrans.out.num_changes, 1); + CHECK_VAL(notify.nttrans.out.changes[0].action, NOTIFY_ACTION_ADDED); + CHECK_WSTR(notify.nttrans.out.changes[0].name, "subdir-name", STR_UNICODE); + + printf("testing notify rmdir\n"); + req = smb_raw_changenotify_send(cli->tree, ¬ify); + smbcli_rmdir(cli->tree, BASEDIR "\\subdir-name"); + + status = smb_raw_changenotify_recv(req, torture, ¬ify); + CHECK_STATUS(status, NT_STATUS_OK); + CHECK_VAL(notify.nttrans.out.num_changes, 1); + CHECK_VAL(notify.nttrans.out.changes[0].action, NOTIFY_ACTION_REMOVED); + CHECK_WSTR(notify.nttrans.out.changes[0].name, "subdir-name", STR_UNICODE); + + printf("CHANGE NOTIFY WITH TDIS OK\n"); +done: + smb_raw_exit(cli->session); + return ret; +} + + /* basic testing of change notify */ @@ -1442,6 +1610,7 @@ bool torture_raw_notify(struct torture_context *torture, return false; } + ret &= test_notify_tcon(cli, torture); ret &= test_notify_dir(cli, cli2, torture); ret &= test_notify_mask(cli, torture); ret &= test_notify_recursive(cli, torture); diff --git a/source4/torture/rpc/dssync.c b/source4/torture/rpc/dssync.c index 847b32827b..1aaf914ceb 100644 --- a/source4/torture/rpc/dssync.c +++ b/source4/torture/rpc/dssync.c @@ -273,7 +273,12 @@ static bool test_GetInfo(struct torture_context *tctx, struct DsSyncTest *ctx) struct cldap_socket *cldap; struct cldap_netlogon search; - cldap = cldap_socket_init(ctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx)); + status = cldap_socket_init(ctx, NULL, NULL, NULL, &cldap); + if (!NT_STATUS_IS_OK(status)) { + printf("failed to setup cldap socket - %s\n", + nt_errstr(status)); + return false; + } r.in.bind_handle = &ctx->admin.drsuapi.bind_handle; r.in.level = 1; @@ -311,7 +316,7 @@ static bool test_GetInfo(struct torture_context *tctx, struct DsSyncTest *ctx) search.in.acct_control = -1; search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX; search.in.map_response = true; - status = cldap_netlogon(cldap, ctx, &search); + status = cldap_netlogon(cldap, lp_iconv_convenience(tctx->lp_ctx), ctx, &search); if (!NT_STATUS_IS_OK(status)) { const char *errstr = nt_errstr(status); ctx->site_name = talloc_asprintf(ctx, "%s", "Default-First-Site-Name"); diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c index 7cacba7418..fe128fea52 100644 --- a/source4/torture/rpc/samba3rpc.c +++ b/source4/torture/rpc/samba3rpc.c @@ -2619,6 +2619,7 @@ static bool enumprinters(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *pipe, DATA_BLOB blob; uint32_t needed; uint32_t count; + union spoolss_PrinterInfo *info; r.in.flags = PRINTER_ENUM_LOCAL; r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", servername); @@ -2627,6 +2628,7 @@ static bool enumprinters(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *pipe, r.in.offered = 0; r.out.needed = &needed; r.out.count = &count; + r.out.info = &info; status = dcerpc_spoolss_EnumPrinters(pipe, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c index 9d8bc4b186..2bdcc3fdaf 100644 --- a/source4/torture/rpc/spoolss.c +++ b/source4/torture/rpc/spoolss.c @@ -108,6 +108,7 @@ static bool test_EnumPorts(struct torture_context *tctx, DATA_BLOB blob; uint32_t needed; uint32_t count; + union spoolss_PortInfo *info; r.in.servername = ""; r.in.level = level; @@ -115,6 +116,7 @@ static bool test_EnumPorts(struct torture_context *tctx, r.in.offered = 0; r.out.needed = &needed; r.out.count = &count; + r.out.info = &info; torture_comment(tctx, "Testing EnumPorts level %u\n", r.in.level); @@ -137,8 +139,10 @@ static bool test_EnumPorts(struct torture_context *tctx, torture_assert_werr_ok(tctx, r.out.result, "EnumPorts failed"); + torture_assert(tctx, info, "EnumPorts returned no info"); + ctx->port_count[level] = count; - ctx->ports[level] = r.out.info; + ctx->ports[level] = info; } for (i=1;i<ARRAY_SIZE(levels);i++) { @@ -307,6 +311,7 @@ static bool test_EnumPrinterDrivers(struct torture_context *tctx, DATA_BLOB blob; uint32_t needed; uint32_t count; + union spoolss_DriverInfo *info; r.in.server = ""; r.in.environment = SPOOLSS_ARCHITECTURE_NT_X86; @@ -315,6 +320,7 @@ static bool test_EnumPrinterDrivers(struct torture_context *tctx, r.in.offered = 0; r.out.needed = &needed; r.out.count = &count; + r.out.info = &info; torture_comment(tctx, "Testing EnumPrinterDrivers level %u\n", r.in.level); @@ -339,7 +345,7 @@ static bool test_EnumPrinterDrivers(struct torture_context *tctx, torture_assert_werr_ok(tctx, r.out.result, "EnumPrinterDrivers failed"); ctx->driver_count[level] = count; - ctx->drivers[level] = r.out.info; + ctx->drivers[level] = info; } for (i=1;i<ARRAY_SIZE(levels);i++) { @@ -426,6 +432,7 @@ static bool test_EnumMonitors(struct torture_context *tctx, DATA_BLOB blob; uint32_t needed; uint32_t count; + union spoolss_MonitorInfo *info; r.in.servername = ""; r.in.level = level; @@ -433,6 +440,7 @@ static bool test_EnumMonitors(struct torture_context *tctx, r.in.offered = 0; r.out.needed = &needed; r.out.count = &count; + r.out.info = &info; torture_comment(tctx, "Testing EnumMonitors level %u\n", r.in.level); @@ -456,7 +464,7 @@ static bool test_EnumMonitors(struct torture_context *tctx, torture_assert_werr_ok(tctx, r.out.result, "EnumMonitors failed"); ctx->monitor_count[level] = count; - ctx->monitors[level] = r.out.info; + ctx->monitors[level] = info; } for (i=1;i<ARRAY_SIZE(levels);i++) { @@ -499,6 +507,7 @@ static bool test_EnumPrintProcessors(struct torture_context *tctx, DATA_BLOB blob; uint32_t needed; uint32_t count; + union spoolss_PrintProcessorInfo *info; r.in.servername = ""; r.in.environment = "Windows NT x86"; @@ -507,6 +516,7 @@ static bool test_EnumPrintProcessors(struct torture_context *tctx, r.in.offered = 0; r.out.needed = &needed; r.out.count = &count; + r.out.info = &info; torture_comment(tctx, "Testing EnumPrintProcessors level %u\n", r.in.level); @@ -530,7 +540,7 @@ static bool test_EnumPrintProcessors(struct torture_context *tctx, torture_assert_werr_ok(tctx, r.out.result, "EnumPrintProcessors failed"); ctx->print_processor_count[level] = count; - ctx->print_processors[level] = r.out.info; + ctx->print_processors[level] = info; } for (i=1;i<ARRAY_SIZE(levels);i++) { @@ -558,6 +568,57 @@ static bool test_EnumPrintProcessors(struct torture_context *tctx, return true; } +static bool test_EnumPrintProcDataTypes(struct torture_context *tctx, + struct dcerpc_pipe *p, + struct test_spoolss_context *ctx) +{ + NTSTATUS status; + struct spoolss_EnumPrintProcDataTypes r; + uint16_t levels[] = { 1 }; + int i; + + for (i=0;i<ARRAY_SIZE(levels);i++) { + int level = levels[i]; + DATA_BLOB blob; + uint32_t needed; + uint32_t count; + union spoolss_PrintProcDataTypesInfo *info; + + r.in.servername = ""; + r.in.print_processor_name = "winprint"; + r.in.level = level; + r.in.buffer = NULL; + r.in.offered = 0; + r.out.needed = &needed; + r.out.count = &count; + r.out.info = &info; + + torture_comment(tctx, "Testing EnumPrintProcDataTypes level %u\n", r.in.level); + + status = dcerpc_spoolss_EnumPrintProcDataTypes(p, ctx, &r); + torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrintProcDataType failed"); + if (W_ERROR_IS_OK(r.out.result)) { + /* TODO: do some more checks here */ + continue; + } + torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER, + "EnumPrintProcDataTypes unexpected return code"); + + blob = data_blob_talloc(ctx, NULL, needed); + data_blob_clear(&blob); + r.in.buffer = &blob; + r.in.offered = needed; + + status = dcerpc_spoolss_EnumPrintProcDataTypes(p, ctx, &r); + torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrintProcDataTypes failed"); + + torture_assert_werr_ok(tctx, r.out.result, "EnumPrintProcDataTypes failed"); + } + + return true; +} + + static bool test_EnumPrinters(struct torture_context *tctx, struct dcerpc_pipe *p, struct test_spoolss_context *ctx) @@ -572,6 +633,7 @@ static bool test_EnumPrinters(struct torture_context *tctx, DATA_BLOB blob; uint32_t needed; uint32_t count; + union spoolss_PrinterInfo *info; r.in.flags = PRINTER_ENUM_LOCAL; r.in.server = ""; @@ -580,6 +642,7 @@ static bool test_EnumPrinters(struct torture_context *tctx, r.in.offered = 0; r.out.needed = &needed; r.out.count = &count; + r.out.info = &info; torture_comment(tctx, "Testing EnumPrinters level %u\n", r.in.level); @@ -603,7 +666,7 @@ static bool test_EnumPrinters(struct torture_context *tctx, torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed"); ctx->printer_count[level] = count; - ctx->printers[level] = r.out.info; + ctx->printers[level] = info; } for (i=1;i<ARRAY_SIZE(levels);i++) { @@ -793,12 +856,15 @@ static bool test_EnumForms(struct torture_context *tctx, for (i=0; i<ARRAY_SIZE(levels); i++) { + union spoolss_FormInfo *info; + r.in.handle = handle; r.in.level = levels[i]; r.in.buffer = NULL; r.in.offered = 0; r.out.needed = &needed; r.out.count = &count; + r.out.info = &info; torture_comment(tctx, "Testing EnumForms level %d\n", levels[i]); @@ -813,7 +879,6 @@ static bool test_EnumForms(struct torture_context *tctx, torture_fail(tctx, "EnumForms on the PrintServer isn't supported by test server (NT4)"); if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) { - union spoolss_FormInfo *info; int j; DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed); data_blob_clear(&blob); @@ -822,9 +887,7 @@ static bool test_EnumForms(struct torture_context *tctx, status = dcerpc_spoolss_EnumForms(p, tctx, &r); - torture_assert(tctx, r.out.info, "No forms returned"); - - info = r.out.info; + torture_assert(tctx, info, "No forms returned"); for (j = 0; j < count; j++) { if (!print_server) @@ -928,6 +991,7 @@ static bool test_EnumPorts_old(struct torture_context *tctx, struct spoolss_EnumPorts r; uint32_t needed; uint32_t count; + union spoolss_PortInfo *info; r.in.servername = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); @@ -936,6 +1000,7 @@ static bool test_EnumPorts_old(struct torture_context *tctx, r.in.offered = 0; r.out.needed = &needed; r.out.count = &count; + r.out.info = &info; torture_comment(tctx, "Testing EnumPorts\n"); @@ -952,7 +1017,7 @@ static bool test_EnumPorts_old(struct torture_context *tctx, status = dcerpc_spoolss_EnumPorts(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "EnumPorts failed"); - torture_assert(tctx, r.out.info, "No ports returned"); + torture_assert(tctx, info, "No ports returned"); } return true; @@ -1080,6 +1145,7 @@ static bool test_EnumJobs(struct torture_context *tctx, struct spoolss_EnumJobs r; uint32_t needed; uint32_t count; + union spoolss_JobInfo *info; r.in.handle = handle; r.in.firstjob = 0; @@ -1089,6 +1155,7 @@ static bool test_EnumJobs(struct torture_context *tctx, r.in.offered = 0; r.out.needed = &needed; r.out.count = &count; + r.out.info = &info; torture_comment(tctx, "Testing EnumJobs\n"); @@ -1097,7 +1164,6 @@ static bool test_EnumJobs(struct torture_context *tctx, torture_assert_ntstatus_ok(tctx, status, "EnumJobs failed"); if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) { - union spoolss_JobInfo *info; int j; DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed); data_blob_clear(&blob); @@ -1106,9 +1172,7 @@ static bool test_EnumJobs(struct torture_context *tctx, status = dcerpc_spoolss_EnumJobs(p, tctx, &r); - torture_assert(tctx, r.out.info, "No jobs returned"); - - info = r.out.info; + torture_assert(tctx, info, "No jobs returned"); for (j = 0; j < count; j++) { @@ -1273,13 +1337,15 @@ static bool test_GetPrinterData(struct torture_context *tctx, NTSTATUS status; struct spoolss_GetPrinterData r; uint32_t needed; - enum spoolss_PrinterDataType type; + enum winreg_Type type; + union spoolss_PrinterData data; r.in.handle = handle; r.in.value_name = value_name; r.in.offered = 0; r.out.needed = &needed; r.out.type = &type; + r.out.data = &data; torture_comment(tctx, "Testing GetPrinterData\n"); @@ -1306,7 +1372,7 @@ static bool test_GetPrinterDataEx(struct torture_context *tctx, { NTSTATUS status; struct spoolss_GetPrinterDataEx r; - uint32_t type; + enum winreg_Type type; uint32_t needed; r.in.handle = handle; @@ -1353,16 +1419,15 @@ static bool test_EnumPrinterData(struct torture_context *tctx, struct dcerpc_pip do { uint32_t value_size = 0; uint32_t data_size = 0; - uint32_t printerdata_type = 0; - DATA_BLOB data = data_blob(NULL,0); + enum winreg_Type type = 0; r.in.value_offered = value_size; r.out.value_needed = &value_size; r.in.data_offered = data_size; r.out.data_needed = &data_size; - r.out.printerdata_type = &printerdata_type; - r.out.buffer = &data; + r.out.type = &type; + r.out.data = talloc_zero_array(tctx, uint8_t, 0); torture_comment(tctx, "Testing EnumPrinterData\n"); @@ -1371,7 +1436,9 @@ static bool test_EnumPrinterData(struct torture_context *tctx, struct dcerpc_pip torture_assert_ntstatus_ok(tctx, status, "EnumPrinterData failed"); r.in.value_offered = value_size; + r.out.value_name = talloc_zero_array(tctx, const char, value_size); r.in.data_offered = data_size; + r.out.data = talloc_zero_array(tctx, uint8_t, data_size); status = dcerpc_spoolss_EnumPrinterData(p, tctx, &r); @@ -1396,6 +1463,7 @@ static bool test_EnumPrinterDataEx(struct torture_context *tctx, { NTSTATUS status; struct spoolss_EnumPrinterDataEx r; + struct spoolss_PrinterEnumValues *info; uint32_t needed; uint32_t count; @@ -1404,6 +1472,7 @@ static bool test_EnumPrinterDataEx(struct torture_context *tctx, r.in.offered = 0; r.out.needed = &needed; r.out.count = &count; + r.out.info = &info; torture_comment(tctx, "Testing EnumPrinterDataEx\n"); @@ -1411,7 +1480,6 @@ static bool test_EnumPrinterDataEx(struct torture_context *tctx, torture_assert_ntstatus_ok(tctx, status, "EnumPrinterDataEx failed"); r.in.offered = needed; - r.out.buffer = talloc_array(tctx, uint8_t, needed); status = dcerpc_spoolss_EnumPrinterDataEx(p, tctx, &r); @@ -1451,7 +1519,7 @@ static bool test_SetPrinterData(struct torture_context *tctx, r.in.handle = handle; r.in.value_name = value_name; - r.in.type = SPOOLSS_PRINTER_DATA_TYPE_STRING; + r.in.type = REG_SZ; r.in.data.string = "dog"; torture_comment(tctx, "Testing SetPrinterData\n"); @@ -1722,6 +1790,7 @@ static bool test_EnumPrinters_old(struct torture_context *tctx, struct dcerpc_pi r.in.offered = 0; r.out.needed = &needed; r.out.count = &count; + r.out.info = &info; torture_comment(tctx, "Testing EnumPrinters level %u\n", r.in.level); @@ -1740,13 +1809,11 @@ static bool test_EnumPrinters_old(struct torture_context *tctx, struct dcerpc_pi torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed"); - if (!r.out.info) { + if (!info) { torture_comment(tctx, "No printers returned\n"); return true; } - info = r.out.info; - for (j=0;j<count;j++) { if (r.in.level == 1) { /* the names appear to be comma-separated name lists? */ @@ -1829,6 +1896,7 @@ static bool test_EnumPrinterDrivers_old(struct torture_context *tctx, uint32_t needed; uint32_t count; + union spoolss_DriverInfo *info; r.in.server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); r.in.environment = "Windows NT x86"; @@ -1837,6 +1905,7 @@ static bool test_EnumPrinterDrivers_old(struct torture_context *tctx, r.in.offered = 0; r.out.needed = &needed; r.out.count = &count; + r.out.info = &info; torture_comment(tctx, "Testing EnumPrinterDrivers level %u\n", r.in.level); @@ -1856,7 +1925,7 @@ static bool test_EnumPrinterDrivers_old(struct torture_context *tctx, torture_assert_werr_ok(tctx, r.out.result, "EnumPrinterDrivers failed"); - if (!r.out.info) { + if (!info) { torture_comment(tctx, "No printer drivers returned\n"); break; } @@ -1937,6 +2006,7 @@ bool torture_rpc_spoolss(struct torture_context *torture) ret &= test_EnumPrinterDrivers(torture, p, ctx); ret &= test_EnumMonitors(torture, p, ctx); ret &= test_EnumPrintProcessors(torture, p, ctx); + ret &= test_EnumPrintProcDataTypes(torture, p, ctx); ret &= test_EnumPrinters(torture, p, ctx); ret &= test_OpenPrinter_badname(torture, p, "__INVALID_PRINTER__"); ret &= test_OpenPrinter_badname(torture, p, "\\\\__INVALID_HOST__"); diff --git a/source4/torture/rpc/spoolss_notify.c b/source4/torture/rpc/spoolss_notify.c index 048f255ffc..b7f2d3c410 100644 --- a/source4/torture/rpc/spoolss_notify.c +++ b/source4/torture/rpc/spoolss_notify.c @@ -252,15 +252,15 @@ static bool test_RFFPCNEx(struct torture_context *tctx, t1.flags = 0; t1.count = 2; t1.types = talloc_zero_array(tctx, struct spoolss_NotifyOptionType, 2); - t1.types[0].type = SPOOLSS_NOTIFY_PRINTER; + t1.types[0].type = PRINTER_NOTIFY_TYPE; t1.types[0].count = 1; - t1.types[0].fields = talloc_array(t1.types, enum spoolss_Field, 1); - t1.types[0].fields[0] = SPOOLSS_FIELD_SERVER_NAME; + t1.types[0].fields = talloc_array(t1.types, union spoolss_Field, 1); + t1.types[0].fields[0].field = PRINTER_NOTIFY_FIELD_SERVER_NAME; - t1.types[1].type = SPOOLSS_NOTIFY_JOB; + t1.types[1].type = JOB_NOTIFY_TYPE; t1.types[1].count = 1; - t1.types[1].fields = talloc_array(t1.types, enum spoolss_Field, 1); - t1.types[1].fields[0] = SPOOLSS_FIELD_PRINTER_NAME; + t1.types[1].fields = talloc_array(t1.types, union spoolss_Field, 1); + t1.types[1].fields[0].field = PRINTER_NOTIFY_FIELD_PRINTER_NAME; r.in.notify_options = &t1; r.in.handle = &handle; diff --git a/source4/torture/rpc/spoolss_win.c b/source4/torture/rpc/spoolss_win.c index 08fadafe2c..c50cbfbaee 100644 --- a/source4/torture/rpc/spoolss_win.c +++ b/source4/torture/rpc/spoolss_win.c @@ -33,7 +33,7 @@ struct test_spoolss_win_context { union spoolss_PrinterInfo *current_info; /* EnumPrinterKeys */ - char *printer_keys; + const char **printer_keys; }; /* This is a convenience function for all OpenPrinterEx calls */ @@ -156,7 +156,8 @@ static bool test_GetPrinterData(struct torture_context *tctx, NTSTATUS status; struct spoolss_GetPrinterData gpd; uint32_t needed; - enum spoolss_PrinterDataType type; + enum winreg_Type type; + union spoolss_PrinterData data; torture_comment(tctx, "Testing GetPrinterData(%s).\n", value_name); gpd.in.handle = handle; @@ -164,6 +165,7 @@ static bool test_GetPrinterData(struct torture_context *tctx, gpd.in.offered = 4; gpd.out.needed = &needed; gpd.out.type = &type; + gpd.out.data = &data; status = dcerpc_spoolss_GetPrinterData(p, tctx, &gpd); torture_assert_ntstatus_ok(tctx, status, "GetPrinterData failed."); @@ -171,7 +173,7 @@ static bool test_GetPrinterData(struct torture_context *tctx, "GetPrinterData did not return expected error value."); if (W_ERROR_IS_OK(expected_werr)) { - torture_assert_int_equal(tctx, gpd.out.data.value, + torture_assert_int_equal(tctx, data.value, expected_value, "GetPrinterData did not return expected value."); } @@ -188,6 +190,7 @@ static bool test_EnumPrinters(struct torture_context *tctx, DATA_BLOB blob = data_blob_talloc_zero(ctx, initial_blob_size); uint32_t needed; uint32_t count; + union spoolss_PrinterInfo *info; ep.in.flags = PRINTER_ENUM_NAME; ep.in.server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); @@ -196,6 +199,7 @@ static bool test_EnumPrinters(struct torture_context *tctx, ep.in.offered = initial_blob_size; ep.out.needed = &needed; ep.out.count = &count; + ep.out.info = &info; status = dcerpc_spoolss_EnumPrinters(p, ctx, &ep); torture_assert_ntstatus_ok(tctx, status, "EnumPrinters failed."); @@ -211,7 +215,7 @@ static bool test_EnumPrinters(struct torture_context *tctx, torture_assert_werr_ok(tctx, ep.out.result, "EnumPrinters failed."); ctx->printer_count = count; - ctx->printer_info = ep.out.info; + ctx->printer_info = info; torture_comment(tctx, "Found %d printer(s).\n", ctx->printer_count); @@ -264,6 +268,7 @@ static bool test_EnumJobs(struct torture_context *tctx, DATA_BLOB blob = data_blob_talloc_zero(tctx, 1024); uint32_t needed; uint32_t count; + union spoolss_JobInfo *info; torture_comment(tctx, "Test EnumJobs\n"); @@ -273,6 +278,7 @@ static bool test_EnumJobs(struct torture_context *tctx, ej.in.offered = 1024; ej.out.needed = &needed; ej.out.count = &count; + ej.out.info = &info; status = dcerpc_spoolss_EnumJobs(p, tctx, &ej); torture_assert_ntstatus_ok(tctx, status, "EnumJobs failed"); @@ -323,6 +329,7 @@ static bool test_EnumForms(struct torture_context *tctx, DATA_BLOB blob = data_blob_talloc_zero(tctx, initial_blob_size); uint32_t needed; uint32_t count; + union spoolss_FormInfo *info; torture_comment(tctx, "Testing EnumForms\n"); @@ -332,6 +339,7 @@ static bool test_EnumForms(struct torture_context *tctx, ef.in.offered = initial_blob_size; ef.out.needed = &needed; ef.out.count = &count; + ef.out.info = &info; status = dcerpc_spoolss_EnumForms(p, tctx, &ef); torture_assert_ntstatus_ok(tctx, status, "EnumForms failed"); @@ -358,22 +366,22 @@ static bool test_EnumPrinterKey(struct torture_context *tctx, NTSTATUS status; struct spoolss_EnumPrinterKey epk; uint32_t needed = 0; + const char **key_buffer = NULL; torture_comment(tctx, "Testing EnumPrinterKey(%s)\n", key); epk.in.handle = handle; epk.in.key_name = talloc_strdup(tctx, key); - epk.in.key_buffer_size = 0; + epk.in.offered = 0; epk.out.needed = &needed; - epk.out.key_buffer = talloc_array(tctx, uint16_t, 0); + epk.out.key_buffer = &key_buffer; status = dcerpc_spoolss_EnumPrinterKey(p, tctx, &epk); torture_assert_ntstatus_ok(tctx, status, "EnumPrinterKey failed"); if (W_ERROR_EQUAL(epk.out.result, WERR_MORE_DATA)) { - epk.in.key_buffer_size = needed; - epk.out.key_buffer = talloc_array(tctx, uint16_t, needed/2); + epk.in.offered = needed; status = dcerpc_spoolss_EnumPrinterKey(p, tctx, &epk); torture_assert_ntstatus_ok(tctx, status, "EnumPrinterKey failed"); @@ -381,9 +389,7 @@ static bool test_EnumPrinterKey(struct torture_context *tctx, torture_assert_werr_ok(tctx, epk.out.result, "EnumPrinterKey failed"); - convert_string_talloc_convenience(ctx, lp_iconv_convenience(tctx->lp_ctx), CH_UTF16, - CH_UNIX, epk.out.key_buffer, *epk.out.needed, - (void**)&ctx->printer_keys, NULL, false); + ctx->printer_keys = key_buffer; return true; } @@ -397,6 +403,7 @@ static bool test_EnumPrinterDataEx(struct torture_context *tctx, { NTSTATUS status; struct spoolss_EnumPrinterDataEx epde; + struct spoolss_PrinterEnumValues *info; uint32_t needed; uint32_t count; @@ -407,13 +414,12 @@ static bool test_EnumPrinterDataEx(struct torture_context *tctx, epde.in.offered = 0; epde.out.needed = &needed; epde.out.count = &count; - epde.out.buffer = talloc_array(tctx, uint8_t, 0); + epde.out.info = &info; status = dcerpc_spoolss_EnumPrinterDataEx(p, tctx, &epde); torture_assert_ntstatus_ok(tctx, status, "EnumPrinterDataEx failed."); if (W_ERROR_EQUAL(epde.out.result, WERR_MORE_DATA)) { epde.in.offered = needed; - epde.out.buffer = talloc_array(tctx, uint8_t, needed); status = dcerpc_spoolss_EnumPrinterDataEx(p, tctx, &epde); torture_assert_ntstatus_ok(tctx, status, "EnumPrinterDataEx failed."); @@ -450,7 +456,7 @@ static bool test_WinXP(struct torture_context *tctx, struct dcerpc_pipe *p) * code, the unused_handle structures are used for that. */ struct policy_handle unused_handle1, unused_handle2; char *server_name; - char *key_pointer; + uint32_t i; ntvfs_init(tctx->lp_ctx); @@ -525,24 +531,15 @@ static bool test_WinXP(struct torture_context *tctx, struct dcerpc_pipe *p) ret &= test_EnumForms(tctx, p, &handle03, 0); ret &= test_EnumPrinterKey(tctx, p, &handle03, "", ctx); - key_pointer = ctx->printer_keys; - while(*key_pointer != '\0') { - char *end_pointer; - char *key_name; - - for(end_pointer = key_pointer; *end_pointer != '\0'; - ++end_pointer) { - /* Do nothing, just move the pointer */ - } - key_name = talloc_strndup(tctx, key_pointer, - end_pointer - key_pointer); - - ret &= test_EnumPrinterKey(tctx, p, &handle03, key_name, - tmp_ctx); - ret &= test_EnumPrinterDataEx(tctx, p, &handle03, key_name, 0, - WERR_OK); - - key_pointer = ++end_pointer; + + for (i=0; ctx->printer_keys[i] != NULL; i++) { + + ret &= test_EnumPrinterKey(tctx, p, &handle03, + ctx->printer_keys[i], + tmp_ctx); + ret &= test_EnumPrinterDataEx(tctx, p, &handle03, + ctx->printer_keys[i], 0, + WERR_OK); } ret &= test_EnumPrinterDataEx(tctx, p, &handle03, "", 0, diff --git a/source4/torture/smb2/create.c b/source4/torture/smb2/create.c index 6d898a128c..febfbe03ec 100644 --- a/source4/torture/smb2/create.c +++ b/source4/torture/smb2/create.c @@ -43,6 +43,8 @@ return false; \ }} while (0) +#define TARGET_IS_WIN7(_tctx) (torture_setting_bool(_tctx, "win7", false)) + /* test some interesting combinations found by gentest */ @@ -160,7 +162,11 @@ static bool test_create_gentest(struct torture_context *torture, struct smb2_tre } } - CHECK_EQUAL(access_mask, 0x0df0fe00); + if (TARGET_IS_WIN7(torture)) { + CHECK_EQUAL(access_mask, 0x0de0fe00); + } else { + CHECK_EQUAL(access_mask, 0x0df0fe00); + } io.in.create_disposition = NTCREATEX_DISP_OPEN_IF; io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED; diff --git a/source4/torture/smb2/lock.c b/source4/torture/smb2/lock.c index d820983022..5f0293c681 100644 --- a/source4/torture/smb2/lock.c +++ b/source4/torture/smb2/lock.c @@ -28,6 +28,9 @@ #include "librpc/gen_ndr/ndr_security.h" +#define TARGET_IS_WINDOWS(_tctx) (torture_setting_bool(_tctx, "win7", false) || torture_setting_bool(torture, "windows", false)) +#define TARGET_IS_WIN7(_tctx) (torture_setting_bool(_tctx, "win7", false)) + #define CHECK_STATUS(status, correct) do { \ if (!NT_STATUS_EQUAL(status, correct)) { \ printf("(%s) Incorrect status %s - should be %s\n", \ @@ -97,16 +100,26 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree el[0].reserved = 0x00000000; el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY; status = smb2_lock(tree, &lck); - CHECK_STATUS(status, NT_STATUS_OK); + if (TARGET_IS_WIN7(torture)) { + CHECK_STATUS(status, NT_STATUS_WIN7_INVALID_RANGE); + } else { + CHECK_STATUS(status, NT_STATUS_OK); + } CHECK_VALUE(lck.out.reserved, 0); lck.in.reserved = 0x123ab2; status = smb2_lock(tree, &lck); - CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); + if (TARGET_IS_WIN7(torture)) { + CHECK_STATUS(status, NT_STATUS_WIN7_INVALID_RANGE); + } else { + CHECK_STATUS(status, NT_STATUS_OK); + } lck.in.reserved = 0x123ab3; status = smb2_lock(tree, &lck); - if (torture_setting_bool(torture, "windows", false)) { + if (TARGET_IS_WIN7(torture)) { + CHECK_STATUS(status, NT_STATUS_WIN7_INVALID_RANGE); + } else if (TARGET_IS_WINDOWS(torture)) { CHECK_STATUS(status, NT_STATUS_OK); } else { CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); @@ -115,11 +128,17 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree lck.in.reserved = 0x123ab4; status = smb2_lock(tree, &lck); - CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); + if (TARGET_IS_WIN7(torture)) { + CHECK_STATUS(status, NT_STATUS_WIN7_INVALID_RANGE); + } else { + CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); + } lck.in.reserved = 0x123ab5; status = smb2_lock(tree, &lck); - if (torture_setting_bool(torture, "windows", false)) { + if (TARGET_IS_WIN7(torture)) { + CHECK_STATUS(status, NT_STATUS_WIN7_INVALID_RANGE); + } else if (TARGET_IS_WINDOWS(torture)) { CHECK_STATUS(status, NT_STATUS_OK); } else { CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); @@ -141,7 +160,7 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); status = smb2_lock(tree, &lck); - if (torture_setting_bool(torture, "windows", false)) { + if (TARGET_IS_WINDOWS(torture)) { CHECK_STATUS(status, NT_STATUS_OK); } else { CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); @@ -152,7 +171,7 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); status = smb2_lock(tree, &lck); - if (torture_setting_bool(torture, "windows", false)) { + if (TARGET_IS_WINDOWS(torture)) { CHECK_STATUS(status, NT_STATUS_OK); } else { CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); @@ -481,7 +500,6 @@ static bool test_lock_rw_exclusiv(struct torture_context *torture, struct smb2_t return test_lock_read_write(torture, tree, &s); } - static bool test_lock_auto_unlock(struct torture_context *torture, struct smb2_tree *tree) { bool ret = true; @@ -513,13 +531,14 @@ static bool test_lock_auto_unlock(struct torture_context *torture, struct smb2_t CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); status = smb2_lock(tree, &lck); - if (torture_setting_bool(torture, "windows", false)) { + if (TARGET_IS_WINDOWS(torture)) { CHECK_STATUS(status, NT_STATUS_OK); } else { CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); } - + status = smb2_lock(tree, &lck); + CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); done: return ret; |