mirror of
https://github.com/samba-team/samba.git
synced 2024-12-24 21:34:56 +03:00
Makefile.in: Moved UBIQX stuff into UTILOBJ.
loadparm.c: Added "ole locking compatibility" option (default "true").
locking.c: Changes to implement union in files_struct.
locking_shm.c: Changes to implement union in files_struct.
nttrans.c: Made opening a directory explicit (we have to).
Added create directory code for nttrans.
reply.c: Changes to implement union in files_struct.
server.c: Changes to implement union in files_struct. Added create directory code.
trans2.c: Changes to implement union in files_struct.
smb.h: Changes to implement union in files_struct.
util.c: Changed linked list code to UNIQX linked list. This will make
the other lists I need to implement for ChangeNotify and blocking
locks easier.
Jeremy.
(This used to be commit 3a5eea850b
)
This commit is contained in:
parent
7d5d83ecec
commit
7284bb5ca0
@ -131,7 +131,8 @@ PASSDB_OBJ = passdb.o ldap.o smbpass.o nisppass.o smbpassfile.o
|
||||
UTILOBJ1 = util.o system.o charset.o kanji.o fault.o smbencrypt.o smbdes.o charcnv.o genrand.o
|
||||
UTILOBJ2 = $(UTILOBJ1) md4.o loadparm.o params.o pcap.o username.o time.o membuffer.o namequery.o nmblib.o
|
||||
UTILOBJ3 = $(UTILOBJ2) signal.o netmask.o dfree.o
|
||||
UTILOBJ = $(UTILOBJ3) credentials.o interface.o replace.o print_svid.o smberr.o pidfile.o slprintf.o $(SSL_OBJ)
|
||||
UTILOBJ = $(UTILOBJ3) credentials.o interface.o replace.o print_svid.o smberr.o pidfile.o slprintf.o \
|
||||
$(SSL_OBJ) $(UBIOBJ)
|
||||
|
||||
# Client utility object files.
|
||||
CLIENTUTIL = clientgen.o nterr.o
|
||||
@ -141,7 +142,7 @@ SMBDOBJ1 = $(UTILOBJ) trans2.o nttrans.o message.o dir.o printing.o
|
||||
SMBDOBJ2 = ipc.o reply.o mangle.o chgpasswd.o password.o quotas.o uid.o
|
||||
SMBDOBJ3 = predict.o pipes.o server.o access.o
|
||||
SMBDOBJ4 = ufc.o connection.o groupname.o
|
||||
SMBDOBJ = $(SMBDOBJ1) $(SMBDOBJ2) $(SMBDOBJ3) $(SMBDOBJ4) $(UBIOBJ) $(RPC_OBJ) $(RPC_SERV_OBJ) \
|
||||
SMBDOBJ = $(SMBDOBJ1) $(SMBDOBJ2) $(SMBDOBJ3) $(SMBDOBJ4) $(RPC_OBJ) $(RPC_SERV_OBJ) \
|
||||
$(RPC_CLIENT_SERVER_SUBSET_OBJ) $(VTP_OBJ) $(LOCKOBJ) $(CLIENTUTIL) $(PASSDB_OBJ)
|
||||
|
||||
# object code needed for programs that handle the the locking files
|
||||
@ -155,7 +156,7 @@ NMBDOBJ4 = nmbd_sendannounce.o nmbd_processlogon.o nmbd_incomingdgrams.o
|
||||
NMBDOBJ5 = asyncdns.o nmbd_winsserver.o nmbd_incomingrequests.o nmbd_nameregister.o
|
||||
NMBDOBJ6 = nmbd_namerelease.o nmbd_namequery.o nmbd_become_lmb.o nmbd_elections.o nmbd_namelistdb.o
|
||||
|
||||
NMBDOBJ = $(UTILOBJ) $(NMBDOBJ1) $(NMBDOBJ2) $(NMBDOBJ3) $(NMBDOBJ4) $(NMBDOBJ5) $(NMBDOBJ6) $(CLIENTUTIL) $(UBIOBJ)
|
||||
NMBDOBJ = $(UTILOBJ) $(NMBDOBJ1) $(NMBDOBJ2) $(NMBDOBJ3) $(NMBDOBJ4) $(NMBDOBJ5) $(NMBDOBJ6) $(CLIENTUTIL)
|
||||
|
||||
# object files for smbclient
|
||||
CLIENT_OBJ = client.o clientutil.o clitar.o getsmbpass.o $(UTILOBJ)
|
||||
|
@ -1023,6 +1023,7 @@ BOOL lp_bind_interfaces_only(void);
|
||||
BOOL lp_net_wksta_user_logon(void);
|
||||
BOOL lp_unix_password_sync(void);
|
||||
BOOL lp_passwd_chat_debug(void);
|
||||
BOOL lp_ole_locking_compat(void);
|
||||
int lp_os_level(void);
|
||||
int lp_max_ttl(void);
|
||||
int lp_max_wins_ttl(void);
|
||||
@ -1804,7 +1805,7 @@ BOOL check_name(char *name,int cnum);
|
||||
void sync_file(int cnum, int fnum);
|
||||
void close_file(int fnum, BOOL normal_close);
|
||||
void close_directory(int fnum);
|
||||
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);
|
||||
BOOL check_file_sharing(int cnum,char *fname, BOOL rename_op);
|
||||
int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
|
||||
BOOL fcbopen, int *flags);
|
||||
@ -2043,7 +2044,7 @@ int read_smb_length(int fd,char *inbuf,int timeout);
|
||||
BOOL receive_smb(int fd,char *buffer, int timeout);
|
||||
BOOL client_receive_smb(int fd,char *buffer, int timeout);
|
||||
BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout);
|
||||
BOOL push_smb_message(char *buf, int msg_len);
|
||||
BOOL push_oplock_pending_smb_message(char *buf, int msg_len);
|
||||
BOOL receive_message_or_smb(int smbfd, int oplock_fd,
|
||||
char *buffer, int buffer_len,
|
||||
int timeout, BOOL *got_smb);
|
||||
|
@ -169,6 +169,7 @@ implemented */
|
||||
#define ERRbaddirectory 267 /* Invalid directory name in a path. */
|
||||
#define ERROR_EAS_DIDNT_FIT 275 /* Extended attributes didn't fit */
|
||||
#define ERROR_EAS_NOT_SUPPORTED 282 /* Extended attributes not supported */
|
||||
#define ERROR_NOTIFY_ENUM_DIR 1022 /* Buffer too small to return change notify. */
|
||||
#define ERRunknownipc 2142
|
||||
|
||||
|
||||
@ -437,10 +438,24 @@ typedef struct
|
||||
int real_open_flags;
|
||||
} file_fd_struct;
|
||||
|
||||
/*
|
||||
* Structure used to keep directory state information around.
|
||||
* Used in NT change-notify code.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
time_t modify_time;
|
||||
time_t status_time;
|
||||
} dir_status_struct;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int cnum;
|
||||
file_fd_struct *fd_ptr;
|
||||
union {
|
||||
file_fd_struct *fd_ptr;
|
||||
dir_status_struct *dir_ptr;
|
||||
} f_u;
|
||||
int pos;
|
||||
uint32 size;
|
||||
int mode;
|
||||
@ -463,7 +478,6 @@ typedef struct
|
||||
char *name;
|
||||
} files_struct;
|
||||
|
||||
|
||||
struct uid_cache {
|
||||
int entries;
|
||||
int list[UID_CACHE_SIZE];
|
||||
|
@ -2611,27 +2611,27 @@ BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout)
|
||||
for processing.
|
||||
****************************************************************************/
|
||||
|
||||
typedef struct _message_list {
|
||||
struct _message_list *msg_next;
|
||||
typedef struct smb_message_list {
|
||||
ubi_slNode msg_next;
|
||||
char *msg_buf;
|
||||
int msg_len;
|
||||
} pending_message_list;
|
||||
|
||||
static pending_message_list *smb_msg_head = NULL;
|
||||
static ubi_slList smb_oplock_queue = { NULL, (ubi_slNodePtr)&smb_oplock_queue, 0};
|
||||
|
||||
/****************************************************************************
|
||||
Function to push a linked list of local messages ready
|
||||
Function to push a message onto the tail of a linked list of smb messages ready
|
||||
for processing.
|
||||
****************************************************************************/
|
||||
|
||||
static BOOL push_local_message(pending_message_list **pml, char *buf, int msg_len)
|
||||
static BOOL push_local_message(ubi_slList *list_head, char *buf, int msg_len)
|
||||
{
|
||||
pending_message_list *msg = (pending_message_list *)
|
||||
malloc(sizeof(pending_message_list));
|
||||
|
||||
if(msg == NULL)
|
||||
{
|
||||
DEBUG(0,("push_message: malloc fail (1)\n"));
|
||||
DEBUG(0,("push_local_message: malloc fail (1)\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
@ -2646,20 +2646,19 @@ static BOOL push_local_message(pending_message_list **pml, char *buf, int msg_le
|
||||
memcpy(msg->msg_buf, buf, msg_len);
|
||||
msg->msg_len = msg_len;
|
||||
|
||||
msg->msg_next = *pml;
|
||||
*pml = msg;
|
||||
ubi_slAddTail( list_head, msg);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Function to push a linked list of local smb messages ready
|
||||
Function to push a smb message onto a linked list of local smb messages ready
|
||||
for processing.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL push_smb_message(char *buf, int msg_len)
|
||||
BOOL push_oplock_pending_smb_message(char *buf, int msg_len)
|
||||
{
|
||||
return push_local_message(&smb_msg_head, buf, msg_len);
|
||||
return push_local_message(&smb_oplock_queue, buf, msg_len);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -2699,11 +2698,10 @@ BOOL receive_message_or_smb(int smbfd, int oplock_fd,
|
||||
* If so - copy and return it.
|
||||
*/
|
||||
|
||||
if(smb_msg_head)
|
||||
if(ubi_slCount(&smb_oplock_queue) != 0)
|
||||
{
|
||||
pending_message_list *msg = smb_msg_head;
|
||||
pending_message_list *msg = (pending_message_list *)ubi_slRemHead(&smb_oplock_queue);
|
||||
memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
|
||||
smb_msg_head = msg->msg_next;
|
||||
|
||||
/* Free the message we just copied. */
|
||||
free((char *)msg->msg_buf);
|
||||
@ -4629,35 +4627,47 @@ BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
|
||||
struct flock lock;
|
||||
int ret;
|
||||
|
||||
#if 1
|
||||
uint32 mask = 0xC0000000;
|
||||
/*
|
||||
* FIXME.
|
||||
* NB - this code will need re-writing to cope with large (64bit)
|
||||
* lock requests. JRA.
|
||||
*/
|
||||
|
||||
/* make sure the count is reasonable, we might kill the lockd otherwise */
|
||||
count &= ~mask;
|
||||
if(lp_ole_locking_compat()) {
|
||||
uint32 mask = 0xC0000000;
|
||||
|
||||
/* the offset is often strange - remove 2 of its bits if either of
|
||||
the top two bits are set. Shift the top ones by two bits. This
|
||||
still allows OLE2 apps to operate, but should stop lockd from
|
||||
dieing */
|
||||
if ((offset & mask) != 0)
|
||||
offset = (offset & ~mask) | ((offset & mask) >> 2);
|
||||
#else
|
||||
uint32 mask = ((unsigned)1<<31);
|
||||
|
||||
/* interpret negative counts as large numbers */
|
||||
if (count < 0)
|
||||
/* make sure the count is reasonable, we might kill the lockd otherwise */
|
||||
count &= ~mask;
|
||||
|
||||
/* no negative offsets */
|
||||
offset &= ~mask;
|
||||
/* the offset is often strange - remove 2 of its bits if either of
|
||||
the top two bits are set. Shift the top ones by two bits. This
|
||||
still allows OLE2 apps to operate, but should stop lockd from
|
||||
dieing */
|
||||
if ((offset & mask) != 0)
|
||||
offset = (offset & ~mask) | ((offset & mask) >> 2);
|
||||
} else {
|
||||
uint32 mask = ((unsigned)1<<31);
|
||||
int32 s_count = (int32) count; /* Signed count. */
|
||||
int32 s_offset = (int32)offset; /* Signed offset. */
|
||||
|
||||
/* count + offset must be in range */
|
||||
while ((offset < 0 || (offset + count < 0)) && mask)
|
||||
/* interpret negative counts as large numbers */
|
||||
if (s_count < 0)
|
||||
s_count &= ~mask;
|
||||
|
||||
/* no negative offsets */
|
||||
if(s_offset < 0)
|
||||
s_offset &= ~mask;
|
||||
|
||||
/* count + offset must be in range */
|
||||
while ((s_offset < 0 || (s_offset + s_count < 0)) && mask)
|
||||
{
|
||||
offset &= ~mask;
|
||||
s_offset &= ~mask;
|
||||
mask = mask >> 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
offset = (uint32)s_offset;
|
||||
count = (uint32)s_count;
|
||||
}
|
||||
|
||||
|
||||
DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
|
||||
|
@ -45,7 +45,7 @@ static struct share_ops *share_ops;
|
||||
|
||||
static int map_lock_type( files_struct *fsp, int lock_type)
|
||||
{
|
||||
if((lock_type == F_WRLCK) && (fsp->fd_ptr->real_open_flags == O_RDONLY)) {
|
||||
if((lock_type == F_WRLCK) && (fsp->f_u.fd_ptr->real_open_flags == O_RDONLY)) {
|
||||
/*
|
||||
* Many UNIX's cannot get a write lock on a file opened read-only.
|
||||
* Win32 locking semantics allow this.
|
||||
@ -53,7 +53,7 @@ static int map_lock_type( files_struct *fsp, int lock_type)
|
||||
*/
|
||||
DEBUG(10,("map_lock_type: Downgrading write lock to read due to read-only file.\n"));
|
||||
return F_RDLCK;
|
||||
} else if( (lock_type == F_RDLCK) && (fsp->fd_ptr->real_open_flags == O_WRONLY)) {
|
||||
} else if( (lock_type == F_RDLCK) && (fsp->f_u.fd_ptr->real_open_flags == O_WRONLY)) {
|
||||
/*
|
||||
* Ditto for read locks on write only files.
|
||||
*/
|
||||
@ -90,7 +90,7 @@ BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset, int lock_type)
|
||||
* fd. So we don't need to use map_lock_type here.
|
||||
*/
|
||||
|
||||
return(fcntl_lock(fsp->fd_ptr->fd,F_GETLK,offset,count,lock_type));
|
||||
return(fcntl_lock(fsp->f_u.fd_ptr->fd,F_GETLK,offset,count,lock_type));
|
||||
}
|
||||
|
||||
|
||||
@ -114,7 +114,7 @@ BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int lock_type,
|
||||
}
|
||||
|
||||
if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->cnum == cnum))
|
||||
ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count,
|
||||
ok = fcntl_lock(fsp->f_u.fd_ptr->fd,F_SETLK,offset,count,
|
||||
map_lock_type(fsp,lock_type));
|
||||
|
||||
if (!ok) {
|
||||
@ -139,7 +139,7 @@ BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *
|
||||
return(True);
|
||||
|
||||
if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->cnum == cnum))
|
||||
ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count,F_UNLCK);
|
||||
ok = fcntl_lock(fsp->f_u.fd_ptr->fd,F_SETLK,offset,count,F_UNLCK);
|
||||
|
||||
if (!ok) {
|
||||
*eclass = ERRDOS;
|
||||
|
@ -268,8 +268,8 @@ static void shm_del_share_mode(int token, int fnum)
|
||||
BOOL found = False;
|
||||
int pid = getpid();
|
||||
|
||||
dev = Files[fnum].fd_ptr->dev;
|
||||
inode = Files[fnum].fd_ptr->inode;
|
||||
dev = Files[fnum].f_u.fd_ptr->dev;
|
||||
inode = Files[fnum].f_u.fd_ptr->inode;
|
||||
|
||||
hash_entry = HASH_ENTRY(dev, inode);
|
||||
|
||||
@ -396,8 +396,8 @@ static BOOL shm_set_share_mode(int token, int fnum, uint16 port, uint16 op_type)
|
||||
int new_entry_offset;
|
||||
BOOL found = False;
|
||||
|
||||
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;
|
||||
|
||||
hash_entry = HASH_ENTRY(dev, inode);
|
||||
|
||||
@ -505,8 +505,8 @@ static BOOL shm_remove_share_oplock(int fnum, int token)
|
||||
BOOL found = False;
|
||||
int pid = getpid();
|
||||
|
||||
dev = Files[fnum].fd_ptr->dev;
|
||||
inode = Files[fnum].fd_ptr->inode;
|
||||
dev = Files[fnum].f_u.fd_ptr->dev;
|
||||
inode = Files[fnum].f_u.fd_ptr->inode;
|
||||
|
||||
hash_entry = HASH_ENTRY(dev, inode);
|
||||
|
||||
|
@ -222,6 +222,7 @@ typedef struct
|
||||
BOOL bNetWkstaUserLogon;
|
||||
BOOL bUnixPasswdSync;
|
||||
BOOL bPasswdChatDebug;
|
||||
BOOL bOleLockingCompat;
|
||||
} global;
|
||||
|
||||
static global Globals;
|
||||
@ -675,6 +676,7 @@ static struct parm_struct parm_table[] =
|
||||
{"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_GLOBAL},
|
||||
{"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_GLOBAL},
|
||||
{"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, 0},
|
||||
{"ole locking compatibility", P_BOOL, P_GLOBAL, &Globals.bOleLockingCompat, NULL, NULL, FLAG_GLOBAL},
|
||||
|
||||
#ifdef WITH_LDAP
|
||||
{"Ldap Options", P_SEP, P_SEPARATOR},
|
||||
@ -832,6 +834,7 @@ static void init_globals(void)
|
||||
the code in password.c protects us from this bug. */
|
||||
Globals.bUnixPasswdSync = False;
|
||||
Globals.bPasswdChatDebug = False;
|
||||
Globals.bOleLockingCompat = True;
|
||||
|
||||
#ifdef WITH_LDAP
|
||||
/* default values for ldap */
|
||||
@ -1120,6 +1123,7 @@ FN_GLOBAL_BOOL(lp_bind_interfaces_only,&Globals.bBindInterfacesOnly)
|
||||
FN_GLOBAL_BOOL(lp_net_wksta_user_logon,&Globals.bNetWkstaUserLogon)
|
||||
FN_GLOBAL_BOOL(lp_unix_password_sync,&Globals.bUnixPasswdSync)
|
||||
FN_GLOBAL_BOOL(lp_passwd_chat_debug,&Globals.bPasswdChatDebug)
|
||||
FN_GLOBAL_BOOL(lp_ole_locking_compat,&Globals.bOleLockingCompat)
|
||||
|
||||
FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
|
||||
FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
|
||||
|
@ -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);
|
||||
|
||||
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_action);
|
||||
|
||||
if(!fsp->open) {
|
||||
fsp->reserved = False;
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
}
|
||||
} else {
|
||||
if((errno == ENOENT) && bad_path) {
|
||||
unix_ERR_class = ERRDOS;
|
||||
unix_ERR_code = ERRbadpath;
|
||||
}
|
||||
restore_case_semantics(file_attributes);
|
||||
|
||||
if(!fsp->open) {
|
||||
fsp->reserved = False;
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
/*
|
||||
* Ordinary file case.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
fsp->reserved = False;
|
||||
|
||||
restore_case_semantics(file_attributes);
|
||||
|
||||
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);
|
||||
|
||||
fsp = &Files[fnum];
|
||||
|
||||
if (!fsp->open) {
|
||||
if((errno == ENOENT) && bad_path) {
|
||||
unix_ERR_class = ERRDOS;
|
||||
unix_ERR_code = ERRbadpath;
|
||||
}
|
||||
Files[fnum].reserved = False;
|
||||
|
||||
restore_case_semantics(file_attributes);
|
||||
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
}
|
||||
|
||||
if (fstat(fsp->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)
|
||||
fmode = FILE_ATTRIBUTE_NORMAL;
|
||||
mtime = sbuf.st_mtime;
|
||||
if (fmode & aDIR) {
|
||||
close_file(fnum,False);
|
||||
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 it's a request for a directory open, deal with it separately.
|
||||
*/
|
||||
|
||||
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));
|
||||
}
|
||||
} else {
|
||||
|
||||
/*
|
||||
* Ordinary file case.
|
||||
*/
|
||||
|
||||
open_file_shared(fnum,cnum,fname,smb_open_mode,smb_ofun,unixmode,
|
||||
oplock_request,&rmode,&smb_action);
|
||||
|
||||
fsp = &Files[fnum];
|
||||
|
||||
if (oplock_request && lp_fake_oplocks(SNUM(cnum)))
|
||||
smb_action |= EXTENDED_OPLOCK_GRANTED;
|
||||
if (!fsp->open) {
|
||||
if((errno == ENOENT) && bad_path) {
|
||||
unix_ERR_class = ERRDOS;
|
||||
unix_ERR_code = ERRbadpath;
|
||||
}
|
||||
Files[fnum].reserved = False;
|
||||
|
||||
restore_case_semantics(file_attributes);
|
||||
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
}
|
||||
|
||||
if(oplock_request && fsp->granted_oplock)
|
||||
smb_action |= EXTENDED_OPLOCK_GRANTED;
|
||||
if (fstat(fsp->f_u.fd_ptr->fd,&sbuf) != 0) {
|
||||
close_file(fnum,False);
|
||||
|
||||
restore_case_semantics(file_attributes);
|
||||
|
||||
return(ERROR(ERRDOS,ERRnoaccess));
|
||||
}
|
||||
|
||||
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 && 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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
fsp->fd_ptr = NULL;
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user