diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/proto.h | 10 | ||||
-rw-r--r-- | source3/include/smb.h | 50 | ||||
-rw-r--r-- | source3/lib/util.c | 75 | ||||
-rw-r--r-- | source3/locking/locking.c | 9 | ||||
-rw-r--r-- | source3/smbd/pipes.c | 2 | ||||
-rw-r--r-- | source3/smbd/reply.c | 79 | ||||
-rw-r--r-- | source3/smbd/server.c | 227 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 6 |
8 files changed, 291 insertions, 167 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 46a96a8bef..8903437d00 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -299,13 +299,13 @@ BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token tok 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 */ @@ -707,8 +707,10 @@ int fd_attempt_close(file_fd_struct *fd_ptr); 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); @@ -979,3 +981,5 @@ void file_unlock(int fd); 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); diff --git a/source3/include/smb.h b/source3/include/smb.h index 435b71f4db..07614194f7 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -330,6 +330,7 @@ typedef struct BOOL share_mode; BOOL print_file; BOOL modified; + BOOL granted_oplock; char *name; } files_struct; @@ -454,6 +455,7 @@ typedef struct int pid; #ifdef USE_OPLOCKS uint16 op_port; + uint16 op_type; #endif /* USE_OPLOCKS */ int share_mode; struct timeval time; @@ -465,6 +467,7 @@ typedef struct int pid; #ifdef USE_OPLOCKS uint16 op_port; + uint16 op_type; #endif /* USE_OPLOCKS */ int share_mode; struct timeval time; @@ -514,7 +517,7 @@ struct connect_record #ifdef USE_OPLOCKS #define SMF_ENTRY_LENGTH 16 #else /* USE_OPLOCKS */ -#define SMF_ENTRY_LENGTH 18 +#define SMF_ENTRY_LENGTH 20 #endif /* USE_OPLOCKS */ /* @@ -528,6 +531,7 @@ struct connect_record #ifdef USE_OPLOCKS #define SME_PORT_OFFSET 16 +#define SME_OPLOCK_TYPE_OFFSET 18 #endif /* USE_OPLOCKS */ #endif /* FAST_SHARE_MODES */ @@ -971,16 +975,52 @@ enum case_handling {CASE_LOWER,CASE_UPPER}; #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 */ diff --git a/source3/lib/util.c b/source3/lib/util.c index 8ffc11068a..05dd619813 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -4061,53 +4061,52 @@ enum remote_arch_types get_remote_arch() 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))); + } +} diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 64f24fb242..7aa0e7dcf9 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -285,6 +285,7 @@ bucket (number of entries now = %d)\n", 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)); @@ -464,7 +465,7 @@ dev = %d, inode = %d in hash bucket %d\n", dev, inode, hash_entry)); /******************************************************************* 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; @@ -557,6 +558,7 @@ inode %d in hash bucket %d\n", fs_p->name, dev, inode, hash_entry)); 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)); @@ -892,6 +894,7 @@ it left a share mode entry with mode 0x%X in share file %s\n", 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++; @@ -939,6 +942,7 @@ position 0 for share mode file %s (%s)\n", fname, strerror(errno))); 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 */ } @@ -1120,7 +1124,7 @@ mode file %s to size %d (%s)\n", fname, newsize, strerror(errno))); /******************************************************************* 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; @@ -1222,6 +1226,7 @@ deleting it.\n", 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++; diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index feb8d91a5b..a465e91145 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -127,7 +127,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) 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) { diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index c1422bbcf6..94839c227a 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1099,6 +1099,8 @@ int reply_open(char *inbuf,char *outbuf) 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); @@ -1123,9 +1125,12 @@ int reply_open(char *inbuf,char *outbuf) 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) { @@ -1135,7 +1140,7 @@ int reply_open(char *inbuf,char *outbuf) 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)); } @@ -1157,10 +1162,12 @@ int reply_open(char *inbuf,char *outbuf) 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); } @@ -1175,7 +1182,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) 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); @@ -1187,6 +1194,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) 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)) @@ -1214,9 +1222,11 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) 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) { @@ -1226,7 +1236,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) 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)); } @@ -1240,9 +1250,12 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) } 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); @@ -1302,6 +1315,8 @@ int reply_mknew(char *inbuf,char *outbuf) 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); @@ -1343,9 +1358,12 @@ int reply_mknew(char *inbuf,char *outbuf) } /* 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) { @@ -1358,10 +1376,13 @@ int reply_mknew(char *inbuf,char *outbuf) 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)); @@ -1382,6 +1403,8 @@ int reply_ctemp(char *inbuf,char *outbuf) 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); @@ -1409,9 +1432,12 @@ int reply_ctemp(char *inbuf,char *outbuf) /* 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) { @@ -1426,10 +1452,13 @@ int reply_ctemp(char *inbuf,char *outbuf) 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)); @@ -2432,7 +2461,8 @@ int reply_printopen(char *inbuf,char *outbuf) 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)); @@ -3094,7 +3124,7 @@ static BOOL copy_file(char *src,char *dest1,int cnum,int ofun, 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); @@ -3107,7 +3137,7 @@ static BOOL copy_file(char *src,char *dest1,int cnum,int ofun, 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); @@ -3713,8 +3743,3 @@ int reply_getattrE(char *inbuf,char *outbuf) return(outsize); } - - - - - diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 22c8448dde..d2ad803c9c 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -88,6 +88,8 @@ static int num_connections_open = 0; /* 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; @@ -1052,9 +1054,10 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct 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); @@ -1192,7 +1195,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); - Files[fnum].fd_ptr = 0; + fsp->fd_ptr = 0; if(fd_ptr->ref_count == 0) sys_unlink(fname); errno = ENOSPC; @@ -1228,25 +1231,26 @@ 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; - 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 @@ -1255,8 +1259,8 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct * 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); @@ -1264,23 +1268,23 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct 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 @@ -1512,12 +1516,52 @@ static void truncate_unless_locked(int fnum, int cnum, share_lock_token token, } } +/**************************************************************************** +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; @@ -1605,7 +1649,6 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun, int i; min_share_mode_entry *old_shares = 0; - if (file_existed) { dev = (uint32)sbuf.st_dev; @@ -1615,55 +1658,61 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun, 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); } @@ -1720,7 +1769,7 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun, 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); @@ -2279,7 +2328,8 @@ static BOOL open_oplock_ipc() 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); } @@ -2290,6 +2340,7 @@ address %x. Error was %s\n", INADDR_LOOPBACK, strerror(errno))); strerror(errno))); close(oplock_sock); oplock_sock = -1; + oplock_port = 0; return False; } oplock_port = ntohs(sock_name.sin_port); @@ -2324,7 +2375,7 @@ static BOOL process_local_message(int oplock_sock, char *buffer, int buf_size) /* 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; } @@ -4010,20 +4061,20 @@ int construct_reply(char *inbuf,char *outbuf,int size,int bufsize) 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; @@ -4031,22 +4082,22 @@ static void process_smb(char *InBuffer, char *OutBuffer) #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++; } diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 59e9ef21b0..8ab024ded2 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -166,7 +166,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum, 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); @@ -213,7 +213,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum, open_file_shared(fnum,cnum,fname,open_mode,open_ofun,unixmode, - &rmode,&smb_action); + oplock_request, &rmode,&smb_action); if (!Files[fnum].open) { @@ -252,7 +252,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum, 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); |