summaryrefslogtreecommitdiffstats
path: root/source/smbd/reply.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2000-04-22 00:33:16 +0000
committerJeremy Allison <jra@samba.org>2000-04-22 00:33:16 +0000
commitab0ecc39d688f16b9692fe90b991f0b89287070a (patch)
treeb269641c3f2fe3fd92b53412160b83984e4e4877 /source/smbd/reply.c
parent763704f78fc44976b2d977e8a08ffdeb727903c4 (diff)
downloadsamba-ab0ecc39d688f16b9692fe90b991f0b89287070a.tar.gz
samba-ab0ecc39d688f16b9692fe90b991f0b89287070a.tar.xz
samba-ab0ecc39d688f16b9692fe90b991f0b89287070a.zip
This is a *big* checkin that may break some things, but implements the
new open mechanism Andrew & I discussed. config.sub: configure: Included the QNX patch. include/vfs.h: smbd/vfs-wrap.c: smbd/vfs.c: Added ftruncate vfs call (needed). Note that we will also need locking calls in the vfs (to be added). lib/util_unistr.c: nmbd/nmbd_processlogon.c: Fix for NT domain logons causing nmbd to core dump. Also fix for sidsize DOS bug. locking/locking.c: Check value of ret before using it for memdup. printing/printing.c: Convert print_fsp_open to return an allocated fsp. rpc_server/srv_lsa.c: Fix for NT domain logons. I have removed all use of lp_share_modes() from the code (although I left the parameter in the table for backwards compatibility). It no longer makes sense for this to exist. smbd/close.c: Removed lp_share_modes(). smbd/fileio.c: Fixed parameters to unlock_share_entry call in panic code. smbd/files.c: Correctly set the unix_ERR_code to ERRnofids on fsp allocation fail. smbd/nttrans.c: smbd/reply.c: smbd/trans2.c: Changed all occurrences of open_file_shared/open_directory/ open_file_stat to return an fsp from the call. smbd/open.c: Changed all occurrences of open_file_shared/open_directory/ open_file_stat to return an fsp from the call. In addition I have fixed a long standing race condition in the deny mode processing w.r.t. two smbd's creating a file. Andrew, please note that your original idea of using open with O_EXCL in this case would not work (I went over the races very carefully) and so we must re-check deny modes *after* the open() call returns. This is because there is a race between the open with O_EXCL and the lock of the share mode entry. Imagine the case where the first smbd does the open with O_EXCL and a deny mode of DENY_ALL, but is pre-empted before it locks the share modes and creates the deny mode entry for DENY_ALL. A second smbd could then come in with O_RDONLY and a deny mode of DENY_NONE and the two opens would be allowed. The *only* way to fix this race is to lock the share modes after the open and then do the deny mode checks *after* this lock in the case where the file did not originally exist. This code will need extensive testing but seems to initially work. Jeremy.
Diffstat (limited to 'source/smbd/reply.c')
-rw-r--r--source/smbd/reply.c64
1 files changed, 14 insertions, 50 deletions
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index e998e1741c0..3acfd988d63 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -1545,23 +1545,18 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
unix_convert(fname,conn,0,&bad_path,NULL);
- fsp = file_new();
- if (!fsp)
- return(ERROR(ERRSRV,ERRnofids));
-
unixmode = unix_mode(conn,aARCH,fname);
- open_file_shared(fsp,conn,fname,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
+ fsp = open_file_shared(conn,fname,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
unixmode, oplock_request,&rmode,NULL);
- if (!fsp->open)
+ if (!fsp)
{
if((errno == ENOENT) && bad_path)
{
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
- file_free(fsp);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1639,23 +1634,18 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
unix_convert(fname,conn,0,&bad_path,NULL);
- fsp = file_new();
- if (!fsp)
- return(ERROR(ERRSRV,ERRnofids));
-
unixmode = unix_mode(conn,smb_attr | aARCH, fname);
- open_file_shared(fsp,conn,fname,smb_mode,smb_ofun,unixmode,
+ fsp = open_file_shared(conn,fname,smb_mode,smb_ofun,unixmode,
oplock_request, &rmode,&smb_action);
- if (!fsp->open)
+ if (!fsp)
{
if((errno == ENOENT) && bad_path)
{
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
- file_free(fsp);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1772,10 +1762,6 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
unixmode = unix_mode(conn,createmode,fname);
- fsp = file_new();
- if (!fsp)
- return(ERROR(ERRSRV,ERRnofids));
-
if(com == SMBmknew)
{
/* We should fail if file exists. */
@@ -1788,17 +1774,16 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
}
/* Open file in dos compatibility share mode. */
- open_file_shared(fsp,conn,fname,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
+ fsp = open_file_shared(conn,fname,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
ofun, unixmode, oplock_request, NULL, NULL);
- if (!fsp->open)
+ if (!fsp)
{
if((errno == ENOENT) && bad_path)
{
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
- file_free(fsp);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1844,25 +1829,20 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
unixmode = unix_mode(conn,createmode,fname);
- fsp = file_new();
- if (fsp)
- return(ERROR(ERRSRV,ERRnofids));
-
pstrcpy(fname2,(char *)smbd_mktemp(fname));
/* Open file in dos compatibility share mode. */
/* We should fail if file exists. */
- open_file_shared(fsp,conn,fname2,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
+ fsp = open_file_shared(conn,fname2,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
(FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL), unixmode, oplock_request, NULL, NULL);
- if (!fsp->open)
+ if (!fsp)
{
if((errno == ENOENT) && bad_path)
{
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
- file_free(fsp);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -3025,15 +3005,10 @@ int reply_printopen(connection_struct *conn,
if (!CAN_PRINT(conn))
return(ERROR(ERRDOS,ERRnoaccess));
- fsp = file_new();
- if (!fsp)
- return(ERROR(ERRSRV,ERRnofids));
-
/* Open for exclusive use, write only. */
- print_fsp_open(fsp,conn,"dos.prn");
+ fsp = print_fsp_open(conn,"dos.prn");
- if (!fsp->open) {
- file_free(fsp);
+ if (!fsp) {
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -3745,32 +3720,21 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
if (!vfs_file_exist(conn,src,&st))
return(False);
- fsp1 = file_new();
- if (!fsp1)
- return(False);
-
- open_file_shared(fsp1,conn,src,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
+ fsp1 = open_file_shared(conn,src,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),0,0,&Access,&action);
- if (!fsp1->open) {
- file_free(fsp1);
+ if (!fsp1) {
return(False);
}
if (!target_is_directory && count)
ofun = 1;
- fsp2 = file_new();
- if (!fsp2) {
- close_file(fsp1,False);
- return(False);
- }
- open_file_shared(fsp2,conn,dest,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
+ fsp2 = open_file_shared(conn,dest,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
ofun,st.st_mode,0,&Access,&action);
- if (!fsp2->open) {
+ if (!fsp2) {
close_file(fsp1,False);
- file_free(fsp2);
return(False);
}