public static extern bool AuthzInitializeContextFromSid(
     AuthzInitFlags flags,
     byte[] rawUserSid,
     SafeAuthzRMHandle authzRM,
     PLARGE_INTEGER expirationTime,
     LUID Identifier,
     LPVOID DynamicGroupArgs,
     out SafeAuthzContextHandle authzClientContext);
 public static extern bool AuthzAccessCheck(
     AuthzACFlags flags,
     SafeAuthzContextHandle hAuthzClientContext,
     ref AUTHZ_ACCESS_REQUEST pRequest,
     AUTHZ_AUDIT_EVENT_HANDLE AuditEvent,
     byte[] rawSecurityDescriptor,
     PSECURITY_DESCRIPTOR[] OptionalSecurityDescriptorArray,
     DWORD OptionalSecurityDescriptorCount,
     ref AUTHZ_ACCESS_REPLY pReply,
     AUTHZ_ACCESS_CHECK_RESULTS_HANDLE cachedResults);
        public ACCESS_MASK ComputeAccess(RawSecurityDescriptor descriptor, IdentityReference identity)
        {
            var accessGranted = ACCESS_MASK.NONE;

            // Create the Resource Manager
            using (SafeAuthzRMHandle authzRM = InitializeResourceManager())
                using (SafeAuthzContextHandle userClientCtxt = InitializeContextFromSid(authzRM, identity))
                {
                    accessGranted = AccessCheck(userClientCtxt, descriptor);
                }

            return(accessGranted);
        }
        /// <summary>
        /// Initializes a new instance of the AuthorizationContext class
        /// </summary>
        /// <param name="accessToken">The access token of the principal to build the authorization context for</param>
        /// <param name="server">The remote server to use to build the authorization context</param>
        /// <param name="allowLocalFallback">A value that indicates if automatically falling back to the local server is allowed if the remote context fails to be established. If fallback occurs, the context will be initialized with the <see cref="Server"/> field set to null</param>
        /// <param name="flags">The initialization flags used to build the context</param>
        public AuthorizationContext(SafeAccessTokenHandle accessToken, string server, bool allowLocalFallback, AuthzInitFlags flags)
        {
            this.authzRm           = InitializeResourceManager(server, allowLocalFallback, out bool localFallbackOccurred);
            this.SecurityIdentifer = GetSecurityIdentifierFromAccessToken(accessToken.DangerousGetHandle());

            if (localFallbackOccurred)
            {
                this.Server = null;
            }
            else
            {
                this.Server = server;
            }

            this.authzContext = InitializeAuthorizationContextFromToken(this.authzRm, accessToken, flags);
        }
        private ACCESS_MASK AccessCheck(SafeAuthzContextHandle userClientCtxt, RawSecurityDescriptor descriptor)
        {
            ACCESS_MASK accessGranted;

            // Prepare the Access Check request
            var request = new NativeMethods.AUTHZ_ACCESS_REQUEST();

            request.DesiredAccess        = ACCESS_MASK.MAXIMUM_ALLOWED;
            request.PrincipalSelfSid     = null;
            request.ObjectTypeList       = IntPtr.Zero;
            request.ObjectTypeListLength = 0;
            request.OptionalArguments    = IntPtr.Zero;


            using (var grantedAccessBuffer = SafeAllocation.Create <ACCESS_MASK>())
                using (var errorBuffer = SafeAllocation.Create <uint>())
                {
                    // Prepare the access check reply
                    var reply = new NativeMethods.AUTHZ_ACCESS_REPLY();
                    reply.ResultListLength      = 1;
                    reply.SaclEvaluationResults = IntPtr.Zero;
                    reply.GrantedAccessMask     = grantedAccessBuffer.DangerousGetHandle();
                    reply.Error = errorBuffer.DangerousGetHandle();


                    var rawSD = new byte[descriptor.BinaryLength];
                    descriptor.GetBinaryForm(rawSD, 0);

                    if (!NativeMethods.AuthzAccessCheck(
                            NativeMethods.AuthzACFlags.None,
                            userClientCtxt,
                            ref request,
                            IntPtr.Zero,
                            rawSD,
                            null,
                            0,
                            ref reply,
                            IntPtr.Zero))
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    accessGranted = grantedAccessBuffer.ToStructure();
                }

            return(accessGranted);
        }
        /// <summary>
        /// Initializes a new instance of the AuthorizationContext class
        /// </summary>
        /// <param name="principal">The security identifier of the principal to build the authorization context for</param>
        /// <param name="server">The remote server to use to build the authorization context</param>
        /// <param name="allowLocalFallback">A value that indicates if automatically falling back to the local server is allowed if the remote context fails to be established. If fallback occurs, the context will be initialized with the <see cref="Server"/> field set to null</param>
        /// <param name="flags">The initialization flags used to build the context</param>
        public AuthorizationContext(SecurityIdentifier principal, string server, bool allowLocalFallback, AuthzInitFlags flags)
        {
            this.SecurityIdentifer = principal;

            this.authzRm = InitializeResourceManager(server, allowLocalFallback, out bool localFallbackOccurred);

            if (localFallbackOccurred)
            {
                this.Server = null;
            }
            else
            {
                this.Server = server;
            }

            this.authzContext = InitializeAuthorizationContextFromSid(this.authzRm, this.SecurityIdentifer, flags);
        }
        private ACCESS_MASK AccessCheck(SafeAuthzContextHandle userClientCtxt, RawSecurityDescriptor descriptor)
        {
            ACCESS_MASK accessGranted;

            // Prepare the Access Check request
            var request = new NativeMethods.AUTHZ_ACCESS_REQUEST();
            request.DesiredAccess = ACCESS_MASK.MAXIMUM_ALLOWED;
            request.PrincipalSelfSid = null;
            request.ObjectTypeList = IntPtr.Zero;
            request.ObjectTypeListLength = 0;
            request.OptionalArguments = IntPtr.Zero;

            using (var grantedAccessBuffer = SafeAllocation.Create<ACCESS_MASK>())
            using (var errorBuffer = SafeAllocation.Create<uint>())
            {
                // Prepare the access check reply
                var reply = new NativeMethods.AUTHZ_ACCESS_REPLY();
                reply.ResultListLength = 1;
                reply.SaclEvaluationResults = IntPtr.Zero;
                reply.GrantedAccessMask = grantedAccessBuffer.DangerousGetHandle();
                reply.Error = errorBuffer.DangerousGetHandle();

                var rawSD = new byte[descriptor.BinaryLength];
                descriptor.GetBinaryForm(rawSD, 0);

                if (!NativeMethods.AuthzAccessCheck(
                    NativeMethods.AuthzACFlags.None,
                    userClientCtxt,
                    ref request,
                    IntPtr.Zero,
                    rawSD,
                    null,
                    0,
                    ref reply,
                    IntPtr.Zero))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                accessGranted = grantedAccessBuffer.ToStructure();
            }

            return accessGranted;
        }