diff options
-rwxr-xr-x | source3/selftest/tests.py | 2 | ||||
-rw-r--r-- | source4/torture/raw/raw.c | 1 | ||||
-rw-r--r-- | source4/torture/raw/samba3misc.c | 138 |
3 files changed, 140 insertions, 1 deletions
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index b07b69086c..7168bfd327 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -281,7 +281,7 @@ raw = ["raw.acls", "raw.chkpath", "raw.close", "raw.composite", "raw.context", " "raw.samba3caseinsensitive", "raw.samba3posixtimedlock", "raw.samba3rootdirfid", "raw.sfileinfo.end-of-file", "raw.bench-oplock", "raw.bench-lock", "raw.bench-open", "raw.bench-tcon", - "raw.samba3checkfsp", "raw.samba3closeerr", "raw.samba3oplocklogoff"] + "raw.samba3checkfsp", "raw.samba3closeerr", "raw.samba3oplocklogoff", "raw.samba3badnameblob"] smb2 = smb4torture_testsuites("smb2.") diff --git a/source4/torture/raw/raw.c b/source4/torture/raw/raw.c index 9686efa80c..bda463b8a7 100644 --- a/source4/torture/raw/raw.c +++ b/source4/torture/raw/raw.c @@ -69,6 +69,7 @@ NTSTATUS torture_raw_init(void) torture_samba3_rootdirfid); torture_suite_add_1smb_test(suite, "samba3checkfsp", torture_samba3_checkfsp); torture_suite_add_1smb_test(suite, "samba3oplocklogoff", torture_samba3_oplock_logoff); + torture_suite_add_1smb_test(suite, "samba3badnameblob", torture_samba3_check_openX_badname); torture_suite_add_simple_test(suite, "samba3badpath", torture_samba3_badpath); torture_suite_add_1smb_test(suite, "samba3caseinsensitive", torture_samba3_caseinsensitive); diff --git a/source4/torture/raw/samba3misc.c b/source4/torture/raw/samba3misc.c index 200438588e..a818c6bb48 100644 --- a/source4/torture/raw/samba3misc.c +++ b/source4/torture/raw/samba3misc.c @@ -29,6 +29,126 @@ #include "param/param.h" #include "torture/raw/proto.h" +/* + The next 2 functions are stolen from source4/libcli/raw/rawfile.c + but allow us to send a raw data blob instead of an OpenX name. +*/ + +#define SETUP_REQUEST(cmd, wct, buflen) do { \ + req = smbcli_request_setup(tree, cmd, wct, buflen); \ + if (!req) return NULL; \ +} while (0) + +static struct smbcli_request *smb_raw_openX_name_blob_send(struct smbcli_tree *tree, + union smb_open *parms, + const DATA_BLOB *pname_blob) +{ + struct smbcli_request *req = NULL; + + if (parms->generic.level != RAW_OPEN_OPENX) { + return NULL; + } + + SETUP_REQUEST(SMBopenX, 15, 0); + SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); + SSVAL(req->out.vwv, VWV(1), 0); + SSVAL(req->out.vwv, VWV(2), parms->openx.in.flags); + SSVAL(req->out.vwv, VWV(3), parms->openx.in.open_mode); + SSVAL(req->out.vwv, VWV(4), parms->openx.in.search_attrs); + SSVAL(req->out.vwv, VWV(5), parms->openx.in.file_attrs); + raw_push_dos_date3(tree->session->transport, + req->out.vwv, VWV(6), parms->openx.in.write_time); + SSVAL(req->out.vwv, VWV(8), parms->openx.in.open_func); + SIVAL(req->out.vwv, VWV(9), parms->openx.in.size); + SIVAL(req->out.vwv, VWV(11),parms->openx.in.timeout); + SIVAL(req->out.vwv, VWV(13),0); /* reserved */ + smbcli_req_append_blob(req, pname_blob); + + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); + return NULL; + } + + return req; +} + +static NTSTATUS smb_raw_openX_name_blob(struct smbcli_tree *tree, + TALLOC_CTX *mem_ctx, + union smb_open *parms, + const DATA_BLOB *pname_blob) +{ + struct smbcli_request *req = smb_raw_openX_name_blob_send(tree, parms, pname_blob); + return smb_raw_open_recv(req, mem_ctx, parms); +} + +static NTSTATUS raw_smbcli_openX_name_blob(struct smbcli_tree *tree, + const DATA_BLOB *pname_blob, + int flags, + int share_mode, + int *fnum) +{ + union smb_open open_parms; + unsigned int openfn=0; + unsigned int accessmode=0; + TALLOC_CTX *mem_ctx; + NTSTATUS status; + + mem_ctx = talloc_init("raw_openX_name_blob"); + if (!mem_ctx) return NT_STATUS_NO_MEMORY; + + if (flags & O_CREAT) { + openfn |= OPENX_OPEN_FUNC_CREATE; + } + if (!(flags & O_EXCL)) { + if (flags & O_TRUNC) { + openfn |= OPENX_OPEN_FUNC_TRUNC; + } else { + openfn |= OPENX_OPEN_FUNC_OPEN; + } + } + + accessmode = (share_mode<<OPENX_MODE_DENY_SHIFT); + + if ((flags & O_ACCMODE) == O_RDWR) { + accessmode |= OPENX_MODE_ACCESS_RDWR; + } else if ((flags & O_ACCMODE) == O_WRONLY) { + accessmode |= OPENX_MODE_ACCESS_WRITE; + } else if ((flags & O_ACCMODE) == O_RDONLY) { + accessmode |= OPENX_MODE_ACCESS_READ; + } + +#if defined(O_SYNC) + if ((flags & O_SYNC) == O_SYNC) { + accessmode |= OPENX_MODE_WRITE_THRU; + } +#endif + + if (share_mode == DENY_FCB) { + accessmode = OPENX_MODE_ACCESS_FCB | OPENX_MODE_DENY_FCB; + } + + open_parms.openx.level = RAW_OPEN_OPENX; + open_parms.openx.in.flags = 0; + open_parms.openx.in.open_mode = accessmode; + open_parms.openx.in.search_attrs = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; + open_parms.openx.in.file_attrs = 0; + open_parms.openx.in.write_time = 0; + open_parms.openx.in.open_func = openfn; + open_parms.openx.in.size = 0; + open_parms.openx.in.timeout = 0; + open_parms.openx.in.fname = NULL; + + status = smb_raw_openX_name_blob(tree, mem_ctx, &open_parms, pname_blob); + talloc_free(mem_ctx); + + if (fnum && NT_STATUS_IS_OK(status)) { + *fnum = open_parms.openx.out.file.fnum; + } + + return status; +} + + #define CHECK_STATUS(torture, status, correct) do { \ if (!NT_STATUS_EQUAL(status, correct)) { \ torture_result(torture, TORTURE_FAIL, "%s: Incorrect status %s - should be %s\n", \ @@ -918,3 +1038,21 @@ bool torture_samba3_oplock_logoff(struct torture_context *tctx, struct smbcli_st done: return ret; } + +bool torture_samba3_check_openX_badname(struct torture_context *tctx, struct smbcli_state *cli) +{ + NTSTATUS status; + bool ret = false; + int fnum = -1; + DATA_BLOB name_blob = data_blob_talloc(cli->tree, NULL, 65535); + + if (name_blob.data == NULL) { + return false; + } + memset(name_blob.data, 0xcc, 65535); + status = raw_smbcli_openX_name_blob(cli->tree, &name_blob, O_RDWR, DENY_NONE, &fnum); + CHECK_STATUS(tctx, status, NT_STATUS_OBJECT_NAME_INVALID); + ret = true; + + return ret; +} |