SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, enum security_descriptor_revision revision, uint16 type, const DOM_SID *owner_sid, const DOM_SID *grp_sid, SEC_ACL *sacl, SEC_ACL *dacl, size_t *sd_size) { SEC_DESC *dst; uint32 offset = 0; *sd_size = 0; if(( dst = TALLOC_ZERO_P(ctx, SEC_DESC)) == NULL) return NULL; dst->revision = revision; dst->type = type; if (sacl) dst->type |= SEC_DESC_SACL_PRESENT; if (dacl) dst->type |= SEC_DESC_DACL_PRESENT; dst->owner_sid = NULL; dst->group_sid = NULL; dst->sacl = NULL; dst->dacl = NULL; if(owner_sid && ((dst->owner_sid = sid_dup_talloc(dst,owner_sid)) == NULL)) goto error_exit; if(grp_sid && ((dst->group_sid = sid_dup_talloc(dst,grp_sid)) == NULL)) goto error_exit; if(sacl && ((dst->sacl = dup_sec_acl(dst, sacl)) == NULL)) goto error_exit; if(dacl && ((dst->dacl = dup_sec_acl(dst, dacl)) == NULL)) goto error_exit; offset = SEC_DESC_HEADER_SIZE; /* * Work out the linearization sizes. */ if (dst->sacl != NULL) { offset += dst->sacl->size; } if (dst->dacl != NULL) { offset += dst->dacl->size; } if (dst->owner_sid != NULL) { offset += ndr_size_dom_sid(dst->owner_sid, 0); } if (dst->group_sid != NULL) { offset += ndr_size_dom_sid(dst->group_sid, 0); } *sd_size = (size_t)offset; return dst; error_exit: *sd_size = 0; return NULL; }
static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, uint32_t security_info_sent, const struct security_descriptor *psd) { NTSTATUS status; DATA_BLOB blob; struct security_descriptor *pdesc_next = NULL; uint8_t hash[XATTR_SD_HASH_SIZE]; if (DEBUGLEVEL >= 10) { DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n", fsp_str_dbg(fsp))); NDR_PRINT_DEBUG(security_descriptor, CONST_DISCARD(struct security_descriptor *,psd)); } /* Ensure we have OWNER/GROUP/DACL set. */ if ((security_info_sent & (OWNER_SECURITY_INFORMATION| GROUP_SECURITY_INFORMATION| DACL_SECURITY_INFORMATION)) != (OWNER_SECURITY_INFORMATION| GROUP_SECURITY_INFORMATION| DACL_SECURITY_INFORMATION)) { /* No we don't - read from the existing SD. */ struct security_descriptor *nc_psd = NULL; status = get_nt_acl_internal(handle, fsp, NULL, (OWNER_SECURITY_INFORMATION| GROUP_SECURITY_INFORMATION| DACL_SECURITY_INFORMATION), &nc_psd); if (!NT_STATUS_IS_OK(status)) { return status; } /* This is safe as nc_psd is discarded at fn exit. */ if (security_info_sent & OWNER_SECURITY_INFORMATION) { nc_psd->owner_sid = psd->owner_sid; } security_info_sent |= OWNER_SECURITY_INFORMATION; if (security_info_sent & GROUP_SECURITY_INFORMATION) { nc_psd->group_sid = psd->group_sid; } security_info_sent |= GROUP_SECURITY_INFORMATION; if (security_info_sent & DACL_SECURITY_INFORMATION) { nc_psd->dacl = dup_sec_acl(talloc_tos(), psd->dacl); if (nc_psd->dacl == NULL) { return NT_STATUS_NO_MEMORY; } } security_info_sent |= DACL_SECURITY_INFORMATION; psd = nc_psd; } status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd); if (!NT_STATUS_IS_OK(status)) { return status; } /* Get the full underlying sd, then hash. */ status = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, HASH_SECURITY_INFO, &pdesc_next); if (!NT_STATUS_IS_OK(status)) { return status; } status = hash_sd_sha256(pdesc_next, hash); if (!NT_STATUS_IS_OK(status)) { return status; } if (DEBUGLEVEL >= 10) { DEBUG(10,("fset_nt_acl_xattr: storing xattr sd for file %s\n", fsp_str_dbg(fsp))); NDR_PRINT_DEBUG(security_descriptor, CONST_DISCARD(struct security_descriptor *,psd)); } create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash); store_acl_blob_fsp(handle, fsp, &blob); return NT_STATUS_OK; }