r7662: Allow someone with SeTakeOwnershipPrivilege to chown the user
authorJeremy Allison <jra@samba.org>
Fri, 17 Jun 2005 01:02:11 +0000 (01:02 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:57:18 +0000 (10:57 -0500)
of a file to themself.
Jeremy.

source/smbd/posix_acls.c

index b5ac2e8241d231ec68dc172bc5a1c154135c581c..796587c94c04d04e814ed1ca7f94a1a2bf96e746 100644 (file)
@@ -2926,7 +2926,8 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
  Try to chown a file. We will be able to chown it under the following conditions.
 
   1) If we have root privileges, then it will just work.
-  2) If we have write permission to the file and dos_filemodes is set
+  2) If we have SeTakeOwnershipPrivilege we can change the user to the current user.
+  3) If we have write permission to the file and dos_filemodes is set
      then allow chown to the currently authenticated user.
 ****************************************************************************/
 
@@ -2935,21 +2936,40 @@ static int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_
        int ret;
        files_struct *fsp;
        SMB_STRUCT_STAT st;
+       SE_PRIV se_take_ownership = SE_TAKE_OWNERSHIP;
 
+       if(!CAN_WRITE(conn)) {
+               return -1;
+       }
+
+       /* Case (1). */
        /* try the direct way first */
        ret = SMB_VFS_CHOWN(conn, fname, uid, gid);
        if (ret == 0)
                return 0;
 
-       if(!CAN_WRITE(conn) || !lp_dos_filemode(SNUM(conn)))
+       /* Case (2). */
+       if ((uid == current_user.uid) && (user_has_privileges(current_user.nt_user_token,&se_take_ownership))) {
+               become_root();
+               /* Keep the current file gid the same - take ownership doesn't imply group change. */
+               ret = SMB_VFS_CHOWN(conn, fname, uid, (gid_t)-1);
+               unbecome_root();
+               return ret;
+       }
+
+       /* Case (3). */
+       if (!lp_dos_filemode(SNUM(conn))) {
                return -1;
+       }
 
-       if (SMB_VFS_STAT(conn,fname,&st))
+       if (SMB_VFS_STAT(conn,fname,&st)) {
                return -1;
+       }
 
        fsp = open_file_fchmod(conn,fname,&st);
-       if (!fsp)
+       if (!fsp) {
                return -1;
+       }
 
        /* only allow chown to the current user. This is more secure,
           and also copes with the case where the SID in a take ownership ACL is
@@ -3017,15 +3037,17 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
         * Unpack the user/group/world id's.
         */
 
-       if (!unpack_nt_owners( SNUM(conn), &sbuf, &user, &grp, security_info_sent, psd))
+       if (!unpack_nt_owners( SNUM(conn), &sbuf, &user, &grp, security_info_sent, psd)) {
                return False;
+       }
 
        /*
         * Do we need to chown ?
         */
 
-       if (((user != (uid_t)-1) && (orig_uid != user)) || (( grp != (gid_t)-1) && (orig_gid != grp)))
+       if (((user != (uid_t)-1) && (orig_uid != user)) || (( grp != (gid_t)-1) && (orig_gid != grp))) {
                need_chown = True;
+       }
 
        /*
         * Chown before setting ACL only if we don't change the user, or