internal static void VerifyTrust(DirectoryContext context, string sourceName, string targetName, bool isForest, TrustDirection direction, bool forceSecureChannelReset, string preferredTargetServer) { PolicySafeHandle handle = null; LSA_UNICODE_STRING result = null; int errorCode = 0; IntPtr zero = IntPtr.Zero; IntPtr ptr = IntPtr.Zero; IntPtr buffer = IntPtr.Zero; IntPtr ptr4 = IntPtr.Zero; bool flag = true; IntPtr s = IntPtr.Zero; string serverName = null; serverName = System.DirectoryServices.ActiveDirectory.Utils.GetPolicyServerName(context, isForest, false, sourceName); flag = System.DirectoryServices.ActiveDirectory.Utils.Impersonate(context); try { try { handle = new PolicySafeHandle(System.DirectoryServices.ActiveDirectory.Utils.GetPolicyHandle(serverName)); result = new LSA_UNICODE_STRING(); s = Marshal.StringToHGlobalUni(targetName); UnsafeNativeMethods.RtlInitUnicodeString(result, s); ValidateTrust(handle, result, sourceName, targetName, isForest, (int) direction, serverName); if (preferredTargetServer == null) { zero = Marshal.StringToHGlobalUni(targetName); } else { zero = Marshal.StringToHGlobalUni(targetName + @"\" + preferredTargetServer); } ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr))); Marshal.WriteIntPtr(ptr, zero); if (!forceSecureChannelReset) { errorCode = UnsafeNativeMethods.I_NetLogonControl2(serverName, NETLOGON_CONTROL_TC_VERIFY, NETLOGON_QUERY_LEVEL, ptr, out buffer); if (errorCode != 0) { if (errorCode == ERROR_INVALID_LEVEL) { throw new NotSupportedException(Res.GetString("TrustVerificationNotSupport")); } throw ExceptionHelper.GetExceptionFromErrorCode(errorCode); } NETLOGON_INFO_2 structure = new NETLOGON_INFO_2(); Marshal.PtrToStructure(buffer, structure); if ((structure.netlog2_flags & NETLOGON_VERIFY_STATUS_RETURNED) == 0) { throw ExceptionHelper.GetExceptionFromErrorCode(structure.netlog2_tc_connection_status); } int num2 = structure.netlog2_pdc_connection_status; if (num2 != 0) { throw ExceptionHelper.GetExceptionFromErrorCode(num2); } } else { errorCode = UnsafeNativeMethods.I_NetLogonControl2(serverName, NETLOGON_CONTROL_REDISCOVER, NETLOGON_QUERY_LEVEL, ptr, out ptr4); if (errorCode != 0) { throw ExceptionHelper.GetExceptionFromErrorCode(errorCode); } } } finally { if (flag) { System.DirectoryServices.ActiveDirectory.Utils.Revert(); } if (s != IntPtr.Zero) { Marshal.FreeHGlobal(s); } if (ptr != IntPtr.Zero) { Marshal.FreeHGlobal(ptr); } if (zero != IntPtr.Zero) { Marshal.FreeHGlobal(zero); } if (buffer != IntPtr.Zero) { UnsafeNativeMethods.NetApiBufferFree(buffer); } if (ptr4 != IntPtr.Zero) { UnsafeNativeMethods.NetApiBufferFree(ptr4); } } } catch { throw; } }
internal static void VerifyTrust(DirectoryContext context, string sourceName, string targetName, bool isForest, TrustDirection direction, bool forceSecureChannelReset, string preferredTargetServer) { PolicySafeHandle policyHandle = null; LSA_UNICODE_STRING trustedDomainName = null; int win32Error = 0; IntPtr data = (IntPtr)0; IntPtr ptr = (IntPtr)0; IntPtr buffer1 = (IntPtr)0; IntPtr buffer2 = (IntPtr)0; bool impersonated = true; IntPtr target = (IntPtr)0; string policyServerName = null; policyServerName = Utils.GetPolicyServerName(context, isForest, false, sourceName); impersonated = Utils.Impersonate(context); try { try { // get the policy handle policyHandle = new PolicySafeHandle(Utils.GetPolicyHandle(policyServerName)); // get the target name trustedDomainName = new LSA_UNICODE_STRING(); target = Marshal.StringToHGlobalUni(targetName); UnsafeNativeMethods.RtlInitUnicodeString(trustedDomainName, target); // validate the trust existence ValidateTrust(policyHandle, trustedDomainName, sourceName, targetName, isForest, (int)direction, policyServerName); // need to verify direction if (preferredTargetServer == null) data = Marshal.StringToHGlobalUni(targetName); else // this is the case that we need to specifically go to a particular server. This is the way to tell netlogon to do that. data = Marshal.StringToHGlobalUni(targetName + "\\" + preferredTargetServer); ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr))); Marshal.WriteIntPtr(ptr, data); if (!forceSecureChannelReset) { win32Error = UnsafeNativeMethods.I_NetLogonControl2(policyServerName, s_NETLOGON_CONTROL_TC_VERIFY, NETLOGON_QUERY_LEVEL, ptr, out buffer1); if (win32Error == 0) { NETLOGON_INFO_2 info = new NETLOGON_INFO_2(); Marshal.PtrToStructure(buffer1, info); if ((info.netlog2_flags & s_NETLOGON_VERIFY_STATUS_RETURNED) != 0) { int result = info.netlog2_pdc_connection_status; if (result == 0) { // verification succeeded return; } else { // don't really know which server is down, the source or the target throw ExceptionHelper.GetExceptionFromErrorCode(result); } } else { int result = info.netlog2_tc_connection_status; throw ExceptionHelper.GetExceptionFromErrorCode(result); } } else { if (win32Error == s_ERROR_INVALID_LEVEL) { // it is pre-win2k SP3 dc that does not support NETLOGON_CONTROL_TC_VERIFY throw new NotSupportedException(Res.GetString(Res.TrustVerificationNotSupport)); } else { throw ExceptionHelper.GetExceptionFromErrorCode(win32Error); } } } else { // then try secure channel reset win32Error = UnsafeNativeMethods.I_NetLogonControl2(policyServerName, NETLOGON_CONTROL_REDISCOVER, NETLOGON_QUERY_LEVEL, ptr, out buffer2); if (win32Error != 0) // don't really know which server is down, the source or the target throw ExceptionHelper.GetExceptionFromErrorCode(win32Error); } } finally { if (impersonated) Utils.Revert(); if (target != (IntPtr)0) Marshal.FreeHGlobal(target); if (ptr != (IntPtr)0) Marshal.FreeHGlobal(ptr); if (data != (IntPtr)0) Marshal.FreeHGlobal(data); if (buffer1 != (IntPtr)0) UnsafeNativeMethods.NetApiBufferFree(buffer1); if (buffer2 != (IntPtr)0) UnsafeNativeMethods.NetApiBufferFree(buffer2); } } catch { throw; } }
internal static void VerifyTrust(DirectoryContext context, string sourceName, string targetName, bool isForest, TrustDirection direction, bool forceSecureChannelReset, string preferredTargetServer) { PolicySafeHandle handle = null; LSA_UNICODE_STRING result = null; int errorCode = 0; IntPtr zero = IntPtr.Zero; IntPtr ptr = IntPtr.Zero; IntPtr buffer = IntPtr.Zero; IntPtr ptr4 = IntPtr.Zero; bool flag = true; IntPtr s = IntPtr.Zero; string serverName = null; serverName = System.DirectoryServices.ActiveDirectory.Utils.GetPolicyServerName(context, isForest, false, sourceName); flag = System.DirectoryServices.ActiveDirectory.Utils.Impersonate(context); try { try { handle = new PolicySafeHandle(System.DirectoryServices.ActiveDirectory.Utils.GetPolicyHandle(serverName)); result = new LSA_UNICODE_STRING(); s = Marshal.StringToHGlobalUni(targetName); UnsafeNativeMethods.RtlInitUnicodeString(result, s); ValidateTrust(handle, result, sourceName, targetName, isForest, (int)direction, serverName); if (preferredTargetServer == null) { zero = Marshal.StringToHGlobalUni(targetName); } else { zero = Marshal.StringToHGlobalUni(targetName + @"\" + preferredTargetServer); } ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr))); Marshal.WriteIntPtr(ptr, zero); if (!forceSecureChannelReset) { errorCode = UnsafeNativeMethods.I_NetLogonControl2(serverName, NETLOGON_CONTROL_TC_VERIFY, NETLOGON_QUERY_LEVEL, ptr, out buffer); if (errorCode != 0) { if (errorCode == ERROR_INVALID_LEVEL) { throw new NotSupportedException(Res.GetString("TrustVerificationNotSupport")); } throw ExceptionHelper.GetExceptionFromErrorCode(errorCode); } NETLOGON_INFO_2 structure = new NETLOGON_INFO_2(); Marshal.PtrToStructure(buffer, structure); if ((structure.netlog2_flags & NETLOGON_VERIFY_STATUS_RETURNED) == 0) { throw ExceptionHelper.GetExceptionFromErrorCode(structure.netlog2_tc_connection_status); } int num2 = structure.netlog2_pdc_connection_status; if (num2 != 0) { throw ExceptionHelper.GetExceptionFromErrorCode(num2); } } else { errorCode = UnsafeNativeMethods.I_NetLogonControl2(serverName, NETLOGON_CONTROL_REDISCOVER, NETLOGON_QUERY_LEVEL, ptr, out ptr4); if (errorCode != 0) { throw ExceptionHelper.GetExceptionFromErrorCode(errorCode); } } } finally { if (flag) { System.DirectoryServices.ActiveDirectory.Utils.Revert(); } if (s != IntPtr.Zero) { Marshal.FreeHGlobal(s); } if (ptr != IntPtr.Zero) { Marshal.FreeHGlobal(ptr); } if (zero != IntPtr.Zero) { Marshal.FreeHGlobal(zero); } if (buffer != IntPtr.Zero) { UnsafeNativeMethods.NetApiBufferFree(buffer); } if (ptr4 != IntPtr.Zero) { UnsafeNativeMethods.NetApiBufferFree(ptr4); } } } catch { throw; } }
internal static void VerifyTrust(DirectoryContext context, string sourceName, string targetName, bool isForest, TrustDirection direction, bool forceSecureChannelReset, string preferredTargetServer) { int num; IntPtr hGlobalUni = (IntPtr)0; IntPtr intPtr = (IntPtr)0; IntPtr intPtr1 = (IntPtr)0; IntPtr intPtr2 = (IntPtr)0; IntPtr hGlobalUni1 = (IntPtr)0; string policyServerName = Utils.GetPolicyServerName(context, isForest, false, sourceName); bool flag = Utils.Impersonate(context); try { try { PolicySafeHandle policySafeHandle = new PolicySafeHandle(Utils.GetPolicyHandle(policyServerName)); LSA_UNICODE_STRING lSAUNICODESTRING = new LSA_UNICODE_STRING(); hGlobalUni1 = Marshal.StringToHGlobalUni(targetName); UnsafeNativeMethods.RtlInitUnicodeString(lSAUNICODESTRING, hGlobalUni1); TrustHelper.ValidateTrust(policySafeHandle, lSAUNICODESTRING, sourceName, targetName, isForest, (int)direction, policyServerName); if (preferredTargetServer != null) { hGlobalUni = Marshal.StringToHGlobalUni(string.Concat(targetName, "\\", preferredTargetServer)); } else { hGlobalUni = Marshal.StringToHGlobalUni(targetName); } intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr))); Marshal.WriteIntPtr(intPtr, hGlobalUni); if (forceSecureChannelReset) { num = UnsafeNativeMethods.I_NetLogonControl2(policyServerName, TrustHelper.NETLOGON_CONTROL_REDISCOVER, TrustHelper.NETLOGON_QUERY_LEVEL, intPtr, out intPtr2); if (num != 0) { throw ExceptionHelper.GetExceptionFromErrorCode(num); } } else { num = UnsafeNativeMethods.I_NetLogonControl2(policyServerName, TrustHelper.NETLOGON_CONTROL_TC_VERIFY, TrustHelper.NETLOGON_QUERY_LEVEL, intPtr, out intPtr1); if (num != 0) { if (num != TrustHelper.ERROR_INVALID_LEVEL) { throw ExceptionHelper.GetExceptionFromErrorCode(num); } else { throw new NotSupportedException(Res.GetString("TrustVerificationNotSupport")); } } else { NETLOGON_INFO_2 nETLOGONINFO2 = new NETLOGON_INFO_2(); Marshal.PtrToStructure(intPtr1, nETLOGONINFO2); if ((nETLOGONINFO2.netlog2_flags & TrustHelper.NETLOGON_VERIFY_STATUS_RETURNED) == 0) { int netlog2TcConnectionStatus = nETLOGONINFO2.netlog2_tc_connection_status; throw ExceptionHelper.GetExceptionFromErrorCode(netlog2TcConnectionStatus); } else { int netlog2PdcConnectionStatus = nETLOGONINFO2.netlog2_pdc_connection_status; if (netlog2PdcConnectionStatus != 0) { throw ExceptionHelper.GetExceptionFromErrorCode(netlog2PdcConnectionStatus); } else { return; } } } } } finally { if (flag) { Utils.Revert(); } if (hGlobalUni1 != (IntPtr)0) { Marshal.FreeHGlobal(hGlobalUni1); } if (intPtr != (IntPtr)0) { Marshal.FreeHGlobal(intPtr); } if (hGlobalUni != (IntPtr)0) { Marshal.FreeHGlobal(hGlobalUni); } if (intPtr1 != (IntPtr)0) { UnsafeNativeMethods.NetApiBufferFree(intPtr1); } if (intPtr2 != (IntPtr)0) { UnsafeNativeMethods.NetApiBufferFree(intPtr2); } } } catch { throw; } }
internal static void VerifyTrust(DirectoryContext context, string? sourceName, string? targetName, bool isForest, TrustDirection direction, bool forceSecureChannelReset, string? preferredTargetServer) { PolicySafeHandle? policyHandle = null; LSA_UNICODE_STRING? trustedDomainName = null; int win32Error = 0; IntPtr data = (IntPtr)0; IntPtr ptr = (IntPtr)0; IntPtr buffer1 = (IntPtr)0; IntPtr buffer2 = (IntPtr)0; bool impersonated = true; IntPtr target = (IntPtr)0; string? policyServerName = null; policyServerName = Utils.GetPolicyServerName(context, isForest, false, sourceName); impersonated = Utils.Impersonate(context); try { try { // get the policy handle policyHandle = new PolicySafeHandle(Utils.GetPolicyHandle(policyServerName)); // get the target name trustedDomainName = new LSA_UNICODE_STRING(); target = Marshal.StringToHGlobalUni(targetName); UnsafeNativeMethods.RtlInitUnicodeString(trustedDomainName, target); // validate the trust existence ValidateTrust(policyHandle, trustedDomainName, sourceName, targetName, isForest, (int)direction, policyServerName); // need to verify direction if (preferredTargetServer == null) data = Marshal.StringToHGlobalUni(targetName); else // this is the case that we need to specifically go to a particular server. This is the way to tell netlogon to do that. data = Marshal.StringToHGlobalUni(targetName + "\\" + preferredTargetServer); ptr = Marshal.AllocHGlobal(IntPtr.Size); Marshal.WriteIntPtr(ptr, data); if (!forceSecureChannelReset) { win32Error = UnsafeNativeMethods.I_NetLogonControl2(policyServerName, NETLOGON_CONTROL_TC_VERIFY, NETLOGON_QUERY_LEVEL, ptr, out buffer1); if (win32Error == 0) { NETLOGON_INFO_2 info = new NETLOGON_INFO_2(); Marshal.PtrToStructure(buffer1, info); if ((info.netlog2_flags & NETLOGON_VERIFY_STATUS_RETURNED) != 0) { int result = info.netlog2_pdc_connection_status; if (result == 0) { // verification succeeded return; } else { // don't really know which server is down, the source or the target throw ExceptionHelper.GetExceptionFromErrorCode(result); } } else { int result = info.netlog2_tc_connection_status; throw ExceptionHelper.GetExceptionFromErrorCode(result); } } else { if (win32Error == ERROR_INVALID_LEVEL) { // it is pre-win2k SP3 dc that does not support NETLOGON_CONTROL_TC_VERIFY throw new NotSupportedException(SR.TrustVerificationNotSupport); } else { throw ExceptionHelper.GetExceptionFromErrorCode(win32Error); } } } else { // then try secure channel reset win32Error = UnsafeNativeMethods.I_NetLogonControl2(policyServerName, NETLOGON_CONTROL_REDISCOVER, NETLOGON_QUERY_LEVEL, ptr, out buffer2); if (win32Error != 0) // don't really know which server is down, the source or the target throw ExceptionHelper.GetExceptionFromErrorCode(win32Error); } } finally { if (impersonated) Utils.Revert(); if (target != (IntPtr)0) Marshal.FreeHGlobal(target); if (ptr != (IntPtr)0) Marshal.FreeHGlobal(ptr); if (data != (IntPtr)0) Marshal.FreeHGlobal(data); if (buffer1 != (IntPtr)0) UnsafeNativeMethods.NetApiBufferFree(buffer1); if (buffer2 != (IntPtr)0) UnsafeNativeMethods.NetApiBufferFree(buffer2); } } catch { throw; } }