summaryrefslogtreecommitdiff
path: root/source4/torture
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2009-03-20 01:30:36 +0100
committerJelmer Vernooij <jelmer@samba.org>2009-03-20 01:30:36 +0100
commit5fe2b28f45289dc5578cdd536600f0d30a14d820 (patch)
tree4bdf36d0d4d8bdddcb3d618b4b01839370ed57c3 /source4/torture
parentec9aeeab00584f4d3dfe9afb83dc1a77b8463b81 (diff)
parent3a4638db0351368d3b148bf547546f28fa0b1479 (diff)
downloadsamba-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.c75
-rw-r--r--source4/torture/ldap/cldapbench.c113
-rw-r--r--source4/torture/local/config.mk2
-rw-r--r--source4/torture/raw/notify.c169
-rw-r--r--source4/torture/rpc/dssync.c9
-rw-r--r--source4/torture/rpc/samba3rpc.c2
-rw-r--r--source4/torture/rpc/spoolss.c122
-rw-r--r--source4/torture/rpc/spoolss_notify.c12
-rw-r--r--source4/torture/rpc/spoolss_win.c61
-rw-r--r--source4/torture/smb2/create.c8
-rw-r--r--source4/torture/smb2/lock.c39
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, &notify);
+ smbcli_mkdir(cli->tree, BASEDIR "\\subdir-name");
+
+ status = smb_raw_changenotify_recv(req, torture, &notify);
+ 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, &notify);
+ smbcli_rmdir(cli->tree, BASEDIR "\\subdir-name");
+
+ status = smb_raw_changenotify_recv(req, torture, &notify);
+ 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, &notify);
+ smbcli_mkdir(cli->tree, BASEDIR "\\subdir-name");
+
+ status = smb_raw_changenotify_recv(req, torture, &notify);
+ 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, &notify);
+ smbcli_rmdir(cli->tree, BASEDIR "\\subdir-name");
+
+ status = smb_raw_changenotify_recv(req, torture, &notify);
+ 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, &notify);
+ smbcli_mkdir(cli->tree, BASEDIR "\\subdir-name");
+
+ status = smb_raw_changenotify_recv(req, torture, &notify);
+ 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, &notify);
+ smbcli_rmdir(cli->tree, BASEDIR "\\subdir-name");
+
+ status = smb_raw_changenotify_recv(req, torture, &notify);
+ 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;