extern pstring sesssetup_user;
extern fstring myworkgroup;
extern int Client;
+extern int global_oplock_break;
/* this macro should always be used to extract an fnum (smb_fid) from
a packet to ensure chaining works correctly */
static void overflow_attack(int len)
{
DEBUG(0,("ERROR: Invalid password length %d\n", len));
- DEBUG(0,("you're machine may be under attack by a user exploiting an old bug\n"));
+ DEBUG(0,("your machine may be under attack by a user exploiting an old bug\n"));
DEBUG(0,("Attack was from IP=%s\n", client_addr()));
exit_server("possible attack");
}
if (Protocol < PROTOCOL_NT1) {
smb_apasslen = SVAL(inbuf,smb_vwv7);
if (smb_apasslen > MAX_PASSWORD_LENGTH)
+ {
overflow_attack(smb_apasslen);
+ }
memcpy(smb_apasswd,smb_buf(inbuf),smb_apasslen);
pstrcpy(user,smb_buf(inbuf)+smb_apasslen);
if (!done_sesssetup)
max_send = MIN(max_send,smb_bufsize);
- DEBUG(1,(" Client requested max send size of %d\n", max_send));
+ DEBUG(6,("Client requested max send size of %d\n", max_send));
done_sesssetup = True;
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+
+ /* Ugly - NT specific hack - but needed (JRA) */
+ if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
+ (get_remote_arch() == RA_WINNT))
+ {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbaddirectory;
+ }
+
return(UNIXERROR(ERRDOS,ERRbadpath));
}
int rmode=0;
struct stat sbuf;
BOOL bad_path = False;
+ files_struct *fsp;
+ int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
cnum = SVAL(inbuf,smb_tid);
unixmode = unix_mode(cnum,aARCH);
- open_file_shared(fnum,cnum,fname,share_mode,3,unixmode,&rmode,NULL);
+ open_file_shared(fnum,cnum,fname,share_mode,3,unixmode,
+ oplock_request,&rmode,NULL);
- if (!Files[fnum].open)
+ fsp = &Files[fnum];
+
+ if (!fsp->open)
{
if((errno == ENOENT) && bad_path)
{
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
+ if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
close_file(fnum);
return(ERROR(ERRDOS,ERRnoaccess));
}
SIVAL(outbuf,smb_vwv4,size);
SSVAL(outbuf,smb_vwv6,rmode);
- if (lp_fake_oplocks(SNUM(cnum))) {
- CVAL(outbuf,smb_flg) |= (CVAL(inbuf,smb_flg) & (1<<5));
+ if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
+ CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
}
+ if(fsp->granted_oplock)
+ CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
return(outsize);
}
int fnum = -1;
int smb_mode = SVAL(inbuf,smb_vwv3);
int smb_attr = SVAL(inbuf,smb_vwv5);
- BOOL oplock_request = BITSETW(inbuf+smb_vwv2,1);
+ BOOL oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
#if 0
int open_flags = SVAL(inbuf,smb_vwv2);
int smb_sattr = SVAL(inbuf,smb_vwv4);
struct stat sbuf;
int smb_action = 0;
BOOL bad_path = False;
+ files_struct *fsp;
/* If it's an IPC, pass off the pipe handler. */
if (IS_IPC(cnum))
unixmode = unix_mode(cnum,smb_attr | aARCH);
open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode,
- &rmode,&smb_action);
+ oplock_request, &rmode,&smb_action);
- if (!Files[fnum].open)
+ fsp = &Files[fnum];
+
+ if (!fsp->open)
{
if((errno == ENOENT) && bad_path)
{
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
+ if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
close_file(fnum);
return(ERROR(ERRDOS,ERRnoaccess));
}
}
if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
- smb_action |= (1<<15);
+ smb_action |= EXTENDED_OPLOCK_GRANTED;
+ CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
+ }
+
+ if(fsp->granted_oplock) {
+ smb_action |= EXTENDED_OPLOCK_GRANTED;
+ CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
}
set_message(outbuf,15,0,True);
mode_t unixmode;
int ofun = 0;
BOOL bad_path = False;
+ files_struct *fsp;
+ int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
com = SVAL(inbuf,smb_com);
cnum = SVAL(inbuf,smb_tid);
}
/* Open file in dos compatibility share mode. */
- open_file_shared(fnum,cnum,fname,(DENY_FCB<<4)|0xF, ofun, unixmode, NULL, NULL);
+ open_file_shared(fnum,cnum,fname,(DENY_FCB<<4)|0xF, ofun, unixmode,
+ oplock_request, NULL, NULL);
- if (!Files[fnum].open)
+ fsp = &Files[fnum];
+
+ if (!fsp->open)
{
if((errno == ENOENT) && bad_path)
{
outsize = set_message(outbuf,1,0,True);
SSVAL(outbuf,smb_vwv0,fnum);
- if (lp_fake_oplocks(SNUM(cnum))) {
- CVAL(outbuf,smb_flg) |= (CVAL(inbuf,smb_flg) & (1<<5));
+ if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
+ CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
}
-
+
+ if(fsp->granted_oplock)
+ 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));
int createmode;
mode_t unixmode;
BOOL bad_path = False;
+ files_struct *fsp;
+ int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
cnum = SVAL(inbuf,smb_tid);
createmode = SVAL(inbuf,smb_vwv0);
/* Open file in dos compatibility share mode. */
/* We should fail if file exists. */
- open_file_shared(fnum,cnum,fname2,(DENY_FCB<<4)|0xF, 0x10, unixmode, NULL, NULL);
+ open_file_shared(fnum,cnum,fname2,(DENY_FCB<<4)|0xF, 0x10, unixmode,
+ oplock_request, NULL, NULL);
- if (!Files[fnum].open)
+ fsp = &Files[fnum];
+
+ if (!fsp->open)
{
if((errno == ENOENT) && bad_path)
{
CVAL(smb_buf(outbuf),0) = 4;
strcpy(smb_buf(outbuf) + 1,fname2);
- if (lp_fake_oplocks(SNUM(cnum))) {
- CVAL(outbuf,smb_flg) |= (CVAL(inbuf,smb_flg) & (1<<5));
+ if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
+ CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
}
+ if(fsp->granted_oplock)
+ 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));
int fd;
char *fname;
+ /*
+ * Special check if an oplock break has been issued
+ * and the readraw request croses on the wire, we must
+ * return a zero length response here.
+ */
+
+ if(global_oplock_break)
+ {
+ _smb_setlen(header,0);
+ transfer_file(0,Client,0,header,4,0);
+ DEBUG(5,("readbraw - oplock break finished\n"));
+ return -1;
+ }
+
cnum = SVAL(inbuf,smb_tid);
fnum = GETFNUM(inbuf,smb_vwv0);
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), NULL, NULL);
+ 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));
fnum1 = find_free_file();
if (fnum1<0) return(False);
open_file_shared(fnum1,cnum,src,(DENY_NONE<<4),
- 1,0,&Access,&action);
+ 1,0,0,&Access,&action);
if (!Files[fnum1].open) return(False);
return(False);
}
open_file_shared(fnum2,cnum,dest,(DENY_NONE<<4)|1,
- ofun,st.st_mode,&Access,&action);
+ ofun,st.st_mode,0,&Access,&action);
if (!Files[fnum2].open) {
close_file(fnum1);
int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize)
{
int fnum = GETFNUM(inbuf,smb_vwv2);
- uint16 locktype = SVAL(inbuf,smb_vwv3);
+ unsigned char locktype = CVAL(inbuf,smb_vwv3);
+#if 0
+ unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1);
+#endif
uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
uint16 num_locks = SVAL(inbuf,smb_vwv7);
uint32 count, offset;
CHECK_ERROR(fnum);
data = smb_buf(inbuf);
+
+ /* Check if this is an oplock break on a file
+ we have granted an oplock on.
+ */
+ if((locktype == LOCKING_ANDX_OPLOCK_RELEASE) &&
+ (num_ulocks == 0) && (num_locks == 0) &&
+ (CVAL(inbuf,smb_vwv0) == 0xFF))
+ {
+ share_lock_token token;
+ files_struct *fsp = &Files[fnum];
+ uint32 dev = fsp->fd_ptr->dev;
+ uint32 inode = fsp->fd_ptr->inode;
+
+ DEBUG(5,("reply_lockingX: oplock break reply from client for fnum = %d\n",
+ fnum));
+ /*
+ * Make sure we have granted an oplock on this file.
+ */
+ if(!fsp->granted_oplock)
+ {
+ DEBUG(0,("reply_lockingX: Error : oplock break from client for fnum = %d and \
+no oplock granted on this file.\n", fnum));
+ return ERROR(ERRDOS,ERRlock);
+ }
+
+ /* Remove the oplock flag from the sharemode. */
+ lock_share_entry(fsp->cnum, dev, inode, &token);
+ if(remove_share_oplock( fnum, token)==False)
+ {
+ DEBUG(0,("reply_lockingX: failed to remove share oplock for fnum %d, \
+dev = %x, inode = %x\n", fnum, dev, inode));
+ unlock_share_entry(fsp->cnum, dev, inode, token);
+ return -1;
+ }
+ unlock_share_entry(fsp->cnum, dev, inode, token);
+
+ /* Clear the granted flag and return. */
+
+ fsp->granted_oplock = False;
+ return -1;
+ }
+
/* Data now points at the beginning of the list
of smb_unlkrng structs */
for(i = 0; i < (int)num_ulocks; i++) {
set_message(outbuf,2,0,True);
DEBUG(3,("%s lockingX fnum=%d cnum=%d type=%d num_locks=%d num_ulocks=%d\n",
- timestring(),fnum,cnum,locktype,num_locks,num_ulocks));
+ timestring(),fnum,cnum,(unsigned int)locktype,num_locks,num_ulocks));
chain_fnum = fnum;
return(outsize);
}
-
-
-
-
-