private static void ValidateTrustAttribute(TRUSTED_DOMAIN_INFORMATION_EX domainInfo, bool isForest, string? sourceName, string? targetName) { if (isForest) { // it should be a forest trust, make sure that TRUST_ATTRIBUTE_FOREST_TRANSITIVE bit is set if ((domainInfo.TrustAttributes & TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_FOREST_TRANSITIVE) == 0) { throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.ForestTrustDoesNotExist, sourceName, targetName), typeof(ForestTrustRelationshipInformation), null); } } else { // it should not be a forest trust, make sure that TRUST_ATTRIBUTE_FOREST_TRANSITIVE bit is not set if ((domainInfo.TrustAttributes & TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_FOREST_TRANSITIVE) != 0) { throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.WrongForestTrust, sourceName, targetName), typeof(TrustRelationshipInformation), null); } // we don't deal with NT4 trust also if (domainInfo.TrustType == TRUST_TYPE_DOWNLEVEL) throw new InvalidOperationException(SR.NT4NotSupported); // we don't perform any operation on kerberos trust also if (domainInfo.TrustType == TRUST_TYPE_MIT) throw new InvalidOperationException(SR.KerberosNotSupported); } }
private static void ValidateTrustAttribute(TRUSTED_DOMAIN_INFORMATION_EX domainInfo, bool isForest, string sourceName, string targetName) { if (isForest) { if ((domainInfo.TrustAttributes & TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_FOREST_TRANSITIVE) == 0) { throw new ActiveDirectoryObjectNotFoundException(Res.GetString("ForestTrustDoesNotExist", new object[] { sourceName, targetName }), typeof(ForestTrustRelationshipInformation), null); } } else { if ((domainInfo.TrustAttributes & TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_FOREST_TRANSITIVE) != 0) { throw new ActiveDirectoryObjectNotFoundException(Res.GetString("WrongForestTrust", new object[] { sourceName, targetName }), typeof(TrustRelationshipInformation), null); } if (domainInfo.TrustType == TRUST_TYPE_DOWNLEVEL) { throw new InvalidOperationException(Res.GetString("NT4NotSupported")); } if (domainInfo.TrustType == TRUST_TYPE_MIT) { throw new InvalidOperationException(Res.GetString("KerberosNotSupported")); } } }
private static void ValidateTrust(PolicySafeHandle handle, LSA_UNICODE_STRING trustedDomainName, string? sourceName, string? targetName, bool isForest, int direction, string serverName) { IntPtr buffer = (IntPtr)0; // get trust information int result = UnsafeNativeMethods.LsaQueryTrustedDomainInfoByName(handle, trustedDomainName, TRUSTED_INFORMATION_CLASS.TrustedDomainInformationEx, ref buffer); if (result != 0) { int win32Error = UnsafeNativeMethods.LsaNtStatusToWinError(result); // 2 ERROR_FILE_NOT_FOUND <--> 0xc0000034 STATUS_OBJECT_NAME_NOT_FOUND if (win32Error == STATUS_OBJECT_NAME_NOT_FOUND) { if (isForest) throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.ForestTrustDoesNotExist, sourceName, targetName), typeof(ForestTrustRelationshipInformation), null); else throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.DomainTrustDoesNotExist, sourceName, targetName), typeof(TrustRelationshipInformation), null); } else throw ExceptionHelper.GetExceptionFromErrorCode(win32Error, serverName); } Debug.Assert(buffer != (IntPtr)0); try { TRUSTED_DOMAIN_INFORMATION_EX domainInfo = new TRUSTED_DOMAIN_INFORMATION_EX(); Marshal.PtrToStructure(buffer, domainInfo); // validate this is the trust that the user refers to ValidateTrustAttribute(domainInfo, isForest, sourceName, targetName); // validate trust direction if applicable if (direction != 0) { if ((direction & domainInfo.TrustDirection) == 0) { if (isForest) throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.WrongTrustDirection, sourceName, targetName, (TrustDirection)direction), typeof(ForestTrustRelationshipInformation), null); else throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.WrongTrustDirection, sourceName, targetName, (TrustDirection)direction), typeof(TrustRelationshipInformation), null); } } } finally { if (buffer != (IntPtr)0) UnsafeNativeMethods.LsaFreeMemory(buffer); } }
private static void ValidateTrust(PolicySafeHandle handle, LSA_UNICODE_STRING trustedDomainName, string sourceName, string targetName, bool isForest, int direction, string serverName) { IntPtr zero = IntPtr.Zero; int status = UnsafeNativeMethods.LsaQueryTrustedDomainInfoByName(handle, trustedDomainName, TRUSTED_INFORMATION_CLASS.TrustedDomainInformationEx, ref zero); if (status != 0) { int errorCode = UnsafeNativeMethods.LsaNtStatusToWinError(status); if (errorCode != STATUS_OBJECT_NAME_NOT_FOUND) { throw ExceptionHelper.GetExceptionFromErrorCode(errorCode, serverName); } if (isForest) { throw new ActiveDirectoryObjectNotFoundException(Res.GetString("ForestTrustDoesNotExist", new object[] { sourceName, targetName }), typeof(ForestTrustRelationshipInformation), null); } throw new ActiveDirectoryObjectNotFoundException(Res.GetString("DomainTrustDoesNotExist", new object[] { sourceName, targetName }), typeof(TrustRelationshipInformation), null); } try { TRUSTED_DOMAIN_INFORMATION_EX structure = new TRUSTED_DOMAIN_INFORMATION_EX(); Marshal.PtrToStructure(zero, structure); ValidateTrustAttribute(structure, isForest, sourceName, targetName); if ((direction != 0) && ((direction & structure.TrustDirection) == 0)) { if (isForest) { throw new ActiveDirectoryObjectNotFoundException(Res.GetString("WrongTrustDirection", new object[] { sourceName, targetName, (TrustDirection)direction }), typeof(ForestTrustRelationshipInformation), null); } throw new ActiveDirectoryObjectNotFoundException(Res.GetString("WrongTrustDirection", new object[] { sourceName, targetName, (TrustDirection)direction }), typeof(TrustRelationshipInformation), null); } } finally { if (zero != IntPtr.Zero) { UnsafeNativeMethods.LsaFreeMemory(zero); } } }
internal static void CreateTrust(DirectoryContext sourceContext, string sourceName, DirectoryContext targetContext, string targetName, bool isForest, TrustDirection direction, string password) { LSA_AUTH_INFORMATION AuthData = null; TRUSTED_DOMAIN_AUTH_INFORMATION AuthInfoEx = null; TRUSTED_DOMAIN_INFORMATION_EX tdi = null; IntPtr fileTime = (IntPtr)0; IntPtr unmanagedPassword = (IntPtr)0; IntPtr info = (IntPtr)0; IntPtr domainHandle = (IntPtr)0; PolicySafeHandle policyHandle = null; IntPtr unmanagedAuthData = (IntPtr)0; bool impersonated = false; string serverName = null; // get the domain info first info = GetTrustedDomainInfo(targetContext, targetName, isForest); try { try { POLICY_DNS_DOMAIN_INFO domainInfo = new POLICY_DNS_DOMAIN_INFO(); Marshal.PtrToStructure(info, domainInfo); AuthData = new LSA_AUTH_INFORMATION(); fileTime = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FileTime))); UnsafeNativeMethods.GetSystemTimeAsFileTime(fileTime); // set the time FileTime tmp = new FileTime(); Marshal.PtrToStructure(fileTime, tmp); AuthData.LastUpdateTime = new LARGE_INTEGER(); AuthData.LastUpdateTime.lowPart = tmp.lower; AuthData.LastUpdateTime.highPart = tmp.higher; AuthData.AuthType = s_TRUST_AUTH_TYPE_CLEAR; unmanagedPassword = Marshal.StringToHGlobalUni(password); AuthData.AuthInfo = unmanagedPassword; AuthData.AuthInfoLength = password.Length * 2; // sizeof(WCHAR) unmanagedAuthData = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LSA_AUTH_INFORMATION))); Marshal.StructureToPtr(AuthData, unmanagedAuthData, false); AuthInfoEx = new TRUSTED_DOMAIN_AUTH_INFORMATION(); if ((direction & TrustDirection.Inbound) != 0) { AuthInfoEx.IncomingAuthInfos = 1; AuthInfoEx.IncomingAuthenticationInformation = unmanagedAuthData; AuthInfoEx.IncomingPreviousAuthenticationInformation = (IntPtr)0; } if ((direction & TrustDirection.Outbound) != 0) { AuthInfoEx.OutgoingAuthInfos = 1; AuthInfoEx.OutgoingAuthenticationInformation = unmanagedAuthData; AuthInfoEx.OutgoingPreviousAuthenticationInformation = (IntPtr)0; } tdi = new TRUSTED_DOMAIN_INFORMATION_EX(); tdi.FlatName = domainInfo.Name; tdi.Name = domainInfo.DnsDomainName; tdi.Sid = domainInfo.Sid; tdi.TrustType = TRUST_TYPE_UPLEVEL; tdi.TrustDirection = (int)direction; if (isForest) { tdi.TrustAttributes = TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_FOREST_TRANSITIVE; } else { tdi.TrustAttributes = TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN; } // get server name serverName = Utils.GetPolicyServerName(sourceContext, isForest, false, sourceName); // do impersonation and get policy handle impersonated = Utils.Impersonate(sourceContext); policyHandle = new PolicySafeHandle(Utils.GetPolicyHandle(serverName)); int result = UnsafeNativeMethods.LsaCreateTrustedDomainEx(policyHandle, tdi, AuthInfoEx, s_TRUSTED_SET_POSIX | s_TRUSTED_SET_AUTH, out domainHandle); if (result != 0) { result = UnsafeNativeMethods.LsaNtStatusToWinError(result); if (result == s_ERROR_ALREADY_EXISTS) { if (isForest) throw new ActiveDirectoryObjectExistsException(Res.GetString(Res.AlreadyExistingForestTrust, sourceName, targetName)); else throw new ActiveDirectoryObjectExistsException(Res.GetString(Res.AlreadyExistingDomainTrust, sourceName, targetName)); } else throw ExceptionHelper.GetExceptionFromErrorCode(result, serverName); } } finally { if (impersonated) Utils.Revert(); if (fileTime != (IntPtr)0) Marshal.FreeHGlobal(fileTime); if (domainHandle != (IntPtr)0) UnsafeNativeMethods.LsaClose(domainHandle); if (info != (IntPtr)0) UnsafeNativeMethods.LsaFreeMemory(info); if (unmanagedPassword != (IntPtr)0) Marshal.FreeHGlobal(unmanagedPassword); if (unmanagedAuthData != (IntPtr)0) Marshal.FreeHGlobal(unmanagedAuthData); } } catch { throw; } }
internal static void SetTrustedDomainInfoStatus(DirectoryContext context, string sourceName, string targetName, TRUST_ATTRIBUTE attribute, bool status, bool isForest) { PolicySafeHandle handle = null; IntPtr buffer = (IntPtr)0; IntPtr newInfo = (IntPtr)0; LSA_UNICODE_STRING trustedDomainName = null; bool impersonated = false; IntPtr target = (IntPtr)0; string serverName = null; serverName = Utils.GetPolicyServerName(context, isForest, false, sourceName); impersonated = Utils.Impersonate(context); try { try { // get the policy handle first handle = new PolicySafeHandle(Utils.GetPolicyHandle(serverName)); // get the target name trustedDomainName = new LSA_UNICODE_STRING(); target = Marshal.StringToHGlobalUni(targetName); UnsafeNativeMethods.RtlInitUnicodeString(trustedDomainName, target); // get the trusted domain information int result = UnsafeNativeMethods.LsaQueryTrustedDomainInfoByName(handle, trustedDomainName, TRUSTED_INFORMATION_CLASS.TrustedDomainInformationEx, ref buffer); if (result != 0) { int win32Error = UnsafeNativeMethods.LsaNtStatusToWinError(result); // 2 ERROR_FILE_NOT_FOUND <--> 0xc0000034 STATUS_OBJECT_NAME_NOT_FOUND if (win32Error == s_STATUS_OBJECT_NAME_NOT_FOUND) { if (isForest) throw new ActiveDirectoryObjectNotFoundException(Res.GetString(Res.ForestTrustDoesNotExist, sourceName, targetName), typeof(ForestTrustRelationshipInformation), null); else throw new ActiveDirectoryObjectNotFoundException(Res.GetString(Res.DomainTrustDoesNotExist, sourceName, targetName), typeof(TrustRelationshipInformation), null); } else throw ExceptionHelper.GetExceptionFromErrorCode(win32Error, serverName); } Debug.Assert(buffer != (IntPtr)0); // get the managed structre representation TRUSTED_DOMAIN_INFORMATION_EX domainInfo = new TRUSTED_DOMAIN_INFORMATION_EX(); Marshal.PtrToStructure(buffer, domainInfo); // validate this is the trust that the user refers to ValidateTrustAttribute(domainInfo, isForest, sourceName, targetName); // change the attribute value properly // selective authentication if (attribute == TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_CROSS_ORGANIZATION) { if (status) { // turns on selective authentication domainInfo.TrustAttributes |= TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_CROSS_ORGANIZATION; } else { // turns off selective authentication domainInfo.TrustAttributes &= ~(TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_CROSS_ORGANIZATION); } } // user wants to change sid filtering behavior for forest trust else if (attribute == TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL) { if (status) { // user wants sid filtering behavior domainInfo.TrustAttributes &= ~(TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL); } else { // users wants to turn off sid filtering behavior domainInfo.TrustAttributes |= TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL; } } // user wants to change sid filtering behavior for external trust else if (attribute == TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) { if (status) { // user wants sid filtering behavior domainInfo.TrustAttributes |= TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN; } else { // user wants to turn off sid filtering behavior domainInfo.TrustAttributes &= ~(TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN); } } else { throw new ArgumentException("attribute"); } // reconstruct the unmanaged structure to set it back newInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TRUSTED_DOMAIN_INFORMATION_EX))); Marshal.StructureToPtr(domainInfo, newInfo, false); result = UnsafeNativeMethods.LsaSetTrustedDomainInfoByName(handle, trustedDomainName, TRUSTED_INFORMATION_CLASS.TrustedDomainInformationEx, newInfo); if (result != 0) { throw ExceptionHelper.GetExceptionFromErrorCode(UnsafeNativeMethods.LsaNtStatusToWinError(result), serverName); } return; } finally { if (impersonated) Utils.Revert(); if (target != (IntPtr)0) Marshal.FreeHGlobal(target); if (buffer != (IntPtr)0) UnsafeNativeMethods.LsaFreeMemory(buffer); if (newInfo != (IntPtr)0) Marshal.FreeHGlobal(newInfo); } } catch { throw; } }
internal static void DeleteTrust(DirectoryContext sourceContext, string sourceName, string targetName, bool isForest) { PolicySafeHandle policyHandle = null; LSA_UNICODE_STRING trustedDomainName = null; int win32Error = 0; bool impersonated = false; IntPtr target = (IntPtr)0; string serverName = null; IntPtr buffer = (IntPtr)0; serverName = Utils.GetPolicyServerName(sourceContext, isForest, false, sourceName); impersonated = Utils.Impersonate(sourceContext); try { try { // get the policy handle policyHandle = new PolicySafeHandle(Utils.GetPolicyHandle(serverName)); // get the target name trustedDomainName = new LSA_UNICODE_STRING(); target = Marshal.StringToHGlobalUni(targetName); UnsafeNativeMethods.RtlInitUnicodeString(trustedDomainName, target); // get trust information int result = UnsafeNativeMethods.LsaQueryTrustedDomainInfoByName(policyHandle, trustedDomainName, TRUSTED_INFORMATION_CLASS.TrustedDomainInformationEx, ref buffer); if (result != 0) { win32Error = UnsafeNativeMethods.LsaNtStatusToWinError(result); // 2 ERROR_FILE_NOT_FOUND <--> 0xc0000034 STATUS_OBJECT_NAME_NOT_FOUND if (win32Error == s_STATUS_OBJECT_NAME_NOT_FOUND) { if (isForest) throw new ActiveDirectoryObjectNotFoundException(Res.GetString(Res.ForestTrustDoesNotExist, sourceName, targetName), typeof(ForestTrustRelationshipInformation), null); else throw new ActiveDirectoryObjectNotFoundException(Res.GetString(Res.DomainTrustDoesNotExist, sourceName, targetName), typeof(TrustRelationshipInformation), null); } else throw ExceptionHelper.GetExceptionFromErrorCode(win32Error, serverName); } Debug.Assert(buffer != (IntPtr)0); try { TRUSTED_DOMAIN_INFORMATION_EX domainInfo = new TRUSTED_DOMAIN_INFORMATION_EX(); Marshal.PtrToStructure(buffer, domainInfo); // validate this is the trust that the user refers to ValidateTrustAttribute(domainInfo, isForest, sourceName, targetName); // delete the trust result = UnsafeNativeMethods.LsaDeleteTrustedDomain(policyHandle, domainInfo.Sid); if (result != 0) { win32Error = UnsafeNativeMethods.LsaNtStatusToWinError(result); throw ExceptionHelper.GetExceptionFromErrorCode(win32Error, serverName); } } finally { if (buffer != (IntPtr)0) UnsafeNativeMethods.LsaFreeMemory(buffer); } } finally { if (impersonated) Utils.Revert(); if (target != (IntPtr)0) Marshal.FreeHGlobal(target); } } catch { throw; } }
internal static void DeleteTrust(DirectoryContext sourceContext, string? sourceName, string? targetName, bool isForest) { PolicySafeHandle? policyHandle = null; LSA_UNICODE_STRING? trustedDomainName = null; int win32Error = 0; bool impersonated = false; IntPtr target = (IntPtr)0; string? serverName = null; IntPtr buffer = (IntPtr)0; serverName = Utils.GetPolicyServerName(sourceContext, isForest, false, sourceName); impersonated = Utils.Impersonate(sourceContext); try { try { // get the policy handle policyHandle = new PolicySafeHandle(Utils.GetPolicyHandle(serverName)); // get the target name trustedDomainName = new LSA_UNICODE_STRING(); target = Marshal.StringToHGlobalUni(targetName); UnsafeNativeMethods.RtlInitUnicodeString(trustedDomainName, target); // get trust information int result = UnsafeNativeMethods.LsaQueryTrustedDomainInfoByName(policyHandle, trustedDomainName, TRUSTED_INFORMATION_CLASS.TrustedDomainInformationEx, ref buffer); if (result != 0) { win32Error = UnsafeNativeMethods.LsaNtStatusToWinError(result); // 2 ERROR_FILE_NOT_FOUND <--> 0xc0000034 STATUS_OBJECT_NAME_NOT_FOUND if (win32Error == STATUS_OBJECT_NAME_NOT_FOUND) { if (isForest) throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.ForestTrustDoesNotExist, sourceName, targetName), typeof(ForestTrustRelationshipInformation), null); else throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.DomainTrustDoesNotExist, sourceName, targetName), typeof(TrustRelationshipInformation), null); } else throw ExceptionHelper.GetExceptionFromErrorCode(win32Error, serverName); } Debug.Assert(buffer != (IntPtr)0); try { TRUSTED_DOMAIN_INFORMATION_EX domainInfo = new TRUSTED_DOMAIN_INFORMATION_EX(); Marshal.PtrToStructure(buffer, domainInfo); // validate this is the trust that the user refers to ValidateTrustAttribute(domainInfo, isForest, sourceName, targetName); // delete the trust result = UnsafeNativeMethods.LsaDeleteTrustedDomain(policyHandle, domainInfo.Sid); if (result != 0) { win32Error = UnsafeNativeMethods.LsaNtStatusToWinError(result); throw ExceptionHelper.GetExceptionFromErrorCode(win32Error, serverName); } } finally { if (buffer != (IntPtr)0) UnsafeNativeMethods.LsaFreeMemory(buffer); } } finally { if (impersonated) Utils.Revert(); if (target != (IntPtr)0) Marshal.FreeHGlobal(target); } } catch { throw; } }
internal static void DeleteTrust(DirectoryContext sourceContext, string sourceName, string targetName, bool isForest) { PolicySafeHandle handle = null; LSA_UNICODE_STRING result = null; int errorCode = 0; bool flag = false; IntPtr zero = IntPtr.Zero; string serverName = null; IntPtr buffer = IntPtr.Zero; serverName = System.DirectoryServices.ActiveDirectory.Utils.GetPolicyServerName(sourceContext, isForest, false, sourceName); flag = System.DirectoryServices.ActiveDirectory.Utils.Impersonate(sourceContext); try { try { handle = new PolicySafeHandle(System.DirectoryServices.ActiveDirectory.Utils.GetPolicyHandle(serverName)); result = new LSA_UNICODE_STRING(); zero = Marshal.StringToHGlobalUni(targetName); UnsafeNativeMethods.RtlInitUnicodeString(result, zero); int status = UnsafeNativeMethods.LsaQueryTrustedDomainInfoByName(handle, result, TRUSTED_INFORMATION_CLASS.TrustedDomainInformationEx, ref buffer); if (status != 0) { errorCode = UnsafeNativeMethods.LsaNtStatusToWinError(status); if (errorCode != STATUS_OBJECT_NAME_NOT_FOUND) { throw ExceptionHelper.GetExceptionFromErrorCode(errorCode, serverName); } if (isForest) { throw new ActiveDirectoryObjectNotFoundException(Res.GetString("ForestTrustDoesNotExist", new object[] { sourceName, targetName }), typeof(ForestTrustRelationshipInformation), null); } throw new ActiveDirectoryObjectNotFoundException(Res.GetString("DomainTrustDoesNotExist", new object[] { sourceName, targetName }), typeof(TrustRelationshipInformation), null); } try { TRUSTED_DOMAIN_INFORMATION_EX structure = new TRUSTED_DOMAIN_INFORMATION_EX(); Marshal.PtrToStructure(buffer, structure); ValidateTrustAttribute(structure, isForest, sourceName, targetName); status = UnsafeNativeMethods.LsaDeleteTrustedDomain(handle, structure.Sid); if (status != 0) { throw ExceptionHelper.GetExceptionFromErrorCode(UnsafeNativeMethods.LsaNtStatusToWinError(status), serverName); } } finally { if (buffer != IntPtr.Zero) { UnsafeNativeMethods.LsaFreeMemory(buffer); } } } finally { if (flag) { System.DirectoryServices.ActiveDirectory.Utils.Revert(); } if (zero != IntPtr.Zero) { Marshal.FreeHGlobal(zero); } } } catch { throw; } }
internal static void SetTrustedDomainInfoStatus(DirectoryContext context, string sourceName, string targetName, TRUST_ATTRIBUTE attribute, bool status, bool isForest) { PolicySafeHandle handle = null; IntPtr zero = IntPtr.Zero; IntPtr ptr = IntPtr.Zero; LSA_UNICODE_STRING result = null; bool flag = false; 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); int num = UnsafeNativeMethods.LsaQueryTrustedDomainInfoByName(handle, result, TRUSTED_INFORMATION_CLASS.TrustedDomainInformationEx, ref zero); if (num != 0) { int errorCode = UnsafeNativeMethods.LsaNtStatusToWinError(num); if (errorCode != STATUS_OBJECT_NAME_NOT_FOUND) { throw ExceptionHelper.GetExceptionFromErrorCode(errorCode, serverName); } if (isForest) { throw new ActiveDirectoryObjectNotFoundException(Res.GetString("ForestTrustDoesNotExist", new object[] { sourceName, targetName }), typeof(ForestTrustRelationshipInformation), null); } throw new ActiveDirectoryObjectNotFoundException(Res.GetString("DomainTrustDoesNotExist", new object[] { sourceName, targetName }), typeof(TrustRelationshipInformation), null); } TRUSTED_DOMAIN_INFORMATION_EX structure = new TRUSTED_DOMAIN_INFORMATION_EX(); Marshal.PtrToStructure(zero, structure); ValidateTrustAttribute(structure, isForest, sourceName, targetName); if (attribute == TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_CROSS_ORGANIZATION) { if (status) { structure.TrustAttributes |= TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_CROSS_ORGANIZATION; } else { structure.TrustAttributes &= ~TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_CROSS_ORGANIZATION; } } else if (attribute == TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL) { if (status) { structure.TrustAttributes &= ~TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL; } else { structure.TrustAttributes |= TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL; } } else { if (attribute != TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) { throw new ArgumentException("attribute"); } if (status) { structure.TrustAttributes |= TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN; } else { structure.TrustAttributes &= ~TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN; } } ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TRUSTED_DOMAIN_INFORMATION_EX))); Marshal.StructureToPtr(structure, ptr, false); num = UnsafeNativeMethods.LsaSetTrustedDomainInfoByName(handle, result, TRUSTED_INFORMATION_CLASS.TrustedDomainInformationEx, ptr); if (num != 0) { throw ExceptionHelper.GetExceptionFromErrorCode(UnsafeNativeMethods.LsaNtStatusToWinError(num), serverName); } } finally { if (flag) { System.DirectoryServices.ActiveDirectory.Utils.Revert(); } if (s != IntPtr.Zero) { Marshal.FreeHGlobal(s); } if (zero != IntPtr.Zero) { UnsafeNativeMethods.LsaFreeMemory(zero); } if (ptr != IntPtr.Zero) { Marshal.FreeHGlobal(ptr); } } } catch { throw; } }
internal static bool GetTrustedDomainInfoStatus(DirectoryContext context, string sourceName, string targetName, TRUST_ATTRIBUTE attribute, bool isForest) { PolicySafeHandle handle = null; IntPtr buffer = (IntPtr)0; LSA_UNICODE_STRING trustedDomainName = null; bool impersonated = false; IntPtr target = (IntPtr)0; string serverName = null; // get policy server name serverName = Utils.GetPolicyServerName(context, isForest, false, sourceName); impersonated = Utils.Impersonate(context); try { try { // get the policy handle first handle = new PolicySafeHandle(Utils.GetPolicyHandle(serverName)); // get the target name trustedDomainName = new LSA_UNICODE_STRING(); target = Marshal.StringToHGlobalUni(targetName); UnsafeNativeMethods.RtlInitUnicodeString(trustedDomainName, target); int result = UnsafeNativeMethods.LsaQueryTrustedDomainInfoByName(handle, trustedDomainName, TRUSTED_INFORMATION_CLASS.TrustedDomainInformationEx, ref buffer); if (result != 0) { int win32Error = UnsafeNativeMethods.LsaNtStatusToWinError(result); // 2 ERROR_FILE_NOT_FOUND <--> 0xc0000034 STATUS_OBJECT_NAME_NOT_FOUND if (win32Error == s_STATUS_OBJECT_NAME_NOT_FOUND) { if (isForest) throw new ActiveDirectoryObjectNotFoundException(Res.GetString(Res.ForestTrustDoesNotExist, sourceName, targetName), typeof(ForestTrustRelationshipInformation), null); else throw new ActiveDirectoryObjectNotFoundException(Res.GetString(Res.DomainTrustDoesNotExist, sourceName, targetName), typeof(TrustRelationshipInformation), null); } else throw ExceptionHelper.GetExceptionFromErrorCode(win32Error, serverName); } Debug.Assert(buffer != (IntPtr)0); TRUSTED_DOMAIN_INFORMATION_EX domainInfo = new TRUSTED_DOMAIN_INFORMATION_EX(); Marshal.PtrToStructure(buffer, domainInfo); // validate this is the trust that the user refers to ValidateTrustAttribute(domainInfo, isForest, sourceName, targetName); // get the attribute of the trust // selective authentication info if (attribute == TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_CROSS_ORGANIZATION) { if ((domainInfo.TrustAttributes & TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_CROSS_ORGANIZATION) == 0) return false; else return true; } // sid filtering behavior for forest trust else if (attribute == TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL) { if ((domainInfo.TrustAttributes & TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL) == 0) return true; else return false; } // sid filtering behavior for domain trust else if (attribute == TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) { if ((domainInfo.TrustAttributes & TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) == 0) return false; else return true; } else { // should not happen throw new ArgumentException("attribute"); } } finally { if (impersonated) Utils.Revert(); if (target != (IntPtr)0) Marshal.FreeHGlobal(target); if (buffer != (IntPtr)0) UnsafeNativeMethods.LsaFreeMemory(buffer); } } catch { throw; } }
private static void ValidateTrustAttribute(TRUSTED_DOMAIN_INFORMATION_EX domainInfo, bool isForest, string sourceName, string targetName) { if (isForest) { // it should be a forest trust, make sure that TRUST_ATTRIBUTE_FOREST_TRANSITIVE bit is set if ((domainInfo.TrustAttributes & TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_FOREST_TRANSITIVE) == 0) { throw new ActiveDirectoryObjectNotFoundException(Res.GetString(Res.ForestTrustDoesNotExist, sourceName, targetName), typeof(ForestTrustRelationshipInformation), null); } } else { // it should not be a forest trust, make sure that TRUST_ATTRIBUTE_FOREST_TRANSITIVE bit is not set if ((domainInfo.TrustAttributes & TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_FOREST_TRANSITIVE) != 0) { throw new ActiveDirectoryObjectNotFoundException(Res.GetString(Res.WrongForestTrust, sourceName, targetName), typeof(TrustRelationshipInformation), null); } // we don't deal with NT4 trust also if (domainInfo.TrustType == TRUST_TYPE_DOWNLEVEL) throw new InvalidOperationException(Res.GetString(Res.NT4NotSupported)); // we don't perform any operation on kerberos trust also if (domainInfo.TrustType == TRUST_TYPE_MIT) throw new InvalidOperationException(Res.GetString(Res.KerberosNotSupported)); } }
internal static void CreateTrust(DirectoryContext sourceContext, string sourceName, DirectoryContext targetContext, string targetName, bool isForest, TrustDirection direction, string password) { LSA_AUTH_INFORMATION structure = null; TRUSTED_DOMAIN_AUTH_INFORMATION authInfo = null; TRUSTED_DOMAIN_INFORMATION_EX domainEx = null; IntPtr zero = IntPtr.Zero; IntPtr hglobal = IntPtr.Zero; IntPtr ptr = IntPtr.Zero; IntPtr domainHandle = IntPtr.Zero; PolicySafeHandle handle = null; IntPtr ptr5 = IntPtr.Zero; bool flag = false; string serverName = null; ptr = GetTrustedDomainInfo(targetContext, targetName, isForest); try { try { POLICY_DNS_DOMAIN_INFO policy_dns_domain_info = new POLICY_DNS_DOMAIN_INFO(); Marshal.PtrToStructure(ptr, policy_dns_domain_info); structure = new LSA_AUTH_INFORMATION(); zero = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FileTime))); UnsafeNativeMethods.GetSystemTimeAsFileTime(zero); FileTime time = new FileTime(); Marshal.PtrToStructure(zero, time); structure.LastUpdateTime = new LARGE_INTEGER(); structure.LastUpdateTime.lowPart = time.lower; structure.LastUpdateTime.highPart = time.higher; structure.AuthType = TRUST_AUTH_TYPE_CLEAR; hglobal = Marshal.StringToHGlobalUni(password); structure.AuthInfo = hglobal; structure.AuthInfoLength = password.Length * 2; ptr5 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LSA_AUTH_INFORMATION))); Marshal.StructureToPtr(structure, ptr5, false); authInfo = new TRUSTED_DOMAIN_AUTH_INFORMATION(); if ((direction & TrustDirection.Inbound) != ((TrustDirection)0)) { authInfo.IncomingAuthInfos = 1; authInfo.IncomingAuthenticationInformation = ptr5; authInfo.IncomingPreviousAuthenticationInformation = IntPtr.Zero; } if ((direction & TrustDirection.Outbound) != ((TrustDirection)0)) { authInfo.OutgoingAuthInfos = 1; authInfo.OutgoingAuthenticationInformation = ptr5; authInfo.OutgoingPreviousAuthenticationInformation = IntPtr.Zero; } domainEx = new TRUSTED_DOMAIN_INFORMATION_EX { FlatName = policy_dns_domain_info.Name, Name = policy_dns_domain_info.DnsDomainName, Sid = policy_dns_domain_info.Sid, TrustType = TRUST_TYPE_UPLEVEL, TrustDirection = (int)direction }; if (isForest) { domainEx.TrustAttributes = TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_FOREST_TRANSITIVE; } else { domainEx.TrustAttributes = TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN; } serverName = System.DirectoryServices.ActiveDirectory.Utils.GetPolicyServerName(sourceContext, isForest, false, sourceName); flag = System.DirectoryServices.ActiveDirectory.Utils.Impersonate(sourceContext); handle = new PolicySafeHandle(System.DirectoryServices.ActiveDirectory.Utils.GetPolicyHandle(serverName)); int status = UnsafeNativeMethods.LsaCreateTrustedDomainEx(handle, domainEx, authInfo, TRUSTED_SET_POSIX | TRUSTED_SET_AUTH, out domainHandle); if (status != 0) { status = UnsafeNativeMethods.LsaNtStatusToWinError(status); if (status != ERROR_ALREADY_EXISTS) { throw ExceptionHelper.GetExceptionFromErrorCode(status, serverName); } if (isForest) { throw new ActiveDirectoryObjectExistsException(Res.GetString("AlreadyExistingForestTrust", new object[] { sourceName, targetName })); } throw new ActiveDirectoryObjectExistsException(Res.GetString("AlreadyExistingDomainTrust", new object[] { sourceName, targetName })); } } finally { if (flag) { System.DirectoryServices.ActiveDirectory.Utils.Revert(); } if (zero != IntPtr.Zero) { Marshal.FreeHGlobal(zero); } if (domainHandle != IntPtr.Zero) { UnsafeNativeMethods.LsaClose(domainHandle); } if (ptr != IntPtr.Zero) { UnsafeNativeMethods.LsaFreeMemory(ptr); } if (hglobal != IntPtr.Zero) { Marshal.FreeHGlobal(hglobal); } if (ptr5 != IntPtr.Zero) { Marshal.FreeHGlobal(ptr5); } } } catch { throw; } }
internal static void CreateTrust(DirectoryContext sourceContext, string? sourceName, DirectoryContext targetContext, string? targetName, bool isForest, TrustDirection direction, string password) { LSA_AUTH_INFORMATION? AuthData = null; TRUSTED_DOMAIN_AUTH_INFORMATION? AuthInfoEx = null; TRUSTED_DOMAIN_INFORMATION_EX? tdi = null; IntPtr fileTime = (IntPtr)0; IntPtr unmanagedPassword = (IntPtr)0; IntPtr info = (IntPtr)0; IntPtr domainHandle = (IntPtr)0; PolicySafeHandle? policyHandle = null; IntPtr unmanagedAuthData = (IntPtr)0; bool impersonated = false; string? serverName = null; // get the domain info first info = GetTrustedDomainInfo(targetContext, targetName, isForest); try { try { POLICY_DNS_DOMAIN_INFO domainInfo = new POLICY_DNS_DOMAIN_INFO(); Marshal.PtrToStructure(info, domainInfo); AuthData = new LSA_AUTH_INFORMATION(); fileTime = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FileTime))); UnsafeNativeMethods.GetSystemTimeAsFileTime(fileTime); // set the time FileTime tmp = new FileTime(); Marshal.PtrToStructure(fileTime, tmp); AuthData.LastUpdateTime = new LARGE_INTEGER(); AuthData.LastUpdateTime.lowPart = tmp.lower; AuthData.LastUpdateTime.highPart = tmp.higher; AuthData.AuthType = TRUST_AUTH_TYPE_CLEAR; unmanagedPassword = Marshal.StringToHGlobalUni(password); AuthData.AuthInfo = unmanagedPassword; AuthData.AuthInfoLength = password.Length * 2; // sizeof(WCHAR) unmanagedAuthData = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LSA_AUTH_INFORMATION))); Marshal.StructureToPtr(AuthData, unmanagedAuthData, false); AuthInfoEx = new TRUSTED_DOMAIN_AUTH_INFORMATION(); if ((direction & TrustDirection.Inbound) != 0) { AuthInfoEx.IncomingAuthInfos = 1; AuthInfoEx.IncomingAuthenticationInformation = unmanagedAuthData; AuthInfoEx.IncomingPreviousAuthenticationInformation = (IntPtr)0; } if ((direction & TrustDirection.Outbound) != 0) { AuthInfoEx.OutgoingAuthInfos = 1; AuthInfoEx.OutgoingAuthenticationInformation = unmanagedAuthData; AuthInfoEx.OutgoingPreviousAuthenticationInformation = (IntPtr)0; } tdi = new TRUSTED_DOMAIN_INFORMATION_EX(); tdi.FlatName = domainInfo.Name; tdi.Name = domainInfo.DnsDomainName; tdi.Sid = domainInfo.Sid; tdi.TrustType = TRUST_TYPE_UPLEVEL; tdi.TrustDirection = (int)direction; if (isForest) { tdi.TrustAttributes = TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_FOREST_TRANSITIVE; } else { tdi.TrustAttributes = TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN; } // get server name serverName = Utils.GetPolicyServerName(sourceContext, isForest, false, sourceName); // do impersonation and get policy handle impersonated = Utils.Impersonate(sourceContext); policyHandle = new PolicySafeHandle(Utils.GetPolicyHandle(serverName)); int result = UnsafeNativeMethods.LsaCreateTrustedDomainEx(policyHandle, tdi, AuthInfoEx, TRUSTED_SET_POSIX | TRUSTED_SET_AUTH, out domainHandle); if (result != 0) { result = UnsafeNativeMethods.LsaNtStatusToWinError(result); if (result == ERROR_ALREADY_EXISTS) { if (isForest) throw new ActiveDirectoryObjectExistsException(SR.Format(SR.AlreadyExistingForestTrust, sourceName, targetName)); else throw new ActiveDirectoryObjectExistsException(SR.Format(SR.AlreadyExistingDomainTrust, sourceName, targetName)); } else throw ExceptionHelper.GetExceptionFromErrorCode(result, serverName); } } finally { if (impersonated) Utils.Revert(); if (fileTime != (IntPtr)0) Marshal.FreeHGlobal(fileTime); if (domainHandle != (IntPtr)0) UnsafeNativeMethods.LsaClose(domainHandle); if (info != (IntPtr)0) UnsafeNativeMethods.LsaFreeMemory(info); if (unmanagedPassword != (IntPtr)0) Marshal.FreeHGlobal(unmanagedPassword); if (unmanagedAuthData != (IntPtr)0) Marshal.FreeHGlobal(unmanagedAuthData); } } catch { throw; } }
internal static bool GetTrustedDomainInfoStatus(DirectoryContext context, string? sourceName, string targetName, TRUST_ATTRIBUTE attribute, bool isForest) { PolicySafeHandle? handle = null; IntPtr buffer = (IntPtr)0; LSA_UNICODE_STRING? trustedDomainName = null; bool impersonated = false; IntPtr target = (IntPtr)0; string? serverName = null; // get policy server name serverName = Utils.GetPolicyServerName(context, isForest, false, sourceName); impersonated = Utils.Impersonate(context); try { try { // get the policy handle first handle = new PolicySafeHandle(Utils.GetPolicyHandle(serverName)); // get the target name trustedDomainName = new LSA_UNICODE_STRING(); target = Marshal.StringToHGlobalUni(targetName); UnsafeNativeMethods.RtlInitUnicodeString(trustedDomainName, target); int result = UnsafeNativeMethods.LsaQueryTrustedDomainInfoByName(handle, trustedDomainName, TRUSTED_INFORMATION_CLASS.TrustedDomainInformationEx, ref buffer); if (result != 0) { int win32Error = UnsafeNativeMethods.LsaNtStatusToWinError(result); // 2 ERROR_FILE_NOT_FOUND <--> 0xc0000034 STATUS_OBJECT_NAME_NOT_FOUND if (win32Error == STATUS_OBJECT_NAME_NOT_FOUND) { if (isForest) throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.ForestTrustDoesNotExist, sourceName, targetName), typeof(ForestTrustRelationshipInformation), null); else throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.DomainTrustDoesNotExist, sourceName, targetName), typeof(TrustRelationshipInformation), null); } else throw ExceptionHelper.GetExceptionFromErrorCode(win32Error, serverName); } Debug.Assert(buffer != (IntPtr)0); TRUSTED_DOMAIN_INFORMATION_EX domainInfo = new TRUSTED_DOMAIN_INFORMATION_EX(); Marshal.PtrToStructure(buffer, domainInfo); // validate this is the trust that the user refers to ValidateTrustAttribute(domainInfo, isForest, sourceName, targetName); // get the attribute of the trust // selective authentication info if (attribute == TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_CROSS_ORGANIZATION) { if ((domainInfo.TrustAttributes & TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_CROSS_ORGANIZATION) == 0) return false; else return true; } // sid filtering behavior for forest trust else if (attribute == TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL) { if ((domainInfo.TrustAttributes & TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL) == 0) return true; else return false; } // sid filtering behavior for domain trust else if (attribute == TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) { if ((domainInfo.TrustAttributes & TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) == 0) return false; else return true; } else { // should not happen throw new ArgumentException(nameof(attribute)); } } finally { if (impersonated) Utils.Revert(); if (target != (IntPtr)0) Marshal.FreeHGlobal(target); if (buffer != (IntPtr)0) UnsafeNativeMethods.LsaFreeMemory(buffer); } } catch { throw; } }
private static void ValidateTrust(PolicySafeHandle handle, LSA_UNICODE_STRING trustedDomainName, string sourceName, string targetName, bool isForest, int direction, string serverName) { IntPtr buffer = (IntPtr)0; // get trust information int result = UnsafeNativeMethods.LsaQueryTrustedDomainInfoByName(handle, trustedDomainName, TRUSTED_INFORMATION_CLASS.TrustedDomainInformationEx, ref buffer); if (result != 0) { int win32Error = UnsafeNativeMethods.LsaNtStatusToWinError(result); // 2 ERROR_FILE_NOT_FOUND <--> 0xc0000034 STATUS_OBJECT_NAME_NOT_FOUND if (win32Error == s_STATUS_OBJECT_NAME_NOT_FOUND) { if (isForest) throw new ActiveDirectoryObjectNotFoundException(Res.GetString(Res.ForestTrustDoesNotExist, sourceName, targetName), typeof(ForestTrustRelationshipInformation), null); else throw new ActiveDirectoryObjectNotFoundException(Res.GetString(Res.DomainTrustDoesNotExist, sourceName, targetName), typeof(TrustRelationshipInformation), null); } else throw ExceptionHelper.GetExceptionFromErrorCode(win32Error, serverName); } Debug.Assert(buffer != (IntPtr)0); try { TRUSTED_DOMAIN_INFORMATION_EX domainInfo = new TRUSTED_DOMAIN_INFORMATION_EX(); Marshal.PtrToStructure(buffer, domainInfo); // validate this is the trust that the user refers to ValidateTrustAttribute(domainInfo, isForest, sourceName, targetName); // validate trust direction if applicable if (direction != 0) { if ((direction & domainInfo.TrustDirection) == 0) { if (isForest) throw new ActiveDirectoryObjectNotFoundException(Res.GetString(Res.WrongTrustDirection, sourceName, targetName, (TrustDirection)direction), typeof(ForestTrustRelationshipInformation), null); else throw new ActiveDirectoryObjectNotFoundException(Res.GetString(Res.WrongTrustDirection, sourceName, targetName, (TrustDirection)direction), typeof(TrustRelationshipInformation), null); } } } finally { if (buffer != (IntPtr)0) UnsafeNativeMethods.LsaFreeMemory(buffer); } }
internal static void DeleteTrust(DirectoryContext sourceContext, string sourceName, string targetName, bool isForest) { int winError; IntPtr hGlobalUni = (IntPtr)0; IntPtr intPtr = (IntPtr)0; string policyServerName = Utils.GetPolicyServerName(sourceContext, isForest, false, sourceName); bool flag = Utils.Impersonate(sourceContext); try { try { PolicySafeHandle policySafeHandle = new PolicySafeHandle(Utils.GetPolicyHandle(policyServerName)); LSA_UNICODE_STRING lSAUNICODESTRING = new LSA_UNICODE_STRING(); hGlobalUni = Marshal.StringToHGlobalUni(targetName); UnsafeNativeMethods.RtlInitUnicodeString(lSAUNICODESTRING, hGlobalUni); int num = UnsafeNativeMethods.LsaQueryTrustedDomainInfoByName(policySafeHandle, lSAUNICODESTRING, TRUSTED_INFORMATION_CLASS.TrustedDomainInformationEx, ref intPtr); if (num == 0) { try { TRUSTED_DOMAIN_INFORMATION_EX tRUSTEDDOMAININFORMATIONEX = new TRUSTED_DOMAIN_INFORMATION_EX(); Marshal.PtrToStructure(intPtr, tRUSTEDDOMAININFORMATIONEX); TrustHelper.ValidateTrustAttribute(tRUSTEDDOMAININFORMATIONEX, isForest, sourceName, targetName); num = UnsafeNativeMethods.LsaDeleteTrustedDomain(policySafeHandle, tRUSTEDDOMAININFORMATIONEX.Sid); if (num != 0) { winError = UnsafeNativeMethods.LsaNtStatusToWinError(num); throw ExceptionHelper.GetExceptionFromErrorCode(winError, policyServerName); } } finally { if (intPtr != (IntPtr)0) { UnsafeNativeMethods.LsaFreeMemory(intPtr); } } } else { winError = UnsafeNativeMethods.LsaNtStatusToWinError(num); if (winError != TrustHelper.STATUS_OBJECT_NAME_NOT_FOUND) { throw ExceptionHelper.GetExceptionFromErrorCode(winError, policyServerName); } else { if (!isForest) { object[] objArray = new object[2]; objArray[0] = sourceName; objArray[1] = targetName; throw new ActiveDirectoryObjectNotFoundException(Res.GetString("DomainTrustDoesNotExist", objArray), typeof(TrustRelationshipInformation), null); } else { object[] objArray1 = new object[2]; objArray1[0] = sourceName; objArray1[1] = targetName; throw new ActiveDirectoryObjectNotFoundException(Res.GetString("ForestTrustDoesNotExist", objArray1), typeof(ForestTrustRelationshipInformation), null); } } } } finally { if (flag) { Utils.Revert(); } if (hGlobalUni != (IntPtr)0) { Marshal.FreeHGlobal(hGlobalUni); } } } catch { throw; } }
public static extern int LsaCreateTrustedDomainEx(PolicySafeHandle handle, TRUSTED_DOMAIN_INFORMATION_EX domainEx, TRUSTED_DOMAIN_AUTH_INFORMATION authInfo, int classInfo, out IntPtr domainHandle);
internal static void SetTrustedDomainInfoStatus(DirectoryContext context, string sourceName, string targetName, TRUST_ATTRIBUTE attribute, bool status, bool isForest) { IntPtr intPtr = (IntPtr)0; IntPtr intPtr1 = (IntPtr)0; IntPtr hGlobalUni = (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(); hGlobalUni = Marshal.StringToHGlobalUni(targetName); UnsafeNativeMethods.RtlInitUnicodeString(lSAUNICODESTRING, hGlobalUni); int num = UnsafeNativeMethods.LsaQueryTrustedDomainInfoByName(policySafeHandle, lSAUNICODESTRING, TRUSTED_INFORMATION_CLASS.TrustedDomainInformationEx, ref intPtr); if (num == 0) { TRUSTED_DOMAIN_INFORMATION_EX tRUSTEDDOMAININFORMATIONEX = new TRUSTED_DOMAIN_INFORMATION_EX(); Marshal.PtrToStructure(intPtr, tRUSTEDDOMAININFORMATIONEX); TrustHelper.ValidateTrustAttribute(tRUSTEDDOMAININFORMATIONEX, isForest, sourceName, targetName); if (attribute != TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_CROSS_ORGANIZATION) { if (attribute != TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL) { if (attribute != TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) { throw new ArgumentException("attribute"); } else { if (!status) { TRUSTED_DOMAIN_INFORMATION_EX trustAttributes = tRUSTEDDOMAININFORMATIONEX; trustAttributes.TrustAttributes = trustAttributes.TrustAttributes & (TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_NON_TRANSITIVE | TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_UPLEVEL_ONLY | TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_FOREST_TRANSITIVE | TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_CROSS_ORGANIZATION | TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_WITHIN_FOREST | TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL); } else { TRUSTED_DOMAIN_INFORMATION_EX trustAttributes1 = tRUSTEDDOMAININFORMATIONEX; trustAttributes1.TrustAttributes = trustAttributes1.TrustAttributes | TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN; } } } else { if (!status) { TRUSTED_DOMAIN_INFORMATION_EX tRUSTEDDOMAININFORMATIONEX1 = tRUSTEDDOMAININFORMATIONEX; tRUSTEDDOMAININFORMATIONEX1.TrustAttributes = tRUSTEDDOMAININFORMATIONEX1.TrustAttributes | TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL; } else { TRUSTED_DOMAIN_INFORMATION_EX trustAttributes2 = tRUSTEDDOMAININFORMATIONEX; trustAttributes2.TrustAttributes = trustAttributes2.TrustAttributes & (TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_NON_TRANSITIVE | TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_UPLEVEL_ONLY | TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN | TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_FOREST_TRANSITIVE | TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_CROSS_ORGANIZATION | TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_WITHIN_FOREST); } } } else { if (!status) { TRUSTED_DOMAIN_INFORMATION_EX tRUSTEDDOMAININFORMATIONEX2 = tRUSTEDDOMAININFORMATIONEX; tRUSTEDDOMAININFORMATIONEX2.TrustAttributes = tRUSTEDDOMAININFORMATIONEX2.TrustAttributes & (TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_NON_TRANSITIVE | TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_UPLEVEL_ONLY | TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN | TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_FOREST_TRANSITIVE | TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_WITHIN_FOREST | TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL); } else { TRUSTED_DOMAIN_INFORMATION_EX trustAttributes3 = tRUSTEDDOMAININFORMATIONEX; trustAttributes3.TrustAttributes = trustAttributes3.TrustAttributes | TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_CROSS_ORGANIZATION; } } intPtr1 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TRUSTED_DOMAIN_INFORMATION_EX))); Marshal.StructureToPtr(tRUSTEDDOMAININFORMATIONEX, intPtr1, false); num = UnsafeNativeMethods.LsaSetTrustedDomainInfoByName(policySafeHandle, lSAUNICODESTRING, TRUSTED_INFORMATION_CLASS.TrustedDomainInformationEx, intPtr1); if (num != 0) { throw ExceptionHelper.GetExceptionFromErrorCode(UnsafeNativeMethods.LsaNtStatusToWinError(num), policyServerName); } } else { int winError = UnsafeNativeMethods.LsaNtStatusToWinError(num); if (winError != TrustHelper.STATUS_OBJECT_NAME_NOT_FOUND) { throw ExceptionHelper.GetExceptionFromErrorCode(winError, policyServerName); } else { if (!isForest) { object[] objArray = new object[2]; objArray[0] = sourceName; objArray[1] = targetName; throw new ActiveDirectoryObjectNotFoundException(Res.GetString("DomainTrustDoesNotExist", objArray), typeof(TrustRelationshipInformation), null); } else { object[] objArray1 = new object[2]; objArray1[0] = sourceName; objArray1[1] = targetName; throw new ActiveDirectoryObjectNotFoundException(Res.GetString("ForestTrustDoesNotExist", objArray1), typeof(ForestTrustRelationshipInformation), null); } } } } finally { if (flag) { Utils.Revert(); } if (hGlobalUni != (IntPtr)0) { Marshal.FreeHGlobal(hGlobalUni); } if (intPtr != (IntPtr)0) { UnsafeNativeMethods.LsaFreeMemory(intPtr); } if (intPtr1 != (IntPtr)0) { Marshal.FreeHGlobal(intPtr1); } } } catch { throw; } }
internal static void CreateTrust(DirectoryContext sourceContext, string sourceName, DirectoryContext targetContext, string targetName, bool isForest, TrustDirection direction, string password) { LSA_AUTH_INFORMATION structure = null; TRUSTED_DOMAIN_AUTH_INFORMATION authInfo = null; TRUSTED_DOMAIN_INFORMATION_EX domainEx = null; IntPtr zero = IntPtr.Zero; IntPtr hglobal = IntPtr.Zero; IntPtr ptr = IntPtr.Zero; IntPtr domainHandle = IntPtr.Zero; PolicySafeHandle handle = null; IntPtr ptr5 = IntPtr.Zero; bool flag = false; string serverName = null; ptr = GetTrustedDomainInfo(targetContext, targetName, isForest); try { try { POLICY_DNS_DOMAIN_INFO policy_dns_domain_info = new POLICY_DNS_DOMAIN_INFO(); Marshal.PtrToStructure(ptr, policy_dns_domain_info); structure = new LSA_AUTH_INFORMATION(); zero = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FileTime))); UnsafeNativeMethods.GetSystemTimeAsFileTime(zero); FileTime time = new FileTime(); Marshal.PtrToStructure(zero, time); structure.LastUpdateTime = new LARGE_INTEGER(); structure.LastUpdateTime.lowPart = time.lower; structure.LastUpdateTime.highPart = time.higher; structure.AuthType = TRUST_AUTH_TYPE_CLEAR; hglobal = Marshal.StringToHGlobalUni(password); structure.AuthInfo = hglobal; structure.AuthInfoLength = password.Length * 2; ptr5 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LSA_AUTH_INFORMATION))); Marshal.StructureToPtr(structure, ptr5, false); authInfo = new TRUSTED_DOMAIN_AUTH_INFORMATION(); if ((direction & TrustDirection.Inbound) != ((TrustDirection) 0)) { authInfo.IncomingAuthInfos = 1; authInfo.IncomingAuthenticationInformation = ptr5; authInfo.IncomingPreviousAuthenticationInformation = IntPtr.Zero; } if ((direction & TrustDirection.Outbound) != ((TrustDirection) 0)) { authInfo.OutgoingAuthInfos = 1; authInfo.OutgoingAuthenticationInformation = ptr5; authInfo.OutgoingPreviousAuthenticationInformation = IntPtr.Zero; } domainEx = new TRUSTED_DOMAIN_INFORMATION_EX { FlatName = policy_dns_domain_info.Name, Name = policy_dns_domain_info.DnsDomainName, Sid = policy_dns_domain_info.Sid, TrustType = TRUST_TYPE_UPLEVEL, TrustDirection = (int) direction }; if (isForest) { domainEx.TrustAttributes = TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_FOREST_TRANSITIVE; } else { domainEx.TrustAttributes = TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN; } serverName = System.DirectoryServices.ActiveDirectory.Utils.GetPolicyServerName(sourceContext, isForest, false, sourceName); flag = System.DirectoryServices.ActiveDirectory.Utils.Impersonate(sourceContext); handle = new PolicySafeHandle(System.DirectoryServices.ActiveDirectory.Utils.GetPolicyHandle(serverName)); int status = UnsafeNativeMethods.LsaCreateTrustedDomainEx(handle, domainEx, authInfo, TRUSTED_SET_POSIX | TRUSTED_SET_AUTH, out domainHandle); if (status != 0) { status = UnsafeNativeMethods.LsaNtStatusToWinError(status); if (status != ERROR_ALREADY_EXISTS) { throw ExceptionHelper.GetExceptionFromErrorCode(status, serverName); } if (isForest) { throw new ActiveDirectoryObjectExistsException(Res.GetString("AlreadyExistingForestTrust", new object[] { sourceName, targetName })); } throw new ActiveDirectoryObjectExistsException(Res.GetString("AlreadyExistingDomainTrust", new object[] { sourceName, targetName })); } } finally { if (flag) { System.DirectoryServices.ActiveDirectory.Utils.Revert(); } if (zero != IntPtr.Zero) { Marshal.FreeHGlobal(zero); } if (domainHandle != IntPtr.Zero) { UnsafeNativeMethods.LsaClose(domainHandle); } if (ptr != IntPtr.Zero) { UnsafeNativeMethods.LsaFreeMemory(ptr); } if (hglobal != IntPtr.Zero) { Marshal.FreeHGlobal(hglobal); } if (ptr5 != IntPtr.Zero) { Marshal.FreeHGlobal(ptr5); } } } catch { throw; } }
internal static void CreateTrust(DirectoryContext sourceContext, string sourceName, DirectoryContext targetContext, string targetName, bool isForest, TrustDirection direction, string password) { IntPtr intPtr = (IntPtr)0; IntPtr hGlobalUni = (IntPtr)0; IntPtr intPtr1 = (IntPtr)0; IntPtr intPtr2 = (IntPtr)0; bool flag = false; IntPtr trustedDomainInfo = TrustHelper.GetTrustedDomainInfo(targetContext, targetName, isForest); try { try { POLICY_DNS_DOMAIN_INFO pOLICYDNSDOMAININFO = new POLICY_DNS_DOMAIN_INFO(); Marshal.PtrToStructure(trustedDomainInfo, pOLICYDNSDOMAININFO); LSA_AUTH_INFORMATION lSAAUTHINFORMATION = new LSA_AUTH_INFORMATION(); intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FileTime))); UnsafeNativeMethods.GetSystemTimeAsFileTime(intPtr); FileTime fileTime = new FileTime(); Marshal.PtrToStructure(intPtr, fileTime); lSAAUTHINFORMATION.LastUpdateTime = new LARGE_INTEGER(); lSAAUTHINFORMATION.LastUpdateTime.lowPart = fileTime.lower; lSAAUTHINFORMATION.LastUpdateTime.highPart = fileTime.higher; lSAAUTHINFORMATION.AuthType = TrustHelper.TRUST_AUTH_TYPE_CLEAR; hGlobalUni = Marshal.StringToHGlobalUni(password); lSAAUTHINFORMATION.AuthInfo = hGlobalUni; lSAAUTHINFORMATION.AuthInfoLength = password.Length * 2; intPtr2 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LSA_AUTH_INFORMATION))); Marshal.StructureToPtr(lSAAUTHINFORMATION, intPtr2, false); TRUSTED_DOMAIN_AUTH_INFORMATION tRUSTEDDOMAINAUTHINFORMATION = new TRUSTED_DOMAIN_AUTH_INFORMATION(); if ((direction & TrustDirection.Inbound) != 0) { tRUSTEDDOMAINAUTHINFORMATION.IncomingAuthInfos = 1; tRUSTEDDOMAINAUTHINFORMATION.IncomingAuthenticationInformation = intPtr2; tRUSTEDDOMAINAUTHINFORMATION.IncomingPreviousAuthenticationInformation = (IntPtr)0; } if ((direction & TrustDirection.Outbound) != 0) { tRUSTEDDOMAINAUTHINFORMATION.OutgoingAuthInfos = 1; tRUSTEDDOMAINAUTHINFORMATION.OutgoingAuthenticationInformation = intPtr2; tRUSTEDDOMAINAUTHINFORMATION.OutgoingPreviousAuthenticationInformation = (IntPtr)0; } TRUSTED_DOMAIN_INFORMATION_EX tRUSTEDDOMAININFORMATIONEX = new TRUSTED_DOMAIN_INFORMATION_EX(); tRUSTEDDOMAININFORMATIONEX.FlatName = pOLICYDNSDOMAININFO.Name; tRUSTEDDOMAININFORMATIONEX.Name = pOLICYDNSDOMAININFO.DnsDomainName; tRUSTEDDOMAININFORMATIONEX.Sid = pOLICYDNSDOMAININFO.Sid; tRUSTEDDOMAININFORMATIONEX.TrustType = TrustHelper.TRUST_TYPE_UPLEVEL; tRUSTEDDOMAININFORMATIONEX.TrustDirection = (int)direction; if (!isForest) { tRUSTEDDOMAININFORMATIONEX.TrustAttributes = TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN; } else { tRUSTEDDOMAININFORMATIONEX.TrustAttributes = TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_FOREST_TRANSITIVE; } string policyServerName = Utils.GetPolicyServerName(sourceContext, isForest, false, sourceName); flag = Utils.Impersonate(sourceContext); PolicySafeHandle policySafeHandle = new PolicySafeHandle(Utils.GetPolicyHandle(policyServerName)); int winError = UnsafeNativeMethods.LsaCreateTrustedDomainEx(policySafeHandle, tRUSTEDDOMAININFORMATIONEX, tRUSTEDDOMAINAUTHINFORMATION, TrustHelper.TRUSTED_SET_POSIX | TrustHelper.TRUSTED_SET_AUTH, out intPtr1); if (winError != 0) { winError = UnsafeNativeMethods.LsaNtStatusToWinError(winError); if (winError != TrustHelper.ERROR_ALREADY_EXISTS) { throw ExceptionHelper.GetExceptionFromErrorCode(winError, policyServerName); } else { if (!isForest) { object[] objArray = new object[2]; objArray[0] = sourceName; objArray[1] = targetName; throw new ActiveDirectoryObjectExistsException(Res.GetString("AlreadyExistingDomainTrust", objArray)); } else { object[] objArray1 = new object[2]; objArray1[0] = sourceName; objArray1[1] = targetName; throw new ActiveDirectoryObjectExistsException(Res.GetString("AlreadyExistingForestTrust", objArray1)); } } } } finally { if (flag) { Utils.Revert(); } if (intPtr != (IntPtr)0) { Marshal.FreeHGlobal(intPtr); } if (intPtr1 != (IntPtr)0) { UnsafeNativeMethods.LsaClose(intPtr1); } if (trustedDomainInfo != (IntPtr)0) { UnsafeNativeMethods.LsaFreeMemory(trustedDomainInfo); } if (hGlobalUni != (IntPtr)0) { Marshal.FreeHGlobal(hGlobalUni); } if (intPtr2 != (IntPtr)0) { Marshal.FreeHGlobal(intPtr2); } } } catch { throw; } }
private static void ValidateTrust(PolicySafeHandle handle, LSA_UNICODE_STRING trustedDomainName, string sourceName, string targetName, bool isForest, int direction, string serverName) { IntPtr zero = IntPtr.Zero; int status = UnsafeNativeMethods.LsaQueryTrustedDomainInfoByName(handle, trustedDomainName, TRUSTED_INFORMATION_CLASS.TrustedDomainInformationEx, ref zero); if (status != 0) { int errorCode = UnsafeNativeMethods.LsaNtStatusToWinError(status); if (errorCode != STATUS_OBJECT_NAME_NOT_FOUND) { throw ExceptionHelper.GetExceptionFromErrorCode(errorCode, serverName); } if (isForest) { throw new ActiveDirectoryObjectNotFoundException(Res.GetString("ForestTrustDoesNotExist", new object[] { sourceName, targetName }), typeof(ForestTrustRelationshipInformation), null); } throw new ActiveDirectoryObjectNotFoundException(Res.GetString("DomainTrustDoesNotExist", new object[] { sourceName, targetName }), typeof(TrustRelationshipInformation), null); } try { TRUSTED_DOMAIN_INFORMATION_EX structure = new TRUSTED_DOMAIN_INFORMATION_EX(); Marshal.PtrToStructure(zero, structure); ValidateTrustAttribute(structure, isForest, sourceName, targetName); if ((direction != 0) && ((direction & structure.TrustDirection) == 0)) { if (isForest) { throw new ActiveDirectoryObjectNotFoundException(Res.GetString("WrongTrustDirection", new object[] { sourceName, targetName, (TrustDirection) direction }), typeof(ForestTrustRelationshipInformation), null); } throw new ActiveDirectoryObjectNotFoundException(Res.GetString("WrongTrustDirection", new object[] { sourceName, targetName, (TrustDirection) direction }), typeof(TrustRelationshipInformation), null); } } finally { if (zero != IntPtr.Zero) { UnsafeNativeMethods.LsaFreeMemory(zero); } } }
private static void ValidateTrust(PolicySafeHandle handle, LSA_UNICODE_STRING trustedDomainName, string sourceName, string targetName, bool isForest, int direction, string serverName) { IntPtr intPtr = (IntPtr)0; int num = UnsafeNativeMethods.LsaQueryTrustedDomainInfoByName(handle, trustedDomainName, TRUSTED_INFORMATION_CLASS.TrustedDomainInformationEx, ref intPtr); if (num == 0) { try { TRUSTED_DOMAIN_INFORMATION_EX tRUSTEDDOMAININFORMATIONEX = new TRUSTED_DOMAIN_INFORMATION_EX(); Marshal.PtrToStructure(intPtr, tRUSTEDDOMAININFORMATIONEX); TrustHelper.ValidateTrustAttribute(tRUSTEDDOMAININFORMATIONEX, isForest, sourceName, targetName); if (direction != 0 && (direction & tRUSTEDDOMAININFORMATIONEX.TrustDirection) == 0) { if (!isForest) { object[] objArray = new object[3]; objArray[0] = sourceName; objArray[1] = targetName; objArray[2] = (TrustDirection)direction; throw new ActiveDirectoryObjectNotFoundException(Res.GetString("WrongTrustDirection", objArray), typeof(TrustRelationshipInformation), null); } else { object[] objArray1 = new object[3]; objArray1[0] = sourceName; objArray1[1] = targetName; objArray1[2] = (TrustDirection)direction; throw new ActiveDirectoryObjectNotFoundException(Res.GetString("WrongTrustDirection", objArray1), typeof(ForestTrustRelationshipInformation), null); } } } finally { if (intPtr != (IntPtr)0) { UnsafeNativeMethods.LsaFreeMemory(intPtr); } } return; } else { int winError = UnsafeNativeMethods.LsaNtStatusToWinError(num); if (winError != TrustHelper.STATUS_OBJECT_NAME_NOT_FOUND) { throw ExceptionHelper.GetExceptionFromErrorCode(winError, serverName); } else { if (!isForest) { object[] objArray2 = new object[2]; objArray2[0] = sourceName; objArray2[1] = targetName; throw new ActiveDirectoryObjectNotFoundException(Res.GetString("DomainTrustDoesNotExist", objArray2), typeof(TrustRelationshipInformation), null); } else { object[] objArray3 = new object[2]; objArray3[0] = sourceName; objArray3[1] = targetName; throw new ActiveDirectoryObjectNotFoundException(Res.GetString("ForestTrustDoesNotExist", objArray3), typeof(ForestTrustRelationshipInformation), null); } } } }
internal static void SetTrustedDomainInfoStatus(DirectoryContext context, string? sourceName, string targetName, TRUST_ATTRIBUTE attribute, bool status, bool isForest) { PolicySafeHandle? handle = null; IntPtr buffer = (IntPtr)0; IntPtr newInfo = (IntPtr)0; LSA_UNICODE_STRING? trustedDomainName = null; bool impersonated = false; IntPtr target = (IntPtr)0; string? serverName = null; serverName = Utils.GetPolicyServerName(context, isForest, false, sourceName); impersonated = Utils.Impersonate(context); try { try { // get the policy handle first handle = new PolicySafeHandle(Utils.GetPolicyHandle(serverName)); // get the target name trustedDomainName = new LSA_UNICODE_STRING(); target = Marshal.StringToHGlobalUni(targetName); UnsafeNativeMethods.RtlInitUnicodeString(trustedDomainName, target); // get the trusted domain information int result = UnsafeNativeMethods.LsaQueryTrustedDomainInfoByName(handle, trustedDomainName, TRUSTED_INFORMATION_CLASS.TrustedDomainInformationEx, ref buffer); if (result != 0) { int win32Error = UnsafeNativeMethods.LsaNtStatusToWinError(result); // 2 ERROR_FILE_NOT_FOUND <--> 0xc0000034 STATUS_OBJECT_NAME_NOT_FOUND if (win32Error == STATUS_OBJECT_NAME_NOT_FOUND) { if (isForest) throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.ForestTrustDoesNotExist, sourceName, targetName), typeof(ForestTrustRelationshipInformation), null); else throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.DomainTrustDoesNotExist, sourceName, targetName), typeof(TrustRelationshipInformation), null); } else throw ExceptionHelper.GetExceptionFromErrorCode(win32Error, serverName); } Debug.Assert(buffer != (IntPtr)0); // get the managed structre representation TRUSTED_DOMAIN_INFORMATION_EX domainInfo = new TRUSTED_DOMAIN_INFORMATION_EX(); Marshal.PtrToStructure(buffer, domainInfo); // validate this is the trust that the user refers to ValidateTrustAttribute(domainInfo, isForest, sourceName, targetName); // change the attribute value properly // selective authentication if (attribute == TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_CROSS_ORGANIZATION) { if (status) { // turns on selective authentication domainInfo.TrustAttributes |= TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_CROSS_ORGANIZATION; } else { // turns off selective authentication domainInfo.TrustAttributes &= ~(TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_CROSS_ORGANIZATION); } } // user wants to change sid filtering behavior for forest trust else if (attribute == TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL) { if (status) { // user wants sid filtering behavior domainInfo.TrustAttributes &= ~(TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL); } else { // users wants to turn off sid filtering behavior domainInfo.TrustAttributes |= TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL; } } // user wants to change sid filtering behavior for external trust else if (attribute == TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) { if (status) { // user wants sid filtering behavior domainInfo.TrustAttributes |= TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN; } else { // user wants to turn off sid filtering behavior domainInfo.TrustAttributes &= ~(TRUST_ATTRIBUTE.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN); } } else { throw new ArgumentException(nameof(attribute)); } // reconstruct the unmanaged structure to set it back newInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TRUSTED_DOMAIN_INFORMATION_EX))); Marshal.StructureToPtr(domainInfo, newInfo, false); result = UnsafeNativeMethods.LsaSetTrustedDomainInfoByName(handle, trustedDomainName, TRUSTED_INFORMATION_CLASS.TrustedDomainInformationEx, newInfo); if (result != 0) { throw ExceptionHelper.GetExceptionFromErrorCode(UnsafeNativeMethods.LsaNtStatusToWinError(result), serverName); } return; } finally { if (impersonated) Utils.Revert(); if (target != (IntPtr)0) Marshal.FreeHGlobal(target); if (buffer != (IntPtr)0) UnsafeNativeMethods.LsaFreeMemory(buffer); if (newInfo != (IntPtr)0) Marshal.FreeHGlobal(newInfo); } } catch { throw; } }