[SCM] Samba Shared Repository - branch master updated

Steven Danneman sdanneman at samba.org
Tue Jul 6 14:28:45 MDT 2010


The branch, master has been updated
       via  85504ae... s4:libcli: Modify S4 client library to check for proper CN alignment
       via  00056e7... s3:smbd: Align change notify replies on 4-byte boundary
      from  502bddf... s4:new_partition LDB module - fix an uninitalised variable warning

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 85504ae6ff72204894ea7a856f0f36b44ad77fe2
Author: Steven Danneman <steven.danneman at isilon.com>
Date:   Mon Jun 28 16:06:33 2010 -0700

    s4:libcli: Modify S4 client library to check for proper CN alignment
    
    MS-CIFS 2.2.7.4.2 states that FILE_NOTIFY_INFORMATION structures in
    change notify replies must be aligned to 4-byte boundaries.
    
    This updates s4 client to check for this restriction and also adds a
    torture test which should tickle a server into giving unaligned
    structures if it doesn't follow the spec.

commit 00056e73c1cb54f5d6c10e63b70afc2c84e5883e
Author: Chere Zhou <chere.zhou at isilon.com>
Date:   Mon Jul 5 17:18:35 2010 -0700

    s3:smbd: Align change notify replies on 4-byte boundary
    
    MS-CIFS section 2.2.7.4.2 states this is mandatory.  WinXP clients
    don't seem to care, but a Win7 client will send an immediate Close()
    to the directory handle when receiving an incorrectly aligned
    change notify response.

-----------------------------------------------------------------------

Summary of changes:
 source3/smbd/notify.c          |   10 ++++
 source4/libcli/raw/rawnotify.c |    4 +-
 source4/torture/raw/notify.c   |  100 +++++++++++++++++++++++++++++++++++++++-
 3 files changed, 112 insertions(+), 2 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
index dc13aad..e473d99 100644
--- a/source3/smbd/notify.c
+++ b/source3/smbd/notify.c
@@ -77,6 +77,7 @@ static bool notify_marshall_changes(int num_changes,
 	for (i=0; i<num_changes; i++) {
 		struct notify_change *c;
 		size_t namelen;
+		int    rem = 0;
 		uint32 u32_tmp;	/* Temp arg to prs_uint32 to avoid
 				 * signed/unsigned issues */
 
@@ -102,6 +103,11 @@ static bool notify_marshall_changes(int num_changes,
 		 */
 
 		u32_tmp = (i == num_changes-1) ? 0 : namelen + 12;
+
+		/* Align on 4-byte boundary according to MS-CIFS 2.2.7.4.2 */
+		if ((rem = u32_tmp % 4 ) != 0)
+			u32_tmp += 4 - rem;
+
 		if (!prs_uint32("offset", ps, 1, &u32_tmp)) goto fail;
 
 		u32_tmp = c->action;
@@ -117,6 +123,10 @@ static bool notify_marshall_changes(int num_changes,
 		 */
 		prs_set_offset(ps, prs_offset(ps)-2);
 
+		if (rem != 0) {
+			if (!prs_align_custom(ps, 4)) goto fail;
+		}
+
 		TALLOC_FREE(uni_name.buffer);
 
 		if (prs_offset(ps) > max_offset) {
diff --git a/source4/libcli/raw/rawnotify.c b/source4/libcli/raw/rawnotify.c
index 2155076..40256aa 100644
--- a/source4/libcli/raw/rawnotify.c
+++ b/source4/libcli/raw/rawnotify.c
@@ -71,10 +71,12 @@ _PUBLIC_ NTSTATUS smb_raw_changenotify_recv(struct smbcli_request *req,
 
 	parms->nttrans.out.changes = NULL;
 	parms->nttrans.out.num_changes = 0;
-	
+
 	/* count them */
 	for (ofs=0; nt.out.params.length - ofs > 12; ) {
 		uint32_t next = IVAL(nt.out.params.data, ofs);
+		if (next % 4 != 0)
+			return NT_STATUS_INVALID_NETWORK_RESPONSE;
 		parms->nttrans.out.num_changes++;
 		if (next == 0 ||
 		    ofs + next >= nt.out.params.length) break;
diff --git a/source4/torture/raw/notify.c b/source4/torture/raw/notify.c
index 5bf7f4a..dd3aae3 100644
--- a/source4/torture/raw/notify.c
+++ b/source4/torture/raw/notify.c
@@ -50,6 +50,14 @@
 		goto done; \
 	}} while (0)
 
+#define CHECK_WSTR2(tctx, field, value, flags) \
+do { \
+	if (!field.s || strcmp(field.s, value) || \
+	    wire_bad_flags(&field, flags, cli->transport)) { \
+		torture_result(tctx, TORTURE_FAIL, \
+		    "(%d) %s [%s] != %s\n",  __LINE__, #field, field.s, value); \
+	} \
+} while (0)
 
 /* 
    basic testing of change notify on directories
@@ -1594,7 +1602,96 @@ done:
 }
 
 
-/* 
+/*
+   testing alignment of multiple change notify infos
+*/
+static bool test_notify_alignment(struct smbcli_state *cli,
+    struct torture_context *tctx)
+{
+	NTSTATUS status;
+	union smb_notify notify;
+	union smb_open io;
+	int i, fnum, fnum2;
+	struct smbcli_request *req;
+	const char *fname = BASEDIR "\\starter";
+	const char *fnames[] = { "a",
+				 "ab",
+				 "abc",
+				 "abcd" };
+	int num_names = ARRAY_SIZE(fnames);
+	const char *fpath = NULL;
+
+	torture_comment(tctx, "TESTING CHANGE NOTIFY REPLY ALIGNMENT\n");
+
+	/* get a handle on the directory */
+	io.generic.level = RAW_OPEN_NTCREATEX;
+	io.ntcreatex.in.root_fid.fnum = 0;
+	io.ntcreatex.in.flags = 0;
+	io.ntcreatex.in.access_mask = SEC_FILE_ALL;
+	io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
+	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
+				       NTCREATEX_SHARE_ACCESS_WRITE;
+	io.ntcreatex.in.alloc_size = 0;
+	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
+	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
+	io.ntcreatex.in.security_flags = 0;
+	io.ntcreatex.in.fname = BASEDIR;
+
+	status = smb_raw_open(cli->tree, tctx, &io);
+	torture_assert_ntstatus_ok(tctx, status, "");
+	fnum = io.ntcreatex.out.file.fnum;
+
+	/* ask for a change notify, on file creation */
+	notify.nttrans.level = RAW_NOTIFY_NTTRANS;
+	notify.nttrans.in.buffer_size = 1000;
+	notify.nttrans.in.completion_filter = FILE_NOTIFY_CHANGE_FILE_NAME;
+	notify.nttrans.in.file.fnum = fnum;
+	notify.nttrans.in.recursive = false;
+
+	/* start change tracking */
+	req = smb_raw_changenotify_send(cli->tree, &notify);
+
+	fnum2 = smbcli_open(cli->tree, fname, O_CREAT|O_RDWR, DENY_NONE);
+	torture_assert(tctx, fnum2 != -1, smbcli_errstr(cli->tree));
+	smbcli_close(cli->tree, fnum2);
+
+	status = smb_raw_changenotify_recv(req, tctx, &notify);
+	torture_assert_ntstatus_ok(tctx, status, "");
+
+	/* create 4 files that will cause CHANGE_NOTIFY_INFO structures
+	 * to be returned in the same packet with all possible 4-byte padding
+	 * permutations.  As per MS-CIFS 2.2.7.4.2 these structures should be
+	 * 4-byte aligned. */
+
+	for (i = 0; i < num_names; i++) {
+		fpath = talloc_asprintf(tctx, "%s\\%s", BASEDIR, fnames[i]);
+		fnum2 = smbcli_open(cli->tree, fpath,
+		    O_CREAT|O_RDWR, DENY_NONE);
+		torture_assert(tctx, fnum2 != -1, smbcli_errstr(cli->tree));
+		smbcli_close(cli->tree, fnum2);
+		talloc_free(fpath);
+	}
+
+	/* We send a notify packet, and let smb_raw_changenotify_recv() do
+	 * the alignment checking for us. */
+	req = smb_raw_changenotify_send(cli->tree, &notify);
+	status = smb_raw_changenotify_recv(req, tctx, &notify);
+	torture_assert_ntstatus_ok(tctx, status, "");
+
+	/* Do basic checking for correctness. */
+	torture_assert(tctx, notify.nttrans.out.num_changes == num_names, "");
+	for (i = 0; i < num_names; i++) {
+		torture_assert(tctx, notify.nttrans.out.changes[i].action ==
+		    NOTIFY_ACTION_ADDED, "");
+		CHECK_WSTR2(tctx, notify.nttrans.out.changes[i].name, fnames[i],
+		    STR_UNICODE);
+	}
+
+	return true;
+}
+
+/*
    basic testing of change notify
 */
 bool torture_raw_notify(struct torture_context *torture, 
@@ -1621,6 +1718,7 @@ bool torture_raw_notify(struct torture_context *torture,
 	ret &= test_notify_tree(cli, torture);
 	ret &= test_notify_overflow(cli, torture);
 	ret &= test_notify_basedir(cli, torture);
+	ret &= test_notify_alignment(cli, torture);
 
 	smb_raw_exit(cli->session);
 	smbcli_deltree(cli->tree, BASEDIR);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list