Added per-share parameter "store dos attributes". When set, will store
authorJeremy Allison <jra@samba.org>
Fri, 2 Apr 2004 18:46:19 +0000 (18:46 +0000)
committerJeremy Allison <jra@samba.org>
Fri, 2 Apr 2004 18:46:19 +0000 (18:46 +0000)
dos attributes in an EA. Based on an original patch from tridge, but
modified somewhat to cover all cases.
Jeremy.
(This used to be commit ed653cd468213e0be901bc654aa3748ce5837947)

13 files changed:
source3/include/smb.h
source3/param/loadparm.c
source3/printing/nt_printing.c
source3/rpc_server/srv_srvsvc_nt.c
source3/smbd/dir.c
source3/smbd/dosmode.c
source3/smbd/fake_file.c
source3/smbd/fileio.c
source3/smbd/nttrans.c
source3/smbd/open.c
source3/smbd/posix_acls.c
source3/smbd/reply.c
source3/smbd/trans2.c

index 24c0100b5b9e5a26da487ab23f1f0d598b6b32b2..3ee6f01d34df68f3e11612e148bcfcf618f3cfa6 100644 (file)
@@ -1668,4 +1668,7 @@ struct ea_struct {
 
 /* EA names used internally in Samba. KEEP UP TO DATE with prohibited_ea_names in trans2.c !. */
 #define SAMBA_POSIX_INHERITANCE_EA_NAME "user.SAMBA_PAI"
+/* EA to use for DOS attributes */
+#define SAMBA_XATTR_DOS_ATTRIB "user.DOSATTRIB"
+
 #endif /* _SMB_H */
index 4c0a3948f89fe3c4c6c9ad40a216b707c53b75a8..6b09faf7bf9bdfba5d26a79c67fde508d2cdb036 100644 (file)
@@ -379,6 +379,7 @@ typedef struct
        BOOL bMap_system;
        BOOL bMap_hidden;
        BOOL bMap_archive;
+       BOOL bStoreDosAttributes;
        BOOL bLocking;
        BOOL bStrictLocking;
        BOOL bPosixLocking;
@@ -501,6 +502,7 @@ static service sDefault = {
        False,                  /* bMap_system */
        False,                  /* bMap_hidden */
        True,                   /* bMap_archive */
+       False,                  /* bStoreDosAttributes */
        True,                   /* bLocking */
        True,                   /* bStrictLocking */
        True,                   /* bPosixLocking */
@@ -994,6 +996,7 @@ static struct parm_struct parm_table[] = {
        {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
        {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED }, 
        {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_ADVANCED}, 
+       {"store dos attributes", P_BOOL, P_LOCAL, &sDefault.bStoreDosAttributes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
 
        {N_("Domain Options"), P_SEP, P_SEPARATOR}, 
 
@@ -1844,6 +1847,7 @@ FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
+FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
 FN_LOCAL_BOOL(lp_locking, bLocking)
 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
index f7e2945426b2211699649cbc19d421a14e266cfb..449b0e83edc603dad1c21827f9ac58f83d63a9e9 100644 (file)
@@ -992,7 +992,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
        fsp = open_file_shared(conn, filepath, &stat_buf,
                                                   SET_OPEN_MODE(DOS_OPEN_RDONLY),
                                                   (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
-                                                  0, 0, &access_mode, &action);
+                                                  FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &action);
        if (!fsp) {
                /* Old file not found, so by definition new file is in fact newer */
                DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
@@ -1021,7 +1021,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
        fsp = open_file_shared(conn, filepath, &stat_buf,
                                                   SET_OPEN_MODE(DOS_OPEN_RDONLY),
                                                   (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
-                                                  0, 0, &access_mode, &action);
+                                                  FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &action);
        if (!fsp) {
                /* New file not found, this shouldn't occur if the caller did its job */
                DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
@@ -1137,7 +1137,7 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
        fsp = open_file_shared(conn, driverpath, &st,
                                                   SET_OPEN_MODE(DOS_OPEN_RDONLY),
                                                   (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
-                                                  0, 0, &access_mode, &action);
+                                                  FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &action);
        if (!fsp) {
                DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
                                driverpath, errno));
index 40d3a43bef9df020823b7afb1b8bbb473f73e1bd..77b9be99660ba64f3d66ea6831398449e5b96fc2 100644 (file)
@@ -1887,13 +1887,13 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
        unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
        unix_convert(filename, conn, NULL, &bad_path, &st);
        fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDONLY),
-                               (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
+                               (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &action);
 
        if (!fsp) {
                /* Perhaps it is a directory */
                if (errno == EISDIR)
                        fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
-                                       (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
+                                       (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), &action);
 
                if (!fsp) {
                        DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
@@ -1991,13 +1991,13 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
        unix_convert(filename, conn, NULL, &bad_path, &st);
 
        fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDWR),
-                       (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
+                       (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &action);
 
        if (!fsp) {
                /* Perhaps it is a directory */
                if (errno == EISDIR)
                        fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
-                                               (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
+                                               (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), &action);
 
                if (!fsp) {
                        DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
index bbd79e165975d9852f3b7d529b5b6952ea675cd3..06ef23ab8cd64e2661cf4a5ad4d1fd368154092e 100644 (file)
@@ -707,7 +707,7 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S
 
        if(S_ISDIR(pst->st_mode))       
                 fsp = open_directory(conn, name, pst, 0, SET_DENY_MODE(DENY_NONE), (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
-                       unix_mode(conn,aRONLY|aDIR, name), &smb_action);
+                       &smb_action);
        else
                fsp = open_file_stat(conn, name, pst);
 
@@ -763,7 +763,7 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_
                return True;
        else
                fsp = open_file_shared1(conn, name, pst, FILE_WRITE_ATTRIBUTES, SET_DENY_MODE(DENY_NONE),
-                       (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
+                       (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action);
 
        if (!fsp)
                return False;
index 1369c46b2f6245d3fa64224029ea10b7d949feff..d7dc63bb2fd746a0092481b9facde94c2b40da5f 100644 (file)
 
 mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname)
 {
-       mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
+       mode_t result = (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
        mode_t dir_mode = 0; /* Mode of the parent directory if inheriting. */
 
-       if ( !IS_DOS_READONLY(dosmode) )
-               result |= (S_IWUSR | S_IWGRP | S_IWOTH);
+       if (!lp_store_dos_attributes(SNUM(conn)) && IS_DOS_READONLY(dosmode)) {
+               result &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
+       }
 
        if (fname && lp_inherit_perms(SNUM(conn))) {
                char *dname;
@@ -159,22 +160,130 @@ uint32 dos_mode_from_sbuf(connection_struct *conn, SMB_STRUCT_STAT *sbuf)
        return result;
 }
 
+/****************************************************************************
+ Get DOS attributes from an EA.
+****************************************************************************/
+
+static BOOL get_ea_dos_attribute(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf, uint32 *pattr)
+{
+       ssize_t sizeret;
+       fstring attrstr;
+       unsigned int dosattr;
+
+       if (!lp_store_dos_attributes(SNUM(conn))) {
+               return False;
+       }
+
+       *pattr = 0;
+
+       sizeret = SMB_VFS_GETXATTR(conn, path, SAMBA_XATTR_DOS_ATTRIB, attrstr, sizeof(attrstr));
+       if (sizeret == -1) {
+#if defined(ENOTSUP) && defined(ENOATTR)
+               if ((errno != ENOTSUP) && (errno != ENOATTR) && (errno != EACCES)) {
+                       DEBUG(1,("get_ea_dos_attributes: Cannot get attribute from EA on file %s: Error = %s\n",
+                               path, strerror(errno) ));
+               }
+#endif
+               return False;
+       }
+       /* Null terminate string. */
+       attrstr[sizeret] = 0;
+       DEBUG(10,("get_ea_dos_attribute: %s attrstr = %s\n", path, attrstr));
+
+       if (sizeret < 2 || attrstr[0] != '0' || attrstr[1] != 'x' ||
+                       sscanf(attrstr, "%x", &dosattr) != 1) {
+               DEBUG(1,("get_ea_dos_attributes: Badly formed DOSATTRIB on file %s - %s\n", path, attrstr));
+                return False;
+        }
+
+       if (S_ISDIR(sbuf->st_mode)) {
+               dosattr |= aDIR;
+       }
+       *pattr = (uint32)(dosattr & SAMBA_ATTRIBUTES_MASK);
+
+       DEBUG(8,("get_ea_dos_attribute returning (0x%x)", dosattr));
+
+       if (dosattr & aHIDDEN) DEBUG(8, ("h"));
+       if (dosattr & aRONLY ) DEBUG(8, ("r"));
+       if (dosattr & aSYSTEM) DEBUG(8, ("s"));
+       if (dosattr & aDIR   ) DEBUG(8, ("d"));
+       if (dosattr & aARCH  ) DEBUG(8, ("a"));
+       
+       DEBUG(8,("\n"));
+
+       return True;
+}
+
+/****************************************************************************
+ Set DOS attributes in an EA.
+****************************************************************************/
+
+static BOOL set_ea_dos_attribute(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf, uint32 dosmode)
+{
+       fstring attrstr;
+       files_struct *fsp = NULL;
+       BOOL ret = False;
+
+       snprintf(attrstr, sizeof(attrstr)-1, "0x%x", dosmode & SAMBA_ATTRIBUTES_MASK);
+       if (SMB_VFS_SETXATTR(conn, path, SAMBA_XATTR_DOS_ATTRIB, attrstr, strlen(attrstr), 0) == -1) {
+               if((errno != EPERM) && (errno != EACCES)) {
+                       return False;
+               }
+
+               /* We want DOS semantics, ie allow non owner with write permission to change the
+                       bits on a file. Just like file_utime below.
+               */
+
+               /* Check if we have write access. */
+               if(!CAN_WRITE(conn) || !lp_dos_filemode(SNUM(conn)))
+                       return False;
+
+               /*
+                * We need to open the file with write access whilst
+                * still in our current user context. This ensures we
+                * are not violating security in doing the setxattr.
+                */
+
+               fsp = open_file_fchmod(conn,path,sbuf);
+               if (!fsp)
+                       return ret;
+               become_root();
+               if (SMB_VFS_SETXATTR(conn, path, SAMBA_XATTR_DOS_ATTRIB, attrstr, strlen(attrstr), 0) == 0) {
+                       ret = True;
+               }
+               unbecome_root();
+               close_file_fchmod(fsp);
+               return ret;
+       }
+       DEBUG(10,("set_ea_dos_attribute: set EA %s on file %s\n", attrstr, path));
+       return True;
+}
+
 /****************************************************************************
  Change a unix mode to a dos mode.
 ****************************************************************************/
 
-uint32 dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf)
+uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf)
 {
-       int result = 0;
+       uint32 result = 0;
 
        DEBUG(8,("dos_mode: %s\n", path));
 
+       if (!VALID_STAT(*sbuf)) {
+               return 0;
+       }
+
+       /* Get the DOS attributes from an EA by preference. */
+       if (get_ea_dos_attribute(conn, path, sbuf, &result)) {
+               return result;
+       }
+
        result = dos_mode_from_sbuf(conn, sbuf);
 
        /* Now do any modifications that depend on the path name. */
        /* hide files with a name starting with a . */
        if (lp_hide_dot_files(SNUM(conn))) {
-               char *p = strrchr_m(path,'/');
+               const char *p = strrchr_m(path,'/');
                if (p)
                        p++;
                else
@@ -207,7 +316,7 @@ uint32 dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf)
  chmod a file - but preserve some bits.
 ********************************************************************/
 
-int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_STAT *st)
+int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, SMB_STRUCT_STAT *st)
 {
        SMB_STRUCT_STAT st1;
        int mask=0;
@@ -215,6 +324,7 @@ int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_ST
        mode_t unixmode;
        int ret = -1;
 
+       DEBUG(10,("file_set_dosmode: setting dos mode 0x%x on file %s\n", dosmode, fname));
        if (!st) {
                st = &st1;
                if (SMB_VFS_STAT(conn,fname,st))
@@ -231,6 +341,11 @@ int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_ST
        if (dos_mode(conn,fname,st) == dosmode)
                return(0);
 
+       /* Store the DOS attributes in an EA by preference. */
+       if (set_ea_dos_attribute(conn, fname, st, dosmode)) {
+               return 0;
+       }
+
        unixmode = unix_mode(conn,dosmode,fname);
 
        /* preserve the s bits */
index 86d78e039a1260f6f094f0c49e4b39cf4edf5952..5ccb548ba5bd530475cf532c3489290aea233cc6 100644 (file)
@@ -26,7 +26,7 @@
 files_struct *open_fake_file_shared1(enum FAKE_FILE_TYPE fake_file_type, connection_struct *conn,char *fname,
                                SMB_STRUCT_STAT *psbuf, 
                                uint32 desired_access, 
-                               int share_mode,int ofun, mode_t mode,int oplock_request, 
+                               int share_mode,int ofun, uint32 new_dos_attr, int oplock_request, 
                                int *Access,int *action)
 {
        extern struct current_user current_user;
@@ -35,7 +35,7 @@ files_struct *open_fake_file_shared1(enum FAKE_FILE_TYPE fake_file_type, connect
 
        if (fake_file_type == 0) {
                return open_file_shared1(conn,fname,psbuf,desired_access,
-                                       share_mode,ofun,mode,
+                                       share_mode,ofun,new_dos_attr,
                                        oplock_request,Access,action);  
        }
 
@@ -51,8 +51,8 @@ files_struct *open_fake_file_shared1(enum FAKE_FILE_TYPE fake_file_type, connect
        if(!fsp)
                return NULL;
 
-       DEBUG(5,("open_fake_file_shared1: fname = %s, FID = %d, share_mode = %x, ofun = %x, mode = %o, oplock request = %d\n",
-               fname, fsp->fnum, share_mode, ofun, (int)mode,  oplock_request ));
+       DEBUG(5,("open_fake_file_shared1: fname = %s, FID = %d, share_mode = %x, ofun = %x, oplock request = %d\n",
+               fname, fsp->fnum, share_mode, ofun, oplock_request ));
 
        if (!check_name(fname,conn)) {
                file_free(fsp);
index 3462a3b9fa57ff03324b838019e0104a50aea479..c2fb6e345665e55728d1f0f51ea0d6f17b3e46fc 100644 (file)
@@ -176,8 +176,9 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n)
                if (SMB_VFS_FSTAT(fsp,fsp->fd,&st) == 0) {
                        int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st);
                        fsp->size = (SMB_BIG_UINT)st.st_size;
-                       if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode))
-                               file_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st);
+                       if ((lp_store_dos_attributes(SNUM(fsp->conn)) || MAP_ARCHIVE(fsp->conn)) && !IS_DOS_ARCHIVE(dosmode)) {
+                               file_set_dosmode(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st);
+                       }
 
                        /*
                         * If this is the first write and we have an exclusive oplock then setup
index 21b6db8b4691df241f484779a15c7811b614d49b..c9cc44627dbc41bbdf73c089dc287966429cd1dd 100644 (file)
@@ -586,11 +586,9 @@ int reply_ntcreate_and_X(connection_struct *conn,
        SMB_BIG_UINT allocation_size = 0;
        int smb_ofun;
        int smb_open_mode;
-       int smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK);
        /* Breakout the oplock request bits so we can set the
           reply bits separately. */
        int oplock_request = 0;
-       mode_t unixmode;
        int fmode=0,rmode=0;
        SMB_OFF_T file_len = 0;
        SMB_STRUCT_STAT sbuf;
@@ -766,8 +764,6 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
                
        unix_convert(fname,conn,0,&bad_path,&sbuf);
                
-       unixmode = unix_mode(conn,smb_attr | aARCH, fname);
-    
        /* 
         * If it's a request for a directory open, deal with it separately.
         */
@@ -781,7 +777,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
                        return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
                }
 
-               fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, unixmode, &smb_action);
+               fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, &smb_action);
                        
                restore_case_semantics(file_attributes);
 
@@ -811,14 +807,14 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
                        fsp = open_file_shared1(conn,fname,&sbuf,
                                        desired_access,
                                        smb_open_mode,
-                                       smb_ofun,unixmode, oplock_request,
+                                       smb_ofun,file_attributes,oplock_request,
                                        &rmode,&smb_action);
                } else {
                        /* to open a fake_file --metze */
                        fsp = open_fake_file_shared1(fake_file_type,conn,fname,&sbuf,
                                        desired_access,
                                        smb_open_mode,
-                                       smb_ofun,unixmode, oplock_request,
+                                       smb_ofun,file_attributes, oplock_request,
                                        &rmode,&smb_action);
                }
                
@@ -857,7 +853,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
                                }
        
                                oplock_request = 0;
-                               fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, unixmode, &smb_action);
+                               fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, &smb_action);
                                
                                if(!fsp) {
                                        restore_case_semantics(file_attributes);
@@ -1134,7 +1130,6 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
        char *data = *ppdata;
        /* Breakout the oplock request bits so we can set the reply bits separately. */
        int oplock_request = 0;
-       mode_t unixmode;
        int fmode=0,rmode=0;
        SMB_OFF_T file_len = 0;
        SMB_STRUCT_STAT sbuf;
@@ -1154,7 +1149,6 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
        SMB_BIG_UINT allocation_size = 0;
        int smb_ofun;
        int smb_open_mode;
-       int smb_attr;
        time_t c_time;
        NTSTATUS status;
 
@@ -1192,7 +1186,6 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
        create_options = IVAL(params,32);
        sd_len = IVAL(params,36);
        root_dir_fid = (uint16)IVAL(params,4);
-       smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK);
 
        if (create_options & FILE_OPEN_BY_FILE_ID) {
                return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
@@ -1297,8 +1290,6 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
 
        unix_convert(fname,conn,0,&bad_path,&sbuf);
     
-       unixmode = unix_mode(conn,smb_attr | aARCH, fname);
-   
        /*
         * If it's a request for a directory open, deal with it separately.
         */
@@ -1318,7 +1309,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
                 * CreateDirectory() call.
                 */
 
-               fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, unixmode, &smb_action);
+               fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, &smb_action);
 
                if(!fsp) {
                        restore_case_semantics(file_attributes);
@@ -1332,7 +1323,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
                 */
 
                fsp = open_file_shared1(conn,fname,&sbuf,desired_access,
-                                               smb_open_mode,smb_ofun,unixmode,
+                                               smb_open_mode,smb_ofun,file_attributes,
                                                oplock_request,&rmode,&smb_action);
 
                if (!fsp) { 
@@ -1350,7 +1341,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
                                }
        
                                oplock_request = 0;
-                               fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, unixmode, &smb_action);
+                               fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, &smb_action);
                                
                                if(!fsp) {
                                        restore_case_semantics(file_attributes);
index 084ae9a1bf2aaed31645e0995967e6996a3d86c6..8ab5dab6ac9322cf11bbb15828a8fd677465f529 100644 (file)
@@ -741,21 +741,10 @@ static void kernel_flock(files_struct *fsp, int deny_mode)
 }
 
 
-static BOOL open_match_attributes(connection_struct *conn, char *path, mode_t existing_mode,
-               mode_t new_mode, mode_t *returned_mode)
+static BOOL open_match_attributes(connection_struct *conn, const char *path, uint32 old_dos_mode, uint32 new_dos_mode,
+               mode_t existing_mode, mode_t new_mode, mode_t *returned_mode)
 {
-       uint32 old_dos_mode, new_dos_mode;
        uint32 noarch_old_dos_mode, noarch_new_dos_mode;
-       SMB_STRUCT_STAT sbuf;
-
-       ZERO_STRUCT(sbuf);
-
-       sbuf.st_mode = existing_mode;
-       old_dos_mode = dos_mode(conn, path, &sbuf);
-
-       sbuf.st_mode = new_mode;
-       /* The new mode conversion shouldn't look at pathname. */
-       new_dos_mode = dos_mode_from_sbuf(conn, &sbuf);
 
        noarch_old_dos_mode = (old_dos_mode & ~FILE_ATTRIBUTE_ARCHIVE);
        noarch_new_dos_mode = (new_dos_mode & ~FILE_ATTRIBUTE_ARCHIVE);
@@ -771,11 +760,11 @@ static BOOL open_match_attributes(connection_struct *conn, char *path, mode_t ex
                old_dos_mode, (unsigned int)existing_mode, new_dos_mode, (unsigned int)*returned_mode ));
 
        /* If we're mapping SYSTEM and HIDDEN ensure they match. */
-       if (lp_map_system(SNUM(conn))) {
+       if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
                if ((old_dos_mode & FILE_ATTRIBUTE_SYSTEM) && !(new_dos_mode & FILE_ATTRIBUTE_SYSTEM))
                        return False;
        }
-       if (lp_map_hidden(SNUM(conn))) {
+       if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
                if ((old_dos_mode & FILE_ATTRIBUTE_HIDDEN) && !(new_dos_mode & FILE_ATTRIBUTE_HIDDEN))
                        return False;
        }
@@ -787,10 +776,10 @@ static BOOL open_match_attributes(connection_struct *conn, char *path, mode_t ex
 ****************************************************************************/
 
 files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf, 
-                              int share_mode,int ofun, mode_t mode,int oplock_request, 
+                              int share_mode,int ofun, uint32 new_dos_mode, int oplock_request, 
                               int *Access,int *action)
 {
-       return open_file_shared1(conn, fname, psbuf, 0, share_mode, ofun, mode, 
+       return open_file_shared1(conn, fname, psbuf, 0, share_mode, ofun, new_dos_mode,
                                 oplock_request, Access, action);
 }
 
@@ -800,8 +789,9 @@ files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_S
 
 files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf, 
                                uint32 desired_access, 
-                               int share_mode,int ofun, mode_t mode,int oplock_request, 
-                               int *Access,int *action)
+                               int share_mode,int ofun, uint32 new_dos_mode,
+                               int oplock_request, 
+                               int *Access,int *paction)
 {
        int flags=0;
        int flags2=0;
@@ -820,6 +810,10 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
        int open_mode=0;
        uint16 port = 0;
        mode_t new_mode = (mode_t)0;
+       int action;
+       uint32 existing_dos_mode = 0;
+       /* We add aARCH to this as this mode is only used if the file is created new. */
+       mode_t mode = unix_mode(conn,new_dos_mode | aARCH,fname);
 
        if (conn->printer) {
                /* printers are handled completely differently. Most of the passed parameters are
@@ -827,7 +821,7 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
                if (Access)
                        *Access = DOS_OPEN_WRONLY;
                if (action)
-                       *action = FILE_WAS_CREATED;
+                       *paction = FILE_WAS_CREATED;
                return print_fsp_open(conn, fname);
        }
 
@@ -835,14 +829,19 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
        if(!fsp)
                return NULL;
 
-       DEBUG(10,("open_file_shared: fname = %s, share_mode = %x, ofun = %x, mode = %o, oplock request = %d\n",
-               fname, share_mode, ofun, (int)mode,  oplock_request ));
+       DEBUG(10,("open_file_shared: fname = %s, dos_attrs = %x, share_mode = %x, ofun = %x, mode = %o, oplock request = %d\n",
+               fname, new_dos_mode, share_mode, ofun, (int)mode,  oplock_request ));
 
        if (!check_name(fname,conn)) {
                file_free(fsp);
                return NULL;
        } 
 
+       new_dos_mode &= SAMBA_ATTRIBUTES_MASK;
+       if (file_existed) {
+               existing_dos_mode = dos_mode(conn, fname, psbuf);
+       }
+
        /* ignore any oplock requests if oplocks are disabled */
        if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break) {
                oplock_request = 0;
@@ -883,9 +882,11 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
 
        /* We only care about matching attributes on file exists and truncate. */
        if (file_existed && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE)) {
-               if (!open_match_attributes(conn, fname, psbuf->st_mode, mode, &new_mode)) {
-                       DEBUG(5,("open_file_shared: attributes missmatch for file %s (0%o, 0%o)\n",
-                                               fname, (int)psbuf->st_mode, (int)mode ));
+               if (!open_match_attributes(conn, fname, existing_dos_mode, new_dos_mode,
+                                       psbuf->st_mode, mode, &new_mode)) {
+                       DEBUG(5,("open_file_shared: attributes missmatch for file %s (%x %x) (0%o, 0%o)\n",
+                                               fname, existing_dos_mode, new_dos_mode,
+                                               (int)psbuf->st_mode, (int)mode ));
                        file_free(fsp);
                        errno = EACCES;
                        return NULL;
@@ -929,7 +930,7 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
 #endif /* O_SYNC */
   
        if (flags != O_RDONLY && file_existed && 
-                       (!CAN_WRITE(conn) || IS_DOS_READONLY(dos_mode(conn,fname,psbuf)))) {
+                       (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_mode))) {
                if (!fcbopen) {
                        DEBUG(5,("open_file_shared: read/write access requested for file %s on read only %s\n",
                                fname, !CAN_WRITE(conn) ? "share" : "file" ));
@@ -1120,16 +1121,19 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
 
        DEBUG(10,("open_file_shared : share_mode = %x\n", fsp->share_mode ));
 
-       if (Access)
+       if (Access) {
                (*Access) = open_mode;
+       }
 
-       if (action) {
-               if (file_existed && !(flags2 & O_TRUNC))
-                       *action = FILE_WAS_OPENED;
-               if (!file_existed)
-                       *action = FILE_WAS_CREATED;
-               if (file_existed && (flags2 & O_TRUNC))
-                       *action = FILE_WAS_OVERWRITTEN;
+       if (file_existed && !(flags2 & O_TRUNC))
+               action = FILE_WAS_OPENED;
+       if (file_existed && (flags2 & O_TRUNC))
+               action = FILE_WAS_OVERWRITTEN;
+       if (!file_existed) 
+               action = FILE_WAS_CREATED;
+
+       if (paction) {
+               *paction = action;
        }
 
        /* 
@@ -1164,6 +1168,13 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
                }
        }
        
+       if (action == FILE_WAS_OVERWRITTEN || action == FILE_WAS_CREATED) {
+               /* Files should be initially set as archive */
+               if (lp_map_archive(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
+                       file_set_dosmode(conn, fname, new_dos_mode | aARCH, NULL);
+               }
+       }
+
        /*
         * Take care of inherited ACLs on created files - if default ACL not
         * selected.
@@ -1257,7 +1268,7 @@ int close_file_fchmod(files_struct *fsp)
 ****************************************************************************/
 
 files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf,
-                       uint32 desired_access, int share_mode, int smb_ofun, mode_t unixmode, int *action)
+                       uint32 desired_access, int share_mode, int smb_ofun, int *action)
 {
        extern struct current_user current_user;
        BOOL got_stat = False;
index ee370437ec35d23da3797b849d0f40b4925e962c..620e123e14dfa6776dee9f4e124278c2c4d4c261 100644 (file)
@@ -3181,7 +3181,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
  the mask bits, not the real group bits, for a file with an ACL.
 ****************************************************************************/
 
-int get_acl_group_bits( connection_struct *conn, char *fname, mode_t *mode )
+int get_acl_group_bits( connection_struct *conn, const char *fname, mode_t *mode )
 {
        int entry_id = SMB_ACL_FIRST_ENTRY;
        SMB_ACL_ENTRY_T entry;
index f5c4f25e408e46394bdb64f691df0dd5c9e32d9a..fde4ee627fdcee56eafd5b1d7496b29c120f5067 100644 (file)
@@ -678,8 +678,9 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
                else
                        mode &= ~aDIR;
 
-               if (check_name(fname,conn))
-                       ok =  (file_chmod(conn,fname,mode,NULL) == 0);
+               if (check_name(fname,conn)) {
+                       ok = (file_set_dosmode(conn,fname,mode,NULL) == 0);
+               }
        } else {
                ok = True;
        }
@@ -1008,12 +1009,12 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
        int share_mode;
        SMB_OFF_T size = 0;
        time_t mtime=0;
-       mode_t unixmode;
        int rmode=0;
        SMB_STRUCT_STAT sbuf;
        BOOL bad_path = False;
        files_struct *fsp;
        int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
+       uint16 dos_attr = SVAL(inbuf,smb_vwv1);
        NTSTATUS status;
        START_PROFILE(SMBopen);
  
@@ -1029,10 +1030,8 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 
        unix_convert(fname,conn,0,&bad_path,&sbuf);
     
-       unixmode = unix_mode(conn,aARCH,fname);
-      
        fsp = open_file_shared(conn,fname,&sbuf,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
-                       unixmode, oplock_request,&rmode,NULL);
+                       (uint32)dos_attr, oplock_request,&rmode,NULL);
 
        if (!fsp) {
                END_PROFILE(SMBopen);
@@ -1089,7 +1088,6 @@ 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);
-       mode_t unixmode;
        SMB_OFF_T size=0;
        int fmode=0,mtime=0,rmode=0;
        SMB_STRUCT_STAT sbuf;
@@ -1121,9 +1119,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
 
        unix_convert(fname,conn,0,&bad_path,&sbuf);
     
-       unixmode = unix_mode(conn,smb_attr | aARCH, fname);
-      
-       fsp = open_file_shared(conn,fname,&sbuf,smb_mode,smb_ofun,unixmode,
+       fsp = open_file_shared(conn,fname,&sbuf,smb_mode,smb_ofun,(uint32)smb_attr,
                        oplock_request, &rmode,&smb_action);
       
        if (!fsp) {
@@ -1215,7 +1211,6 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
        int com;
        int outsize = 0;
        int createmode;
-       mode_t unixmode;
        int ofun = 0;
        BOOL bad_path = False;
        files_struct *fsp;
@@ -1240,8 +1235,6 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
        if (createmode & aVOLID)
                DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
   
-       unixmode = unix_mode(conn,createmode,fname);
-  
        if(com == SMBmknew) {
                /* We should fail if file exists. */
                ofun = FILE_CREATE_IF_NOT_EXIST;
@@ -1252,7 +1245,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 
        /* Open file in dos compatibility share mode. */
        fsp = open_file_shared(conn,fname,&sbuf,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB), 
-                       ofun, unixmode, oplock_request, NULL, NULL);
+                       ofun, (uint32)createmode, oplock_request, NULL, NULL);
   
        if (!fsp) {
                END_PROFILE(SMBcreate);
@@ -1269,7 +1262,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
                SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
  
        DEBUG( 2, ( "new file %s\n", fname ) );
-       DEBUG( 3, ( "mknew %s fd=%d dmode=%d umode=%o\n", fname, fsp->fd, createmode, (int)unixmode ) );
+       DEBUG( 3, ( "mknew %s fd=%d dmode=%d\n", fname, fsp->fd, createmode ) );
 
        END_PROFILE(SMBcreate);
        return(outsize);
@@ -1283,8 +1276,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 {
        pstring fname;
        int outsize = 0;
-       int createmode;
-       mode_t unixmode;
+       int createattr;
        BOOL bad_path = False;
        files_struct *fsp;
        int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
@@ -1295,7 +1287,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 
        START_PROFILE(SMBctemp);
 
-       createmode = SVAL(inbuf,smb_vwv0);
+       createattr = SVAL(inbuf,smb_vwv0);
        srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status);
        if (!NT_STATUS_IS_OK(status)) {
                END_PROFILE(SMBctemp);
@@ -1307,8 +1299,6 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 
        unix_convert(fname,conn,0,&bad_path,&sbuf);
   
-       unixmode = unix_mode(conn,createmode,fname);
-  
        tmpfd = smb_mkstemp(fname);
        if (tmpfd == -1) {
                END_PROFILE(SMBctemp);
@@ -1322,7 +1312,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
        fsp = open_file_shared(conn,fname,&sbuf,
                SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
                FILE_EXISTS_OPEN|FILE_FAIL_IF_NOT_EXIST,
-               unixmode, oplock_request, NULL, NULL);
+               (uint32)createattr, oplock_request, NULL, NULL);
 
        /* close fd from smb_mkstemp() */
        close(tmpfd);
@@ -1356,8 +1346,8 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
                SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
 
        DEBUG( 2, ( "created temp file %s\n", fname ) );
-       DEBUG( 3, ( "ctemp %s fd=%d dmode=%d umode=%o\n",
-                       fname, fsp->fd, createmode, (int)unixmode ) );
+       DEBUG( 3, ( "ctemp %s fd=%d umode=%o\n",
+                       fname, fsp->fd, sbuf.st_mode ) );
 
        END_PROFILE(SMBctemp);
        return(outsize);
@@ -1384,7 +1374,7 @@ static NTSTATUS can_rename(char *fname,connection_struct *conn, SMB_STRUCT_STAT
        unix_ERR_code = 0;
 
        fsp = open_file_shared1(conn, fname, pst, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
-               (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
+               (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action);
 
        if (!fsp) {
                NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
@@ -1449,7 +1439,7 @@ static NTSTATUS can_delete(char *fname,connection_struct *conn, int dirtype, BOO
        unix_ERR_code = 0;
 
        fsp = open_file_shared1(conn, fname, &sbuf, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
-               (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
+               (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action);
 
        if (!fsp) {
                NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
@@ -3949,7 +3939,8 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
        SMB_OFF_T ret=-1;
        files_struct *fsp1,*fsp2;
        pstring dest;
-  
+       uint32 dosattrs;
        *err_ret = 0;
 
        pstrcpy(dest,dest1);
@@ -3967,7 +3958,7 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
                return(False);
 
        fsp1 = open_file_shared(conn,src,&src_sbuf,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
-                                       (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),0,0,&Access,&action);
+                                       (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),FILE_ATTRIBUTE_NORMAL,0,&Access,&action);
 
        if (!fsp1)
                return(False);
@@ -3975,11 +3966,12 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
        if (!target_is_directory && count)
                ofun = FILE_EXISTS_OPEN;
 
+       dosattrs = dos_mode(conn, src, &src_sbuf);
        if (SMB_VFS_STAT(conn,dest,&sbuf2) == -1)
                ZERO_STRUCTP(&sbuf2);
 
        fsp2 = open_file_shared(conn,dest,&sbuf2,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
-                       ofun,src_sbuf.st_mode,0,&Access,&action);
+                       ofun,dosattrs,0,&Access,&action);
 
        if (!fsp2) {
                close_file(fsp1,False);
index b1807705a0bf353ac512c938910e96d65a833b4d..a88722edde51febab368dc8bb69925852e1c32c2 100644 (file)
@@ -55,6 +55,7 @@ SMB_BIG_UINT get_allocation_size(files_struct *fsp, SMB_STRUCT_STAT *sbuf)
 
 static const char *prohibited_ea_names[] = {
        SAMBA_POSIX_INHERITANCE_EA_NAME,
+       SAMBA_XATTR_DOS_ATTRIB,
        NULL
 };
 
@@ -538,7 +539,6 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
        int32 open_size;
        char *pname;
        pstring fname;
-       mode_t unixmode;
        SMB_OFF_T size=0;
        int fmode=0,mtime=0,rmode;
        SMB_INO_T inode = 0;
@@ -586,9 +586,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
                return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
        }
 
-       unixmode = unix_mode(conn,open_attr | aARCH, fname);
-      
-       fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,unixmode,
+       fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,(uint32)open_attr,
                oplock_request, &rmode,&smb_action);
       
        if (!fsp) {
@@ -3133,7 +3131,8 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
                                        new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA,
                                                                        SET_OPEN_MODE(DOS_OPEN_RDWR),
                                                                        (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
-                                                                       0, 0, &access_mode, &action);
+                                                                       FILE_ATTRIBUTE_NORMAL,
+                                                                       0, &access_mode, &action);
  
                                        if (new_fsp == NULL)
                                                return(UNIXERROR(ERRDOS,ERRbadpath));
@@ -3528,8 +3527,8 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
 
                DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode ));
 
-               if(file_chmod(conn, fname, dosmode, NULL)) {
-                       DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
+               if(file_set_dosmode(conn, fname, dosmode, NULL)) {
+                       DEBUG(2,("file_set_dosmode of %s failed (%s)\n", fname, strerror(errno)));
                        return(UNIXERROR(ERRDOS,ERRnoaccess));
                }
        }
@@ -3559,7 +3558,8 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
                        new_fsp = open_file_shared(conn, fname, &sbuf,
                                                SET_OPEN_MODE(DOS_OPEN_RDWR),
                                                (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
-                                               0, 0, &access_mode, &action);
+                                               FILE_ATTRIBUTE_NORMAL,
+                                               0, &access_mode, &action);
        
                        if (new_fsp == NULL)
                                return(UNIXERROR(ERRDOS,ERRbadpath));