summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/modules/onefs.h10
-rw-r--r--source3/modules/onefs_acl.c238
-rw-r--r--source3/modules/onefs_system.c2
3 files changed, 183 insertions, 67 deletions
diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h
index 6e5eae3085..e189fc4570 100644
--- a/source3/modules/onefs.h
+++ b/source3/modules/onefs.h
@@ -45,6 +45,14 @@ enum onefs_acl_wire_format
#define PARM_SIMPLE_FILE_SHARING_COMPATIBILITY_MODE_DEFAULT false
#define PARM_CREATOR_OWNER_GETS_FULL_CONTROL "creator owner gets full control"
#define PARM_CREATOR_OWNER_GETS_FULL_CONTROL_DEFAULT true
+#define PARM_UNMAPPABLE_SIDS_DENY_EVERYONE "unmappable sids deny everyone"
+#define PARM_UNMAPPABLE_SIDS_DENY_EVERYONE_DEFAULT false
+#define PARM_UNMAPPABLE_SIDS_IGNORE "ignore unmappable sids"
+#define PARM_UNMAPPABLE_SIDS_IGNORE_DEFAULT false
+#define PARM_UNMAPPABLE_SIDS_IGNORE_LIST "unmappable sids ignore list"
+#define PARM_UNMAPPABLE_SIDS_IGNORE_LIST_DEFAULT NULL
+#define PARM_IGNORE_SACL "ignore sacl"
+#define PARM_IGNORE_SACL_DEFAULT false
/*
* vfs interface handlers
@@ -105,7 +113,7 @@ NTSTATUS onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
* Utility functions
*/
NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd,
- struct ifs_security_descriptor *sd);
+ struct ifs_security_descriptor *sd, int snum);
NTSTATUS onefs_split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
char **pbase, char **pstream);
diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c
index 9258e0cddc..b9ec2d68e0 100644
--- a/source3/modules/onefs_acl.c
+++ b/source3/modules/onefs_acl.c
@@ -35,7 +35,8 @@ const struct enum_list enum_onefs_acl_wire_format[] = {
* Turn SID into UID/GID and setup a struct ifs_identity
*/
static bool
-onefs_sid_to_identity(const DOM_SID *sid, struct ifs_identity *id, bool is_group)
+onefs_sid_to_identity(const DOM_SID *sid, struct ifs_identity *id,
+ bool is_group)
{
enum ifs_identity_type type = IFS_ID_TYPE_LAST+1;
uid_t uid = 0;
@@ -111,18 +112,137 @@ onefs_identity_to_sid(struct ifs_identity *id, DOM_SID *sid)
return true;
}
+static bool
+onefs_og_to_identity(DOM_SID *sid, struct ifs_identity * ident,
+ bool is_group, int snum)
+{
+ const DOM_SID *b_admin_sid = &global_sid_Builtin_Administrators;
+
+ if (!onefs_sid_to_identity(sid, ident, is_group)) {
+ if (!lp_parm_bool(snum, PARM_ONEFS_TYPE,
+ PARM_UNMAPPABLE_SIDS_IGNORE,
+ PARM_UNMAPPABLE_SIDS_IGNORE_DEFAULT)) {
+ DEBUG(3, ("Unresolvable SID (%s) found.\n",
+ sid_string_dbg(sid)));
+ return false;
+ }
+ if (!onefs_sid_to_identity(b_admin_sid, ident, is_group)) {
+ return false;
+ }
+ DEBUG(3, ("Mapping unresolvable owner SID (%s) to Builtin "
+ "Administrators group.\n",
+ sid_string_dbg(sid)));
+ }
+ return true;
+}
+
+static bool
+sid_in_ignore_list(DOM_SID * sid, int snum)
+{
+ const char ** sid_list = NULL;
+ DOM_SID match;
+
+ sid_list = lp_parm_string_list(snum, PARM_ONEFS_TYPE,
+ PARM_UNMAPPABLE_SIDS_IGNORE_LIST,
+ PARM_UNMAPPABLE_SIDS_IGNORE_LIST_DEFAULT);
+
+ /* Fast path a NULL list */
+ if (!sid_list || *sid_list == NULL)
+ return false;
+
+ while (*sid_list) {
+ if (string_to_sid(&match, *sid_list))
+ if (sid_equal(sid, &match))
+ return true;
+ sid_list++;
+ }
+
+ return false;
+}
+
+/**
+ * Convert a trustee to a struct identity
+ */
+static bool
+onefs_samba_ace_to_ace(SEC_ACE * samba_ace, struct ifs_ace * ace,
+ bool *mapped, int snum)
+{
+ struct ifs_identity ident = {.type=IFS_ID_TYPE_LAST, .id.uid=0};
+
+ SMB_ASSERT(ace);
+ SMB_ASSERT(mapped);
+ SMB_ASSERT(samba_ace);
+
+ if (onefs_sid_to_identity(&samba_ace->trustee, &ident, false)) {
+ *mapped = true;
+ } else {
+
+ SMB_ASSERT(ident.id.uid >= 0);
+
+ /* Ignore the sid if it's in the list */
+ if (sid_in_ignore_list(&samba_ace->trustee, snum)) {
+ DEBUG(3, ("Silently failing to set ACE for SID (%s) "
+ "because it is in the ignore sids list\n",
+ sid_string_dbg(&samba_ace->trustee)));
+ *mapped = false;
+ } else if ((samba_ace->type == SEC_ACE_TYPE_ACCESS_DENIED) &&
+ lp_parm_bool(snum, PARM_ONEFS_TYPE,
+ PARM_UNMAPPABLE_SIDS_DENY_EVERYONE,
+ PARM_UNMAPPABLE_SIDS_DENY_EVERYONE_DEFAULT)) {
+ /* If the ace is deny translated to Everyone */
+ DEBUG(3, ("Mapping unresolvable deny ACE SID (%s) "
+ "to Everyone.\n",
+ sid_string_dbg(&samba_ace->trustee)));
+ if (aclu_initialize_identity(&ident,
+ IFS_ID_TYPE_EVERYONE, 0, 0, False) != 0) {
+ DEBUG(2, ("aclu_initialize_identity() "
+ "failed making Everyone\n"));
+ return false;
+ }
+ *mapped = true;
+ } else if (lp_parm_bool(snum, PARM_ONEFS_TYPE,
+ PARM_UNMAPPABLE_SIDS_IGNORE,
+ PARM_UNMAPPABLE_SIDS_IGNORE_DEFAULT)) {
+ DEBUG(3, ("Silently failing to set ACE for SID (%s) "
+ "because it is unresolvable\n",
+ sid_string_dbg(&samba_ace->trustee)));
+ *mapped = false;
+ } else {
+ /* Fail for lack of a better option */
+ return false;
+ }
+ }
+
+ if (*mapped) {
+ if (aclu_initialize_ace(ace, samba_ace->type,
+ samba_ace->access_mask, samba_ace->flags, 0,
+ &ident))
+ return false;
+
+ if ((ace->trustee.type == IFS_ID_TYPE_CREATOR_OWNER ||
+ ace->trustee.type == IFS_ID_TYPE_CREATOR_GROUP) &&
+ nt4_compatible_acls())
+ ace->flags |= SEC_ACE_FLAG_INHERIT_ONLY;
+ }
+
+ return true;
+}
+
/**
* Convert a SEC_ACL to a struct ifs_security_acl
*/
static bool
-onefs_samba_acl_to_acl(SEC_ACL *samba_acl, struct ifs_security_acl **acl)
+onefs_samba_acl_to_acl(SEC_ACL *samba_acl, struct ifs_security_acl **acl,
+ bool * ignore_aces, int snum)
{
int num_aces = 0;
struct ifs_ace *aces = NULL;
- struct ifs_identity temp;
SEC_ACE *samba_aces;
+ bool mapped;
int i, j;
+ SMB_ASSERT(ignore_aces);
+
if ((!acl) || (!samba_acl))
return false;
@@ -134,39 +254,30 @@ onefs_samba_acl_to_acl(SEC_ACL *samba_acl, struct ifs_security_acl **acl)
aces = SMB_MALLOC_ARRAY(struct ifs_ace, num_aces);
for (i = 0, j = 0; j < num_aces; i++, j++) {
- if (!onefs_sid_to_identity(&samba_aces[j].trustee,
- &temp, false))
+ if (!onefs_samba_ace_to_ace(&samba_aces[j],
+ &aces[i], &mapped, snum))
goto err_free;
- /*
- * XXX Act like we did pre-Thai: Silently fail setting
- * ACEs for BUILTIN accounts.
- */
- if (temp.id.uid == -1) {
- DEBUG(3, ("Silently failing to set ACE "
- "because our id was == -1.\n"));
+ if (!mapped)
i--;
- continue;
- }
-
- if (aclu_initialize_ace(&aces[i], samba_aces[i].type,
- samba_aces[i].access_mask, samba_aces[i].flags,
- 0, &temp))
- goto err_free;
-
- if ((aces[i].trustee.type == IFS_ID_TYPE_CREATOR_OWNER ||
- aces[i].trustee.type == IFS_ID_TYPE_CREATOR_GROUP) &&
- nt4_compatible_acls())
- aces[i].flags |= IFS_ACE_FLAG_INHERIT_ONLY;
}
num_aces = i;
}
+ /* If aces are given but we cannot apply them due to the reasons
+ * above we do not change the SD. However, if we are told to
+ * explicitly set an SD with 0 aces we honor this operation */
+ *ignore_aces = samba_acl->num_aces > 0 && num_aces < 1;
+
+ if (*ignore_aces == false)
+ if (aclu_initialize_acl(acl, aces, num_aces))
+ goto err_free;
+
if (aclu_initialize_acl(acl, aces, num_aces))
goto err_free;
- /* Currently aclu_initialize_acl should copy the aces over, allowing us
- * to immediately free */
+ /* Currently aclu_initialize_acl should copy the aces over, allowing
+ * us to immediately free */
free(aces);
return true;
@@ -697,10 +808,11 @@ onefs_get_nt_acl(vfs_handle_struct *handle, const char* name,
* @return NTSTATUS_OK if successful
*/
NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd,
- struct ifs_security_descriptor *sd)
+ struct ifs_security_descriptor *sd, int snum)
{
- struct ifs_security_acl dacl, sacl, *daclp, *saclp;
+ struct ifs_security_acl *daclp, *saclp;
struct ifs_identity owner, group, *ownerp, *groupp;
+ bool ignore_aces;
ownerp = NULL;
groupp = NULL;
@@ -709,58 +821,53 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd,
/* Setup owner */
if (security_info_sent & OWNER_SECURITY_INFORMATION) {
- if (!onefs_sid_to_identity(psd->owner_sid, &owner, false))
+ if (!onefs_og_to_identity(psd->owner_sid, &owner, false, snum))
return NT_STATUS_UNSUCCESSFUL;
- /*
- * XXX Act like we did pre-Thai: Silently fail setting the
- * owner to a BUILTIN account.
- */
- if (owner.id.uid == -1) {
- DEBUG(3, ("Silently failing to set owner because our "
- "id was == -1.\n"));
- security_info_sent &= ~OWNER_SECURITY_INFORMATION;
- if (!security_info_sent)
- return NT_STATUS_OK;
- }
- else
- ownerp = &owner;
+ SMB_ASSERT(owner.id.uid >= 0);
+
+ ownerp = &owner;
}
/* Setup group */
if (security_info_sent & GROUP_SECURITY_INFORMATION) {
- if (!onefs_sid_to_identity(psd->group_sid, &group, true))
+ if (!onefs_og_to_identity(psd->group_sid, &group, true, snum))
return NT_STATUS_UNSUCCESSFUL;
- /*
- * XXX Act like we did pre-Thai: Silently fail setting the
- * group to a BUILTIN account.
- */
- if (group.id.gid == -1) {
- DEBUG(3, ("Silently failing to set group because our "
- "id was == -1.\n"));
- security_info_sent &= ~GROUP_SECURITY_INFORMATION;
- if (!security_info_sent)
- return NT_STATUS_OK;
- }
- else
- groupp = &group;
+ SMB_ASSERT(group.id.gid >= 0);
+
+ groupp = &group;
}
/* Setup DACL */
if ((security_info_sent & DACL_SECURITY_INFORMATION) && (psd->dacl)) {
- daclp = &dacl;
-
- if (!onefs_samba_acl_to_acl(psd->dacl, &daclp))
+ if (!onefs_samba_acl_to_acl(psd->dacl, &daclp, &ignore_aces,
+ snum))
return NT_STATUS_UNSUCCESSFUL;
+
+ if (ignore_aces == true)
+ security_info_sent &= ~DACL_SECURITY_INFORMATION;
}
/* Setup SACL */
- if ((security_info_sent & SACL_SECURITY_INFORMATION) && (psd->sacl)) {
- saclp = &sacl;
-
- if (!onefs_samba_acl_to_acl(psd->sacl, &saclp))
- return NT_STATUS_UNSUCCESSFUL;
+ if (security_info_sent & SACL_SECURITY_INFORMATION) {
+
+ if (lp_parm_bool(snum, PARM_ONEFS_TYPE,
+ PARM_IGNORE_SACL, PARM_IGNORE_SACL_DEFAULT)) {
+ DEBUG(5, ("Ignoring SACLs.\n"));
+ security_info_sent &= ~SACL_SECURITY_INFORMATION;
+ } else {
+ if (psd->sacl) {
+ if (!onefs_samba_acl_to_acl(psd->sacl,
+ &saclp, &ignore_aces, snum))
+ return NT_STATUS_UNSUCCESSFUL;
+
+ if (ignore_aces == true) {
+ security_info_sent &=
+ ~SACL_SECURITY_INFORMATION;
+ }
+ }
+ }
}
/* Setup ifs_security_descriptor */
@@ -789,7 +896,8 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
DEBUG(5,("Setting SD on file %s.\n", fsp->fsp_name ));
- status = onefs_samba_sd_to_sd(security_info_sent, psd, &sd);
+ status = onefs_samba_sd_to_sd(security_info_sent, psd, &sd,
+ SNUM(handle->conn));
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("SD initialization failure: %s", nt_errstr(status)));
diff --git a/source3/modules/onefs_system.c b/source3/modules/onefs_system.c
index ee257d8f90..4ebdf12a50 100644
--- a/source3/modules/onefs_system.c
+++ b/source3/modules/onefs_system.c
@@ -152,7 +152,7 @@ int onefs_sys_create_file(connection_struct *conn,
secinfo = (get_sec_info(sd) & IFS_SEC_INFO_KNOWN_MASK);
- status = onefs_samba_sd_to_sd(secinfo, sd, &ifs_sd);
+ status = onefs_samba_sd_to_sd(secinfo, sd, &ifs_sd, SNUM(conn));
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("SD initialization failure: %s",