SAM database "set user info".
[samba.git] / source3 / smbd / reply.c
index 12a39589d62e9cef86b69b52af35fca0338a0775..57742003ff6e876cfc98e7e9ea7810f0fb32caf1 100644 (file)
@@ -60,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 
 ****************************************************************************/
@@ -220,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);
   
@@ -300,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)
@@ -413,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);
@@ -447,13 +472,46 @@ 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;    
@@ -582,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);
 
@@ -597,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);
@@ -610,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);
 
@@ -631,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) &&
+      !check_domain_security(orig_user, domain,
                              smb_apasswd, smb_apasslen,
-                            smb_ntpasswd, smb_ntpasslen)) &&
+                             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));
@@ -682,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 */
@@ -723,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);
@@ -760,7 +829,7 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
     if(VALID_STAT(st))
       ok = S_ISDIR(st.st_mode);
     else
-      ok = directory_exist(name,NULL);
+      ok = dos_directory_exist(name,NULL);
   }
 
   if (!ok)
@@ -895,7 +964,7 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   mode = SVAL(inbuf,smb_vwv0);
   mtime = make_unix_date3(inbuf+smb_vwv1);
   
-  if (VALID_STAT_OF_DIR(st) || directory_exist(fname,NULL))
+  if (VALID_STAT_OF_DIR(st) || dos_directory_exist(fname,NULL))
     mode |= aDIR;
   if (check_name(fname,conn))
     ok =  (file_chmod(conn,fname,mode,NULL) == 0);
@@ -1239,6 +1308,7 @@ 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;
@@ -1276,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)
   {
@@ -1353,8 +1423,10 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
   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 */
 
@@ -1529,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)
   {
@@ -1601,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)
   {
@@ -1702,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) && !dos_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;
@@ -1844,6 +1918,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
   
 #if UNSAFE_READRAW
   {
+    BOOL seek_fail = False;
     int predict=0;
     _smb_setlen(header,nread);
 
@@ -1852,11 +1927,18 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
       predict = read_predict(fsp->fd_ptr->fd,startpos,header+4,NULL,nread);
 #endif /* USE_READ_PREDICTION */
 
-    if ((nread-predict) > 0)
-      seek_file(fsp,startpos + predict);
-    
-    ret = (ssize_t)transfer_file(fsp->fd_ptr->fd,Client,(SMB_OFF_T)(nread-predict),header,4+predict,
-                       startpos+predict);
+    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(!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)
@@ -2065,8 +2147,10 @@ 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)
+  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);
@@ -2153,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
@@ -2205,7 +2290,8 @@ 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
@@ -2250,6 +2336,10 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
   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);
@@ -2268,7 +2358,8 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
   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, unlike SMBwrite
      if the length is zero then NO truncation is
@@ -2327,7 +2418,9 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
       umode = SEEK_SET; break;
   }
 
-  res = sys_lseek(fsp->fd_ptr->fd,startpos,umode);
+  if((res = sys_lseek(fsp->fd_ptr->fd,startpos,umode)) == -1)
+    return(UNIXERROR(ERRDOS,ERRnoaccess));
+
   fsp->pos = res;
   
   outsize = set_message(outbuf,2,0,True);
@@ -2419,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 */
@@ -2465,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);
 
@@ -2655,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);
@@ -3190,7 +3294,7 @@ 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) &&
@@ -3199,7 +3303,7 @@ int rename_internals(connection_struct *conn,
                } else {
                        if (resolve_wildcards(directory,newname) && 
                            can_rename(directory,conn) && 
-                           !file_exist(newname,NULL) &&
+                           !dos_file_exist(newname,NULL) &&
                            !dos_rename(directory,newname))
                                count++;
                }
@@ -3207,10 +3311,10 @@ int rename_internals(connection_struct *conn,
                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 {
                /*
@@ -3249,8 +3353,8 @@ 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;
                                }
@@ -3303,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;
   SMB_STRUCT_STAT st;
-  int ret=0;
+  int ret=-1;
   files_struct *fsp1,*fsp2;
   pstring dest;
   
@@ -3323,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);
@@ -3343,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) {
@@ -3353,7 +3461,15 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
   }
 
   if ((ofun&3) == 1) {
-    sys_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)
@@ -3405,7 +3521,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   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));
@@ -3415,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));    
@@ -3442,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;
@@ -3517,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);
          }
@@ -3581,7 +3697,7 @@ 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 = %.0f\n", fsp->fnum, (unsigned int)dev, (double)inode));
@@ -3803,7 +3919,9 @@ 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)
@@ -3905,7 +4023,18 @@ 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)
@@ -4033,7 +4162,7 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_si
   else
     {
       SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size);
-      SIVAL(outbuf,smb_vwv8,ROUNDUP(sbuf.st_size,1024));
+      SIVAL(outbuf,smb_vwv8,SMB_ROUNDUP(sbuf.st_size,1024));
     }
   SSVAL(outbuf,smb_vwv10, mode);