locking.c: Fixed incorrect parameter count in debug statements. May explain
authorJeremy Allison <jra@samba.org>
Fri, 3 Oct 1997 20:36:06 +0000 (20:36 +0000)
committerJeremy Allison <jra@samba.org>
Fri, 3 Oct 1997 20:36:06 +0000 (20:36 +0000)
           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)

source3/lib/util.c
source3/locking/locking.c
source3/smbd/reply.c
source3/smbd/server.c
source3/smbd/trans2.c

index 3317efb80411e8578639d46d6e5d7a4dee93626f..01e2dae154c8103561d97c90a6084a15de07fd8b 100644 (file)
@@ -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
index 693beb74326b2c4f8f37d26b4462375fef5188fa..834f3e565895c4266e8e5f4e65f588b2d9e1fa12 100644 (file)
@@ -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;
index aa3f43a813d6a79bc4067a1789811eb8fb14e196..a8f674183c510fdd6ef752e7ac574480fd2ec0c6 100644 (file)
@@ -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 */
index 9af1a88062957baf2606a7378e4fcf43128d2477..52869505c096b5d8ee1a952af3dd2b63022a009e 100644 (file)
@@ -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;
 }
index 56f153f12fb6fe0146e98ccb869de14158b60ab7..7f46604cce9dcade4c038b0e0367a2d0425ba967 100644 (file)
@@ -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));