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;
            }
        }
예제 #2
0
        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; }
        }