summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/posix_acls.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index b5ac2e8241..796587c94c 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -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