/// <summary> /// Construct DIGEST_VALIDATION_RESP structure from Dpsp pass-through validation data /// returned from domain controller. /// </summary> /// <param name="validationInfo">validation information /// returned from domain controller in Dpsp pass-through authentication /// </param> /// <returns>DIGEST_VALIDATION_RESP structure</returns> /// <exception cref="ArgumentException"> /// throw when validationInfo input is invalid. /// </exception> public static DIGEST_VALIDATION_RESP ConvertDataToDigestValidationResponse(_NETLOGON_VALIDATION validationInfo) { if (validationInfo.ValidationGeneric2 == null) { throw new ArgumentException( "ValidationGeneric2 array should not be null", "validationInfo"); } if (validationInfo.ValidationGeneric2[0].ValidationData == null) { throw new ArgumentException( "ValidationData byte array in ValidationGeneric2 should not be null", "validationInfo"); } DIGEST_VALIDATION_RESP digestValidationResp = new DIGEST_VALIDATION_RESP(); byte[] validationData = validationInfo.ValidationGeneric2[0].ValidationData; using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(validationData))) { digestValidationResp.MessageType = (MessageType_Values)binaryReader.ReadInt32(); digestValidationResp.Version = (Version_Values)binaryReader.ReadInt16(); digestValidationResp.Pad2 = (Pad2_Values)binaryReader.ReadInt16(); digestValidationResp.Status = (uint)binaryReader.ReadInt32(); digestValidationResp.SessionKeyLength = (ushort)binaryReader.ReadInt16(); digestValidationResp.Pad3 = (Pad3_Values)binaryReader.ReadInt16(); digestValidationResp.AuthDataSize = (uint)binaryReader.ReadInt32(); digestValidationResp.AcctNameSize = (ushort)binaryReader.ReadInt16(); digestValidationResp.Reserved1 = (Reserved1_Values)binaryReader.ReadInt16(); digestValidationResp.MessageSize = (uint)binaryReader.ReadInt32(); digestValidationResp.Reserved3 = (Reserved3_Values)binaryReader.ReadInt32(); digestValidationResp.SessionKey = binaryReader.ReadBytes(DIGEST_SESSION_KEY_LENGTH); digestValidationResp.SessionKey_NULL_terminator = (SessionKey_NULL_terminator_Values)binaryReader.ReadByte(); digestValidationResp.Pad4 = new Pad4_Values[DIGEST_VALIDATION_RESPONSE_PAD4_LENGTH]; byte[] pad4Data = binaryReader.ReadBytes(DIGEST_VALIDATION_RESPONSE_PAD4_LENGTH); for (int i = 0; i < DIGEST_VALIDATION_RESPONSE_PAD4_LENGTH; i++) { digestValidationResp.Pad4[i] = (Pad4_Values)pad4Data[i]; } digestValidationResp.Pad1 = (Pad1_Values)binaryReader.ReadInt64(); digestValidationResp.AuthData = binaryReader.ReadBytes((int)digestValidationResp.AuthDataSize); digestValidationResp.AccountName = binaryReader.ReadBytes((int)digestValidationResp.AcctNameSize); } return digestValidationResp; }
/// <summary> /// The NetrLogonSamLogonWithFlags method Supported in windows_xpwindows_server_2003, /// windows_vista, windows_server_2008, windows_7, and /// windows_server_7. handles logon requests for the SAM /// accounts. Opnum: 45 /// </summary> /// <param name="LogonServer"> /// The custom RPC binding handle, as specified in section /// . /// </param> /// <param name="ComputerName"> /// The Unicode string that contains the NetBIOS name of /// the client computer calling this method. /// </param> /// <param name="Authenticator"> /// A pointer to a NETLOGON_AUTHENTICATOR structure, as /// specified in section , that contains the client authenticator. /// </param> /// <param name="ReturnAuthenticator"> /// A pointer to a NETLOGON_AUTHENTICATOR structure, as /// specified in section , that contains the server return /// authenticator. /// </param> /// <param name="LogonLevel"> /// A NETLOGON_LOGON_INFO_CLASS structure, as specified /// in section , that specifies the type of logon information /// passed in the LogonInformation parameter. /// </param> /// <param name="LogonInformation"> /// A pointer to a NETLOGON_LEVEL structure, as specified /// in section , that describes the logon request information. /// </param> /// <param name="ValidationLevel"> /// A NETLOGON_VALIDATION_INFO_CLASS enumerated type, as /// specified in section , that contains the validation /// level requested by the client. /// </param> /// <param name="ValidationInformation"> /// A pointer to a NETLOGON_VALIDATION structure, as specified /// in section , that describes the user validation information /// returned to the client. The type of the NETLOGON_VALIDATION /// used is determined by the value of the ValidationLevel /// parameter. /// </param> /// <param name="Authoritative"> /// A pointer to a char value representing a Boolean condition. /// FALSE is indicated by the value 0x00; TRUE SHOULD be /// indicated by the value 0x01 and MAY also be indicated /// by any nonzero value. Windows uses the value of 0x01 /// as the representation of TRUE and 0x00 for FALSE. This /// Boolean value indicates whether the validation information /// is final. This field is necessary because the request /// might be forwarded through multiple servers. A value /// of TRUE indicates that the validation information is /// final and MUST remain unchanged. /// </param> /// <param name="ExtraFlags"> /// A pointer to a set of bit flags that specify delivery /// settings. A flag is TRUE (or set) if its value is equal /// to 1. The value is constructed from zero or more bit /// flags from the following table. /// </param> public NtStatus NetrLogonSamLogonWithFlags( string LogonServer, string ComputerName, _NETLOGON_AUTHENTICATOR? Authenticator, ref _NETLOGON_AUTHENTICATOR? ReturnAuthenticator, _NETLOGON_LOGON_INFO_CLASS LogonLevel, _NETLOGON_LEVEL? LogonInformation, _NETLOGON_VALIDATION_INFO_CLASS ValidationLevel, out _NETLOGON_VALIDATION? ValidationInformation, out byte? Authoritative, ref uint? ExtraFlags) { const ushort opnum = 45; byte[] requestStub; byte[] responseStub; Int3264[] paramList; int retVal; SafeIntPtr pLogonServer = Marshal.StringToHGlobalUni(LogonServer); SafeIntPtr pComputerName = Marshal.StringToHGlobalUni(ComputerName); SafeIntPtr pAuthenticator = TypeMarshal.ToIntPtr(Authenticator); SafeIntPtr pReturnAuthenticatorIn = TypeMarshal.ToIntPtr(ReturnAuthenticator); SafeIntPtr pLogonInformation = TypeMarshal.ToIntPtr(LogonInformation, LogonLevel, null, null); SafeIntPtr pExtraFlags = TypeMarshal.ToIntPtr(ExtraFlags); paramList = new Int3264[] { pLogonServer, pComputerName, pAuthenticator, pReturnAuthenticatorIn, (uint)LogonLevel, pLogonInformation, (uint)ValidationLevel, IntPtr.Zero, IntPtr.Zero, pExtraFlags, 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 pReturnAuthenticatorOut = outParamList[3]; ReturnAuthenticator = TypeMarshal.ToNullableStruct<_NETLOGON_AUTHENTICATOR>(pReturnAuthenticatorOut); IntPtr pValidationInformation = outParamList[7]; ValidationInformation = TypeMarshal.ToNullableStruct<_NETLOGON_VALIDATION>( pValidationInformation, ValidationLevel, null, null); Authoritative = TypeMarshal.ToNullableStruct<byte>(outParamList[8]); ExtraFlags = TypeMarshal.ToNullableStruct<uint>(outParamList[9]); retVal = outParamList[10].ToInt32(); } pLogonServer.Dispose(); pComputerName.Dispose(); pAuthenticator.Dispose(); pReturnAuthenticatorIn.Dispose(); pLogonInformation.Dispose(); pExtraFlags.Dispose(); return (NtStatus)retVal; }
/// <summary> /// The NetrLogonSamLogonWithFlags method Supported in windows_xpwindows_server_2003, /// windows_vista, windows_server_2008, windows_7, and /// windows_server_7. handles logon requests for the SAM /// accounts. Opnum: 45 /// </summary> /// <param name="logonServer"> /// The custom RPC binding handle. /// </param> /// <param name="computerName"> /// The Unicode string that contains the NetBIOS name of /// the client computer calling this method. /// </param> /// <param name="authenticator"> /// A pointer to a NETLOGON_AUTHENTICATOR structure, /// that contains the client authenticator. /// </param> /// <param name="returnAuthenticator"> /// A pointer to a NETLOGON_AUTHENTICATOR structure, /// that contains the server return /// authenticator. /// </param> /// <param name="logonLevel"> /// A NETLOGON_LOGON_INFO_CLASS structure, /// that specifies the type of logon information /// passed in the LogonInformation parameter. /// </param> /// <param name="logonInformation"> /// A pointer to a NETLOGON_LEVEL structure, /// that describes the logon request information. /// </param> /// <param name="validationLevel"> /// A NETLOGON_VALIDATION_INFO_CLASS enumerated type, /// that contains the validation /// level requested by the client. /// </param> /// <param name="validationInformation"> /// A pointer to a NETLOGON_VALIDATION structure, /// that describes the user validation information /// returned to the client. The type of the NETLOGON_VALIDATION /// used is determined by the value of the ValidationLevel /// parameter. /// </param> /// <param name="authoritative"> /// A pointer to a char value representing a Boolean condition. /// FALSE is indicated by the value 0x00; TRUE SHOULD be /// indicated by the value 0x01 and MAY also be indicated /// by any nonzero value. Windows uses the value of 0x01 /// as the representation of TRUE and 0x00 for FALSE. This /// Boolean value indicates whether the validation information /// is final. This field is necessary because the request /// might be forwarded through multiple servers. A value /// of TRUE indicates that the validation information is /// final and MUST remain unchanged. /// </param> /// <param name="extraFlags"> /// A pointer to a set of bit flags that specify delivery /// settings. A flag is TRUE (or set) if its value is equal /// to 1. The value is constructed from zero or more bit /// flags from the following table. /// </param> /// <returns> /// The method returns 0x00000000 on success; /// otherwise, it returns a nonzero error code. /// </returns> public NtStatus NetrLogonSamLogonWithFlags( string logonServer, string computerName, _NETLOGON_AUTHENTICATOR? authenticator, ref _NETLOGON_AUTHENTICATOR? returnAuthenticator, _NETLOGON_LOGON_INFO_CLASS logonLevel, _NETLOGON_LEVEL? logonInformation, _NETLOGON_VALIDATION_INFO_CLASS validationLevel, out _NETLOGON_VALIDATION? validationInformation, out byte? authoritative, ref NrpcNetrLogonSamLogonExtraFlags? extraFlags) { uint? flags = (uint?)extraFlags; NtStatus status = rpc.NetrLogonSamLogonWithFlags( logonServer, computerName, authenticator, ref returnAuthenticator, logonLevel, logonInformation, validationLevel, out validationInformation, out authoritative, ref flags); context.ConnectionStatus = status; extraFlags = (NrpcNetrLogonSamLogonExtraFlags?)flags; return status; }
/// <summary> /// The NetrLogonSamLogonEx method Supported in windows_2000_server, /// windows_xp, windows_server_2003, windows_vista, windows_server_2008, /// windows_7, and windows_server_7. provides an extension /// to NetrLogonSamLogon that accepts an extra flags parameter /// and uses Secure RPC ([MS-RPCE]) instead of /// Netlogon authenticators. This method handles logon /// requests for the SAM accounts and allows for generic /// pass-through authentication. /// For more information about fields and structures /// used by Netlogon pass-through methods. /// Opnum: 39 /// </summary> /// <param name="contextHandle"> /// A primitive RPC handle that identifies a particular /// client/server binding. /// </param> /// <param name="logonServer"> /// The null-terminated Unicode string that contains the /// NetBIOS name of the server that will handle the logon /// request. /// </param> /// <param name="computerName"> /// The null-terminated Unicode string that contains the /// NetBIOS name of the client computer sending the logon /// request. /// </param> /// <param name="logonLevel"> /// A NETLOGON_LOGON_INFO_CLASS structure, /// that specifies the type of the logon information /// passed in the LogonInformation parameter. /// </param> /// <param name="logonInformation"> /// A pointer to a NETLOGON_LEVEL structure, /// that describes the logon request information. /// </param> /// <param name="validationLevel"> /// A NETLOGON_VALIDATION_INFO_CLASS enumerated type, /// that contains the validation /// level requested by the client. /// </param> /// <param name="validationInformation"> /// A pointer to a NETLOGON_VALIDATION structure, /// that describes the user validation information /// returned to the client. The type of the NETLOGON_VALIDATION /// used is determined by the value of the ValidationLevel /// parameter. /// </param> /// <param name="authoritative"> /// A pointer to a char value that represents a Boolean /// condition. FALSE is indicated by the value 0x00, and /// TRUE SHOULDwindows uses the value 0x01 as the representation /// of TRUE and 0x00 for FALSE. be indicated by the value /// 0x01 and MAY also be indicated by any nonzero value. /// This Boolean value indicates whether the validation /// information is final. This field is necessary because /// the request might be forwarded through multiple servers. /// The value TRUE indicates that the validation information /// is final and MUST remain unchanged. The Authoritative /// parameter indicates whether the response to this call /// is final or if the same request can be sent to another /// server. The value SHOULD be set to FALSE if the server /// encounters a transient error, and the client can resend /// the request to another server. If the same request /// is known to fail in all subsequent requests, the server /// SHOULD return TRUE. /// </param> /// <param name="extraFlags"> /// A pointer to a set of bit flags that specify delivery /// settings. A flag is TRUE (or set) if its value is equal /// to 1. Output flags MUST be the same as input. The value /// is constructed from zero or more bit flags from the /// following table. /// </param> /// <returns> /// The method returns 0x00000000 on success; /// otherwise, it returns a nonzero error code. /// </returns> public NtStatus NetrLogonSamLogonEx( IntPtr contextHandle, string logonServer, string computerName, _NETLOGON_LOGON_INFO_CLASS logonLevel, _NETLOGON_LEVEL? logonInformation, _NETLOGON_VALIDATION_INFO_CLASS validationLevel, out _NETLOGON_VALIDATION? validationInformation, out byte? authoritative, ref NrpcNetrLogonSamLogonExtraFlags? extraFlags) { uint? flags = (uint?)extraFlags; NtStatus status = rpc.NetrLogonSamLogonEx( contextHandle, logonServer, computerName, logonLevel, logonInformation, validationLevel, out validationInformation, out authoritative, ref flags); context.ConnectionStatus = status; extraFlags = (NrpcNetrLogonSamLogonExtraFlags?)flags; return status; }
/// <summary> /// The NetrLogonSamLogon method This method was used in /// windows_nt_4_0. It was superseded by the NetrLogonSamLogonWithFlags /// method in windows_2000_server, windows_xp, /// windows_server_2003, windows_vista, and windows_server_2008, /// windows_7, and windows_server_7. is a predecessor to /// the NetrLogonSamLogonWithFlags method. All /// parameters of this method have the same meanings as /// the identically named parameters of the NetrLogonSamLogonWithFlags /// method. Opnum: 2 /// </summary> /// <param name="logonServer"> /// LogonServer parameter. /// </param> /// <param name="computerName"> /// ComputerName parameter. /// </param> /// <param name="authenticator"> /// Authenticator parameter. /// </param> /// <param name="returnAuthenticator"> /// ReturnAuthenticator parameter. /// </param> /// <param name="logonLevel"> /// LogonLevel parameter. /// </param> /// <param name="logonInformation"> /// LogonInformation parameter. /// </param> /// <param name="validationLevel"> /// ValidationLevel parameter. /// </param> /// <param name="validationInformation"> /// ValidationInformation parameter. /// </param> /// <param name="authoritative"> /// Authoritative parameter. /// </param> /// <returns> /// The method returns 0x00000000 on success; /// otherwise, it returns a nonzero error code. /// </returns> public NtStatus NetrLogonSamLogon( string logonServer, string computerName, _NETLOGON_AUTHENTICATOR? authenticator, ref _NETLOGON_AUTHENTICATOR? returnAuthenticator, _NETLOGON_LOGON_INFO_CLASS logonLevel, _NETLOGON_LEVEL? logonInformation, _NETLOGON_VALIDATION_INFO_CLASS validationLevel, out _NETLOGON_VALIDATION? validationInformation, out byte? authoritative) { NtStatus status = rpc.NetrLogonSamLogon( logonServer, computerName, authenticator, ref returnAuthenticator, logonLevel, logonInformation, validationLevel, out validationInformation, out authoritative); //ConnectionStatus: A 4-byte value that contains the most recent //connection status return value (section 3.4.5.3.1) last returned //during secure channel establishment or by a method requiring //session key establishment (section 3.1.4.6). context.ConnectionStatus = status; return status; }
/// <summary> /// Decrypt a _NETLOGON_VALIDATION structure based on /// validationInformation parameter in Nrpc NetrlogonSamLogonXXX API. /// </summary> /// <param name="validationInfoClass"> /// Validation Info Class /// </param> /// <param name="validationInformation"> /// Validation info returned from NetrlogonSamLogonXXX API /// </param> /// <returns>Decrypted _NETLOGON_VALIDATION data structure</returns> /// <exception cref="InvalidOperationException"> /// Thrown when the method is called before establishing a NRPC secure channel. /// </exception>> /// <exception cref="ArgumentException"> /// Thrown when input invalid validationInformation argument /// </exception>> public _NETLOGON_VALIDATION DecryptNetlogonValidation( _NETLOGON_VALIDATION_INFO_CLASS validationInfoClass, _NETLOGON_VALIDATION validationInformation) { ValidateSecureChannelExists(); switch (validationInfoClass) { case _NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationGenericInfo: case _NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationGenericInfo2: //If the LogonLevel is NetlogonGenericInformation, //then encrypt<104> the LogonData member in the //NETLOGON_GENERIC_INFO structure. if (validationInformation.ValidationGeneric2 == null || validationInformation.ValidationGeneric2.Length != 1) { throw new ArgumentException("validationInformation is invalid.", "validationInformation"); } if (validationInformation.ValidationGeneric2[0].ValidationData == null) { throw new ArgumentException("validationInformation is invalid.", "validationInformation"); } validationInformation.ValidationGeneric2[0].ValidationData = NrpcUtility.DecryptBuffer( (context.NegotiateFlags & NrpcNegotiateFlags.SupportsAESAndSHA2) == NrpcNegotiateFlags.SupportsAESAndSHA2, context.SessionKey, validationInformation.ValidationGeneric2[0].ValidationData); break; //If the LogonLevel is NetlogonNetworkInformation or //NetlogonNetworkTransitiveInformation, then encrypt the //UserSessionKey and the first two elements of the //ExpansionRoom array in the NETLOGON_VALIDATION_SAM_INFO //(section 2.2.1.4.11) or in the NETLOGON_VALIDATION_SAM_INFO2 //(section 2.2.1.4.12) structure. case _NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo: if (validationInformation.ValidationSam == null || validationInformation.ValidationSam.Length != 1) { throw new ArgumentException("validationInformation is invalid.", "validationInformation"); } validationInformation.ValidationSam[0].UserSessionKey = DecryptUserSessionKey(validationInformation.ValidationSam[0].UserSessionKey); validationInformation.ValidationSam[0].ExpansionRoom = DecryptExpansionRoom(validationInformation.ValidationSam[0].ExpansionRoom); break; case _NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo2: if (validationInformation.ValidationSam2 == null || validationInformation.ValidationSam2.Length != 1) { throw new ArgumentException("validationInformation is invalid.", "validationInformation"); } validationInformation.ValidationSam2[0].UserSessionKey = DecryptUserSessionKey(validationInformation.ValidationSam2[0].UserSessionKey); validationInformation.ValidationSam2[0].ExpansionRoom = DecryptExpansionRoom(validationInformation.ValidationSam2[0].ExpansionRoom); break; case _NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo4: case _NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationUasInfo: // no encrypted field break; default: throw new ArgumentException("validationInfoClass is invalid.", "validationInfoClass"); } return validationInformation; }