r20356: Consolidate the calls to parent_dirname() per open to one.
authorVolker Lendecke <vlendec@samba.org>
Wed, 27 Dec 2006 10:57:59 +0000 (10:57 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:16:43 +0000 (12:16 -0500)
This involved passing the dirname as argument to a few routines instead of
calling parent_dirname() deep down.

Volker

source/smbd/dosmode.c
source/smbd/nttrans.c
source/smbd/open.c
source/smbd/posix_acls.c
source/smbd/trans2.c

index 260a8dadbd69176a20c501c4f66a18767c5ea2dd..1172fe3e6b55fe0747f632413e3a41d2483e8d5d 100644 (file)
@@ -59,7 +59,7 @@ static uint32 set_offline_flag(connection_struct *conn, const char *const path)
 /****************************************************************************
  Change a dos mode to a unix mode.
     Base permission for files:
-         if creating file and inheriting
+         if creating file and inheriting (i.e. parent_dir != NULL)
            apply read/write bits from parent directory.
          else   
            everybody gets read bit set
@@ -79,23 +79,26 @@ static uint32 set_offline_flag(connection_struct *conn, const char *const path)
          }
 ****************************************************************************/
 
-mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname, BOOL creating_file)
+mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname,
+                const char *inherit_from_dir)
 {
        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. */
+       mode_t dir_mode = 0; /* Mode of the inherit_from directory if
+                             * inheriting. */
 
        if (!lp_store_dos_attributes(SNUM(conn)) && IS_DOS_READONLY(dosmode)) {
                result &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
        }
 
-       if (fname && creating_file && lp_inherit_perms(SNUM(conn))) {
-               char *dname;
+       if (fname && (inherit_from_dir != NULL)
+           && lp_inherit_perms(SNUM(conn))) {
                SMB_STRUCT_STAT sbuf;
 
-               dname = parent_dirname(fname);
-               DEBUG(2,("unix_mode(%s) inheriting from %s\n",fname,dname));
-               if (SMB_VFS_STAT(conn,dname,&sbuf) != 0) {
-                       DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",fname,dname,strerror(errno)));
+               DEBUG(2, ("unix_mode(%s) inheriting from %s\n", fname,
+                         inherit_from_dir));
+               if (SMB_VFS_STAT(conn, inherit_from_dir, &sbuf) != 0) {
+                       DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n", fname,
+                                inherit_from_dir, strerror(errno)));
                        return(0);      /* *** shouldn't happen! *** */
                }
 
@@ -429,7 +432,9 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf)
  chmod a file - but preserve some bits.
 ********************************************************************/
 
-int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, SMB_STRUCT_STAT *st, BOOL creating_file)
+int file_set_dosmode(connection_struct *conn, const char *fname,
+                    uint32 dosmode, SMB_STRUCT_STAT *st,
+                    const char *parent_dir)
 {
        SMB_STRUCT_STAT st1;
        int mask=0;
@@ -462,7 +467,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode,
                return 0;
        }
 
-       unixmode = unix_mode(conn,dosmode,fname, creating_file);
+       unixmode = unix_mode(conn,dosmode,fname, parent_dir);
 
        /* preserve the s bits */
        mask |= (S_ISUID | S_ISGID);
index 260a640dae3e03da2e07ffcda658802b9e193327..377ddbeec3339b606245354967c05fdd1ab6a169 100644 (file)
@@ -1697,7 +1697,8 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
        /* Grrr. We have to do this as open_file_ntcreate adds aARCH when it
           creates the file. This isn't the correct thing to do in the copy
           case. JRA */
-       file_set_dosmode(conn, newname, fattr, &sbuf2, True);
+       file_set_dosmode(conn, newname, fattr, &sbuf2,
+                        parent_dirname(newname));
 
        if (ret < (SMB_OFF_T)sbuf1.st_size) {
                return NT_STATUS_DISK_FULL;
index 59cd8030af64dccc4ae1bcbcab815beb1cf30935..28170e9cd8531b4fb0ce31bdd75bb532a38b4c10 100644 (file)
@@ -84,18 +84,18 @@ int fd_close(struct connection_struct *conn,
  Do this by fd if possible.
 ****************************************************************************/
 
-static void change_fd_owner_to_parent(connection_struct *conn,
-                                     files_struct *fsp)
+static void change_file_owner_to_parent(connection_struct *conn,
+                                       const char *inherit_from_dir,
+                                       files_struct *fsp)
 {
-       const char *parent_path = parent_dirname(fsp->fsp_name);
        SMB_STRUCT_STAT parent_st;
        int ret;
 
-       ret = SMB_VFS_STAT(conn, parent_path, &parent_st);
+       ret = SMB_VFS_STAT(conn, inherit_from_dir, &parent_st);
        if (ret == -1) {
-               DEBUG(0,("change_fd_owner_to_parent: failed to stat parent "
+               DEBUG(0,("change_file_owner_to_parent: failed to stat parent "
                         "directory %s. Error was %s\n",
-                        parent_path, strerror(errno) ));
+                        inherit_from_dir, strerror(errno) ));
                return;
        }
 
@@ -103,33 +103,33 @@ static void change_fd_owner_to_parent(connection_struct *conn,
        ret = SMB_VFS_FCHOWN(fsp, fsp->fh->fd, parent_st.st_uid, (gid_t)-1);
        unbecome_root();
        if (ret == -1) {
-               DEBUG(0,("change_fd_owner_to_parent: failed to fchown "
+               DEBUG(0,("change_file_owner_to_parent: failed to fchown "
                         "file %s to parent directory uid %u. Error "
                         "was %s\n", fsp->fsp_name,
                         (unsigned int)parent_st.st_uid,
                         strerror(errno) ));
        }
 
-       DEBUG(10,("change_fd_owner_to_parent: changed new file %s to "
+       DEBUG(10,("change_file_owner_to_parent: changed new file %s to "
                  "parent directory uid %u.\n", fsp->fsp_name,
                  (unsigned int)parent_st.st_uid ));
 }
 
-static void change_owner_to_parent(connection_struct *conn,
-                                  const char *fname,
-                                  SMB_STRUCT_STAT *psbuf)
+static void change_dir_owner_to_parent(connection_struct *conn,
+                                      const char *inherit_from_dir,
+                                      const char *fname,
+                                      SMB_STRUCT_STAT *psbuf)
 {
        pstring saved_dir;
        SMB_STRUCT_STAT sbuf;
-       const char *parent_path = parent_dirname(fname);
        SMB_STRUCT_STAT parent_st;
        int ret;
 
-       ret = SMB_VFS_STAT(conn, parent_path, &parent_st);
+       ret = SMB_VFS_STAT(conn, inherit_from_dir, &parent_st);
        if (ret == -1) {
-               DEBUG(0,("change_owner_to_parent: failed to stat parent "
+               DEBUG(0,("change_dir_owner_to_parent: failed to stat parent "
                         "directory %s. Error was %s\n",
-                        parent_path, strerror(errno) ));
+                        inherit_from_dir, strerror(errno) ));
                return;
        }
 
@@ -141,21 +141,21 @@ static void change_owner_to_parent(connection_struct *conn,
        */
 
        if (!vfs_GetWd(conn,saved_dir)) {
-               DEBUG(0,("change_owner_to_parent: failed to get "
+               DEBUG(0,("change_dir_owner_to_parent: failed to get "
                         "current working directory\n"));
                return;
        }
 
        /* Chdir into the new path. */
        if (vfs_ChDir(conn, fname) == -1) {
-               DEBUG(0,("change_owner_to_parent: failed to change "
+               DEBUG(0,("change_dir_owner_to_parent: failed to change "
                         "current working directory to %s. Error "
                         "was %s\n", fname, strerror(errno) ));
                goto out;
        }
 
        if (SMB_VFS_STAT(conn,".",&sbuf) == -1) {
-               DEBUG(0,("change_owner_to_parent: failed to stat "
+               DEBUG(0,("change_dir_owner_to_parent: failed to stat "
                         "directory '.' (%s) Error was %s\n",
                         fname, strerror(errno)));
                goto out;
@@ -165,7 +165,7 @@ static void change_owner_to_parent(connection_struct *conn,
        if (sbuf.st_dev != psbuf->st_dev ||
            sbuf.st_ino != psbuf->st_ino ||
            sbuf.st_mode != psbuf->st_mode ) {
-               DEBUG(0,("change_owner_to_parent: "
+               DEBUG(0,("change_dir_owner_to_parent: "
                         "device/inode/mode on directory %s changed. "
                         "Refusing to chown !\n", fname ));
                goto out;
@@ -175,14 +175,14 @@ static void change_owner_to_parent(connection_struct *conn,
        ret = SMB_VFS_CHOWN(conn, ".", parent_st.st_uid, (gid_t)-1);
        unbecome_root();
        if (ret == -1) {
-               DEBUG(10,("change_owner_to_parent: failed to chown "
+               DEBUG(10,("change_dir_owner_to_parent: failed to chown "
                          "directory %s to parent directory uid %u. "
                          "Error was %s\n", fname,
                          (unsigned int)parent_st.st_uid, strerror(errno) ));
                goto out;
        }
 
-       DEBUG(10,("change_owner_to_parent: changed ownership of new "
+       DEBUG(10,("change_dir_owner_to_parent: changed ownership of new "
                  "directory %s to parent directory uid %u.\n",
                  fname, (unsigned int)parent_st.st_uid ));
 
@@ -197,6 +197,7 @@ static void change_owner_to_parent(connection_struct *conn,
 
 static NTSTATUS open_file(files_struct *fsp,
                          connection_struct *conn,
+                         const char *parent_dir,
                          const char *fname,
                          SMB_STRUCT_STAT *psbuf,
                          int flags,
@@ -297,12 +298,14 @@ static NTSTATUS open_file(files_struct *fsp,
 
                        /* Inherit the ACL if required */
                        if (lp_inherit_perms(SNUM(conn))) {
-                               inherit_access_acl(conn, fname, unx_mode);
+                               inherit_access_acl(conn, parent_dir, fname,
+                                                  unx_mode);
                        }
 
                        /* Change the owner if required. */
                        if (lp_inherit_owner(SNUM(conn))) {
-                               change_fd_owner_to_parent(conn, fsp);
+                               change_file_owner_to_parent(conn, parent_dir,
+                                                           fsp);
                        }
                }
 
@@ -1124,6 +1127,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
        uint32 open_access_mask = access_mask;
        NTSTATUS status;
        int ret_flock;
+       const char *parent_dir;
 
        if (conn->printer) {
                /* 
@@ -1140,9 +1144,15 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
                return print_fsp_open(conn, fname, result);
        }
 
+       if (!(parent_dir = talloc_strdup(tmp_talloc_ctx(),
+                                        parent_dirname(fname)))) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
        /* 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, True);
+       unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname,
+                            parent_dir);
 
        DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
                   "access_mask=0x%x share_access=0x%x "
@@ -1194,7 +1204,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
        /* this is for OS/2 long file names - say we don't support them */
        if (!lp_posix_pathnames() && strstr(fname,".+,;=[].")) {
                /* OS/2 Workplace shell fix may be main code stream in a later
-                * release. */ 
+                * release. */
                DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
                         "supported.\n"));
                if (use_nt_status()) {
@@ -1554,8 +1564,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
         */
 
         if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
-           (def_acl = directory_has_default_acl(conn,
-                                                parent_dirname(fname)))) {
+           (def_acl = directory_has_default_acl(conn, parent_dir))) {
                unx_mode = 0777;
        }
 
@@ -1569,8 +1578,8 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
         * open_file strips any O_TRUNC flags itself.
         */
 
-       fsp_open = open_file(fsp,conn,fname,psbuf,flags|flags2,unx_mode,
-                            access_mask, open_access_mask);
+       fsp_open = open_file(fsp, conn, parent_dir, fname, psbuf, flags|flags2,
+                            unx_mode, access_mask, open_access_mask);
 
        if (!NT_STATUS_IS_OK(fsp_open)) {
                if (lck != NULL) {
@@ -1658,7 +1667,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
        ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, fsp->fh->fd, share_access);
        if(ret_flock == -1 ){
 
-               talloc_free(lck);
+               TALLOC_FREE(lck);
                fd_close(conn, fsp);
                file_free(fsp);
                
@@ -1755,7 +1764,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
                    lp_store_dos_attributes(SNUM(conn))) {
                        file_set_dosmode(conn, fname,
                                         new_dos_attributes | aARCH, NULL,
-                                        True);
+                                        parent_dir);
                }
        }
 
@@ -1835,7 +1844,8 @@ NTSTATUS open_file_fchmod(connection_struct *conn, const char *fname,
 
        /* note! we must use a non-zero desired access or we don't get
            a real file descriptor. Oh what a twisted web we weave. */
-       status = open_file(fsp,conn,fname,psbuf,O_WRONLY,0,FILE_WRITE_DATA,FILE_WRITE_DATA);
+       status = open_file(fsp, conn, NULL, fname, psbuf, O_WRONLY, 0,
+                          FILE_WRITE_DATA, FILE_WRITE_DATA);
 
        /* 
         * This is not a user visible file open.
@@ -1868,6 +1878,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn, const char *name,
 {
        int ret= -1;
        mode_t mode;
+       const char *parent_dir;
 
        if(!CAN_WRITE(conn)) {
                DEBUG(5,("mkdir_internal: failing create on read-only share "
@@ -1879,7 +1890,12 @@ static NTSTATUS mkdir_internal(connection_struct *conn, const char *name,
                return map_nt_error_from_unix(errno);
        }
 
-       mode = unix_mode(conn, aDIR, name, True);
+       if (!(parent_dir = talloc_strdup(tmp_talloc_ctx(),
+                                        parent_dirname(name)))) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       mode = unix_mode(conn, aDIR, name, parent_dir);
 
        if ((ret=SMB_VFS_MKDIR(conn, name, mode)) != 0) {
                return map_nt_error_from_unix(errno);
@@ -1901,7 +1917,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn, const char *name,
        }
 
        if (lp_inherit_perms(SNUM(conn))) {
-               inherit_access_acl(conn, name, mode);
+               inherit_access_acl(conn, parent_dir, name, mode);
        }
 
        /*
@@ -1917,7 +1933,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn, const char *name,
 
        /* Change the owner if required. */
        if (lp_inherit_owner(SNUM(conn))) {
-               change_owner_to_parent(conn, name, psbuf);
+               change_dir_owner_to_parent(conn, parent_dir, name, psbuf);
        }
 
        return NT_STATUS_OK;
index 75605ace8a67c9cddf0946b9d00dcda35f66f56c..c5da33c9df78cabaa726d569059795732d65a735 100644 (file)
@@ -1878,7 +1878,10 @@ 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, False) : S_IRUSR;
+       mode_t mode = interitable_mode
+               ? unix_mode( fsp->conn, FILE_ATTRIBUTE_ARCHIVE, fsp->fsp_name,
+                            NULL )
+               : S_IRUSR;
 
        if (fsp->is_directory)
                mode |= (S_IWUSR|S_IXUSR);
@@ -3461,15 +3464,13 @@ int chmod_acl(connection_struct *conn, const char *name, mode_t mode)
  inherit this Access ACL to file name.
 ****************************************************************************/
 
-int inherit_access_acl(connection_struct *conn, const char *name, mode_t mode)
+int inherit_access_acl(connection_struct *conn, const char *inherit_from_dir,
+                      const char *name, mode_t mode)
 {
-       pstring dirname;
-       pstrcpy(dirname, parent_dirname(name));
-
-       if (directory_has_default_acl(conn, dirname))
+       if (directory_has_default_acl(conn, inherit_from_dir))
                return 0;
 
-       return copy_access_acl(conn, dirname, name, mode);
+       return copy_access_acl(conn, inherit_from_dir, name, mode);
 }
 
 /****************************************************************************
index e91cc7be06ea1fc44f5af063911a1bbbc3aea107..9f22f65e34988ae67c9388eb8bf5347f14bb52e0 100644 (file)
@@ -4300,8 +4300,9 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
                                        return(UNIXERROR(ERRDOS,ERRnoaccess));
 
                                if (lp_inherit_perms(SNUM(conn))) {
-                                       inherit_access_acl(conn, fname,
-                                                          unixmode);
+                                       inherit_access_acl(
+                                               conn, parent_dirname(fname),
+                                               fname, unixmode);
                                }
 
                                SSVAL(params,0,0);