Latest leases patchset - getting there !

Stefan (metze) Metzmacher metze at samba.org
Mon Dec 8 08:41:01 MST 2014


Am 05.12.2014 um 22:17 schrieb Jeremy Allison:
> On Fri, Dec 05, 2014 at 02:54:39PM +0100, Stefan (metze) Metzmacher wrote:
>> I think we need to change the data model for the
>> leases_db.
>>
>> Maybe something like this:
>>
>> diff --git a/source3/librpc/idl/leases_db.idl
>> b/source3/librpc/idl/leases_db.idl
>> index 2ab1591..f6a979d 100644
>> --- a/source3/librpc/idl/leases_db.idl
>> +++ b/source3/librpc/idl/leases_db.idl
>> @@ -15,9 +15,14 @@ interface leases_db
>>         } leases_db_key;
>>
>>         typedef [public] struct {
>> -               uint32 num_file_ids;
>> -               [size_is(num_file_ids)] file_id ids[];
>> -               [string,charset(UTF8)] char *filename;
>> +               file_id id;
>> +               [string,charset(UTF8)] char *servicepath;
>> +               [string,charset(UTF8)] char *base_name;
>>                 [string,charset(UTF8)] char *stream_name;
>> +       } leases_db_file;
>> +
>> +       typedef [public] struct {
>> +               uint32 num_files;
>> +               [size_is(num_filess)] leases_db_file files[];
>>         } leases_db_value;
>>  }
>>
>> I'm not sure about the servicepath, I took the same values
>> as we have in share_mode_data. But we need to maintain the names
>> per file_id in order to support dynamic shares.
>>
>> That way we can check if an open with the same file_id uses
>> the correct file name.
> 
> Here is an implementation of that data model.
> 
> Passes all our smb2.leases tests as well as the
> dynamic share test that is in your wip git branch.
> 
> I'm hoping this is the last leases change we need
> before 4.2.0rc3.
> 
> I couldn't figure out how to split out all the
> changes and still keep everything compiling inbetween,
> so this isn't elegantly bisectable :-(. If you
> can figure out how to do that without it being
> a blob of a patch, then I'll learn something :-).

The end result is the same, but each commit passes
TDB_NO_FSYNC=1 buildnice make -j test TESTS=smb2.*lease
SOCKET_WRAPPER_KEEP_PCAP=1 FAIL_IMMEDIATELY=1 SMBD_DONT_LOG_STDOUT=1
SMBD_OPTIONS="-d10"

The last patch is not as small as possible, but I think it's ok.

Please have a look and push if you also happy.

metze
-------------- next part --------------
From 5fc88729e351f3ea8d638f3885a040f808ef957a Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 5 Dec 2014 12:56:03 -0800
Subject: [PATCH 1/5] s3:locking: pass servicename_new to leases_db_rename()

Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 source3/locking/leases_db.c | 1 +
 source3/locking/leases_db.h | 1 +
 source3/locking/locking.c   | 1 +
 3 files changed, 3 insertions(+)

diff --git a/source3/locking/leases_db.c b/source3/locking/leases_db.c
index 7e000aa..4cb38f0 100644
--- a/source3/locking/leases_db.c
+++ b/source3/locking/leases_db.c
@@ -389,6 +389,7 @@ NTSTATUS leases_db_parse(const struct GUID *client_guid,
 NTSTATUS leases_db_rename(const struct GUID *client_guid,
 		       const struct smb2_lease_key *lease_key,
 		       const struct file_id *id,
+		       const char *servicename_new,
 		       const char *filename_new,
 		       const char *stream_name_new)
 {
diff --git a/source3/locking/leases_db.h b/source3/locking/leases_db.h
index 906a99b..f398863 100644
--- a/source3/locking/leases_db.h
+++ b/source3/locking/leases_db.h
@@ -45,6 +45,7 @@ NTSTATUS leases_db_parse(const struct GUID *client_guid,
 NTSTATUS leases_db_rename(const struct GUID *client_guid,
 			const struct smb2_lease_key *lease_key,
 			const struct file_id *id,
+			const char *servicepath_new,
 			const char *filename_new,
 			const char *stream_name_new);
 #endif /* _LEASES_DB_H_ */
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index dd73f68..221d6ee 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -575,6 +575,7 @@ bool rename_share_filename(struct messaging_context *msg_ctx,
 		status = leases_db_rename(&l->client_guid,
 					&l->lease_key,
 					&id,
+					d->servicepath,
 					d->base_name,
 					d->stream_name);
 		if (!NT_STATUS_IS_OK(status)) {
-- 
1.9.1


From f531d8751481da4f972f0606e3699455756be8b7 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 5 Dec 2014 12:47:52 -0800
Subject: [PATCH 2/5] s3:locking: prepare the data model for leases_db to cope
 with dynamic path renames.

interface leases_db
{
        typedef [public] struct {
                GUID client_guid;
                smb2_lease_key lease_key;
        } leases_db_key;

        typedef [public] struct {
                file_id id;
                [string,charset(UTF8)] char *servicepath;
                [string,charset(UTF8)] char *base_name;
                [string,charset(UTF8)] char *stream_name;
        } leases_db_file;

        typedef [public] struct {
                uint32 num_files;
                [size_is(num_files)] leases_db_file files[];
        } leases_db_value;
}

As designed by metze.

Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 source3/librpc/idl/leases_db.idl | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/source3/librpc/idl/leases_db.idl b/source3/librpc/idl/leases_db.idl
index 2ab1591..bdb875d 100644
--- a/source3/librpc/idl/leases_db.idl
+++ b/source3/librpc/idl/leases_db.idl
@@ -15,6 +15,13 @@ interface leases_db
 	} leases_db_key;
 
 	typedef [public] struct {
+		file_id id;
+		[string,charset(UTF8)] char *servicepath;
+		[string,charset(UTF8)] char *base_name;
+		[string,charset(UTF8)] char *stream_name;
+	} leases_db_file;
+
+	typedef [public] struct {
 		uint32 num_file_ids;
 		[size_is(num_file_ids)] file_id ids[];
 		[string,charset(UTF8)] char *filename;
-- 
1.9.1


From fefc18e421f7ec5836409e3751de53aaa59fb5c4 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 5 Dec 2014 12:57:24 -0800
Subject: [PATCH 3/5] s3:locking: Add new utility function
 leases_db_copy_file_ids()

Will be used by lease db parsers.

Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 source3/locking/leases_db.c | 20 ++++++++++++++++++++
 source3/locking/leases_db.h |  5 +++++
 2 files changed, 25 insertions(+)

diff --git a/source3/locking/leases_db.c b/source3/locking/leases_db.c
index 4cb38f0..ed4f09a 100644
--- a/source3/locking/leases_db.c
+++ b/source3/locking/leases_db.c
@@ -408,3 +408,23 @@ NTSTATUS leases_db_rename(const struct GUID *client_guid,
 				filename_new,
 				stream_name_new);
 }
+
+NTSTATUS leases_db_copy_file_ids(TALLOC_CTX *mem_ctx,
+			uint32_t num_files,
+			const struct leases_db_file *files,
+			struct file_id **pp_ids)
+{
+	uint32_t i;
+	struct file_id *ids = talloc_array(mem_ctx,
+				struct file_id,
+				num_files);
+	if (ids == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	for (i = 0; i < num_files; i++) {
+		ids[i] = files[i].id;
+	}
+	*pp_ids = ids;
+	return NT_STATUS_OK;
+}
diff --git a/source3/locking/leases_db.h b/source3/locking/leases_db.h
index f398863..0daa0ec 100644
--- a/source3/locking/leases_db.h
+++ b/source3/locking/leases_db.h
@@ -24,6 +24,7 @@
 struct GUID;
 struct smb2_lease_key;
 struct file_id;
+struct leases_db_file;
 
 bool leases_db_init(bool read_only);
 NTSTATUS leases_db_add(const struct GUID *client_guid,
@@ -48,4 +49,8 @@ NTSTATUS leases_db_rename(const struct GUID *client_guid,
 			const char *servicepath_new,
 			const char *filename_new,
 			const char *stream_name_new);
+NTSTATUS leases_db_copy_file_ids(TALLOC_CTX *mem_ctx,
+			uint32_t num_files,
+			const struct leases_db_file *files,
+			struct file_id **pp_ids);
 #endif /* _LEASES_DB_H_ */
-- 
1.9.1


From 1b989bf6de26036f6ecb4ebf7c223ed03ea0b5ff Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 5 Dec 2014 12:58:39 -0800
Subject: [PATCH 4/5] s3:locking: pass down servicepath to leases_db_add()

Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 source3/locking/leases_db.c | 2 ++
 source3/locking/leases_db.h | 1 +
 source3/smbd/open.c         | 7 +++++--
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/source3/locking/leases_db.c b/source3/locking/leases_db.c
index ed4f09a..a9e2566 100644
--- a/source3/locking/leases_db.c
+++ b/source3/locking/leases_db.c
@@ -85,6 +85,7 @@ static bool leases_db_key(TALLOC_CTX *mem_ctx,
 NTSTATUS leases_db_add(const struct GUID *client_guid,
 		       const struct smb2_lease_key *lease_key,
 		       const struct file_id *id,
+		       const char *servicepath,
 		       const char *filename,
 		       const char *stream_name)
 {
@@ -405,6 +406,7 @@ NTSTATUS leases_db_rename(const struct GUID *client_guid,
 	return leases_db_add(client_guid,
 				lease_key,
 				id,
+				servicename_new,
 				filename_new,
 				stream_name_new);
 }
diff --git a/source3/locking/leases_db.h b/source3/locking/leases_db.h
index 0daa0ec..20ec522 100644
--- a/source3/locking/leases_db.h
+++ b/source3/locking/leases_db.h
@@ -30,6 +30,7 @@ bool leases_db_init(bool read_only);
 NTSTATUS leases_db_add(const struct GUID *client_guid,
 		       const struct smb2_lease_key *lease_key,
 		       const struct file_id *id,
+		       const char *servicepath,
 		       const char *filename,
 		       const char *stream_name);
 NTSTATUS leases_db_del(const struct GUID *client_guid,
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 8f19a36..c1a8ee0 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -1677,8 +1677,11 @@ static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
 		.epoch = fsp->lease->lease.lease_epoch,
 	};
 
-	status = leases_db_add(client_guid, &lease->lease_key,
-			       &fsp->file_id, fsp->fsp_name->base_name,
+	status = leases_db_add(client_guid,
+			       &lease->lease_key,
+			       &fsp->file_id,
+			       fsp->conn->connectpath,
+			       fsp->fsp_name->base_name,
 			       fsp->fsp_name->stream_name);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__,
-- 
1.9.1


From 50406161cb17cfad6709ee57c517fd86ce4f40ad Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 5 Dec 2014 12:47:52 -0800
Subject: [PATCH 5/5] s3:locking: Change the data model for leases_db to cope
 with dynamic path renames.

interface leases_db
{
        typedef [public] struct {
                GUID client_guid;
                smb2_lease_key lease_key;
        } leases_db_key;

        typedef [public] struct {
                file_id id;
                [string,charset(UTF8)] char *servicepath;
                [string,charset(UTF8)] char *base_name;
                [string,charset(UTF8)] char *stream_name;
        } leases_db_file;

        typedef [public] struct {
                uint32 num_files;
                [size_is(num_files)] leases_db_file files[];
        } leases_db_value;
}

As designed by metze.

Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 source3/librpc/idl/leases_db.idl |   6 +-
 source3/locking/leases_db.c      |  62 +++++++++--------
 source3/locking/leases_db.h      |   6 +-
 source3/smbd/open.c              | 144 +++++++++++++++++++++++++++++++--------
 source3/smbd/smb2_break.c        |  16 ++---
 5 files changed, 161 insertions(+), 73 deletions(-)

diff --git a/source3/librpc/idl/leases_db.idl b/source3/librpc/idl/leases_db.idl
index bdb875d..d021875 100644
--- a/source3/librpc/idl/leases_db.idl
+++ b/source3/librpc/idl/leases_db.idl
@@ -22,9 +22,7 @@ interface leases_db
 	} leases_db_file;
 
 	typedef [public] struct {
-		uint32 num_file_ids;
-		[size_is(num_file_ids)] file_id ids[];
-		[string,charset(UTF8)] char *filename;
-		[string,charset(UTF8)] char *stream_name;
+		uint32 num_files;
+		[size_is(num_files)] leases_db_file files[];
 	} leases_db_value;
 }
diff --git a/source3/locking/leases_db.c b/source3/locking/leases_db.c
index a9e2566..0700ba9 100644
--- a/source3/locking/leases_db.c
+++ b/source3/locking/leases_db.c
@@ -86,7 +86,7 @@ NTSTATUS leases_db_add(const struct GUID *client_guid,
 		       const struct smb2_lease_key *lease_key,
 		       const struct file_id *id,
 		       const char *servicepath,
-		       const char *filename,
+		       const char *base_name,
 		       const char *stream_name)
 {
 	TDB_DATA db_key, db_value;
@@ -95,6 +95,7 @@ NTSTATUS leases_db_add(const struct GUID *client_guid,
 	NTSTATUS status;
 	bool ok;
 	struct leases_db_value new_value;
+	struct leases_db_file new_file;
 	struct leases_db_value *value = NULL;
 	enum ndr_err_code ndr_err;
 
@@ -140,31 +141,40 @@ NTSTATUS leases_db_add(const struct GUID *client_guid,
 		}
 
 		/* id must be unique. */
-		for (i = 0; i < value->num_file_ids; i++) {
-			if (file_id_equal(id, &value->ids[i])) {
+		for (i = 0; i < value->num_files; i++) {
+			if (file_id_equal(id, &value->files[i].id)) {
 				status = NT_STATUS_OBJECT_NAME_COLLISION;
 				goto out;
 			}
 		}
 
-		value->ids = talloc_realloc(value, value->ids, struct file_id,
-					value->num_file_ids + 1);
-		if (value->ids == NULL) {
+		value->files = talloc_realloc(value, value->files,
+					struct leases_db_file,
+					value->num_files + 1);
+		if (value->files == NULL) {
 			status = NT_STATUS_NO_MEMORY;
 			goto out;
 		}
-		value->ids[value->num_file_ids] = *id;
-		value->num_file_ids += 1;
+		value->files[value->num_files].id = *id;
+		value->files[value->num_files].servicepath = servicepath;
+		value->files[value->num_files].base_name = base_name;
+		value->files[value->num_files].stream_name = stream_name;
+		value->num_files += 1;
 
 	} else {
 		DEBUG(10, ("%s: new record\n", __func__));
 
-		new_value = (struct leases_db_value) {
-			.num_file_ids = 1,
-			.ids = discard_const_p(struct file_id, id),
-			.filename = filename,
+		new_file = (struct leases_db_file) {
+			.id = *id,
+			.servicepath = servicepath,
+			.base_name = base_name,
 			.stream_name = stream_name,
 		};
+
+		new_value = (struct leases_db_value) {
+			.num_files = 1,
+			.files = &new_file,
+		};
 		value = &new_value;
 	}
 
@@ -253,21 +263,21 @@ NTSTATUS leases_db_del(const struct GUID *client_guid,
 	}
 
 	/* id must exist. */
-	for (i = 0; i < value->num_file_ids; i++) {
-		if (file_id_equal(id, &value->ids[i])) {
+	for (i = 0; i < value->num_files; i++) {
+		if (file_id_equal(id, &value->files[i].id)) {
 			break;
 		}
 	}
 
-	if (i == value->num_file_ids) {
+	if (i == value->num_files) {
 		status = NT_STATUS_NOT_FOUND;
 		goto out;
 	}
 
-	value->ids[i] = value->ids[value->num_file_ids-1];
-	value->num_file_ids -= 1;
+	value->files[i] = value->files[value->num_files-1];
+	value->num_files -= 1;
 
-	if (value->num_file_ids == 0) {
+	if (value->num_files == 0) {
 		DEBUG(10, ("%s: deleting record\n", __func__));
 		status = dbwrap_record_delete(rec);
 	} else {
@@ -304,9 +314,9 @@ NTSTATUS leases_db_del(const struct GUID *client_guid,
 }
 
 struct leases_db_fetch_state {
-	void (*parser)(uint32_t num_file_ids,
-			struct file_id *ids, const char *filename,
-			const char *stream_name, void *private_data);
+	void (*parser)(uint32_t num_files,
+			const struct leases_db_file *files,
+			void *private_data);
 	void *private_data;
 	NTSTATUS status;
 };
@@ -341,8 +351,8 @@ static void leases_db_parser(TDB_DATA key, TDB_DATA data, void *private_data)
 		NDR_PRINT_DEBUG(leases_db_value, value);
 	}
 
-	state->parser(value->num_file_ids,
-			value->ids, value->filename, value->stream_name,
+	state->parser(value->num_files,
+			value->files,
 			state->private_data);
 
 	TALLOC_FREE(value);
@@ -351,10 +361,8 @@ static void leases_db_parser(TDB_DATA key, TDB_DATA data, void *private_data)
 
 NTSTATUS leases_db_parse(const struct GUID *client_guid,
 			 const struct smb2_lease_key *lease_key,
-			 void (*parser)(uint32_t num_file_ids,
-					struct file_id *ids,
-					const char *filename,
-					const char *stream_name,
+			 void (*parser)(uint32_t num_files,
+					const struct leases_db_file *files,
 					void *private_data),
 			 void *private_data)
 {
diff --git a/source3/locking/leases_db.h b/source3/locking/leases_db.h
index 20ec522..383575a 100644
--- a/source3/locking/leases_db.h
+++ b/source3/locking/leases_db.h
@@ -38,10 +38,8 @@ NTSTATUS leases_db_del(const struct GUID *client_guid,
 		       const struct file_id *id);
 NTSTATUS leases_db_parse(const struct GUID *client_guid,
 			 const struct smb2_lease_key *lease_key,
-			 void (*parser)(uint32_t num_file_ids,
-					struct file_id *ids,
-					const char *filename,
-					const char *stream_name,
+			 void (*parser)(uint32_t num_files,
+					const struct leases_db_file *files,
 					void *private_data),
 			 void *private_data);
 NTSTATUS leases_db_rename(const struct GUID *client_guid,
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index c1a8ee0..06770e0 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -36,6 +36,7 @@
 #include "messages.h"
 #include "source3/lib/dbwrap/dbwrap_watch.h"
 #include "locking/leases_db.h"
+#include "librpc/gen_ndr/ndr_leases_db.h"
 
 extern const struct generic_mapping file_generic_mapping;
 
@@ -4127,8 +4128,10 @@ static NTSTATUS inherit_new_acl(files_struct *fsp)
  * used for a different file name.
  */
 
-struct lease_fname_match_state {
+struct lease_match_state {
 	/* Input parameters. */
+	TALLOC_CTX *mem_ctx;
+	const char *servicepath;
 	const struct smb_filename *fname;
 	bool file_existed;
 	struct file_id id;
@@ -4138,57 +4141,139 @@ struct lease_fname_match_state {
 	NTSTATUS match_status;
 };
 
-static void lease_fname_match_parser(
-	uint32_t num_file_ids,
-	struct file_id *ids, const char *filename, const char *stream_name,
+/*************************************************************
+ File doesn't exist but this lease key+guid is already in use.
+
+ This is only allowable in the dynamic share case where the
+ service path must be different.
+
+ There is a small race condition here in the multi-connection
+ case where a client sends two create calls on different connections,
+ where the file doesn't exist and one smbd creates the leases_db
+ entry first, but this will get fixed by the multichannel cleanup
+ when all identical client_guids get handled by a single smbd.
+**************************************************************/
+
+static void lease_match_parser_new_file(
+	uint32_t num_files,
+	const struct leases_db_file *files,
+	struct lease_match_state *state)
+{
+	uint32_t i;
+
+	for (i = 0; i < num_files; i++) {
+		const struct leases_db_file *f = &files[i];
+		if (strequal(state->servicepath, f->servicepath)) {
+			state->match_status = NT_STATUS_INVALID_PARAMETER;
+			return;
+		}
+	}
+
+	/* Dynamic share case. Break leases on all other files. */
+	state->match_status = leases_db_copy_file_ids(state->mem_ctx,
+					num_files,
+					files,
+					&state->ids);
+	if (!NT_STATUS_IS_OK(state->match_status)) {
+		return;
+	}
+
+	state->num_file_ids = num_files;
+	state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
+	return;
+}
+
+static void lease_match_parser(
+	uint32_t num_files,
+	const struct leases_db_file *files,
 	void *private_data)
 {
-	struct lease_fname_match_state *state =
-		(struct lease_fname_match_state *)private_data;
+	struct lease_match_state *state =
+		(struct lease_match_state *)private_data;
+	uint32_t i;
 
-	if (!strequal(filename, state->fname->base_name) ||
-	    !strequal(stream_name, state->fname->stream_name))
-	{
-		/* Names don't match lease key. */
-		state->match_status = NT_STATUS_INVALID_PARAMETER;
+	if (!state->file_existed) {
+		/*
+		 * Deal with name mismatch or
+		 * possible dynamic share case separately
+		 * to make code clearer.
+		 */
+		lease_match_parser_new_file(num_files,
+						files,
+						state);
 		return;
 	}
 
-	if (state->file_existed &&
-	    num_file_ids == 1 &&
-	    file_id_equal(&ids[0],&state->id))
-	{
-		/* Common case - non-dynamic share. We're ok.. */
-		state->match_status = NT_STATUS_OK;
+	/* File existed. */
+	state->match_status = NT_STATUS_OK;
+
+	for (i = 0; i < num_files; i++) {
+		const struct leases_db_file *f = &files[i];
+
+		/* Everything should be the same. */
+		if (!file_id_equal(&state->id, &f->id)) {
+			/* This should catch all dynamic share cases. */
+			state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
+			break;
+		}
+		if (!strequal(f->servicepath, state->servicepath)) {
+			state->match_status = NT_STATUS_INVALID_PARAMETER;
+			break;
+		}
+		if (!strequal(f->base_name, state->fname->base_name)) {
+			state->match_status = NT_STATUS_INVALID_PARAMETER;
+			break;
+		}
+		if (!strequal(f->stream_name, state->fname->stream_name)) {
+			state->match_status = NT_STATUS_INVALID_PARAMETER;
+			break;
+		}
+	}
+
+	if (NT_STATUS_IS_OK(state->match_status)) {
+		/*
+		 * Common case - just opening another handle on a
+		 * file on a non-dynamic share.
+		 */
+		return;
+	}
+
+	if (NT_STATUS_EQUAL(state->match_status, NT_STATUS_INVALID_PARAMETER)) {
+		/* Mismatched path. Error back to client. */
 		return;
 	}
 
 	/*
-	 * More than one file id, or not equal, or new file
-	 * being created and there's already an existing lease
-	 * on this (client_guid, lease id) pair.
+	 * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
 	 * Don't allow leases.
 	 */
 
-	state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
-	state->num_file_ids = num_file_ids;
-	state->ids = talloc_memdup(talloc_tos(),
-				ids,
-				num_file_ids * sizeof(struct file_id));
-	if (state->ids == NULL) {
-		state->match_status = NT_STATUS_NO_MEMORY;
+	state->match_status = leases_db_copy_file_ids(state->mem_ctx,
+					num_files,
+					files,
+					&state->ids);
+	if (!NT_STATUS_IS_OK(state->match_status)) {
+		return;
 	}
+
+	state->num_file_ids = num_files;
+	state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
+	return;
 }
 
 static NTSTATUS lease_match(connection_struct *conn,
 			    struct smb_request *req,
 			    struct smb2_lease_key *lease_key,
+			    const char *servicepath,
 			    const struct smb_filename *fname,
 			    uint16_t *p_version,
 			    uint16_t *p_epoch)
 {
 	struct smbd_server_connection *sconn = req->sconn;
-	struct lease_fname_match_state state = {
+	TALLOC_CTX *tos = talloc_tos();
+	struct lease_match_state state = {
+		.mem_ctx = tos,
+		.servicepath = servicepath,
 		.fname = fname,
 		.match_status = NT_STATUS_OK
 	};
@@ -4203,7 +4288,7 @@ static NTSTATUS lease_match(connection_struct *conn,
 	}
 
 	status = leases_db_parse(&sconn->client->connections->smb2.client.guid,
-				 lease_key, lease_fname_match_parser, &state);
+				 lease_key, lease_match_parser, &state);
 	if (!NT_STATUS_IS_OK(status)) {
 		/*
 		 * Not found or error means okay: We can make the lease pass
@@ -4356,6 +4441,7 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
 		status = lease_match(conn,
 				req,
 				&lease->lease_key,
+				conn->connectpath,
 				smb_fname,
 				&version,
 				&epoch);
diff --git a/source3/smbd/smb2_break.c b/source3/smbd/smb2_break.c
index 126bf78..5eab0a1 100644
--- a/source3/smbd/smb2_break.c
+++ b/source3/smbd/smb2_break.c
@@ -340,21 +340,19 @@ struct lease_lookup_state {
 };
 
 static void lease_parser(
-	uint32_t num_file_ids,
-	struct file_id *ids, const char *filename, const char *stream_name,
+	uint32_t num_files,
+	const struct leases_db_file *files,
 	void *private_data)
 {
 	struct lease_lookup_state *lls =
 		(struct lease_lookup_state *)private_data;
 
 	lls->status = NT_STATUS_OK;
-	lls->num_file_ids = num_file_ids;
-	lls->ids = talloc_memdup(lls->mem_ctx,
-				ids,
-				num_file_ids * sizeof(struct file_id));
-	if (lls->ids == NULL) {
-		lls->status = NT_STATUS_NO_MEMORY;
-	}
+	lls->num_file_ids = num_files;
+	lls->status = leases_db_copy_file_ids(lls->mem_ctx,
+				num_files,
+				files,
+				&lls->ids);
 }
 
 static struct tevent_req *smbd_smb2_lease_break_send(
-- 
1.9.1

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: OpenPGP digital signature
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20141208/816ae979/attachment.pgp>


More information about the samba-technical mailing list