summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>1997-10-03 20:36:06 +0000
committerJeremy Allison <jra@samba.org>1997-10-03 20:36:06 +0000
commit2f7b04061e61df7dcc1029b71fe12ca4dfca5f10 (patch)
tree332e217c0435dba1ace5bef198d69443c2e48e68
parent2534e0688ba703423c9d18b3296b00c097aa351d (diff)
downloadsamba-2f7b04061e61df7dcc1029b71fe12ca4dfca5f10.tar.gz
samba-2f7b04061e61df7dcc1029b71fe12ca4dfca5f10.tar.bz2
samba-2f7b04061e61df7dcc1029b71fe12ca4dfca5f10.zip
locking.c: Fixed incorrect parameter count in debug statements. May explain
solaris crashes. reply.c: Added NT specific error code. Put oplock break code in correct place in reply_lockingX. server.c: Removed unneeded error mapping stuff. Fixed race condition in oplock code. trans2.c: Added NT specific error code. util.c: Added paranoia check in interpret_addr. Some core dumps reported here. Upped fcntl debug levels. Andrew. Please check the NT specific error code handling (search for the string "/* Ugly - NT specific hack - but needed (JRA) */", this makes NT and 95 clients behave correctly here - please check your Visual Basic apps with this code. Jeremy (jallison@whistle.com). (This used to be commit 97ee4a5f69bd9cfbbc8710a1a04d80db0ee40104)
-rw-r--r--source3/lib/util.c8
-rw-r--r--source3/locking/locking.c11
-rw-r--r--source3/smbd/reply.c34
-rw-r--r--source3/smbd/server.c74
-rw-r--r--source3/smbd/trans2.c17
5 files changed, 74 insertions, 70 deletions
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 3317efb804..01e2dae154 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -3415,6 +3415,10 @@ uint32 interpret_addr(char *str)
DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
return 0;
}
+ if(hp->h_addr == NULL) {
+ DEBUG(3,("Get_Hostbyname: host address is invalid for host %s.\n",str));
+ return 0;
+ }
putip((char *)&res,(char *)hp->h_addr);
}
@@ -4033,7 +4037,7 @@ BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
#endif
- DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
+ DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
lock.l_type = type;
lock.l_whence = SEEK_SET;
@@ -4081,7 +4085,7 @@ BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
}
/* everything went OK */
- DEBUG(5,("Lock call successful\n"));
+ DEBUG(8,("Lock call successful\n"));
return(True);
#else
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index 693beb7432..834f3e5658 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -206,7 +206,7 @@ file dev = %d, ino = %d in hash_bucket %d\n", dev, inode, hash_entry));
{
DEBUG(0,("ERROR:get_share_modes (FAST_SHARE_MODES): Deleting old share mode \
record due to old locking version %d for file dev = %d, inode = %d in hash \
-bucket %d",file_scanner_p->locking_version, dev, inode, hash_entry));
+bucket %d\n", file_scanner_p->locking_version, dev, inode, hash_entry));
if(file_prev_p == file_scanner_p)
mode_array[hash_entry] = file_scanner_p->next_offset;
else
@@ -270,7 +270,7 @@ for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries
DEBUG(0,("get_share_modes (FAST_SHARE_MODES): process %d no longer exists and \
it left a share mode entry with mode 0x%X for file dev = %d, ino = %d in hash \
-bucket (number of entries now = %d)\n",
+bucket %d (number of entries now = %d)\n",
pid, entry_scanner_p->share_mode, dev, inode, hash_entry,
file_scanner_p->num_share_mode_entries));
@@ -316,8 +316,7 @@ hash bucket %d has a share mode record but no entries - deleting\n",
}
DEBUG(5,("get_share_modes (FAST_SHARE_MODES): file with dev %d, inode %d in \
-hash bucket %d returning %d entries\n", dev, inode, hash_entry,
- num_entries_copied));
+hash bucket %d returning %d entries\n", dev, inode, hash_entry, num_entries_copied));
return(num_entries_copied);
}
@@ -878,8 +877,8 @@ for share file %s (%s)\n", fname, strerror(errno)));
if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION) {
DEBUG(0,("ERROR: read_share_file: share file %s has incorrect \
locking version (was %d, should be %d).\n",fname,
- IVAL(buf,SMF_VERSION_OFFSET), LOCKING_VERSION));
- if(buf)
+ IVAL(buf,SMF_VERSION_OFFSET), LOCKING_VERSION));
+ if(buf)
free(buf);
delete_share_file(cnum, fname);
return -1;
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index aa3f43a813..a8f674183c 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -640,6 +640,15 @@ int reply_chkpth(char *inbuf,char *outbuf)
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+
+ /* Ugly - NT specific hack - but needed (JRA) */
+ if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
+ (get_remote_arch() == RA_WINNT))
+ {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbaddirectory;
+ }
+
return(UNIXERROR(ERRDOS,ERRbadpath));
}
@@ -3390,22 +3399,37 @@ int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize)
(num_ulocks == 0) && (num_locks == 0) &&
(CVAL(inbuf,smb_vwv0) == 0xFF))
{
+ share_lock_token token;
+ files_struct *fsp = &Files[fnum];
+ uint32 dev = fsp->fd_ptr->dev;
+ uint32 inode = fsp->fd_ptr->inode;
+
DEBUG(5,("reply_lockingX: oplock break reply from client for fnum = %d\n",
fnum));
/*
* Make sure we have granted an oplock on this file.
*/
- if(!Files[fnum].granted_oplock)
+ if(!fsp->granted_oplock)
{
DEBUG(0,("reply_lockingX: Error : oplock break from client for fnum = %d and \
-oplock granted on this file.\n", fnum));
+no oplock granted on this file.\n", fnum));
return ERROR(ERRDOS,ERRlock);
}
- /* Just clear the granted flag and return. oplock_break()
- will handle changing the share_mode_entry. */
+ /* Remove the oplock flag from the sharemode. */
+ lock_share_entry(fsp->cnum, dev, inode, &token);
+ if(remove_share_oplock( fnum, token)==False)
+ {
+ DEBUG(0,("reply_lockingX: failed to remove share oplock for fnum %d, \
+dev = %x, inode = %x\n", fnum, dev, inode));
+ unlock_share_entry(fsp->cnum, dev, inode, token);
+ return -1;
+ }
+ unlock_share_entry(fsp->cnum, dev, inode, token);
+
+ /* Clear the granted flag and return. */
- Files[fnum].granted_oplock = 0;
+ fsp->granted_oplock = False;
return -1;
}
#endif /* USE_OPLOCKS */
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 9af1a88062..52869505c0 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -2137,20 +2137,6 @@ struct
{0,0,0}
};
-/* Mapping for old clients. */
-
-struct
-{
- int new_smb_error;
- int old_smb_error;
- int protocol_level;
- enum remote_arch_types valid_ra_type;
-} old_client_errmap[] =
-{
- {ERRbaddirectory, ERRbadpath, (int)PROTOCOL_NT1, RA_WINNT},
- {0,0,0}
-};
-
/****************************************************************************
create an error packet from errno
****************************************************************************/
@@ -2181,29 +2167,6 @@ int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int
}
}
- /* Make sure we don't return error codes that old
- clients don't understand. */
-
- /* JRA - unfortunately, WinNT needs some error codes
- for apps to work correctly, Win95 will break if
- these error codes are returned. But they both
- negotiate the *same* protocol. So we need to use
- the revolting 'remote_arch' enum to tie break.
-
- There must be a better way of doing this...
- */
-
- for(i = 0; old_client_errmap[i].new_smb_error != 0; i++)
- {
- if(((Protocol < old_client_errmap[i].protocol_level) ||
- (old_client_errmap[i].valid_ra_type != get_remote_arch())) &&
- (old_client_errmap[i].new_smb_error == ecode))
- {
- ecode = old_client_errmap[i].old_smb_error;
- break;
- }
- }
-
return(error_packet(inbuf,outbuf,eclass,ecode,line));
}
@@ -2612,7 +2575,6 @@ BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
static char *outbuf = NULL;
files_struct *fsp = NULL;
int fnum;
- share_lock_token token;
time_t start_time;
BOOL shutdown_server = False;
@@ -2660,16 +2622,19 @@ allowing break to succeed.\n", dev, inode, fnum));
/* Ensure we have an oplock on the file */
- /* Question - can a client asynchronously break an oplock ? Would it
- ever do so ? If so this test is invalid for external smbd oplock
- breaks and we should return True in these cases (JRA).
+ /* There is a potential race condition in that an oplock could
+ have been broken due to another udp request, and yet there are
+ still oplock break messages being sent in the udp message
+ queue for this file. So return true if we don't have an oplock,
+ as we may have just freed it. But this is an unusual case so
+ we should log a message at low debug priority (1).
*/
if(!fsp->granted_oplock)
{
- DEBUG(0,("oplock_break: file %s (fnum = %d, dev = %x, inode = %x) has no oplock.\n",
- fsp->name, fnum, dev, inode));
- return False;
+ DEBUG(1,("oplock_break: file %s (fnum = %d, dev = %x, inode = %x) has no oplock. \
+Allowing break to succeed regardless.\n", fsp->name, fnum, dev, inode));
+ return True;
}
/* Now comes the horrid part. We must send an oplock break to the client,
@@ -2729,7 +2694,8 @@ inode = %x).\n", fsp->name, fnum, dev, inode));
process_smb(inbuf, outbuf);
/* We only need this in case a readraw crossed on the wire. */
- global_oplock_break = False;
+ if(global_oplock_break)
+ global_oplock_break = False;
/*
* Die if we go over the time limit.
@@ -2760,16 +2726,10 @@ inode = %x).\n", fsp->name, fnum, dev, inode));
if(OPEN_FNUM(fnum))
{
- /* Remove the oplock flag from the sharemode. */
- lock_share_entry(fsp->cnum, dev, inode, &token);
- if(remove_share_oplock( fnum, token)==False)
- {
- DEBUG(0,("oplock_break: failed to remove share oplock for fnum %d, \
-dev = %x, inode = %x\n", fnum, dev, inode));
- unlock_share_entry(fsp->cnum, dev, inode, token);
- return False;
- }
- unlock_share_entry(fsp->cnum, dev, inode, token);
+ /* The lockingX reply will have removed the oplock flag
+ from the sharemode. */
+ /* Paranoia.... */
+ fsp->granted_oplock = False;
}
global_oplocks_open--;
@@ -2782,8 +2742,8 @@ dev = %x, inode = %x\n", fnum, dev, inode));
abort();
}
- DEBUG(5,("oplock_break: returning success for dev = %x, inode = %x. Current \
-global_oplocks_open = %d\n", dev, inode, global_oplocks_open));
+ DEBUG(5,("oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
+global_oplocks_open = %d\n", fnum, dev, inode, global_oplocks_open));
return True;
}
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 56f153f12f..7f46604cce 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -607,6 +607,15 @@ static int call_trans2findfirst(char *inbuf, char *outbuf, int bufsize, int cnum
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+
+ /* Ugly - NT specific hack - but needed (JRA) */
+ if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
+ (get_remote_arch() == RA_WINNT))
+ {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbaddirectory;
+ }
+
return(ERROR(ERRDOS,ERRbadpath));
}
@@ -641,6 +650,14 @@ static int call_trans2findfirst(char *inbuf, char *outbuf, int bufsize, int cnum
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+
+ /* Ugly - NT specific hack - but needed (JRA) */
+ if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
+ (get_remote_arch() == RA_WINNT))
+ {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbaddirectory;
+ }
return (UNIXERROR(ERRDOS,ERRbadpath));
}
return(ERROR(ERRDOS,ERRbadpath));