s3: convert unix_mode to take an smb_filename
authorTim Prouty <tprouty@samba.org>
Wed, 8 Jul 2009 02:20:22 +0000 (19:20 -0700)
committerTim Prouty <tprouty@samba.org>
Thu, 9 Jul 2009 04:36:03 +0000 (21:36 -0700)
source3/include/proto.h
source3/modules/onefs_acl.c
source3/modules/onefs_open.c
source3/smbd/dosmode.c
source3/smbd/open.c
source3/smbd/posix_acls.c

index f835da2ab841bc58bbce484fe56a3a273a7c4993..ef252c28466786c729819514eee05eeed5b83cf5 100644 (file)
@@ -6234,7 +6234,8 @@ bool smbd_setup_mdns_registration(struct tevent_context *ev,
 
 /* The following definitions come from smbd/dosmode.c  */
 
-mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname,
+mode_t unix_mode(connection_struct *conn, int dosmode,
+                const struct smb_filename *smb_fname,
                 const char *inherit_from_dir);
 uint32 dos_mode_msdfs(connection_struct *conn, const char *path, const SMB_STRUCT_STAT *sbuf);
 int dos_attributes_to_stat_dos_flags(uint32_t dosmode);
index 81bdfd26cc4be5913d444ad9c74481d9866426ef..5c72d10a6baa908e6c7a42170f5bef1cdafc99b1 100644 (file)
@@ -542,14 +542,25 @@ static bool add_sfs_aces(files_struct *fsp, struct ifs_security_descriptor *sd)
        /* Only continue if this is a synthetic ACL and a directory. */
        if (S_ISDIR(sbuf.st_ex_mode) &&
            (sbuf.st_ex_flags & SF_HASNTFSACL) == 0) {
+               struct smb_filename *smb_fname = NULL;
                struct ifs_ace new_aces[6];
                struct ifs_ace *old_aces;
                int i, num_aces_to_add = 0;
                mode_t file_mode = 0, dir_mode = 0;
+               NTSTATUS status;
+
+               status = create_synthetic_smb_fname_split(talloc_tos(),
+                                                         fsp->fsp_name, NULL,
+                                                         &smb_fname);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return false;
+               }
 
                /* Use existing samba logic to derive the mode bits. */
-               file_mode = unix_mode(fsp->conn, 0, fsp->fsp_name, false);
-               dir_mode = unix_mode(fsp->conn, aDIR, fsp->fsp_name, false);
+               file_mode = unix_mode(fsp->conn, 0, smb_fname, NULL);
+               dir_mode = unix_mode(fsp->conn, aDIR, smb_fname, NULL);
+
+               TALLOC_FREE(smb_fname);
 
                /* Initialize ACEs. */
                new_aces[0] = onefs_init_ace(fsp->conn, file_mode, false, USR);
index da7d4130730bb29d8f9efbe7bf34728ee2de9f75..20ce814518f83bbc231241821e933620a97d082f 100644 (file)
@@ -504,8 +504,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
        } else {
                /* We add aARCH to this as this mode is only used if the file is
                 * created new. */
-               unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname,
-                                    parent_dir);
+               unx_mode = unix_mode(conn, new_dos_attributes | aARCH,
+                                    smb_fname, parent_dir);
        }
 
        DEBUG(10,("onefs_open_file_ntcreate: fname=%s, dos_attrs=0x%x "
@@ -1444,7 +1444,7 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
                mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
                file_attributes = 0;
        } else {
-               mode = unix_mode(conn, aDIR, smb_dname->base_name, parent_dir);
+               mode = unix_mode(conn, aDIR, smb_dname, parent_dir);
        }
 
        /*
index 9d44eeec7db1cec244b9440e7db14eff83cad732..9bd097c0bbe5dd644e0807dd1ad261be7ff56a64 100644 (file)
@@ -64,7 +64,8 @@ static int set_link_read_only_flag(const SMB_STRUCT_STAT *const sbuf)
          }
 ****************************************************************************/
 
-mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname,
+mode_t unix_mode(connection_struct *conn, int dosmode,
+                const struct smb_filename *smb_fname,
                 const char *inherit_from_dir)
 {
        mode_t result = (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
@@ -75,23 +76,39 @@ mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname,
                result &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
        }
 
-       if (fname && (inherit_from_dir != NULL)
-           && lp_inherit_perms(SNUM(conn))) {
-               SMB_STRUCT_STAT sbuf;
+       if ((inherit_from_dir != NULL) && lp_inherit_perms(SNUM(conn))) {
+               struct smb_filename *smb_fname_parent = NULL;
+               NTSTATUS status;
 
-               DEBUG(2, ("unix_mode(%s) inheriting from %s\n", fname,
+               DEBUG(2, ("unix_mode(%s) inheriting from %s\n",
+                         smb_fname_str_dbg(smb_fname),
                          inherit_from_dir));
-               if (vfs_stat_smb_fname(conn, inherit_from_dir, &sbuf) != 0) {
-                       DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n", fname,
+
+               status = create_synthetic_smb_fname(talloc_tos(),
+                                                   inherit_from_dir, NULL,
+                                                   NULL, &smb_fname_parent);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(1,("unix_mode(%s) failed, [dir %s]: %s\n",
+                                smb_fname_str_dbg(smb_fname),
+                                inherit_from_dir, nt_errstr(status)));
+                       return(0);
+               }
+
+               if (SMB_VFS_STAT(conn, smb_fname_parent) != 0) {
+                       DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",
+                                smb_fname_str_dbg(smb_fname),
                                 inherit_from_dir, strerror(errno)));
+                       TALLOC_FREE(smb_fname_parent);
                        return(0);      /* *** shouldn't happen! *** */
                }
 
                /* Save for later - but explicitly remove setuid bit for safety. */
-               dir_mode = sbuf.st_ex_mode & ~S_ISUID;
-               DEBUG(2,("unix_mode(%s) inherit mode %o\n",fname,(int)dir_mode));
+               dir_mode = smb_fname_parent->st.st_ex_mode & ~S_ISUID;
+               DEBUG(2,("unix_mode(%s) inherit mode %o\n",
+                        smb_fname_str_dbg(smb_fname), (int)dir_mode));
                /* Clear "result" */
                result = 0;
+               TALLOC_FREE(smb_fname_parent);
        } 
 
        if (IS_DOS_DIR(dosmode)) {
@@ -132,7 +149,8 @@ mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname,
                }
        }
 
-       DEBUG(3,("unix_mode(%s) returning 0%o\n",fname,(int)result ));
+       DEBUG(3,("unix_mode(%s) returning 0%o\n", smb_fname_str_dbg(smb_fname),
+                (int)result));
        return(result);
 }
 
@@ -635,7 +653,7 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname,
                return 0;
        }
 
-       unixmode = unix_mode(conn,dosmode,fname, parent_dir);
+       unixmode = unix_mode(conn, dosmode, smb_fname, parent_dir);
 
        /* preserve the s bits */
        mask |= (S_ISUID | S_ISGID);
index e93485b3d83e85412131db97483a6812cb197b49..a58cffa2578c96959f8f0d36332b9afad04c554b 100644 (file)
@@ -1513,8 +1513,8 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
        } else {
                /* We add aARCH to this as this mode is only used if the file is
                 * created new. */
-               unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname,
-                                    parent_dir);
+               unx_mode = unix_mode(conn, new_dos_attributes | aARCH,
+                                    smb_fname, parent_dir);
        }
 
        DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
@@ -2362,7 +2362,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
                posix_open = true;
                mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
        } else {
-               mode = unix_mode(conn, aDIR, smb_dname->base_name, parent_dir);
+               mode = unix_mode(conn, aDIR, smb_dname, parent_dir);
        }
 
        if (SMB_VFS_MKDIR(conn, smb_dname->base_name, mode) != 0) {
index 627ca2e171f2288ba404fa1124222fcde1385d5d..0c7f4b7bb7f0d658cccb988b35e0efc02b9d464d 100644 (file)
@@ -2166,10 +2166,23 @@ static mode_t create_default_mode(files_struct *fsp, bool interitable_mode)
        int snum = SNUM(fsp->conn);
        mode_t and_bits = (mode_t)0;
        mode_t or_bits = (mode_t)0;
-       mode_t mode = interitable_mode
-               ? unix_mode( fsp->conn, FILE_ATTRIBUTE_ARCHIVE, fsp->fsp_name,
-                            NULL )
-               : S_IRUSR;
+       mode_t mode;
+
+       if (interitable_mode) {
+               struct smb_filename *smb_fname = NULL;
+               NTSTATUS status;
+
+               status = create_synthetic_smb_fname_split(talloc_tos(),
+                                                         fsp->fsp_name, NULL,
+                                                         &smb_fname);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return 0;
+               }
+               mode = unix_mode(fsp->conn, FILE_ATTRIBUTE_ARCHIVE, smb_fname,
+                                NULL);
+       } else {
+               mode = S_IRUSR;
+       }
 
        if (fsp->is_directory)
                mode |= (S_IWUSR|S_IXUSR);