summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2012-05-15 12:33:18 -0700
committerAndrew Bartlett <abartlet@samba.org>2012-05-17 03:17:05 +0200
commit5b1c42228b8badbc7e7a4446c33f590bd1257f1f (patch)
treec57282dc530023effc44cb6df955565f6a2b968a
parent367a644c4d91531faf8b2ce9a167fc196da12422 (diff)
downloadsamba-5b1c42228b8badbc7e7a4446c33f590bd1257f1f.tar.gz
samba-5b1c42228b8badbc7e7a4446c33f590bd1257f1f.tar.bz2
samba-5b1c42228b8badbc7e7a4446c33f590bd1257f1f.zip
s3-smbd: Handle ID_TYPE_BOTH by mapping to both a group ACL entry and file ownership This will allow groups, such as domain administrators, to own files while correctly handling the rest of the ACL permissions.
Andrew Bartlett Signed-off-by: Jeremy Allison <jra@samba.org>
-rw-r--r--source3/smbd/posix_acls.c148
1 files changed, 109 insertions, 39 deletions
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index a833fbf1b7..6e97dcf873 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -1938,53 +1938,123 @@ static bool create_canon_ace_lists(files_struct *fsp,
*/
psa->flags |= SEC_ACE_FLAG_INHERIT_ONLY;
- } else if (sid_to_uid( &current_ace->trustee, &current_ace->unix_ug.uid)) {
- current_ace->owner_type = UID_ACE;
- /* If it's the owning user, this is a user_obj, not
- * a user. */
- if (current_ace->unix_ug.uid == pst->st_ex_uid) {
- current_ace->type = SMB_ACL_USER_OBJ;
- } else {
- current_ace->type = SMB_ACL_USER;
- }
- } else if (sid_to_gid( &current_ace->trustee, &current_ace->unix_ug.gid)) {
- current_ace->owner_type = GID_ACE;
- /* If it's the primary group, this is a group_obj, not
- * a group. */
- if (current_ace->unix_ug.gid == pst->st_ex_gid) {
- current_ace->type = SMB_ACL_GROUP_OBJ;
- } else {
- current_ace->type = SMB_ACL_GROUP;
- }
} else {
- /*
- * Silently ignore map failures in non-mappable SIDs (NT Authority, BUILTIN etc).
- */
+ struct unixid unixid;
- if (non_mappable_sid(&psa->trustee)) {
- DEBUG(10, ("create_canon_ace_lists: ignoring "
- "non-mappable SID %s\n",
- sid_string_dbg(&psa->trustee)));
+ if (!sids_to_unixids(&current_ace->trustee, 1, &unixid)) {
+ free_canon_ace_list(file_ace);
+ free_canon_ace_list(dir_ace);
TALLOC_FREE(current_ace);
- continue;
+ DEBUG(0, ("create_canon_ace_lists: sids_to_unixids "
+ "failed for %s (allocation failure)\n",
+ sid_string_dbg(&current_ace->trustee)));
+ return false;
}
- if (lp_force_unknown_acl_user(SNUM(fsp->conn))) {
- DEBUG(10, ("create_canon_ace_lists: ignoring "
- "unknown or foreign SID %s\n",
- sid_string_dbg(&psa->trustee)));
+ if (unixid.type == ID_TYPE_BOTH) {
+ /* If it's the owning user, this is a
+ * user_obj, not a user. This way, we
+ * get a valid ACL for groups that own
+ * files, without putting user ACL
+ * entries in for groups otherwise */
+ if (unixid.id == pst->st_ex_uid) {
+ current_ace->owner_type = UID_ACE;
+ current_ace->unix_ug.uid = unixid.id;
+ current_ace->type = SMB_ACL_USER_OBJ;
+
+ /* Add the user object to the posix ACL,
+ and proceed to the group mapping
+ below. This handles the talloc_free
+ of current_ace if not added for some
+ reason */
+ if (!add_current_ace_to_acl(fsp,
+ psa,
+ &file_ace,
+ &dir_ace,
+ &got_file_allow,
+ &got_dir_allow,
+ &all_aces_are_inherit_only,
+ current_ace)) {
+ free_canon_ace_list(file_ace);
+ free_canon_ace_list(dir_ace);
+ return false;
+ }
+
+ if ((current_ace = talloc(talloc_tos(),
+ canon_ace)) == NULL) {
+ free_canon_ace_list(file_ace);
+ free_canon_ace_list(dir_ace);
+ DEBUG(0,("create_canon_ace_lists: "
+ "malloc fail.\n"));
+ return False;
+ }
+
+ ZERO_STRUCTP(current_ace);
+ }
+
+ sid_copy(&current_ace->trustee, &psa->trustee);
+
+ current_ace->unix_ug.gid = unixid.id;
+ current_ace->owner_type = GID_ACE;
+ /* If it's the primary group, this is a
+ group_obj, not a group. */
+ if (current_ace->unix_ug.gid == pst->st_ex_gid) {
+ current_ace->type = SMB_ACL_GROUP_OBJ;
+ } else {
+ current_ace->type = SMB_ACL_GROUP;
+ }
+
+ } else if (unixid.type == ID_TYPE_UID) {
+ current_ace->owner_type = UID_ACE;
+ current_ace->unix_ug.uid = unixid.id;
+ /* If it's the owning user, this is a user_obj,
+ not a user. */
+ if (current_ace->unix_ug.uid == pst->st_ex_uid) {
+ current_ace->type = SMB_ACL_USER_OBJ;
+ } else {
+ current_ace->type = SMB_ACL_USER;
+ }
+ } else if (unixid.type == ID_TYPE_GID) {
+ current_ace->unix_ug.gid = unixid.id;
+ current_ace->owner_type = GID_ACE;
+ /* If it's the primary group, this is a
+ group_obj, not a group. */
+ if (current_ace->unix_ug.gid == pst->st_ex_gid) {
+ current_ace->type = SMB_ACL_GROUP_OBJ;
+ } else {
+ current_ace->type = SMB_ACL_GROUP;
+ }
+ } else {
+ /*
+ * Silently ignore map failures in non-mappable SIDs (NT Authority, BUILTIN etc).
+ */
+
+ if (non_mappable_sid(&psa->trustee)) {
+ DEBUG(10, ("create_canon_ace_lists: ignoring "
+ "non-mappable SID %s\n",
+ sid_string_dbg(&psa->trustee)));
+ TALLOC_FREE(current_ace);
+ continue;
+ }
+
+ if (lp_force_unknown_acl_user(SNUM(fsp->conn))) {
+ DEBUG(10, ("create_canon_ace_lists: ignoring "
+ "unknown or foreign SID %s\n",
+ sid_string_dbg(&psa->trustee)));
+ TALLOC_FREE(current_ace);
+ continue;
+ }
+
+ free_canon_ace_list(file_ace);
+ free_canon_ace_list(dir_ace);
+ DEBUG(0, ("create_canon_ace_lists: unable to map SID "
+ "%s to uid or gid.\n",
+ sid_string_dbg(&current_ace->trustee)));
TALLOC_FREE(current_ace);
- continue;
+ return false;
}
-
- free_canon_ace_list(file_ace);
- free_canon_ace_list(dir_ace);
- DEBUG(0, ("create_canon_ace_lists: unable to map SID "
- "%s to uid or gid.\n",
- sid_string_dbg(&current_ace->trustee)));
- TALLOC_FREE(current_ace);
- return false;
}
+
/* handles the talloc_free of current_ace if not added for some reason */
if (!add_current_ace_to_acl(fsp, psa, &file_ace, &dir_ace,
&got_file_allow, &got_dir_allow,