summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>1998-01-12 00:27:52 +0000
committerAndrew Tridgell <tridge@samba.org>1998-01-12 00:27:52 +0000
commit6b41bab79dc44ed63c0f22978f519d7ed353d5c3 (patch)
tree8fcbfda8d4b56d53d7b013b7481a5763828fcd88
parentd72183bda7bcb2204ad0ac1c387bdbf09cbe44dd (diff)
downloadsamba-6b41bab79dc44ed63c0f22978f519d7ed353d5c3.tar.gz
samba-6b41bab79dc44ed63c0f22978f519d7ed353d5c3.tar.xz
samba-6b41bab79dc44ed63c0f22978f519d7ed353d5c3.zip
(applying fix to 1.9.18)
this is a proper fix for the find_free_file/oplock bug. Files[] elements are now marked reserved while the open is taking place and find_free_file() does not allow a reserved file to be opened The reservation is removed if the open fails or in close_file()
-rw-r--r--source/include/smb.h1
-rw-r--r--source/smbd/reply.c26
-rw-r--r--source/smbd/server.c16
-rw-r--r--source/smbd/trans2.c2
4 files changed, 34 insertions, 11 deletions
diff --git a/source/include/smb.h b/source/include/smb.h
index ebf0945855e..e6c0565b056 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -1443,6 +1443,7 @@ typedef struct
BOOL modified;
BOOL granted_oplock;
BOOL sent_oplock_break;
+ BOOL reserved;
char *name;
} files_struct;
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index c903c7a1fd2..7194f3b1446 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -1191,6 +1191,7 @@ int reply_open(char *inbuf,char *outbuf)
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1208,6 +1209,7 @@ int reply_open(char *inbuf,char *outbuf)
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1291,6 +1293,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1308,6 +1311,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1437,6 +1441,7 @@ int reply_mknew(char *inbuf,char *outbuf)
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1464,6 +1469,7 @@ int reply_mknew(char *inbuf,char *outbuf)
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1519,6 +1525,7 @@ int reply_ctemp(char *inbuf,char *outbuf)
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1538,6 +1545,7 @@ int reply_ctemp(char *inbuf,char *outbuf)
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -2572,15 +2580,19 @@ int reply_printopen(char *inbuf,char *outbuf)
strcpy(fname2,(char *)mktemp(fname));
- if (!check_name(fname2,cnum))
- return(ERROR(ERRDOS,ERRnoaccess));
+ if (!check_name(fname2,cnum)) {
+ Files[fnum].reserved = False;
+ return(ERROR(ERRDOS,ERRnoaccess));
+ }
/* Open for exclusive use, write only. */
open_file_shared(fnum,cnum,fname2,(DENY_ALL<<4)|1, 0x12, unix_mode(cnum,0),
0, NULL, NULL);
- if (!Files[fnum].open)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
+ if (!Files[fnum].open) {
+ Files[fnum].reserved = False;
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
/* force it to be a print file */
Files[fnum].print_file = True;
@@ -3250,7 +3262,10 @@ static BOOL copy_file(char *src,char *dest1,int cnum,int ofun,
open_file_shared(fnum1,cnum,src,(DENY_NONE<<4),
1,0,0,&Access,&action);
- if (!Files[fnum1].open) return(False);
+ if (!Files[fnum1].open) {
+ Files[fnum1].reserved = False;
+ return(False);
+ }
if (!target_is_directory && count)
ofun = 1;
@@ -3265,6 +3280,7 @@ static BOOL copy_file(char *src,char *dest1,int cnum,int ofun,
if (!Files[fnum2].open) {
close_file(fnum1,False);
+ Files[fnum2].reserved = False;
return(False);
}
diff --git a/source/smbd/server.c b/source/smbd/server.c
index 82e163fadd4..1b4f6f35d0f 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -1466,6 +1466,8 @@ void close_file(int fnum, BOOL normal_close)
uint32 inode = fs_p->fd_ptr->inode;
int token;
+ Files[fnum].reserved = False;
+
#if USE_READ_PREDICTION
invalidate_read_prediction(fs_p->fd_ptr->fd);
#endif
@@ -3671,21 +3673,23 @@ int find_free_file(void )
if (first_file == 0) first_file = 1;
}
- if (first_file == MAX_OPEN_FILES)
- first_file = 0;
+ if (first_file >= MAX_OPEN_FILES)
+ first_file = 1;
for (i=first_file;i<MAX_OPEN_FILES;i++)
- if (!Files[i].open) {
+ if (!Files[i].open && !Files[i].reserved) {
memset(&Files[i], 0, sizeof(Files[i]));
- first_file++;
+ first_file = i+1;
+ Files[i].reserved = True;
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) {
+ if (!Files[i].open && !Files[i].reserved) {
memset(&Files[i], 0, sizeof(Files[i]));
- first_file++;
+ first_file = i+1;
+ Files[i].reserved = True;
return(i);
}
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index ce4a4500502..b52169a66b2 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -208,6 +208,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum,
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -224,6 +225,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum,
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}