The Samba-Bugzilla – Attachment 10396 Details for
Bug 10911
SMB2 leases are not yet supported.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Leases prerequisite patchset (part1) cherry-picked from master. (already pushed)
4.2-lease-prereq (text/plain), 36.42 KB, created by
Jeremy Allison
on 2014-11-03 18:24:28 UTC
(
hide
)
Description:
Leases prerequisite patchset (part1) cherry-picked from master. (already pushed)
Filename:
MIME Type:
Creator:
Jeremy Allison
Created:
2014-11-03 18:24:28 UTC
Size:
36.42 KB
patch
obsolete
>From c2fdd9bfdf52c23234f9f47251b6fc4ac16c25c2 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Wed, 8 Oct 2014 09:06:06 -0700 >Subject: [PATCH 01/10] s3: smbd: Preparation for leases code merge. Ensure VFS > is ready for 4.2.0. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> > >Autobuild-User(master): Jeremy Allison <jra@samba.org> >Autobuild-Date(master): Fri Oct 10 02:55:53 CEST 2014 on sn-devel-104 > >(cherry picked from commit aa2a6c7b18e2e2bd3979ffb53208564764b8b9cf) >--- > source3/include/vfs.h | 7 +++++++ > 1 file changed, 7 insertions(+) > >diff --git a/source3/include/vfs.h b/source3/include/vfs.h >index 3702b75..b0f00e8 100644 >--- a/source3/include/vfs.h >+++ b/source3/include/vfs.h >@@ -158,6 +158,7 @@ > > /* Bump to version 32 - Samba 4.2 will ship with that. */ > /* Version 32 - Add "lease" to CREATE_FILE operation */ >+/* Version 32 - Add "lease" to struct files_struct */ > > #define SMB_VFS_INTERFACE_VERSION 32 > >@@ -202,6 +203,11 @@ struct fd_handle { > unsigned long gen_id; > }; > >+struct fsp_lease { >+ size_t ref_count; >+ struct smb2_lease lease; >+}; >+ > typedef struct files_struct { > struct files_struct *next, *prev; > uint64_t fnum; >@@ -225,6 +231,7 @@ typedef struct files_struct { > bool write_time_forced; > > int oplock_type; >+ struct fsp_lease *lease; /* Not yet used. Placeholder for leases. */ > int sent_oplock_break; > struct tevent_timer *oplock_timeout; > struct lock_struct last_lock_failure; >-- >2.1.0.rc2.206.gedb03e5 > > >From 1390ab9f9f0add5b1a8589dd2a94b757673ed5c0 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Tue, 23 Sep 2014 05:18:54 +0200 >Subject: [PATCH 02/10] s3:locking: Rename > share_mode_forall->share_entry_forall > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 0d4f7bfdb995a239508457cd433bc8001c0e8279) >--- > source3/locking/proto.h | 4 ++-- > source3/locking/share_mode_lock.c | 4 ++-- > source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 8 ++++---- > source3/utils/status.c | 2 +- > 4 files changed, 9 insertions(+), 9 deletions(-) > >diff --git a/source3/locking/proto.h b/source3/locking/proto.h >index 46eec2a..ce8c25c 100644 >--- a/source3/locking/proto.h >+++ b/source3/locking/proto.h >@@ -190,8 +190,8 @@ bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash); > bool set_sticky_write_time(struct file_id fileid, struct timespec write_time); > bool set_write_time(struct file_id fileid, struct timespec write_time); > struct timespec get_share_mode_write_time(struct share_mode_lock *lck); >-int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *, >- const char *, void *), >+int share_entry_forall(void (*fn)(const struct share_mode_entry *, const char *, >+ const char *, void *), > void *private_data); > bool share_mode_cleanup_disconnected(struct file_id id, > uint64_t open_persistent_id); >diff --git a/source3/locking/share_mode_lock.c b/source3/locking/share_mode_lock.c >index 12f499b..53039eb 100644 >--- a/source3/locking/share_mode_lock.c >+++ b/source3/locking/share_mode_lock.c >@@ -499,8 +499,8 @@ static int traverse_fn(struct db_record *rec, void *_state) > share mode system. > ********************************************************************/ > >-int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *, >- const char *, void *), >+int share_entry_forall(void (*fn)(const struct share_mode_entry *, >+ const char *, const char *, void *), > void *private_data) > { > struct forall_state state; >diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c >index 855b8c7..d2f05f3 100644 >--- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c >+++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c >@@ -166,7 +166,7 @@ static WERROR net_enum_files(TALLOC_CTX *ctx, > f_enum_cnt.username = username; > f_enum_cnt.ctr3 = *ctr3; > >- share_mode_forall( enum_file_fn, (void *)&f_enum_cnt ); >+ share_entry_forall( enum_file_fn, (void *)&f_enum_cnt ); > > *ctr3 = f_enum_cnt.ctr3; > >@@ -867,7 +867,7 @@ static void net_count_files_for_all_sess(struct srvsvc_NetSessCtr1 *ctr1, > s_file_info.resume_handle = resume_handle; > s_file_info.num_entries = num_entries; > >- share_mode_forall(count_sess_files_fn, &s_file_info); >+ share_entry_forall(count_sess_files_fn, &s_file_info); > } > > /******************************************************************* >@@ -984,7 +984,7 @@ static void count_share_opens(struct srvsvc_NetConnInfo1 *arr, > sfs.resp_entries = resp_entries; > sfs.total_entries = total_entries; > >- share_mode_forall(share_file_fn, &sfs); >+ share_entry_forall(share_file_fn, &sfs); > } > > /**************************************************************************** >@@ -2744,7 +2744,7 @@ WERROR _srvsvc_NetFileClose(struct pipes_struct *p, > r->out.result = WERR_BADFILE; > state.r = r; > state.msg_ctx = p->msg_ctx; >- share_mode_forall(enum_file_close_fn, &state); >+ share_entry_forall(enum_file_close_fn, &state); > return r->out.result; > } > >diff --git a/source3/utils/status.c b/source3/utils/status.c >index 7bbcea5..2c850bb 100644 >--- a/source3/utils/status.c >+++ b/source3/utils/status.c >@@ -526,7 +526,7 @@ int main(int argc, const char *argv[]) > goto done; > } > >- result = share_mode_forall(print_share_mode, NULL); >+ result = share_entry_forall(print_share_mode, NULL); > > if (result == 0) { > d_printf("No locked files\n"); >-- >2.1.0.rc2.206.gedb03e5 > > >From f6cecf7c2240fdc42e1c1e1404d357510361b353 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Tue, 23 Sep 2014 05:45:49 +0200 >Subject: [PATCH 03/10] s3:locking: Introduce share_mode_forall > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 48926b761975a7d9cb6daf30d64d6a4f0a34f38a) >--- > source3/locking/proto.h | 4 ++ > source3/locking/share_mode_lock.c | 92 +++++++++++++++++++++++++++------------ > 2 files changed, 68 insertions(+), 28 deletions(-) > >diff --git a/source3/locking/proto.h b/source3/locking/proto.h >index ce8c25c..a5c46c8 100644 >--- a/source3/locking/proto.h >+++ b/source3/locking/proto.h >@@ -190,6 +190,10 @@ bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash); > bool set_sticky_write_time(struct file_id fileid, struct timespec write_time); > bool set_write_time(struct file_id fileid, struct timespec write_time); > struct timespec get_share_mode_write_time(struct share_mode_lock *lck); >+int share_mode_forall(int (*fn)(struct file_id fid, >+ const struct share_mode_data *data, >+ void *private_data), >+ void *private_data); > int share_entry_forall(void (*fn)(const struct share_mode_entry *, const char *, > const char *, void *), > void *private_data); >diff --git a/source3/locking/share_mode_lock.c b/source3/locking/share_mode_lock.c >index 53039eb..c2f3402 100644 >--- a/source3/locking/share_mode_lock.c >+++ b/source3/locking/share_mode_lock.c >@@ -440,30 +440,33 @@ struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx, > return lck; > } > >-struct forall_state { >- void (*fn)(const struct share_mode_entry *entry, >- const char *sharepath, >- const char *fname, >- void *private_data); >+struct share_mode_forall_state { >+ int (*fn)(struct file_id fid, const struct share_mode_data *data, >+ void *private_data); > void *private_data; > }; > >-static int traverse_fn(struct db_record *rec, void *_state) >+static int share_mode_traverse_fn(struct db_record *rec, void *_state) > { >- struct forall_state *state = (struct forall_state *)_state; >+ struct share_mode_forall_state *state = >+ (struct share_mode_forall_state *)_state; > uint32_t i; > TDB_DATA key; > TDB_DATA value; > DATA_BLOB blob; > enum ndr_err_code ndr_err; > struct share_mode_data *d; >+ struct file_id fid; >+ int ret; > > key = dbwrap_record_get_key(rec); > value = dbwrap_record_get_value(rec); > > /* Ensure this is a locking_key record. */ >- if (key.dsize != sizeof(struct file_id)) >+ if (key.dsize != sizeof(fid)) { > return 0; >+ } >+ memcpy(&fid, key.dptr, sizeof(fid)); > > d = talloc(talloc_tos(), struct share_mode_data); > if (d == NULL) { >@@ -485,11 +488,58 @@ static int traverse_fn(struct db_record *rec, void *_state) > } > for (i=0; i<d->num_share_modes; i++) { > d->share_modes[i].stale = false; /* [skip] in idl */ >- state->fn(&d->share_modes[i], >- d->servicepath, d->base_name, >- state->private_data); > } >+ >+ ret = state->fn(fid, d, state->private_data); >+ > TALLOC_FREE(d); >+ return ret; >+} >+ >+int share_mode_forall(int (*fn)(struct file_id fid, >+ const struct share_mode_data *data, >+ void *private_data), >+ void *private_data) >+{ >+ struct share_mode_forall_state state = { >+ .fn = fn, >+ .private_data = private_data >+ }; >+ NTSTATUS status; >+ int count; >+ >+ if (lock_db == NULL) { >+ return 0; >+ } >+ >+ status = dbwrap_traverse_read(lock_db, share_mode_traverse_fn, >+ &state, &count); >+ if (!NT_STATUS_IS_OK(status)) { >+ return -1; >+ } >+ >+ return count; >+} >+ >+struct share_entry_forall_state { >+ void (*fn)(const struct share_mode_entry *e, >+ const char *service_path, const char *base_name, >+ void *private_data); >+ void *private_data; >+}; >+ >+static int share_entry_traverse_fn(struct file_id fid, >+ const struct share_mode_data *data, >+ void *private_data) >+{ >+ struct share_entry_forall_state *state = private_data; >+ uint32_t i; >+ >+ for (i=0; i<data->num_share_modes; i++) { >+ state->fn(&data->share_modes[i], >+ data->servicepath, data->base_name, >+ state->private_data); >+ } > > return 0; > } >@@ -503,24 +553,10 @@ int share_entry_forall(void (*fn)(const struct share_mode_entry *, > const char *, const char *, void *), > void *private_data) > { >- struct forall_state state; >- NTSTATUS status; >- int count; >- >- if (lock_db == NULL) >- return 0; >- >- state.fn = fn; >- state.private_data = private_data; >+ struct share_entry_forall_state state = { >+ .fn = fn, .private_data = private_data }; > >- status = dbwrap_traverse_read(lock_db, traverse_fn, (void *)&state, >- &count); >- >- if (!NT_STATUS_IS_OK(status)) { >- return -1; >- } else { >- return count; >- } >+ return share_mode_forall(share_entry_traverse_fn, &state); > } > > bool share_mode_cleanup_disconnected(struct file_id fid, >-- >2.1.0.rc2.206.gedb03e5 > > >From fcb5a60652474c69c1b3dbd6d387b4828c0fa766 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Wed, 24 Sep 2014 20:46:15 +0200 >Subject: [PATCH 04/10] s3:locking: allow early return for share_entry_forall() > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 9010bbeb00264f4476c3be7d2e8c8420c695cfbb) >--- > source3/locking/proto.h | 4 +-- > source3/locking/share_mode_lock.c | 23 ++++++++++------ > source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 46 +++++++++++++++++-------------- > source3/utils/status.c | 12 ++++---- > 4 files changed, 49 insertions(+), 36 deletions(-) > >diff --git a/source3/locking/proto.h b/source3/locking/proto.h >index a5c46c8..44f3ba1 100644 >--- a/source3/locking/proto.h >+++ b/source3/locking/proto.h >@@ -194,8 +194,8 @@ int share_mode_forall(int (*fn)(struct file_id fid, > const struct share_mode_data *data, > void *private_data), > void *private_data); >-int share_entry_forall(void (*fn)(const struct share_mode_entry *, const char *, >- const char *, void *), >+int share_entry_forall(int (*fn)(const struct share_mode_entry *, const char *, >+ const char *, void *), > void *private_data); > bool share_mode_cleanup_disconnected(struct file_id id, > uint64_t open_persistent_id); >diff --git a/source3/locking/share_mode_lock.c b/source3/locking/share_mode_lock.c >index c2f3402..da16d1a 100644 >--- a/source3/locking/share_mode_lock.c >+++ b/source3/locking/share_mode_lock.c >@@ -522,9 +522,9 @@ int share_mode_forall(int (*fn)(struct file_id fid, > } > > struct share_entry_forall_state { >- void (*fn)(const struct share_mode_entry *e, >- const char *service_path, const char *base_name, >- void *private_data); >+ int (*fn)(const struct share_mode_entry *e, >+ const char *service_path, const char *base_name, >+ void *private_data); > void *private_data; > }; > >@@ -536,9 +536,14 @@ static int share_entry_traverse_fn(struct file_id fid, > uint32_t i; > > for (i=0; i<data->num_share_modes; i++) { >- state->fn(&data->share_modes[i], >- data->servicepath, data->base_name, >- state->private_data); >+ int ret; >+ >+ ret = state->fn(&data->share_modes[i], >+ data->servicepath, data->base_name, >+ state->private_data); >+ if (ret != 0) { >+ return ret; >+ } > } > > return 0; >@@ -549,9 +554,9 @@ static int share_entry_traverse_fn(struct file_id fid, > share mode system. > ********************************************************************/ > >-int share_entry_forall(void (*fn)(const struct share_mode_entry *, >- const char *, const char *, void *), >- void *private_data) >+int share_entry_forall(int (*fn)(const struct share_mode_entry *, >+ const char *, const char *, void *), >+ void *private_data) > { > struct share_entry_forall_state state = { > .fn = fn, .private_data = private_data }; >diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c >index d2f05f3..eaa70e7 100644 >--- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c >+++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c >@@ -79,9 +79,9 @@ struct share_conn_stat { > /******************************************************************* > ********************************************************************/ > >-static void enum_file_fn( const struct share_mode_entry *e, >- const char *sharepath, const char *fname, >- void *private_data ) >+static int enum_file_fn(const struct share_mode_entry *e, >+ const char *sharepath, const char *fname, >+ void *private_data) > { > struct file_enum_count *fenum = > (struct file_enum_count *)private_data; >@@ -98,21 +98,21 @@ static void enum_file_fn( const struct share_mode_entry *e, > /* If the pid was not found delete the entry from connections.tdb */ > > if ( !process_exists(e->pid) ) { >- return; >+ return 0; > } > > username = uidtoname(e->uid); > > if ((fenum->username != NULL) > && !strequal(username, fenum->username)) { >- return; >+ return 0; > } > > f = talloc_realloc(fenum->ctx, fenum->ctr3->array, > struct srvsvc_NetFileInfo3, i+1); > if ( !f ) { > DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1)); >- return; >+ return 0; > } > fenum->ctr3->array = f; > >@@ -133,7 +133,7 @@ static void enum_file_fn( const struct share_mode_entry *e, > sharepath, fname ); > } > if (!fullpath) { >- return; >+ return 0; > } > string_replace( fullpath, '/', '\\' ); > >@@ -150,6 +150,8 @@ static void enum_file_fn( const struct share_mode_entry *e, > fenum->ctr3->array[i].user = username; > > fenum->ctr3->count++; >+ >+ return 0; > } > > /******************************************************************* >@@ -826,9 +828,9 @@ static WERROR init_srv_sess_info_0(struct pipes_struct *p, > * find out the session on which this file is open and bump up its count > **********************************************************************/ > >-static void count_sess_files_fn(const struct share_mode_entry *e, >- const char *sharepath, const char *fname, >- void *data) >+static int count_sess_files_fn(const struct share_mode_entry *e, >+ const char *sharepath, const char *fname, >+ void *data) > { > struct sess_file_info *info = data; > uint32_t rh = info->resume_handle; >@@ -846,9 +848,10 @@ static void count_sess_files_fn(const struct share_mode_entry *e, > serverid_equal(&e->pid, &sess->pid)) { > > info->ctr->array[i].num_open++; >- return; >+ return 0; > } > } >+ return 0; > } > > /******************************************************************* >@@ -950,9 +953,9 @@ static WERROR init_srv_sess_info_1(struct pipes_struct *p, > find the share connection on which this open exists. > ********************************************************************/ > >-static void share_file_fn(const struct share_mode_entry *e, >- const char *sharepath, const char *fname, >- void *data) >+static int share_file_fn(const struct share_mode_entry *e, >+ const char *sharepath, const char *fname, >+ void *data) > { > struct share_file_stat *sfs = data; > uint32_t i; >@@ -962,10 +965,11 @@ static void share_file_fn(const struct share_mode_entry *e, > for (i=0; i < sfs->resp_entries; i++) { > if (serverid_equal(&e->pid, &sfs->svrid_arr[offset + i])) { > sfs->netconn_arr[i].num_open ++; >- return; >+ return 0; > } > } > } >+ return 0; > } > > /******************************************************************* >@@ -2690,9 +2694,9 @@ struct enum_file_close_state { > struct messaging_context *msg_ctx; > }; > >-static void enum_file_close_fn( const struct share_mode_entry *e, >- const char *sharepath, const char *fname, >- void *private_data ) >+static int enum_file_close_fn(const struct share_mode_entry *e, >+ const char *sharepath, const char *fname, >+ void *private_data) > { > char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE]; > struct enum_file_close_state *state = >@@ -2700,11 +2704,11 @@ static void enum_file_close_fn( const struct share_mode_entry *e, > uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id); > > if (fid != state->r->in.fid) { >- return; /* Not this file. */ >+ return 0; /* Not this file. */ > } > > if (!process_exists(e->pid) ) { >- return; >+ return 0; > } > > /* Ok - send the close message. */ >@@ -2718,6 +2722,8 @@ static void enum_file_close_fn( const struct share_mode_entry *e, > messaging_send_buf(state->msg_ctx, > e->pid, MSG_SMB_CLOSE_FILE, > (uint8 *)msg, sizeof(msg))); >+ >+ return 0; > } > > /******************************************************************** >diff --git a/source3/utils/status.c b/source3/utils/status.c >index 2c850bb..b589813 100644 >--- a/source3/utils/status.c >+++ b/source3/utils/status.c >@@ -115,10 +115,10 @@ static bool Ucrit_addPid( struct server_id pid ) > return True; > } > >-static void print_share_mode(const struct share_mode_entry *e, >- const char *sharepath, >- const char *fname, >- void *dummy) >+static int print_share_mode(const struct share_mode_entry *e, >+ const char *sharepath, >+ const char *fname, >+ void *dummy) > { > static int count; > >@@ -135,7 +135,7 @@ static void print_share_mode(const struct share_mode_entry *e, > > if (do_checks && !serverid_exists(&e->pid)) { > /* the process for this entry does not exist any more */ >- return; >+ return 0; > } > > if (Ucrit_checkPid(e->pid)) { >@@ -183,6 +183,8 @@ static void print_share_mode(const struct share_mode_entry *e, > > d_printf(" %s %s %s",sharepath, fname, time_to_asc((time_t)e->time.tv_sec)); > } >+ >+ return 0; > } > > static void print_brl(struct file_id id, >-- >2.1.0.rc2.206.gedb03e5 > > >From 742df0942ab0ea9f9ce8be8d2b674a9ca45bbedd Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Fri, 24 Oct 2014 13:57:04 -0700 >Subject: [PATCH 05/10] s3:param: Add new option "strict rename". > >Control whether smbd can rename directories containing >open files. Defaults to "no" (meaning we *can* do >such renames). > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit b0a434386dc2f77df89811bc3f56c4cc7fb7b16c) >--- > docs-xml/smbdotconf/tuning/strictrename.xml | 25 +++++++++++++++++++++++++ > lib/param/param_table.c | 9 +++++++++ > source3/param/loadparm.c | 1 + > 3 files changed, 35 insertions(+) > create mode 100644 docs-xml/smbdotconf/tuning/strictrename.xml > >diff --git a/docs-xml/smbdotconf/tuning/strictrename.xml b/docs-xml/smbdotconf/tuning/strictrename.xml >new file mode 100644 >index 0000000..5478863 >--- /dev/null >+++ b/docs-xml/smbdotconf/tuning/strictrename.xml >@@ -0,0 +1,25 @@ >+<samba:parameter name="strict rename" >+ context="S" >+ type="boolean" >+ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> >+<description> >+ <para>By default a Windows SMB server prevents directory >+ renames when there are open file or directory handles below >+ it in the filesystem hierarchy. Historically Samba has always >+ allowed this as POSIX filesystem semantics require it.</para> >+ >+ <para>This boolean parameter allows Samba to match the Windows >+ behavior. Setting this to "yes" is a very expensive change, >+ as it forces Samba to travers the entire open file handle >+ database on every directory rename request. In a clustered >+ Samba system the cost is even greater than the non-clustered >+ case.</para> >+ >+ <para>For this reason the default is "no", and it is recommended >+ to be left that way unless a specific Windows application requires >+ it to be changed.</para> >+ >+</description> >+ >+<value type="default">no</value> >+</samba:parameter> >diff --git a/lib/param/param_table.c b/lib/param/param_table.c >index d3f60c3..4d0e6a9 100644 >--- a/lib/param/param_table.c >+++ b/lib/param/param_table.c >@@ -1882,6 +1882,15 @@ struct parm_struct parm_table[] = { > .flags = FLAG_ADVANCED | FLAG_SHARE, > }, > { >+ .label = "strict rename", >+ .type = P_BOOL, >+ .p_class = P_LOCAL, >+ .offset = LOCAL_VAR(strict_rename), >+ .special = NULL, >+ .enum_list = NULL, >+ .flags = FLAG_ADVANCED | FLAG_SHARE, >+ }, >+ { > .label = "strict sync", > .type = P_BOOL, > .p_class = P_LOCAL, >diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c >index 5ab0de7..884cc45 100644 >--- a/source3/param/loadparm.c >+++ b/source3/param/loadparm.c >@@ -206,6 +206,7 @@ static struct loadparm_service sDefault = > .follow_symlinks = true, > .sync_always = false, > .strict_allocate = false, >+ .strict_rename = false, > .strict_sync = false, > .mangling_char = '~', > .copymap = NULL, >-- >2.1.0.rc2.206.gedb03e5 > > >From 96cd73c632761bbad3e63a8e6f87c8d53dc50072 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Fri, 24 Oct 2014 13:57:04 -0700 >Subject: [PATCH 06/10] selftest:Samba3: use "strict rename = yes" > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 5f60dcc38ca275aedeb1d67611b5acf9b26361d5) >--- > selftest/target/Samba3.pm | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm >index de40ced..ebe2c09 100755 >--- a/selftest/target/Samba3.pm >+++ b/selftest/target/Samba3.pm >@@ -1073,6 +1073,7 @@ sub provision($$$$$$) > store dos attributes = yes > create mask = 755 > dos filemode = yes >+ strict rename = yes > vfs objects = acl_xattr fake_acls xattr_tdb streams_depot > > printing = vlp >-- >2.1.0.rc2.206.gedb03e5 > > >From 43524fe3e32874c3c8b12188fc187f2c71c8a306 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Thu, 25 Sep 2014 01:30:33 +0200 >Subject: [PATCH 07/10] s3:smbd: Don't rename a dir with files open underneath > >This is an EXPENSIVE check. We'll have to guard this with an option > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 035fd7200d8a025cdb8bfae30c264757aa3cb193) >--- > source3/smbd/dir.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 120 insertions(+), 1 deletion(-) > >diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c >index e60bc2c..36d95d5 100644 >--- a/source3/smbd/dir.c >+++ b/source3/smbd/dir.c >@@ -25,6 +25,7 @@ > #include "libcli/security/security.h" > #include "lib/util/bitmap.h" > #include "../lib/util/memcache.h" >+#include "../librpc/gen_ndr/open_files.h" > > /* > This module implements directory related functions for Samba. >@@ -1809,6 +1810,113 @@ bool SearchDir(struct smb_Dir *dirp, const char *name, long *poffset) > return False; > } > >+struct files_below_forall_state { >+ char *dirpath; >+ size_t dirpath_len; >+ int (*fn)(struct file_id fid, const struct share_mode_data *data, >+ void *private_data); >+ void *private_data; >+}; >+ >+static int files_below_forall_fn(struct file_id fid, >+ const struct share_mode_data *data, >+ void *private_data) >+{ >+ struct files_below_forall_state *state = private_data; >+ char tmpbuf[PATH_MAX]; >+ char *fullpath, *to_free; >+ size_t len; >+ >+ len = full_path_tos(data->servicepath, data->base_name, >+ tmpbuf, sizeof(tmpbuf), >+ &fullpath, &to_free); >+ if (len == -1) { >+ return 0; >+ } >+ if (state->dirpath_len >= len) { >+ /* >+ * Filter files above dirpath >+ */ >+ return 0; >+ } >+ if (fullpath[state->dirpath_len] != '/') { >+ /* >+ * Filter file that don't have a path separator at the end of >+ * dirpath's length >+ */ >+ return 0; >+ } >+ >+ if (memcmp(state->dirpath, fullpath, len) != 0) { >+ /* >+ * Not a parent >+ */ >+ return 0; >+ } >+ >+ return state->fn(fid, data, private_data); >+} >+ >+static int files_below_forall(connection_struct *conn, >+ const struct smb_filename *dir_name, >+ int (*fn)(struct file_id fid, >+ const struct share_mode_data *data, >+ void *private_data), >+ void *private_data) >+{ >+ struct files_below_forall_state state = {}; >+ int ret; >+ char tmpbuf[PATH_MAX]; >+ char *to_free; >+ >+ state.dirpath_len = full_path_tos(conn->connectpath, >+ dir_name->base_name, >+ tmpbuf, sizeof(tmpbuf), >+ &state.dirpath, &to_free); >+ if (state.dirpath_len == -1) { >+ return -1; >+ >+ } >+ >+ ret = share_mode_forall(files_below_forall_fn, &state); >+ TALLOC_FREE(to_free); >+ return ret; >+} >+ >+struct have_file_open_below_state { >+ bool found_one; >+}; >+ >+static int have_file_open_below_fn(struct file_id fid, >+ const struct share_mode_data *data, >+ void *private_data) >+{ >+ struct have_file_open_below_state *state = private_data; >+ state->found_one = true; >+ return 1; >+} >+ >+static bool have_file_open_below(connection_struct *conn, >+ const struct smb_filename *name) >+{ >+ struct have_file_open_below_state state = {}; >+ int ret; >+ >+ if (!VALID_STAT(name->st)) { >+ return false; >+ } >+ if (!S_ISDIR(name->st.st_ex_mode)) { >+ return false; >+ } >+ >+ ret = files_below_forall(conn, name, have_file_open_below_fn, &state); >+ if (ret == -1) { >+ return false; >+ } >+ >+ return state.found_one; >+} >+ > /***************************************************************** > Is this directory empty ? > *****************************************************************/ >@@ -1854,5 +1962,16 @@ NTSTATUS can_delete_directory_fsp(files_struct *fsp) > TALLOC_FREE(talloced); > TALLOC_FREE(dir_hnd); > >- return status; >+ if (!NT_STATUS_IS_OK(status)) { >+ return status; >+ } >+ >+ if (!lp_posix_pathnames() && >+ lp_strict_rename(SNUM(conn)) && >+ have_file_open_below(fsp->conn, fsp->fsp_name)) >+ { >+ return NT_STATUS_ACCESS_DENIED; >+ } >+ >+ return NT_STATUS_OK; > } >-- >2.1.0.rc2.206.gedb03e5 > > >From 25bee982a551a2c37be807ad51baea73bcf4a463 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Thu, 25 Sep 2014 01:32:00 +0200 >Subject: [PATCH 08/10] s4:torture/smb2: test rename dir deny with open files > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 8334428666b8282d2cfbcfd411acab0c338ae390) >--- > selftest/knownfail | 1 + > source4/torture/smb2/rename.c | 97 +++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 98 insertions(+) > >diff --git a/selftest/knownfail b/selftest/knownfail >index 3d73495..6cca3dd 100644 >--- a/selftest/knownfail >+++ b/selftest/knownfail >@@ -112,6 +112,7 @@ > ^samba4.smb2.rename.no_share_delete_no_delete_access\(.*\)$ > ^samba4.smb2.rename.msword > ^samba4.smb2.rename.rename_dir_bench\(dc\) >+^samba4.smb2.rename.rename_dir_openfile\(.*\)$ > ^samba4.smb2.oplock.doc > ^samba4.smb2.compound.related3 > ^samba4.smb2.compound.compound-break >diff --git a/source4/torture/smb2/rename.c b/source4/torture/smb2/rename.c >index 9d0f4e1..07bdabd 100644 >--- a/source4/torture/smb2/rename.c >+++ b/source4/torture/smb2/rename.c >@@ -928,6 +928,99 @@ done: > return ret; > } > >+static bool torture_smb2_rename_dir_openfile(struct torture_context *torture, >+ struct smb2_tree *tree1) >+{ >+ bool ret = true; >+ NTSTATUS status; >+ union smb_open io; >+ union smb_close cl; >+ union smb_setfileinfo sinfo; >+ struct smb2_handle d1, h1; >+ >+ smb2_deltree(tree1, BASEDIR); >+ smb2_util_rmdir(tree1, BASEDIR); >+ >+ torture_comment(torture, "Creating base directory\n"); >+ >+ ZERO_STRUCT(io.smb2); >+ io.generic.level = RAW_OPEN_SMB2; >+ io.smb2.in.create_flags = 0; >+ io.smb2.in.desired_access = 0x0017019f; >+ io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; >+ io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY; >+ io.smb2.in.share_access = 0; >+ io.smb2.in.alloc_size = 0; >+ io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE; >+ io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS; >+ io.smb2.in.security_flags = 0; >+ io.smb2.in.fname = BASEDIR; >+ >+ status = smb2_create(tree1, torture, &(io.smb2)); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ d1 = io.smb2.out.file.handle; >+ >+ torture_comment(torture, "Creating test file\n"); >+ >+ ZERO_STRUCT(io.smb2); >+ io.generic.level = RAW_OPEN_SMB2; >+ io.smb2.in.create_flags = 0; >+ io.smb2.in.desired_access = 0x0017019f; >+ io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE; >+ io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL; >+ io.smb2.in.share_access = 0; >+ io.smb2.in.alloc_size = 0; >+ io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE; >+ io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS; >+ io.smb2.in.security_flags = 0; >+ io.smb2.in.fname = BASEDIR "\\file.txt"; >+ >+ status = smb2_create(tree1, torture, &(io.smb2)); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ h1 = io.smb2.out.file.handle; >+ >+ torture_comment(torture, "Renaming directory\n"); >+ >+ ZERO_STRUCT(sinfo); >+ sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION; >+ sinfo.rename_information.in.file.handle = d1; >+ sinfo.rename_information.in.overwrite = 0; >+ sinfo.rename_information.in.root_fid = 0; >+ sinfo.rename_information.in.new_name = >+ BASEDIR "-new"; >+ status = smb2_setinfo_file(tree1, &sinfo); >+ CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); >+ >+ torture_comment(torture, "Closing directory\n"); >+ >+ ZERO_STRUCT(cl.smb2); >+ cl.smb2.level = RAW_CLOSE_SMB2; >+ cl.smb2.in.file.handle = d1; >+ status = smb2_close(tree1, &(cl.smb2)); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ ZERO_STRUCT(d1); >+ >+ torture_comment(torture, "Closing test file\n"); >+ >+ cl.smb2.in.file.handle = h1; >+ status = smb2_close(tree1, &(cl.smb2)); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ ZERO_STRUCT(h1); >+ >+done: >+ >+ torture_comment(torture, "Cleaning up\n"); >+ >+ if (h1.data) { >+ ZERO_STRUCT(cl.smb2); >+ cl.smb2.level = RAW_CLOSE_SMB2; >+ cl.smb2.in.file.handle = h1; >+ status = smb2_close(tree1, &(cl.smb2)); >+ } >+ smb2_deltree(tree1, BASEDIR); >+ return ret; >+} >+ > struct rename_one_dir_cycle_state { > struct tevent_context *ev; > struct smb2_tree *tree; >@@ -1336,6 +1429,10 @@ struct torture_suite *torture_smb2_rename_init(void) > "msword", > torture_smb2_rename_msword); > >+ torture_suite_add_1smb2_test( >+ suite, "rename_dir_openfile", >+ torture_smb2_rename_dir_openfile); >+ > torture_suite_add_1smb2_test(suite, > "rename_dir_bench", > torture_smb2_rename_dir_bench); >-- >2.1.0.rc2.206.gedb03e5 > > >From 4881014943f992ca8d0402bc6bf90ddb327a4710 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Tue, 28 Oct 2014 15:20:26 -0700 >Subject: [PATCH 09/10] s3:locking: Change from ndr_pull_struct_blob() to > ndr_pull_struct_blob_all() so we fail if not all bytes are consumed. > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 151b9caeef7dc4fa4816035a406acb9f1c5812c3) >--- > source3/locking/share_mode_lock.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/source3/locking/share_mode_lock.c b/source3/locking/share_mode_lock.c >index da16d1a..65409ac 100644 >--- a/source3/locking/share_mode_lock.c >+++ b/source3/locking/share_mode_lock.c >@@ -133,7 +133,7 @@ static struct share_mode_data *parse_share_modes(TALLOC_CTX *mem_ctx, > blob.data = dbuf.dptr; > blob.length = dbuf.dsize; > >- ndr_err = ndr_pull_struct_blob( >+ ndr_err = ndr_pull_struct_blob_all( > &blob, d, d, (ndr_pull_flags_fn_t)ndr_pull_share_mode_data); > if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { > DEBUG(1, ("ndr_pull_share_mode_lock failed: %s\n", >@@ -476,7 +476,7 @@ static int share_mode_traverse_fn(struct db_record *rec, void *_state) > blob.data = value.dptr; > blob.length = value.dsize; > >- ndr_err = ndr_pull_struct_blob( >+ ndr_err = ndr_pull_struct_blob_all( > &blob, d, d, (ndr_pull_flags_fn_t)ndr_pull_share_mode_data); > if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { > DEBUG(1, ("ndr_pull_share_mode_lock failed\n")); >-- >2.1.0.rc2.206.gedb03e5 > > >From dadda2d92a2be92f66d9d15a14807a66e1aa0163 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 29 Oct 2014 17:29:06 +0100 >Subject: [PATCH 10/10] s3:locking: remove dead code from > brl_get_locks_readonly() > >struct byte_range_lock *rw = NULL; will never change... > >commit 105724073300af03eb0835b3c93d9b2e2bfacb07 removed the >possible assigment of 'rw'. > >So we can remove all code under if (rw != NULL) { ... > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> > >Autobuild-User(master): Jeremy Allison <jra@samba.org> >Autobuild-Date(master): Fri Oct 31 06:07:43 CET 2014 on sn-devel-104 > >(cherry picked from commit a3b333a1a2ab23ba0c59be1fc65c730e2b53e8c5) >--- > source3/locking/brlock.c | 78 +++++++++++++++++------------------------------- > 1 file changed, 28 insertions(+), 50 deletions(-) > >diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c >index 295e147..1c4c4d0 100644 >--- a/source3/locking/brlock.c >+++ b/source3/locking/brlock.c >@@ -2026,7 +2026,8 @@ static void brl_get_locks_readonly_parser(TDB_DATA key, TDB_DATA data, > struct byte_range_lock *brl_get_locks_readonly(files_struct *fsp) > { > struct byte_range_lock *br_lock = NULL; >- struct byte_range_lock *rw = NULL; >+ struct brl_get_locks_readonly_state state; >+ NTSTATUS status; > > DEBUG(10, ("seqnum=%d, fsp->brlock_seqnum=%d\n", > dbwrap_get_seqnum(brlock_db), fsp->brlock_seqnum)); >@@ -2040,60 +2041,39 @@ struct byte_range_lock *brl_get_locks_readonly(files_struct *fsp) > return fsp->brlock_rec; > } > >- if (rw != NULL) { >- size_t lock_data_size; >+ /* >+ * Parse the record fresh from the database >+ */ >+ >+ state.mem_ctx = fsp; >+ state.br_lock = &br_lock; > >+ status = dbwrap_parse_record( >+ brlock_db, >+ make_tdb_data((uint8_t *)&fsp->file_id, >+ sizeof(fsp->file_id)), >+ brl_get_locks_readonly_parser, &state); >+ >+ if (NT_STATUS_EQUAL(status,NT_STATUS_NOT_FOUND)) { > /* >- * Make a copy of the already retrieved and sanitized rw record >+ * No locks on this file. Return an empty br_lock. > */ >- lock_data_size = rw->num_locks * sizeof(struct lock_struct); >- br_lock = talloc_pooled_object( >- fsp, struct byte_range_lock, 1, lock_data_size); >+ br_lock = talloc(fsp, struct byte_range_lock); > if (br_lock == NULL) { >- goto fail; >+ return NULL; > } >- br_lock->have_read_oplocks = rw->have_read_oplocks; >- br_lock->num_locks = rw->num_locks; >- br_lock->lock_data = (struct lock_struct *)talloc_memdup( >- br_lock, rw->lock_data, lock_data_size); >- } else { >- struct brl_get_locks_readonly_state state; >- NTSTATUS status; >- >- /* >- * Parse the record fresh from the database >- */ > >- state.mem_ctx = fsp; >- state.br_lock = &br_lock; >- >- status = dbwrap_parse_record( >- brlock_db, >- make_tdb_data((uint8_t *)&fsp->file_id, >- sizeof(fsp->file_id)), >- brl_get_locks_readonly_parser, &state); >- >- if (NT_STATUS_EQUAL(status,NT_STATUS_NOT_FOUND)) { >- /* >- * No locks on this file. Return an empty br_lock. >- */ >- br_lock = talloc(fsp, struct byte_range_lock); >- if (br_lock == NULL) { >- goto fail; >- } >- >- br_lock->have_read_oplocks = false; >- br_lock->num_locks = 0; >- br_lock->lock_data = NULL; >+ br_lock->have_read_oplocks = false; >+ br_lock->num_locks = 0; >+ br_lock->lock_data = NULL; > >- } else if (!NT_STATUS_IS_OK(status)) { >- DEBUG(3, ("Could not parse byte range lock record: " >- "%s\n", nt_errstr(status))); >- goto fail; >- } >- if (br_lock == NULL) { >- goto fail; >- } >+ } else if (!NT_STATUS_IS_OK(status)) { >+ DEBUG(3, ("Could not parse byte range lock record: " >+ "%s\n", nt_errstr(status))); >+ return NULL; >+ } >+ if (br_lock == NULL) { >+ return NULL; > } > > br_lock->fsp = fsp; >@@ -2117,8 +2097,6 @@ struct byte_range_lock *brl_get_locks_readonly(files_struct *fsp) > fsp->brlock_seqnum = dbwrap_get_seqnum(brlock_db); > } > >-fail: >- TALLOC_FREE(rw); > return br_lock; > } > >-- >2.1.0.rc2.206.gedb03e5 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
metze
:
review+
Actions:
View
Attachments on
bug 10911
:
10394
| 10396 |
10397
|
10399
|
10400
|
10401
|
10406
|
10407
|
10411
|
10412
|
10415
|
10416
|
10417
|
10418
|
10421
|
10478
|
10479
|
10481
|
10484
|
10486
|
10488
|
10492
|
10493
|
10507
|
10546