From 1dfd8df23d63f786788bc24ebb71039feaf34d91 Mon Sep 17 00:00:00 2001 From: Uri Simchoni Date: Tue, 2 Aug 2016 09:37:00 +0300 Subject: [PATCH] smbd: add an option to inherit only the UNIX owner This can be used to emulate folder quotas, as explained in the modified manpage. Signed-off-by: Uri Simchoni Reviewed-by: Jeremy Allison --- docs-xml/smbdotconf/security/inheritowner.xml | 41 ++++++++++++++++++- lib/param/loadparm.h | 7 ++++ lib/param/param_table.c | 6 +++ source3/smbd/open.c | 7 ++-- source3/smbd/posix_acls.c | 8 ++++ 5 files changed, 64 insertions(+), 5 deletions(-) diff --git a/docs-xml/smbdotconf/security/inheritowner.xml b/docs-xml/smbdotconf/security/inheritowner.xml index ab7da57ed59..2a7a4b8b61d 100644 --- a/docs-xml/smbdotconf/security/inheritowner.xml +++ b/docs-xml/smbdotconf/security/inheritowner.xml @@ -1,6 +1,7 @@ The ownership of new files and directories @@ -8,11 +9,47 @@ This option allows the Samba administrator to specify that the ownership for new files and directories should be controlled by the ownership of the parent directory. - + + Valid options are: + + no - + Both the Windows (SID) owner and the UNIX (uid) owner of the file are + governed by the identity of the user that created the file. + + + windows and unix - + The Windows (SID) owner and the UNIX (uid) owner of new files and + directories are set to the respective owner of the parent directory. + + + yes - a synonym for + windows and unix. + + + unix only - + Only the UNIX owner is set to the UNIX owner of the parent directory. + + + Common scenarios where this behavior is useful is in implementing drop-boxes, where users can create and edit files but not delete them and ensuring that newly created files in a user's roaming profile directory are actually owned by the user. + + The unix only option effectively + breaks the tie between the Windows owner of a file and the + UNIX owner. As a logical consequence, in this mode, + setting the the Windows owner of a file does not modify the UNIX + owner. Using this mode should typically be combined with a + backing store that can emulate the full NT ACL model without + affecting the POSIX permissions, such as the acl_xattr + VFS module, coupled with + yes. + This can be used to emulate folder quotas, when files are + exposed only via SMB (without UNIX extensions). + The UNIX owner of a directory is locally set + and inherited by all subdirectories and files, and they all + consume the same quota. inherit permissions diff --git a/lib/param/loadparm.h b/lib/param/loadparm.h index d8f69753ad4..f9fb7d8d804 100644 --- a/lib/param/loadparm.h +++ b/lib/param/loadparm.h @@ -229,6 +229,13 @@ enum mapreadonly_options {MAP_READONLY_NO, MAP_READONLY_YES, MAP_READONLY_PERMIS /* case handling */ enum case_handling {CASE_LOWER,CASE_UPPER}; +/* inherit owner options */ +enum inheritowner_options { + INHERIT_OWNER_NO, + INHERIT_OWNER_WINDOWS_AND_UNIX, + INHERIT_OWNER_UNIX_ONLY +}; + /* * Default passwd chat script. */ diff --git a/lib/param/param_table.c b/lib/param/param_table.c index c8520d29c55..4b5234a7c9e 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -308,6 +308,12 @@ static const struct enum_list enum_case[] = { {-1, NULL} }; +static const struct enum_list enum_inherit_owner_vals[] = { + {INHERIT_OWNER_NO, "no"}, + {INHERIT_OWNER_WINDOWS_AND_UNIX, "windows and unix"}, + {INHERIT_OWNER_WINDOWS_AND_UNIX, "yes"}, + {INHERIT_OWNER_UNIX_ONLY, "unix only"}, + {-1, NULL}}; /* Note: We do not initialise the defaults union - it is not allowed in ANSI C * diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 2ae6f835bbc..d5360767efd 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -930,7 +930,7 @@ static NTSTATUS open_file(files_struct *fsp, } /* Change the owner if required. */ - if (lp_inherit_owner(SNUM(conn))) { + if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) { change_file_owner_to_parent(conn, parent_dir, fsp); need_re_stat = true; @@ -3375,7 +3375,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn, } /* Change the owner if required. */ - if (lp_inherit_owner(SNUM(conn))) { + if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) { change_dir_owner_to_parent(conn, parent_dir, smb_dname->base_name, &smb_dname->st); @@ -4017,7 +4017,8 @@ static NTSTATUS inherit_new_acl(files_struct *fsp) const struct dom_sid *group_sid = NULL; uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL); struct security_token *token = fsp->conn->session_info->security_token; - bool inherit_owner = lp_inherit_owner(SNUM(fsp->conn)); + bool inherit_owner = + (lp_inherit_owner(SNUM(fsp->conn)) == INHERIT_OWNER_WINDOWS_AND_UNIX); bool inheritable_components = false; bool try_builtin_administrators = false; const struct dom_sid *BA_U_sid = NULL; diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index c5755683658..e8e819c7eeb 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3754,6 +3754,14 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32_t security_info_sent, const struct security_info_sent &= ~SECINFO_GROUP; } + /* If UNIX owner is inherited and Windows isn't, then + * setting the UNIX owner based on Windows owner conflicts + * with the inheritance rule + */ + if (lp_inherit_owner(SNUM(conn)) == INHERIT_OWNER_UNIX_ONLY) { + security_info_sent &= ~SECINFO_OWNER; + } + status = unpack_nt_owners( conn, &user, &grp, security_info_sent, psd); if (!NT_STATUS_IS_OK(status)) { return status; -- 2.47.2