diff options
Diffstat (limited to 'source3/smbd/server.c')
-rw-r--r-- | source3/smbd/server.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 15258e02ea..bf66e1ca4b 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -3630,16 +3630,35 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de ****************************************************************************/ int find_free_file(void ) { - int i; - /* returning a file handle of 0 is a bad idea - so we start at 1 */ - for (i=1;i<MAX_OPEN_FILES;i++) - if (!Files[i].open) { - /* paranoia */ - memset(&Files[i], 0, sizeof(Files[i])); - return(i); - } - DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n")); - return(-1); + int i; + static int first_file; + + /* we want to give out file handles differently on each new + connection because of a common bug in MS clients where they try to + reuse a file descriptor from an earlier smb connection. This code + increases the chance that the errant client will get an error rather + than causing corruption */ + if (first_file == 0) { + first_file = (getpid() ^ (int)time(NULL)) % MAX_OPEN_FILES; + if (first_file == 0) first_file = 1; + } + + for (i=first_file;i<MAX_OPEN_FILES;i++) + if (!Files[i].open) { + memset(&Files[i], 0, sizeof(Files[i])); + return(i); + } + + /* returning a file handle of 0 is a bad idea - so we start at 1 */ + for (i=1;i<first_file;i++) + if (!Files[i].open) { + memset(&Files[i], 0, sizeof(Files[i])); + return(i); + } + + + DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n")); + return(-1); } /**************************************************************************** |