so should have no effect on other work.
Jeremy (jallison@whistle.com)
int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode,
min_share_mode_entry **old_shares);
void del_share_mode(share_lock_token token, int fnum);
-BOOL set_share_mode(share_lock_token token, int fnum, uint16 port);
+BOOL set_share_mode(share_lock_token token, int fnum, uint16 port, uint16 op_type);
BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok);
BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token token);
int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode,
min_share_mode_entry **old_shares);
void del_share_mode(share_lock_token token, int fnum);
-BOOL set_share_mode(share_lock_token token,int fnum, uint16 port);
+BOOL set_share_mode(share_lock_token token,int fnum, uint16 port, uint16 op_type);
/*The following definitions come from mangle.c */
void sync_file(int fnum);
void close_file(int fnum);
BOOL check_file_sharing(int cnum,char *fname);
+int check_share_mode( min_share_mode_entry *share, int deny_mode, char *fname,
+ BOOL fcbopen, int *flags);
void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
- int mode,int *Access,int *action);
+ int mode,int oplock_request, int *Access,int *action);
int seek_file(int fnum,uint32 pos);
int read_file(int fnum,char *data,uint32 pos,int n);
int write_file(int fnum,char *data,int n);
BOOL is_myname(char *s);
void set_remote_arch(enum remote_arch_types type);
enum remote_arch_types get_remote_arch();
+void fstrcpy(char *dest, char *src);
+void pstrcpy(char *dest, char *src);
BOOL share_mode;
BOOL print_file;
BOOL modified;
+ BOOL granted_oplock;
char *name;
} files_struct;
int pid;
#ifdef USE_OPLOCKS
uint16 op_port;
+ uint16 op_type;
#endif /* USE_OPLOCKS */
int share_mode;
struct timeval time;
int pid;
#ifdef USE_OPLOCKS
uint16 op_port;
+ uint16 op_type;
#endif /* USE_OPLOCKS */
int share_mode;
struct timeval time;
#ifdef USE_OPLOCKS
#define SMF_ENTRY_LENGTH 16
#else /* USE_OPLOCKS */
-#define SMF_ENTRY_LENGTH 18
+#define SMF_ENTRY_LENGTH 20
#endif /* USE_OPLOCKS */
/*
#ifdef USE_OPLOCKS
#define SME_PORT_OFFSET 16
+#define SME_OPLOCK_TYPE_OFFSET 18
#endif /* USE_OPLOCKS */
#endif /* FAST_SHARE_MODES */
#define KANJI_CODEPAGE 932
#ifdef KANJI
-/* Default client code page - Japanese */
+/*
+ * Default client code page - Japanese
+ */
#define DEFAULT_CLIENT_CODE_PAGE KANJI_CODEPAGE
#else /* KANJI */
-/* Default client code page - 850 - Western European */
+/*
+ * Default client code page - 850 - Western European
+ */
#define DEFAULT_CLIENT_CODE_PAGE 850
#endif /* KANJI */
-/* Size of buffer to use when moving files across filesystems. */
+
+/*
+ * Size of buffer to use when moving files across filesystems.
+ */
#define COPYBUF_SIZE (8*1024)
-/* Integers used to override error codes. */
+/*
+ * Integers used to override error codes.
+ */
extern int unix_ERR_class;
extern int unix_ERR_code;
+
+/*
+ * Map the Core and Extended Oplock requesst bits down
+ * to common bits (EXCLUSIVE_OPLOCK & BATCH_OPLOCK).
+ */
+
+/*
+ * Core protocol.
+ */
+#define CORE_OPLOCK_REQUEST(inbuf) (((CVAL(inbuf,smb_flg)|(1<<5))>>5) | \
+ ((CVAL(inbuf,smb_flg)|(1<<6))>>5))
+
+/*
+ * Extended protocol.
+ */
+#define EXTENDED_OPLOCK_REQUEST(inbuf) (((SVAL(inbuf,smb_vwv2)|(1<<1))>>1) | \
+ ((SVAL(inbuf,smb_vwv2)|(1<<2))>>1))
+
+/*
+ * Bits we test with.
+ */
+#define EXCLUSIVE_OPLOCK 1
+#define BATCH_OPLOCK 2
+
+#define CORE_OPLOCK_GRANTED (1<<5)
+#define EXTENDED_OPLOCK_GRANTED (1<<15)
+
/* _SMB_H */
return ra_type;
}
-
/*******************************************************************
safe string copy into a fstring
********************************************************************/
void fstrcpy(char *dest, char *src)
{
- int maxlength = sizeof(fstring) - 1;
- if (!dest) {
- DEBUG(0,("ERROR: NULL dest in fstrcpy\n"));
- return;
- }
-
- if (!src) {
- *dest = 0;
- return;
- }
+ int maxlength = sizeof(fstring) - 1;
+ if (!dest) {
+ DEBUG(0,("ERROR: NULL dest in fstrcpy\n"));
+ return;
+ }
- while (maxlength-- && *src)
- *dest++ = *src++;
- *dest = 0;
- if (*src) {
- DEBUG(0,("ERROR: string overflow by %d in fstrcpy\n",
- strlen(src)));
- }
-}
+ if (!src) {
+ *dest = 0;
+ return;
+ }
+
+ while (maxlength-- && *src)
+ *dest++ = *src++;
+ *dest = 0;
+ if (*src) {
+ DEBUG(0,("ERROR: string overflow by %d in fstrcpy\n",
+ strlen(src)));
+ }
+}
/*******************************************************************
safe string copy into a pstring
********************************************************************/
void pstrcpy(char *dest, char *src)
{
- int maxlength = sizeof(pstring) - 1;
- if (!dest) {
- DEBUG(0,("ERROR: NULL dest in pstrcpy\n"));
- return;
- }
-
- if (!src) {
- *dest = 0;
- return;
- }
-
- while (maxlength-- && *src)
- *dest++ = *src++;
- *dest = 0;
- if (*src) {
- DEBUG(0,("ERROR: string overflow by %d in pstrcpy\n",
- strlen(src)));
- }
-}
+ int maxlength = sizeof(pstring) - 1;
+ if (!dest) {
+ DEBUG(0,("ERROR: NULL dest in pstrcpy\n"));
+ return;
+ }
+
+ if (!src) {
+ *dest = 0;
+ return;
+ }
+
+ while (maxlength-- && *src)
+ *dest++ = *src++;
+ *dest = 0;
+ if (*src) {
+ DEBUG(0,("ERROR: string overflow by %d in pstrcpy\n",
+ strlen(src)));
+ }
+}
share_array[num_entries_copied].share_mode = entry_scanner_p->share_mode;
#ifdef USE_OPLOCKS
share_array[num_entries_copied].op_port = entry_scanner_p->op_port;
+ share_array[num_entries_copied].op_type = entry_scanner_p->op_type;
#endif /* USE_OPLOCKS */
memcpy(&share_array[num_entries_copied].time, &entry_scanner_p->time,
sizeof(struct timeval));
/*******************************************************************
set the share mode of a file. Return False on fail, True on success.
********************************************************************/
-BOOL set_share_mode(share_lock_token token, int fnum, uint16 port)
+BOOL set_share_mode(share_lock_token token, int fnum, uint16 port, uint16 op_type)
{
files_struct *fs_p = &Files[fnum];
int32 dev, inode;
new_entry_p->share_mode = fs_p->share_mode;
#ifdef USE_OPLOCKS
new_entry_p->op_port = port;
+ new_entry_p->op_type = op_type;
#endif /* USE_OPLOCKS */
memcpy( (char *)&new_entry_p->time, (char *)&fs_p->open_time, sizeof(struct timeval));
share_array[num_entries_copied].pid = pid;
#ifdef USE_OPLOCKS
share_array[num_entries_copied].op_port = SVAL(p,SME_PORT_OFFSET);
+ share_array[num_entries_copied].op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
#endif /* USE_OPLOCKS */
num_entries_copied++;
SIVAL(p,SME_USEC_OFFSET,share_array[i].time.tv_usec);
#ifdef USE_OPLOCKS
SIVAL(p,SME_PORT_OFFSET,share_array[i].op_port);
+ SIVAL(p,SME_OPLOCK_TYPE_OFFSET,share_array[i].op_type);
#endif /* USE_OPLOCKS */
}
/*******************************************************************
set the share mode of a file
********************************************************************/
-BOOL set_share_mode(share_lock_token token,int fnum, uint16 port)
+BOOL set_share_mode(share_lock_token token,int fnum, uint16 port, uint16 op_type)
{
files_struct *fs_p = &Files[fnum];
pstring fname;
SIVAL(p,SME_PID_OFFSET,pid);
#ifdef USE_OPLOCKS
SSVAL(p,SME_PORT_OFFSET,port);
+ SSVAL(p,SME_OPLOCK_TYPE_OFFSET,op_type);
#endif /* USE_OPLOCKS */
num_entries++;
unixmode = unix_mode(cnum,smb_attr);
open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode,
- &rmode,&smb_action);
+ 0, &rmode,&smb_action);
if (!Files[fnum].open)
{
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))) {
+ fsp->granted_oplock = True;
}
+ 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);
+ fsp->granted_oplock = True;
}
+ if(fsp->granted_oplock)
+ smb_action |= EXTENDED_OPLOCK_GRANTED;
+
set_message(outbuf,15,0,True);
SSVAL(outbuf,smb_vwv2,fnum);
SSVAL(outbuf,smb_vwv3,fmode);
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))) {
+ fsp->granted_oplock = True;
}
-
+
+ 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))) {
+ fsp->granted_oplock = True;
}
+ 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));
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);
return(outsize);
}
-
-
-
-
-
/* Oplock ipc UDP socket. */
int oplock_sock = -1;
uint16 oplock_port = 0;
+/* Current number of oplocks we have outstanding. */
+uint32 oplocks_open = 0;
#endif /* USE_OPLOCKS */
extern fstring remote_machine;
pstring fname;
struct stat statbuf;
file_fd_struct *fd_ptr;
+ files_struct *fsp = &Files[fnum];
- Files[fnum].open = False;
- Files[fnum].fd_ptr = 0;
+ fsp->open = False;
+ fsp->fd_ptr = 0;
errno = EPERM;
pstrcpy(fname,fname1);
if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
lp_minprintspace(SNUM(cnum))) {
fd_attempt_close(fd_ptr);
- Files[fnum].fd_ptr = 0;
+ fsp->fd_ptr = 0;
if(fd_ptr->ref_count == 0)
sys_unlink(fname);
errno = ENOSPC;
fd_ptr->dev = (uint32)sbuf->st_dev;
fd_ptr->inode = (uint32)sbuf->st_ino;
- Files[fnum].fd_ptr = fd_ptr;
+ fsp->fd_ptr = fd_ptr;
Connections[cnum].num_files_open++;
- Files[fnum].mode = sbuf->st_mode;
- GetTimeOfDay(&Files[fnum].open_time);
- Files[fnum].uid = current_user.id;
- Files[fnum].size = 0;
- Files[fnum].pos = -1;
- Files[fnum].open = True;
- Files[fnum].mmap_ptr = NULL;
- Files[fnum].mmap_size = 0;
- Files[fnum].can_lock = True;
- Files[fnum].can_read = ((flags & O_WRONLY)==0);
- Files[fnum].can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
- Files[fnum].share_mode = 0;
- Files[fnum].print_file = Connections[cnum].printer;
- Files[fnum].modified = False;
- Files[fnum].cnum = cnum;
- string_set(&Files[fnum].name,dos_to_unix(fname,False));
- Files[fnum].wbmpx_ptr = NULL;
+ fsp->mode = sbuf->st_mode;
+ GetTimeOfDay(&fsp->open_time);
+ fsp->uid = current_user.id;
+ fsp->size = 0;
+ fsp->pos = -1;
+ fsp->open = True;
+ fsp->mmap_ptr = NULL;
+ fsp->mmap_size = 0;
+ fsp->can_lock = True;
+ fsp->can_read = ((flags & O_WRONLY)==0);
+ fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
+ fsp->share_mode = 0;
+ fsp->print_file = Connections[cnum].printer;
+ fsp->modified = False;
+ fsp->granted_oplock = False;
+ fsp->cnum = cnum;
+ string_set(&fsp->name,dos_to_unix(fname,False));
+ fsp->wbmpx_ptr = NULL;
/*
* If the printer is marked as postscript output a leading
* This has a similar effect as CtrlD=0 in WIN.INI file.
* tim@fsg.com 09/06/94
*/
- if (Files[fnum].print_file && POSTSCRIPT(cnum) &&
- Files[fnum].can_write)
+ if (fsp->print_file && POSTSCRIPT(cnum) &&
+ fsp->can_write)
{
DEBUG(3,("Writing postscript line\n"));
write_file(fnum,"%!\n",3);
DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
timestring(),Connections[cnum].user,fname,
- BOOLSTR(Files[fnum].can_read),BOOLSTR(Files[fnum].can_write),
+ BOOLSTR(fsp->can_read),BOOLSTR(fsp->can_write),
Connections[cnum].num_files_open,fnum));
}
#if USE_MMAP
/* mmap it if read-only */
- if (!Files[fnum].can_write)
+ if (!fsp->can_write)
{
- Files[fnum].mmap_size = file_size(fname);
- Files[fnum].mmap_ptr = (char *)mmap(NULL,Files[fnum].mmap_size,
- PROT_READ,MAP_SHARED,Files[fnum].fd_ptr->fd,0);
+ fsp->mmap_size = file_size(fname);
+ fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
+ PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
- if (Files[fnum].mmap_ptr == (char *)-1 || !Files[fnum].mmap_ptr)
+ if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr)
{
DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
- Files[fnum].mmap_ptr = NULL;
+ fsp->mmap_ptr = NULL;
}
}
#endif
}
}
+/****************************************************************************
+check if we can open a file with a share mode
+****************************************************************************/
+int check_share_mode( min_share_mode_entry *share, int deny_mode, char *fname,
+ BOOL fcbopen, int *flags)
+{
+ int old_open_mode = share->share_mode &0xF;
+ int old_deny_mode = (share->share_mode >>4)&7;
+
+ if (old_deny_mode > 4 || old_open_mode > 2)
+ {
+ DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
+ deny_mode,old_deny_mode,old_open_mode,fname));
+ return False;
+ }
+
+ {
+ int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
+ share->pid,fname);
+
+ if ((access_allowed == AFAIL) ||
+ (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
+ (access_allowed == AREAD && *flags == O_WRONLY) ||
+ (access_allowed == AWRITE && *flags == O_RDONLY))
+ {
+ DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
+ deny_mode,old_deny_mode,old_open_mode,
+ share->pid,fname, access_allowed));
+ return False;
+ }
+
+ if (access_allowed == AREAD)
+ *flags = O_RDONLY;
+
+ if (access_allowed == AWRITE)
+ *flags = O_WRONLY;
+
+ }
+ return True;
+}
/****************************************************************************
open a file with a share mode
****************************************************************************/
void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
- int mode,int *Access,int *action)
+ int mode,int oplock_request, int *Access,int *action)
{
files_struct *fs_p = &Files[fnum];
int flags=0;
int i;
min_share_mode_entry *old_shares = 0;
-
if (file_existed)
{
dev = (uint32)sbuf.st_dev;
num_shares = get_share_modes(cnum, token, dev, inode, &old_shares);
}
- for(i = 0; i < num_shares; i++)
- {
- /* someone else has a share lock on it, check to see
- if we can too */
- int old_open_mode = old_shares[i].share_mode &0xF;
- int old_deny_mode = (old_shares[i].share_mode >>4)&7;
+ /*
+ * Check if the share modes will give us access.
+ */
- if (old_deny_mode > 4 || old_open_mode > 2)
- {
- DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
- deny_mode,old_deny_mode,old_open_mode,fname));
- free((char *)old_shares);
- if(share_locked)
- unlock_share_entry(cnum, dev, inode, token);
- errno = EACCES;
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadshare;
- return;
- }
+ if(share_locked && (num_shares != 0))
+ {
+ BOOL broke_oplock;
+ do
{
- int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
- old_shares[i].pid,fname);
-
- if ((access_allowed == AFAIL) ||
- (!fcbopen && (access_allowed == AREAD && flags == O_RDWR)) ||
- (access_allowed == AREAD && flags == O_WRONLY) ||
- (access_allowed == AWRITE && flags == O_RDONLY))
+ broke_oplock = False;
+ for(i = 0; i < num_shares; i++)
{
- DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
- deny_mode,old_deny_mode,old_open_mode,
- old_shares[i].pid,fname,
- access_allowed));
- free((char *)old_shares);
- if(share_locked)
+ /* someone else has a share lock on it, check to see
+ if we can too */
+ if(check_share_mode(&old_shares[i], deny_mode, fname, fcbopen, &flags) == False)
+ {
+ free((char *)old_shares);
unlock_share_entry(cnum, dev, inode, token);
- errno = EACCES;
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadshare;
- return;
+ errno = EACCES;
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadshare;
+ return;
+ }
+#ifdef USE_OPLOCKS
+ /*
+ * The share modes would give us access. Check if someone
+ * has an oplock on this file. If so we must break it before
+ * continuing.
+ */
+ if(old_shares[i].op_type != 0)
+ {
+ /* Oplock break.... */
+ unlock_share_entry(cnum, dev, inode, token);
+#if 0 /* Work in progress..... */
+ if(break_oplock())
+ {
+ free((char *)old_shares);
+ /* Error condition here... */
+ }
+ lock_share_entry(cnum, dev, inode, &token);
+ broke_oplock = True;
+ break;
+#endif
+ }
+#endif /* USE_OPLOCKS */
}
-
- if (access_allowed == AREAD)
- flags = O_RDONLY;
-
- if (access_allowed == AWRITE)
- flags = O_WRONLY;
- }
+ if(broke_oplock)
+ {
+ free((char *)old_shares);
+ num_shares = get_share_modes(cnum, token, dev, inode, &old_shares);
+ }
+ } while(broke_oplock);
}
+
if(old_shares != 0)
free((char *)old_shares);
}
file (which expects the share_mode_entry to be there).
*/
if (lp_share_modes(SNUM(cnum)))
- set_share_mode(token, fnum, 0);
+ set_share_mode(token, fnum, 0, 0);
if ((flags2&O_TRUNC) && file_existed)
truncate_unless_locked(fnum,cnum,token,&share_locked);
if (oplock_sock == -1)
{
DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
-address %x. Error was %s\n", INADDR_LOOPBACK, strerror(errno)));
+address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
+ oplock_port = 0;
return(False);
}
strerror(errno)));
close(oplock_sock);
oplock_sock = -1;
+ oplock_port = 0;
return False;
}
oplock_port = ntohs(sock_name.sin_port);
/* Validate message from address (must be localhost). */
if(from_addr.s_addr != htonl(INADDR_LOOPBACK))
{
- DEBUG(0,("process_local_message: invalid from address \
+ DEBUG(0,("process_local_message: invalid 'from' address \
(was %x should be 127.0.0.1\n", from_addr.s_addr));
return False;
}
it can be used by the oplock break code.
****************************************************************************/
-static void process_smb(char *InBuffer, char *OutBuffer)
+static void process_smb(char *inbuf, char *outbuf)
{
extern int Client;
static int trans_num = 0;
- int msg_type = CVAL(InBuffer,0);
- int32 len = smb_len(InBuffer);
+ int msg_type = CVAL(inbuf,0);
+ int32 len = smb_len(outbuf);
int nread = len + 4;
DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
#ifdef WITH_VTP
- if(trans_num == 1 && VT_Check(InBuffer))
+ if(trans_num == 1 && VT_Check(inbuf))
{
VT_Process();
return;
#endif
if (msg_type == 0)
- show_msg(InBuffer);
+ show_msg(inbuf);
- nread = construct_reply(InBuffer,OutBuffer,nread,max_send);
+ nread = construct_reply(inbuf,outbuf,nread,max_send);
if(nread > 0)
{
- if (CVAL(OutBuffer,0) == 0)
- show_msg(OutBuffer);
+ if (CVAL(outbuf,0) == 0)
+ show_msg(outbuf);
- if (nread != smb_len(OutBuffer) + 4)
+ if (nread != smb_len(outbuf) + 4)
{
DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
- nread, smb_len(OutBuffer)));
+ nread, smb_len(outbuf)));
}
else
- send_smb(Client,OutBuffer);
+ send_smb(Client,outbuf);
}
trans_num++;
}
char *params = *pparams;
int16 open_mode = SVAL(params, 2);
int16 open_attr = SVAL(params,6);
- BOOL oplock_request = BITSETW(params,1);
+ BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
#if 0
BOOL return_additional_info = BITSETW(params,0);
int16 open_sattr = SVAL(params, 4);
open_file_shared(fnum,cnum,fname,open_mode,open_ofun,unixmode,
- &rmode,&smb_action);
+ oplock_request, &rmode,&smb_action);
if (!Files[fnum].open)
{
SSVAL(params,12,rmode);
if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
- smb_action |= (1<<15);
+ smb_action |= EXTENDED_OPLOCK_GRANTED;
}
SSVAL(params,18,smb_action);