[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Thu Jun 14 14:05:05 MDT 2012


The branch, master has been updated
       via  3f110e5 s3:smbd: use fsp_persistent_id() as persistent_file_id part for SMB2 (bug #8995)
       via  47f837c s3:smbd: add a fsp_persistent_id() function
       via  5662166 s3:smbd: only set fsp->fh->gen_id for a client connection
       via  c7c351b s3:smbd: try to make fsp->fh->gen_id as globally unique as possible
      from  2fd28dc s3: Simplify tdb_data_is_cstr a bit

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


- Log -----------------------------------------------------------------
commit 3f110e50bfdbaf6958c12098e06ef599341d7e3b
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Jun 13 12:13:01 2012 +0200

    s3:smbd: use fsp_persistent_id() as persistent_file_id part for SMB2 (bug #8995)
    
    It seems to be important to have unique persistent file ids,
    because windows clients seem to index files by server_guid + persistent_file_id.
    Which may break, if we just have a 16-bit range per connection
    and the client connects multiple times.
    
    Based on code from Ira Cooper. Use fsp->fh->gen_id as the persistent
    fileid in SMB2.
    
    metze
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Thu Jun 14 22:04:13 CEST 2012 on sn-devel-104

commit 47f837c105ee7b70b7e80e41772b7c9470bbe153
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jun 14 10:32:43 2012 +0200

    s3:smbd: add a fsp_persistent_id() function
    
    This calculates a 64-bit value that most likely uniquely identifies
    the files_struct globally to the server.
    
    * 32-bit random gen_id
    * 16-bit truncated open_time
    * 16-bit fnum (valatile_id)
    
    Based on code from Ira Cooper. Use fsp->fh->gen_id as the persistent
    fileid in SMB2.
    
    Pair-Programmed-With: Michael Adam <obnox at samba.org>
    
    metze

commit 5662166b231f64ba2003f917057b8ffb8886b8bc
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Jun 13 15:40:23 2012 +0200

    s3:smbd: only set fsp->fh->gen_id for a client connection
    
    For faked connections, like dfs and printing, we leave it as 0.
    
    metze

commit c7c351b8171ee5536090a04b61fb1566a6092af5
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Jun 13 12:11:51 2012 +0200

    s3:smbd: try to make fsp->fh->gen_id as globally unique as possible
    
    This makes sure the value is never 0, it's between 1 and UINT32_MAX.
    
    While fsp->fh->gen_id is 'unsigned long' currently (which might by 8 bytes),
    there's some oplock code which truncates it to uint32_t (using IVAL()).
    
    Which means we could reuse fsp->fh->gen_id as persistent file id
    until we have a final fix, which uses database.
    
    See bug #8995 for more details.
    
    Based on code from Ira Cooper. Ensure fsp->fh->gen_id starts from
    a random point. We will use this as the SMB2 persistent_id.
    
    metze

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

Summary of changes:
 source3/smbd/files.c       |   57 +++++++++++++++++++++++++++++++++++++++----
 source3/smbd/proto.h       |    1 +
 source3/smbd/smb2_break.c  |    3 +-
 source3/smbd/smb2_create.c |    2 +-
 4 files changed, 55 insertions(+), 8 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index 97db348..d410083 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -28,12 +28,26 @@
 #define FILE_HANDLE_OFFSET 0x1000
 
 /****************************************************************************
- Return a unique number identifying this fsp over the life of this pid.
+ Return a unique number identifying this fsp over the life of this pid,
+ and try to make it as globally unique as possible.
+ See bug #8995 for the details.
 ****************************************************************************/
 
 static unsigned long get_gen_count(struct smbd_server_connection *sconn)
 {
+	/*
+	 * While fsp->fh->gen_id is 'unsigned long' currently
+	 * (which might by 8 bytes),
+	 * there's some oplock code which truncates it to
+	 * uint32_t(using IVAL()).
+	 */
+	if (sconn->file_gen_counter == 0) {
+		sconn->file_gen_counter = generate_random();
+	}
 	sconn->file_gen_counter += 1;
+	if (sconn->file_gen_counter >= UINT32_MAX) {
+		sconn->file_gen_counter = 0;
+	}
 	if (sconn->file_gen_counter == 0) {
 		sconn->file_gen_counter += 1;
 	}
@@ -105,7 +119,6 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn,
 
 	fsp->fnum = -1;
 	fsp->conn = conn;
-	fsp->fh->gen_id = get_gen_count(sconn);
 	GetTimeOfDay(&fsp->open_time);
 
 	if (sconn->file_bmap != NULL) {
@@ -115,6 +128,8 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn,
 
 		fsp->fnum = i + FILE_HANDLE_OFFSET;
 		SMB_ASSERT(fsp->fnum < 65536);
+
+		fsp->fh->gen_id = get_gen_count(sconn);
 	}
 
 	DLIST_ADD(sconn->files, fsp);
@@ -315,6 +330,10 @@ files_struct *file_find_dif(struct smbd_server_connection *sconn,
 	int count=0;
 	files_struct *fsp;
 
+	if (gen_id == 0) {
+		return NULL;
+	}
+
 	for (fsp=sconn->files; fsp; fsp=fsp->next,count++) {
 		/* We can have a fsp->fh->fd == -1 here as it could be a stat open. */
 		if (file_id_equal(&fsp->file_id, &id) &&
@@ -578,20 +597,41 @@ files_struct *file_fsp(struct smb_request *req, uint16 fid)
 	return fsp;
 }
 
+uint64_t fsp_persistent_id(const struct files_struct *fsp)
+{
+	uint64_t persistent_id;
+
+	/*
+	 * This calculates a number that is most likely
+	 * globally unique. In future we will have a database
+	 * to make it completely unique.
+	 *
+	 * 32-bit random gen_id
+	 * 16-bit truncated open_time
+	 * 16-bit fnum (valatile_id)
+	 */
+	persistent_id = fsp->fh->gen_id & UINT32_MAX;
+	persistent_id <<= 16;
+	persistent_id &= 0x0000FFFFFFFF0000LLU;
+	persistent_id |= fsp->open_time.tv_usec & UINT16_MAX;
+	persistent_id <<= 16;
+	persistent_id &= 0xFFFFFFFFFFFF0000LLU;
+	persistent_id |= fsp->fnum & UINT16_MAX;
+
+	return persistent_id;
+}
+
 struct files_struct *file_fsp_smb2(struct smbd_smb2_request *smb2req,
 				   uint64_t persistent_id,
 				   uint64_t volatile_id)
 {
 	struct files_struct *fsp;
+	uint64_t fsp_persistent;
 
 	if (smb2req->compat_chain_fsp != NULL) {
 		return smb2req->compat_chain_fsp;
 	}
 
-	if (persistent_id != volatile_id) {
-		return NULL;
-	}
-
 	if (volatile_id > UINT16_MAX) {
 		return NULL;
 	}
@@ -600,6 +640,11 @@ struct files_struct *file_fsp_smb2(struct smbd_smb2_request *smb2req,
 	if (fsp == NULL) {
 		return NULL;
 	}
+	fsp_persistent = fsp_persistent_id(fsp);
+
+	if (persistent_id != fsp_persistent) {
+		return NULL;
+	}
 
 	if (smb2req->tcon == NULL) {
 		return NULL;
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index e7bc3eb..53d9e2d 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -387,6 +387,7 @@ bool file_find_subpath(files_struct *dir_fsp);
 void file_sync_all(connection_struct *conn);
 void file_free(struct smb_request *req, files_struct *fsp);
 files_struct *file_fsp(struct smb_request *req, uint16 fid);
+uint64_t fsp_persistent_id(const struct files_struct *fsp);
 struct files_struct *file_fsp_smb2(struct smbd_smb2_request *smb2req,
 				   uint64_t persistent_id,
 				   uint64_t volatile_id);
diff --git a/source3/smbd/smb2_break.c b/source3/smbd/smb2_break.c
index 75505e5..9318068 100644
--- a/source3/smbd/smb2_break.c
+++ b/source3/smbd/smb2_break.c
@@ -237,6 +237,7 @@ void send_break_message_smb2(files_struct *fsp, int level)
 				SMB2_OPLOCK_LEVEL_II :
 				SMB2_OPLOCK_LEVEL_NONE;
 	NTSTATUS status;
+	uint64_t fsp_persistent = fsp_persistent_id(fsp);
 
 	DEBUG(10,("send_break_message_smb2: sending oplock break "
 		"for file %s, fnum = %d, smb2 level %u\n",
@@ -245,7 +246,7 @@ void send_break_message_smb2(files_struct *fsp, int level)
 		(unsigned int)smb2_oplock_level ));
 
 	status = smbd_smb2_send_oplock_break(fsp->conn->sconn,
-					(uint64_t)fsp->fnum,
+					fsp_persistent,
 					(uint64_t)fsp->fnum,
 					smb2_oplock_level);
 	if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index 2aedfb6..9881ed2 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -822,7 +822,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 	if (state->out_file_attributes == 0) {
 		state->out_file_attributes = FILE_ATTRIBUTE_NORMAL;
 	}
-	state->out_file_id_persistent = result->fnum;
+	state->out_file_id_persistent = fsp_persistent_id(result);
 	state->out_file_id_volatile = result->fnum;
 	state->out_context_blobs = out_context_blobs;
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list