SAM database "set user info".
[samba.git] / source3 / smbd / reply.c
index e62c0bd5760841ff7a236538dbe2a38a8458d68b..57742003ff6e876cfc98e7e9ea7810f0fb32caf1 100644 (file)
@@ -33,7 +33,6 @@ extern int Protocol;
 extern int DEBUGLEVEL;
 extern int max_send;
 extern int max_recv;
-extern files_struct *chain_fsp;
 extern char magic_char;
 extern BOOL case_sensitive;
 extern BOOL case_preserve;
@@ -42,6 +41,8 @@ extern pstring sesssetup_user;
 extern fstring global_myworkgroup;
 extern int Client;
 extern int global_oplock_break;
+uint32 global_client_caps = 0;
+
 
 /****************************************************************************
 report a possible attack via the password buffer overflow bug
@@ -59,6 +60,51 @@ static void overflow_attack(int len)
 }
 
 
+/****************************************************************************
+  does _both_ nt->unix and unix->unix username remappings.
+****************************************************************************/
+static void map_nt_and_unix_username(const char *domain, char *user)
+{
+       DOM_NAME_MAP gmep;
+       fstring nt_username;
+
+       /*
+        * Pass the user through the NT -> unix user mapping
+        * function.
+        */
+   
+       if (lp_server_role() != ROLE_DOMAIN_NONE)
+       {
+               memset(nt_username, 0, sizeof(nt_username));
+               if (domain != NULL)
+               {
+                       slprintf(nt_username, sizeof(nt_username)-1, "%s\\%s",
+                                domain, user);
+               }
+               else
+               {
+                       fstrcpy(nt_username, user);
+               }
+
+               if (lookupsmbpwntnam(nt_username, &gmep))
+               {
+                       fstrcpy(user, gmep.unix_name);
+               }
+       }
+
+       /*
+        * Pass the user through the unix -> unix user mapping
+        * function.
+        */
+
+       (void)map_username(user);
+
+       /*
+        * Do any UNIX username case mangling.
+        */
+       (void)Get_Pwnam( user, True);
+}
+
 /****************************************************************************
   reply to an special message 
 ****************************************************************************/
@@ -219,17 +265,7 @@ int reply_tcon(connection_struct *conn,
 
        parse_connect(smb_buf(inbuf)+1,service,user,password,&pwlen,dev);
 
-       /*
-        * Pass the user through the NT -> unix user mapping
-        * function.
-        */
-   
-       (void)map_username(user);
-
-       /*
-        * Do any UNIX username case mangling.
-        */
-       (void)Get_Pwnam( user, True);
+       map_nt_and_unix_username(global_myworkgroup, user);
 
        conn = make_connection(service,user,password,pwlen,dev,vuid,&ecode);
   
@@ -299,18 +335,8 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
        StrnCpy(devicename,path + strlen(path) + 1,6);
        DEBUG(4,("Got device type %s\n",devicename));
 
-       /*
-        * Pass the user through the NT -> unix user mapping
-        * function.
-        */
-       
-       (void)map_username(user);
-       
-       /*
-        * Do any UNIX username case mangling.
-        */
-       (void)Get_Pwnam(user, True);
-       
+       map_nt_and_unix_username(global_myworkgroup, user);
+
        conn = make_connection(service,user,password,passlen,devicename,vuid,&ecode);
        
        if (!conn)
@@ -320,7 +346,7 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
                set_message(outbuf,2,strlen(devicename)+1,True);
                pstrcpy(smb_buf(outbuf),devicename);
        } else {
-               char *fsname = FSTYPE_STRING;
+               char *fsname = lp_fstype(SNUM(conn));
 
                set_message(outbuf,3,3,True);
 
@@ -330,7 +356,9 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
                
                set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
                
-               SSVAL(outbuf, smb_vwv2, 0x0); /* optional support */
+               /* what does setting this bit do? It is set by NT4 and
+                  may affect the ability to autorun mounted cdroms */
+               SSVAL(outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS); 
        }
   
        DEBUG(3,("tconX service=%s user=%s\n",
@@ -410,7 +438,7 @@ static int session_trust_account(connection_struct *conn, char *inbuf, char *out
       return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
     }
 
-    if (!smb_password_ok(smb_trust_acct, (unsigned char *)smb_passwd, (unsigned char *)smb_nt_passwd))
+    if (!smb_password_ok(smb_trust_acct, NULL, (unsigned char *)smb_passwd, (unsigned char *)smb_nt_passwd))
     {
       DEBUG(0,("session_trust_account: Trust Account %s - password failed\n", user));
       SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
@@ -444,19 +472,49 @@ static int session_trust_account(connection_struct *conn, char *inbuf, char *out
   return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
 }
 
+/****************************************************************************
+ Check for a valid username and password in security=server mode.
+****************************************************************************/
+
+static BOOL check_server_security(char *orig_user, char *domain, 
+                                  char *smb_apasswd, int smb_apasslen,
+                                  char *smb_ntpasswd, int smb_ntpasslen)
+{
+  if(lp_security() != SEC_SERVER)
+    return False;
+
+  return server_validate(orig_user, domain, 
+                            smb_apasswd, smb_apasslen, 
+                            smb_ntpasswd, smb_ntpasslen);
+}
+
+/****************************************************************************
+ Check for a valid username and password in security=domain mode.
+****************************************************************************/
+
+static BOOL check_domain_security(char *orig_user, char *domain, 
+                                  char *smb_apasswd, int smb_apasslen,
+                                  char *smb_ntpasswd, int smb_ntpasslen)
+{
+  if(lp_security() != SEC_DOMAIN)
+    return False;
+
+  return domain_client_validate(orig_user, domain,
+                                smb_apasswd, smb_apasslen,
+                                smb_ntpasswd, smb_ntpasslen);
+}
 
 /****************************************************************************
 reply to a session setup command
 ****************************************************************************/
+
 int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
 {
   uint16 sess_vuid;
+  uchar user_sess_key[16];
   int gid;
   int uid;
   int   smb_bufsize;    
-  int   smb_mpxmax;     
-  int   smb_vc_num;     
-  uint32   smb_sesskey;    
   int   smb_apasslen = 0;   
   pstring smb_apasswd;
   int   smb_ntpasslen = 0;   
@@ -473,9 +531,6 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
   *smb_ntpasswd = 0;
   
   smb_bufsize = SVAL(inbuf,smb_vwv2);
-  smb_mpxmax = SVAL(inbuf,smb_vwv3);
-  smb_vc_num = SVAL(inbuf,smb_vwv4);
-  smb_sesskey = IVAL(inbuf,smb_vwv5);
 
   if (Protocol < PROTOCOL_NT1) {
     smb_apasslen = SVAL(inbuf,smb_vwv7);
@@ -494,11 +549,11 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
   } else {
     uint16 passlen1 = SVAL(inbuf,smb_vwv7);
     uint16 passlen2 = SVAL(inbuf,smb_vwv8);
-    uint32 client_caps = IVAL(inbuf,smb_vwv11);
     enum remote_arch_types ra_type = get_remote_arch();
-
     char *p = smb_buf(inbuf);    
 
+    global_client_caps = IVAL(inbuf,smb_vwv11);
+
     /* client_caps is used as final determination if client is NT or Win95. 
        This is needed to return the correct error codes in some
        circumstances.
@@ -506,7 +561,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
     
     if(ra_type == RA_WINNT || ra_type == RA_WIN95)
     {
-      if(client_caps & (CAP_NT_SMBS | CAP_STATUS32))
+      if(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))
         set_remote_arch( RA_WINNT);
       else
         set_remote_arch( RA_WIN95);
@@ -585,12 +640,12 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
 
   /* If no username is sent use the guest account */
   if (!*user)
-    {
-      pstrcpy(user,lp_guestaccount(-1));
-      /* If no user and no password then set guest flag. */
-      if( *smb_apasswd == 0)
-        guest = True;
-    }
+  {
+    pstrcpy(user,lp_guestaccount(-1));
+    /* If no user and no password then set guest flag. */
+    if( *smb_apasswd == 0)
+      guest = True;
+  }
 
   strlower(user);
 
@@ -600,7 +655,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
    * working.
    */
 
-  if((lp_security() != SEC_SHARE) || *user)
+  if((lp_security() != SEC_SHARE) || (*user && !guest))
     pstrcpy(sesssetup_user,user);
 
   reload_services(True);
@@ -613,17 +668,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
 
   pstrcpy( orig_user, user);
 
-  /*
-   * Pass the user through the NT -> unix user mapping
-   * function.
-   */
-   
-  (void)map_username(user);
-
-  /*
-   * Do any UNIX username case mangling.
-   */
-  (void)Get_Pwnam( user, True);
+       map_nt_and_unix_username(domain, user);
 
   add_session_user(user);
 
@@ -634,48 +679,65 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
   if(!guest && strequal(user,lp_guestaccount(-1)) && (*smb_apasswd == 0))
     guest = True;
 
-  if (!guest && !(lp_security() == SEC_SERVER && 
-      /* Check with orig_user for security=server and
-         security=domain. */
-      server_validate(orig_user, domain, 
-                      smb_apasswd, smb_apasslen, 
-                      smb_ntpasswd, smb_ntpasslen)) &&
-      !(lp_security() == SEC_DOMAIN &&
-      domain_client_validate(orig_user, domain,
+  /* 
+   * Check with orig_user for security=server and
+   * security=domain.
+   */
+
+  if (!guest && 
+      !check_server_security(orig_user, domain,
                              smb_apasswd, smb_apasslen,
-                            smb_ntpasswd, smb_ntpasslen)) &&
+                             smb_ntpasswd, smb_ntpasslen) &&
+      !check_domain_security(orig_user, domain,
+                             smb_apasswd, smb_apasslen,
+                             smb_ntpasswd, smb_ntpasslen) &&
       !check_hosts_equiv(user)
      )
+  {
+
+    /* 
+     * If we get here then the user wasn't guest and the remote
+     * authentication methods failed. Check the authentication
+     * methods on this local server.
+     *
+     * If an NT password was supplied try and validate with that
+     * first. This is superior as the passwords are mixed case 
+     * 128 length unicode.
+      */
+
+    if(smb_ntpasslen)
     {
+      if(!password_ok(user, smb_ntpasswd,smb_ntpasslen,NULL,user_sess_key))
+        DEBUG(0,("NT Password did not match ! Defaulting to Lanman\n"));
+      else
+        valid_nt_password = True;
+    } 
 
-      /* now check if it's a valid username/password */
-      /* If an NT password was supplied try and validate with that
-        first. This is superior as the passwords are mixed case 
-         128 length unicode */
-      if(smb_ntpasslen)
-       {
-         if(!password_ok(user,smb_ntpasswd,smb_ntpasslen,NULL))
-           DEBUG(0,("NT Password did not match ! Defaulting to Lanman\n"));
-         else
-           valid_nt_password = True;
-       } 
-      if (!valid_nt_password && !password_ok(user,smb_apasswd,smb_apasslen,NULL))
-       {
-         if (lp_security() >= SEC_USER) {
-#if (GUEST_SESSSETUP == 0)
-           return(ERROR(ERRSRV,ERRbadpw));
-#endif
-#if (GUEST_SESSSETUP == 1)
-           if (Get_Pwnam(user,True))
-             return(ERROR(ERRSRV,ERRbadpw));
-#endif
-         }
-         if (*smb_apasswd || !Get_Pwnam(user,True))
-           pstrcpy(user,lp_guestaccount(-1));
-         DEBUG(3,("Registered username %s for guest access\n",user));
-         guest = True;
-       }
+    if (!valid_nt_password && !password_ok(user, smb_apasswd,smb_apasslen,NULL,user_sess_key))
+    {
+      if (lp_security() >= SEC_USER) 
+      {
+        if (lp_map_to_guest() == NEVER_MAP_TO_GUEST)
+          return(ERROR(ERRSRV,ERRbadpw));
+
+        if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER)
+        {
+         if (Get_Pwnam(user,True))
+            return(ERROR(ERRSRV,ERRbadpw));
+        }
+
+        /*
+         * ..else if lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD
+         * Then always map to guest account - as done below.
+         */
+      }
+
+      if (*smb_apasswd || !Get_Pwnam(user,True))
+         pstrcpy(user,lp_guestaccount(-1));
+      DEBUG(3,("Registered username %s for guest access\n",user));
+      guest = True;
     }
+  }
 
   if (!Get_Pwnam(user,True)) {
     DEBUG(3,("No such user %s - using guest account\n",user));
@@ -685,12 +747,16 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
 
   if (!strequal(user,lp_guestaccount(-1)) &&
       lp_servicenumber(user) < 0)      
-    {
-      int homes = lp_servicenumber(HOMES_NAME);
-      char *home = get_home_dir(user);
-      if (homes >= 0 && home)
-       lp_add_home(user,homes,home);
-    }
+  {
+    int homes = lp_servicenumber(HOMES_NAME);
+    char *home = get_home_dir(user);
+    if (homes >= 0 && home)
+       {
+               pstring home_dir;
+               fstrcpy(home_dir, home);
+               lp_add_home(user,homes,home_dir);
+       }
+  }
 
 
   /* it's ok - setup a reply */
@@ -726,7 +792,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
 
   /* register the name and uid as being validated, so further connections
      to a uid can get through without a password, on the same VC */
-  sess_vuid = register_vuid(uid,gid,user,sesssetup_user,guest);
+  sess_vuid = register_vuid(uid,gid,user,sesssetup_user,guest,user_sess_key);
  
   SSVAL(outbuf,smb_uid,sess_vuid);
   SSVAL(inbuf,smb_uid,sess_vuid);
@@ -752,14 +818,19 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   pstring name;
   BOOL ok = False;
   BOOL bad_path = False;
+  SMB_STRUCT_STAT st;
  
   pstrcpy(name,smb_buf(inbuf) + 1);
-  unix_convert(name,conn,0,&bad_path);
+  unix_convert(name,conn,0,&bad_path,&st);
 
   mode = SVAL(inbuf,smb_vwv0);
 
-  if (check_name(name,conn))
-    ok = directory_exist(name,NULL);
+  if (check_name(name,conn)) {
+    if(VALID_STAT(st))
+      ok = S_ISDIR(st.st_mode);
+    else
+      ok = dos_directory_exist(name,NULL);
+  }
 
   if (!ok)
   {
@@ -802,30 +873,31 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
 {
   pstring fname;
   int outsize = 0;
-  struct stat sbuf;
+  SMB_STRUCT_STAT sbuf;
   BOOL ok = False;
   int mode=0;
-  uint32 size=0;
+  SMB_OFF_T size=0;
   time_t mtime=0;
   BOOL bad_path = False;
  
   pstrcpy(fname,smb_buf(inbuf) + 1);
-  unix_convert(fname,conn,0,&bad_path);
 
   /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
      under WfWg - weird! */
   if (! (*fname))
-    {
-      mode = aHIDDEN | aDIR;
-      if (!CAN_WRITE(conn)) mode |= aRONLY;
-      size = 0;
-      mtime = 0;
-      ok = True;
-    }
+  {
+    mode = aHIDDEN | aDIR;
+    if (!CAN_WRITE(conn)) mode |= aRONLY;
+    size = 0;
+    mtime = 0;
+    ok = True;
+  }
   else
+  {
+    unix_convert(fname,conn,0,&bad_path,&sbuf);
     if (check_name(fname,conn))
     {
-      if (sys_stat(fname,&sbuf) == 0)
+      if (VALID_STAT(sbuf) || dos_stat(fname,&sbuf) == 0)
       {
         mode = dos_mode(conn,fname,&sbuf);
         size = sbuf.st_size;
@@ -837,6 +909,7 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
       else
         DEBUG(3,("stat of %s failed (%s)\n",fname,strerror(errno)));
     }
+  }
   
   if (!ok)
   {
@@ -856,7 +929,7 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
     put_dos_date3(outbuf,smb_vwv1,mtime & ~1);
   else
     put_dos_date3(outbuf,smb_vwv1,mtime);
-  SIVAL(outbuf,smb_vwv3,size);
+  SIVAL(outbuf,smb_vwv3,(uint32)size);
 
   if (Protocol >= PROTOCOL_NT1) {
     char *p = strrchr(fname,'/');
@@ -866,7 +939,7 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
       SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
   }
   
-  DEBUG( 3, ( "getatr name=%s mode=%d size=%d\n", fname, mode, size ) );
+  DEBUG( 3, ( "getatr name=%s mode=%d size=%d\n", fname, mode, (uint32)size ) );
   
   return(outsize);
 }
@@ -882,18 +955,19 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   BOOL ok=False;
   int mode;
   time_t mtime;
+  SMB_STRUCT_STAT st;
   BOOL bad_path = False;
  
   pstrcpy(fname,smb_buf(inbuf) + 1);
-  unix_convert(fname,conn,0,&bad_path);
+  unix_convert(fname,conn,0,&bad_path,&st);
 
   mode = SVAL(inbuf,smb_vwv0);
   mtime = make_unix_date3(inbuf+smb_vwv1);
   
-  if (directory_exist(fname,NULL))
+  if (VALID_STAT_OF_DIR(st) || dos_directory_exist(fname,NULL))
     mode |= aDIR;
   if (check_name(fname,conn))
-    ok =  (dos_chmod(conn,fname,mode,NULL) == 0);
+    ok =  (file_chmod(conn,fname,mode,NULL) == 0);
   if (ok)
     ok = set_filetime(conn,fname,mtime);
   
@@ -922,7 +996,7 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
 int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
   int outsize = 0;
-  int dfree,dsize,bsize;
+  SMB_BIG_UINT dfree,dsize,bsize;
   
   sys_disk_free(".",&bsize,&dfree,&dsize);
   
@@ -933,7 +1007,7 @@ int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
   SSVAL(outbuf,smb_vwv2,512);
   SSVAL(outbuf,smb_vwv3,dfree);
 
-  DEBUG(3,("dskattr dfree=%d\n", dfree));
+  DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
 
   return(outsize);
 }
@@ -948,7 +1022,8 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   pstring mask;
   pstring directory;
   pstring fname;
-  int size,mode;
+  SMB_OFF_T size;
+  int mode;
   time_t date;
   int dirtype;
   int outsize = 0;
@@ -991,7 +1066,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
 
       pstrcpy(directory,smb_buf(inbuf)+1);
       pstrcpy(dir2,smb_buf(inbuf)+1);
-      unix_convert(directory,conn,0,&bad_path);
+      unix_convert(directory,conn,0,&bad_path,NULL);
       unix_format(dir2);
 
       if (!check_name(directory,conn))
@@ -1052,14 +1127,24 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   mask_convert(mask);
 
   {
-    for (p=mask; *p; p++)
+    int skip;
+    p = mask;
+    while(*p)
+    {
+      if((skip = skip_multibyte_char( *p )) != 0 )
       {
-       if (*p != '?' && *p != '*' && !isdoschar(*p))
-         {
-           DEBUG(5,("Invalid char [%c] in search mask?\n",*p));
-           *p = '?';
-         }
+        p += skip;
+      }
+      else
+      {
+        if (*p != '?' && *p != '*' && !isdoschar(*p))
+        {
+          DEBUG(5,("Invalid char [%c] in search mask?\n",*p));
+          *p = '?';
+        }
+        p++;
       }
+    }
   }
 
   if (!strchr(mask,'.') && strlen(mask)>8)
@@ -1223,17 +1308,18 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
 /****************************************************************************
   reply to an open
 ****************************************************************************/
+
 int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
   pstring fname;
   int outsize = 0;
   int fmode=0;
   int share_mode;
-  int size = 0;
+  SMB_OFF_T size = 0;
   time_t mtime=0;
-  int unixmode;
+  mode_t unixmode;
   int rmode=0;
-  struct stat sbuf;
+  SMB_STRUCT_STAT sbuf;
   BOOL bad_path = False;
   files_struct *fsp;
   int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
@@ -1241,7 +1327,7 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   share_mode = SVAL(inbuf,smb_vwv0);
 
   pstrcpy(fname,smb_buf(inbuf)+1);
-  unix_convert(fname,conn,0,&bad_path);
+  unix_convert(fname,conn,0,&bad_path,NULL);
     
   fsp = file_new();
   if (!fsp)
@@ -1260,8 +1346,8 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
  
   unixmode = unix_mode(conn,aARCH);
       
-  open_file_shared(fsp,conn,fname,share_mode,3,unixmode,
-                   oplock_request,&rmode,NULL);
+  open_file_shared(fsp,conn,fname,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
+                   unixmode, oplock_request,&rmode,NULL);
 
   if (!fsp->open)
   {
@@ -1274,7 +1360,7 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
-  if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
+  if (sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
     close_file(fsp,False);
     return(ERROR(ERRDOS,ERRnoaccess));
   }
@@ -1296,7 +1382,7 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
     put_dos_date3(outbuf,smb_vwv2,mtime & ~1);
   else
     put_dos_date3(outbuf,smb_vwv2,mtime);
-  SIVAL(outbuf,smb_vwv4,size);
+  SIVAL(outbuf,smb_vwv4,(uint32)size);
   SSVAL(outbuf,smb_vwv6,rmode);
 
   if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
@@ -1328,21 +1414,24 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
   uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
 #endif
   int smb_ofun = SVAL(inbuf,smb_vwv8);
-  int unixmode;
-  int size=0,fmode=0,mtime=0,rmode=0;
-  struct stat sbuf;
+  mode_t unixmode;
+  SMB_OFF_T size=0;
+  int fmode=0,mtime=0,rmode=0;
+  SMB_STRUCT_STAT sbuf;
   int smb_action = 0;
   BOOL bad_path = False;
   files_struct *fsp;
 
   /* If it's an IPC, pass off the pipe handler. */
-  if (IS_IPC(conn))
+  if (IS_IPC(conn) && lp_nt_pipe_support() && lp_security() != SEC_SHARE)
+  {
     return reply_open_pipe_and_X(conn, inbuf,outbuf,length,bufsize);
+  }
 
   /* XXXX we need to handle passed times, sattr and flags */
 
   pstrcpy(fname,smb_buf(inbuf));
-  unix_convert(fname,conn,0,&bad_path);
+  unix_convert(fname,conn,0,&bad_path,NULL);
     
   fsp = file_new();
   if (!fsp)
@@ -1362,7 +1451,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
   unixmode = unix_mode(conn,smb_attr | aARCH);
       
   open_file_shared(fsp,conn,fname,smb_mode,smb_ofun,unixmode,
-                  oplock_request, &rmode,&smb_action);
+                      oplock_request, &rmode,&smb_action);
       
   if (!fsp->open)
   {
@@ -1375,7 +1464,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
-  if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
+  if (sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
     close_file(fsp,False);
     return(ERROR(ERRDOS,ERRnoaccess));
   }
@@ -1421,12 +1510,10 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
     put_dos_date3(outbuf,smb_vwv4,mtime & ~1);
   else
     put_dos_date3(outbuf,smb_vwv4,mtime);
-  SIVAL(outbuf,smb_vwv6,size);
+  SIVAL(outbuf,smb_vwv6,(uint32)size);
   SSVAL(outbuf,smb_vwv8,rmode);
   SSVAL(outbuf,smb_vwv11,smb_action);
 
-  chain_fsp = fsp;
-
   return chain_reply(inbuf,outbuf,length,bufsize);
 }
 
@@ -1478,7 +1565,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 
   createmode = SVAL(inbuf,smb_vwv0);
   pstrcpy(fname,smb_buf(inbuf)+1);
-  unix_convert(fname,conn,0,&bad_path);
+  unix_convert(fname,conn,0,&bad_path,NULL);
 
   if (createmode & aVOLID)
     {
@@ -1514,8 +1601,8 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   }
 
   /* Open file in dos compatibility share mode. */
-  open_file_shared(fsp,conn,fname,(DENY_FCB<<4)|0xF, ofun, unixmode
-                   oplock_request, NULL, NULL);
+  open_file_shared(fsp,conn,fname,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB)
+                   ofun, unixmode, oplock_request, NULL, NULL);
   
   if (!fsp->open)
   {
@@ -1563,7 +1650,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   createmode = SVAL(inbuf,smb_vwv0);
   pstrcpy(fname,smb_buf(inbuf)+1);
   pstrcat(fname,"/TMXXXXXX");
-  unix_convert(fname,conn,0,&bad_path);
+  unix_convert(fname,conn,0,&bad_path,NULL);
   
   unixmode = unix_mode(conn,createmode);
   
@@ -1586,8 +1673,8 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 
   /* Open file in dos compatibility share mode. */
   /* We should fail if file exists. */
-  open_file_shared(fsp,conn,fname2,(DENY_FCB<<4)|0xF, 0x10, unixmode
-                   oplock_request, NULL, NULL);
+  open_file_shared(fsp,conn,fname2,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB)
+                   (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL), unixmode, oplock_request, NULL, NULL);
 
   if (!fsp->open)
   {
@@ -1625,12 +1712,12 @@ check if a user is allowed to delete a file
 ********************************************************************/
 static BOOL can_delete(char *fname,connection_struct *conn, int dirtype)
 {
-  struct stat sbuf;
+  SMB_STRUCT_STAT sbuf;
   int fmode;
 
   if (!CAN_WRITE(conn)) return(False);
 
-  if (sys_lstat(fname,&sbuf) != 0) return(False);
+  if (dos_lstat(fname,&sbuf) != 0) return(False);
   fmode = dos_mode(conn,fname,&sbuf);
   if (fmode & aDIR) return(False);
   if (!lp_delete_readonly(SNUM(conn))) {
@@ -1667,7 +1754,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
    
   DEBUG(3,("reply_unlink : %s\n",name));
    
-  unix_convert(name,conn,0,&bad_path);
+  unix_convert(name,conn,0,&bad_path,NULL);
 
   p = strrchr(name,'/');
   if (!p) {
@@ -1687,8 +1774,10 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   if (!has_wild) {
     pstrcat(directory,"/");
     pstrcat(directory,mask);
-    if (can_delete(directory,conn,dirtype) && !sys_unlink(directory)) count++;
-    if (!count) exists = file_exist(directory,NULL);    
+    if (can_delete(directory,conn,dirtype) && !dos_unlink(directory))
+      count++;
+    if (!count)
+      exists = dos_file_exist(directory,NULL);    
   } else {
     void *dirptr = NULL;
     char *dname;
@@ -1718,7 +1807,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
            error = ERRnoaccess;
            slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
            if (!can_delete(fname,conn,dirtype)) continue;
-           if (!sys_unlink(fname)) count++;
+           if (!dos_unlink(fname)) count++;
            DEBUG(3,("reply_unlink : doing unlink on %s\n",fname));
          }
        CloseDir(dirptr);
@@ -1750,13 +1839,11 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
 ****************************************************************************/
 int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
 {
-  int maxcount,mincount;
-  int nread = 0;
-  uint32 startpos;
+  size_t maxcount,mincount;
+  size_t nread = 0;
+  SMB_OFF_T startpos;
   char *header = outbuf;
-  int ret=0;
-  int fd;
-  char *fname;
+  ssize_t ret=0;
   files_struct *fsp;
 
   /*
@@ -1768,16 +1855,31 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
   if(global_oplock_break)
   {
     _smb_setlen(header,0);
-    transfer_file(0,Client,0,header,4,0);
+    transfer_file(0,Client,(SMB_OFF_T)0,header,4,0);
     DEBUG(5,("readbraw - oplock break finished\n"));
     return -1;
   }
 
-  fsp = GETFSP(inbuf,smb_vwv0);
+  fsp = file_fsp(inbuf,smb_vwv0);
 
   startpos = IVAL(inbuf,smb_vwv1);
-  maxcount = SVAL(inbuf,smb_vwv3);
-  mincount = SVAL(inbuf,smb_vwv4);
+#ifdef LARGE_SMB_OFF_T
+  if(CVAL(inbuf,smb_wct) == 10) {
+    /*
+     * This is a large offset (64 bit) read.
+     */
+    startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv8)) << 32);
+    if(startpos < 0) {
+      DEBUG(0,("readbraw - negative 64 bit readraw offset (%.0f) !\n",
+            (double)startpos ));
+         _smb_setlen(header,0);
+         transfer_file(0,Client,(SMB_OFF_T)0,header,4,0);
+         return(-1);
+    }      
+  }
+#endif /* LARGE_SMB_OFF_T */
+  maxcount = (SVAL(inbuf,smb_vwv3) & 0xFFFF);
+  mincount = (SVAL(inbuf,smb_vwv4) & 0xFFFF);
 
   /* ensure we don't overrun the packet size */
   maxcount = MIN(65535,maxcount);
@@ -1786,65 +1888,70 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
   if (!FNUM_OK(fsp,conn) || !fsp->can_read) {
          DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",fsp->fnum));
          _smb_setlen(header,0);
-         transfer_file(0,Client,0,header,4,0);
+         transfer_file(0,Client,(SMB_OFF_T)0,header,4,0);
          return(-1);
-  } else {
-         fd = fsp->fd_ptr->fd;
-         fname = fsp->fsp_name;
   }
 
-
   if (!is_locked(fsp,conn,maxcount,startpos, F_RDLCK))
   {
-    int size = fsp->size;
-    int sizeneeded = startpos + maxcount;
+    SMB_OFF_T size = fsp->size;
+    SMB_OFF_T sizeneeded = startpos + maxcount;
            
-    if (size < sizeneeded) {
-      struct stat st;
-      if (fstat(fsp->fd_ptr->fd,&st) == 0)
+    if (size < sizeneeded)
+    {
+      SMB_STRUCT_STAT st;
+      if (sys_fstat(fsp->fd_ptr->fd,&st) == 0)
         size = st.st_size;
       if (!fsp->can_write) 
         fsp->size = size;
     }
 
-    nread = MIN(maxcount,(int)(size - startpos));        
+    nread = MIN(maxcount,(size - startpos));     
   }
 
   if (nread < mincount)
     nread = 0;
   
-  DEBUG( 3, ( "readbraw fnum=%d start=%d max=%d min=%d nread=%d\n",
-             fsp->fnum, startpos,
+  DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n",
+             fsp->fnum, (double)startpos,
              maxcount, mincount, nread ) );
   
 #if UNSAFE_READRAW
   {
+    BOOL seek_fail = False;
     int predict=0;
     _smb_setlen(header,nread);
 
 #if USE_READ_PREDICTION
     if (!fsp->can_write)
-      predict = read_predict(fd,startpos,header+4,NULL,nread);
-#endif
+      predict = read_predict(fsp->fd_ptr->fd,startpos,header+4,NULL,nread);
+#endif /* USE_READ_PREDICTION */
+
+    if ((nread-predict) > 0) {
+      if(seek_file(fsp,startpos + predict) == -1) {
+        DEBUG(0,("reply_readbraw: ERROR: seek_file failed.\n"));
+        ret = 0;
+        seek_fail = True;
+      } 
+    }
 
-    if ((nread-predict) > 0)
-      seek_file(fsp,startpos + predict);
-    
-    ret = transfer_file(fd,Client,nread-predict,header,4+predict,
-                       startpos+predict);
+    if(!seek_fail)
+      ret = (ssize_t)transfer_file(fsp->fd_ptr->fd,Client,
+                                   (SMB_OFF_T)(nread-predict),header,4+predict, 
+                                   startpos+predict);
   }
 
   if (ret != nread+4)
     DEBUG(0,("ERROR: file read failure on %s at %d for %d bytes (%d)\n",
-            fname,startpos,nread,ret));
+            fsp->fsp_name,startpos,nread,ret));
 
-#else
+#else /* UNSAFE_READRAW */
   ret = read_file(fsp,header+4,startpos,nread);
   if (ret < mincount) ret = 0;
 
   _smb_setlen(header,ret);
   transfer_file(0,Client,0,header,4+ret,0);
-#endif
+#endif /* UNSAFE_READRAW */
 
   DEBUG(5,("readbraw finished\n"));
   return -1;
@@ -1854,15 +1961,16 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
 /****************************************************************************
   reply to a lockread (core+ protocol)
 ****************************************************************************/
-int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsiz)
+int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length, int dum_buffsiz)
 {
-  int nread = -1;
+  ssize_t nread = -1;
   char *data;
   int outsize = 0;
-  uint32 startpos, numtoread;
+  SMB_OFF_T startpos;
+  size_t numtoread;
   int eclass;
   uint32 ecode;
-  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
+  files_struct *fsp = file_fsp(inbuf,smb_vwv0);
 
   CHECK_FSP(fsp,conn);
   CHECK_READ(fsp);
@@ -1875,8 +1983,18 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int dum_si
   numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
   data = smb_buf(outbuf) + 3;
   
-  if(!do_lock( fsp, conn, numtoread, startpos, F_RDLCK, &eclass, &ecode))
+  if(!do_lock( fsp, conn, numtoread, startpos, F_RDLCK, &eclass, &ecode)) {
+    if((ecode == ERRlock) && lp_blocking_locks(SNUM(conn))) {
+      /*
+       * A blocking lock was requested. Package up
+       * this smb into a queued request and push it
+       * onto the blocking lock queue.
+       */
+      if(push_blocking_lock_request(inbuf, length, -1, 0))
+        return -1;
+    }
     return (ERROR(eclass,ecode));
+  }
 
   nread = read_file(fsp,data,startpos,numtoread);
 
@@ -1900,12 +2018,12 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int dum_si
 ****************************************************************************/
 int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-  int numtoread;
-  int nread = 0;
+  size_t numtoread;
+  ssize_t nread = 0;
   char *data;
-  uint32 startpos;
+  SMB_OFF_T startpos;
   int outsize = 0;
-  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
+  files_struct *fsp = file_fsp(inbuf,smb_vwv0);
 
   CHECK_FSP(fsp,conn);
   CHECK_READ(fsp);
@@ -1945,13 +2063,12 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 ****************************************************************************/
 int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
 {
-  files_struct *fsp = GETFSP(inbuf,smb_vwv2);
-  uint32 smb_offs = IVAL(inbuf,smb_vwv3);
-  int smb_maxcnt = SVAL(inbuf,smb_vwv5);
-  int smb_mincnt = SVAL(inbuf,smb_vwv6);
-  int nread = -1;
+  files_struct *fsp = file_fsp(inbuf,smb_vwv2);
+  SMB_OFF_T startpos = IVAL(inbuf,smb_vwv3);
+  size_t smb_maxcnt = SVAL(inbuf,smb_vwv5);
+  size_t smb_mincnt = SVAL(inbuf,smb_vwv6);
+  ssize_t nread = -1;
   char *data;
-  BOOL ok = False;
 
   /* If it's an IPC, pass off the pipe handler. */
   if (IS_IPC(conn))
@@ -1964,10 +2081,18 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
   set_message(outbuf,12,0,True);
   data = smb_buf(outbuf);
 
-  if (is_locked(fsp,conn,smb_maxcnt,smb_offs, F_RDLCK))
+#ifdef LARGE_SMB_OFF_T
+  if(CVAL(inbuf,smb_wct) == 12) {
+    /*
+     * This is a large offset (64 bit) read.
+     */
+    startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv10)) << 32);
+  }
+#endif /* LARGE_SMB_OFF_T */
+
+  if (is_locked(fsp,conn,smb_maxcnt,startpos, F_RDLCK))
     return(ERROR(ERRDOS,ERRlock));
-  nread = read_file(fsp,data,smb_offs,smb_maxcnt);
-  ok = True;
+  nread = read_file(fsp,data,startpos,smb_maxcnt);
   
   if (nread < 0)
     return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -1979,26 +2104,23 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
   DEBUG( 3, ( "readX fnum=%d min=%d max=%d nread=%d\n",
              fsp->fnum, smb_mincnt, smb_maxcnt, nread ) );
 
-  chain_fsp = fsp;
-
   return chain_reply(inbuf,outbuf,length,bufsize);
 }
 
-
 /****************************************************************************
   reply to a writebraw (core+ or LANMAN1.0 protocol)
 ****************************************************************************/
 int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-  int nwritten=0;
-  int total_written=0;
-  int numtowrite=0;
-  int outsize = 0;
-  long startpos;
+  ssize_t nwritten=0;
+  ssize_t total_written=0;
+  size_t numtowrite=0;
+  size_t tcount;
+  SMB_OFF_T startpos;
   char *data=NULL;
   BOOL write_through;
-  int tcount;
-  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
+  files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+  int outsize = 0;
 
   CHECK_FSP(fsp,conn);
   CHECK_WRITE(fsp);
@@ -2025,14 +2147,16 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
   if (is_locked(fsp,conn,tcount,startpos, F_WRLCK))
     return(ERROR(ERRDOS,ERRlock));
 
-  if (seek_file(fsp,startpos) != startpos)
-    DEBUG(0,("couldn't seek to %ld in writebraw\n",startpos));
+  if (seek_file(fsp,startpos) == -1) {
+    DEBUG(0,("couldn't seek to %.0f in writebraw\n",(double)startpos));
+    return(UNIXERROR(ERRDOS,ERRnoaccess));
+  }
 
   if (numtowrite>0)
     nwritten = write_file(fsp,data,numtowrite);
   
-  DEBUG(3,("writebraw1 fnum=%d start=%ld num=%d wrote=%d sync=%d\n",
-          fsp->fnum, startpos, numtowrite, nwritten, write_through));
+  DEBUG(3,("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n",
+          fsp->fnum, (double)startpos, numtowrite, nwritten, write_through));
 
   if (nwritten < numtowrite) 
     return(UNIXERROR(ERRHRD,ERRdiskfull));
@@ -2060,7 +2184,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
             tcount,nwritten,numtowrite));
   }
 
-  nwritten = transfer_file(Client,fsp->fd_ptr->fd,numtowrite,NULL,0,
+  nwritten = transfer_file(Client,fsp->fd_ptr->fd,(SMB_OFF_T)numtowrite,NULL,0,
                           startpos+nwritten);
   total_written += nwritten;
   
@@ -2069,7 +2193,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
   CVAL(outbuf,smb_com) = SMBwritec;
   SSVAL(outbuf,smb_vwv0,total_written);
 
-  if (nwritten < numtowrite) {
+  if (nwritten < (ssize_t)numtowrite) {
     CVAL(outbuf,smb_rcls) = ERRHRD;
     SSVAL(outbuf,smb_err,ERRdiskfull);      
   }
@@ -2077,8 +2201,8 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
   if (lp_syncalways(SNUM(conn)) || write_through)
     sync_file(conn,fsp);
 
-  DEBUG(3,("writebraw2 fnum=%d start=%ld num=%d wrote=%d\n",
-          fsp->fnum, startpos, numtowrite, total_written));
+  DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
+          fsp->fnum, (double)startpos, numtowrite, total_written));
 
   /* we won't return a status if write through is not selected - this 
      follows what WfWg does */
@@ -2088,19 +2212,19 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
   return(outsize);
 }
 
-
 /****************************************************************************
   reply to a writeunlock (core+)
 ****************************************************************************/
 int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-  int nwritten = -1;
-  int outsize = 0;
+  ssize_t nwritten = -1;
+  size_t numtowrite;
+  SMB_OFF_T startpos;
   char *data;
-  uint32 numtowrite,startpos;
   int eclass;
   uint32 ecode;
-  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
+  files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+  int outsize = 0;
 
   CHECK_FSP(fsp,conn);
   CHECK_WRITE(fsp);
@@ -2113,7 +2237,8 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int dum
   if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
     return(ERROR(ERRDOS,ERRlock));
 
-  seek_file(fsp,startpos);
+  if(seek_file(fsp,startpos) == -1)
+    return(UNIXERROR(ERRDOS,ERRnoaccess));
 
   /* The special X/Open SMB protocol handling of
      zero length writes is *NOT* done for
@@ -2142,18 +2267,17 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int dum
   return(outsize);
 }
 
-
 /****************************************************************************
   reply to a write
 ****************************************************************************/
 int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int dum_size,int dum_buffsize)
 {
-  int numtowrite;
-  int nwritten = -1;
-  int outsize = 0;
-  int startpos;
+  size_t numtowrite;
+  ssize_t nwritten = -1;
+  SMB_OFF_T startpos;
   char *data;
-  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
+  files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+  int outsize = 0;
 
   CHECK_FSP(fsp,conn);
   CHECK_WRITE(fsp);
@@ -2166,13 +2290,14 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int dum_size,i
   if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
     return(ERROR(ERRDOS,ERRlock));
 
-  seek_file(fsp,startpos);
+  if(seek_file(fsp,startpos) == -1)
+    return(UNIXERROR(ERRDOS,ERRnoaccess));
 
   /* X/Open SMB protocol says that if smb_vwv1 is
      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(fsp->fd_ptr->fd, startpos);
+    nwritten = set_filelen(fsp->fd_ptr->fd, (SMB_OFF_T)startpos);
   else
     nwritten = write_file(fsp,data,numtowrite);
   
@@ -2186,7 +2311,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int dum_size,i
   
   SSVAL(outbuf,smb_vwv0,nwritten);
 
-  if (nwritten < numtowrite) {
+  if (nwritten < (ssize_t)numtowrite) {
     CVAL(outbuf,smb_rcls) = ERRHRD;
     SSVAL(outbuf,smb_err,ERRdiskfull);      
   }
@@ -2203,50 +2328,62 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int dum_size,i
 ****************************************************************************/
 int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
 {
-  files_struct *fsp = GETFSP(inbuf,smb_vwv2);
-  uint32 smb_offs = IVAL(inbuf,smb_vwv3);
-  int smb_dsize = SVAL(inbuf,smb_vwv10);
-  int smb_doff = SVAL(inbuf,smb_vwv11);
+  files_struct *fsp = file_fsp(inbuf,smb_vwv2);
+  SMB_OFF_T startpos = IVAL(inbuf,smb_vwv3);
+  size_t numtowrite = SVAL(inbuf,smb_vwv10);
   BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
-  int nwritten = -1;
+  ssize_t nwritten = -1;
+  int smb_doff = SVAL(inbuf,smb_vwv11);
   char *data;
 
+  /* If it's an IPC, pass off the pipe handler. */
+  if (IS_IPC(conn))
+    return reply_pipe_write_and_X(inbuf,outbuf,length,bufsize);
+
   CHECK_FSP(fsp,conn);
   CHECK_WRITE(fsp);
   CHECK_ERROR(fsp);
 
   data = smb_base(inbuf) + smb_doff;
 
-  if (is_locked(fsp,conn,smb_dsize,smb_offs, F_WRLCK))
+#ifdef LARGE_SMB_OFF_T
+  if(CVAL(inbuf,smb_wct) == 14) {
+    /*
+     * This is a large offset (64 bit) write.
+     */
+    startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv12)) << 32);
+  }
+#endif /* LARGE_SMB_OFF_T */
+
+  if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
     return(ERROR(ERRDOS,ERRlock));
 
-  seek_file(fsp,smb_offs);
+  if(seek_file(fsp,startpos) == -1)
+    return(UNIXERROR(ERRDOS,ERRnoaccess));
   
   /* X/Open SMB protocol says that, unlike SMBwrite
      if the length is zero then NO truncation is
      done, just a write of zero. To truncate a file,
      use SMBwrite. */
-  if(smb_dsize == 0)
+  if(numtowrite == 0)
     nwritten = 0;
   else
-    nwritten = write_file(fsp,data,smb_dsize);
+    nwritten = write_file(fsp,data,numtowrite);
   
-  if(((nwritten == 0) && (smb_dsize != 0))||(nwritten < 0))
+  if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
     return(UNIXERROR(ERRDOS,ERRnoaccess));
 
   set_message(outbuf,6,0,True);
   
   SSVAL(outbuf,smb_vwv2,nwritten);
   
-  if (nwritten < smb_dsize) {
+  if (nwritten < (ssize_t)numtowrite) {
     CVAL(outbuf,smb_rcls) = ERRHRD;
     SSVAL(outbuf,smb_err,ERRdiskfull);      
   }
 
   DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
-          fsp->fnum, smb_dsize, nwritten));
-
-  chain_fsp = fsp;
+          fsp->fnum, numtowrite, nwritten));
 
   if (lp_syncalways(SNUM(conn)) || write_through)
     sync_file(conn,fsp);
@@ -2260,11 +2397,11 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
 ****************************************************************************/
 int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-  uint32 startpos;
-  int32 res= -1;
+  SMB_OFF_T startpos;
+  SMB_OFF_T res= -1;
   int mode,umode;
   int outsize = 0;
-  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
+  files_struct *fsp = file_fsp(inbuf,smb_vwv0);
 
   CHECK_FSP(fsp,conn);
   CHECK_ERROR(fsp);
@@ -2273,34 +2410,35 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   startpos = IVAL(inbuf,smb_vwv2);
 
   switch (mode & 3) 
-    {
+  {
     case 0: umode = SEEK_SET; break;
     case 1: umode = SEEK_CUR; break;
     case 2: umode = SEEK_END; break;
     default:
       umode = SEEK_SET; break;
-    }
+  }
+
+  if((res = sys_lseek(fsp->fd_ptr->fd,startpos,umode)) == -1)
+    return(UNIXERROR(ERRDOS,ERRnoaccess));
 
-  res = lseek(fsp->fd_ptr->fd,startpos,umode);
   fsp->pos = res;
   
   outsize = set_message(outbuf,2,0,True);
   SIVALS(outbuf,smb_vwv0,res);
   
-  DEBUG(3,("lseek fnum=%d ofs=%d mode=%d\n",
-          fsp->fnum, startpos, mode));
+  DEBUG(3,("lseek fnum=%d ofs=%.0f mode=%d\n",
+          fsp->fnum, (double)startpos, mode));
 
   return(outsize);
 }
 
-
 /****************************************************************************
   reply to a flush
 ****************************************************************************/
 int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
   int outsize = set_message(outbuf,0,0,True);
-  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
+  files_struct *fsp = file_fsp(inbuf,smb_vwv0);
 
   if (fsp) {
          CHECK_FSP(fsp,conn);
@@ -2349,14 +2487,14 @@ int reply_close(connection_struct *conn,
                return reply_pipe_close(conn, inbuf,outbuf);
        }
 
-       fsp = GETFSP(inbuf,smb_vwv0);
+       fsp = file_fsp(inbuf,smb_vwv0);
 
        /*
         * We can only use CHECK_FSP if we know it's not a directory.
         */
 
-       if(!(fsp && fsp->open && fsp->is_directory))
-               CHECK_FSP(fsp,conn);
+    if(!fsp || !fsp->open || (fsp->conn != conn))
+      return(ERROR(ERRDOS,ERRbadfid));
 
        if(HAS_CACHED_ERROR(fsp)) {
                eclass = fsp->wbmpx_ptr->wr_errclass;
@@ -2374,6 +2512,17 @@ int reply_close(connection_struct *conn,
                /*
                 * Close ordinary file.
                 */
+
+               /*
+                * If there was a modify time outstanding,
+                * try and set it here.
+                */
+               if(fsp->pending_modtime)
+                       set_filetime(conn, fsp->fsp_name, fsp->pending_modtime);
+
+               /*
+                * Now take care of any time sent in the close.
+                */
                mtime = make_unix_date3(inbuf+smb_vwv1);
                
                /* try and set the date */
@@ -2400,13 +2549,13 @@ int reply_close(connection_struct *conn,
 int reply_writeclose(connection_struct *conn,
                     char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-       int numtowrite;
-       int nwritten = -1;
+       size_t numtowrite;
+       ssize_t nwritten = -1;
        int outsize = 0;
-       int startpos;
+       SMB_OFF_T startpos;
        char *data;
        time_t mtime;
-       files_struct *fsp = GETFSP(inbuf,smb_vwv0);
+       files_struct *fsp = file_fsp(inbuf,smb_vwv0);
 
        CHECK_FSP(fsp,conn);
        CHECK_WRITE(fsp);
@@ -2420,7 +2569,8 @@ int reply_writeclose(connection_struct *conn,
        if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
                return(ERROR(ERRDOS,ERRlock));
       
-       seek_file(fsp,startpos);
+       if(seek_file(fsp,startpos) == -1)
+               return(UNIXERROR(ERRDOS,ERRnoaccess));
       
        nwritten = write_file(fsp,data,numtowrite);
 
@@ -2446,13 +2596,13 @@ int reply_writeclose(connection_struct *conn,
   reply to a lock
 ****************************************************************************/
 int reply_lock(connection_struct *conn,
-              char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+              char *inbuf,char *outbuf, int length, int dum_buffsize)
 {
        int outsize = set_message(outbuf,0,0,True);
-       uint32 count,offset;
+       SMB_OFF_T count,offset;
        int eclass;
        uint32 ecode;
-       files_struct *fsp = GETFSP(inbuf,smb_vwv0);
+       files_struct *fsp = file_fsp(inbuf,smb_vwv0);
 
        CHECK_FSP(fsp,conn);
        CHECK_ERROR(fsp);
@@ -2460,11 +2610,21 @@ int reply_lock(connection_struct *conn,
        count = IVAL(inbuf,smb_vwv1);
        offset = IVAL(inbuf,smb_vwv3);
 
-       DEBUG(3,("lock fd=%d fnum=%d ofs=%d cnt=%d\n",
-                fsp->fd_ptr->fd, fsp->fnum, offset, count));
+       DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
+                fsp->fd_ptr->fd, fsp->fnum, (double)offset, (double)count));
 
-       if (!do_lock(fsp, conn, count, offset, F_WRLCK, &eclass, &ecode))
-               return (ERROR(eclass,ecode));
+       if (!do_lock(fsp, conn, count, offset, F_WRLCK, &eclass, &ecode)) {
+      if((ecode == ERRlock) && lp_blocking_locks(SNUM(conn))) {
+        /*
+         * A blocking lock was requested. Package up
+         * this smb into a queued request and push it
+         * onto the blocking lock queue.
+         */
+        if(push_blocking_lock_request(inbuf, length, -1, 0))
+          return -1;
+      }
+      return (ERROR(eclass,ecode));
+    }
 
        return(outsize);
 }
@@ -2476,10 +2636,10 @@ int reply_lock(connection_struct *conn,
 int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
   int outsize = set_message(outbuf,0,0,True);
-  uint32 count,offset;
+  SMB_OFF_T count,offset;
   int eclass;
   uint32 ecode;
-  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
+  files_struct *fsp = file_fsp(inbuf,smb_vwv0);
 
   CHECK_FSP(fsp,conn);
   CHECK_ERROR(fsp);
@@ -2490,8 +2650,8 @@ int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   if(!do_unlock(fsp, conn, count, offset, &eclass, &ecode))
     return (ERROR(eclass,ecode));
 
-  DEBUG( 3, ( "unlock fd=%d fnum=%d ofs=%d cnt=%d\n",
-        fsp->fd_ptr->fd, fsp->fnum, offset, count ) );
+  DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
+        fsp->fd_ptr->fd, fsp->fnum, (double)offset, (double)count ) );
   
   return(outsize);
 }
@@ -2600,9 +2760,8 @@ int reply_printopen(connection_struct *conn,
        }
 
        /* Open for exclusive use, write only. */
-       open_file_shared(fsp,conn,fname2,
-                        (DENY_ALL<<4)|1, 0x12, unix_mode(conn,0), 
-                        0, NULL, NULL);
+       open_file_shared(fsp,conn,fname2, SET_DENY_MODE(DENY_ALL)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
+                     (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL), unix_mode(conn,0), 0, NULL, NULL);
 
        if (!fsp->open) {
                file_free(fsp);
@@ -2629,7 +2788,7 @@ int reply_printclose(connection_struct *conn,
                     char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
        int outsize = set_message(outbuf,0,0,True);
-       files_struct *fsp = GETFSP(inbuf,smb_vwv0);
+       files_struct *fsp = file_fsp(inbuf,smb_vwv0);
 
        CHECK_FSP(fsp,conn);
        CHECK_ERROR(fsp);
@@ -2655,9 +2814,6 @@ int reply_printqueue(connection_struct *conn,
        int outsize = set_message(outbuf,2,3,True);
        int max_count = SVAL(inbuf,smb_vwv0);
        int start_index = SVAL(inbuf,smb_vwv1);
-       uint16 vuid;
-
-       vuid = SVAL(inbuf,smb_uid);
 
        /* we used to allow the client to get the cnum wrong, but that
           is really quite gross and only worked when there was only
@@ -2724,7 +2880,7 @@ int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_
   int numtowrite;
   int outsize = set_message(outbuf,0,0,True);
   char *data;
-  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
+  files_struct *fsp = file_fsp(inbuf,smb_vwv0);
   
   if (!CAN_PRINT(conn))
     return(ERROR(ERRDOS,ERRnoaccess));
@@ -2755,10 +2911,10 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   BOOL bad_path = False;
  
   pstrcpy(directory,smb_buf(inbuf) + 1);
-  unix_convert(directory,conn,0,&bad_path);
+  unix_convert(directory,conn,0,&bad_path,NULL);
   
   if (check_name(directory, conn))
-    ret = sys_mkdir(directory,unix_mode(conn,aDIR));
+    ret = dos_mkdir(directory,unix_mode(conn,aDIR));
   
   if (ret < 0)
   {
@@ -2793,7 +2949,7 @@ static BOOL recursive_rmdir(char *directory)
   while((dname = ReadDirName(dirptr)))
   {
     pstring fullname;
-    struct stat st;
+    SMB_STRUCT_STAT st;
 
     if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
       continue;
@@ -2809,7 +2965,7 @@ static BOOL recursive_rmdir(char *directory)
     pstrcat(fullname, "/");
     pstrcat(fullname, dname);
 
-    if(sys_lstat(fullname, &st) != 0)
+    if(dos_lstat(fullname, &st) != 0)
     {
       ret = True;
       break;
@@ -2822,13 +2978,13 @@ static BOOL recursive_rmdir(char *directory)
         ret = True;
         break;
       }
-      if(sys_rmdir(fullname) != 0)
+      if(dos_rmdir(fullname) != 0)
       {
         ret = True;
         break;
       }
     }
-    else if(sys_unlink(fullname) != 0)
+    else if(dos_unlink(fullname) != 0)
     {
       ret = True;
       break;
@@ -2849,13 +3005,13 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   BOOL bad_path = False;
 
   pstrcpy(directory,smb_buf(inbuf) + 1);
-  unix_convert(directory,conn, NULL,&bad_path);
+  unix_convert(directory,conn, NULL,&bad_path,NULL);
   
   if (check_name(directory,conn))
     {
 
       dptr_closepath(directory,SVAL(inbuf,smb_pid));
-      ok = (sys_rmdir(directory) == 0);
+      ok = (dos_rmdir(directory) == 0);
       if(!ok && (errno == ENOTEMPTY) && lp_veto_files(SNUM(conn)))
         {
           /* Check to see if the only thing in this directory are
@@ -2885,7 +3041,7 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
                   while ((dname = ReadDirName(dirptr)))
                     {
                       pstring fullname;
-                      struct stat st;
+                      SMB_STRUCT_STAT st;
 
                       if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
                         continue;
@@ -2900,7 +3056,7 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
                       pstrcat(fullname, "/");
                       pstrcat(fullname, dname);
                       
-                      if(sys_lstat(fullname, &st) != 0)
+                      if(dos_lstat(fullname, &st) != 0)
                         break;
                       if(st.st_mode & S_IFDIR)
                       {
@@ -2909,15 +3065,15 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
                           if(recursive_rmdir(fullname) != 0)
                             break;
                         }
-                        if(sys_rmdir(fullname) != 0)
+                        if(dos_rmdir(fullname) != 0)
                           break;
                       }
-                      else if(sys_unlink(fullname) != 0)
+                      else if(dos_unlink(fullname) != 0)
                         break;
                     }
                   CloseDir(dirptr);
                   /* Retry the rmdir */
-                  ok = (sys_rmdir(directory) == 0);
+                  ok = (dos_rmdir(directory) == 0);
                 }
               else
                 CloseDir(dirptr);
@@ -3018,11 +3174,11 @@ check if a user is allowed to rename a file
 ********************************************************************/
 static BOOL can_rename(char *fname,connection_struct *conn)
 {
-  struct stat sbuf;
+  SMB_STRUCT_STAT sbuf;
 
   if (!CAN_WRITE(conn)) return(False);
 
-  if (sys_lstat(fname,&sbuf) != 0) return(False);
+  if (dos_lstat(fname,&sbuf) != 0) return(False);
   if (!check_file_sharing(conn,fname,True)) return(False);
 
   return(True);
@@ -3049,8 +3205,8 @@ int rename_internals(connection_struct *conn,
 
        *directory = *mask = 0;
 
-       unix_convert(name,conn,0,&bad_path1);
-       unix_convert(newname,conn,newname_last_component,&bad_path2);
+       unix_convert(name,conn,0,&bad_path1,NULL);
+       unix_convert(newname,conn,newname_last_component,&bad_path2,NULL);
 
        /*
         * Split the old name into directory and last component
@@ -3138,27 +3294,27 @@ int rename_internals(connection_struct *conn,
                        /*
                         * NT SMB specific flag - rename can overwrite
                         * file with the same name so don't check for
-                        * file_exist().
+                        * dos_file_exist().
                         */
                        if(resolve_wildcards(directory,newname) &&
                           can_rename(directory,conn) &&
-                          !sys_rename(directory,newname))
+                          !dos_rename(directory,newname))
                                count++;
                } else {
                        if (resolve_wildcards(directory,newname) && 
                            can_rename(directory,conn) && 
-                           !file_exist(newname,NULL) &&
-                           !sys_rename(directory,newname))
+                           !dos_file_exist(newname,NULL) &&
+                           !dos_rename(directory,newname))
                                count++;
                }
 
                DEBUG(3,("rename_internals: %s doing rename on %s -> %s\n",(count != 0) ? "succeeded" : "failed",
                          directory,newname));
                
-               if (!count) exists = file_exist(directory,NULL);
-               if (!count && exists && file_exist(newname,NULL)) {
+               if (!count) exists = dos_file_exist(directory,NULL);
+               if (!count && exists && dos_file_exist(newname,NULL)) {
                        exists = True;
-                       error = 183;
+                       error = ERRrename;
                }
        } else {
                /*
@@ -3197,13 +3353,13 @@ int rename_internals(connection_struct *conn,
                                        continue;
                                }
                                
-                               if (!replace_if_exists && file_exist(destname,NULL)) {
-                                       DEBUG(6,("file_exist %s\n", destname));
+                               if (!replace_if_exists && dos_file_exist(destname,NULL)) {
+                                       DEBUG(6,("dos_file_exist %s\n", destname));
                                        error = 183;
                                        continue;
                                }
                                
-                               if (!sys_rename(fname,destname))
+                               if (!dos_rename(fname,destname))
                                        count++;
                                DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname));
                        }
@@ -3251,12 +3407,13 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, in
 /*******************************************************************
   copy a file as part of a reply_copy
   ******************************************************************/
+
 static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
                      int count,BOOL target_is_directory)
 {
   int Access,action;
-  struct stat st;
-  int ret=0;
+  SMB_STRUCT_STAT st;
+  int ret=-1;
   files_struct *fsp1,*fsp2;
   pstring dest;
   
@@ -3271,12 +3428,15 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
     pstrcat(dest,p);
   }
 
-  if (!file_exist(src,&st)) return(False);
+  if (!dos_file_exist(src,&st))
+    return(False);
 
   fsp1 = file_new();
-  if (!fsp1) return(False);
-  open_file_shared(fsp1,conn,src,(DENY_NONE<<4),
-                  1,0,0,&Access,&action);
+  if (!fsp1)
+    return(False);
+
+  open_file_shared(fsp1,conn,src,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
+                  (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),0,0,&Access,&action);
 
   if (!fsp1->open) {
          file_free(fsp1);
@@ -3291,7 +3451,7 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
          close_file(fsp1,False);
          return(False);
   }
-  open_file_shared(fsp2,conn,dest,(DENY_NONE<<4)|1,
+  open_file_shared(fsp2,conn,dest,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
                   ofun,st.st_mode,0,&Access,&action);
 
   if (!fsp2->open) {
@@ -3301,7 +3461,15 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
   }
 
   if ((ofun&3) == 1) {
-    lseek(fsp2->fd_ptr->fd,0,SEEK_END);
+    if(sys_lseek(fsp2->fd_ptr->fd,0,SEEK_END) == -1) {
+      DEBUG(0,("copy_file: error - sys_lseek returned error %s\n",
+               strerror(errno) ));
+      /*
+       * Stop the copy from occurring.
+       */
+      ret = -1;
+      st.st_size = 0;
+    }
   }
   
   if (st.st_size)
@@ -3350,10 +3518,10 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
     return(ERROR(ERRSRV,ERRinvdevice));
   }
 
-  unix_convert(name,conn,0,&bad_path1);
-  unix_convert(newname,conn,0,&bad_path2);
+  unix_convert(name,conn,0,&bad_path1,NULL);
+  unix_convert(newname,conn,0,&bad_path2,NULL);
 
-  target_is_directory = directory_exist(newname,NULL);
+  target_is_directory = dos_directory_exist(newname,NULL);
 
   if ((flags&1) && target_is_directory) {
     return(ERROR(ERRDOS,ERRbadfile));
@@ -3363,7 +3531,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
     return(ERROR(ERRDOS,ERRbadpath));
   }
 
-  if ((flags&(1<<5)) && directory_exist(name,NULL)) {
+  if ((flags&(1<<5)) && dos_directory_exist(name,NULL)) {
     /* wants a tree copy! XXXX */
     DEBUG(3,("Rejecting tree copy\n"));
     return(ERROR(ERRSRV,ERRerror));    
@@ -3390,7 +3558,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
     if (resolve_wildcards(directory,newname) && 
        copy_file(directory,newname,conn,ofun,
                  count,target_is_directory)) count++;
-    if (!count) exists = file_exist(directory,NULL);
+    if (!count) exists = dos_file_exist(directory,NULL);
   } else {
     void *dirptr = NULL;
     char *dname;
@@ -3445,8 +3613,6 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   return(outsize);
 }
 
-
-
 /****************************************************************************
   reply to a setdir
 ****************************************************************************/
@@ -3467,7 +3633,7 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   if (strlen(newdir) == 0) {
          ok = True;
   } else {
-         ok = directory_exist(newdir,NULL);
+         ok = dos_directory_exist(newdir,NULL);
          if (ok) {
                  string_set(&conn->connectpath,newdir);
          }
@@ -3484,26 +3650,25 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   return(outsize);
 }
 
-
 /****************************************************************************
   reply to a lockingX request
 ****************************************************************************/
 int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
 {
-  files_struct *fsp = GETFSP(inbuf,smb_vwv2);
+  files_struct *fsp = file_fsp(inbuf,smb_vwv2);
   unsigned char locktype = CVAL(inbuf,smb_vwv3);
 #if 0
   unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1);
 #endif
   uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
   uint16 num_locks = SVAL(inbuf,smb_vwv7);
-  uint32 count, offset;
+  SMB_OFF_T count = 0, offset = 0;
   int32 lock_timeout = IVAL(inbuf,smb_vwv4);
   int i;
   char *data;
   uint32 ecode=0, dummy2;
   int eclass=0, dummy1;
-
+  BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
   CHECK_FSP(fsp,conn);
   CHECK_ERROR(fsp);
 
@@ -3515,8 +3680,8 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
   if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE))
   {
     int token;
-    uint32 dev = fsp->fd_ptr->dev;
-    uint32 inode = fsp->fd_ptr->inode;
+    SMB_DEV_T dev = fsp->fd_ptr->dev;
+    SMB_INO_T inode = fsp->fd_ptr->inode;
 
     DEBUG(5,("reply_lockingX: oplock break reply from client for fnum = %d\n",
               fsp->fnum));
@@ -3532,10 +3697,11 @@ no oplock granted on this file.\n", fsp->fnum));
 
     /* Remove the oplock flag from the sharemode. */
     lock_share_entry(fsp->conn, dev, inode, &token);
-    if(remove_share_oplock(fsp, token)==False) {
+    if(remove_share_oplock(token, fsp)==False) {
+
            DEBUG(0,("reply_lockingX: failed to remove share oplock for fnum %d, \
-dev = %x, inode = %x\n", 
-                    fsp->fnum, dev, inode));
+dev = %x, inode = %.0f\n", fsp->fnum, (unsigned int)dev, (double)inode));
+
            unlock_share_entry(fsp->conn, dev, inode, token);
     } else {
            unlock_share_entry(fsp->conn, dev, inode, token);
@@ -3559,8 +3725,22 @@ dev = %x, inode = %x\n",
   /* Data now points at the beginning of the list
      of smb_unlkrng structs */
   for(i = 0; i < (int)num_ulocks; i++) {
-    count = IVAL(data,SMB_LKLEN_OFFSET(i));
-    offset = IVAL(data,SMB_LKOFF_OFFSET(i));
+    if(!large_file_format) {
+      count = IVAL(data,SMB_LKLEN_OFFSET(i));
+      offset = IVAL(data,SMB_LKOFF_OFFSET(i));
+    }
+#ifdef LARGE_SMB_OFF_T
+    else {
+      count = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(i))) << 32) |
+              ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(i)));
+      offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) |
+               ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i)));
+    }
+#endif /* LARGE_SMB_OFF_T */
+
+    DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for file %s\n",
+          (double)offset, (double)count, fsp->fsp_name ));
+
     if(!do_unlock(fsp,conn,count,offset,&eclass, &ecode))
       return ERROR(eclass,ecode);
   }
@@ -3569,16 +3749,31 @@ dev = %x, inode = %x\n",
   lock_timeout = ((lock_timeout == -1) ? -1 : lock_timeout/1000);
 
   /* Now do any requested locks */
-  data += 10*num_ulocks;
+  data += ((large_file_format ? 20 : 10)*num_ulocks);
+
   /* Data now points at the beginning of the list
      of smb_lkrng structs */
+
   for(i = 0; i < (int)num_locks; i++) {
-    count = IVAL(data,SMB_LKLEN_OFFSET(i)); 
-    offset = IVAL(data,SMB_LKOFF_OFFSET(i)); 
+    if(!large_file_format) {
+      count = IVAL(data,SMB_LKLEN_OFFSET(i)); 
+      offset = IVAL(data,SMB_LKOFF_OFFSET(i)); 
+    }
+#ifdef LARGE_SMB_OFF_T
+    else {
+      count = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(i))) << 32) |
+              ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(i)));
+      offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) |
+               ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i)));
+    }
+#endif /* LARGE_SMB_OFF_T */
+    DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for file %s\n",
+          (double)offset, (double)count, fsp->fsp_name ));
+
     if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK),
-                &eclass, &ecode))
-#if 0 /* JRATEST - blocking lock code. */
-      if((ecode == ERRlock) && (lock_timeout != 0)) {
+                &eclass, &ecode)) {
+      if((ecode == ERRlock) && (lock_timeout != 0) && lp_blocking_locks(SNUM(conn))) {
         /*
          * A blocking lock was requested. Package up
          * this smb into a queued request and push it
@@ -3586,16 +3781,28 @@ dev = %x, inode = %x\n",
          */
         if(push_blocking_lock_request(inbuf, length, lock_timeout, i))
           return -1;
-#endif /* JRATEST */
+      }
       break;
+    }
   }
 
   /* If any of the above locks failed, then we must unlock
      all of the previous locks (X/Open spec). */
   if(i != num_locks && num_locks != 0) {
     for(; i >= 0; i--) {
-      count = IVAL(data,SMB_LKLEN_OFFSET(i));  
-      offset = IVAL(data,SMB_LKOFF_OFFSET(i)); 
+      if(!large_file_format) {
+        count = IVAL(data,SMB_LKLEN_OFFSET(i));  
+        offset = IVAL(data,SMB_LKOFF_OFFSET(i)); 
+      }
+#ifdef LARGE_SMB_OFF_T
+      else {
+        count = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(i))) << 32) |
+                ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(i)));
+        offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) |
+                 ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i)));
+      }
+#endif /* LARGE_SMB_OFF_T */
+
       do_unlock(fsp,conn,count,offset,&dummy1,&dummy2);
     }
     return ERROR(eclass,ecode);
@@ -3606,8 +3813,6 @@ dev = %x, inode = %x\n",
   DEBUG( 3, ( "lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
        fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks ) );
 
-  chain_fsp = fsp;
-
   return chain_reply(inbuf,outbuf,length,bufsize);
 }
 
@@ -3617,15 +3822,16 @@ dev = %x, inode = %x\n",
 ****************************************************************************/
 int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
 {
-  int nread = -1;
-  int total_read;
+  ssize_t nread = -1;
+  ssize_t total_read;
   char *data;
-  uint32 startpos;
-  int outsize, mincount, maxcount;
+  SMB_OFF_T startpos;
+  int outsize;
+  size_t maxcount;
   int max_per_packet;
-  int tcount;
+  size_t tcount;
   int pad;
-  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
+  files_struct *fsp = file_fsp(inbuf,smb_vwv0);
 
   /* this function doesn't seem to work - disable by default */
   if (!lp_readbmpx())
@@ -3639,7 +3845,6 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
 
   startpos = IVAL(inbuf,smb_vwv1);
   maxcount = SVAL(inbuf,smb_vwv3);
-  mincount = SVAL(inbuf,smb_vwv4);
 
   data = smb_buf(outbuf);
   pad = ((long)data)%4;
@@ -3655,14 +3860,14 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
        
   do
     {
-      int N = MIN(max_per_packet,tcount-total_read);
+      size_t N = MIN(max_per_packet,tcount-total_read);
   
       nread = read_file(fsp,data,startpos,N);
 
       if (nread <= 0) nread = 0;
 
-      if (nread < N)
-       tcount = total_read + nread;
+      if (nread < (ssize_t)N)
+        tcount = total_read + nread;
 
       set_message(outbuf,8,nread,False);
       SIVAL(outbuf,smb_vwv0,startpos);
@@ -3675,24 +3880,25 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
       total_read += nread;
       startpos += nread;
     }
-  while (total_read < tcount);
+  while (total_read < (ssize_t)tcount);
 
   return(-1);
 }
 
-
 /****************************************************************************
   reply to a SMBwritebmpx (write block multiplex primary) request
 ****************************************************************************/
 int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-  int numtowrite;
-  int nwritten = -1;
+  size_t numtowrite;
+  ssize_t nwritten = -1;
   int outsize = 0;
-  uint32 startpos;
-  int tcount, write_through, smb_doff;
+  SMB_OFF_T startpos;
+  size_t tcount;
+  BOOL write_through;
+  int smb_doff;
   char *data;
-  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
+  files_struct *fsp = file_fsp(inbuf,smb_vwv0);
 
   CHECK_FSP(fsp,conn);
   CHECK_WRITE(fsp);
@@ -3713,38 +3919,40 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
   if (is_locked(fsp,conn,tcount,startpos,F_WRLCK))
     return(ERROR(ERRDOS,ERRlock));
 
-  seek_file(fsp,startpos);
+  if(seek_file(fsp,startpos) == -1)
+    return(UNIXERROR(ERRDOS,ERRnoaccess));
+
   nwritten = write_file(fsp,data,numtowrite);
 
   if(lp_syncalways(SNUM(conn)) || write_through)
     sync_file(conn,fsp);
   
-  if(nwritten < numtowrite)
+  if(nwritten < (ssize_t)numtowrite)
     return(UNIXERROR(ERRHRD,ERRdiskfull));
 
   /* If the maximum to be written to this file
      is greater than what we just wrote then set
      up a secondary struct to be attached to this
      fd, we will use this to cache error messages etc. */
-  if(tcount > nwritten) 
+  if((ssize_t)tcount > nwritten) 
+  {
+    write_bmpx_struct *wbms;
+    if(fsp->wbmpx_ptr != NULL)
+      wbms = fsp->wbmpx_ptr; /* Use an existing struct */
+    else
+      wbms = (write_bmpx_struct *)malloc(sizeof(write_bmpx_struct));
+    if(!wbms)
     {
-      write_bmpx_struct *wbms;
-      if(fsp->wbmpx_ptr != NULL)
-       wbms = fsp->wbmpx_ptr; /* Use an existing struct */
-      else
-       wbms = (write_bmpx_struct *)malloc(sizeof(write_bmpx_struct));
-      if(!wbms)
-       {
-         DEBUG(0,("Out of memory in reply_readmpx\n"));
-         return(ERROR(ERRSRV,ERRnoresource));
-       }
-      wbms->wr_mode = write_through;
-      wbms->wr_discard = False; /* No errors yet */
-      wbms->wr_total_written = nwritten;
-      wbms->wr_errclass = 0;
-      wbms->wr_error = 0;
-      fsp->wbmpx_ptr = wbms;
+      DEBUG(0,("Out of memory in reply_readmpx\n"));
+      return(ERROR(ERRSRV,ERRnoresource));
     }
+    wbms->wr_mode = write_through;
+    wbms->wr_discard = False; /* No errors yet */
+    wbms->wr_total_written = nwritten;
+    wbms->wr_errclass = 0;
+    wbms->wr_error = 0;
+    fsp->wbmpx_ptr = wbms;
+  }
 
   /* We are returning successfully, set the message type back to
      SMBwritebmpx */
@@ -3777,15 +3985,17 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
 ****************************************************************************/
 int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-  int numtowrite;
-  int nwritten = -1;
+  size_t numtowrite;
+  ssize_t nwritten = -1;
   int outsize = 0;
-  int32 startpos;
-  int tcount, write_through, smb_doff;
+  SMB_OFF_T startpos;
+  size_t tcount;
+  BOOL write_through;
+  int smb_doff;
   char *data;
   write_bmpx_struct *wbms;
   BOOL send_response = False; 
-  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
+  files_struct *fsp = file_fsp(inbuf,smb_vwv0);
 
   CHECK_FSP(fsp,conn);
   CHECK_WRITE(fsp);
@@ -3813,38 +4023,51 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
   if(wbms->wr_discard)
     return -1; /* Just discard the packet */
 
-  seek_file(fsp,startpos);
+  if(seek_file(fsp,startpos) == -1)
+  {
+    if(write_through)
+    {
+      /* We are returning an error - we can delete the aux struct */
+      if (wbms) free((char *)wbms);
+      fsp->wbmpx_ptr = NULL;
+      return(UNIXERROR(ERRDOS,ERRnoaccess));
+    }
+    return(CACHE_ERROR(wbms,ERRDOS,ERRnoaccess));
+  } 
+
   nwritten = write_file(fsp,data,numtowrite);
 
   if(lp_syncalways(SNUM(conn)) || write_through)
     sync_file(conn,fsp);
   
-  if (nwritten < numtowrite)
+  if (nwritten < (ssize_t)numtowrite)
+  {
+    if(write_through)
     {
-      if(write_through)        {
-       /* We are returning an error - we can delete the aux struct */
-       if (wbms) free((char *)wbms);
-       fsp->wbmpx_ptr = NULL;
-       return(ERROR(ERRHRD,ERRdiskfull));
-      }
-      return(CACHE_ERROR(wbms,ERRHRD,ERRdiskfull));
+      /* We are returning an error - we can delete the aux struct */
+      if (wbms) free((char *)wbms);
+      fsp->wbmpx_ptr = NULL;
+      return(ERROR(ERRHRD,ERRdiskfull));
     }
+    return(CACHE_ERROR(wbms,ERRHRD,ERRdiskfull));
+  }
 
   /* Increment the total written, if this matches tcount
      we can discard the auxiliary struct (hurrah !) and return a writeC */
   wbms->wr_total_written += nwritten;
   if(wbms->wr_total_written >= tcount)
+  {
+    if (write_through)
     {
-      if (write_through) {
-       outsize = set_message(outbuf,1,0,True);
-       SSVAL(outbuf,smb_vwv0,wbms->wr_total_written);    
-       send_response = True;
-      }
-
-      free((char *)wbms);
-      fsp->wbmpx_ptr = NULL;
+      outsize = set_message(outbuf,1,0,True);
+      SSVAL(outbuf,smb_vwv0,wbms->wr_total_written);    
+      send_response = True;
     }
 
+    free((char *)wbms);
+    fsp->wbmpx_ptr = NULL;
+  }
+
   if(send_response)
     return(outsize);
 
@@ -3859,7 +4082,7 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_si
 {
   struct utimbuf unix_times;
   int outsize = 0;
-  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
+  files_struct *fsp = file_fsp(inbuf,smb_vwv0);
 
   outsize = set_message(outbuf,0,0,True);
 
@@ -3909,10 +4132,10 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_si
 ****************************************************************************/
 int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
-  struct stat sbuf;
+  SMB_STRUCT_STAT sbuf;
   int outsize = 0;
   int mode;
-  files_struct *fsp = GETFSP(inbuf,smb_vwv0);
+  files_struct *fsp = file_fsp(inbuf,smb_vwv0);
 
   outsize = set_message(outbuf,11,0,True);
 
@@ -3920,7 +4143,7 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_si
   CHECK_ERROR(fsp);
 
   /* Do an fstat on this file */
-  if(fstat(fsp->fd_ptr->fd, &sbuf))
+  if(sys_fstat(fsp->fd_ptr->fd, &sbuf))
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   
   mode = dos_mode(conn,fsp->fsp_name,&sbuf);
@@ -3938,8 +4161,8 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_si
     }
   else
     {
-      SIVAL(outbuf,smb_vwv6,sbuf.st_size);
-      SIVAL(outbuf,smb_vwv8,ROUNDUP(sbuf.st_size,1024));
+      SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size);
+      SIVAL(outbuf,smb_vwv8,SMB_ROUNDUP(sbuf.st_size,1024));
     }
   SSVAL(outbuf,smb_vwv10, mode);