[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