From 8c1159461a0c5a948cd04cdf969e54e1fa83387e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 13 Jun 2012 12:11:51 +0200 Subject: [PATCH] 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 Signed-off-by: Jeremy Allison --- source3/smbd/files.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/source3/smbd/files.c b/source3/smbd/files.c index d222bafbd96..0018ceed5e5 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; } @@ -284,6 +298,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) && -- 2.34.1