mirror of
https://github.com/samba-team/samba.git
synced 2025-03-02 08:58:33 +03:00
locking.c: Added fix for race condition in slow share mode code.
lsaparse.c: #ifdef'ed out code so this will compile - LUKE PLEASE CHECK THIS. pipes.c: #ifdef'ed out code so this will compile - LUKE PLEASE CHECK THIS. server.c: Fixed last known oplock race condition. smb.h: Re-removed USE_OPLOCK defines - someone checked in an old version. smbparse.c: #ifdef'ed out code so this will compile - LUKE PLEASE CHECK THIS. Jeremy (jallison@whistle.com)
This commit is contained in:
parent
bef12478d2
commit
1e1366ddc5
@ -1042,10 +1042,8 @@ typedef struct
|
||||
{
|
||||
smb_shm_offset_t next_share_mode_entry;
|
||||
int pid;
|
||||
#ifdef USE_OPLOCKS
|
||||
uint16 op_port;
|
||||
uint16 op_type;
|
||||
#endif /* USE_OPLOCKS */
|
||||
int share_mode;
|
||||
struct timeval time;
|
||||
} share_mode_entry;
|
||||
@ -1054,10 +1052,8 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
int pid;
|
||||
#ifdef USE_OPLOCKS
|
||||
uint16 op_port;
|
||||
uint16 op_type;
|
||||
#endif /* USE_OPLOCKS */
|
||||
int share_mode;
|
||||
struct timeval time;
|
||||
} min_share_mode_entry;
|
||||
@ -1083,11 +1079,7 @@ struct connect_record
|
||||
};
|
||||
|
||||
#ifndef LOCKING_VERSION
|
||||
#ifdef USE_OPLOCKS
|
||||
#define LOCKING_VERSION 4
|
||||
#else /* USE_OPLOCKS */
|
||||
#define LOCKING_VERSION 3
|
||||
#endif /* USE_OPLOCKS */
|
||||
#endif /* LOCKING_VERSION */
|
||||
|
||||
#if !defined(FAST_SHARE_MODES)
|
||||
@ -1103,11 +1095,7 @@ struct connect_record
|
||||
#define SMF_FILENAME_LEN_OFFSET 8
|
||||
#define SMF_HEADER_LENGTH 10
|
||||
|
||||
#ifdef USE_OPLOCKS
|
||||
#define SMF_ENTRY_LENGTH 20
|
||||
#else /* USE_OPLOCKS */
|
||||
#define SMF_ENTRY_LENGTH 16
|
||||
#endif /* USE_OPLOCKS */
|
||||
|
||||
/*
|
||||
* Share mode record offsets.
|
||||
@ -1117,11 +1105,8 @@ struct connect_record
|
||||
#define SME_USEC_OFFSET 4
|
||||
#define SME_SHAREMODE_OFFSET 8
|
||||
#define SME_PID_OFFSET 12
|
||||
|
||||
#ifdef USE_OPLOCKS
|
||||
#define SME_PORT_OFFSET 16
|
||||
#define SME_OPLOCK_TYPE_OFFSET 18
|
||||
#endif /* USE_OPLOCKS */
|
||||
|
||||
#endif /* FAST_SHARE_MODES */
|
||||
|
||||
|
@ -25,6 +25,10 @@
|
||||
|
||||
May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
|
||||
locking to deal with multiple share modes per open file.
|
||||
|
||||
September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
|
||||
support.
|
||||
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
@ -726,13 +730,60 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok
|
||||
|
||||
{
|
||||
int old_umask;
|
||||
BOOL gotlock = False;
|
||||
unbecome_user();
|
||||
old_umask = umask(0);
|
||||
|
||||
/*
|
||||
* There was a race condition in the original slow share mode code.
|
||||
* A smbd could open a share mode file, and before getting
|
||||
* the lock, another smbd could delete the last entry for
|
||||
* the share mode file and delete the file entry from the
|
||||
* directory. Thus this smbd would be left with a locked
|
||||
* share mode fd attached to a file that no longer had a
|
||||
* directory entry. Thus another smbd would think that
|
||||
* there were no outstanding opens on the file. To fix
|
||||
* this we now check we can do a stat() call on the filename
|
||||
* before allowing the lock to proceed, and back out completely
|
||||
* and try the open again if we cannot.
|
||||
* Jeremy Allison (jallison@whistle.com).
|
||||
*/
|
||||
|
||||
do
|
||||
{
|
||||
struct stat dummy_stat;
|
||||
|
||||
#ifdef SECURE_SHARE_MODES
|
||||
fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0600);
|
||||
fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0600);
|
||||
#else /* SECURE_SHARE_MODES */
|
||||
fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0666);
|
||||
fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0666);
|
||||
#endif /* SECURE_SHARE_MODES */
|
||||
|
||||
/* At this point we have an open fd to the share mode file.
|
||||
Lock the first byte exclusively to signify a lock. */
|
||||
if(fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False)
|
||||
{
|
||||
DEBUG(0,("ERROR lock_share_entry: fcntl_lock on file %s failed with %s\n",
|
||||
fname, strerror(errno)));
|
||||
close(fd);
|
||||
return False;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we cannot stat the filename, the file was deleted between
|
||||
* the open and the lock call. Back out and try again.
|
||||
*/
|
||||
|
||||
if(stat(fname, &dummy_stat)!=0)
|
||||
{
|
||||
DEBUG(2,("lock_share_entry: Re-issuing open on %s to fix race. Error was %s\n",
|
||||
fname, strerror(errno)));
|
||||
close(fd);
|
||||
}
|
||||
else
|
||||
gotlock = True;
|
||||
} while(!gotlock);
|
||||
|
||||
umask(old_umask);
|
||||
if(!become_user(cnum,Connections[cnum].vuid))
|
||||
{
|
||||
@ -750,18 +801,8 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok
|
||||
}
|
||||
}
|
||||
|
||||
/* At this point we have an open fd to the share mode file.
|
||||
Lock the first byte exclusively to signify a lock. */
|
||||
if(fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False)
|
||||
{
|
||||
DEBUG(0,("ERROR lock_share_entry: fcntl_lock failed with %s\n",
|
||||
strerror(errno)));
|
||||
close(fd);
|
||||
return False;
|
||||
}
|
||||
|
||||
*ptok = (share_lock_token)fd;
|
||||
return True;
|
||||
*ptok = (share_lock_token)fd;
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
@ -781,7 +822,7 @@ BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token tok
|
||||
ret = False;
|
||||
}
|
||||
|
||||
close((int)token);
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
|
||||
#if 0 /* NEED TO DO THIS TO GET A COMPILE - LUKE PLEASE CHECK THIS !!! */
|
||||
/*******************************************************************
|
||||
reads or writes an LSA_R_OPEN_POL structure.
|
||||
********************************************************************/
|
||||
@ -446,6 +447,7 @@ char* lsa_io_r_sam_logoff(BOOL io, LSA_R_SAM_LOGOFF *r_l, char *q, char *base, i
|
||||
return q;
|
||||
}
|
||||
|
||||
#endif /* 0 LUKE PLEASE CHECK !! */
|
||||
#if 0
|
||||
/*******************************************************************
|
||||
reads or writes a structure.
|
||||
|
@ -364,6 +364,8 @@ BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data,
|
||||
return(True);
|
||||
}
|
||||
|
||||
#if 0 /* HAVING TO DO THIS TO GET THINGS TO COMPILE - LUKE PLEASE CHECK THIS !!! */
|
||||
|
||||
/*
|
||||
PAXX: Someone fix above.
|
||||
The above API is indexing RPC calls based on RPC flags and
|
||||
@ -757,3 +759,5 @@ static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base,
|
||||
/* return length of SMB data stored */
|
||||
return q - start;
|
||||
}
|
||||
|
||||
#endif /* LUKE PLEASE CHECK THIS !! */
|
||||
|
@ -2455,6 +2455,9 @@ address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
|
||||
}
|
||||
oplock_port = ntohs(sock_name.sin_port);
|
||||
|
||||
DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n",
|
||||
getpid(), oplock_port));
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
@ -2545,6 +2548,31 @@ pid %d, port %d, for file dev = %x, inode = %x\n", remotepid,
|
||||
|
||||
}
|
||||
break;
|
||||
/*
|
||||
* Keep this as a debug case - eventually we can remove it.
|
||||
*/
|
||||
case 0x8001:
|
||||
DEBUG(0,("process_local_message: Received unsolicited break \
|
||||
reply - dumping info.\n"));
|
||||
|
||||
if(msg_len != OPLOCK_BREAK_MSG_LEN)
|
||||
{
|
||||
DEBUG(0,("process_local_message: ubr: incorrect length for reply \
|
||||
(was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
|
||||
return False;
|
||||
}
|
||||
|
||||
{
|
||||
uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
|
||||
uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
|
||||
uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
|
||||
|
||||
DEBUG(0,("process_local_message: unsolicited oplock break reply from \
|
||||
pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
|
||||
|
||||
}
|
||||
return False;
|
||||
|
||||
default:
|
||||
DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
|
||||
(unsigned int)SVAL(msg_start,0)));
|
||||
@ -2860,6 +2888,7 @@ oplock break response from pid %d on port %d for dev = %x, inode = %x.\n",
|
||||
share_entry->pid, share_entry->op_port, dev, inode));
|
||||
if(push_local_message(op_break_reply, sizeof(op_break_reply)) == False)
|
||||
return False;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -456,7 +456,9 @@ char* smb_io_dom_query(BOOL io, DOM_QUERY *d_q, char *q, char *base, int align)
|
||||
|
||||
if (d_q->buffer_dom_name != 0)
|
||||
{
|
||||
#if 0 /* REMOVED AS WON'T COMPILE AS IS - LUKE PLEASE CHECK !!!!! */
|
||||
q = smb_io_unistr(io, &(d_q->uni_domain_name), q, base, align); /* domain name (unicode string) */
|
||||
#endif
|
||||
}
|
||||
if (d_q->buffer_dom_sid != 0)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user