[SCM] Samba Shared Repository - branch master updated
Stefan Metzmacher
metze at samba.org
Fri Sep 7 21:15:03 MDT 2012
The branch, master has been updated
via 3fef8e2 selftest/Samba3: don't explicitly set 'server max protocol'
via 196b7f3 docs-xml: change "server max protocol" to "SMB3"
via 1c9c5c1 s3:param: change "server max protocol" to "SMB3"
via 9576638 s3:smbd: add basic support for durable handle v2 request and reconnect
via 267b976 s3:smbd: add basic support for durable handle request and reconnect
via f935ebd s3:smbd: initial durable handle support: special treatment of durable handles in close
via 35260ae s3:vfs: add durable VFS operations
via eb1a05f s3:smbd: add disconnected checks to the open code.
via 42afa59 s3:smbd: also close durable file handles in a tdis
via f0a5b79 s3:locking: add brl_mark_disconnected() and brl_reconnect_disconnected()
via 9a81f8e s3:locking: add mark_share_mode_disconnected()
via bc29605 s3:smbXsrv_open: add smb2srv_open_recreate() to support durable handles
via 5e63494 s3:smbXsrv.idl: add properties for durable handles to smbXsrv_open_global0
from c853b68 s3:quota: don't add the string '"' into the argument list
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 3fef8e207c92c7ef9274669cb4cb8b29c2164558
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri May 18 10:43:18 2012 +0200
selftest/Samba3: don't explicitly set 'server max protocol'
metze
Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
Autobuild-Date(master): Sat Sep 8 05:15:00 CEST 2012 on sn-devel-104
commit 196b7f336e93048c2b55c20a2cdd7c903633d174
Author: Stefan Metzmacher <metze at samba.org>
Date: Sun Jun 3 23:09:33 2012 +0200
docs-xml: change "server max protocol" to "SMB3"
metze
commit 1c9c5c12761c2a18e7584fce3f40346321c021f6
Author: Stefan Metzmacher <metze at samba.org>
Date: Sun Jun 3 23:04:44 2012 +0200
s3:param: change "server max protocol" to "SMB3"
metze
commit 9576638dbacd24183b8715febf50d8be86aa950a
Author: Michael Adam <obnox at samba.org>
Date: Fri Jun 15 13:37:26 2012 +0200
s3:smbd: add basic support for durable handle v2 request and reconnect
This does not yet cover persistent handle support which is also
negotiated through these create request blobs.
Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
commit 267b976d432f3c21cf1d8352183cd4b308fe726d
Author: Michael Adam <obnox at samba.org>
Date: Fri Jun 8 17:54:19 2012 +0200
s3:smbd: add basic support for durable handle request and reconnect
Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
Pair-Programmed-With: Volker Lendecke <vl at samba.org>
commit f935ebdf7a2fd084930b33ba8d208d699b37300c
Author: Michael Adam <obnox at samba.org>
Date: Fri Aug 3 16:47:57 2012 +0200
s3:smbd: initial durable handle support: special treatment of durable handles in close
Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
commit 35260ae89e2970712e2a141cd034b513076fc1ed
Author: Michael Adam <obnox at samba.org>
Date: Tue Sep 4 18:04:11 2012 +0200
s3:vfs: add durable VFS operations
This allows a VFS module to implement durable handles in different ways.
Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
commit eb1a05f783721247e9e01f4039f36c3d69b2dca7
Author: Stefan Metzmacher <metze at samba.org>
Date: Sat Aug 4 15:30:11 2012 +0200
s3:smbd: add disconnected checks to the open code.
(delay_for_batch_oplocks, open_mode_check, and delay_for_exclusive_oplocks)
Pair-Programmed-With: Michael Adam <obnox at samba.org>
commit 42afa596d5e58875944c5429fac4866a5614ebca
Author: Michael Adam <obnox at samba.org>
Date: Fri Aug 3 16:38:38 2012 +0200
s3:smbd: also close durable file handles in a tdis
Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
commit f0a5b791ae4e64e42270edad7a961aa046efbaac
Author: Stefan Metzmacher <metze at samba.org>
Date: Sat Jun 30 21:48:43 2012 +0200
s3:locking: add brl_mark_disconnected() and brl_reconnect_disconnected()
Pair-Programmed-With: Michael Adam <obnox at samba.org>
commit 9a81f8ee1713317262f3fc773dae38cb51816149
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Aug 3 16:31:32 2012 +0200
s3:locking: add mark_share_mode_disconnected()
Pair-Programmed-With: Michael Adam <obnox at samba.org>
commit bc296053cba15869d3417f6089bd2e7e96d42c09
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Jun 18 12:46:15 2012 +0200
s3:smbXsrv_open: add smb2srv_open_recreate() to support durable handles
metze
commit 5e63494508ade5da00ad5ab9db139efe03d39c2e
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Jun 29 09:34:56 2012 +0200
s3:smbXsrv.idl: add properties for durable handles to smbXsrv_open_global0
Pair-Programmed-With: Michael Adam <obnox at samba.org>
metze
-----------------------------------------------------------------------
Summary of changes:
docs-xml/smbdotconf/protocol/servermaxprotocol.xml | 2 +-
selftest/target/Samba3.pm | 1 -
source3/include/vfs.h | 35 ++
source3/include/vfs_macros.h | 25 ++
source3/librpc/idl/smbXsrv.idl | 8 +
source3/locking/brlock.c | 125 +++++++
source3/locking/locking.c | 38 ++
source3/locking/proto.h | 4 +
source3/modules/vfs_default.c | 35 ++-
source3/param/loadparm.c | 2 +-
source3/smbd/close.c | 44 +++
source3/smbd/files.c | 11 +-
source3/smbd/globals.h | 6 +
source3/smbd/open.c | 31 ++
source3/smbd/smb2_create.c | 376 +++++++++++++++++---
source3/smbd/smbXsrv_open.c | 205 +++++++++++-
source3/smbd/vfs.c | 34 ++
17 files changed, 929 insertions(+), 53 deletions(-)
Changeset truncated at 500 lines:
diff --git a/docs-xml/smbdotconf/protocol/servermaxprotocol.xml b/docs-xml/smbdotconf/protocol/servermaxprotocol.xml
index 68f2579..57e82d1 100644
--- a/docs-xml/smbdotconf/protocol/servermaxprotocol.xml
+++ b/docs-xml/smbdotconf/protocol/servermaxprotocol.xml
@@ -73,6 +73,6 @@
<related>server min protocol</related>
<synonym>max protocol</synonym>
-<value type="default">SMB2</value>
+<value type="default">SMB3</value>
<value type="example">LANMAN1</value>
</samba:parameter>
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index cb11827..943e922 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -901,7 +901,6 @@ sub provision($$$$$$)
# min receivefile size = 4000
- server max protocol = SMB3
read only = no
server signing = auto
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 45895e7..3e4eefe 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -142,6 +142,7 @@
/* Leave at 29 - not yet released. move to plain off_t - abartlet */
/* Leave at 29 - not yet released. Remove sys_acl functions other than set and get - abartlet */
/* Leave at 29 - not yet released. Added backup_intent bool to files_struct - JRA */
+/* Leave at 29 - not yet released. Add durable handle functions - metze/obnox */
#define SMB_VFS_INTERFACE_VERSION 29
/*
@@ -712,6 +713,24 @@ struct vfs_fn_pointers {
SMB_STRUCT_STAT *sbuf);
int (*set_offline_fn)(struct vfs_handle_struct *handle,
const struct smb_filename *fname);
+
+ /* durable handle operations */
+ NTSTATUS (*durable_cookie_fn)(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ TALLOC_CTX *mem_ctx,
+ DATA_BLOB *cookie);
+ NTSTATUS (*durable_disconnect_fn)(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ const DATA_BLOB old_cookie,
+ TALLOC_CTX *mem_ctx,
+ DATA_BLOB *new_cookie);
+ NTSTATUS (*durable_reconnect_fn)(struct vfs_handle_struct *handle,
+ struct smb_request *smb1req,
+ struct smbXsrv_open *op,
+ const DATA_BLOB old_cookie,
+ TALLOC_CTX *mem_ctx,
+ struct files_struct **fsp,
+ DATA_BLOB *new_cookie);
};
/*
@@ -1108,6 +1127,22 @@ bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
SMB_STRUCT_STAT *sbuf);
int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
const struct smb_filename *fname);
+NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ TALLOC_CTX *mem_ctx,
+ DATA_BLOB *cookie);
+NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ const DATA_BLOB old_cookie,
+ TALLOC_CTX *mem_ctx,
+ DATA_BLOB *new_cookie);
+NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
+ struct smb_request *smb1req,
+ struct smbXsrv_open *op,
+ const DATA_BLOB old_cookie,
+ TALLOC_CTX *mem_ctx,
+ struct files_struct **fsp,
+ DATA_BLOB *new_cookie);
NTSTATUS smb_register_vfs(int version, const char *name,
const struct vfs_fn_pointers *fns);
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index e577e99..f077a6f 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -509,4 +509,29 @@
#define SMB_VFS_NEXT_SET_OFFLINE(handle,fname) \
smb_vfs_call_set_offline((handle)->next, (fname))
+/* durable handle operations */
+
+#define SMB_VFS_DURABLE_COOKIE(fsp, mem_ctx, cookie) \
+ smb_vfs_call_durable_cookie((fsp)->conn->vfs_handles, \
+ (fsp), (mem_ctx), (cookie))
+#define SMB_VFS_NEXT_DURABLE_COOKIE(handle, fsp, mem_ctx, cookie) \
+ smb_vfs_call_durable_cookie(((handle)->next, \
+ (fsp), (mem_ctx), (cookie))
+
+#define SMB_VFS_DURABLE_DISCONNECT(fsp, old_cookie, mem_ctx, new_cookie) \
+ smb_vfs_call_durable_disconnect((fsp)->conn->vfs_handles, \
+ (fsp), (old_cookie), (mem_ctx), (new_cookie))
+#define SMB_VFS_NEXT_DURABLE_DISCONNECT(handle, fsp, old_cookie, mem_ctx, new_cookie) \
+ smb_vfs_call_durable_disconnect((handle)->next, \
+ (fsp), (old_cookie), (mem_ctx), (new_cookie))
+
+#define SMB_VFS_DURABLE_RECONNECT(conn, smb1req, op, old_cookie, mem_ctx, fsp, new_cookie) \
+ smb_vfs_call_durable_reconnect((conn)->vfs_handles, \
+ (smb1req), (op), (old_cookie), \
+ (mem_ctx), (fsp), (new_cookie))
+#define SMB_VFS_NEXT_DURABLE_RECONNECT(handle, smb1req, op, old_cookie, mem_ctx, fsp, new_cookie) \
+ smb_vfs_call_durable_reconnect((handle)->next, \
+ (smb1req), (op), (old_cookie), \
+ (mem_ctx), (fsp), (new_cookie))
+
#endif /* _VFS_MACROS_H */
diff --git a/source3/librpc/idl/smbXsrv.idl b/source3/librpc/idl/smbXsrv.idl
index 90572e5..2a6d7b3 100644
--- a/source3/librpc/idl/smbXsrv.idl
+++ b/source3/librpc/idl/smbXsrv.idl
@@ -1,5 +1,6 @@
#include "idl_types.h"
+import "misc.idl";
import "server_id.idl";
import "security.idl";
import "auth.idl";
@@ -267,12 +268,19 @@ interface smbXsrv
hyper open_volatile_id;
dom_sid open_owner;
NTTIME open_time;
+ GUID create_guid;
+ GUID client_guid;
+ GUID app_instance_id;
/*
* TODO: for durable/resilient/persistent handles we need more
* things here. See [MS-SMB2] 3.3.1.10 Per Open
*
* NOTE: this is still version 0, which is not a stable format!
*/
+ NTTIME disconnect_time;
+ uint32 durable_timeout_msec;
+ boolean8 durable;
+ DATA_BLOB backend_cookie;
} smbXsrv_open_global0;
typedef union {
diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c
index c03e451..b7abaa9 100644
--- a/source3/locking/brlock.c
+++ b/source3/locking/brlock.c
@@ -1522,6 +1522,131 @@ void brl_close_fnum(struct messaging_context *msg_ctx,
}
}
+bool brl_mark_disconnected(struct files_struct *fsp)
+{
+ uint32_t tid = fsp->conn->cnum;
+ uint64_t smblctx = fsp->op->global->open_persistent_id;
+ uint64_t fnum = fsp->fnum;
+ unsigned int i;
+ struct server_id self = messaging_server_id(fsp->conn->sconn->msg_ctx);
+ struct byte_range_lock *br_lck = NULL;
+
+ if (!fsp->op->global->durable) {
+ return false;
+ }
+
+ if (fsp->current_lock_count == 0) {
+ return true;
+ }
+
+ br_lck = brl_get_locks(talloc_tos(), fsp);
+ if (br_lck == NULL) {
+ return false;
+ }
+
+ for (i=0; i < br_lck->num_locks; i++) {
+ struct lock_struct *lock = &br_lck->lock_data[i];
+
+ /*
+ * as this is a durable handle, we only expect locks
+ * of the current file handle!
+ */
+
+ if (lock->context.smblctx != smblctx) {
+ TALLOC_FREE(br_lck);
+ return false;
+ }
+
+ if (lock->context.tid != tid) {
+ TALLOC_FREE(br_lck);
+ return false;
+ }
+
+ if (!serverid_equal(&lock->context.pid, &self)) {
+ TALLOC_FREE(br_lck);
+ return false;
+ }
+
+ if (lock->fnum != fnum) {
+ TALLOC_FREE(br_lck);
+ return false;
+ }
+
+ server_id_set_disconnected(&lock->context.pid);
+ lock->context.tid = TID_FIELD_INVALID;
+ lock->fnum = FNUM_FIELD_INVALID;
+ }
+
+ br_lck->modified = true;
+ TALLOC_FREE(br_lck);
+ return true;
+}
+
+bool brl_reconnect_disconnected(struct files_struct *fsp)
+{
+ uint32_t tid = fsp->conn->cnum;
+ uint64_t smblctx = fsp->op->global->open_persistent_id;
+ uint64_t fnum = fsp->fnum;
+ unsigned int i;
+ struct server_id self = messaging_server_id(fsp->conn->sconn->msg_ctx);
+ struct byte_range_lock *br_lck = NULL;
+
+ if (!fsp->op->global->durable) {
+ return false;
+ }
+
+ /* we want to validate ourself */
+ fsp->lockdb_clean = true;
+
+ br_lck = brl_get_locks(talloc_tos(), fsp);
+ if (br_lck == NULL) {
+ return false;
+ }
+
+ if (br_lck->num_locks == 0) {
+ TALLOC_FREE(br_lck);
+ return true;
+ }
+
+ for (i=0; i < br_lck->num_locks; i++) {
+ struct lock_struct *lock = &br_lck->lock_data[i];
+
+ /*
+ * as this is a durable handle we only expect locks
+ * of the current file handle!
+ */
+
+ if (lock->context.smblctx != smblctx) {
+ TALLOC_FREE(br_lck);
+ return false;
+ }
+
+ if (lock->context.tid != TID_FIELD_INVALID) {
+ TALLOC_FREE(br_lck);
+ return false;
+ }
+
+ if (!server_id_is_disconnected(&lock->context.pid)) {
+ TALLOC_FREE(br_lck);
+ return false;
+ }
+
+ if (lock->fnum != FNUM_FIELD_INVALID) {
+ TALLOC_FREE(br_lck);
+ return false;
+ }
+
+ lock->context.pid = self;
+ lock->context.tid = tid;
+ lock->fnum = fnum;
+ }
+
+ fsp->current_lock_count = br_lck->num_locks;
+ br_lck->modified = true;
+ TALLOC_FREE(br_lck);
+ return true;
+}
+
/****************************************************************************
Ensure this set of lock entries is valid.
****************************************************************************/
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index d3ab7f3..a7fc50c 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -811,6 +811,44 @@ bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
return True;
}
+bool mark_share_mode_disconnected(struct share_mode_lock *lck,
+ struct files_struct *fsp)
+{
+ struct share_mode_entry entry, *e;
+
+ if (lck->data->num_share_modes != 1) {
+ return false;
+ }
+
+ if (fsp->op == NULL) {
+ return false;
+ }
+ if (!fsp->op->global->durable) {
+ return false;
+ }
+
+ /* Don't care about the pid owner being correct here - just a search. */
+ fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
+
+ e = find_share_mode_entry(lck->data, &entry);
+ if (e == NULL) {
+ return false;
+ }
+
+ DEBUG(10, ("Marking share mode entry disconnected for durable handle\n"));
+
+ server_id_set_disconnected(&e->pid);
+
+ /*
+ * On reopen the caller needs to check that
+ * the client comes with the correct handle.
+ */
+ e->share_file_id = fsp->op->global->open_persistent_id;
+
+ lck->data->modified = true;
+ return true;
+}
+
void del_deferred_open_entry(struct share_mode_lock *lck, uint64_t mid,
struct server_id pid)
{
diff --git a/source3/locking/proto.h b/source3/locking/proto.h
index 74cf323..c170c73 100644
--- a/source3/locking/proto.h
+++ b/source3/locking/proto.h
@@ -79,6 +79,8 @@ bool brl_lock_cancel(struct byte_range_lock *br_lck,
struct blocking_lock_record *blr);
bool brl_lock_cancel_default(struct byte_range_lock *br_lck,
struct lock_struct *plock);
+bool brl_mark_disconnected(struct files_struct *fsp);
+bool brl_reconnect_disconnected(struct files_struct *fsp);
void brl_close_fnum(struct messaging_context *msg_ctx,
struct byte_range_lock *br_lck);
int brl_forall(void (*fn)(struct file_id id, struct server_id pid,
@@ -175,6 +177,8 @@ void add_deferred_open(struct share_mode_lock *lck, uint64_t mid,
struct timeval request_time,
struct server_id pid, struct file_id id);
bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp);
+bool mark_share_mode_disconnected(struct share_mode_lock *lck,
+ struct files_struct *fsp);
void del_deferred_open_entry(struct share_mode_lock *lck, uint64_t mid,
struct server_id pid);
bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp);
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 42671a1..427e3af 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -2227,6 +2227,34 @@ static int vfswrap_set_offline(struct vfs_handle_struct *handle,
return -1;
}
+static NTSTATUS vfswrap_durable_cookie(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ TALLOC_CTX *mem_ctx,
+ DATA_BLOB *cookie)
+{
+ return NT_STATUS_NOT_SUPPORTED;
+}
+
+static NTSTATUS vfswrap_durable_disconnect(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ const DATA_BLOB old_cookie,
+ TALLOC_CTX *mem_ctx,
+ DATA_BLOB *new_cookie)
+{
+ return NT_STATUS_NOT_SUPPORTED;
+}
+
+static NTSTATUS vfswrap_durable_reconnect(struct vfs_handle_struct *handle,
+ struct smb_request *smb1req,
+ struct smbXsrv_open *op,
+ const DATA_BLOB old_cookie,
+ TALLOC_CTX *mem_ctx,
+ struct files_struct **fsp,
+ DATA_BLOB *new_cookie)
+{
+ return NT_STATUS_NOT_SUPPORTED;
+}
+
static struct vfs_fn_pointers vfs_default_fns = {
/* Disk operations */
@@ -2344,7 +2372,12 @@ static struct vfs_fn_pointers vfs_default_fns = {
/* offline operations */
.is_offline_fn = vfswrap_is_offline,
- .set_offline_fn = vfswrap_set_offline
+ .set_offline_fn = vfswrap_set_offline,
+
+ /* durable handle operations */
+ .durable_cookie_fn = vfswrap_durable_cookie,
+ .durable_disconnect_fn = vfswrap_durable_disconnect,
+ .durable_reconnect_fn = vfswrap_durable_reconnect,
};
NTSTATUS vfs_default_init(void);
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 2c77691..5f00932 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -831,7 +831,7 @@ static void init_globals(bool reinit_globals)
Globals.max_log_size = 5000;
Globals.max_open_files = max_open_files();
Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
- Globals.srv_maxprotocol = PROTOCOL_SMB2_10;
+ Globals.srv_maxprotocol = PROTOCOL_SMB3_00;
Globals.srv_minprotocol = PROTOCOL_LANMAN1;
Globals.security = SEC_USER;
Globals.bEncryptPasswords = true;
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index 5143232..8bf481d 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -706,6 +706,7 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
NTSTATUS status = NT_STATUS_OK;
NTSTATUS tmp;
connection_struct *conn = fsp->conn;
+ bool is_durable = false;
if (fsp->num_aio_requests != 0) {
@@ -752,6 +753,49 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
tmp = close_filestruct(fsp);
status = ntstatus_keeperror(status, tmp);
+ if (NT_STATUS_IS_OK(status) && fsp->op != NULL) {
+ is_durable = fsp->op->global->durable;
+ }
+
+ if (close_type != SHUTDOWN_CLOSE) {
+ is_durable = false;
+ }
+
+ if (is_durable) {
+ DATA_BLOB new_cookie = data_blob_null;
+
+ tmp = SMB_VFS_DURABLE_DISCONNECT(fsp,
+ fsp->op->global->backend_cookie,
+ fsp->op,
+ &new_cookie);
+ if (NT_STATUS_IS_OK(tmp)) {
+ data_blob_free(&fsp->op->global->backend_cookie);
+ fsp->op->global->backend_cookie = new_cookie;
+
+ tmp = smbXsrv_open_update(fsp->op);
+ }
+ if (!NT_STATUS_IS_OK(tmp)) {
+ is_durable = false;
+ }
+ }
+
+ if (is_durable) {
+ /*
+ * This is the case where we successfully disconnected
+ * a durable handle and closed the underlying file.
+ * In all other cases, we proceed with a genuine close.
+ */
+ file_free(req, fsp);
+ return NT_STATUS_OK;
+ }
+
+ if (fsp->op != NULL) {
+ /*
+ * Make sure the handle is not marked as durable anymore
+ */
+ fsp->op->global->durable = false;
+ }
+
if (fsp->print_file) {
/* FIXME: return spool errors */
print_spool_end(fsp, close_type);
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index 0550b31..ef229a4 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -151,9 +151,16 @@ void file_close_conn(connection_struct *conn)
for (fsp=conn->sconn->files; fsp; fsp=next) {
next = fsp->next;
- if (fsp->conn == conn) {
- close_file(NULL, fsp, SHUTDOWN_CLOSE);
+ if (fsp->conn != conn) {
+ continue;
+ }
+ if (fsp->op != NULL && fsp->op->global->durable) {
+ /*
+ * A tree disconnect closes a durable handle
--
Samba Shared Repository
More information about the samba-cvs
mailing list