summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2006-09-20 20:32:36 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:19:06 -0500
commitfec00fd6f8f68bc9ebb96c4590fb8bed7d1930b5 (patch)
tree04a5ae9c016604a03e2a70d16fbfcb843aa77ea3
parent345863915ff9d07d3b9de851bf49222ec52ded4d (diff)
downloadsamba-fec00fd6f8f68bc9ebb96c4590fb8bed7d1930b5.tar.gz
samba-fec00fd6f8f68bc9ebb96c4590fb8bed7d1930b5.tar.bz2
samba-fec00fd6f8f68bc9ebb96c4590fb8bed7d1930b5.zip
r18740: Some more work around srvsvc
(This used to be commit be2f4a2c44ed2b4d586f0d6e9976158f33fb29d8)
-rw-r--r--source4/rpc_server/srvsvc/dcesrv_srvsvc.c351
-rw-r--r--source4/torture/rpc/srvsvc.c267
2 files changed, 438 insertions, 180 deletions
diff --git a/source4/rpc_server/srvsvc/dcesrv_srvsvc.c b/source4/rpc_server/srvsvc/dcesrv_srvsvc.c
index b8da68e920..983c51f137 100644
--- a/source4/rpc_server/srvsvc/dcesrv_srvsvc.c
+++ b/source4/rpc_server/srvsvc/dcesrv_srvsvc.c
@@ -1101,88 +1101,45 @@ static WERROR srvsvc_NetShareGetInfo(struct dcesrv_call_state *dce_call, TALLOC_
return WERR_UNKNOWN_LEVEL;
}
-
-/*
- srvsvc_NetShareSetInfo
-*/
-static WERROR srvsvc_NetShareSetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct srvsvc_NetShareSetInfo *r)
+static WERROR srvsvc_fill_share_info(struct share_info *info, int *count,
+ const char *share_name, int level,
+ const char *name,
+ const char *path,
+ const char *comment,
+ const char *password,
+ enum srvsvc_ShareType type,
+ int32_t max_users,
+ uint32_t csc_policy,
+ struct security_descriptor *sd)
{
- NTSTATUS nterr;
- struct share_context *sctx = NULL;
- struct share_config *scfg = NULL;
-
- ZERO_STRUCT(r->out);
+ int i = 0;
- /* TODO: - access check
- */
-
- if (strcmp("", r->in.share_name) == 0) {
- return WERR_INVALID_PARAM;
- }
-
- nterr = share_get_context(mem_ctx, &sctx);
- if (!NT_STATUS_IS_OK(nterr)) {
- return ntstatus_to_werror(nterr);
- }
-
- switch (r->in.level) {
- case 0:
- {
- return WERR_NOT_SUPPORTED;
- }
- case 1:
- {
- return WERR_NOT_SUPPORTED;
+ if (level == 501) {
+ info[i].name = SHARE_CSC_POLICY;
+ info[i].type = SHARE_INFO_INT;
+ info[i].value = talloc(info, int);
+ *((int *)info[i].value) = csc_policy;
+ i++;
}
- case 2:
- {
- struct share_info *info;
- int count = 8;
- int i;
+
+ switch(level) {
- /* there are no more than 8 options in struct srvsvc_NetShareInfo2 */
- info = talloc_array(mem_ctx, struct share_info, count);
- W_ERROR_HAVE_NO_MEMORY(info);
-
- i = 0;
-
- if (strcasecmp(r->in.share_name, r->in.info.info2->name) != 0) {
- info[i].name = SHARE_NAME;
- info[i].type = SHARE_INFO_STRING;
- info[i].value = talloc_strdup(info, r->in.info.info2->name);
- W_ERROR_HAVE_NO_MEMORY(info[i].value);
- i++;
- }
+ case 502:
+ /* TODO: check if unknown is csc_policy */
- info[i].name = SHARE_TYPE;
- info[i].type = SHARE_INFO_STRING;
- switch (r->in.info.info2->type) {
- case 0x00:
- info[i].value = talloc_strdup(info, "DISK");
- break;
- case 0x01:
- info[i].value = talloc_strdup(info, "PRINTER");
- break;
- case 0x03:
- info[i].value = talloc_strdup(info, "IPC");
- break;
- default:
- return WERR_INVALID_PARAM;
- }
- W_ERROR_HAVE_NO_MEMORY(info[i].value);
- i++;
+ /* TODO: security descriptor */
- if (r->in.info.info2->path && r->in.info.info2->path[0]) {
+ case 2:
+ if (path && path[0]) {
info[i].name = SHARE_PATH;
info[i].type = SHARE_INFO_STRING;
/* Windows will send a path in a form of C:\example\path */
- if (r->in.info.info2->path[1] == ':') {
- info[i].value = talloc_strdup(info, &r->in.info.info2->path[2]);
+ if (path[1] == ':') {
+ info[i].value = talloc_strdup(info, &path[2]);
} else {
/* very strange let's try to set as is */
- info[i].value = talloc_strdup(info, r->in.info.info2->path);
+ info[i].value = talloc_strdup(info, path);
}
W_ERROR_HAVE_NO_MEMORY(info[i].value);
all_string_sub((char *)info[i].value, "\\", "/", 0);
@@ -1190,19 +1147,10 @@ static WERROR srvsvc_NetShareSetInfo(struct dcesrv_call_state *dce_call, TALLOC_
i++;
}
- if (r->in.info.info2->comment && r->in.info.info2->comment[0]) {
- info[i].name = SHARE_COMMENT;
- info[i].type = SHARE_INFO_STRING;
- info[i].value = talloc_strdup(info, r->in.info.info2->comment);
- W_ERROR_HAVE_NO_MEMORY(info[i].value);
-
- i++;
- }
-
- if (r->in.info.info2->password && r->in.info.info2->password[0]) {
+ if (password && password[0]) {
info[i].name = SHARE_PASSWORD;
info[i].type = SHARE_INFO_STRING;
- info[i].value = talloc_strdup(info, r->in.info.info502->password);
+ info[i].value = talloc_strdup(info, password);
W_ERROR_HAVE_NO_MEMORY(info[i].value);
i++;
@@ -1211,49 +1159,14 @@ static WERROR srvsvc_NetShareSetInfo(struct dcesrv_call_state *dce_call, TALLOC_
info[i].name = SHARE_MAX_CONNECTIONS;
info[i].type = SHARE_INFO_INT;
info[i].value = talloc(info, int);
- *((int *)info[i].value) = r->in.info.info2->max_users;
+ *((int *)info[i].value) = max_users;
i++;
- /* TODO: security descriptor */
-
- nterr = share_set(sctx, r->in.share_name, info, i);
- if (!NT_STATUS_IS_OK(nterr)) {
- return ntstatus_to_werror(nterr);
- }
-
- if (r->in.parm_error) {
- r->out.parm_error = r->in.parm_error;
- }
-
- return WERR_OK;
- }
case 501:
- {
- return WERR_NOT_SUPPORTED;
- }
- case 502:
- {
- struct share_info *info;
- int count = 8;
- int i;
-
- /* there are no more than 8 options in struct srvsvc_NetShareInfo502 */
- info = talloc_array(mem_ctx, struct share_info, count);
- W_ERROR_HAVE_NO_MEMORY(info);
-
- i = 0;
-
- if (strcasecmp(r->in.share_name, r->in.info.info502->name) != 0) {
- info[i].name = SHARE_NAME;
- info[i].type = SHARE_INFO_STRING;
- info[i].value = talloc_strdup(info, r->in.info.info502->name);
- W_ERROR_HAVE_NO_MEMORY(info[i].value);
- i++;
- }
-
+ case 1:
info[i].name = SHARE_TYPE;
info[i].type = SHARE_INFO_STRING;
- switch (r->in.info.info502->type) {
+ switch (type) {
case 0x00:
info[i].value = talloc_strdup(info, "DISK");
break;
@@ -1269,74 +1182,171 @@ static WERROR srvsvc_NetShareSetInfo(struct dcesrv_call_state *dce_call, TALLOC_
W_ERROR_HAVE_NO_MEMORY(info[i].value);
i++;
- if (r->in.info.info502->path && r->in.info.info502->path[0]) {
- info[i].name = SHARE_PATH;
+ case 1004:
+ if (comment) {
+ info[i].name = SHARE_COMMENT;
info[i].type = SHARE_INFO_STRING;
-
- /* Windows will send a path in a form of C:\example\path */
- if (r->in.info.info2->path[1] == ':') {
- info[i].value = talloc_strdup(info, &r->in.info.info502->path[2]);
- } else {
- /* very strange let's try to set as is */
- info[i].value = talloc_strdup(info, r->in.info.info502->path);
- }
+ info[i].value = talloc_strdup(info, comment);
W_ERROR_HAVE_NO_MEMORY(info[i].value);
- all_string_sub((char *)info[i].value, "\\", "/", 0);
i++;
}
-
- if (r->in.info.info502->comment && r->in.info.info502->comment[0]) {
- info[i].name = SHARE_COMMENT;
+ case 0:
+ if (name &&
+ strcasecmp(share_name, name) != 0) {
+ info[i].name = SHARE_NAME;
info[i].type = SHARE_INFO_STRING;
- info[i].value = talloc_strdup(info, r->in.info.info502->comment);
+ info[i].value = talloc_strdup(info, name);
W_ERROR_HAVE_NO_MEMORY(info[i].value);
-
i++;
}
- if (r->in.info.info502->password && r->in.info.info502->password[0]) {
- info[i].name = SHARE_PASSWORD;
- info[i].type = SHARE_INFO_STRING;
- info[i].value = talloc_strdup(info, r->in.info.info502->password);
- W_ERROR_HAVE_NO_MEMORY(info[i].value);
+ break;
- i++;
- }
+ default:
+ return WERR_UNKNOWN_LEVEL;
+ }
- info[i].name = SHARE_MAX_CONNECTIONS;
- info[i].type = SHARE_INFO_INT;
- info[i].value = talloc(info, int);
- *((int *)info[i].value) = r->in.info.info502->max_users;
- i++;
+ *count = i;
- /* TODO: security descriptor */
+ return WERR_OK;
+}
- nterr = share_set(sctx, r->in.share_name, info, i);
- if (!NT_STATUS_IS_OK(nterr)) {
- return ntstatus_to_werror(nterr);
- }
+/*
+ srvsvc_NetShareSetInfo
+*/
+static WERROR srvsvc_NetShareSetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+ struct srvsvc_NetShareSetInfo *r)
+{
+ NTSTATUS nterr;
+ WERROR status;
+ struct share_context *sctx = NULL;
+ struct share_info *info;
+ int count;
- if (r->in.parm_error) {
- r->out.parm_error = r->in.parm_error;
+ /* TODO: - access check
+ */
+
+ /* there are no more than 10 options in all struct srvsvc_NetShareInfoXXX */
+ info = talloc_array(mem_ctx, struct share_info, 10);
+ W_ERROR_HAVE_NO_MEMORY(info);
+
+ ZERO_STRUCT(r->out);
+
+ if (strcmp("", r->in.share_name) == 0) {
+ return WERR_INVALID_PARAM;
+ }
+
+ nterr = share_get_context(mem_ctx, &sctx);
+ if (!NT_STATUS_IS_OK(nterr)) {
+ return ntstatus_to_werror(nterr);
+ }
+
+ switch (r->in.level) {
+ case 0:
+ {
+ status = srvsvc_fill_share_info(info, &count,
+ r->in.share_name, r->in.level,
+ r->in.info.info0->name,
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ 0,
+ 0,
+ NULL);
+ if (status != WERR_OK) {
+ return status;
}
-
- return WERR_OK;
+ break;
+ }
+ case 1:
+ {
+ status = srvsvc_fill_share_info(info, &count,
+ r->in.share_name, r->in.level,
+ r->in.info.info1->name,
+ NULL,
+ r->in.info.info1->comment,
+ NULL,
+ r->in.info.info1->type,
+ 0,
+ 0,
+ NULL);
+ if (status != WERR_OK) {
+ return status;
+ }
+ break;
+ }
+ case 2:
+ {
+ status = srvsvc_fill_share_info(info, &count,
+ r->in.share_name, r->in.level,
+ r->in.info.info2->name,
+ r->in.info.info2->path,
+ r->in.info.info2->comment,
+ r->in.info.info2->password,
+ r->in.info.info2->type,
+ r->in.info.info2->max_users,
+ 0,
+ NULL);
+ if (status != WERR_OK) {
+ return status;
+ }
+ break;
+ }
+ case 501:
+ {
+ status = srvsvc_fill_share_info(info, &count,
+ r->in.share_name, r->in.level,
+ r->in.info.info501->name,
+ NULL,
+ r->in.info.info501->comment,
+ NULL,
+ r->in.info.info501->type,
+ 0,
+ r->in.info.info501->csc_policy,
+ NULL);
+ if (status != WERR_OK) {
+ return status;
+ }
+ break;
+ }
+ case 502:
+ {
+ status = srvsvc_fill_share_info(info, &count,
+ r->in.share_name, r->in.level,
+ r->in.info.info502->name,
+ r->in.info.info502->path,
+ r->in.info.info502->comment,
+ r->in.info.info502->password,
+ r->in.info.info502->type,
+ r->in.info.info502->max_users,
+ 0,
+ r->in.info.info502->sd);
+ if (status != WERR_OK) {
+ return status;
+ }
+ break;
}
case 1004:
{
- WERROR status;
- union srvsvc_NetShareInfo info;
-
- /* r->in.info.comment; */
-
- return WERR_NOT_SUPPORTED;
+ status = srvsvc_fill_share_info(info, &count,
+ r->in.share_name, r->in.level,
+ NULL,
+ NULL,
+ r->in.info.info1004->comment,
+ NULL,
+ 0,
+ 0,
+ 0,
+ NULL);
+ if (status != WERR_OK) {
+ return status;
+ }
+ break;
}
case 1005:
{
- WERROR status;
- union srvsvc_NetShareInfo info;
-
/* r->in.info.dfs_flags; */
if (r->in.parm_error) {
@@ -1349,7 +1359,16 @@ static WERROR srvsvc_NetShareSetInfo(struct dcesrv_call_state *dce_call, TALLOC_
return WERR_UNKNOWN_LEVEL;
}
- return WERR_UNKNOWN_LEVEL;
+ nterr = share_set(sctx, r->in.share_name, info, count);
+ if (!NT_STATUS_IS_OK(nterr)) {
+ return ntstatus_to_werror(nterr);
+ }
+
+ if (r->in.parm_error) {
+ r->out.parm_error = r->in.parm_error;
+ }
+
+ return WERR_OK;
}
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);