Fix the UNIX extensions CHOWN calls to use FCHOWN if available, else LCHOWN.
authorJeremy Allison <jra@samba.org>
Wed, 21 Aug 2013 19:20:48 +0000 (12:20 -0700)
committerJeremy Allison <jra@samba.org>
Sat, 24 Aug 2013 23:02:40 +0000 (01:02 +0200)
UNIX calls never deref links.

Signed-off-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Sun Aug 25 01:02:40 CEST 2013 on sn-devel-104

source3/smbd/trans2.c

index 55272e9018f3283fe04a020c77ad3dcab5386db7..04947d3c8ad5bdbd54288fb01649db95abf7d0c9 100644 (file)
@@ -7148,12 +7148,12 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
                          (unsigned int)set_owner,
                          smb_fname_str_dbg(smb_fname)));
 
-               if (S_ISLNK(sbuf.st_ex_mode)) {
+               if (fsp && fsp->fh->fd != -1) {
+                       ret = SMB_VFS_FCHOWN(fsp, set_owner, (gid_t)-1);
+               } else {
+                       /* UNIX calls always operate on symlinks. */
                        ret = SMB_VFS_LCHOWN(conn, smb_fname->base_name,
                                             set_owner, (gid_t)-1);
-               } else {
-                       ret = SMB_VFS_CHOWN(conn, smb_fname->base_name,
-                                           set_owner, (gid_t)-1);
                }
 
                if (ret != 0) {
@@ -7171,12 +7171,20 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
 
        if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) &&
            (sbuf.st_ex_gid != set_grp)) {
+               int ret;
+
                DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
                          "changing group %u for file %s\n",
                          (unsigned int)set_owner,
                          smb_fname_str_dbg(smb_fname)));
-               if (SMB_VFS_CHOWN(conn, smb_fname->base_name, (uid_t)-1,
-                                 set_grp) != 0) {
+               if (fsp && fsp->fh->fd != -1) {
+                       ret = SMB_VFS_FCHOWN(fsp, set_owner, (gid_t)-1);
+               } else {
+                       /* UNIX calls always operate on symlinks. */
+                       ret = SMB_VFS_LCHOWN(conn, smb_fname->base_name, (uid_t)-1,
+                                 set_grp);
+               }
+               if (ret != 0) {
                        status = map_nt_error_from_unix(errno);
                        if (delete_on_fail) {
                                SMB_VFS_UNLINK(conn, smb_fname);