diff options
author | Andrew Bartlett <abartlet@samba.org> | 2007-05-14 05:53:26 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 14:52:23 -0500 |
commit | 8861c4a68ed23af2388103f2ca793f6833b4b58b (patch) | |
tree | 5a1b6ed2b7d74fb8f152a218503f60b4a602c5ad /source4 | |
parent | 0f6b62072e673887d354bccd7a15d4188b5c4fca (diff) | |
download | samba-8861c4a68ed23af2388103f2ca793f6833b4b58b.tar.gz samba-8861c4a68ed23af2388103f2ca793f6833b4b58b.tar.bz2 samba-8861c4a68ed23af2388103f2ca793f6833b4b58b.zip |
r22838: Add in an explority test for what QFSINFO operations are valid on IPC$
It seems most opertaions are supported, but that the values are not
consistant. I think these are very much hand-hacked stubs, which is
what they will be on Samba4 too.
I'll need to add some more 'don't fail for...' hacks before this
passes against Win2k3.
Andrew Bartlett
(This used to be commit dcb858d0c716b23be6c5d36b4aa6f155582ada63)
Diffstat (limited to 'source4')
-rw-r--r-- | source4/librpc/rpc/dcerpc_smb.c | 15 | ||||
-rw-r--r-- | source4/torture/raw/notify.c | 4 | ||||
-rw-r--r-- | source4/torture/raw/qfileinfo.c | 181 | ||||
-rw-r--r-- | source4/torture/raw/qfsinfo.c | 2 | ||||
-rw-r--r-- | source4/torture/raw/raw.c | 1 | ||||
-rw-r--r-- | source4/torture/raw/search.c | 4 | ||||
-rw-r--r-- | source4/torture/util_smb.c | 4 |
7 files changed, 148 insertions, 63 deletions
diff --git a/source4/librpc/rpc/dcerpc_smb.c b/source4/librpc/rpc/dcerpc_smb.c index 1eead06a48..7f0bcf0485 100644 --- a/source4/librpc/rpc/dcerpc_smb.c +++ b/source4/librpc/rpc/dcerpc_smb.c @@ -561,3 +561,18 @@ struct smbcli_tree *dcerpc_smb_tree(struct dcerpc_connection *c) return smb->tree; } + +/* + return the SMB fnum used for a dcerpc over SMB pipe (hack for torture operations) +*/ +uint16_t dcerpc_smb_fnum(struct dcerpc_connection *c) +{ + struct smb_private *smb; + + if (c->transport.transport != NCACN_NP) return 0; + + smb = talloc_get_type(c->transport.private, struct smb_private); + if (!smb) return 0; + + return smb->fnum; +} diff --git a/source4/torture/raw/notify.c b/source4/torture/raw/notify.c index 51e73f1115..74f33f0dbd 100644 --- a/source4/torture/raw/notify.c +++ b/source4/torture/raw/notify.c @@ -45,7 +45,7 @@ }} while (0) #define CHECK_WSTR(field, value, flags) do { \ - if (!field.s || strcmp(field.s, value) || wire_bad_flags(&field, flags, cli)) { \ + if (!field.s || strcmp(field.s, value) || wire_bad_flags(&field, flags, cli->transport)) { \ printf("(%d) %s [%s] != %s\n", __LINE__, #field, field.s, value); \ ret = False; \ goto done; \ @@ -278,7 +278,7 @@ static BOOL check_rename_reply(struct smbcli_state *cli, if ((actions[i].name.s == NULL) || (strcmp(actions[i].name.s, name) != 0) || (wire_bad_flags(&actions[i].name, STR_UNICODE, - cli))) { + cli->transport))) { printf("(%d) name [%s] != %s\n", line, actions[i].name.s, name); return False; diff --git a/source4/torture/raw/qfileinfo.c b/source4/torture/raw/qfileinfo.c index d7199972ca..fad32f6a9e 100644 --- a/source4/torture/raw/qfileinfo.c +++ b/source4/torture/raw/qfileinfo.c @@ -23,6 +23,8 @@ #include "libcli/raw/libcliraw.h" #include "libcli/libcli.h" #include "torture/util.h" +#include "librpc/rpc/dcerpc.h" +#include "torture/rpc/rpc.h" static struct { const char *name; @@ -67,6 +69,8 @@ static struct { { NULL, } }; +static bool is_ipc; + /* compare a dos time (2 second resolution) to a nt time */ @@ -100,6 +104,9 @@ static union smb_fileinfo *fnum_find(const char *name) static union smb_fileinfo *fname_find(const char *name) { int i; + if (is_ipc) { + return NULL; + } for (i=0; levels[i].name; i++) { if (NT_STATUS_IS_OK(levels[i].fname_status) && strcmp(name, levels[i].name) == 0 && @@ -153,56 +160,39 @@ static union smb_fileinfo *fname_find(const char *name) for each call we test that it succeeds, and where possible test for consistency between the calls. */ -BOOL torture_raw_qfileinfo(struct torture_context *torture) +static BOOL torture_raw_qfileinfo_internals(struct torture_context *torture, TALLOC_CTX *mem_ctx, + struct smbcli_tree *tree, int fnum, const char *fname) { - struct smbcli_state *cli; int i; BOOL ret = True; int count; union smb_fileinfo *s1, *s2; - TALLOC_CTX *mem_ctx; - int fnum; - const char *fname = "\\torture_qfileinfo.txt"; NTTIME correct_time; uint64_t correct_size; uint32_t correct_attrib; const char *correct_name; BOOL skip_streams = False; - if (!torture_open_connection(&cli, 0)) { - return False; - } - - mem_ctx = talloc_init("torture_qfileinfo"); - - fnum = create_complex_file(cli, mem_ctx, fname); - if (fnum == -1) { - printf("ERROR: open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree)); - ret = False; - goto done; - } - - /* scan all the fileinfo and pathinfo levels */ for (i=0; levels[i].name; i++) { if (!levels[i].only_paths) { levels[i].fnum_finfo.generic.level = levels[i].level; levels[i].fnum_finfo.generic.in.file.fnum = fnum; - levels[i].fnum_status = smb_raw_fileinfo(cli->tree, mem_ctx, + levels[i].fnum_status = smb_raw_fileinfo(tree, mem_ctx, &levels[i].fnum_finfo); } if (!levels[i].only_handles) { levels[i].fname_finfo.generic.level = levels[i].level; levels[i].fname_finfo.generic.in.file.path = talloc_strdup(mem_ctx, fname); - levels[i].fname_status = smb_raw_pathinfo(cli->tree, mem_ctx, + levels[i].fname_status = smb_raw_pathinfo(tree, mem_ctx, &levels[i].fname_finfo); } } /* check for completely broken levels */ for (count=i=0; levels[i].name; i++) { - uint32_t cap = cli->transport->negotiate.capabilities; + uint32_t cap = tree->session->transport->negotiate.capabilities; /* see if this server claims to support this level */ if ((cap & levels[i].capability_mask) != levels[i].capability_mask) { continue; @@ -213,7 +203,7 @@ BOOL torture_raw_qfileinfo(struct torture_context *torture) levels[i].name, nt_errstr(levels[i].fnum_status)); count++; } - if (!levels[i].only_handles && !NT_STATUS_IS_OK(levels[i].fname_status)) { + if (!(is_ipc || levels[i].only_handles) && !NT_STATUS_IS_OK(levels[i].fname_status)) { printf("ERROR: level %s failed - %s\n", levels[i].name, nt_errstr(levels[i].fname_status)); count++; @@ -232,8 +222,10 @@ BOOL torture_raw_qfileinfo(struct torture_context *torture) /* see if we can do streams */ s1 = fnum_find("STREAM_INFO"); if (!s1 || s1->stream_info.out.num_streams == 0) { - printf("STREAM_INFO broken (%d) - skipping streams checks\n", - s1 ? s1->stream_info.out.num_streams : -1); + if (!is_ipc) { + printf("STREAM_INFO broken (%d) - skipping streams checks\n", + s1 ? s1->stream_info.out.num_streams : -1); + } skip_streams = True; } @@ -511,14 +503,14 @@ BOOL torture_raw_qfileinfo(struct torture_context *torture) #define NAME_CHECK(sname, stype, tfield, flags) do { \ s1 = fnum_find(sname); \ if (s1 && (strcmp_safe(s1->stype.out.tfield.s, correct_name) != 0 || \ - wire_bad_flags(&s1->stype.out.tfield, flags, cli))) { \ + wire_bad_flags(&s1->stype.out.tfield, flags, tree->session->transport))) { \ printf("(%d) handle %s/%s incorrect - '%s/%d'\n", __LINE__, #stype, #tfield, \ s1->stype.out.tfield.s, s1->stype.out.tfield.private_length); \ ret = False; \ } \ s1 = fname_find(sname); \ if (s1 && (strcmp_safe(s1->stype.out.tfield.s, correct_name) != 0 || \ - wire_bad_flags(&s1->stype.out.tfield, flags, cli))) { \ + wire_bad_flags(&s1->stype.out.tfield, flags, tree->session->transport))) { \ printf("(%d) path %s/%s incorrect - '%s/%d'\n", __LINE__, #stype, #tfield, \ s1->stype.out.tfield.s, s1->stype.out.tfield.private_length); \ ret = False; \ @@ -546,42 +538,44 @@ BOOL torture_raw_qfileinfo(struct torture_context *torture) ret = False; } } - if (wire_bad_flags(&s1->all_info.out.fname, STR_UNICODE, cli)) { + if (wire_bad_flags(&s1->all_info.out.fname, STR_UNICODE, tree->session->transport)) { printf("Should not null terminate all_info/fname\n"); ret = False; } } s1 = fnum_find("ALT_NAME_INFO"); - correct_name = s1->alt_name_info.out.fname.s; - printf("alt_name: %s\n", correct_name); - - NAME_CHECK("ALT_NAME_INFO", alt_name_info, fname, STR_UNICODE); - NAME_CHECK("ALT_NAME_INFORMATION", alt_name_info, fname, STR_UNICODE); - - /* and make sure we can open by alternate name */ - smbcli_close(cli->tree, fnum); - fnum = smbcli_nt_create_full(cli->tree, correct_name, 0, - SEC_RIGHTS_FILE_ALL, - FILE_ATTRIBUTE_NORMAL, - NTCREATEX_SHARE_ACCESS_DELETE| - NTCREATEX_SHARE_ACCESS_READ| - NTCREATEX_SHARE_ACCESS_WRITE, - NTCREATEX_DISP_OVERWRITE_IF, - 0, 0); - if (fnum == -1) { - printf("Unable to open by alt_name - %s\n", smbcli_errstr(cli->tree)); - ret = False; - } - - if (!skip_streams) { - correct_name = "::$DATA"; - printf("stream_name: %s\n", correct_name); - - NAME_CHECK("STREAM_INFO", stream_info, streams[0].stream_name, STR_UNICODE); - NAME_CHECK("STREAM_INFORMATION", stream_info, streams[0].stream_name, STR_UNICODE); + if (s1) { + correct_name = s1->alt_name_info.out.fname.s; + printf("alt_name: %s\n", correct_name); + + NAME_CHECK("ALT_NAME_INFO", alt_name_info, fname, STR_UNICODE); + NAME_CHECK("ALT_NAME_INFORMATION", alt_name_info, fname, STR_UNICODE); + + /* and make sure we can open by alternate name */ + smbcli_close(tree, fnum); + fnum = smbcli_nt_create_full(tree, correct_name, 0, + SEC_RIGHTS_FILE_ALL, + FILE_ATTRIBUTE_NORMAL, + NTCREATEX_SHARE_ACCESS_DELETE| + NTCREATEX_SHARE_ACCESS_READ| + NTCREATEX_SHARE_ACCESS_WRITE, + NTCREATEX_DISP_OVERWRITE_IF, + 0, 0); + if (fnum == -1) { + printf("Unable to open by alt_name - %s\n", smbcli_errstr(tree)); + ret = False; + } + + if (!skip_streams) { + correct_name = "::$DATA"; + printf("stream_name: %s\n", correct_name); + + NAME_CHECK("STREAM_INFO", stream_info, streams[0].stream_name, STR_UNICODE); + NAME_CHECK("STREAM_INFORMATION", stream_info, streams[0].stream_name, STR_UNICODE); + } } - + /* make sure the EAs look right */ s1 = fnum_find("ALL_EAS"); s2 = fnum_find("ALL_INFO"); @@ -714,10 +708,85 @@ BOOL torture_raw_qfileinfo(struct torture_context *torture) done: + + return ret; +} + +/* basic testing of all RAW_FILEINFO_* calls + for each call we test that it succeeds, and where possible test + for consistency between the calls. +*/ +BOOL torture_raw_qfileinfo(struct torture_context *torture) +{ + struct smbcli_state *cli; + BOOL ret = True; + TALLOC_CTX *mem_ctx; + int fnum; + const char *fname = "\\torture_qfileinfo.txt"; + + is_ipc = 0; + + if (!torture_open_connection(&cli, 0)) { + return False; + } + + mem_ctx = talloc_init("torture_qfileinfo"); + + fnum = create_complex_file(cli, mem_ctx, fname); + if (fnum == -1) { + printf("ERROR: open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree)); + ret = False; + goto done; + } + + ret = torture_raw_qfileinfo_internals(torture, mem_ctx, cli->tree, fnum, fname); + smbcli_close(cli->tree, fnum); smbcli_unlink(cli->tree, fname); +done: torture_close_connection(cli); talloc_free(mem_ctx); return ret; } + +BOOL torture_raw_qfileinfo_pipe(struct torture_context *torture) +{ + TALLOC_CTX *mem_ctx; + BOOL ret = True; + int fnum; + const char *fname = "\\lsass"; + struct smbcli_state *cli; + struct dcerpc_pipe *p; + struct smbcli_tree *ipc_tree; + NTSTATUS status; + + is_ipc = True; + + if (!torture_open_connection(&cli, 0)) { + return False; + } + + mem_ctx = talloc_init("torture_qfileinfo_pipe"); + + if (!(p = dcerpc_pipe_init(mem_ctx, + cli->tree->session->transport->socket->event.ctx))) { + return False; + } + + status = dcerpc_pipe_open_smb(p, cli->tree, fname); + if (!NT_STATUS_IS_OK(status)) { + d_printf("dcerpc_pipe_open_smb failed: %s\n", + nt_errstr(status)); + talloc_free(p); + return False; + } + + ipc_tree = dcerpc_smb_tree(p->conn); + fnum = dcerpc_smb_fnum(p->conn); + + ret = torture_raw_qfileinfo_internals(torture, mem_ctx, ipc_tree, fnum, fname); + + talloc_free(p); + return ret; +} diff --git a/source4/torture/raw/qfsinfo.c b/source4/torture/raw/qfsinfo.c index 175a4ed15a..50a5a6609a 100644 --- a/source4/torture/raw/qfsinfo.c +++ b/source4/torture/raw/qfsinfo.c @@ -289,7 +289,7 @@ BOOL torture_raw_qfsinfo(struct torture_context *torture) #define STR_CHECK(sname, stype, field, flags) do { \ s1 = find(sname); \ if (s1) { \ - if (s1->stype.out.field.s && wire_bad_flags(&s1->stype.out.field, flags, cli)) { \ + if (s1->stype.out.field.s && wire_bad_flags(&s1->stype.out.field, flags, cli->transport)) { \ printf("(%d) incorrect string termination in %s/%s\n", \ __LINE__, #stype, #field); \ ret = False; \ diff --git a/source4/torture/raw/raw.c b/source4/torture/raw/raw.c index eb89193f47..bdf4072a62 100644 --- a/source4/torture/raw/raw.c +++ b/source4/torture/raw/raw.c @@ -34,6 +34,7 @@ NTSTATUS torture_raw_init(void) torture_suite_add_simple_test(suite, "BENCH-OPEN", torture_bench_open); torture_suite_add_simple_test(suite, "QFSINFO", torture_raw_qfsinfo); torture_suite_add_simple_test(suite, "QFILEINFO", torture_raw_qfileinfo); + torture_suite_add_simple_test(suite, "QFILEINFO-IPC", torture_raw_qfileinfo_pipe); torture_suite_add_simple_test(suite, "SFILEINFO", torture_raw_sfileinfo); torture_suite_add_simple_test(suite, "SFILEINFO-BUG", torture_raw_sfileinfo_bug); torture_suite_add_simple_test(suite, "SEARCH", torture_raw_search); diff --git a/source4/torture/raw/search.c b/source4/torture/raw/search.c index 09b7ff7dc7..1fb35e8b19 100644 --- a/source4/torture/raw/search.c +++ b/source4/torture/raw/search.c @@ -391,7 +391,7 @@ static BOOL test_one_file(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) if (s) { \ if (!s->sname1.field1.s || \ strcmp(s->sname1.field1.s, v.sname2.out.field2.s) || \ - wire_bad_flags(&s->sname1.field1, flags, cli)) { \ + wire_bad_flags(&s->sname1.field1, flags, cli->transport)) { \ printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \ __location__, \ #sname1, #field1, s->sname1.field1.s, \ @@ -405,7 +405,7 @@ static BOOL test_one_file(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) if (s) { \ if (!s->sname1.field1.s || \ strcmp(s->sname1.field1.s, fname) || \ - wire_bad_flags(&s->sname1.field1, flags, cli)) { \ + wire_bad_flags(&s->sname1.field1, flags, cli->transport)) { \ printf("(%s) %s/%s [%s] != %s\n", \ __location__, \ #sname1, #field1, s->sname1.field1.s, \ diff --git a/source4/torture/util_smb.c b/source4/torture/util_smb.c index c47741c5b9..4cadbe20fe 100644 --- a/source4/torture/util_smb.c +++ b/source4/torture/util_smb.c @@ -282,7 +282,7 @@ void *shm_setup(int size) check that a wire string matches the flags specified not 100% accurate, but close enough for testing */ -bool wire_bad_flags(struct smb_wire_string *str, int flags, struct smbcli_state *cli) +bool wire_bad_flags(struct smb_wire_string *str, int flags, struct smbcli_transport *transport) { bool server_unicode; int len; @@ -290,7 +290,7 @@ bool wire_bad_flags(struct smb_wire_string *str, int flags, struct smbcli_state len = strlen(str->s); if (flags & STR_TERMINATE) len++; - server_unicode = (cli->transport->negotiate.capabilities&CAP_UNICODE)?True:False; + server_unicode = (transport->negotiate.capabilities&CAP_UNICODE)?True:False; if (getenv("CLI_FORCE_ASCII") || !lp_unicode()) { server_unicode = False; } |