summaryrefslogtreecommitdiff
path: root/source4/torture
diff options
context:
space:
mode:
Diffstat (limited to 'source4/torture')
-rw-r--r--source4/torture/rpc/srvsvc.c267
1 files changed, 253 insertions, 14 deletions
diff --git a/source4/torture/rpc/srvsvc.c b/source4/torture/rpc/srvsvc.c
index 685a71cfa3..696a42d167 100644
--- a/source4/torture/rpc/srvsvc.c
+++ b/source4/torture/rpc/srvsvc.c
@@ -500,6 +500,230 @@ static BOOL test_NetShareGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return ret;
}
+static BOOL test_NetShareAddSetDel(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
+{
+ NTSTATUS status;
+ struct srvsvc_NetShareAdd a;
+ struct srvsvc_NetShareSetInfo r;
+ struct srvsvc_NetShareGetInfo q;
+ struct srvsvc_NetShareDel d;
+ struct {
+ uint32_t level;
+ WERROR expected;
+ } levels[] = {
+ { 0, WERR_UNKNOWN_LEVEL },
+ { 1, WERR_OK },
+ { 2, WERR_OK },
+ { 501, WERR_UNKNOWN_LEVEL },
+ { 502, WERR_OK },
+ { 1004, WERR_OK },
+ { 1005, WERR_OK },
+ { 1006, WERR_OK },
+/* { 1007, WERR_OK }, */
+ { 1501, WERR_OK },
+ };
+ int i;
+ BOOL ret = True;
+
+ a.in.server_unc = r.in.server_unc = q.in.server_unc = d.in.server_unc =
+ talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
+ r.in.share_name = talloc_strdup(mem_ctx, "testshare");
+
+ a.in.level = 2;
+ a.in.info.info2 = talloc(mem_ctx, struct srvsvc_NetShareInfo2);
+ a.in.info.info2->name = r.in.share_name;
+ a.in.info.info2->type = STYPE_DISKTREE;
+ a.in.info.info2->comment = talloc_strdup(mem_ctx, "test comment");
+ a.in.info.info2->permissions = 123434566;
+ a.in.info.info2->max_users = -1;
+ a.in.info.info2->current_users = 0;
+ a.in.info.info2->path = talloc_strdup(mem_ctx, "C:\\");
+ a.in.info.info2->password = NULL;
+
+ a.in.parm_error = NULL;
+
+ status = dcerpc_srvsvc_NetShareAdd(p, mem_ctx, &a);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("NetShareAdd level 2 on share 'testshare' failed - %s\n",
+ nt_errstr(status));
+ return False;
+ } else if (!W_ERROR_EQUAL(a.out.result, WERR_OK)) {
+ d_printf("NetShareAdd level 2 on share 'testshare' failed - %s\n",
+ win_errstr(a.out.result));
+ return False;
+ }
+
+ r.in.parm_error = NULL;
+
+ q.in.level = 502;
+
+ for (i = 0; i < ARRAY_SIZE(levels); i++) {
+
+ r.in.level = levels[i].level;
+ ZERO_STRUCT(r.out);
+
+ d_printf("testing NetShareSetInfo level %u on share '%s'\n",
+ r.in.level, r.in.share_name);
+
+ switch (levels[i].level) {
+ case 0:
+ r.in.info.info0 = talloc(mem_ctx, struct srvsvc_NetShareInfo0);
+ r.in.info.info0->name = r.in.share_name;
+ break;
+ case 1:
+ r.in.info.info1 = talloc(mem_ctx, struct srvsvc_NetShareInfo1);
+ r.in.info.info1->name = r.in.share_name;
+ r.in.info.info1->type = STYPE_DISKTREE;
+ r.in.info.info1->comment = talloc_strdup(mem_ctx, "test comment 1");
+ break;
+ case 2:
+ r.in.info.info2 = talloc(mem_ctx, struct srvsvc_NetShareInfo2);
+ r.in.info.info2->name = r.in.share_name;
+ r.in.info.info2->type = STYPE_DISKTREE;
+ r.in.info.info2->comment = talloc_strdup(mem_ctx, "test comment 2");
+ r.in.info.info2->permissions = 0;
+ r.in.info.info2->max_users = 2;
+ r.in.info.info2->current_users = 1;
+ r.in.info.info2->path = talloc_strdup(mem_ctx, "::BLaH::"); /* "C:\\"); */
+ r.in.info.info2->password = NULL;
+ break;
+ case 501:
+ r.in.info.info501 = talloc(mem_ctx, struct srvsvc_NetShareInfo501);
+ r.in.info.info501->name = r.in.share_name;
+ r.in.info.info501->type = STYPE_DISKTREE;
+ r.in.info.info501->comment = talloc_strdup(mem_ctx, "test comment 501");
+ r.in.info.info501->csc_policy = 0;
+ break;
+ case 502:
+ r.in.info.info502 = talloc(mem_ctx, struct srvsvc_NetShareInfo502);
+ r.in.info.info502->name = r.in.share_name;
+ r.in.info.info502->type = STYPE_DISKTREE;
+ r.in.info.info502->comment = talloc_strdup(mem_ctx, "test comment 502");
+ r.in.info.info502->permissions = 0;
+ r.in.info.info502->max_users = 502;
+ r.in.info.info502->current_users = 1;
+ r.in.info.info502->path = talloc_strdup(mem_ctx, "C:\\");
+ r.in.info.info502->password = NULL;
+ r.in.info.info502->unknown = 0;
+ r.in.info.info502->sd = NULL;
+ break;
+ case 1004:
+ r.in.info.info1004 = talloc(mem_ctx, struct srvsvc_NetShareInfo1004);
+ r.in.info.info1004->comment = talloc_strdup(mem_ctx, "test comment 1004");
+ break;
+ case 1005:
+ r.in.info.info1005 = talloc(mem_ctx, struct srvsvc_NetShareInfo1005);
+ r.in.info.info1005->dfs_flags = 0;
+ break;
+ case 1006:
+ r.in.info.info1006 = talloc(mem_ctx, struct srvsvc_NetShareInfo1006);
+ r.in.info.info1006->max_users = 1006;
+ break;
+/* case 1007:
+ r.in.info.info1007 = talloc(mem_ctx, struct srvsvc_NetShareInfo1007);
+ r.in.info.info1007->flags = 0;
+ r.in.info.info1007->alternate_directory_name = talloc_strdup(mem_ctx, "test");
+ break;
+*/
+ case 1501:
+ r.in.info.info1501 = talloc_zero(mem_ctx, struct sec_desc_buf);
+ break;
+ }
+
+ status = dcerpc_srvsvc_NetShareSetInfo(p, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("NetShareGetInfo level %u on share '%s' failed - %s\n",
+ r.in.level, r.in.share_name, nt_errstr(status));
+ ret = False;
+ continue;
+ } else if (!W_ERROR_EQUAL(r.out.result, levels[i].expected)) {
+ d_printf("NetShareSetInfo level %u on share '%s' failed - %s (expected %s)\n",
+ r.in.level, r.in.share_name, win_errstr(r.out.result),
+ win_errstr(levels[i].expected));
+ ret = False;
+ continue;
+ }
+
+ q.in.share_name = r.in.share_name;
+
+ status = dcerpc_srvsvc_NetShareGetInfo(p, mem_ctx, &q);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("NetShareGetInfo level %u on share '%s' failed - %s\n",
+ q.in.level, q.in.share_name, nt_errstr(status));
+ ret = False;
+ continue;
+ } else if (!W_ERROR_EQUAL(q.out.result, WERR_OK)) {
+ d_printf("NetShareGetInfo level %u on share '%s' failed - %s\n",
+ q.in.level, q.in.share_name, win_errstr(q.out.result));
+ ret = False;
+ continue;
+ }
+
+ if (strcmp(q.out.info.info502->name, r.in.share_name) != 0) {
+ ret = False;
+ }
+ switch (levels[i].level) {
+ case 0:
+ break;
+ case 1:
+ if (strcmp(q.out.info.info502->comment, "test comment 1") != 0)
+ ret = False;
+ break;
+ case 2:
+ if (strcmp(q.out.info.info502->comment, "test comment 2") != 0)
+ ret = False;
+ if (q.out.info.info2->max_users != 2)
+ ret = False;
+ if (strcmp(q.out.info.info2->path, "C:\\") != 0)
+ ret = False;
+ break;
+ case 501:
+ if (strcmp(q.out.info.info501->comment, "test comment 501") != 0)
+ ret = False;
+ break;
+ case 502:
+ if (strcmp(q.out.info.info502->comment, "test comment 502") != 0)
+ ret = False;
+ if (q.out.info.info2->max_users != 502)
+ ret = False;
+ if (strcmp(q.out.info.info2->path, "C:\\") != 0)
+ ret = False;
+ break;
+ case 1004:
+ if (strcmp(q.out.info.info502->comment, "test comment 1004") != 0)
+ ret = False;
+ break;
+ case 1005:
+ break;
+ case 1006:
+ if (q.out.info.info2->max_users != 1006)
+ ret = False;
+ break;
+/* case 1007:
+ break;
+*/
+ case 1501:
+ break;
+ }
+ }
+
+ d.in.share_name = r.in.share_name;
+ d.in.reserved = 0;
+
+ status = dcerpc_srvsvc_NetShareDel(p, mem_ctx, &d);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("NetShareDel on share 'testshare502' failed - %s\n",
+ nt_errstr(status));
+ ret = False;
+ } else if (!W_ERROR_EQUAL(a.out.result, WERR_OK)) {
+ d_printf("NetShareDel on share 'testshare502' failed - %s\n",
+ win_errstr(d.out.result));
+ ret = False;
+ }
+
+ return ret;
+}
+
/**************************/
/* srvsvc_NetShare */
/**************************/
@@ -776,7 +1000,8 @@ static BOOL test_NetNameValidate(struct dcerpc_pipe *p,
NTSTATUS status;
struct srvsvc_NetNameValidate r;
char *invalidc;
- int i, n;
+ char *name;
+ int i, n, min, max;
r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
r.in.flags = 0x0;
@@ -787,31 +1012,44 @@ static BOOL test_NetNameValidate(struct dcerpc_pipe *p,
for (i = 1; i < 14; i++) {
again:
- /* Find maximum length accepted by this type */
- ZERO_STRUCT(r.out);
- r.in.name_type = i;
- r.in.name = talloc_strdup(mem_ctx, "A");
- n = 0;
+ /* let's limit ourselves to a maximum of 4096 bytes */
+ r.in.name = name = talloc_array(mem_ctx, char, 4097);
+ max = 4096;
+ min = 0;
+ n = max;
+
+ while (1) {
+
+ /* Find maximum length accepted by this type */
+ ZERO_STRUCT(r.out);
+ r.in.name_type = i;
+ memset(name, 'A', n);
+ name[n] = '\0';
- while (W_ERROR_IS_OK(r.out.result)) {
status = dcerpc_srvsvc_NetNameValidate(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
d_printf("NetNameValidate failed while checking maximum size (%s)\n",
nt_errstr(status));
break;
}
-
- r.in.name = talloc_append_string(mem_ctx, r.in.name, "A");
- if (!r.in.name) {
- d_printf("NetNameValidate: Out of memory!\n");
- return False;
+
+ if (W_ERROR_IS_OK(r.out.result)) {
+ min = n;
+ n += (max - min + 1)/2;
+ continue;
+
+ } else {
+ if ((min + 1) >= max) break; /* found it */
+
+ max = n;
+ n -= (max - min)/2;
+ continue;
}
- n++;
}
talloc_free(r.in.name);
- d_printf("Maximum length for type %2d, flags %08x: %d\n", i, r.in.flags, n);
+ d_printf("Maximum length for type %2d, flags %08x: %d\n", i, r.in.flags, max);
/* find invalid chars for this type check only ASCII between 0x20 and 0x7e */
@@ -877,6 +1115,7 @@ BOOL torture_rpc_srvsvc(struct torture_context *torture)
ret &= test_NetRemoteTOD(p, mem_ctx);
ret &= test_NetShareEnum(p, mem_ctx, True);
ret &= test_NetShareGetInfo(p, mem_ctx, "ADMIN$", True);
+ ret &= test_NetShareAddSetDel(p, mem_ctx);
ret &= test_NetNameValidate(p, mem_ctx);
status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_srvsvc);