[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Sat Sep 8 15:19:02 MDT 2012


The branch, master has been updated
       via  7a51c5e selftest/knownfail: we pass some samba3.smb2.durable-* tests now
       via  eabe4c8 s3:vfs_default: add basic support for durable handle request and reconnect
       via  1d012a6 s3: introduce a new share config option "durable handles" defaulting to "yes"
       via  ba011c1d s3:smbd: make fd_open() public
      from  f5a6b7b s3:smbd: don't set kernel flock if "kernel share modes = no"

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


- Log -----------------------------------------------------------------
commit 7a51c5e46959d2f142052a2f9799ac5a44b99345
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Aug 9 15:27:50 2012 +0200

    selftest/knownfail: we pass some samba3.smb2.durable-* tests now
    
    metze
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Sat Sep  8 23:18:39 CEST 2012 on sn-devel-104

commit eabe4c8fc4f8ba7ac75ceb9924cd5a90ff14470d
Author: Michael Adam <obnox at samba.org>
Date:   Fri Jun 8 17:54:19 2012 +0200

    s3:vfs_default: add basic support for durable handle request and reconnect
    
    We only grant durable handles for CIFS/SMB2 only access,
    that means "kernel oplocks", "kernel share modes" and "posix locking"
    need to be set to "no".
    
    For now we also don't grant durable handles if delete on close
    is active on the handle.
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    Pair-Programmed-With: Volker Lendecke <vl at samba.org>

commit 1d012a6780c543620413b24237cb7e9b97a6e3bc
Author: Michael Adam <obnox at samba.org>
Date:   Thu Sep 6 14:23:26 2012 +0200

    s3: introduce a new share config option "durable handles" defaulting to "yes"
    
    This is in order to be able to turn durable handles off and on on a per share
    basis.
    
    Note: This is only used in combination with:
    
    	kernel share modes = no
    	kernel oplocks = no
    	posix locking = no
    
    Which means CIFS/SMB2 only access.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit ba011c1de0e8dc4c6bb9e2b53fef2f0fcff43854
Author: Michael Adam <obnox at samba.org>
Date:   Mon Jun 11 13:05:37 2012 +0200

    s3:smbd: make fd_open() public

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

Summary of changes:
 lib/param/param_functions.c       |    1 +
 lib/param/param_table.c           |    9 +
 selftest/knownfail                |   14 -
 selftest/target/Samba3.pm         |    5 +
 selftest/target/Samba4.pm         |    6 +
 source3/Makefile.in               |    1 +
 source3/include/proto.h           |    1 +
 source3/librpc/idl/open_files.idl |   16 +
 source3/modules/vfs_default.c     |    9 +-
 source3/param/loadparm.c          |    1 +
 source3/selftest/tests.py         |    3 +
 source3/smbd/durable.c            |  569 +++++++++++++++++++++++++++++++++++++
 source3/smbd/open.c               |    8 +-
 source3/smbd/proto.h              |   19 ++
 source3/wscript_build             |    1 +
 15 files changed, 642 insertions(+), 21 deletions(-)
 create mode 100644 source3/smbd/durable.c


Changeset truncated at 500 lines:

diff --git a/lib/param/param_functions.c b/lib/param/param_functions.c
index 3b39e88..bf6863e 100644
--- a/lib/param/param_functions.c
+++ b/lib/param/param_functions.c
@@ -156,6 +156,7 @@ FN_LOCAL_CHAR(magicchar, magic_char)
 FN_LOCAL_STRING(cups_options, szCupsOptions)
 FN_LOCAL_PARM_BOOL(change_notify, bChangeNotify)
 FN_LOCAL_PARM_BOOL(kernel_change_notify, bKernelChangeNotify)
+FN_LOCAL_BOOL(durable_handles, bDurableHandles)
 
 FN_GLOBAL_BOOL(allow_insecure_widelinks, bAllowInsecureWidelinks)
 FN_GLOBAL_BOOL(allow_trusted_domains, bAllowTrustedDomains)
diff --git a/lib/param/param_table.c b/lib/param/param_table.c
index 23489ae..060608a 100644
--- a/lib/param/param_table.c
+++ b/lib/param/param_table.c
@@ -1763,6 +1763,15 @@ static struct parm_struct parm_table[] = {
 		.special	= NULL,
 		.enum_list	= NULL
 	},
+	{
+		.label		= "durable handles",
+		.type		= P_BOOL,
+		.p_class	= P_LOCAL,
+		.offset		= LOCAL_VAR(bDurableHandles),
+		.special	= NULL,
+		.enum_list	= NULL,
+		.flags		= FLAG_ADVANCED,
+	},
 
 	{N_("Tuning Options"), P_SEP, P_SEPARATOR},
 
diff --git a/selftest/knownfail b/selftest/knownfail
index b81dbfb..094b2a4 100644
--- a/selftest/knownfail
+++ b/selftest/knownfail
@@ -175,24 +175,10 @@
 ^samba3.smb2.notify.valid-req
 ^samba3.smb2.notify.dir
 ^samba3.smb2.notify.rec
-^samba3.smb2.durable-open.file-position
-^samba3.smb2.durable-open.alloc-size
-^samba3.smb2.durable-open.lease
-^samba3.smb2.durable-open.lock-oplock
 ^samba3.smb2.durable-open.lock-lease
-^samba3.smb2.durable-open.open
-^samba3.smb2.durable-open.reopen1
-^samba3.smb2.durable-open.reopen2
-^samba3.smb2.durable-open.reopen2a
-^samba3.smb2.durable-open.reopen3
 ^samba3.smb2.durable-open.reopen4
 ^samba3.smb2.durable-open.delete_on_close1
-^samba3.smb2.durable-open.oplock
-^samba3.smb2.durable-v2-open.open-oplock
 ^samba3.smb2.durable-v2-open.open-lease
-^samba3.smb2.durable-v2-open.reopen1
-^samba3.smb2.durable-v2-open.reopen2
-^samba3.smb2.durable-v2-open.persistent-open-oplock
 ^samba3.smb2.durable-v2-open.persistent-open-lease
 ^samba3.smb2.ioctl.shadow_copy
 ^samba3.smb2.ioctl.req_resume_key
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index 943e922..c1f8fbd 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -981,6 +981,11 @@ sub provision($$$$$$)
 [hideunwrite]
 	copy = tmp
 	hide unwriteable files = yes
+[durable]
+	copy = tmp
+	kernel share modes = no
+	kernel oplocks = no
+	posix locking = no
 [print1]
 	copy = tmp
 	printable = yes
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index d2e890e..9563da6 100644
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -1419,6 +1419,12 @@ sub provision_plugin_s4_dc($$)
 	copy = tmp
 	hide unreadable = yes
 
+[durable]
+	copy = tmp
+	kernel share modes = no
+	kernel oplocks = no
+	posix locking = no
+
 [print\$]
 	copy = tmp
 
diff --git a/source3/Makefile.in b/source3/Makefile.in
index b448c02..2ad8ecc 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -984,6 +984,7 @@ SMBD_OBJ_SRV = smbd/server_reload.o \
 	       smbd/smbXsrv_session.o \
 	       smbd/smbXsrv_tcon.o \
 	       smbd/smbXsrv_open.o \
+	       smbd/durable.o \
 	       $(MANGLE_OBJ) @VFS_STATIC@
 
 SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 44b9d71..6dbdf4e 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1327,6 +1327,7 @@ bool lp_afs_share(int );
 bool lp_acl_check_permissions(int );
 bool lp_acl_group_control(int );
 bool lp_acl_map_full_control(int );
+bool lp_durable_handles(int);
 int lp_create_mask(int );
 int lp_force_create_mode(int );
 int lp_security_mask(int );
diff --git a/source3/librpc/idl/open_files.idl b/source3/librpc/idl/open_files.idl
index 98e1c32..eb0dfa0 100644
--- a/source3/librpc/idl/open_files.idl
+++ b/source3/librpc/idl/open_files.idl
@@ -46,4 +46,20 @@ interface open_files
 		uint8 modified;
 		[ignore] db_record *record;
 	} share_mode_data;
+
+	/* these are 0x30 (48) characters */
+	const string VFS_DEFAULT_DURABLE_COOKIE_MAGIC =
+		"VFS_DEFAULT_DURABLE_COOKIE_MAGIC                ";
+	const uint32 VFS_DEFAULT_DURABLE_COOKIE_VERSION = 0;
+
+	typedef [public] struct {
+		[value(VFS_DEFAULT_DURABLE_COOKIE_MAGIC),charset(DOS)] uint8 magic[0x30];
+		[value(VFS_DEFAULT_DURABLE_COOKIE_VERSION)] uint32 version;
+		boolean8 allow_reconnect;
+		file_id id;
+		[string,charset(UTF8)] char *servicepath;
+		[string,charset(UTF8)] char *base_name;
+		hyper initial_allocation_size;
+		hyper position_information;
+	} vfs_default_durable_cookie;
 }
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 427e3af..8392feb 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -2232,7 +2232,7 @@ static NTSTATUS vfswrap_durable_cookie(struct vfs_handle_struct *handle,
 				       TALLOC_CTX *mem_ctx,
 				       DATA_BLOB *cookie)
 {
-	return NT_STATUS_NOT_SUPPORTED;
+	return vfs_default_durable_cookie(fsp, mem_ctx, cookie);
 }
 
 static NTSTATUS vfswrap_durable_disconnect(struct vfs_handle_struct *handle,
@@ -2241,7 +2241,8 @@ static NTSTATUS vfswrap_durable_disconnect(struct vfs_handle_struct *handle,
 					   TALLOC_CTX *mem_ctx,
 					   DATA_BLOB *new_cookie)
 {
-	return NT_STATUS_NOT_SUPPORTED;
+	return vfs_default_durable_disconnect(fsp, old_cookie, mem_ctx,
+					      new_cookie);
 }
 
 static NTSTATUS vfswrap_durable_reconnect(struct vfs_handle_struct *handle,
@@ -2252,7 +2253,9 @@ static NTSTATUS vfswrap_durable_reconnect(struct vfs_handle_struct *handle,
 					  struct files_struct **fsp,
 					  DATA_BLOB *new_cookie)
 {
-	return NT_STATUS_NOT_SUPPORTED;
+	return vfs_default_durable_reconnect(handle->conn, smb1req, op,
+					     old_cookie, mem_ctx,
+					     fsp, new_cookie);
 }
 
 static struct vfs_fn_pointers vfs_default_fns = {
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 563d644..f1999ad 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -282,6 +282,7 @@ static struct loadparm_service sDefault =
 #endif
 	.ismb_encrypt = SMB_SIGNING_DEFAULT,
 	.bKernelShareModes = true,
+	.bDurableHandles = true,
 	.param_opt = NULL,
 	.dummy = ""
 };
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index f6b8c01..f887f7f 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -355,6 +355,9 @@ for t in tests:
         plansmbtorturetestsuite(t, "s3dc", 'ncacn_ip_tcp:$SERVER_IP -U$USERNAME%$PASSWORD', 'over ncacn_ip_tcp ')
         plansmbtorturetestsuite(t, "plugin_s4_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD', 'over ncacn_np ')
         plansmbtorturetestsuite(t, "plugin_s4_dc", 'ncacn_ip_tcp:$SERVER_IP -U$USERNAME%$PASSWORD', 'over ncacn_ip_tcp ')
+    elif t == "smb2.durable-open" or t == "smb2.durable-v2-open":
+        plansmbtorturetestsuite(t, "s3dc", '//$SERVER_IP/durable -U$USERNAME%$PASSWORD')
+        plansmbtorturetestsuite(t, "plugin_s4_dc", '//$SERVER_IP/durable -U$USERNAME%$PASSWORD')
     else:
         plansmbtorturetestsuite(t, "s3dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD')
         plansmbtorturetestsuite(t, "plugin_s4_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD')
diff --git a/source3/smbd/durable.c b/source3/smbd/durable.c
new file mode 100644
index 0000000..5953e1b
--- /dev/null
+++ b/source3/smbd/durable.c
@@ -0,0 +1,569 @@
+/*
+   Unix SMB/CIFS implementation.
+   Durable Handle default VFS implementation
+
+   Copyright (C) Stefan Metzmacher 2012
+   Copyright (C) Michael Adam 2012
+   Copyright (C) Volker Lendecke 2012
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "system/filesys.h"
+#include "smbd/smbd.h"
+#include "smbd/globals.h"
+#include "libcli/security/security.h"
+#include "messages.h"
+#include "librpc/gen_ndr/ndr_open_files.h"
+#include "serverid.h"
+#include "fake_file.h"
+
+NTSTATUS vfs_default_durable_cookie(struct files_struct *fsp,
+				    TALLOC_CTX *mem_ctx,
+				    DATA_BLOB *cookie_blob)
+{
+	struct connection_struct *conn = fsp->conn;
+	enum ndr_err_code ndr_err;
+	struct vfs_default_durable_cookie cookie;
+
+	if (!lp_durable_handles(SNUM(conn))) {
+		return NT_STATUS_NOT_SUPPORTED;
+	}
+
+	if (lp_kernel_share_modes(SNUM(conn))) {
+		/*
+		 * We do not support durable handles
+		 * if kernel share modes (flocks) are used
+		 */
+		return NT_STATUS_NOT_SUPPORTED;
+	}
+
+	if (lp_kernel_oplocks(SNUM(conn))) {
+		/*
+		 * We do not support durable handles
+		 * if kernel oplocks are used
+		 */
+		return NT_STATUS_NOT_SUPPORTED;
+	}
+
+	if ((fsp->current_lock_count > 0) &&
+	    lp_posix_locking(fsp->conn->params))
+	{
+		/*
+		 * We do not support durable handles
+		 * if the handle has posix locks.
+		 */
+		return NT_STATUS_NOT_SUPPORTED;
+	}
+
+	if (fsp->is_directory) {
+		return NT_STATUS_NOT_SUPPORTED;
+	}
+
+	if (fsp->fh->fd == -1) {
+		return NT_STATUS_NOT_SUPPORTED;
+	}
+
+	if (is_ntfs_stream_smb_fname(fsp->fsp_name)) {
+		/*
+		 * We do not support durable handles
+		 * on streams for now.
+		 */
+		return NT_STATUS_NOT_SUPPORTED;
+	}
+
+	if (is_fake_file(fsp->fsp_name)) {
+		/*
+		 * We do not support durable handles
+		 * on fake files.
+		 */
+		return NT_STATUS_NOT_SUPPORTED;
+	}
+
+	ZERO_STRUCT(cookie);
+	cookie.allow_reconnect = false;
+	cookie.id = fsp->file_id;
+	cookie.servicepath = conn->connectpath;
+	cookie.base_name = fsp->fsp_name->base_name;
+	cookie.initial_allocation_size = fsp->initial_allocation_size;
+	cookie.position_information = fsp->fh->position_information;
+
+	ndr_err = ndr_push_struct_blob(cookie_blob, mem_ctx, &cookie,
+			(ndr_push_flags_fn_t)ndr_push_vfs_default_durable_cookie);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+		return status;
+	}
+
+	return NT_STATUS_OK;
+}
+
+NTSTATUS vfs_default_durable_disconnect(struct files_struct *fsp,
+					const DATA_BLOB old_cookie,
+					TALLOC_CTX *mem_ctx,
+					DATA_BLOB *new_cookie)
+{
+	struct connection_struct *conn = fsp->conn;
+	NTSTATUS status;
+	enum ndr_err_code ndr_err;
+	struct vfs_default_durable_cookie cookie;
+	DATA_BLOB new_cookie_blob = data_blob_null;
+	struct share_mode_lock *lck;
+	bool ok;
+
+	*new_cookie = data_blob_null;
+
+	ZERO_STRUCT(cookie);
+
+	ndr_err = ndr_pull_struct_blob(&old_cookie, talloc_tos(), &cookie,
+			(ndr_pull_flags_fn_t)ndr_pull_vfs_default_durable_cookie);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		status = ndr_map_error2ntstatus(ndr_err);
+		return status;
+	}
+
+	if (strcmp(cookie.magic, VFS_DEFAULT_DURABLE_COOKIE_MAGIC) != 0) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	if (cookie.version != VFS_DEFAULT_DURABLE_COOKIE_VERSION) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	if (!file_id_equal(&fsp->file_id, &cookie.id)) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	if (!BATCH_OPLOCK_TYPE(fsp->oplock_type)) {
+		return NT_STATUS_NOT_SUPPORTED;
+	}
+
+	if (fsp->num_pending_break_messages > 0) {
+		return NT_STATUS_NOT_SUPPORTED;
+	}
+
+	/*
+	 * For now let it be simple and do not keep
+	 * delete on close files durable open
+	 */
+	if (fsp->initial_delete_on_close) {
+		return NT_STATUS_NOT_SUPPORTED;
+	}
+	if (fsp->delete_on_close) {
+		return NT_STATUS_NOT_SUPPORTED;
+	}
+
+	if (!VALID_STAT(fsp->fsp_name->st)) {
+		return NT_STATUS_NOT_SUPPORTED;
+	}
+
+	if (!S_ISREG(fsp->fsp_name->st.st_ex_mode)) {
+		return NT_STATUS_NOT_SUPPORTED;
+	}
+
+	/*
+	 * The above checks are done in mark_share_mode_disconnected() too
+	 * but we want to avoid getting the lock if possible
+	 */
+	lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
+	if (lck != NULL) {
+		ok = mark_share_mode_disconnected(lck, fsp);
+		if (!ok) {
+			TALLOC_FREE(lck);
+		}
+	}
+	if (lck != NULL) {
+		ok = brl_mark_disconnected(fsp);
+		if (!ok) {
+			TALLOC_FREE(lck);
+		}
+	}
+	if (lck == NULL) {
+		return NT_STATUS_NOT_SUPPORTED;
+	}
+	TALLOC_FREE(lck);
+
+	ZERO_STRUCT(cookie);
+	cookie.allow_reconnect = true;
+	cookie.id = fsp->file_id;
+	cookie.servicepath = conn->connectpath;
+	cookie.base_name = fsp->fsp_name->base_name;
+	cookie.initial_allocation_size = fsp->initial_allocation_size;
+	cookie.position_information = fsp->fh->position_information;
+
+	ndr_err = ndr_push_struct_blob(&new_cookie_blob, mem_ctx, &cookie,
+			(ndr_push_flags_fn_t)ndr_push_vfs_default_durable_cookie);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		status = ndr_map_error2ntstatus(ndr_err);
+		return status;
+	}
+
+	status = fd_close(fsp);
+	if (!NT_STATUS_IS_OK(status)) {
+		data_blob_free(&new_cookie_blob);
+		return status;
+	}
+
+	*new_cookie = new_cookie_blob;
+	return NT_STATUS_OK;
+}
+
+NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
+				       struct smb_request *smb1req,
+				       struct smbXsrv_open *op,
+				       const DATA_BLOB old_cookie,
+				       TALLOC_CTX *mem_ctx,
+				       files_struct **result,
+				       DATA_BLOB *new_cookie)
+{
+	struct share_mode_lock *lck;
+	struct share_mode_entry *e;
+	struct files_struct *fsp = NULL;
+	NTSTATUS status;
+	bool ok;
+	int ret;
+	int flags;
+	struct file_id file_id;
+	struct smb_filename *smb_fname = NULL;
+	enum ndr_err_code ndr_err;
+	struct vfs_default_durable_cookie cookie;
+	DATA_BLOB new_cookie_blob = data_blob_null;
+
+	*result = NULL;
+	*new_cookie = data_blob_null;
+
+	if (!lp_durable_handles(SNUM(conn))) {
+		return NT_STATUS_NOT_SUPPORTED;
+	}
+
+	/*
+	 * the checks for kernel oplocks
+	 * and similar things are done
+	 * in the vfs_default_durable_cookie()
+	 * call below.
+	 */
+
+	ZERO_STRUCT(cookie);
+
+	ndr_err = ndr_pull_struct_blob(&old_cookie, talloc_tos(), &cookie,
+			(ndr_pull_flags_fn_t)ndr_pull_vfs_default_durable_cookie);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		status = ndr_map_error2ntstatus(ndr_err);
+		return status;
+	}
+
+	if (strcmp(cookie.magic, VFS_DEFAULT_DURABLE_COOKIE_MAGIC) != 0) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	if (cookie.version != VFS_DEFAULT_DURABLE_COOKIE_VERSION) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	if (!cookie.allow_reconnect) {
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	}
+
+	if (strcmp(cookie.servicepath, conn->connectpath) != 0) {
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	}
+
+	/* Create an smb_filename with stream_name == NULL. */
+	status = create_synthetic_smb_fname(talloc_tos(),
+					    cookie.base_name,
+					    NULL, NULL,
+					    &smb_fname);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+


-- 
Samba Shared Repository


More information about the samba-cvs mailing list