summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/posix_acls.c295
1 files changed, 141 insertions, 154 deletions
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 1f3874cad6..cc953fdfa9 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -1425,34 +1425,34 @@ static bool ensure_canon_entry_valid_on_get(connection_struct *conn,
}
/****************************************************************************
- A well formed POSIX file or default ACL has at least 3 entries, a
+ A well formed POSIX file or default ACL has at least 3 entries, a
SMB_ACL_USER_OBJ, SMB_ACL_GROUP_OBJ, SMB_ACL_OTHER_OBJ.
In addition, the owner must always have at least read access.
- When using this call on get_acl, the pst struct is valid and contains
- the mode of the file. When using this call on set_acl, the pst struct has
+ When using this call on set_acl, the pst struct has
been modified to have a mode containing the default for this file or directory
type.
****************************************************************************/
-static bool ensure_canon_entry_valid(connection_struct *conn,
+static bool ensure_canon_entry_valid_on_set(connection_struct *conn,
canon_ace **pp_ace,
bool is_default_acl,
const struct share_params *params,
const bool is_directory,
const struct dom_sid *pfile_owner_sid,
const struct dom_sid *pfile_grp_sid,
- const SMB_STRUCT_STAT *pst,
- bool setting_acl)
+ const SMB_STRUCT_STAT *pst)
{
canon_ace *pace;
canon_ace *pace_user = NULL;
canon_ace *pace_group = NULL;
canon_ace *pace_other = NULL;
+ bool got_duplicate_user = false;
+ bool got_duplicate_group = false;
for (pace = *pp_ace; pace; pace = pace->next) {
if (pace->type == SMB_ACL_USER_OBJ) {
- if (setting_acl && !is_default_acl) {
+ if (!is_default_acl) {
apply_default_perms(params, is_directory, pace, S_IRUSR);
}
pace_user = pace;
@@ -1463,7 +1463,7 @@ static bool ensure_canon_entry_valid(connection_struct *conn,
* Ensure create mask/force create mode is respected on set.
*/
- if (setting_acl && !is_default_acl) {
+ if (!is_default_acl) {
apply_default_perms(params, is_directory, pace, S_IRGRP);
}
pace_group = pace;
@@ -1474,7 +1474,7 @@ static bool ensure_canon_entry_valid(connection_struct *conn,
* Ensure create mask/force create mode is respected on set.
*/
- if (setting_acl && !is_default_acl) {
+ if (!is_default_acl) {
apply_default_perms(params, is_directory, pace, S_IROTH);
}
pace_other = pace;
@@ -1485,16 +1485,18 @@ static bool ensure_canon_entry_valid(connection_struct *conn,
* Ensure create mask/force create mode is respected on set.
*/
- if (setting_acl && !is_default_acl) {
+ if (!is_default_acl) {
apply_default_perms(params, is_directory, pace, S_IRGRP);
}
}
}
if (!pace_user) {
+ canon_ace *pace_iter;
+
if ((pace = talloc(talloc_tos(), canon_ace)) == NULL) {
- DEBUG(0,("ensure_canon_entry_valid: malloc fail.\n"));
- return False;
+ DEBUG(0,("talloc fail.\n"));
+ return false;
}
ZERO_STRUCTP(pace);
@@ -1508,38 +1510,33 @@ static bool ensure_canon_entry_valid(connection_struct *conn,
surprises for the user. */
pace->perms = pst->st_ex_mode;
- if (setting_acl) {
- /* See if the owning user is in any of the other groups in
- the ACE, or if there's a matching user entry (by uid
- or in the case of ID_TYPE_BOTH by SID).
- If so, OR in the permissions from that entry. */
+ /* See if the owning user is in any of the other groups in
+ the ACE, or if there's a matching user entry (by uid
+ or in the case of ID_TYPE_BOTH by SID).
+ If so, OR in the permissions from that entry. */
- canon_ace *pace_iter;
- for (pace_iter = *pp_ace; pace_iter; pace_iter = pace_iter->next) {
- if (pace_iter->type == SMB_ACL_USER &&
- pace_iter->unix_ug.id == pace->unix_ug.id) {
+ for (pace_iter = *pp_ace; pace_iter; pace_iter = pace_iter->next) {
+ if (pace_iter->type == SMB_ACL_USER &&
+ pace_iter->unix_ug.id == pace->unix_ug.id) {
+ pace->perms |= pace_iter->perms;
+ } else if (pace_iter->type == SMB_ACL_GROUP_OBJ || pace_iter->type == SMB_ACL_GROUP) {
+ if (dom_sid_equal(&pace->trustee, &pace_iter->trustee)) {
+ pace->perms |= pace_iter->perms;
+ } else if (uid_entry_in_group(conn, pace, pace_iter)) {
pace->perms |= pace_iter->perms;
- } else if (pace_iter->type == SMB_ACL_GROUP_OBJ || pace_iter->type == SMB_ACL_GROUP) {
- if (dom_sid_equal(&pace->trustee, &pace_iter->trustee)) {
- pace->perms |= pace_iter->perms;
- } else if (uid_entry_in_group(conn, pace, pace_iter)) {
- pace->perms |= pace_iter->perms;
- }
}
}
+ }
- if (pace->perms == 0) {
- /* If we only got an "everyone" perm, just use that. */
- if (pace_other)
- pace->perms = pace_other->perms;
- }
+ if (pace->perms == 0) {
+ /* If we only got an "everyone" perm, just use that. */
+ if (pace_other)
+ pace->perms = pace_other->perms;
+ }
- if (!is_default_acl) {
- apply_default_perms(params, is_directory, pace, S_IRUSR);
- }
- } else {
- pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRUSR, S_IWUSR, S_IXUSR);
+ if (!is_default_acl) {
+ apply_default_perms(params, is_directory, pace, S_IRUSR);
}
DLIST_ADD(*pp_ace, pace);
@@ -1548,8 +1545,8 @@ static bool ensure_canon_entry_valid(connection_struct *conn,
if (!pace_group) {
if ((pace = talloc(talloc_tos(), canon_ace)) == NULL) {
- DEBUG(0,("ensure_canon_entry_valid: malloc fail.\n"));
- return False;
+ DEBUG(0,("talloc fail.\n"));
+ return false;
}
ZERO_STRUCTP(pace);
@@ -1559,17 +1556,15 @@ static bool ensure_canon_entry_valid(connection_struct *conn,
pace->unix_ug.id = pst->st_ex_gid;
pace->trustee = *pfile_grp_sid;
pace->attr = ALLOW_ACE;
- if (setting_acl) {
- /* If we only got an "everyone" perm, just use that. */
- if (pace_other)
- pace->perms = pace_other->perms;
- else
- pace->perms = 0;
- if (!is_default_acl) {
- apply_default_perms(params, is_directory, pace, S_IRGRP);
- }
+
+ /* If we only got an "everyone" perm, just use that. */
+ if (pace_other) {
+ pace->perms = pace_other->perms;
} else {
- pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRGRP, S_IWGRP, S_IXGRP);
+ pace->perms = 0;
+ }
+ if (!is_default_acl) {
+ apply_default_perms(params, is_directory, pace, S_IRGRP);
}
DLIST_ADD(*pp_ace, pace);
@@ -1578,8 +1573,8 @@ static bool ensure_canon_entry_valid(connection_struct *conn,
if (!pace_other) {
if ((pace = talloc(talloc_tos(), canon_ace)) == NULL) {
- DEBUG(0,("ensure_canon_entry_valid: malloc fail.\n"));
- return False;
+ DEBUG(0,("talloc fail.\n"));
+ return false;
}
ZERO_STRUCTP(pace);
@@ -1589,126 +1584,118 @@ static bool ensure_canon_entry_valid(connection_struct *conn,
pace->unix_ug.id = -1;
pace->trustee = global_sid_World;
pace->attr = ALLOW_ACE;
- if (setting_acl) {
- pace->perms = 0;
- if (!is_default_acl) {
- apply_default_perms(params, is_directory, pace, S_IROTH);
- }
- } else
- pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IROTH, S_IWOTH, S_IXOTH);
+ pace->perms = 0;
+ if (!is_default_acl) {
+ apply_default_perms(params, is_directory, pace, S_IROTH);
+ }
DLIST_ADD(*pp_ace, pace);
pace_other = pace;
}
- if (setting_acl) {
- /* Ensure when setting a POSIX ACL, that the uid for a
- SMB_ACL_USER_OBJ ACE (the owner ACE entry) has a duplicate
- permission entry as an SMB_ACL_USER, and a gid for a
- SMB_ACL_GROUP_OBJ ACE (the primary group ACE entry) also has
- a duplicate permission entry as an SMB_ACL_GROUP. If not,
- then if the ownership or group ownership of this file or
- directory gets changed, the user or group can lose their
- access. */
- bool got_duplicate_user = false;
- bool got_duplicate_group = false;
-
- for (pace = *pp_ace; pace; pace = pace->next) {
- if (pace->type == SMB_ACL_USER &&
- pace->unix_ug.id == pace_user->unix_ug.id) {
- /* Already got one. */
- got_duplicate_user = true;
- } else if (pace->type == SMB_ACL_GROUP &&
- pace->unix_ug.id == pace_user->unix_ug.id) {
- /* Already got one. */
- got_duplicate_group = true;
- } else if ((pace->type == SMB_ACL_GROUP)
- && (dom_sid_equal(&pace->trustee, &pace_user->trustee))) {
- /* If the SID owning the file appears
- * in a group entry, then we have
- * enough duplication, they will still
- * have access */
- got_duplicate_user = true;
- }
- }
-
- /* If the SID is equal for the user and group that we need
- to add the duplicate for, add only the group */
- if (!got_duplicate_user && !got_duplicate_group
- && dom_sid_equal(&pace_group->trustee,
- &pace_user->trustee)) {
- /* Add a duplicate SMB_ACL_GROUP entry, this
- * will cover the owning SID as well, as it
- * will always be mapped to both a uid and
- * gid. */
-
- if ((pace = talloc(talloc_tos(), canon_ace)) == NULL) {
- DEBUG(0,("ensure_canon_entry_valid: talloc fail.\n"));
- return false;
- }
-
- ZERO_STRUCTP(pace);
- pace->type = SMB_ACL_GROUP;;
- pace->owner_type = GID_ACE;
- pace->unix_ug.type = ID_TYPE_GID;
- pace->unix_ug.id = pace_group->unix_ug.id;
- pace->trustee = pace_group->trustee;
- pace->attr = pace_group->attr;
- pace->perms = pace_group->perms;
-
- DLIST_ADD(*pp_ace, pace);
+ /* Ensure when setting a POSIX ACL, that the uid for a
+ SMB_ACL_USER_OBJ ACE (the owner ACE entry) has a duplicate
+ permission entry as an SMB_ACL_USER, and a gid for a
+ SMB_ACL_GROUP_OBJ ACE (the primary group ACE entry) also has
+ a duplicate permission entry as an SMB_ACL_GROUP. If not,
+ then if the ownership or group ownership of this file or
+ directory gets changed, the user or group can lose their
+ access. */
- /* We're done here, make sure the
- statements below are not executed. */
+ for (pace = *pp_ace; pace; pace = pace->next) {
+ if (pace->type == SMB_ACL_USER &&
+ pace->unix_ug.id == pace_user->unix_ug.id) {
+ /* Already got one. */
got_duplicate_user = true;
+ } else if (pace->type == SMB_ACL_GROUP &&
+ pace->unix_ug.id == pace_user->unix_ug.id) {
+ /* Already got one. */
got_duplicate_group = true;
+ } else if ((pace->type == SMB_ACL_GROUP)
+ && (dom_sid_equal(&pace->trustee, &pace_user->trustee))) {
+ /* If the SID owning the file appears
+ * in a group entry, then we have
+ * enough duplication, they will still
+ * have access */
+ got_duplicate_user = true;
}
+ }
- if (!got_duplicate_user) {
- /* Add a duplicate SMB_ACL_USER entry. */
- if ((pace = talloc(talloc_tos(), canon_ace)) == NULL) {
- DEBUG(0,("ensure_canon_entry_valid: talloc fail.\n"));
- return false;
- }
+ /* If the SID is equal for the user and group that we need
+ to add the duplicate for, add only the group */
+ if (!got_duplicate_user && !got_duplicate_group
+ && dom_sid_equal(&pace_group->trustee,
+ &pace_user->trustee)) {
+ /* Add a duplicate SMB_ACL_GROUP entry, this
+ * will cover the owning SID as well, as it
+ * will always be mapped to both a uid and
+ * gid. */
- ZERO_STRUCTP(pace);
- pace->type = SMB_ACL_USER;;
- pace->owner_type = UID_ACE;
- pace->unix_ug.type = ID_TYPE_UID;
- pace->unix_ug.id = pace_user->unix_ug.id;
- pace->trustee = pace_user->trustee;
- pace->attr = pace_user->attr;
- pace->perms = pace_user->perms;
+ if ((pace = talloc(talloc_tos(), canon_ace)) == NULL) {
+ DEBUG(0,("talloc fail.\n"));
+ return false;
+ }
+
+ ZERO_STRUCTP(pace);
+ pace->type = SMB_ACL_GROUP;;
+ pace->owner_type = GID_ACE;
+ pace->unix_ug.type = ID_TYPE_GID;
+ pace->unix_ug.id = pace_group->unix_ug.id;
+ pace->trustee = pace_group->trustee;
+ pace->attr = pace_group->attr;
+ pace->perms = pace_group->perms;
- DLIST_ADD(*pp_ace, pace);
+ DLIST_ADD(*pp_ace, pace);
- got_duplicate_user = true;
+ /* We're done here, make sure the
+ statements below are not executed. */
+ got_duplicate_user = true;
+ got_duplicate_group = true;
+ }
+
+ if (!got_duplicate_user) {
+ /* Add a duplicate SMB_ACL_USER entry. */
+ if ((pace = talloc(talloc_tos(), canon_ace)) == NULL) {
+ DEBUG(0,("talloc fail.\n"));
+ return false;
}
- if (!got_duplicate_group) {
- /* Add a duplicate SMB_ACL_GROUP entry. */
- if ((pace = talloc(talloc_tos(), canon_ace)) == NULL) {
- DEBUG(0,("ensure_canon_entry_valid: talloc fail.\n"));
- return false;
- }
+ ZERO_STRUCTP(pace);
+ pace->type = SMB_ACL_USER;;
+ pace->owner_type = UID_ACE;
+ pace->unix_ug.type = ID_TYPE_UID;
+ pace->unix_ug.id = pace_user->unix_ug.id;
+ pace->trustee = pace_user->trustee;
+ pace->attr = pace_user->attr;
+ pace->perms = pace_user->perms;
- ZERO_STRUCTP(pace);
- pace->type = SMB_ACL_GROUP;;
- pace->owner_type = GID_ACE;
- pace->unix_ug.type = ID_TYPE_GID;
- pace->unix_ug.id = pace_group->unix_ug.id;
- pace->trustee = pace_group->trustee;
- pace->attr = pace_group->attr;
- pace->perms = pace_group->perms;
+ DLIST_ADD(*pp_ace, pace);
- DLIST_ADD(*pp_ace, pace);
+ got_duplicate_user = true;
+ }
- got_duplicate_group = true;
+ if (!got_duplicate_group) {
+ /* Add a duplicate SMB_ACL_GROUP entry. */
+ if ((pace = talloc(talloc_tos(), canon_ace)) == NULL) {
+ DEBUG(0,("talloc fail.\n"));
+ return false;
}
+ ZERO_STRUCTP(pace);
+ pace->type = SMB_ACL_GROUP;;
+ pace->owner_type = GID_ACE;
+ pace->unix_ug.type = ID_TYPE_GID;
+ pace->unix_ug.id = pace_group->unix_ug.id;
+ pace->trustee = pace_group->trustee;
+ pace->attr = pace_group->attr;
+ pace->perms = pace_group->perms;
+
+ DLIST_ADD(*pp_ace, pace);
+
+ got_duplicate_group = true;
}
- return True;
+ return true;
}
/****************************************************************************
@@ -2232,7 +2219,7 @@ static bool create_canon_ace_lists(files_struct *fsp,
* the file ACL. If we don't have them, check if any SMB_ACL_USER/SMB_ACL_GROUP
* entries can be converted to *_OBJ. Don't do this for the default
* ACL, we will create them separately for this if needed inside
- * ensure_canon_entry_valid().
+ * ensure_canon_entry_valid_on_set().
*/
if (file_ace) {
check_owning_objs(file_ace, pfile_owner_sid, pfile_grp_sid);
@@ -2634,8 +2621,8 @@ static bool unpack_canon_ace(files_struct *fsp,
print_canon_ace_list( "file ace - before valid", file_ace);
- if (!ensure_canon_entry_valid(fsp->conn, &file_ace, false, fsp->conn->params,
- fsp->is_directory, pfile_owner_sid, pfile_grp_sid, pst, True)) {
+ if (!ensure_canon_entry_valid_on_set(fsp->conn, &file_ace, false, fsp->conn->params,
+ fsp->is_directory, pfile_owner_sid, pfile_grp_sid, pst)) {
free_canon_ace_list(file_ace);
free_canon_ace_list(dir_ace);
return False;
@@ -2643,8 +2630,8 @@ static bool unpack_canon_ace(files_struct *fsp,
print_canon_ace_list( "dir ace - before valid", dir_ace);
- if (dir_ace && !ensure_canon_entry_valid(fsp->conn, &dir_ace, true, fsp->conn->params,
- fsp->is_directory, pfile_owner_sid, pfile_grp_sid, pst, True)) {
+ if (dir_ace && !ensure_canon_entry_valid_on_set(fsp->conn, &dir_ace, true, fsp->conn->params,
+ fsp->is_directory, pfile_owner_sid, pfile_grp_sid, pst)) {
free_canon_ace_list(file_ace);
free_canon_ace_list(dir_ace);
return False;