diff options
-rw-r--r-- | source3/modules/onefs.h | 10 | ||||
-rw-r--r-- | source3/modules/onefs_acl.c | 238 | ||||
-rw-r--r-- | source3/modules/onefs_system.c | 2 |
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", |