/// <summary>
        ///  The NetrServerAuthenticate3 method mutually authenticates
        ///  the client and the server and establishes the session
        ///  key to be used for the secure channel message protection
        ///  between the client and the server. Supported in windows_2000_server,
        ///  windows_xp, windows_server_2003, windows_vista, windows_server_2008,
        ///  windows_7, and windows_server_7. It is called after
        ///  the NetrServerReqChallenge method, as specified in
        ///  section. Opnum: 26 
        /// </summary>
        /// <param name="PrimaryName">
        ///  The custom RPC binding handle, as specified in section
        ///  .
        /// </param>
        /// <param name="AccountName">
        ///  A null-terminated Unicode string that identifies the
        ///  name of the account that contains the secret key (password)
        ///  that is shared between the client and the server, as
        ///  specified in section.In windows, all machine account
        ///  names are the name of the machine with a $ (dollar
        ///  sign) appended. If there is a period at the end of
        ///  the account name, it is ignored during processing.
        /// </param>
        /// <param name="SecureChannelType">
        ///  A NETLOGON_SECURE_CHANNEL_TYPE enumerated value, as
        ///  specified in section , that indicates the type of the
        ///  secure channel being established by this call.
        /// </param>
        /// <param name="ComputerName">
        ///  A null-terminated Unicode string that contains the NetBIOS
        ///  name of the client computer calling this method.
        /// </param>
        /// <param name="ClientCredential">
        ///  A pointer to a NETLOGON_CREDENTIAL structure, as specified
        ///  in section , that contains the supplied client credentials,
        ///  as specified in section.
        /// </param>
        /// <param name="ServerCredential">
        ///  A pointer to a NETLOGON_CREDENTIAL structure, as specified
        ///  in section , that contains the returned server credentials.
        /// </param>
        /// <param name="NegotiateFlags">
        ///  A pointer to a 32-bit set of bit flags that indicate
        ///  features supported. As input, the set of flags are
        ///  those requested by the client and SHOULD be the same
        ///  as ClientCapabilities. As output, they are the bit-wise
        ///  AND of the client's requested capabilities and the
        ///  server's ServerCapabilities. For more details, see
        ///  section.
        /// </param>
        /// <param name="AccountRid">
        ///  A pointer that receives the RID of the account specified
        ///  by the AccountName parameter. (Section  of [MS-ADTS]
        ///  describes how this RID is assigned at account creation
        ///  time.) This value is stored in the AccountRid ADM element
        ///  within the ClientSessionInfo table.
        /// </param>
        public NtStatus NetrServerAuthenticate3(
            string PrimaryName,
            string AccountName,
            _NETLOGON_SECURE_CHANNEL_TYPE SecureChannelType,
            string ComputerName,
            _NETLOGON_CREDENTIAL? ClientCredential,
            out _NETLOGON_CREDENTIAL? ServerCredential,
            ref uint? NegotiateFlags,
            out uint? AccountRid)
        {
            const ushort opnum = 26;

            byte[] requestStub;
            byte[] responseStub;
            Int3264[] paramList;
            int retVal;

            SafeIntPtr pPrimaryName = Marshal.StringToHGlobalUni(PrimaryName);
            SafeIntPtr pAccountName = Marshal.StringToHGlobalUni(AccountName);
            SafeIntPtr pComputerName = Marshal.StringToHGlobalUni(ComputerName);
            SafeIntPtr pClientCredential = TypeMarshal.ToIntPtr(ClientCredential);
            SafeIntPtr pNegotiateFlags = TypeMarshal.ToIntPtr(NegotiateFlags);

            paramList = new Int3264[] {
                pPrimaryName,
                pAccountName,
                (uint)SecureChannelType,
                pComputerName,
                pClientCredential,
                IntPtr.Zero,
                pNegotiateFlags,
                IntPtr.Zero,
                0 // retVal
            };

            requestStub = RpceStubEncoder.ToBytes(
                     RpceStubHelper.GetPlatform(),
                    NrpcRpcStubFormatString.TypeFormatString,
                    new RpceStubExprEval[] { new RpceStubExprEval(logon__NETLOGON_DELTA_USERExprEval_0000) },
                    NrpcRpcStubFormatString.ProcFormatString,
                    NrpcRpcStubFormatString.ProcFormatStringOffsetTable[opnum],
                    true,
                    paramList);

            rpceClientTransport.Call(opnum, requestStub, rpceTimeout, out responseStub);

            using (RpceInt3264Collection outParamList = RpceStubDecoder.ToParamList(
                     RpceStubHelper.GetPlatform(),
                    NrpcRpcStubFormatString.TypeFormatString,
                    new RpceStubExprEval[] { new RpceStubExprEval(logon__NETLOGON_DELTA_USERExprEval_0000) },
                    NrpcRpcStubFormatString.ProcFormatString,
                    NrpcRpcStubFormatString.ProcFormatStringOffsetTable[opnum],
                    true,
                    responseStub,
                    paramList))
            {
                IntPtr pServerCredential = outParamList[5];
                ServerCredential = TypeMarshal.ToNullableStruct<_NETLOGON_CREDENTIAL>(pServerCredential);

                NegotiateFlags = TypeMarshal.ToNullableStruct<uint>(outParamList[6]);

                AccountRid = TypeMarshal.ToNullableStruct<uint>(outParamList[7]);

                retVal = outParamList[8].ToInt32();
            }

            pPrimaryName.Dispose();
            pAccountName.Dispose();
            pComputerName.Dispose();
            pClientCredential.Dispose();
            pNegotiateFlags.Dispose();

            return (NtStatus)retVal;
        }
        /// <summary>
        ///  The NetrServerReqChallenge method receives a client
        ///  challenge and returns a server challenge. Opnum: 4
        ///  
        /// </summary>
        /// <param name="PrimaryName">
        ///  The custom RPC binding handle, as specified in section
        ///  .
        /// </param>
        /// <param name="ComputerName">
        ///  A Unicode string that contains the NetBIOS name of the
        ///  client computer calling this method.
        /// </param>
        /// <param name="ClientChallenge">
        ///  A pointer to a NETLOGON_CREDENTIAL structure, as specified
        ///  in section , that contains the client challenge.
        /// </param>
        /// <param name="ServerChallenge">
        ///  A pointer to a NETLOGON_CREDENTIAL structure, as specified
        ///  in section , that contains the server challenge response.
        /// </param>
        public NtStatus NetrServerReqChallenge(
            string PrimaryName,
            string ComputerName,
            _NETLOGON_CREDENTIAL? ClientChallenge,
            out _NETLOGON_CREDENTIAL? ServerChallenge)
        {
            const ushort opnum = 4;

            byte[] requestStub;
            byte[] responseStub;
            Int3264[] paramList;
            int retVal;

            SafeIntPtr pPrimaryName = Marshal.StringToHGlobalUni(PrimaryName);
            SafeIntPtr pComputerName = Marshal.StringToHGlobalUni(ComputerName);
            SafeIntPtr pClientChallenge = TypeMarshal.ToIntPtr(ClientChallenge);

            paramList = new Int3264[] {
                pPrimaryName,
                pComputerName,
                pClientChallenge,
                IntPtr.Zero,
                0 // retVal
            };

            requestStub = RpceStubEncoder.ToBytes(
                     RpceStubHelper.GetPlatform(),
                    NrpcRpcStubFormatString.TypeFormatString,
                    new RpceStubExprEval[] { new RpceStubExprEval(logon__NETLOGON_DELTA_USERExprEval_0000) },
                    NrpcRpcStubFormatString.ProcFormatString,
                    NrpcRpcStubFormatString.ProcFormatStringOffsetTable[opnum],
                    true,
                    paramList);

            rpceClientTransport.Call(opnum, requestStub, rpceTimeout, out responseStub);

            using (RpceInt3264Collection outParamList = RpceStubDecoder.ToParamList(
                     RpceStubHelper.GetPlatform(),
                    NrpcRpcStubFormatString.TypeFormatString,
                    new RpceStubExprEval[] { new RpceStubExprEval(logon__NETLOGON_DELTA_USERExprEval_0000) },
                    NrpcRpcStubFormatString.ProcFormatString,
                    NrpcRpcStubFormatString.ProcFormatStringOffsetTable[opnum],
                    true,
                    responseStub,
                    paramList))
            {
                IntPtr pServerChallenge = outParamList[3];
                ServerChallenge = TypeMarshal.ToNullableStruct<_NETLOGON_CREDENTIAL>(pServerChallenge);

                retVal = outParamList[4].ToInt32();
            }

            pPrimaryName.Dispose();
            pComputerName.Dispose();
            pClientChallenge.Dispose();

            return (NtStatus)retVal;
        }
        /// <summary>
        ///  The NetrServerReqChallenge method receives a client
        ///  challenge and returns a server challenge. Opnum: 4<para/>
        /// </summary>
        /// <param name="primaryName">
        ///  The custom RPC binding handle.
        /// </param>
        /// <param name="computerName">
        ///  A Unicode string that contains the NetBIOS name of the
        ///  client computer calling this method.
        /// </param>
        /// <param name="clientChallenge">
        ///  A pointer to a NETLOGON_CREDENTIAL structure, 
        ///  that contains the client challenge.
        /// </param>
        /// <param name="serverChallenge">
        ///  A pointer to a NETLOGON_CREDENTIAL structure, 
        ///  that contains the server challenge response.
        /// </param>
        /// <returns>
        /// The method returns 0x00000000 on success; 
        /// otherwise, it returns a nonzero error code.
        /// </returns>
        public NtStatus NetrServerReqChallenge(
            string primaryName,
            string computerName,
            _NETLOGON_CREDENTIAL? clientChallenge,
            out _NETLOGON_CREDENTIAL? serverChallenge)
        {
            context.PrimaryName = primaryName;
            context.ClientComputerName = computerName;
            if (clientChallenge != null)
            {
                context.ClientChallenge = clientChallenge.Value.data;
            }

            NtStatus status = rpc.NetrServerReqChallenge(
                primaryName,
                computerName,
                clientChallenge,
                out serverChallenge);

            context.ConnectionStatus = status;
            if (status == NtStatus.STATUS_SUCCESS && serverChallenge != null)
            {
                context.ServerChallenge = serverChallenge.Value.data;
            }

            return status;
        }
        /// <summary>
        /// Validates the client credential.
        /// </summary>
        /// <param name="sessionKey">the session key negotiated</param>
        /// <param name="negotiateFlags">the negotiation flags</param>
        ///  <param name="clientChallenge">client challenge received</param>
        /// <param name="clientCredentialReceived">the client credential received</param>
        private void ValidateClientCredential(byte[] sessionKey, uint negotiateFlags, byte[] clientChallenge,
            _NETLOGON_CREDENTIAL? clientCredentialReceived)
        {
            if (clientCredentialReceived == null || clientCredentialReceived.Value.data == null)
            {
                throw new InvalidOperationException("Client Credential doesn't match");
            }

            byte[] clientCredentialComputed = NrpcUtility.ComputeNetlogonCredential(sessionKey, negotiateFlags,
                clientChallenge);

            bool compareResult = ArrayUtility.CompareArrays<byte>(clientCredentialReceived.Value.data,
                clientCredentialComputed);

            if (!compareResult)
            {
                throw new InvalidOperationException("Client Credential doesn't match");
            }
            StoredCredential = clientCredentialComputed;
        }
        /// <summary>
        /// Call NetrServerReqChallenge, get necessary information from context.
        /// </summary>
        /// <param name="computerName">
        /// A null-terminated Unicode string that contains the NetBIOS name of 
        /// the client computer calling this method.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Thrown when computerName is null.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// Thrown when server returned an error code.
        /// </exception>
        public void NetrServerReqChallenge(string computerName)
        {
            if (computerName == null)
            {
                throw new ArgumentNullException("computerName");
            }

            _NETLOGON_CREDENTIAL clientChallenge = new _NETLOGON_CREDENTIAL();
            clientChallenge.data = NrpcUtility.GenerateNonce(NrpcUtility.NL_CREDENTIAL_LENGTH);
            _NETLOGON_CREDENTIAL? serverChallenge;

            NtStatus status = NetrServerReqChallenge(
                context.PrimaryName,
                computerName,
                clientChallenge,
                out serverChallenge);

            if (status != NtStatus.STATUS_SUCCESS)
            {
                NrpcUtility.ThrowExceptionOnStatus("NetrServerReqChallenge", (int)status);
            }
        }
        /// <summary>
        ///  The NetrServerAuthenticate3 method mutually authenticates
        ///  the client and the server and establishes the session
        ///  key to be used for the secure channel message protection
        ///  between the client and the server. Supported in windows_2000_server,
        ///  windows_xp, windows_server_2003, windows_vista, windows_server_2008,
        ///  windows_7, and windows_server_7. It is called after
        ///  the NetrServerReqChallenge method.
        ///  Opnum: 26 
        /// </summary>
        /// <param name="primaryName">
        ///  The custom RPC binding handle.
        /// </param>
        /// <param name="accountName">
        ///  A null-terminated Unicode string that identifies the
        ///  name of the account that contains the secret key (password)
        ///  that is shared between the client and the server. 
        ///  In windows, all machine account
        ///  names are the name of the machine with a $ (dollar
        ///  sign) appended. If there is a period at the end of
        ///  the account name, it is ignored during processing.
        /// </param>
        /// <param name="secureChannelType">
        ///  A NETLOGON_SECURE_CHANNEL_TYPE enumerated value, 
        ///  that indicates the type of the
        ///  secure channel being established by this call.
        /// </param>
        /// <param name="computerName">
        ///  A null-terminated Unicode string that contains the NetBIOS
        ///  name of the client computer calling this method.
        /// </param>
        /// <param name="clientCredential">
        ///  A pointer to a NETLOGON_CREDENTIAL structure, 
        ///  that contains the supplied client credentials.
        /// </param>
        /// <param name="serverCredential">
        ///  A pointer to a NETLOGON_CREDENTIAL structure, 
        ///  that contains the returned server credentials.
        /// </param>
        /// <param name="negotiateFlags">
        ///  A pointer to a 32-bit set of bit flags that indicate
        ///  features supported. As input, the set of flags are
        ///  those requested by the client and SHOULD be the same
        ///  as ClientCapabilities. As output, they are the bit-wise
        ///  AND of the client's requested capabilities and the
        ///  server's ServerCapabilities.
        /// </param>
        /// <param name="accountRid">
        ///  A pointer that receives the RID of the account specified
        ///  by the AccountName parameter. ([MS-ADTS]
        ///  describes how this RID is assigned at account creation
        ///  time.) This value is stored in the AccountRid ADM element
        ///  within the ClientSessionInfo table.
        /// </param>
        /// <returns>
        /// The method returns 0x00000000 on success; 
        /// otherwise, it returns a nonzero error code.
        /// </returns>
        public NtStatus NetrServerAuthenticate3(
            string primaryName,
            string accountName,
            _NETLOGON_SECURE_CHANNEL_TYPE secureChannelType,
            string computerName,
            _NETLOGON_CREDENTIAL? clientCredential,
            out _NETLOGON_CREDENTIAL? serverCredential,
            ref NrpcNegotiateFlags? negotiateFlags,
            out uint? accountRid)
        {
            context.PrimaryName = primaryName;
            context.AccountName = accountName;
            context.SecureChannelType = secureChannelType;
            context.ClientComputerName = computerName;
            if (clientCredential != null)
            {
                context.StoredCredential = clientCredential.Value.data;
            }
            if (negotiateFlags != null)
            {
                context.NegotiateFlags = (NrpcNegotiateFlags)negotiateFlags.Value;
            }

            uint? flags = (uint?)negotiateFlags;

            NtStatus status = rpc.NetrServerAuthenticate3(
                primaryName,
                accountName,
                secureChannelType,
                computerName,
                clientCredential,
                out serverCredential,
                ref flags,
                out accountRid);

            context.ConnectionStatus = status;
            if (status == NtStatus.STATUS_SUCCESS)
            {
                negotiateFlags = (NrpcNegotiateFlags?)flags;
                if (negotiateFlags != null)
                {
                    context.NegotiateFlags = (NrpcNegotiateFlags)negotiateFlags.Value;
                }
                if (accountRid != null)
                {
                    context.AccountRid = accountRid.Value;
                }
                if (context.SessionKey == null
                    && context.SharedSecret != null
                    && context.ClientChallenge != null
                    && context.ServerChallenge != null)
                {
                    if ((context.NegotiateFlags & NrpcNegotiateFlags.SupportsAESAndSHA2) != 0)
                    {
                        context.SessionKey = NrpcUtility.ComputeSessionKey(
                            NrpcComputeSessionKeyAlgorithm.HMACSHA256,
                            context.SharedSecret,
                            context.ClientChallenge,
                            context.ServerChallenge);
                    }
                    else if ((context.NegotiateFlags & NrpcNegotiateFlags.SupportsStrongKeys) != 0)
                    {
                        context.SessionKey = NrpcUtility.ComputeSessionKey(
                            NrpcComputeSessionKeyAlgorithm.MD5,
                            context.SharedSecret,
                            context.ClientChallenge,
                            context.ServerChallenge);
                    }
                    else
                    {
                        context.SessionKey = NrpcUtility.ComputeSessionKey(
                            NrpcComputeSessionKeyAlgorithm.DES,
                            context.SharedSecret,
                            context.ClientChallenge,
                            context.ServerChallenge);
                    }
                }
            }

            return status;
        }
        /// <summary>
        /// Call NetrServerAuthenticate3, get necessary information from context.
        /// </summary>
        /// <param name="accountName">
        /// A null-terminated Unicode string that identifies the name of 
        /// the account that contains the secret key (password) that is shared 
        /// between the client and the server.
        /// </param>
        /// <param name="secureChannelType">
        /// A NETLOGON_SECURE_CHANNEL_TYPE enumerated value, 
        /// that indicates the type of the
        /// secure channel being established by this call.
        /// </param>
        /// <param name="clientCapabilities">
        /// A pointer to a 32-bit set of bit flags in little-endian format that 
        /// indicate features supported. As input, the set of flags are those 
        /// requested by the client and SHOULD be the same as ClientCapabilities. 
        /// As output, they are the bit-wise AND of the client's requested capabilities 
        /// and the server's ServerCapabilities.
        /// </param>
        /// <param name="sharedSecret">
        /// An even-numbered sequence of bytes, with no embedded zero values, 
        /// that is a plain-text secret (password) shared between the client and the server.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Thrown when account or sharedSecret is null.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// Thrown when server returned an error code or 
        /// server returned credential validation failed.
        /// </exception>
        public void NetrServerAuthenticate3(
            string accountName,
            _NETLOGON_SECURE_CHANNEL_TYPE secureChannelType,
            ref NrpcNegotiateFlags clientCapabilities,
            string sharedSecret)
        {
            if (accountName == null)
            {
                throw new ArgumentNullException("accountName");
            }
            if (sharedSecret == null)
            {
                throw new ArgumentNullException("sharedSecret");
            }

            context.SharedSecret = sharedSecret;

            NrpcComputeSessionKeyAlgorithm computeSessionKeyAlgorithm;
            NrpcComputeNetlogonCredentialAlgorithm computeNetlogonCredentialAlgorithm;

            if ((clientCapabilities & NrpcNegotiateFlags.SupportsAESAndSHA2) ==
                NrpcNegotiateFlags.SupportsAESAndSHA2)
            {
                computeSessionKeyAlgorithm = NrpcComputeSessionKeyAlgorithm.HMACSHA256;
                computeNetlogonCredentialAlgorithm = NrpcComputeNetlogonCredentialAlgorithm.AES128;
            }
            else if ((clientCapabilities & NrpcNegotiateFlags.SupportsStrongKeys) ==
                NrpcNegotiateFlags.SupportsStrongKeys)
            {
                computeSessionKeyAlgorithm = NrpcComputeSessionKeyAlgorithm.MD5;
                computeNetlogonCredentialAlgorithm = NrpcComputeNetlogonCredentialAlgorithm.DESECB;
            }
            else
            {
                computeSessionKeyAlgorithm = NrpcComputeSessionKeyAlgorithm.DES;
                computeNetlogonCredentialAlgorithm = NrpcComputeNetlogonCredentialAlgorithm.DESECB;
            }

            context.SessionKey = NrpcUtility.ComputeSessionKey(
                computeSessionKeyAlgorithm,
                context.SharedSecret,
                context.ClientChallenge,
                context.ServerChallenge);

            _NETLOGON_CREDENTIAL clientCredential = new _NETLOGON_CREDENTIAL();
            clientCredential.data = NrpcUtility.ComputeNetlogonCredential(
                computeNetlogonCredentialAlgorithm,
                context.ClientChallenge,
                context.SessionKey);

            _NETLOGON_CREDENTIAL? serverCredential;

            NrpcNegotiateFlags? flags = clientCapabilities;
            uint? accountRid;

            NtStatus status = NetrServerAuthenticate3(
                context.PrimaryName,
                accountName,
                secureChannelType,
                context.ClientComputerName,
                clientCredential,
                out serverCredential,
                ref flags,
                out accountRid);

            if (status != NtStatus.STATUS_SUCCESS)
            {
                NrpcUtility.ThrowExceptionOnStatus("NetrServerAuthenticate3", (int)status);
            }
            if (serverCredential == null
                || !ArrayUtility.CompareArrays(
                    serverCredential.Value.data,
                    NrpcUtility.ComputeNetlogonCredential(
                        computeNetlogonCredentialAlgorithm,
                        context.ServerChallenge,
                        context.SessionKey)))
            {
                NrpcUtility.ThrowExceptionOnValidationFail("NetrServerAuthenticate3");
            }
        }
        /// <summary>
        ///  The NetrServerAuthenticate2 method This method was used
        ///  in windows_nt_3_5 and windows_nt_4_0. In windows_2000_server,
        ///  windows_xp, windows_server_2003, windows_vista, windows_server_2008,
        ///  windows_7, and windows_server_7, it was superseded
        ///  by the NetrServerAuthenticate3 method. is
        ///  a predecessor to the NetrServerAuthenticate3 method. 
        ///  All parameters of this method
        ///  have the same meanings as the identically named parameters
        ///  of the NetrServerAuthenticate3 method. Opnum: 15 
        /// </summary>
        /// <param name="primaryName">
        ///  PrimaryName parameter.
        /// </param>
        /// <param name="accountName">
        ///  AccountName parameter.
        /// </param>
        /// <param name="secureChannelType">
        ///  SecureChannelType parameter.
        /// </param>
        /// <param name="computerName">
        ///  ComputerName parameter.
        /// </param>
        /// <param name="clientCredential">
        ///  ClientCredential parameter.
        /// </param>
        /// <param name="serverCredential">
        ///  ServerCredential parameter.
        /// </param>
        /// <param name="negotiateFlags">
        ///  NegotiateFlags parameter.
        /// </param>
        /// <returns>
        /// The method returns 0x00000000 on success; 
        /// otherwise, it returns a nonzero error code.
        /// </returns>
        public NtStatus NetrServerAuthenticate2(
            string primaryName,
            string accountName,
            _NETLOGON_SECURE_CHANNEL_TYPE secureChannelType,
            string computerName,
            _NETLOGON_CREDENTIAL? clientCredential,
            out _NETLOGON_CREDENTIAL? serverCredential,
            ref NrpcNegotiateFlags? negotiateFlags)
        {
            uint? flags = (uint?)negotiateFlags;

            NtStatus status = rpc.NetrServerAuthenticate2(
                primaryName,
                accountName,
                secureChannelType,
                computerName,
                clientCredential,
                out serverCredential,
                ref flags);

            context.ConnectionStatus = status;
            negotiateFlags = (NrpcNegotiateFlags?)flags;
            return status;
        }
        /// <summary>
        ///  The NetrServerAuthenticate method This method was used
        ///  in windows_nt_server_3_1. In windows_nt_server_3_5,
        ///  it was superseded by the NetrServerAuthenticate2 method.
        ///  In windows_2000_server, windows_xp, windows_server_2003,
        ///  windows_vista, windows_server_2008, windows_7, and
        ///  windows_server_7, the NetrServerAuthenticate2 method
        ///  was superseded by the NetrServerAuthenticate3
        ///  method. is a predecessor to the NetrServerAuthenticate3
        ///  method. All parameters of this method have
        ///  the same meanings as the identically named parameters
        ///  of the NetrServerAuthenticate3 method. Opnum: 5 
        /// </summary>
        /// <param name="primaryName">
        ///  PrimaryName parameter.
        /// </param>
        /// <param name="accountName">
        ///  AccountName parameter.
        /// </param>
        /// <param name="secureChannelType">
        ///  SecureChannelType parameter.
        /// </param>
        /// <param name="computerName">
        ///  ComputerName parameter.
        /// </param>
        /// <param name="clientCredential">
        ///  ClientCredential parameter.
        /// </param>
        /// <param name="serverCredential">
        ///  ServerCredential parameter.
        /// </param>
        /// <returns>
        /// The method returns 0x00000000 on success; 
        /// otherwise, it returns a nonzero error code.
        /// </returns>
        public NtStatus NetrServerAuthenticate(
            string primaryName,
            string accountName,
            _NETLOGON_SECURE_CHANNEL_TYPE secureChannelType,
            string computerName,
            _NETLOGON_CREDENTIAL? clientCredential,
            out _NETLOGON_CREDENTIAL? serverCredential)
        {
            NtStatus status = rpc.NetrServerAuthenticate(
                primaryName,
                accountName,
                secureChannelType,
                computerName,
                clientCredential,
                out serverCredential);

            context.ConnectionStatus = status;
            return status;
        }