diff options
author | Stefan Metzmacher <metze@samba.org> | 2012-06-13 12:11:51 +0200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2012-06-14 18:13:31 +0200 |
commit | c7c351b8171ee5536090a04b61fb1566a6092af5 (patch) | |
tree | 38e73d7f8200ab850187f4ed262c28c28ab72577 /source3 | |
parent | 2fd28dc4cf4f40a690adfd846911e4da1a776bf2 (diff) | |
download | samba-c7c351b8171ee5536090a04b61fb1566a6092af5.tar.gz samba-c7c351b8171ee5536090a04b61fb1566a6092af5.tar.bz2 samba-c7c351b8171ee5536090a04b61fb1566a6092af5.zip |
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
Diffstat (limited to 'source3')
-rw-r--r-- | source3/smbd/files.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/source3/smbd/files.c b/source3/smbd/files.c index 97db348a01..fb9dacce99 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; } @@ -315,6 +329,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) && |