summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>1997-10-07 18:46:19 +0000
committerJeremy Allison <jra@samba.org>1997-10-07 18:46:19 +0000
commit1e1366ddc5542283a37debdf830ca139bbade1b0 (patch)
treec1a6a329284f0020dded65a47a90404e75a9554a
parentbef12478d212a950578843d6d4dece1f153bfd25 (diff)
downloadsamba-1e1366ddc5542283a37debdf830ca139bbade1b0.tar.gz
samba-1e1366ddc5542283a37debdf830ca139bbade1b0.tar.xz
samba-1e1366ddc5542283a37debdf830ca139bbade1b0.zip
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)
-rw-r--r--source/include/smb.h15
-rw-r--r--source/locking/locking.c71
-rw-r--r--source/lsaparse.c2
-rw-r--r--source/smbd/pipes.c4
-rw-r--r--source/smbd/server.c29
-rw-r--r--source/smbparse.c2
6 files changed, 93 insertions, 30 deletions
diff --git a/source/include/smb.h b/source/include/smb.h
index 3adb3e5a4cb..c347202743c 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -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 */
diff --git a/source/locking/locking.c b/source/locking/locking.c
index 6e321d0626e..639bc7be0ba 100644
--- a/source/locking/locking.c
+++ b/source/locking/locking.c
@@ -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;
}
diff --git a/source/lsaparse.c b/source/lsaparse.c
index 2113b19cd33..b1d9d739240 100644
--- a/source/lsaparse.c
+++ b/source/lsaparse.c
@@ -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.
diff --git a/source/smbd/pipes.c b/source/smbd/pipes.c
index 95b69ef4d97..ffa64a4e808 100644
--- a/source/smbd/pipes.c
+++ b/source/smbd/pipes.c
@@ -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 !! */
diff --git a/source/smbd/server.c b/source/smbd/server.c
index 4f5b01ba91e..92c219c71b3 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -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;
diff --git a/source/smbparse.c b/source/smbparse.c
index 7ea140f7cb7..ae1f4f4b253 100644
--- a/source/smbparse.c
+++ b/source/smbparse.c
@@ -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)
{