static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx,
				    struct security_descriptor **sd,
				    struct dom_sid *sid,
				    uint32_t sid_access)
{
	NTSTATUS status;
	uint32_t rid;
	struct dom_sid *domain_sid, *domain_admins_sid;
	const char *domain_admins_sid_str, *sidstr;
	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);

	status = dom_sid_split_rid(tmp_ctx, sid, &domain_sid, &rid);
	if (!NT_STATUS_IS_OK(status)) {
		TALLOC_FREE(tmp_ctx);
		return status;
	}

	domain_admins_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
	if (domain_admins_sid == NULL) {
		TALLOC_FREE(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	domain_admins_sid_str = dom_sid_string(tmp_ctx, domain_admins_sid);
	if (domain_admins_sid_str == NULL) {
		TALLOC_FREE(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	sidstr = dom_sid_string(tmp_ctx, sid);
	if (sidstr == NULL) {
		TALLOC_FREE(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	*sd = security_descriptor_dacl_create(mem_ctx,
					      0, sidstr, NULL,

					      SID_WORLD,
					      SEC_ACE_TYPE_ACCESS_ALLOWED,
					      SEC_GENERIC_EXECUTE | SEC_GENERIC_READ, 0,

					      SID_BUILTIN_ADMINISTRATORS,
					      SEC_ACE_TYPE_ACCESS_ALLOWED,
					      SEC_GENERIC_ALL, 0,

					      SID_BUILTIN_ACCOUNT_OPERATORS,
					      SEC_ACE_TYPE_ACCESS_ALLOWED,
					      SEC_GENERIC_ALL, 0,

					      domain_admins_sid_str,
					      SEC_ACE_TYPE_ACCESS_ALLOWED,
					      SEC_GENERIC_ALL, 0,

					      sidstr,
					      SEC_ACE_TYPE_ACCESS_ALLOWED,
					      sid_access, 0,

					      NULL);
	talloc_free(tmp_ctx);

	NT_STATUS_HAVE_NO_MEMORY(*sd);

	return NT_STATUS_OK;
}
static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx,
				    struct security_descriptor **sd,
				    struct dom_sid *sid,
				    uint32_t sid_access)
{
	NTSTATUS status;
	uint32_t rid;
	struct dom_sid *domain_sid, *domain_admins_sid;
	const char *domain_admins_sid_str, *sidstr;
	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);

	status = dom_sid_split_rid(tmp_ctx, sid, &domain_sid, &rid);
	if (!NT_STATUS_IS_OK(status)) {
		TALLOC_FREE(tmp_ctx);
		return status;
	}

	domain_admins_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
	if (domain_admins_sid == NULL) {
		TALLOC_FREE(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	domain_admins_sid_str = dom_sid_string(tmp_ctx, domain_admins_sid);
	if (domain_admins_sid_str == NULL) {
		TALLOC_FREE(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	sidstr = dom_sid_string(tmp_ctx, sid);
	if (sidstr == NULL) {
		TALLOC_FREE(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	*sd = security_descriptor_dacl_create(mem_ctx,
					      0, sidstr, NULL,

					      SID_WORLD,
					      SEC_ACE_TYPE_ACCESS_ALLOWED,
					      SEC_GENERIC_EXECUTE | SEC_GENERIC_READ, 0,

					      SID_BUILTIN_ADMINISTRATORS,
					      SEC_ACE_TYPE_ACCESS_ALLOWED,
					      SEC_GENERIC_ALL, 0,

					      SID_BUILTIN_ACCOUNT_OPERATORS,
					      SEC_ACE_TYPE_ACCESS_ALLOWED,
					      SEC_GENERIC_ALL, 0,

					      domain_admins_sid_str,
					      SEC_ACE_TYPE_ACCESS_ALLOWED,
					      SEC_GENERIC_ALL, 0,

					      sidstr,
					      SEC_ACE_TYPE_ACCESS_ALLOWED,
					      sid_access, 0,

					      NULL);
	talloc_free(tmp_ctx);

	NT_STATUS_HAVE_NO_MEMORY(*sd);

	return NT_STATUS_OK;
}