diff options
Diffstat (limited to 'source4/torture')
-rw-r--r-- | source4/torture/rpc/srvsvc.c | 267 |
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); |