summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/nttrans.c220
-rw-r--r--source3/smbd/reply.c140
-rw-r--r--source3/smbd/server.c169
-rw-r--r--source3/smbd/trans2.c20
4 files changed, 332 insertions, 217 deletions
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 9b6cfe1621..4e857c183c 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -424,10 +424,6 @@ int reply_ntcreate_and_X(char *inbuf,char *outbuf,int length,int bufsize)
files_struct *fsp;
char *p = NULL;
- /* If it's a request for a directory open, fail it. */
- if(flags & OPEN_DIRECTORY)
- return(ERROR(ERRDOS,ERRnoaccess));
-
/*
* We need to construct the open_and_X ofun value from the
* NT values, as that's what our code is structured to accept.
@@ -459,7 +455,7 @@ int reply_ntcreate_and_X(char *inbuf,char *outbuf,int length,int bufsize)
} else {
/*
- * Ordinary file.
+ * Ordinary file or directory.
*/
/*
@@ -495,66 +491,95 @@ int reply_ntcreate_and_X(char *inbuf,char *outbuf,int length,int bufsize)
oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
- /*
- * NB. We have a potential bug here. If we cause an oplock
- * break to ourselves, then we could end up processing filename
- * related SMB requests whilst we await the oplock break
- * response. As we may have changed the filename case
- * semantics to be POSIX-like, this could mean a filename
- * request could fail when it should succeed. This is a
- * rare condition, but eventually we must arrange to restore
- * the correct case semantics before issuing an oplock break
- * request to our client. JRA.
+ /*
+ * If it's a request for a directory open, deal with it separately.
*/
- open_file_shared(fnum,cnum,fname,smb_open_mode,smb_ofun,unixmode,
- oplock_request,&rmode,&smb_action);
+ if(flags & OPEN_DIRECTORY) {
+ oplock_request = 0;
- restore_case_semantics(file_attributes);
+ open_directory(fnum, cnum, fname, smb_ofun, unixmode, &smb_action);
+
+ restore_case_semantics(file_attributes);
+
+ if(!fsp->open) {
+ fsp->reserved = False;
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+ } else {
+
+ /*
+ * Ordinary file case.
+ */
- if (!fsp->open) {
/*
- * We cheat here. The only case we care about is a directory
- * rename, where the NT client will attempt to open the source
- * directory for DELETE access. Note that when the NT client
- * does this it does *not* set the directory bit in the
- * request packet. This is translated into a read/write open
- * request. POSIX states that any open for write request on a directory
- * will generate an EISDIR error, so we can catch this here and open
- * a pseudo handle that is flagged as a directory. JRA.
+ * NB. We have a potential bug here. If we cause an oplock
+ * break to ourselves, then we could end up processing filename
+ * related SMB requests whilst we await the oplock break
+ * response. As we may have changed the filename case
+ * semantics to be POSIX-like, this could mean a filename
+ * request could fail when it should succeed. This is a
+ * rare condition, but eventually we must arrange to restore
+ * the correct case semantics before issuing an oplock break
+ * request to our client. JRA.
*/
- if(errno == EISDIR) {
- oplock_request = 0;
- open_directory(fnum, cnum, fname, &smb_action);
+ open_file_shared(fnum,cnum,fname,smb_open_mode,smb_ofun,unixmode,
+ oplock_request,&rmode,&smb_action);
+
+ if (!fsp->open) {
+ /*
+ * We cheat here. The only case we care about is a directory
+ * rename, where the NT client will attempt to open the source
+ * directory for DELETE access. Note that when the NT client
+ * does this it does *not* set the directory bit in the
+ * request packet. This is translated into a read/write open
+ * request. POSIX states that any open for write request on a directory
+ * will generate an EISDIR error, so we can catch this here and open
+ * a pseudo handle that is flagged as a directory. JRA.
+ */
+
+ if(errno == EISDIR) {
+ oplock_request = 0;
+
+ open_directory(fnum, cnum, fname, smb_ofun, unixmode, &smb_action);
+
+ if(!fsp->open) {
+ fsp->reserved = False;
+ restore_case_semantics(file_attributes);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+ } else {
+ if((errno == ENOENT) && bad_path) {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadpath;
+ }
- if(!fsp->open) {
fsp->reserved = False;
+
+ restore_case_semantics(file_attributes);
+
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- } else {
- if((errno == ENOENT) && bad_path) {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
-
- fsp->reserved = False;
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
- }
+ }
+ }
if(fsp->is_directory) {
- if(stat(fsp->name, &sbuf) != 0) {
+ if(sys_stat(fsp->name, &sbuf) != 0) {
close_directory(fnum);
+ restore_case_semantics(file_attributes);
return(ERROR(ERRDOS,ERRnoaccess));
}
} else {
- if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
+ if (fstat(fsp->f_u.fd_ptr->fd,&sbuf) != 0) {
close_file(fnum,False);
+ restore_case_semantics(file_attributes);
return(ERROR(ERRDOS,ERRnoaccess));
}
}
+ restore_case_semantics(file_attributes);
+
file_len = sbuf.st_size;
fmode = dos_mode(cnum,fname,&sbuf);
if(fmode == 0)
@@ -668,10 +693,6 @@ static int call_nt_transact_create(char *inbuf, char *outbuf, int length,
files_struct *fsp;
char *p = NULL;
- /* If it's a request for a directory open, fail it. */
- if(flags & OPEN_DIRECTORY)
- return(ERROR(ERRDOS,ERRnoaccess));
-
/*
* We need to construct the open_and_X ofun value from the
* NT values, as that's what our code is structured to accept.
@@ -733,56 +754,85 @@ static int call_nt_transact_create(char *inbuf, char *outbuf, int length,
oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
- open_file_shared(fnum,cnum,fname,smb_open_mode,smb_ofun,unixmode,
- oplock_request,&rmode,&smb_action);
+ /*
+ * If it's a request for a directory open, deal with it separately.
+ */
- fsp = &Files[fnum];
-
- if (!fsp->open) {
- if((errno == ENOENT) && bad_path) {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
+ if(flags & OPEN_DIRECTORY) {
+
+ oplock_request = 0;
+
+ /*
+ * We will get a create directory here if the Win32
+ * app specified a security descriptor in the
+ * CreateDirectory() call.
+ */
+
+ open_directory(fnum, cnum, fname, smb_ofun, unixmode, &smb_action);
+
+ if(!fsp->open) {
+ fsp->reserved = False;
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- Files[fnum].reserved = False;
+ } else {
- restore_case_semantics(file_attributes);
+ /*
+ * Ordinary file case.
+ */
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
- close_file(fnum,False);
+ open_file_shared(fnum,cnum,fname,smb_open_mode,smb_ofun,unixmode,
+ oplock_request,&rmode,&smb_action);
- restore_case_semantics(file_attributes);
+ fsp = &Files[fnum];
+
+ if (!fsp->open) {
+ if((errno == ENOENT) && bad_path) {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadpath;
+ }
+ Files[fnum].reserved = False;
- return(ERROR(ERRDOS,ERRnoaccess));
- }
+ restore_case_semantics(file_attributes);
+
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
- restore_case_semantics(file_attributes);
+ if (fstat(fsp->f_u.fd_ptr->fd,&sbuf) != 0) {
+ close_file(fnum,False);
- file_len = sbuf.st_size;
- fmode = dos_mode(cnum,fname,&sbuf);
- if(fmode == 0)
- fmode = FILE_ATTRIBUTE_NORMAL;
- mtime = sbuf.st_mtime;
- if (fmode & aDIR) {
- close_file(fnum,False);
- return(ERROR(ERRDOS,ERRnoaccess));
- }
+ restore_case_semantics(file_attributes);
+
+ return(ERROR(ERRDOS,ERRnoaccess));
+ }
- /*
- * If the caller set the extended oplock request bit
- * and we granted one (by whatever means) - set the
- * correct bit for extended oplock reply.
- */
+ file_len = sbuf.st_size;
+ fmode = dos_mode(cnum,fname,&sbuf);
+ if(fmode == 0)
+ fmode = FILE_ATTRIBUTE_NORMAL;
+ mtime = sbuf.st_mtime;
+
+ if (fmode & aDIR) {
+ close_file(fnum,False);
+ restore_case_semantics(file_attributes);
+ return(ERROR(ERRDOS,ERRnoaccess));
+ }
+
+ /*
+ * If the caller set the extended oplock request bit
+ * and we granted one (by whatever means) - set the
+ * correct bit for extended oplock reply.
+ */
- if (oplock_request && lp_fake_oplocks(SNUM(cnum)))
- smb_action |= EXTENDED_OPLOCK_GRANTED;
+ if (oplock_request && lp_fake_oplocks(SNUM(cnum)))
+ smb_action |= EXTENDED_OPLOCK_GRANTED;
- if(oplock_request && fsp->granted_oplock)
- smb_action |= EXTENDED_OPLOCK_GRANTED;
+ if(oplock_request && fsp->granted_oplock)
+ smb_action |= EXTENDED_OPLOCK_GRANTED;
+ }
}
+ restore_case_semantics(file_attributes);
+
/* Realloc the size of parameters and data we will return */
params = *ppparams = Realloc(*ppparams, 69);
if(params == NULL)
@@ -972,7 +1022,7 @@ int reply_nttrans(char *inbuf,char *outbuf,int length,int bufsize)
DEBUG(2,("%s: reply_nttrans: queueing message NT_TRANSACT_CREATE \
due to being in oplock break state.\n", timestring() ));
- push_smb_message( inbuf, length);
+ push_oplock_pending_smb_message( inbuf, length);
return -1;
}
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index f05ba2eee6..2845d5650a 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -1287,6 +1287,8 @@ int reply_open(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
if (fnum < 0)
return(ERROR(ERRSRV,ERRnofids));
+ fsp = &Files[fnum];
+
if (!check_name(fname,cnum))
{
if((errno == ENOENT) && bad_path)
@@ -1294,7 +1296,7 @@ int reply_open(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
- Files[fnum].reserved = False;
+ fsp->reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1303,8 +1305,6 @@ int reply_open(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
open_file_shared(fnum,cnum,fname,share_mode,3,unixmode,
oplock_request,&rmode,NULL);
- fsp = &Files[fnum];
-
if (!fsp->open)
{
if((errno == ENOENT) && bad_path)
@@ -1312,11 +1312,11 @@ int reply_open(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
- Files[fnum].reserved = False;
+ fsp->reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
+ if (fstat(fsp->f_u.fd_ptr->fd,&sbuf) != 0) {
close_file(fnum,False);
return(ERROR(ERRDOS,ERRnoaccess));
}
@@ -1392,6 +1392,8 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
if (fnum < 0)
return(ERROR(ERRSRV,ERRnofids));
+ fsp = &Files[fnum];
+
if (!check_name(fname,cnum))
{
if((errno == ENOENT) && bad_path)
@@ -1399,7 +1401,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;
+ fsp->reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1408,8 +1410,6 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode,
oplock_request, &rmode,&smb_action);
- fsp = &Files[fnum];
-
if (!fsp->open)
{
if((errno == ENOENT) && bad_path)
@@ -1417,11 +1417,11 @@ 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;
+ fsp->reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
+ if (fstat(fsp->f_u.fd_ptr->fd,&sbuf) != 0) {
close_file(fnum,False);
return(ERROR(ERRDOS,ERRnoaccess));
}
@@ -1548,6 +1548,8 @@ int reply_mknew(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
if (fnum < 0)
return(ERROR(ERRSRV,ERRnofids));
+ fsp = &Files[fnum];
+
if (!check_name(fname,cnum))
{
if((errno == ENOENT) && bad_path)
@@ -1555,7 +1557,7 @@ int reply_mknew(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
- Files[fnum].reserved = False;
+ fsp->reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1574,8 +1576,6 @@ int reply_mknew(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
open_file_shared(fnum,cnum,fname,(DENY_FCB<<4)|0xF, ofun, unixmode,
oplock_request, NULL, NULL);
- fsp = &Files[fnum];
-
if (!fsp->open)
{
if((errno == ENOENT) && bad_path)
@@ -1583,7 +1583,7 @@ int reply_mknew(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
- Files[fnum].reserved = False;
+ fsp->reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1598,7 +1598,8 @@ int reply_mknew(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
DEBUG(2,("new file %s\n",fname));
- DEBUG(3,("%s mknew %s fd=%d fnum=%d cnum=%d dmode=%d umode=%o\n",timestring(),fname,Files[fnum].fd_ptr->fd,fnum,cnum,createmode,unixmode));
+ DEBUG(3,("%s mknew %s fd=%d fnum=%d cnum=%d dmode=%d umode=%o\n",
+ timestring(),fname,fsp->f_u.fd_ptr->fd,fnum,cnum,createmode,unixmode));
return(outsize);
}
@@ -1632,6 +1633,8 @@ int reply_ctemp(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
if (fnum < 0)
return(ERROR(ERRSRV,ERRnofids));
+ fsp = &Files[fnum];
+
if (!check_name(fname,cnum))
{
if((errno == ENOENT) && bad_path)
@@ -1639,7 +1642,7 @@ int reply_ctemp(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
- Files[fnum].reserved = False;
+ fsp->reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1650,8 +1653,6 @@ int reply_ctemp(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
open_file_shared(fnum,cnum,fname2,(DENY_FCB<<4)|0xF, 0x10, unixmode,
oplock_request, NULL, NULL);
- fsp = &Files[fnum];
-
if (!fsp->open)
{
if((errno == ENOENT) && bad_path)
@@ -1659,7 +1660,7 @@ int reply_ctemp(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
- Files[fnum].reserved = False;
+ fsp->reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1676,7 +1677,8 @@ int reply_ctemp(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
DEBUG(2,("created temp file %s\n",fname2));
- DEBUG(3,("%s ctemp %s fd=%d fnum=%d cnum=%d dmode=%d umode=%o\n",timestring(),fname2,Files[fnum].fd_ptr->fd,fnum,cnum,createmode,unixmode));
+ DEBUG(3,("%s ctemp %s fd=%d fnum=%d cnum=%d dmode=%d umode=%o\n",
+ timestring(),fname2,fsp->f_u.fd_ptr->fd,fnum,cnum,createmode,unixmode));
return(outsize);
}
@@ -1821,6 +1823,7 @@ int reply_readbraw(char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
int ret=0;
int fd;
char *fname;
+ files_struct *fsp;
/*
* Special check if an oplock break has been issued
@@ -1848,35 +1851,37 @@ int reply_readbraw(char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
maxcount = MAX(mincount,maxcount);
if (!FNUM_OK(fnum,cnum) || !Files[fnum].can_read)
- {
- DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",fnum));
- _smb_setlen(header,0);
- transfer_file(0,Client,0,header,4,0);
- return(-1);
- }
+ {
+ DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",fnum));
+ _smb_setlen(header,0);
+ transfer_file(0,Client,0,header,4,0);
+ return(-1);
+ }
else
- {
- fd = Files[fnum].fd_ptr->fd;
- fname = Files[fnum].name;
- }
+ {
+ fsp = &Files[fnum];
+
+ fd = fsp->f_u.fd_ptr->fd;
+ fname = fsp->name;
+ }
if (!is_locked(fnum,cnum,maxcount,startpos, F_RDLCK))
- {
- int size = Files[fnum].size;
- int sizeneeded = startpos + maxcount;
+ {
+ int size = fsp->size;
+ int sizeneeded = startpos + maxcount;
- if (size < sizeneeded) {
- struct stat st;
- if (fstat(Files[fnum].fd_ptr->fd,&st) == 0)
- size = st.st_size;
- if (!Files[fnum].can_write)
- Files[fnum].size = size;
- }
-
- nread = MIN(maxcount,(int)(size - startpos));
+ if (size < sizeneeded) {
+ struct stat st;
+ if (fstat(fsp->f_u.fd_ptr->fd,&st) == 0)
+ size = st.st_size;
+ if (!fsp->can_write)
+ fsp->size = size;
}
+ nread = MIN(maxcount,(int)(size - startpos));
+ }
+
if (nread < mincount)
nread = 0;
@@ -1891,7 +1896,7 @@ int reply_readbraw(char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
_smb_setlen(header,nread);
#if USE_READ_PREDICTION
- if (!Files[fnum].can_write)
+ if (!fsp->can_write)
predict = read_predict(fd,startpos,header+4,NULL,nread);
#endif
@@ -2138,7 +2143,7 @@ int reply_writebraw(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
tcount,nwritten,numtowrite));
}
- nwritten = transfer_file(Client,Files[fnum].fd_ptr->fd,numtowrite,NULL,0,
+ nwritten = transfer_file(Client,Files[fnum].f_u.fd_ptr->fd,numtowrite,NULL,0,
startpos+nwritten);
total_written += nwritten;
@@ -2255,7 +2260,7 @@ int reply_write(char *inbuf,char *outbuf,int dum_size,int dum_buffsize)
zero then the file size should be extended or
truncated to the size given in smb_vwv[2-3] */
if(numtowrite == 0)
- nwritten = set_filelen(Files[fnum].fd_ptr->fd, startpos);
+ nwritten = set_filelen(Files[fnum].f_u.fd_ptr->fd, startpos);
else
nwritten = write_file(fnum,data,numtowrite);
@@ -2349,7 +2354,8 @@ int reply_lseek(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
int32 res= -1;
int mode,umode;
int outsize = 0;
-
+ files_struct *fsp;
+
cnum = SVAL(inbuf,smb_tid);
fnum = GETFNUM(inbuf,smb_vwv0);
@@ -2367,9 +2373,11 @@ int reply_lseek(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
default:
umode = SEEK_SET; break;
}
+
+ fsp = &Files[fnum];
- res = lseek(Files[fnum].fd_ptr->fd,startpos,umode);
- Files[fnum].pos = res;
+ res = lseek(fsp->f_u.fd_ptr->fd,startpos,umode);
+ fsp->pos = res;
outsize = set_message(outbuf,2,0,True);
SIVALS(outbuf,smb_vwv0,res);
@@ -2477,7 +2485,7 @@ int reply_close(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
set_filetime(cnum, fsp->name,mtime);
DEBUG(3,("%s close fd=%d fnum=%d cnum=%d (numopen=%d)\n",
- timestring(),fsp->fd_ptr->fd,fnum,cnum,
+ timestring(),fsp->f_u.fd_ptr->fd,fnum,cnum,
Connections[cnum].num_files_open));
close_file(fnum,True);
@@ -2560,7 +2568,8 @@ int reply_lock(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
count = IVAL(inbuf,smb_vwv1);
offset = IVAL(inbuf,smb_vwv3);
- DEBUG(3,("%s lock fd=%d fnum=%d cnum=%d ofs=%d cnt=%d\n",timestring(),Files[fnum].fd_ptr->fd,fnum,cnum,offset,count));
+ DEBUG(3,("%s lock fd=%d fnum=%d cnum=%d ofs=%d cnt=%d\n",
+ timestring(),Files[fnum].f_u.fd_ptr->fd,fnum,cnum,offset,count));
if(!do_lock( fnum, cnum, count, offset, F_WRLCK, &eclass, &ecode))
return (ERROR(eclass,ecode));
@@ -2592,7 +2601,8 @@ int reply_unlock(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
if(!do_unlock(fnum, cnum, count, offset, &eclass, &ecode))
return (ERROR(eclass,ecode));
- DEBUG(3,("%s unlock fd=%d fnum=%d cnum=%d ofs=%d cnt=%d\n",timestring(),Files[fnum].fd_ptr->fd,fnum,cnum,offset,count));
+ DEBUG(3,("%s unlock fd=%d fnum=%d cnum=%d ofs=%d cnt=%d\n",
+ timestring(),Files[fnum].f_u.fd_ptr->fd,fnum,cnum,offset,count));
return(outsize);
}
@@ -2686,6 +2696,7 @@ int reply_printopen(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
int cnum;
int fnum = -1;
int outsize = 0;
+ files_struct *fsp;
*fname = *fname2 = 0;
@@ -2715,10 +2726,12 @@ int reply_printopen(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
if (fnum < 0)
return(ERROR(ERRSRV,ERRnofids));
+ fsp = &Files[fnum];
+
pstrcpy(fname2,(char *)mktemp(fname));
if (!check_name(fname2,cnum)) {
- Files[fnum].reserved = False;
+ fsp->reserved = False;
return(ERROR(ERRDOS,ERRnoaccess));
}
@@ -2726,18 +2739,19 @@ int reply_printopen(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
open_file_shared(fnum,cnum,fname2,(DENY_ALL<<4)|1, 0x12, unix_mode(cnum,0),
0, NULL, NULL);
- if (!Files[fnum].open) {
- Files[fnum].reserved = False;
+ if (!fsp->open) {
+ fsp->reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
/* force it to be a print file */
- Files[fnum].print_file = True;
+ fsp->print_file = True;
outsize = set_message(outbuf,1,0,True);
SSVAL(outbuf,smb_vwv0,fnum);
- DEBUG(3,("%s openprint %s fd=%d fnum=%d cnum=%d\n",timestring(),fname2,Files[fnum].fd_ptr->fd,fnum,cnum));
+ DEBUG(3,("%s openprint %s fd=%d fnum=%d cnum=%d\n",
+ timestring(),fname2,fsp->f_u.fd_ptr->fd,fnum,cnum));
return(outsize);
}
@@ -2760,7 +2774,8 @@ int reply_printclose(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
if (!CAN_PRINT(cnum))
return(ERROR(ERRDOS,ERRnoaccess));
- DEBUG(3,("%s printclose fd=%d fnum=%d cnum=%d\n",timestring(),Files[fnum].fd_ptr->fd,fnum,cnum));
+ DEBUG(3,("%s printclose fd=%d fnum=%d cnum=%d\n",
+ timestring(),Files[fnum].f_u.fd_ptr->fd,fnum,cnum));
close_file(fnum,True);
@@ -3453,11 +3468,12 @@ static BOOL copy_file(char *src,char *dest1,int cnum,int ofun,
}
if ((ofun&3) == 1) {
- lseek(Files[fnum2].fd_ptr->fd,0,SEEK_END);
+ lseek(Files[fnum2].f_u.fd_ptr->fd,0,SEEK_END);
}
if (st.st_size)
- ret = transfer_file(Files[fnum1].fd_ptr->fd,Files[fnum2].fd_ptr->fd,st.st_size,NULL,0,0);
+ ret = transfer_file(Files[fnum1].f_u.fd_ptr->fd,
+ Files[fnum2].f_u.fd_ptr->fd,st.st_size,NULL,0,0);
close_file(fnum1,False);
close_file(fnum2,False);
@@ -3675,8 +3691,8 @@ int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize)
{
int token;
files_struct *fsp = &Files[fnum];
- uint32 dev = fsp->fd_ptr->dev;
- uint32 inode = fsp->fd_ptr->inode;
+ uint32 dev = fsp->f_u.fd_ptr->dev;
+ uint32 inode = fsp->f_u.fd_ptr->inode;
DEBUG(5,("reply_lockingX: oplock break reply from client for fnum = %d\n",
fnum));
@@ -4077,7 +4093,7 @@ int reply_getattrE(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
CHECK_ERROR(fnum);
/* Do an fstat on this file */
- if(fstat(Files[fnum].fd_ptr->fd, &sbuf))
+ if(fstat(Files[fnum].f_u.fd_ptr->fd, &sbuf))
return(UNIXERROR(ERRDOS,ERRnoaccess));
mode = dos_mode(cnum,Files[fnum].name,&sbuf);
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 8eee0209b6..056611a886 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -1047,7 +1047,7 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct
int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
fsp->open = False;
- fsp->fd_ptr = 0;
+ fsp->f_u.fd_ptr = 0;
fsp->granted_oplock = False;
errno = EPERM;
@@ -1222,7 +1222,7 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct
if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
lp_minprintspace(SNUM(cnum))) {
fd_attempt_close(fd_ptr);
- fsp->fd_ptr = 0;
+ fsp->f_u.fd_ptr = 0;
if(fd_ptr->ref_count == 0)
sys_unlink(fname);
errno = ENOSPC;
@@ -1259,7 +1259,7 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct
fd_ptr->dev = (uint32)sbuf->st_dev;
fd_ptr->inode = (uint32)sbuf->st_ino;
- fsp->fd_ptr = fd_ptr;
+ fsp->f_u.fd_ptr = fd_ptr;
Connections[cnum].num_files_open++;
fsp->mode = sbuf->st_mode;
GetTimeOfDay(&fsp->open_time);
@@ -1316,7 +1316,7 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct
{
fsp->mmap_size = file_size(fname);
fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
- PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
+ PROT_READ,MAP_SHARED,fsp->f_u.fd_ptr->fd,0);
if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr)
{
@@ -1334,7 +1334,7 @@ void sync_file(int cnum, int fnum)
{
#ifdef HAVE_FSYNC
if(lp_strict_sync(SNUM(cnum)))
- fsync(Files[fnum].fd_ptr->fd);
+ fsync(Files[fnum].f_u.fd_ptr->fd);
#endif
}
@@ -1381,26 +1381,26 @@ static void check_magic(int fnum,int cnum)
Common code to close a file or a directory.
****************************************************************************/
-static void close_filestruct(files_struct *fs_p)
+static void close_filestruct(files_struct *fsp)
{
- int cnum = fs_p->cnum;
+ int cnum = fsp->cnum;
- fs_p->reserved = False;
- fs_p->open = False;
- fs_p->is_directory = False;
+ fsp->reserved = False;
+ fsp->open = False;
+ fsp->is_directory = False;
Connections[cnum].num_files_open--;
- if(fs_p->wbmpx_ptr)
+ if(fsp->wbmpx_ptr)
{
- free((char *)fs_p->wbmpx_ptr);
- fs_p->wbmpx_ptr = NULL;
+ free((char *)fsp->wbmpx_ptr);
+ fsp->wbmpx_ptr = NULL;
}
#if WITH_MMAP
- if(fs_p->mmap_ptr)
+ if(fsp->mmap_ptr)
{
- munmap(fs_p->mmap_ptr,fs_p->mmap_size);
- fs_p->mmap_ptr = NULL;
+ munmap(fsp->mmap_ptr,fsp->mmap_size);
+ fsp->mmap_ptr = NULL;
}
#endif
}
@@ -1418,14 +1418,14 @@ void close_file(int fnum, BOOL normal_close)
{
files_struct *fs_p = &Files[fnum];
int cnum = fs_p->cnum;
- uint32 dev = fs_p->fd_ptr->dev;
- uint32 inode = fs_p->fd_ptr->inode;
+ uint32 dev = fs_p->f_u.fd_ptr->dev;
+ uint32 inode = fs_p->f_u.fd_ptr->inode;
int token;
close_filestruct(fs_p);
#if USE_READ_PREDICTION
- invalidate_read_prediction(fs_p->fd_ptr->fd);
+ invalidate_read_prediction(fs_p->f_u.fd_ptr->fd);
#endif
if (lp_share_modes(SNUM(cnum)))
@@ -1434,7 +1434,7 @@ void close_file(int fnum, BOOL normal_close)
del_share_mode(token, fnum);
}
- fd_attempt_close(fs_p->fd_ptr);
+ fd_attempt_close(fs_p->f_u.fd_ptr);
if (lp_share_modes(SNUM(cnum)))
unlock_share_entry( cnum, dev, inode, token);
@@ -1470,31 +1470,74 @@ void close_file(int fnum, BOOL normal_close)
void close_directory(int fnum)
{
- files_struct *fs_p = &Files[fnum];
+ files_struct *fsp = &Files[fnum];
+
+ /* TODO - walk the list of pending
+ change notify requests and free
+ any pertaining to this fnum. */
/*
* Do the code common to files and directories.
*/
- close_filestruct(fs_p);
+ close_filestruct(fsp);
- if (fs_p->name) {
- string_free(&fs_p->name);
- }
+ if (fsp->name)
+ string_free(&fsp->name);
+
+ if (fsp->f_u.dir_ptr)
+ free((char *)fsp->f_u.dir_ptr);
/* we will catch bugs faster by zeroing this structure */
- memset(fs_p, 0, sizeof(*fs_p));
+ memset(fsp, 0, sizeof(*fsp));
}
/****************************************************************************
Open a directory from an NT SMB call.
****************************************************************************/
-void open_directory(int fnum,int cnum,char *fname, int *action)
+int open_directory(int fnum,int cnum,char *fname, int smb_ofun, int unixmode, int *action)
{
extern struct current_user current_user;
files_struct *fsp = &Files[fnum];
+ struct stat st;
+
+ if (smb_ofun & 0x10) {
+ /*
+ * Create the directory.
+ */
+
+ if(sys_mkdir(fname, unixmode) < 0) {
+ DEBUG(0,("open_directory: unable to create %s. Error was %s\n",
+ fname, strerror(errno) ));
+ return -1;
+ }
+
+ *action = FILE_WAS_CREATED;
+
+ } else {
+
+ /*
+ * Check that it *was* a directory.
+ */
+
+ if(sys_stat(fname, &st) < 0) {
+ DEBUG(0,("open_directory: unable to stat name = %s. Error was %s\n",
+ fname, strerror(errno) ));
+ return -1;
+ }
+
+ if(!S_ISDIR(st.st_mode)) {
+ DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
+ return -1;
+ }
+ *action = FILE_WAS_OPENED;
+ }
- fsp->fd_ptr = NULL;
+ /*
+ * Setup the files_struct for it.
+ */
+
+ fsp->f_u.dir_ptr = NULL;
Connections[cnum].num_files_open++;
fsp->mode = 0;
GetTimeOfDay(&fsp->open_time);
@@ -1524,7 +1567,7 @@ void open_directory(int fnum,int cnum,char *fname, int *action)
string_set(&fsp->name,fname);
fsp->wbmpx_ptr = NULL;
- *action = FILE_WAS_OPENED;
+ return 0;
}
enum {AFAIL,AREAD,AWRITE,AALL};
@@ -1719,8 +1762,8 @@ static void truncate_unless_locked(int fnum, int cnum, int token,
/* If share modes are in force for this connection we
have the share entry locked. Unlock it before closing. */
if (*share_locked && lp_share_modes(SNUM(cnum)))
- unlock_share_entry( cnum, Files[fnum].fd_ptr->dev,
- Files[fnum].fd_ptr->inode, token);
+ unlock_share_entry( cnum, Files[fnum].f_u.fd_ptr->dev,
+ Files[fnum].f_u.fd_ptr->inode, token);
close_file(fnum,False);
/* Share mode no longer locked. */
*share_locked = False;
@@ -1729,7 +1772,7 @@ static void truncate_unless_locked(int fnum, int cnum, int token,
unix_ERR_code = ERRlock;
}
else
- ftruncate(Files[fnum].fd_ptr->fd,0);
+ ftruncate(Files[fnum].f_u.fd_ptr->fd,0);
}
}
@@ -1794,7 +1837,7 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
int num_share_modes = 0;
fs_p->open = False;
- fs_p->fd_ptr = 0;
+ fs_p->f_u.fd_ptr = 0;
/* this is for OS/2 EAs - try and say we don't support them */
if (strstr(fname,".+,;=[]."))
@@ -1970,8 +2013,8 @@ dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
if((share_locked == False) && lp_share_modes(SNUM(cnum)))
{
/* We created the file - thus we must now lock the share entry before creating it. */
- dev = fs_p->fd_ptr->dev;
- inode = fs_p->fd_ptr->inode;
+ dev = fs_p->f_u.fd_ptr->dev;
+ inode = fs_p->f_u.fd_ptr->inode;
lock_share_entry(cnum, dev, inode, &token);
share_locked = True;
}
@@ -2046,12 +2089,13 @@ seek a file. Try to avoid the seek if possible
int seek_file(int fnum,uint32 pos)
{
uint32 offset = 0;
- if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
+ files_struct *fsp = &Files[fnum];
+
+ if (fsp->print_file && POSTSCRIPT(fsp->cnum))
offset = 3;
- Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET)
- - offset);
- return(Files[fnum].pos);
+ fsp->pos = (int)(lseek(fsp->f_u.fd_ptr->fd,pos+offset,SEEK_SET) - offset);
+ return(fsp->pos);
}
/****************************************************************************
@@ -2060,11 +2104,12 @@ read from a file
int read_file(int fnum,char *data,uint32 pos,int n)
{
int ret=0,readret;
+ files_struct *fsp = &Files[fnum];
#if USE_READ_PREDICTION
- if (!Files[fnum].can_write)
+ if (!fsp->can_write)
{
- ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
+ ret = read_predict(fsp->f_u.fd_ptr->fd,pos,data,NULL,n);
data += ret;
n -= ret;
@@ -2073,13 +2118,13 @@ int read_file(int fnum,char *data,uint32 pos,int n)
#endif
#if WITH_MMAP
- if (Files[fnum].mmap_ptr)
+ if (fsp->mmap_ptr)
{
- int num = (Files[fnum].mmap_size > pos) ? (Files[fnum].mmap_size - pos) : -1;
+ int num = (fsp->mmap_size > pos) ? (fsp->mmap_size - pos) : -1;
num = MIN(n,num);
if (num > 0)
{
- memcpy(data,Files[fnum].mmap_ptr+pos,num);
+ memcpy(data,fsp->mmap_ptr+pos,num);
data += num;
pos += num;
n -= num;
@@ -2098,7 +2143,7 @@ int read_file(int fnum,char *data,uint32 pos,int n)
}
if (n > 0) {
- readret = read(Files[fnum].fd_ptr->fd,data,n);
+ readret = read(fsp->f_u.fd_ptr->fd,data,n);
if (readret > 0) ret += readret;
}
@@ -2111,23 +2156,25 @@ write to a file
****************************************************************************/
int write_file(int fnum,char *data,int n)
{
- if (!Files[fnum].can_write) {
+ files_struct *fsp = &Files[fnum];
+
+ if (!fsp->can_write) {
errno = EPERM;
return(0);
}
- if (!Files[fnum].modified) {
+ if (!fsp->modified) {
struct stat st;
- Files[fnum].modified = True;
- if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
- int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
- if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
- dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
+ fsp->modified = True;
+ if (fstat(fsp->f_u.fd_ptr->fd,&st) == 0) {
+ int dosmode = dos_mode(fsp->cnum,fsp->name,&st);
+ if (MAP_ARCHIVE(fsp->cnum) && !IS_DOS_ARCHIVE(dosmode)) {
+ dos_chmod(fsp->cnum,fsp->name,dosmode | aARCH,&st);
}
}
}
- return(write_data(Files[fnum].fd_ptr->fd,data,n));
+ return(write_data(fsp->f_u.fd_ptr->fd,data,n));
}
@@ -2871,7 +2918,7 @@ global_oplocks_open = %d\n", timestring(), dev, inode, global_oplocks_open));
{
if(OPEN_FNUM(fnum))
{
- if((Files[fnum].fd_ptr->dev == dev) && (Files[fnum].fd_ptr->inode == inode) &&
+ if((Files[fnum].f_u.fd_ptr->dev == dev) && (Files[fnum].f_u.fd_ptr->inode == inode) &&
(Files[fnum].open_time.tv_sec == tval->tv_sec) &&
(Files[fnum].open_time.tv_usec == tval->tv_usec)) {
fsp = &Files[fnum];
@@ -3687,17 +3734,17 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de
file table when we have run out.
****************************************************************************/
-static BOOL attempt_close_oplocked_file(files_struct *fp)
+static BOOL attempt_close_oplocked_file(files_struct *fsp)
{
- DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fp->name));
+ DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->name));
- if (fp->open && fp->granted_oplock && !fp->sent_oplock_break) {
+ if (fsp->open && fsp->granted_oplock && !fsp->sent_oplock_break) {
/* Try and break the oplock. */
- file_fd_struct *fsp = fp->fd_ptr;
- if(oplock_break( fsp->dev, fsp->inode, &fp->open_time)) {
- if(!fp->open) /* Did the oplock break close the file ? */
+ file_fd_struct *fd_ptr = fsp->f_u.fd_ptr;
+ if(oplock_break( fd_ptr->dev, fd_ptr->inode, &fsp->open_time)) {
+ if(!fsp->open) /* Did the oplock break close the file ? */
return True;
}
}
@@ -4601,7 +4648,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
DEBUG(2,("%s: switch_message: queueing message due to being in oplock break state.\n",
timestring() ));
- push_smb_message( inbuf, size);
+ push_oplock_pending_smb_message( inbuf, size);
return -1;
}
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 2fcab32afb..08f6803005 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -207,6 +207,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum,
struct stat sbuf;
int smb_action = 0;
BOOL bad_path = False;
+ files_struct *fsp;
StrnCpy(fname,pname,namelen);
@@ -221,6 +222,8 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum,
if (fnum < 0)
return(ERROR(ERRSRV,ERRnofids));
+ fsp = &Files[fnum];
+
if (!check_name(fname,cnum))
{
if((errno == ENOENT) && bad_path)
@@ -228,28 +231,27 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum,
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
- Files[fnum].reserved = False;
+ fsp->reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
unixmode = unix_mode(cnum,open_attr | aARCH);
-
open_file_shared(fnum,cnum,fname,open_mode,open_ofun,unixmode,
oplock_request, &rmode,&smb_action);
- if (!Files[fnum].open)
+ if (!fsp->open)
{
if((errno == ENOENT) && bad_path)
{
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
- Files[fnum].reserved = False;
+ fsp->reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
+ if (fstat(fsp->f_u.fd_ptr->fd,&sbuf) != 0) {
close_file(fnum,False);
return(ERROR(ERRDOS,ERRnoaccess));
}
@@ -1187,11 +1189,11 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length,
CHECK_ERROR(fnum);
fname = Files[fnum].name;
- if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
+ if (fstat(Files[fnum].f_u.fd_ptr->fd,&sbuf) != 0) {
DEBUG(3,("fstat of fnum %d failed (%s)\n",fnum, strerror(errno)));
return(UNIXERROR(ERRDOS,ERRbadfid));
}
- pos = lseek(Files[fnum].fd_ptr->fd,0,SEEK_CUR);
+ pos = lseek(Files[fnum].f_u.fd_ptr->fd,0,SEEK_CUR);
} else {
/* qpathinfo */
info_level = SVAL(params,0);
@@ -1411,7 +1413,7 @@ static int call_trans2setfilepathinfo(char *inbuf, char *outbuf, int length,
CHECK_ERROR(fnum);
fname = Files[fnum].name;
- fd = Files[fnum].fd_ptr->fd;
+ fd = Files[fnum].f_u.fd_ptr->fd;
if(fstat(fd,&st)!=0) {
DEBUG(3,("fstat of %s failed (%s)\n", fname, strerror(errno)));
@@ -1788,7 +1790,7 @@ int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize)
DEBUG(2,("%s: reply_trans2: queueing message trans2open due to being in oplock break state.\n",
timestring() ));
- push_smb_message( inbuf, length);
+ push_oplock_pending_smb_message( inbuf, length);
return -1;
}