#include "passdb/lookup_sid.h"
#include "auth.h"
#include "../librpc/gen_ndr/idmap.h"
+#include "../librpc/gen_ndr/ndr_smb_acl.h"
#include "lib/param/loadparm.h"
extern const struct generic_mapping file_generic_mapping;
Map POSIX ACL perms to canon_ace permissions (a mode_t containing only S_(R|W|X)USR bits).
****************************************************************************/
-static mode_t convert_permset_to_mode_t(connection_struct *conn, SMB_ACL_PERMSET_T permset)
+static mode_t convert_permset_to_mode_t(SMB_ACL_PERMSET_T permset)
{
mode_t ret = 0;
if (sys_acl_clear_perms(*p_permset) == -1)
return -1;
if (mode & S_IRUSR) {
- if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_READ) == -1)
+ if (sys_acl_add_perm(*p_permset, SMB_ACL_READ) == -1)
return -1;
}
if (mode & S_IWUSR) {
- if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_WRITE) == -1)
+ if (sys_acl_add_perm(*p_permset, SMB_ACL_WRITE) == -1)
return -1;
}
if (mode & S_IXUSR) {
- if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_EXECUTE) == -1)
+ if (sys_acl_add_perm(*p_permset, SMB_ACL_EXECUTE) == -1)
return -1;
}
return 0;
*pp_list_head = l_head;
}
-/****************************************************************************
- Check if we need to return NT4.x compatible ACL entries.
-****************************************************************************/
-
-bool nt4_compatible_acls(void)
-{
- int compat = lp_acl_compatibility();
-
- if (compat == ACL_COMPAT_AUTO) {
- enum remote_arch_types ra_type = get_remote_arch();
-
- /* Automatically adapt to client */
- return (ra_type <= RA_WINNT);
- } else
- return (compat == ACL_COMPAT_WINNT);
-}
-
-
/****************************************************************************
Map canon_ace perms to permission bits NT.
The attr element is not used here - we only process deny entries on set,
* to be changed in the future.
*/
- if (nt4_compatible_acls())
- nt_mask = UNIX_ACCESS_NONE;
- else
- nt_mask = 0;
+ nt_mask = 0;
} else {
if (directory_ace) {
nt_mask |= ((perms & S_IRUSR) ? UNIX_DIRECTORY_ACCESS_R : 0 );
/* Get the initial bits to apply. */
if (is_directory) {
- and_bits = lp_dir_security_mask(params->service);
- or_bits = lp_force_dir_security_mode(params->service);
+ and_bits = lp_dir_mask(params->service);
+ or_bits = lp_force_dir_mode(params->service);
} else {
- and_bits = lp_security_mask(params->service);
- or_bits = lp_force_security_mode(params->service);
+ and_bits = lp_create_mask(params->service);
+ or_bits = lp_force_create_mode(params->service);
}
/* Now bounce them into the S_USR space. */
}
/****************************************************************************
- 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
+ the mode of the file.
+****************************************************************************/
+
+static bool ensure_canon_entry_valid_on_get(connection_struct *conn,
+ canon_ace **pp_ace,
+ const struct dom_sid *pfile_owner_sid,
+ const struct dom_sid *pfile_grp_sid,
+ const SMB_STRUCT_STAT *pst)
+{
+ canon_ace *pace;
+ bool got_user = false;
+ bool got_group = false;
+ bool got_other = false;
+
+ for (pace = *pp_ace; pace; pace = pace->next) {
+ if (pace->type == SMB_ACL_USER_OBJ) {
+ got_user = true;
+ } else if (pace->type == SMB_ACL_GROUP_OBJ) {
+ got_group = true;
+ } else if (pace->type == SMB_ACL_OTHER) {
+ got_other = true;
+ }
+ }
+
+ if (!got_user) {
+ if ((pace = talloc(talloc_tos(), canon_ace)) == NULL) {
+ DEBUG(0,("malloc fail.\n"));
+ return false;
+ }
+
+ ZERO_STRUCTP(pace);
+ pace->type = SMB_ACL_USER_OBJ;
+ pace->owner_type = UID_ACE;
+ pace->unix_ug.type = ID_TYPE_UID;
+ pace->unix_ug.id = pst->st_ex_uid;
+ pace->trustee = *pfile_owner_sid;
+ pace->attr = ALLOW_ACE;
+ pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRUSR, S_IWUSR, S_IXUSR);
+ DLIST_ADD(*pp_ace, pace);
+ }
+
+ if (!got_group) {
+ if ((pace = talloc(talloc_tos(), canon_ace)) == NULL) {
+ DEBUG(0,("malloc fail.\n"));
+ return false;
+ }
+
+ ZERO_STRUCTP(pace);
+ pace->type = SMB_ACL_GROUP_OBJ;
+ pace->owner_type = GID_ACE;
+ pace->unix_ug.type = ID_TYPE_GID;
+ pace->unix_ug.id = pst->st_ex_gid;
+ pace->trustee = *pfile_grp_sid;
+ pace->attr = ALLOW_ACE;
+ pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRGRP, S_IWGRP, S_IXGRP);
+ DLIST_ADD(*pp_ace, pace);
+ }
+
+ if (!got_other) {
+ if ((pace = talloc(talloc_tos(), canon_ace)) == NULL) {
+ DEBUG(0,("malloc fail.\n"));
+ return false;
+ }
+
+ ZERO_STRUCTP(pace);
+ pace->type = SMB_ACL_OTHER;
+ pace->owner_type = WORLD_ACE;
+ pace->unix_ug.type = ID_TYPE_NOT_SPECIFIED;
+ pace->unix_ug.id = -1;
+ pace->trustee = global_sid_World;
+ pace->attr = ALLOW_ACE;
+ pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IROTH, S_IWOTH, S_IXOTH);
+ DLIST_ADD(*pp_ace, pace);
+ }
+
+ return true;
+}
+
+/****************************************************************************
+ 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 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, canon_ace **pp_ace,
- 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)
+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)
{
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)
+ if (!is_default_acl) {
apply_default_perms(params, is_directory, pace, S_IRUSR);
+ }
pace_user = pace;
} else if (pace->type == SMB_ACL_GROUP_OBJ) {
* Ensure create mask/force create mode is respected on set.
*/
- if (setting_acl)
+ if (!is_default_acl) {
apply_default_perms(params, is_directory, pace, S_IRGRP);
+ }
pace_group = pace;
} else if (pace->type == SMB_ACL_OTHER) {
* Ensure create mask/force create mode is respected on set.
*/
- if (setting_acl)
+ if (!is_default_acl) {
apply_default_perms(params, is_directory, pace, S_IROTH);
+ }
pace_other = pace;
+
+ } else if (pace->type == SMB_ACL_USER || pace->type == SMB_ACL_GROUP) {
+
+ /*
+ * Ensure create mask/force create mode is respected on set.
+ */
+
+ 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);
pace->unix_ug.id = pst->st_ex_uid;
pace->trustee = *pfile_owner_sid;
pace->attr = ALLOW_ACE;
- /* Start with existing permissions, principle of least
+ /* Start with existing user permissions, principle of least
surprises for the user. */
- pace->perms = pst->st_ex_mode;
+ pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRUSR, S_IWUSR, S_IXUSR);
- 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);
}
DLIST_ADD(*pp_ace, pace);
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);
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;
- 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);
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);
pace->unix_ug.id = -1;
pace->trustee = global_sid_World;
pace->attr = ALLOW_ACE;
- if (setting_acl) {
- pace->perms = 0;
+ 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);
+ }
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_group->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. */
+
+ 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;
- 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;
+ DLIST_ADD(*pp_ace, pace);
- DLIST_ADD(*pp_ace, pace);
+ /* We're done here, make sure the
+ statements below are not executed. */
+ got_duplicate_user = true;
+ got_duplicate_group = true;
+ }
- 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,("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;
}
/****************************************************************************
DEBUG(3,("create_canon_ace_lists: unable to set anything but an ALLOW or DENY ACE.\n"));
return False;
}
-
- if (nt4_compatible_acls()) {
- /*
- * The security mask may be UNIX_ACCESS_NONE which should map into
- * no permissions (we overload the WRITE_OWNER bit for this) or it
- * should be one of the ALL/EXECUTE/READ/WRITE bits. Arrange for this
- * to be so. Any other bits override the UNIX_ACCESS_NONE bit.
- */
-
- /*
- * Convert GENERIC bits to specific bits.
- */
-
- se_map_generic(&psa->access_mask, &file_generic_mapping);
-
- psa->access_mask &= (UNIX_ACCESS_NONE|FILE_ALL_ACCESS);
-
- if(psa->access_mask != UNIX_ACCESS_NONE)
- psa->access_mask &= ~UNIX_ACCESS_NONE;
- }
}
/*
* 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);
print_canon_ace_list( "file ace - before valid", file_ace);
- if (!ensure_canon_entry_valid(fsp->conn, &file_ace, 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;
print_canon_ace_list( "dir ace - before valid", dir_ace);
- if (dir_ace && !ensure_canon_entry_valid(fsp->conn, &dir_ace, 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;
canon_ace *ace = NULL;
canon_ace *next_ace = NULL;
int entry_id = SMB_ACL_FIRST_ENTRY;
+ bool is_default_acl = (the_acl_type == SMB_ACL_TYPE_DEFAULT);
SMB_ACL_ENTRY_T entry;
size_t ace_count;
unix_ug.type = ID_TYPE_UID;
unix_ug.id = *puid;
owner_type = UID_ACE;
- sys_acl_free_qualifier((void *)puid,tagtype);
break;
}
case SMB_ACL_GROUP_OBJ:
unix_ug.type = ID_TYPE_GID;
unix_ug.id = *pgid;
owner_type = GID_ACE;
- sys_acl_free_qualifier((void *)pgid,tagtype);
break;
}
case SMB_ACL_MASK:
- acl_mask = convert_permset_to_mode_t(conn, permset);
+ acl_mask = convert_permset_to_mode_t(permset);
continue; /* Don't count the mask as an entry. */
case SMB_ACL_OTHER:
/* Use the Everyone SID */
ZERO_STRUCTP(ace);
ace->type = tagtype;
- ace->perms = convert_permset_to_mode_t(conn, permset);
+ ace->perms = convert_permset_to_mode_t(permset);
ace->attr = ALLOW_ACE;
ace->trustee = sid;
ace->unix_ug = unix_ug;
ace->owner_type = owner_type;
- ace->ace_flags = get_pai_flags(pal, ace, (the_acl_type == SMB_ACL_TYPE_DEFAULT));
+ ace->ace_flags = get_pai_flags(pal, ace, is_default_acl);
DLIST_ADD(l_head, ace);
}
* This next call will ensure we have at least a user/group/world set.
*/
- if (!ensure_canon_entry_valid(conn, &l_head, conn->params,
- S_ISDIR(psbuf->st_ex_mode), powner, pgroup,
- psbuf, False))
+ if (!ensure_canon_entry_valid_on_get(conn, &l_head,
+ powner, pgroup,
+ psbuf))
goto fail;
/*
* acl_mask. Ensure all DENY Entries are at the start of the list.
*/
- DEBUG(10,("canonicalise_acl: %s ace entries before arrange :\n", the_acl_type == SMB_ACL_TYPE_ACCESS ? "Access" : "Default" ));
+ DEBUG(10,("canonicalise_acl: %s ace entries before arrange :\n", is_default_acl ? "Default" : "Access"));
for ( ace_count = 0, ace = l_head; ace; ace = next_ace, ace_count++) {
next_ace = ace->next;
{
connection_struct *conn = fsp->conn;
bool ret = False;
- SMB_ACL_T the_acl = sys_acl_init(count_canon_ace_list(the_ace) + 1);
+ SMB_ACL_T the_acl = sys_acl_init(talloc_tos());
canon_ace *p_ace;
int i;
SMB_ACL_ENTRY_T mask_entry;
#endif
if (the_acl == NULL) {
-
- if (!no_acl_syscall_error(errno)) {
- /*
- * Only print this error message if we have some kind of ACL
- * support that's not working. Otherwise we would always get this.
- */
- DEBUG(0,("set_canon_ace_list: Unable to init %s ACL. (%s)\n",
- default_ace ? "default" : "file", strerror(errno) ));
- }
- *pacl_set_support = False;
- goto fail;
+ DEBUG(0, ("sys_acl_init failed to allocate an ACL\n"));
+ return false;
}
if( DEBUGLVL( 10 )) {
* Get the entry for this ACE.
*/
- if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &the_acl, &the_entry) == -1) {
+ if (sys_acl_create_entry(&the_acl, &the_entry) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to create entry %d. (%s)\n",
i, strerror(errno) ));
goto fail;
* First tell the entry what type of ACE this is.
*/
- if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, the_entry, p_ace->type) == -1) {
+ if (sys_acl_set_tag_type(the_entry, p_ace->type) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to set tag type on entry %d. (%s)\n",
i, strerror(errno) ));
goto fail;
*/
if ((p_ace->type == SMB_ACL_USER) || (p_ace->type == SMB_ACL_GROUP)) {
- if (SMB_VFS_SYS_ACL_SET_QUALIFIER(conn, the_entry,(void *)&p_ace->unix_ug.id) == -1) {
+ if (sys_acl_set_qualifier(the_entry,(void *)&p_ace->unix_ug.id) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to set qualifier on entry %d. (%s)\n",
i, strerror(errno) ));
goto fail;
* ..and apply them to the entry.
*/
- if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, the_entry, the_permset) == -1) {
+ if (sys_acl_set_permset(the_entry, the_permset) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to add permset on entry %d. (%s)\n",
i, strerror(errno) ));
goto fail;
}
if (needs_mask && !got_mask_entry) {
- if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &the_acl, &mask_entry) == -1) {
+ if (sys_acl_create_entry(&the_acl, &mask_entry) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to create mask entry. (%s)\n", strerror(errno) ));
goto fail;
}
- if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, mask_entry, SMB_ACL_MASK) == -1) {
+ if (sys_acl_set_tag_type(mask_entry, SMB_ACL_MASK) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to set tag type on mask entry. (%s)\n",strerror(errno) ));
goto fail;
}
goto fail;
}
- if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, mask_entry, mask_permset) == -1) {
+ if (sys_acl_set_permset(mask_entry, mask_permset) == -1) {
DEBUG(0,("set_canon_ace_list: Failed to add mask permset. (%s)\n", strerror(errno) ));
goto fail;
}
fail:
if (the_acl != NULL) {
- sys_acl_free_acl(the_acl);
+ TALLOC_FREE(the_acl);
}
return ret;
}
-/****************************************************************************
- Find a particular canon_ace entry.
-****************************************************************************/
-
-static struct canon_ace *canon_ace_entry_for(struct canon_ace *list, SMB_ACL_TAG_T type, struct unixid *id)
-{
- while (list) {
- if (list->type == type && ((type != SMB_ACL_USER && type != SMB_ACL_GROUP) ||
- (type == SMB_ACL_USER && id && id->id == list->unix_ug.id) ||
- (type == SMB_ACL_GROUP && id && id->id == list->unix_ug.id)))
- break;
- list = list->next;
- }
- return list;
-}
-
/****************************************************************************
****************************************************************************/
if (!the_acl)
return NULL;
if (sys_acl_get_entry(the_acl, SMB_ACL_FIRST_ENTRY, &entry) != 1) {
- sys_acl_free_acl(the_acl);
+ TALLOC_FREE(the_acl);
return NULL;
}
return the_acl;
/* Get the initial bits to apply. */
if (fsp->is_directory) {
- and_bits = lp_dir_security_mask(snum);
- or_bits = lp_force_dir_security_mode(snum);
+ and_bits = lp_dir_mask(snum);
+ or_bits = lp_force_dir_mode(snum);
} else {
- and_bits = lp_security_mask(snum);
- or_bits = lp_force_security_mode(snum);
+ and_bits = lp_create_mask(snum);
+ or_bits = lp_force_create_mode(snum);
}
*posix_perms = (((*posix_perms) & and_bits)|or_bits);
SMB_ACL_T posix_acl,
SMB_ACL_T def_acl,
uint32_t security_info,
+ TALLOC_CTX *mem_ctx,
struct security_descriptor **ppdesc)
{
struct dom_sid owner_sid;
canon_ace *ace;
enum security_ace_type nt_acl_type;
- if (nt4_compatible_acls() && dir_ace) {
- /*
- * NT 4 chokes if an ACL contains an INHERIT_ONLY entry
- * but no non-INHERIT_ONLY entry for one SID. So we only
- * remove entries from the Access ACL if the
- * corresponding Default ACL entries have also been
- * removed. ACEs for CREATOR-OWNER and CREATOR-GROUP
- * are exceptions. We can do nothing
- * intelligent if the Default ACL contains entries that
- * are not also contained in the Access ACL, so this
- * case will still fail under NT 4.
- */
-
- ace = canon_ace_entry_for(dir_ace, SMB_ACL_OTHER, NULL);
- if (ace && !ace->perms) {
- DLIST_REMOVE(dir_ace, ace);
- TALLOC_FREE(ace);
-
- ace = canon_ace_entry_for(file_ace, SMB_ACL_OTHER, NULL);
- if (ace && !ace->perms) {
- DLIST_REMOVE(file_ace, ace);
- TALLOC_FREE(ace);
- }
- }
-
- /*
- * WinNT doesn't usually have Creator Group
- * in browse lists, so we send this entry to
- * WinNT even if it contains no relevant
- * permissions. Once we can add
- * Creator Group to browse lists we can
- * re-enable this.
- */
-
-#if 0
- ace = canon_ace_entry_for(dir_ace, SMB_ACL_GROUP_OBJ, NULL);
- if (ace && !ace->perms) {
- DLIST_REMOVE(dir_ace, ace);
- TALLOC_FREE(ace);
- }
-#endif
-
- ace = canon_ace_entry_for(file_ace, SMB_ACL_GROUP_OBJ, NULL);
- if (ace && !ace->perms) {
- DLIST_REMOVE(file_ace, ace);
- TALLOC_FREE(ace);
- }
- }
-
num_acls = count_canon_ace_list(file_ace);
num_def_acls = count_canon_ace_list(dir_ace);
}
} /* security_info & SECINFO_DACL */
- psd = make_standard_sec_desc( talloc_tos(),
+ psd = make_standard_sec_desc(mem_ctx,
(security_info & SECINFO_OWNER) ? &owner_sid : NULL,
(security_info & SECINFO_GROUP) ? &group_sid : NULL,
psa,
done:
if (posix_acl) {
- sys_acl_free_acl(posix_acl);
+ TALLOC_FREE(posix_acl);
}
if (def_acl) {
- sys_acl_free_acl(def_acl);
+ TALLOC_FREE(def_acl);
}
free_canon_ace_list(file_ace);
free_canon_ace_list(dir_ace);
}
NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info,
+ TALLOC_CTX *mem_ctx,
struct security_descriptor **ppdesc)
{
SMB_STRUCT_STAT sbuf;
SMB_ACL_T posix_acl = NULL;
struct pai_val *pal;
+ TALLOC_CTX *frame = talloc_stackframe();
+ NTSTATUS status;
*ppdesc = NULL;
/* can it happen that fsp_name == NULL ? */
if (fsp->is_directory || fsp->fh->fd == -1) {
- return posix_get_nt_acl(fsp->conn, fsp->fsp_name->base_name,
- security_info, ppdesc);
+ status = posix_get_nt_acl(fsp->conn, fsp->fsp_name->base_name,
+ security_info, mem_ctx, ppdesc);
+ TALLOC_FREE(frame);
+ return status;
}
/* Get the stat struct for the owner info. */
if(SMB_VFS_FSTAT(fsp, &sbuf) != 0) {
+ TALLOC_FREE(frame);
return map_nt_error_from_unix(errno);
}
/* Get the ACL from the fd. */
- posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp);
+ posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, frame);
pal = fload_inherited_info(fsp);
- return posix_get_nt_acl_common(fsp->conn, fsp->fsp_name->base_name,
- &sbuf, pal, posix_acl, NULL,
- security_info, ppdesc);
+ status = posix_get_nt_acl_common(fsp->conn, fsp->fsp_name->base_name,
+ &sbuf, pal, posix_acl, NULL,
+ security_info, mem_ctx, ppdesc);
+ TALLOC_FREE(frame);
+ return status;
}
NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name,
- uint32_t security_info, struct security_descriptor **ppdesc)
+ uint32_t security_info,
+ TALLOC_CTX *mem_ctx,
+ struct security_descriptor **ppdesc)
{
SMB_ACL_T posix_acl = NULL;
SMB_ACL_T def_acl = NULL;
struct pai_val *pal;
struct smb_filename smb_fname;
int ret;
+ TALLOC_CTX *frame = talloc_stackframe();
+ NTSTATUS status;
*ppdesc = NULL;
}
if (ret == -1) {
+ TALLOC_FREE(frame);
return map_nt_error_from_unix(errno);
}
/* Get the ACL from the path. */
- posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_ACCESS);
+ posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name,
+ SMB_ACL_TYPE_ACCESS, frame);
/* If it's a directory get the default POSIX ACL. */
if(S_ISDIR(smb_fname.st.st_ex_mode)) {
- def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_DEFAULT);
+ def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name,
+ SMB_ACL_TYPE_DEFAULT, frame);
def_acl = free_empty_sys_acl(conn, def_acl);
}
pal = load_inherited_info(conn, name);
- return posix_get_nt_acl_common(conn, name, &smb_fname.st, pal,
- posix_acl, def_acl, security_info,
- ppdesc);
+ status = posix_get_nt_acl_common(conn, name, &smb_fname.st, pal,
+ posix_acl, def_acl, security_info,
+ mem_ctx,
+ ppdesc);
+ TALLOC_FREE(frame);
+ return status;
}
/****************************************************************************
SMB_ACL_T posix_acl;
int result = -1;
- posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS);
+ posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname,
+ SMB_ACL_TYPE_ACCESS, talloc_tos());
if (posix_acl == (SMB_ACL_T)NULL)
return -1;
}
}
}
- sys_acl_free_acl(posix_acl);
+ TALLOC_FREE(posix_acl);
return result;
}
if (map_acl_perms_to_permset(conn, perms, &permset) == -1)
return -1;
- if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, entry, permset) == -1)
+ if (sys_acl_set_permset(entry, permset) == -1)
return -1;
}
SMB_ACL_T posix_acl = NULL;
int ret = -1;
- if ((posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, from, SMB_ACL_TYPE_ACCESS)) == NULL)
+ if ((posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, from,
+ SMB_ACL_TYPE_ACCESS,
+ talloc_tos())) == NULL)
return -1;
if ((ret = chmod_acl_internals(conn, posix_acl, mode)) == -1)
done:
- sys_acl_free_acl(posix_acl);
+ TALLOC_FREE(posix_acl);
return ret;
}
static bool directory_has_default_posix_acl(connection_struct *conn, const char *fname)
{
- SMB_ACL_T def_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, SMB_ACL_TYPE_DEFAULT);
+ SMB_ACL_T def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname,
+ SMB_ACL_TYPE_DEFAULT,
+ talloc_tos());
bool has_acl = False;
SMB_ACL_ENTRY_T entry;
}
if (def_acl) {
- sys_acl_free_acl(def_acl);
+ TALLOC_FREE(def_acl);
}
return has_acl;
}
SMB_ACL_T posix_acl = NULL;
int ret = -1;
- if ((posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp)) == NULL)
+ if ((posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, talloc_tos())) == NULL)
return -1;
if ((ret = chmod_acl_internals(conn, posix_acl, mode)) == -1)
done:
- sys_acl_free_acl(posix_acl);
+ TALLOC_FREE(posix_acl);
return ret;
}
}
if (wire_perm & SMB_POSIX_ACL_READ) {
- if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_READ) == -1) {
+ if (sys_acl_add_perm(*p_permset, SMB_ACL_READ) == -1) {
return False;
}
}
if (wire_perm & SMB_POSIX_ACL_WRITE) {
- if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_WRITE) == -1) {
+ if (sys_acl_add_perm(*p_permset, SMB_ACL_WRITE) == -1) {
return False;
}
}
if (wire_perm & SMB_POSIX_ACL_EXECUTE) {
- if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_EXECUTE) == -1) {
+ if (sys_acl_add_perm(*p_permset, SMB_ACL_EXECUTE) == -1) {
return False;
}
}
FIXME ! How does the share mask/mode fit into this.... ?
****************************************************************************/
-static SMB_ACL_T create_posix_acl_from_wire(connection_struct *conn, uint16 num_acls, const char *pdata)
+static SMB_ACL_T create_posix_acl_from_wire(connection_struct *conn,
+ uint16 num_acls,
+ const char *pdata,
+ TALLOC_CTX *mem_ctx)
{
unsigned int i;
- SMB_ACL_T the_acl = sys_acl_init(num_acls);
+ SMB_ACL_T the_acl = sys_acl_init(mem_ctx);
if (the_acl == NULL) {
return NULL;
SMB_ACL_PERMSET_T the_permset;
SMB_ACL_TAG_T tag_type;
- if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &the_acl, &the_entry) == -1) {
+ if (sys_acl_create_entry(&the_acl, &the_entry) == -1) {
DEBUG(0,("create_posix_acl_from_wire: Failed to create entry %u. (%s)\n",
i, strerror(errno) ));
goto fail;
goto fail;
}
- if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, the_entry, tag_type) == -1) {
+ if (sys_acl_set_tag_type(the_entry, tag_type) == -1) {
DEBUG(0,("create_posix_acl_from_wire: Failed to set tagtype on entry %u. (%s)\n",
i, strerror(errno) ));
goto fail;
}
/* Now apply to the new ACL entry. */
- if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, the_entry, the_permset) == -1) {
+ if (sys_acl_set_permset(the_entry, the_permset) == -1) {
DEBUG(0,("create_posix_acl_from_wire: Failed to add permset on entry %u. (%s)\n",
i, strerror(errno) ));
goto fail;
if (tag_type == SMB_ACL_USER) {
uint32 uidval = IVAL(pdata,(i*SMB_POSIX_ACL_ENTRY_SIZE)+2);
uid_t uid = (uid_t)uidval;
- if (SMB_VFS_SYS_ACL_SET_QUALIFIER(conn, the_entry,(void *)&uid) == -1) {
+ if (sys_acl_set_qualifier(the_entry,(void *)&uid) == -1) {
DEBUG(0,("create_posix_acl_from_wire: Failed to set uid %u on entry %u. (%s)\n",
(unsigned int)uid, i, strerror(errno) ));
goto fail;
if (tag_type == SMB_ACL_GROUP) {
uint32 gidval = IVAL(pdata,(i*SMB_POSIX_ACL_ENTRY_SIZE)+2);
gid_t gid = (uid_t)gidval;
- if (SMB_VFS_SYS_ACL_SET_QUALIFIER(conn, the_entry,(void *)&gid) == -1) {
+ if (sys_acl_set_qualifier(the_entry,(void *)&gid) == -1) {
DEBUG(0,("create_posix_acl_from_wire: Failed to set gid %u on entry %u. (%s)\n",
(unsigned int)gid, i, strerror(errno) ));
goto fail;
fail:
if (the_acl != NULL) {
- sys_acl_free_acl(the_acl);
+ TALLOC_FREE(the_acl);
}
return NULL;
}
return True;
}
- if ((def_acl = create_posix_acl_from_wire(conn, num_def_acls, pdata)) == NULL) {
+ if ((def_acl = create_posix_acl_from_wire(conn, num_def_acls,
+ pdata,
+ talloc_tos())) == NULL) {
return False;
}
if (SMB_VFS_SYS_ACL_SET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT, def_acl) == -1) {
DEBUG(5,("set_unix_posix_default_acl: acl_set_file failed on directory %s (%s)\n",
fname, strerror(errno) ));
- sys_acl_free_acl(def_acl);
+ TALLOC_FREE(def_acl);
return False;
}
DEBUG(10,("set_unix_posix_default_acl: set default acl for file %s\n", fname ));
- sys_acl_free_acl(def_acl);
+ TALLOC_FREE(def_acl);
return True;
}
SMB_ACL_ENTRY_T entry;
bool ret = False;
/* Create a new ACL with only 3 entries, u/g/w. */
- SMB_ACL_T new_file_acl = sys_acl_init(3);
+ SMB_ACL_T new_file_acl = sys_acl_init(talloc_tos());
SMB_ACL_ENTRY_T user_ent = NULL;
SMB_ACL_ENTRY_T group_ent = NULL;
SMB_ACL_ENTRY_T other_ent = NULL;
}
/* Now create the u/g/w entries. */
- if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &new_file_acl, &user_ent) == -1) {
+ if (sys_acl_create_entry(&new_file_acl, &user_ent) == -1) {
DEBUG(5,("remove_posix_acl: Failed to create user entry for file %s. (%s)\n",
fname, strerror(errno) ));
goto done;
}
- if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, user_ent, SMB_ACL_USER_OBJ) == -1) {
+ if (sys_acl_set_tag_type(user_ent, SMB_ACL_USER_OBJ) == -1) {
DEBUG(5,("remove_posix_acl: Failed to set user entry for file %s. (%s)\n",
fname, strerror(errno) ));
goto done;
}
- if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &new_file_acl, &group_ent) == -1) {
+ if (sys_acl_create_entry(&new_file_acl, &group_ent) == -1) {
DEBUG(5,("remove_posix_acl: Failed to create group entry for file %s. (%s)\n",
fname, strerror(errno) ));
goto done;
}
- if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, group_ent, SMB_ACL_GROUP_OBJ) == -1) {
+ if (sys_acl_set_tag_type(group_ent, SMB_ACL_GROUP_OBJ) == -1) {
DEBUG(5,("remove_posix_acl: Failed to set group entry for file %s. (%s)\n",
fname, strerror(errno) ));
goto done;
}
- if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &new_file_acl, &other_ent) == -1) {
+ if (sys_acl_create_entry(&new_file_acl, &other_ent) == -1) {
DEBUG(5,("remove_posix_acl: Failed to create other entry for file %s. (%s)\n",
fname, strerror(errno) ));
goto done;
}
- if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, other_ent, SMB_ACL_OTHER) == -1) {
+ if (sys_acl_set_tag_type(other_ent, SMB_ACL_OTHER) == -1) {
DEBUG(5,("remove_posix_acl: Failed to set other entry for file %s. (%s)\n",
fname, strerror(errno) ));
goto done;
/* Get the current file ACL. */
if (fsp && fsp->fh->fd != -1) {
- file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp);
+ file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, talloc_tos());
} else {
- file_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, SMB_ACL_TYPE_ACCESS);
+ file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname,
+ SMB_ACL_TYPE_ACCESS,
+ talloc_tos());
}
if (file_acl == NULL) {
}
if (tagtype == SMB_ACL_USER_OBJ) {
- if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, user_ent, permset) == -1) {
+ if (sys_acl_set_permset(user_ent, permset) == -1) {
DEBUG(5,("remove_posix_acl: failed to set permset from ACL on file %s (%s).\n",
fname, strerror(errno) ));
}
} else if (tagtype == SMB_ACL_GROUP_OBJ) {
- if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, group_ent, permset) == -1) {
+ if (sys_acl_set_permset(group_ent, permset) == -1) {
DEBUG(5,("remove_posix_acl: failed to set permset from ACL on file %s (%s).\n",
fname, strerror(errno) ));
}
} else if (tagtype == SMB_ACL_OTHER) {
- if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, other_ent, permset) == -1) {
+ if (sys_acl_set_permset(other_ent, permset) == -1) {
DEBUG(5,("remove_posix_acl: failed to set permset from ACL on file %s (%s).\n",
fname, strerror(errno) ));
}
done:
if (file_acl) {
- sys_acl_free_acl(file_acl);
+ TALLOC_FREE(file_acl);
}
if (new_file_acl) {
- sys_acl_free_acl(new_file_acl);
+ TALLOC_FREE(new_file_acl);
}
return ret;
}
return remove_posix_acl(conn, fsp, fname);
}
- if ((file_acl = create_posix_acl_from_wire(conn, num_acls, pdata)) == NULL) {
+ if ((file_acl = create_posix_acl_from_wire(conn, num_acls,
+ pdata,
+ talloc_tos())) == NULL) {
return False;
}
if (SMB_VFS_SYS_ACL_SET_FD(fsp, file_acl) == -1) {
DEBUG(5,("set_unix_posix_acl: acl_set_file failed on %s (%s)\n",
fname, strerror(errno) ));
- sys_acl_free_acl(file_acl);
+ TALLOC_FREE(file_acl);
return False;
}
} else {
if (SMB_VFS_SYS_ACL_SET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS, file_acl) == -1) {
DEBUG(5,("set_unix_posix_acl: acl_set_file failed on %s (%s)\n",
fname, strerror(errno) ));
- sys_acl_free_acl(file_acl);
+ TALLOC_FREE(file_acl);
return False;
}
}
DEBUG(10,("set_unix_posix_acl: set acl for file %s\n", fname ));
- sys_acl_free_acl(file_acl);
+ TALLOC_FREE(file_acl);
return True;
}
check. Caller is responsible for freeing the returned security
descriptor via TALLOC_FREE(). This is designed for dealing with
user space access checks in smbd outside of the VFS. For example,
- checking access rights in OpenEventlog().
+ checking access rights in OpenEventlog() or from python.
- Assume we are dealing with files (for now)
********************************************************************/
-struct security_descriptor *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname)
+NTSTATUS get_nt_acl_no_snum(TALLOC_CTX *ctx, const char *fname,
+ uint32 security_info_wanted,
+ struct security_descriptor **sd)
{
- struct security_descriptor *psd, *ret_sd;
+ TALLOC_CTX *frame = talloc_stackframe();
connection_struct *conn;
- files_struct finfo;
- struct fd_handle fh;
- NTSTATUS status;
+ NTSTATUS status = NT_STATUS_OK;
- conn = talloc_zero(ctx, connection_struct);
+ if (!posix_locking_init(false)) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ conn = talloc_zero(frame, connection_struct);
if (conn == NULL) {
+ TALLOC_FREE(frame);
DEBUG(0, ("talloc failed\n"));
- return NULL;
+ return NT_STATUS_NO_MEMORY;
}
if (!(conn->params = talloc(conn, struct share_params))) {
- DEBUG(0,("get_nt_acl_no_snum: talloc() failed!\n"));
- TALLOC_FREE(conn);
- return NULL;
+ DEBUG(0, ("talloc failed\n"));
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_MEMORY;
}
conn->params->service = -1;
set_conn_connectpath(conn, "/");
if (!smbd_vfs_init(conn)) {
- DEBUG(0,("get_nt_acl_no_snum: Unable to create a fake connection struct!\n"));
- conn_free(conn);
- return NULL;
- }
-
- ZERO_STRUCT( finfo );
- ZERO_STRUCT( fh );
-
- finfo.fnum = FNUM_FIELD_INVALID;
- finfo.conn = conn;
- finfo.fh = &fh;
- finfo.fh->fd = -1;
-
- status = create_synthetic_smb_fname(talloc_tos(), fname, NULL, NULL,
- &finfo.fsp_name);
- if (!NT_STATUS_IS_OK(status)) {
- conn_free(conn);
- return NULL;
+ DEBUG(0,("smbd_vfs_init() failed!\n"));
+ TALLOC_FREE(frame);
+ return NT_STATUS_INTERNAL_ERROR;
}
- if (!NT_STATUS_IS_OK(SMB_VFS_FGET_NT_ACL( &finfo, SECINFO_DACL, &psd))) {
- DEBUG(0,("get_nt_acl_no_snum: get_nt_acl returned zero.\n"));
- TALLOC_FREE(finfo.fsp_name);
- conn_free(conn);
- return NULL;
+ status = SMB_VFS_GET_NT_ACL(conn, fname, security_info_wanted, ctx, sd);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("set_nt_acl_no_snum: fset_nt_acl returned %s.\n",
+ nt_errstr(status)));
}
- ret_sd = dup_sec_desc( ctx, psd );
-
- TALLOC_FREE(finfo.fsp_name);
conn_free(conn);
+ TALLOC_FREE(frame);
- return ret_sd;
+ return status;
}
/* Stolen shamelessly from pvfs_default_acl() in source4 :-). */
}
return NT_STATUS_OK;
}
+
+int posix_sys_acl_blob_get_file(vfs_handle_struct *handle,
+ const char *path_p,
+ TALLOC_CTX *mem_ctx,
+ char **blob_description,
+ DATA_BLOB *blob)
+{
+ int ret;
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct smb_acl_wrapper acl_wrapper = {};
+ struct smb_filename *smb_fname = NULL;
+ NTSTATUS status = create_synthetic_smb_fname_split(frame, path_p,
+ NULL,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ TALLOC_FREE(frame);
+ return -1;
+ }
+
+ acl_wrapper.access_acl
+ = smb_vfs_call_sys_acl_get_file(handle,
+ path_p,
+ SMB_ACL_TYPE_ACCESS,
+ frame);
+
+ ret = smb_vfs_call_stat(handle, smb_fname);
+ if (ret == -1) {
+ TALLOC_FREE(frame);
+ return -1;
+ }
+
+ if (S_ISDIR(smb_fname->st.st_ex_mode)) {
+ acl_wrapper.default_acl
+ = smb_vfs_call_sys_acl_get_file(handle,
+ path_p,
+ SMB_ACL_TYPE_DEFAULT,
+ frame);
+ }
+
+ acl_wrapper.owner = smb_fname->st.st_ex_uid;
+ acl_wrapper.group = smb_fname->st.st_ex_gid;
+ acl_wrapper.mode = smb_fname->st.st_ex_mode;
+
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_struct_blob(blob, mem_ctx,
+ &acl_wrapper,
+ (ndr_push_flags_fn_t)ndr_push_smb_acl_wrapper))) {
+ errno = EINVAL;
+ TALLOC_FREE(frame);
+ return -1;
+ }
+
+ *blob_description = talloc_strdup(mem_ctx, "posix_acl");
+ if (!*blob_description) {
+ errno = EINVAL;
+ TALLOC_FREE(frame);
+ return -1;
+ }
+
+ TALLOC_FREE(frame);
+ return 0;
+}
+
+int posix_sys_acl_blob_get_fd(vfs_handle_struct *handle,
+ files_struct *fsp,
+ TALLOC_CTX *mem_ctx,
+ char **blob_description,
+ DATA_BLOB *blob)
+{
+ SMB_STRUCT_STAT sbuf;
+ TALLOC_CTX *frame;
+ struct smb_acl_wrapper acl_wrapper;
+ int ret;
+
+ /* This ensures that we also consider the default ACL */
+ if (fsp->is_directory || fsp->fh->fd == -1) {
+ return posix_sys_acl_blob_get_file(handle, fsp->fsp_name->base_name,
+ mem_ctx, blob_description, blob);
+ }
+ frame = talloc_stackframe();
+
+ acl_wrapper.default_acl = NULL;
+
+ acl_wrapper.access_acl = smb_vfs_call_sys_acl_get_file(handle, fsp->fsp_name->base_name,
+ SMB_ACL_TYPE_ACCESS, frame);
+
+ ret = smb_vfs_call_fstat(handle, fsp, &sbuf);
+ if (ret == -1) {
+ TALLOC_FREE(frame);
+ return -1;
+ }
+
+ acl_wrapper.owner = sbuf.st_ex_uid;
+ acl_wrapper.group = sbuf.st_ex_gid;
+ acl_wrapper.mode = sbuf.st_ex_mode;
+
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_struct_blob(blob, mem_ctx,
+ &acl_wrapper,
+ (ndr_push_flags_fn_t)ndr_push_smb_acl_wrapper))) {
+ errno = EINVAL;
+ TALLOC_FREE(frame);
+ return -1;
+ }
+
+ *blob_description = talloc_strdup(mem_ctx, "posix_acl");
+ if (!*blob_description) {
+ errno = EINVAL;
+ TALLOC_FREE(frame);
+ return -1;
+ }
+
+ TALLOC_FREE(frame);
+ return 0;
+}