summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2012-09-28 09:39:15 -0700
committerJeremy Allison <jra@samba.org>2012-10-01 23:29:25 +0200
commit9f83968e1c201c1196fb4a9699b592bdfc718ea8 (patch)
tree9bf94c17c38d64c28bee95b0eda613794e2b0331 /source4
parentaa6a7a97803b1106d2200c889a2260f81059c450 (diff)
downloadsamba-9f83968e1c201c1196fb4a9699b592bdfc718ea8.tar.gz
samba-9f83968e1c201c1196fb4a9699b592bdfc718ea8.tar.bz2
samba-9f83968e1c201c1196fb4a9699b592bdfc718ea8.zip
Add samba3.samba3badnameblob test to check regressions in bug #9215.
Bad name in SMB1 openX can cause a crash in iconv inside glibc. Autobuild-User(master): Jeremy Allison <jra@samba.org> Autobuild-Date(master): Mon Oct 1 23:29:25 CEST 2012 on sn-devel-104
Diffstat (limited to 'source4')
-rw-r--r--source4/torture/raw/raw.c1
-rw-r--r--source4/torture/raw/samba3misc.c138
2 files changed, 139 insertions, 0 deletions
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;
+}