示例#1
0
        /// <summary>
        /// Perform an Access Check.
        /// </summary>
        /// <param name="sd">The security descriptor for the check.</param>
        /// <param name="optional_sd">Optional list of security descriptors to merge.</param>
        /// <param name="desired_access">The desired access.</param>
        /// <param name="principal">Optional Principal SID.</param>
        /// <param name="object_types">Optional list of object types.</param>
        /// <param name="type">NT Type for access checking.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The list of access check results.</returns>
        /// <remarks>The list of object types is restricted to 256 entries for remote access checks.</remarks>
        public NtResult <AuthZAccessCheckResult[]> AccessCheck(SecurityDescriptor sd, IEnumerable <SecurityDescriptor> optional_sd,
                                                               AccessMask desired_access, Sid principal, IEnumerable <ObjectTypeEntry> object_types, NtType type,
                                                               bool throw_on_error)
        {
            if (sd is null)
            {
                throw new ArgumentNullException(nameof(sd));
            }

            if (type is null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            using (var list = new DisposableList())
            {
                AUTHZ_ACCESS_REQUEST request = new AUTHZ_ACCESS_REQUEST();
                request.DesiredAccess = desired_access;
                if (principal != null)
                {
                    request.PrincipalSelfSid = list.AddResource(principal.ToSafeBuffer()).DangerousGetHandle();
                }

                int result_count = 1;
                var object_list  = NtSecurity.ConvertObjectTypes(object_types, list);
                if (object_list?.Length > 0)
                {
                    result_count                 = object_list.Length;
                    request.ObjectTypeList       = list.AddResource(object_list.ToBuffer()).DangerousGetHandle();
                    request.ObjectTypeListLength = object_list.Length;
                }
                var      sd_buffer           = list.AddResource(sd.ToSafeBuffer());
                int      optional_sd_count   = optional_sd?.Count() ?? 0;
                IntPtr[] optional_sd_buffers = null;
                if (optional_sd_count > 0)
                {
                    optional_sd_buffers = optional_sd.Select(s => list.AddResource(s.ToSafeBuffer()).DangerousGetHandle()).ToArray();
                }
                AUTHZ_ACCESS_REPLY reply = new AUTHZ_ACCESS_REPLY();
                reply.ResultListLength = result_count;
                var error_buffer = list.AddResource(new int[result_count].ToBuffer());
                reply.Error = error_buffer.DangerousGetHandle();
                var access_buffer = list.AddResource(new AccessMask[result_count].ToBuffer());
                reply.GrantedAccessMask = access_buffer.DangerousGetHandle();
                var audit_buffer = list.AddResource(new int[result_count].ToBuffer());
                reply.SaclEvaluationResults = audit_buffer.DangerousGetHandle();

                return(SecurityNativeMethods.AuthzAccessCheck(AuthZAccessCheckFlags.None, _handle,
                                                              ref request, IntPtr.Zero, sd_buffer, optional_sd_buffers, optional_sd_count,
                                                              ref reply, IntPtr.Zero).CreateWin32Result(throw_on_error,
                                                                                                        () => CreateResult(result_count, error_buffer, access_buffer, object_types?.ToArray(), type)));
            }
        }