The branch, master has been updated via 32915ce... Make Samba3 pass the RAW-LOCK test as Windows. via 1d3942c... Make smbtorture4 match Windows behavior. from 265e4df... s3: bug #6967: Prevent glibc error on net ads join: talloc()ed memory should not be SAFE_FREE()ed.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 32915ceefc718621e2e9b17fee97da82744ab67a Author: Jeremy Allison <j...@samba.org> Date: Fri Dec 4 14:04:08 2009 -0800 Make Samba3 pass the RAW-LOCK test as Windows. Implement the win7 NT_STATUS_INVALID_LOCK_RANGE. Make smbd behave as Windows does in canceling locks. Jeremy. commit 1d3942c534791e7767b64be383e6e035b164c506 Author: Jeremy Allison <j...@samba.org> Date: Fri Dec 4 14:02:52 2009 -0800 Make smbtorture4 match Windows behavior. Jeremy. ----------------------------------------------------------------------- Summary of changes: source3/locking/brlock.c | 5 +++ source3/smbd/reply.c | 24 ++++++++++++ source4/torture/raw/lock.c | 84 ++++++++++++++++++++------------------------ 3 files changed, 67 insertions(+), 46 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index b021293..22c6c9e 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -333,6 +333,11 @@ NTSTATUS brl_lock_windows_default(struct byte_range_lock *br_lck, SMB_ASSERT(plock->lock_type != UNLOCK_LOCK); for (i=0; i < br_lck->num_locks; i++) { + if (locks[i].start + locks[i].size < locks[i].start) { + /* 64-bit wrap. Error. */ + return NT_STATUS_INVALID_LOCK_RANGE; + } + /* Do any Windows or POSIX locks conflict ? */ if (brl_conflict(&locks[i], plock)) { /* Remember who blocked us. */ diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 030939f..185f601 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -7038,6 +7038,30 @@ NTSTATUS smbd_do_locking(struct smb_request *req, if (type & LOCKING_ANDX_CANCEL_LOCK) { struct blocking_lock_record *blr = NULL; + if (num_locks > 1) { + /* + * MS-CIFS (2.2.4.32.1) states that a cancel is honored if and only + * if the lock vector contains one entry. When given mutliple cancel + * requests in a single PDU we expect the server to return an + * error. Windows servers seem to accept the request but only + * cancel the first lock. + * JRA - Do what Windows does (tm) :-). + */ + +#if 0 + /* MS-CIFS (2.2.4.32.1) behavior. */ + return NT_STATUS_DOS(ERRDOS, + ERRcancelviolation); +#else + /* Windows behavior. */ + if (i != 0) { + DEBUG(10,("smbd_do_locking: ignoring subsequent " + "cancel request\n")); + continue; + } +#endif + } + if (lp_blocking_locks(SNUM(conn))) { /* Schedule a message to ourselves to diff --git a/source4/torture/raw/lock.c b/source4/torture/raw/lock.c index f36d492..6871ed3 100644 --- a/source4/torture/raw/lock.c +++ b/source4/torture/raw/lock.c @@ -69,19 +69,20 @@ }} while (0) #define BASEDIR "\\testlock" -#define TARGET_SUPPORTS_SMBLOCK(_tctx) \ - (torture_setting_bool(_tctx, "smblock_pdu_support", true)) -#define TARGET_SUPPORTS_OPENX_DENY_DOS(_tctx) \ - (torture_setting_bool(_tctx, "openx_deny_dos_support", true)) -#define TARGET_SUPPORTS_INVALID_LOCK_RANGE(_tctx) \ - (torture_setting_bool(_tctx, "invalid_lock_range_support", true)) #define TARGET_IS_W2K8(_tctx) (torture_setting_bool(_tctx, "w2k8", false)) #define TARGET_IS_WIN7(_tctx) (torture_setting_bool(_tctx, "win7", false)) #define TARGET_IS_WINDOWS(_tctx) ((torture_setting_bool(_tctx, "w2k8", false)) || \ - (torture_setting_bool(_tctx, "win7", false))) + (torture_setting_bool(_tctx, "win7", false)) || \ + (torture_setting_bool(_tctx, "w2k3", false))) #define TARGET_IS_SAMBA3(_tctx) (torture_setting_bool(_tctx, "samba3", false)) #define TARGET_IS_SAMBA4(_tctx) (torture_setting_bool(_tctx, "samba4", false)) +#define TARGET_SUPPORTS_INVALID_LOCK_RANGE(_tctx) \ + (torture_setting_bool(_tctx, "invalid_lock_range_support", true)) +#define TARGET_SUPPORTS_SMBLOCK(_tctx) \ + (torture_setting_bool(_tctx, "smblock_pdu_support", true)) +#define TARGET_SUPPORTS_OPENX_DENY_DOS(_tctx) \ + (torture_setting_bool(_tctx, "openx_deny_dos_support", true)) /* test SMBlock and SMBunlock ops */ @@ -576,7 +577,8 @@ static bool test_async(struct torture_context *tctx, * requests in a single PDU we expect the server to return an * error. Samba4 handles this correctly. Windows servers seem to * accept the request but only cancel the first lock. Samba3 - * cancels both locks. */ + * now does what Windows does (JRA). + */ torture_comment(tctx, "testing multiple cancel\n"); /* acquire second lock */ @@ -607,45 +609,35 @@ static bool test_async(struct torture_context *tctx, io.lockx.in.mode = LOCKING_ANDX_CANCEL_LOCK | LOCKING_ANDX_LARGE_FILES; io.lockx.in.locks = lock; status = smb_raw_lock(cli->tree, &io); - if (TARGET_IS_WINDOWS(tctx) || TARGET_IS_SAMBA3(tctx)) { - CHECK_STATUS(status, NT_STATUS_OK); + CHECK_STATUS(status, NT_STATUS_OK); - torture_warning(tctx, "Target server accepted a lock cancel " - "request with multiple locks. This violates " - "MS-CIFS 2.2.4.32.1.\n"); + torture_warning(tctx, "Target server accepted a lock cancel " + "request with multiple locks. This violates " + "MS-CIFS 2.2.4.32.1.\n"); - /* receive the failed lock requests */ - status = smbcli_request_simple_recv(req); - CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); + /* receive the failed lock requests */ + status = smbcli_request_simple_recv(req); + CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); - torture_assert(tctx,!(time(NULL) > t+2), talloc_asprintf(tctx, - "first lock was not cancelled immediately (%s)\n", - __location__)); + torture_assert(tctx,!(time(NULL) > t+2), talloc_asprintf(tctx, + "first lock was not cancelled immediately (%s)\n", + __location__)); - /* send cancel to second lock */ - io.lockx.in.timeout = 0; - io.lockx.in.lock_cnt = 1; - io.lockx.in.mode = LOCKING_ANDX_CANCEL_LOCK | - LOCKING_ANDX_LARGE_FILES; - io.lockx.in.locks = &lock[1]; - status = smb_raw_lock(cli->tree, &io); - if (TARGET_IS_SAMBA3(tctx)) { - /* Samba3 supports multiple cancels in a single PDU. */ - CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, - ERRcancelviolation)); - } else { - CHECK_STATUS(status, NT_STATUS_OK); - } + /* send cancel to second lock */ + io.lockx.in.timeout = 0; + io.lockx.in.lock_cnt = 1; + io.lockx.in.mode = LOCKING_ANDX_CANCEL_LOCK | + LOCKING_ANDX_LARGE_FILES; + io.lockx.in.locks = &lock[1]; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); - status = smbcli_request_simple_recv(req2); - CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); + status = smbcli_request_simple_recv(req2); + CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); - torture_assert(tctx,!(time(NULL) > t+2), talloc_asprintf(tctx, - "second lock was not cancelled immediately (%s)\n", - __location__)); - } else { - CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRcancelviolation)); - } + torture_assert(tctx,!(time(NULL) > t+2), talloc_asprintf(tctx, + "second lock was not cancelled immediately (%s)\n", + __location__)); /* cleanup the second lock */ io.lockx.in.ulock_cnt = 1; -- Samba Shared Repository