public void MoveToAnotherSite(string siteName) { CheckIfDisposed(); // validate siteName if (siteName == null) { throw new ArgumentNullException(nameof(siteName)); } if (siteName.Length == 0) { throw new ArgumentException(SR.EmptyStringParameter, nameof(siteName)); } // the dc is really being moved to a different site if (Utils.Compare(SiteName, siteName) != 0) { DirectoryEntry newParentEntry = null; try { // Bind to the target site's server container // Get the distinguished name for the site string parentDN = "CN=Servers,CN=" + siteName + "," + directoryEntryMgr.ExpandWellKnownDN(WellKnownDN.SitesContainer); newParentEntry = DirectoryEntryManager.GetDirectoryEntry(context, parentDN); string serverName = (this is DomainController) ? ((DomainController)this).ServerObjectName : ((AdamInstance)this).ServerObjectName; DirectoryEntry serverEntry = directoryEntryMgr.GetCachedDirectoryEntry(serverName); // force binding (needed otherwise S.DS throw an exception while releasing the COM interface pointer) _ = (string)PropertyManager.GetPropertyValue(context, serverEntry, PropertyManager.DistinguishedName); // move the object to the servers container of the target site serverEntry.MoveTo(newParentEntry); } catch (COMException e) { throw ExceptionHelper.GetExceptionFromCOMException(context, e); } finally { if (newParentEntry != null) { newParentEntry.Dispose(); } } // remove stale cached directory entries // invalidate the cached properties that get affected by this siteInfoModified = true; cachedSiteName = null; if (cachedSiteObjectName != null) { directoryEntryMgr.RemoveIfExists(cachedSiteObjectName); cachedSiteObjectName = null; } if (cachedServerObjectName != null) { directoryEntryMgr.RemoveIfExists(cachedServerObjectName); cachedServerObjectName = null; } if (cachedNtdsaObjectName != null) { directoryEntryMgr.RemoveIfExists(cachedNtdsaObjectName); cachedNtdsaObjectName = null; } } }
internal new static GlobalCatalog FindOneInternal(DirectoryContext context, string forestName, string siteName, LocatorOptions flag) { DomainControllerInfo domainControllerInfo = null; DomainControllerInfo domainControllerInfo1 = null; int num = 0; if (siteName == null || siteName.Length != 0) { if (((int)flag & -23554) == 0) { if (forestName == null) { int num1 = Locator.DsGetDcNameWrapper(null, DirectoryContext.GetLoggedOnDomain(), null, (long)16, out domainControllerInfo1); if (num1 != 0x54b) { if (num1 == 0) { forestName = domainControllerInfo1.DnsForestName; } else { throw ExceptionHelper.GetExceptionFromErrorCode(num); } } else { throw new ActiveDirectoryObjectNotFoundException(Res.GetString("ContextNotAssociatedWithDomain"), typeof(GlobalCatalog), null); } } num = Locator.DsGetDcNameWrapper(null, forestName, siteName, (int)flag | 80, out domainControllerInfo); if (num != 0x54b) { if (num != 0x3ec) { if (num == 0) { string str = domainControllerInfo.DomainControllerName.Substring(2); DirectoryContext newDirectoryContext = Utils.GetNewDirectoryContext(str, DirectoryContextType.DirectoryServer, context); return(new GlobalCatalog(newDirectoryContext, str)); } else { throw ExceptionHelper.GetExceptionFromErrorCode(num); } } else { throw new ArgumentException(Res.GetString("InvalidFlags"), "flag"); } } else { object[] objArray = new object[1]; objArray[0] = forestName; throw new ActiveDirectoryObjectNotFoundException(Res.GetString("GCNotFoundInForest", objArray), typeof(GlobalCatalog), null); } } else { throw new ArgumentException(Res.GetString("InvalidFlags"), "flag"); } } else { throw new ArgumentException(Res.GetString("EmptyStringParameter"), "siteName"); } }
public static ConfigurationSet GetConfigurationSet(DirectoryContext context) { // check that the argument is not null if (context == null) { throw new ArgumentNullException("context"); } // target should ConfigurationSet or DirectoryServer if ((context.ContextType != DirectoryContextType.ConfigurationSet) && (context.ContextType != DirectoryContextType.DirectoryServer)) { throw new ArgumentException(SR.TargetShouldBeServerORConfigSet, "context"); } // target should be an adam config set or server if (((!context.isServer()) && (!context.isADAMConfigSet()))) { // the target should be a server or an ADAM Config Set if (context.ContextType == DirectoryContextType.ConfigurationSet) { throw new ActiveDirectoryObjectNotFoundException(SR.ConfigSetNotFound, typeof(ConfigurationSet), context.Name); } else { throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.AINotFound, context.Name), typeof(ConfigurationSet), null); } } // work with copy of the context context = new DirectoryContext(context); // // bind to rootdse of an adam instance (if target is already a server, verify that it is an adam instance) // DirectoryEntryManager directoryEntryMgr = new DirectoryEntryManager(context); DirectoryEntry rootDSE = null; string configSetName = null; try { rootDSE = directoryEntryMgr.GetCachedDirectoryEntry(WellKnownDN.RootDSE); if ((context.isServer()) && (!Utils.CheckCapability(rootDSE, Capability.ActiveDirectoryApplicationMode))) { throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.AINotFound, context.Name), typeof(ConfigurationSet), null); } configSetName = (string)PropertyManager.GetPropertyValue(context, rootDSE, PropertyManager.ConfigurationNamingContext); } catch (COMException e) { int errorCode = e.ErrorCode; if (errorCode == unchecked ((int)0x8007203a)) { if (context.ContextType == DirectoryContextType.ConfigurationSet) { throw new ActiveDirectoryObjectNotFoundException(SR.ConfigSetNotFound, typeof(ConfigurationSet), context.Name); } else { throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.AINotFound, context.Name), typeof(ConfigurationSet), null); } } else { throw ExceptionHelper.GetExceptionFromCOMException(context, e); } } catch (ActiveDirectoryObjectNotFoundException) { if (context.ContextType == DirectoryContextType.ConfigurationSet) { // this is the case when we could not find an ADAM instance in that config set throw new ActiveDirectoryObjectNotFoundException(SR.ConfigSetNotFound, typeof(ConfigurationSet), context.Name); } else { throw; } } // return config set object return(new ConfigurationSet(context, configSetName, directoryEntryMgr)); }
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; } }
public static ActiveDirectorySiteLinkBridge FindByName(DirectoryContext context, string bridgeName, ActiveDirectoryTransportType transport) { ValidateArgument(context, bridgeName, transport); // work with copy of the context context = new DirectoryContext(context); // bind to the rootdse to get the configurationnamingcontext DirectoryEntry de; try { de = DirectoryEntryManager.GetDirectoryEntry(context, WellKnownDN.RootDSE); string config = (string)PropertyManager.GetPropertyValue(context, de, PropertyManager.ConfigurationNamingContext); string containerDN = "CN=Inter-Site Transports,CN=Sites," + config; if (transport == ActiveDirectoryTransportType.Rpc) { containerDN = "CN=IP," + containerDN; } else { containerDN = "CN=SMTP," + containerDN; } de = DirectoryEntryManager.GetDirectoryEntry(context, containerDN); } catch (COMException e) { throw ExceptionHelper.GetExceptionFromCOMException(context, e); } catch (ActiveDirectoryObjectNotFoundException) { // this is the case where the context is a config set and we could not find an ADAM instance in that config set throw new ActiveDirectoryOperationException(SR.Format(SR.ADAMInstanceNotFoundInConfigSet, context.Name)); } try { ADSearcher adSearcher = new ADSearcher(de, "(&(objectClass=siteLinkBridge)(objectCategory=SiteLinkBridge)(name=" + Utils.GetEscapedFilterValue(bridgeName) + "))", new string[] { "distinguishedName" }, SearchScope.OneLevel, false, /* don't need paged search */ false /* don't need to cache result */); SearchResult srchResult = adSearcher.FindOne(); if (srchResult == null) { // no such site link bridge object Exception e = new ActiveDirectoryObjectNotFoundException(SR.DSNotFound, typeof(ActiveDirectorySiteLinkBridge), bridgeName); throw e; } else { DirectoryEntry connectionEntry = srchResult.GetDirectoryEntry(); // it is an existing site link bridge object ActiveDirectorySiteLinkBridge bridge = new ActiveDirectorySiteLinkBridge(context, bridgeName, transport, true); bridge.cachedEntry = connectionEntry; return(bridge); } } catch (COMException e) { if (e.ErrorCode == unchecked ((int)0x80072030)) { // if it is ADAM and transport type is SMTP, throw NotSupportedException. DirectoryEntry tmpDE = DirectoryEntryManager.GetDirectoryEntry(context, WellKnownDN.RootDSE); if (Utils.CheckCapability(tmpDE, Capability.ActiveDirectoryApplicationMode) && transport == ActiveDirectoryTransportType.Smtp) { throw new NotSupportedException(SR.NotSupportTransportSMTP); } else { // object is not found since we cannot even find the container in which to search throw new ActiveDirectoryObjectNotFoundException(SR.DSNotFound, typeof(ActiveDirectorySiteLinkBridge), bridgeName); } } throw ExceptionHelper.GetExceptionFromCOMException(context, e); } finally { de.Dispose(); } }
internal static AdamInstance FindAnyAdamInstance(DirectoryContext context) { if (context.ContextType != DirectoryContextType.ConfigurationSet) { // assuming it's an ADAM Instance // check that it is an ADAM server only (not AD) DirectoryEntryManager directoryEntryMgr = new DirectoryEntryManager(context); DirectoryEntry rootDSE = directoryEntryMgr.GetCachedDirectoryEntry(WellKnownDN.RootDSE); if (!Utils.CheckCapability(rootDSE, Capability.ActiveDirectoryApplicationMode)) { directoryEntryMgr.RemoveIfExists(directoryEntryMgr.ExpandWellKnownDN(WellKnownDN.RootDSE)); throw new ArgumentException(SR.TargetShouldBeServerORConfigSet, "context"); } string dnsHostName = (string)PropertyManager.GetPropertyValue(context, rootDSE, PropertyManager.DnsHostName); return(new AdamInstance(context, dnsHostName, directoryEntryMgr)); } // Now this is the case where context is a Config Set // Here we need to search for the service connection points in the forest // (if the forest object was created by specifying the server, we stick to that, else search in a GC) DirectoryEntry rootEntry = GetSearchRootEntry(Forest.GetCurrentForest()); ArrayList adamInstanceNames = new ArrayList(); try { string entryName = (string)rootEntry.Properties["distinguishedName"].Value; // Search for computer "serviceConnectionObjects" where the keywords attribute // contains the specified keyword // set up the searcher object // build the filter StringBuilder str = new StringBuilder(15); str.Append("(&("); str.Append(PropertyManager.ObjectCategory); str.Append("=serviceConnectionPoint)"); str.Append("("); str.Append(PropertyManager.Keywords); str.Append("=1.2.840.113556.1.4.1851)("); str.Append(PropertyManager.Keywords); str.Append("="); str.Append(Utils.GetEscapedFilterValue(context.Name)); // target = config set name str.Append("))"); string filter = str.ToString(); string[] propertiesToLoad = new string[1]; propertiesToLoad[0] = PropertyManager.ServiceBindingInformation; ADSearcher searcher = new ADSearcher(rootEntry, filter, propertiesToLoad, SearchScope.Subtree, false /*not paged search*/, false /*no cached results*/); SearchResultCollection resCol = searcher.FindAll(); try { foreach (SearchResult res in resCol) { // the binding info contains two values // "ldap://hostname:ldapport" // and "ldaps://hostname:sslport" // we need the "hostname:ldapport" value string prefix = "ldap://"; foreach (string bindingInfo in res.Properties[PropertyManager.ServiceBindingInformation]) { if ((bindingInfo.Length > prefix.Length) && (String.Compare(bindingInfo.Substring(0, prefix.Length), prefix, StringComparison.OrdinalIgnoreCase) == 0)) { adamInstanceNames.Add(bindingInfo.Substring(prefix.Length)); } } } } finally { resCol.Dispose(); } } catch (COMException e) { throw ExceptionHelper.GetExceptionFromCOMException(context, e); } finally { rootEntry.Dispose(); } // // we have all the adam instance names in teh form of server:port from the scp // now we need to find one that is alive // return(FindAliveAdamInstance(null, context, adamInstanceNames)); }
internal static new GlobalCatalog FindOneWithCredentialValidation(DirectoryContext context, string siteName, LocatorOptions flag) { GlobalCatalog gc; bool retry = false; bool credsValidated = false; // work with copy of the context context = new DirectoryContext(context); // authenticate against this GC to validate the credentials gc = FindOneInternal(context, context.Name, siteName, flag); try { ValidateCredential(gc, context); credsValidated = true; } catch (COMException e) { if (e.ErrorCode == unchecked ((int)0x8007203a)) { // server is down , so try again with force rediscovery if the flags did not already contain force rediscovery if ((flag & LocatorOptions.ForceRediscovery) == 0) { retry = true; } else { throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.GCNotFoundInForest, context.Name), typeof(GlobalCatalog), null); } } else { throw ExceptionHelper.GetExceptionFromCOMException(context, e); } } finally { if (!credsValidated) { gc.Dispose(); } } if (retry) { credsValidated = false; gc = FindOneInternal(context, context.Name, siteName, flag | LocatorOptions.ForceRediscovery); try { ValidateCredential(gc, context); credsValidated = true; } catch (COMException e) { if (e.ErrorCode == unchecked ((int)0x8007203a)) { // server is down throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.GCNotFoundInForest, context.Name), typeof(GlobalCatalog), null); } else { throw ExceptionHelper.GetExceptionFromCOMException(context, e); } } finally { if (!credsValidated) { gc.Dispose(); } } } return(gc); }
private void ValidateTargetAndSourceServer(DirectoryContext context, DirectoryServer sourceServer) { bool targetIsDC = false; DirectoryEntry?targetDE = null; DirectoryEntry?sourceDE = null; // first find out target is a dc or ADAM instance targetDE = DirectoryEntryManager.GetDirectoryEntry(context, WellKnownDN.RootDSE); try { if (Utils.CheckCapability(targetDE, Capability.ActiveDirectory)) { targetIsDC = true; } else if (!Utils.CheckCapability(targetDE, Capability.ActiveDirectoryApplicationMode)) { // if it is also not an ADAM instance, it is invalid then throw new ArgumentException(SR.DirectoryContextNeedHost, nameof(context)); } if (targetIsDC && !(sourceServer is DomainController)) { // target and sourceServer are not of the same type throw new ArgumentException(SR.ConnectionSourcServerShouldBeDC, nameof(sourceServer)); } else if (!targetIsDC && (sourceServer is DomainController)) { // target and sourceServer are not of the same type throw new ArgumentException(SR.ConnectionSourcServerShouldBeADAM, nameof(sourceServer)); } sourceDE = DirectoryEntryManager.GetDirectoryEntry(sourceServer.Context, WellKnownDN.RootDSE); // now if they are both dc, we need to check whether they come from the same forest if (targetIsDC) { string?targetRoot = (string?)PropertyManager.GetPropertyValue(context, targetDE, PropertyManager.RootDomainNamingContext); string?sourceRoot = (string?)PropertyManager.GetPropertyValue(sourceServer.Context, sourceDE, PropertyManager.RootDomainNamingContext); if (Utils.Compare(targetRoot, sourceRoot) != 0) { throw new ArgumentException(SR.ConnectionSourcServerSameForest, nameof(sourceServer)); } } else { string?targetRoot = (string?)PropertyManager.GetPropertyValue(context, targetDE, PropertyManager.ConfigurationNamingContext); string?sourceRoot = (string?)PropertyManager.GetPropertyValue(sourceServer.Context, sourceDE, PropertyManager.ConfigurationNamingContext); if (Utils.Compare(targetRoot, sourceRoot) != 0) { throw new ArgumentException(SR.ConnectionSourcServerSameConfigSet, nameof(sourceServer)); } } } catch (COMException e) { ExceptionHelper.GetExceptionFromCOMException(context, e); } finally { if (targetDE != null) { targetDE.Close(); } if (sourceDE != null) { sourceDE.Close(); } } }
internal static void UpdateTrustDirection(DirectoryContext context, string? sourceName, string? targetName, string password, bool isForest, TrustDirection newTrustDirection) { PolicySafeHandle? handle = null; IntPtr buffer = (IntPtr)0; LSA_UNICODE_STRING? trustedDomainName = null; IntPtr newBuffer = (IntPtr)0; bool impersonated = false; LSA_AUTH_INFORMATION? AuthData = null; IntPtr fileTime = (IntPtr)0; IntPtr unmanagedPassword = (IntPtr)0; IntPtr unmanagedAuthData = (IntPtr)0; TRUSTED_DOMAIN_AUTH_INFORMATION? AuthInfoEx = null; 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.TrustedDomainFullInformation, 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); } // get the managed structre representation TRUSTED_DOMAIN_FULL_INFORMATION domainInfo = new TRUSTED_DOMAIN_FULL_INFORMATION(); Marshal.PtrToStructure(buffer, domainInfo); // validate the trust attribute first ValidateTrustAttribute(domainInfo.Information!, isForest, sourceName, targetName); // change the attribute value properly 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; unmanagedAuthData = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LSA_AUTH_INFORMATION))); Marshal.StructureToPtr(AuthData, unmanagedAuthData, false); AuthInfoEx = new TRUSTED_DOMAIN_AUTH_INFORMATION(); if ((newTrustDirection & TrustDirection.Inbound) != 0) { AuthInfoEx.IncomingAuthInfos = 1; AuthInfoEx.IncomingAuthenticationInformation = unmanagedAuthData; AuthInfoEx.IncomingPreviousAuthenticationInformation = (IntPtr)0; } else { AuthInfoEx.IncomingAuthInfos = 0; AuthInfoEx.IncomingAuthenticationInformation = (IntPtr)0; AuthInfoEx.IncomingPreviousAuthenticationInformation = (IntPtr)0; } if ((newTrustDirection & TrustDirection.Outbound) != 0) { AuthInfoEx.OutgoingAuthInfos = 1; AuthInfoEx.OutgoingAuthenticationInformation = unmanagedAuthData; AuthInfoEx.OutgoingPreviousAuthenticationInformation = (IntPtr)0; } else { AuthInfoEx.OutgoingAuthInfos = 0; AuthInfoEx.OutgoingAuthenticationInformation = (IntPtr)0; AuthInfoEx.OutgoingPreviousAuthenticationInformation = (IntPtr)0; } // reconstruct the unmanaged structure to set it back domainInfo.AuthInformation = AuthInfoEx; // reset the trust direction domainInfo.Information!.TrustDirection = (int)newTrustDirection; newBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TRUSTED_DOMAIN_FULL_INFORMATION))); Marshal.StructureToPtr(domainInfo, newBuffer, false); result = UnsafeNativeMethods.LsaSetTrustedDomainInfoByName(handle, trustedDomainName, TRUSTED_INFORMATION_CLASS.TrustedDomainFullInformation, newBuffer); 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 (newBuffer != (IntPtr)0) Marshal.FreeHGlobal(newBuffer); if (fileTime != (IntPtr)0) Marshal.FreeHGlobal(fileTime); if (unmanagedPassword != (IntPtr)0) Marshal.FreeHGlobal(unmanagedPassword); if (unmanagedAuthData != (IntPtr)0) Marshal.FreeHGlobal(unmanagedAuthData); } } catch { throw; } }
public static ActiveDirectoryInterSiteTransport FindByTransportType(DirectoryContext context, ActiveDirectoryTransportType transport) { if (context == null) { throw new ArgumentNullException(nameof(context)); } // if target is not specified, then we determin the target from the logon credential, so if it is a local user context, it should fail if ((context.Name == null) && (!context.isRootDomain())) { throw new ArgumentException(SR.ContextNotAssociatedWithDomain, nameof(context)); } // more validation for the context, if the target is not null, then it should be either forest name or server name if (context.Name != null) { if (!(context.isRootDomain() || context.isServer() || context.isADAMConfigSet())) { throw new ArgumentException(SR.NotADOrADAM, nameof(context)); } } if (transport < ActiveDirectoryTransportType.Rpc || transport > ActiveDirectoryTransportType.Smtp) { throw new InvalidEnumArgumentException("value", (int)transport, typeof(ActiveDirectoryTransportType)); } // work with copy of the context context = new DirectoryContext(context); // bind to the rootdse to get the configurationnamingcontext DirectoryEntry de; try { de = DirectoryEntryManager.GetDirectoryEntry(context, WellKnownDN.RootDSE); string config = (string)PropertyManager.GetPropertyValue(context, de, PropertyManager.ConfigurationNamingContext); string containerDN = "CN=Inter-Site Transports,CN=Sites," + config; if (transport == ActiveDirectoryTransportType.Rpc) { containerDN = "CN=IP," + containerDN; } else { containerDN = "CN=SMTP," + containerDN; } de = DirectoryEntryManager.GetDirectoryEntry(context, containerDN); } catch (COMException e) { throw ExceptionHelper.GetExceptionFromCOMException(context, e); } catch (ActiveDirectoryObjectNotFoundException) { // this is the case where the context is a config set and we could not find an ADAM instance in that config set throw new ActiveDirectoryOperationException(SR.Format(SR.ADAMInstanceNotFoundInConfigSet, context.Name)); } try { de.RefreshCache(new string[] { "options" }); } catch (COMException e) { if (e.ErrorCode == unchecked ((int)0x80072030)) { // if it is ADAM and transport type is SMTP, throw NotSupportedException. DirectoryEntry tmpDE = DirectoryEntryManager.GetDirectoryEntry(context, WellKnownDN.RootDSE); if (Utils.CheckCapability(tmpDE, Capability.ActiveDirectoryApplicationMode) && transport == ActiveDirectoryTransportType.Smtp) { throw new NotSupportedException(SR.NotSupportTransportSMTP); } throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.TransportNotFound, transport.ToString()), typeof(ActiveDirectoryInterSiteTransport), transport.ToString()); } else { throw ExceptionHelper.GetExceptionFromCOMException(context, e); } } return(new ActiveDirectoryInterSiteTransport(context, transport, de)); }
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; } }
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 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; } }
internal static GlobalCatalog FindOneWithCredentialValidation(DirectoryContext context, string siteName, LocatorOptions flag) { bool flag1 = false; bool flag2 = false; context = new DirectoryContext(context); GlobalCatalog globalCatalog = GlobalCatalog.FindOneInternal(context, context.Name, siteName, flag); using (globalCatalog) { if (flag2) { try { DomainController.ValidateCredential(globalCatalog, context); } catch (COMException cOMException1) { COMException cOMException = cOMException1; if (cOMException.ErrorCode != -2147016646) { throw ExceptionHelper.GetExceptionFromCOMException(context, cOMException); } else { if ((flag & LocatorOptions.ForceRediscovery) != 0) { object[] name = new object[1]; name[0] = context.Name; throw new ActiveDirectoryObjectNotFoundException(Res.GetString("GCNotFoundInForest", name), typeof(GlobalCatalog), null); } else { flag1 = true; } } } } } if (flag1) { flag2 = false; globalCatalog = GlobalCatalog.FindOneInternal(context, context.Name, siteName, flag | LocatorOptions.ForceRediscovery); using (globalCatalog) { if (flag2) { try { DomainController.ValidateCredential(globalCatalog, context); } catch (COMException cOMException3) { COMException cOMException2 = cOMException3; if (cOMException2.ErrorCode != -2147016646) { throw ExceptionHelper.GetExceptionFromCOMException(context, cOMException2); } else { object[] objArray = new object[1]; objArray[0] = context.Name; throw new ActiveDirectoryObjectNotFoundException(Res.GetString("GCNotFoundInForest", objArray), typeof(GlobalCatalog), null); } } } } } return(globalCatalog); }
public static GlobalCatalog GetGlobalCatalog(DirectoryContext context) { string gcDnsName = null; bool isGlobalCatalog = false; DirectoryEntryManager directoryEntryMgr = null; // check that the context argument is not null if (context == null) { throw new ArgumentNullException(nameof(context)); } // target should be GC if (context.ContextType != DirectoryContextType.DirectoryServer) { throw new ArgumentException(SR.TargetShouldBeGC, nameof(context)); } // target should be a server if (!(context.isServer())) { throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.GCNotFound, context.Name), typeof(GlobalCatalog), context.Name); } // work with copy of the context context = new DirectoryContext(context); try { // Get dns name of the dc // by binding to root dse and getting the "dnsHostName" attribute // (also check that the "isGlobalCatalogReady" attribute is true) directoryEntryMgr = new DirectoryEntryManager(context); DirectoryEntry rootDSE = DirectoryEntryManager.GetDirectoryEntry(context, WellKnownDN.RootDSE); if (!Utils.CheckCapability(rootDSE, Capability.ActiveDirectory)) { throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.GCNotFound, context.Name), typeof(GlobalCatalog), context.Name); } gcDnsName = (string)PropertyManager.GetPropertyValue(context, rootDSE, PropertyManager.DnsHostName); isGlobalCatalog = (bool)bool.Parse((string)PropertyManager.GetPropertyValue(context, rootDSE, PropertyManager.IsGlobalCatalogReady)); if (!isGlobalCatalog) { throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.GCNotFound, context.Name), typeof(GlobalCatalog), context.Name); } } catch (COMException e) { int errorCode = e.ErrorCode; if (errorCode == unchecked ((int)0x8007203a)) { throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.GCNotFound, context.Name), typeof(GlobalCatalog), context.Name); } else { throw ExceptionHelper.GetExceptionFromCOMException(context, e); } } return(new GlobalCatalog(context, gcDnsName, directoryEntryMgr)); }
public static GlobalCatalog GetGlobalCatalog(DirectoryContext context) { string propertyValue = null; DirectoryEntryManager directoryEntryManager = null; if (context != null) { if (context.ContextType == DirectoryContextType.DirectoryServer) { if (context.isServer()) { context = new DirectoryContext(context); try { directoryEntryManager = new DirectoryEntryManager(context); DirectoryEntry directoryEntry = DirectoryEntryManager.GetDirectoryEntry(context, WellKnownDN.RootDSE); if (Utils.CheckCapability(directoryEntry, Capability.ActiveDirectory)) { propertyValue = (string)PropertyManager.GetPropertyValue(context, directoryEntry, PropertyManager.DnsHostName); bool flag = bool.Parse((string)PropertyManager.GetPropertyValue(context, directoryEntry, PropertyManager.IsGlobalCatalogReady)); if (!flag) { object[] name = new object[1]; name[0] = context.Name; throw new ActiveDirectoryObjectNotFoundException(Res.GetString("GCNotFound", name), typeof(GlobalCatalog), context.Name); } } else { object[] objArray = new object[1]; objArray[0] = context.Name; throw new ActiveDirectoryObjectNotFoundException(Res.GetString("GCNotFound", objArray), typeof(GlobalCatalog), context.Name); } } catch (COMException cOMException1) { COMException cOMException = cOMException1; int errorCode = cOMException.ErrorCode; if (errorCode != -2147016646) { throw ExceptionHelper.GetExceptionFromCOMException(context, cOMException); } else { object[] name1 = new object[1]; name1[0] = context.Name; throw new ActiveDirectoryObjectNotFoundException(Res.GetString("GCNotFound", name1), typeof(GlobalCatalog), context.Name); } } return(new GlobalCatalog(context, propertyValue, directoryEntryManager)); } else { object[] objArray1 = new object[1]; objArray1[0] = context.Name; throw new ActiveDirectoryObjectNotFoundException(Res.GetString("GCNotFound", objArray1), typeof(GlobalCatalog), context.Name); } } else { throw new ArgumentException(Res.GetString("TargetShouldBeGC"), "context"); } } else { throw new ArgumentNullException("context"); } }
internal static new GlobalCatalog FindOneInternal(DirectoryContext context, string forestName, string siteName, LocatorOptions flag) { DomainControllerInfo domainControllerInfo; int errorCode = 0; if (siteName != null && siteName.Length == 0) { throw new ArgumentException(SR.EmptyStringParameter, nameof(siteName)); } // check that the flags passed have only the valid bits set if (((long)flag & (~((long)LocatorOptions.AvoidSelf | (long)LocatorOptions.ForceRediscovery | (long)LocatorOptions.KdcRequired | (long)LocatorOptions.TimeServerRequired | (long)LocatorOptions.WriteableRequired))) != 0) { throw new ArgumentException(SR.InvalidFlags, nameof(flag)); } if (forestName == null) { // get the dns name of the logged on forest DomainControllerInfo tempDomainControllerInfo; int error = Locator.DsGetDcNameWrapper(null, DirectoryContext.GetLoggedOnDomain(), null, (long)PrivateLocatorFlags.DirectoryServicesRequired, out tempDomainControllerInfo); if (error == NativeMethods.ERROR_NO_SUCH_DOMAIN) { // throw not found exception throw new ActiveDirectoryObjectNotFoundException(SR.ContextNotAssociatedWithDomain, typeof(GlobalCatalog), null); } else if (error != 0) { throw ExceptionHelper.GetExceptionFromErrorCode(errorCode); } Debug.Assert(tempDomainControllerInfo.DnsForestName != null); forestName = tempDomainControllerInfo.DnsForestName; } // call DsGetDcName errorCode = Locator.DsGetDcNameWrapper(null, forestName, siteName, (long)flag | (long)(PrivateLocatorFlags.GCRequired | PrivateLocatorFlags.DirectoryServicesRequired), out domainControllerInfo); if (errorCode == NativeMethods.ERROR_NO_SUCH_DOMAIN) { throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.GCNotFoundInForest, forestName), typeof(GlobalCatalog), null); } // this can only occur when flag is being explicitly passed (since the flags that we pass internally are valid) if (errorCode == NativeMethods.ERROR_INVALID_FLAGS) { throw new ArgumentException(SR.InvalidFlags, nameof(flag)); } else if (errorCode != 0) { throw ExceptionHelper.GetExceptionFromErrorCode(errorCode); } // create a GlobalCatalog object // the name is returned in the form "\\servername", so skip the "\\" Debug.Assert(domainControllerInfo.DomainControllerName.Length > 2); string globalCatalogName = domainControllerInfo.DomainControllerName.Substring(2); // create a new context object for the global catalog DirectoryContext gcContext = Utils.GetNewDirectoryContext(globalCatalogName, DirectoryContextType.DirectoryServer, context); return(new GlobalCatalog(gcContext, globalCatalogName)); }
public ReplicationConnection(DirectoryContext context, string name, DirectoryServer sourceServer, ActiveDirectorySchedule?schedule, ActiveDirectoryTransportType transport) { ValidateArgument(context, name); if (sourceServer == null) { throw new ArgumentNullException(nameof(sourceServer)); } if (transport < ActiveDirectoryTransportType.Rpc || transport > ActiveDirectoryTransportType.Smtp) { throw new InvalidEnumArgumentException("value", (int)transport, typeof(ActiveDirectoryTransportType)); } // work with copy of the context context = new DirectoryContext(context); ValidateTargetAndSourceServer(context, sourceServer); this.context = context; _connectionName = name; _transport = transport; DirectoryEntry de = DirectoryEntryManager.GetDirectoryEntry(context, WellKnownDN.RootDSE); try { string serverDN = (string)PropertyManager.GetPropertyValue(context, de, PropertyManager.ServerName) !; string connectionContainer = "CN=NTDS Settings," + serverDN; de = DirectoryEntryManager.GetDirectoryEntry(context, connectionContainer); // create the connection entry string rdn = "cn=" + _connectionName; rdn = Utils.GetEscapedPath(rdn); cachedDirectoryEntry = de.Children.Add(rdn, "nTDSConnection"); // set all the properties // sourceserver property DirectoryContext sourceServerContext = sourceServer.Context; de = DirectoryEntryManager.GetDirectoryEntry(sourceServerContext, WellKnownDN.RootDSE); string serverName = (string)PropertyManager.GetPropertyValue(sourceServerContext, de, PropertyManager.ServerName) !; serverName = "CN=NTDS Settings," + serverName; cachedDirectoryEntry.Properties["fromServer"].Add(serverName); // schedule property if (schedule != null) { cachedDirectoryEntry.Properties[nameof(schedule)].Value = schedule.GetUnmanagedSchedule(); } // transporttype property string transportPath = Utils.GetDNFromTransportType(TransportType, context); // verify that the transport is supported de = DirectoryEntryManager.GetDirectoryEntry(context, transportPath); try { de.Bind(true); } catch (COMException e) { if (e.ErrorCode == unchecked ((int)0x80072030)) { // if it is ADAM and transport type is SMTP, throw NotSupportedException. DirectoryEntry tmpDE = DirectoryEntryManager.GetDirectoryEntry(context, WellKnownDN.RootDSE); if (Utils.CheckCapability(tmpDE, Capability.ActiveDirectoryApplicationMode) && transport == ActiveDirectoryTransportType.Smtp) { throw new NotSupportedException(SR.NotSupportTransportSMTP); } } throw ExceptionHelper.GetExceptionFromCOMException(context, e); } cachedDirectoryEntry.Properties["transportType"].Add(transportPath); // enabledConnection property cachedDirectoryEntry.Properties["enabledConnection"].Value = false; // options cachedDirectoryEntry.Properties["options"].Value = 0; } catch (COMException e) { throw ExceptionHelper.GetExceptionFromCOMException(context, e); } finally { de.Close(); } }
public static ActiveDirectorySchema GetSchema(DirectoryContext context) { if (context == null) { throw new ArgumentNullException("context"); } if (((context.ContextType != DirectoryContextType.Forest) && (context.ContextType != DirectoryContextType.ConfigurationSet)) && (context.ContextType != DirectoryContextType.DirectoryServer)) { throw new ArgumentException(Res.GetString("NotADOrADAM"), "context"); } if ((context.Name == null) && !context.isRootDomain()) { throw new ActiveDirectoryObjectNotFoundException(Res.GetString("ContextNotAssociatedWithDomain"), typeof(ActiveDirectorySchema), null); } if (((context.Name != null) && !context.isRootDomain()) && (!context.isADAMConfigSet() && !context.isServer())) { if (context.ContextType == DirectoryContextType.Forest) { throw new ActiveDirectoryObjectNotFoundException(Res.GetString("ForestNotFound"), typeof(ActiveDirectorySchema), context.Name); } if (context.ContextType == DirectoryContextType.ConfigurationSet) { throw new ActiveDirectoryObjectNotFoundException(Res.GetString("ConfigSetNotFound"), typeof(ActiveDirectorySchema), context.Name); } throw new ActiveDirectoryObjectNotFoundException(Res.GetString("ServerNotFound", new object[] { context.Name }), typeof(ActiveDirectorySchema), null); } context = new DirectoryContext(context); DirectoryEntryManager directoryEntryMgr = new DirectoryEntryManager(context); string distinguishedName = null; try { DirectoryEntry cachedDirectoryEntry = directoryEntryMgr.GetCachedDirectoryEntry(WellKnownDN.RootDSE); if (context.isServer() && !Utils.CheckCapability(cachedDirectoryEntry, Capability.ActiveDirectoryOrADAM)) { throw new ActiveDirectoryObjectNotFoundException(Res.GetString("ServerNotFound", new object[] { context.Name }), typeof(ActiveDirectorySchema), null); } distinguishedName = (string)PropertyManager.GetPropertyValue(context, cachedDirectoryEntry, PropertyManager.SchemaNamingContext); } catch (COMException exception) { if (exception.ErrorCode != -2147016646) { throw ExceptionHelper.GetExceptionFromCOMException(context, exception); } if (context.ContextType == DirectoryContextType.Forest) { throw new ActiveDirectoryObjectNotFoundException(Res.GetString("ForestNotFound"), typeof(ActiveDirectorySchema), context.Name); } if (context.ContextType == DirectoryContextType.ConfigurationSet) { throw new ActiveDirectoryObjectNotFoundException(Res.GetString("ConfigSetNotFound"), typeof(ActiveDirectorySchema), context.Name); } throw new ActiveDirectoryObjectNotFoundException(Res.GetString("ServerNotFound", new object[] { context.Name }), typeof(ActiveDirectorySchema), null); } catch (ActiveDirectoryObjectNotFoundException) { if (context.ContextType == DirectoryContextType.ConfigurationSet) { throw new ActiveDirectoryObjectNotFoundException(Res.GetString("ConfigSetNotFound"), typeof(ActiveDirectorySchema), context.Name); } throw; } return(new ActiveDirectorySchema(context, distinguishedName, directoryEntryMgr)); }
public ActiveDirectorySiteLinkBridge(DirectoryContext context, string bridgeName, ActiveDirectoryTransportType transport) { ValidateArgument(context, bridgeName, transport); // work with copy of the context context = new DirectoryContext(context); this.context = context; _name = bridgeName; _transport = transport; // bind to the rootdse to get the configurationnamingcontext DirectoryEntry de; try { de = DirectoryEntryManager.GetDirectoryEntry(context, WellKnownDN.RootDSE); string config = (string)PropertyManager.GetPropertyValue(context, de, PropertyManager.ConfigurationNamingContext); string parentDN = null; if (transport == ActiveDirectoryTransportType.Rpc) { parentDN = "CN=IP,CN=Inter-Site Transports,CN=Sites," + config; } else { parentDN = "CN=SMTP,CN=Inter-Site Transports,CN=Sites," + config; } de = DirectoryEntryManager.GetDirectoryEntry(context, parentDN); } catch (COMException e) { throw ExceptionHelper.GetExceptionFromCOMException(context, e); } catch (ActiveDirectoryObjectNotFoundException) { // this is the case where the context is a config set and we could not find an ADAM instance in that config set throw new ActiveDirectoryOperationException(SR.Format(SR.ADAMInstanceNotFoundInConfigSet, context.Name)); } try { string rdn = "cn=" + _name; rdn = Utils.GetEscapedPath(rdn); cachedEntry = de.Children.Add(rdn, "siteLinkBridge"); } catch (COMException e) { if (e.ErrorCode == unchecked ((int)0x80072030)) { // if it is ADAM and transport type is SMTP, throw NotSupportedException. DirectoryEntry tmpDE = DirectoryEntryManager.GetDirectoryEntry(context, WellKnownDN.RootDSE); if (Utils.CheckCapability(tmpDE, Capability.ActiveDirectoryApplicationMode) && transport == ActiveDirectoryTransportType.Smtp) { throw new NotSupportedException(SR.NotSupportTransportSMTP); } } throw ExceptionHelper.GetExceptionFromCOMException(context, e); } finally { de.Dispose(); } }
internal IntPtr GetReplicationInfoHelper(IntPtr dsHandle, int type, int secondaryType, string partition, ref bool advanced, int context, LoadLibrarySafeHandle libHandle) { IntPtr info = (IntPtr)0; int result = 0; bool needToTryAgain = true; IntPtr functionPtr; // first try to use the DsReplicaGetInfo2W API which does not exist on win2k machine // call DsReplicaGetInfo2W functionPtr = UnsafeNativeMethods.GetProcAddress(libHandle, "DsReplicaGetInfo2W"); if (functionPtr == (IntPtr)0) { // a win2k machine which does not have it. functionPtr = UnsafeNativeMethods.GetProcAddress(libHandle, "DsReplicaGetInfoW"); if (functionPtr == (IntPtr)0) { throw ExceptionHelper.GetExceptionFromErrorCode(Marshal.GetLastWin32Error()); } UnsafeNativeMethods.DsReplicaGetInfoW dsReplicaGetInfoW = (UnsafeNativeMethods.DsReplicaGetInfoW)Marshal.GetDelegateForFunctionPointer(functionPtr, typeof(UnsafeNativeMethods.DsReplicaGetInfoW)); result = dsReplicaGetInfoW(dsHandle, secondaryType, partition, (IntPtr)0, ref info); advanced = false; needToTryAgain = false; } else { UnsafeNativeMethods.DsReplicaGetInfo2W dsReplicaGetInfo2W = (UnsafeNativeMethods.DsReplicaGetInfo2W)Marshal.GetDelegateForFunctionPointer(functionPtr, typeof(UnsafeNativeMethods.DsReplicaGetInfo2W)); result = dsReplicaGetInfo2W(dsHandle, type, partition, (IntPtr)0, null, null, 0, context, ref info); } // check the result if (needToTryAgain && result == DS_REPL_NOTSUPPORTED) { // this is the case that client is xp/win2k3, dc is win2k functionPtr = UnsafeNativeMethods.GetProcAddress(libHandle, "DsReplicaGetInfoW"); if (functionPtr == (IntPtr)0) { throw ExceptionHelper.GetExceptionFromErrorCode(Marshal.GetLastWin32Error()); } UnsafeNativeMethods.DsReplicaGetInfoW dsReplicaGetInfoW = (UnsafeNativeMethods.DsReplicaGetInfoW)Marshal.GetDelegateForFunctionPointer(functionPtr, typeof(UnsafeNativeMethods.DsReplicaGetInfoW)); result = dsReplicaGetInfoW(dsHandle, secondaryType, partition, (IntPtr)0, ref info); advanced = false; } if (result != 0) { if (partition != null) { // this is the case of meta data if (type == (int)DS_REPL_INFO_TYPE.DS_REPL_INFO_METADATA_2_FOR_OBJ) { if (result == ExceptionHelper.ERROR_DS_DRA_BAD_DN || result == ExceptionHelper.ERROR_DS_NAME_UNPARSEABLE) { throw new ArgumentException(ExceptionHelper.GetErrorMessage(result, false), "objectPath"); } DirectoryEntry verifyEntry = DirectoryEntryManager.GetDirectoryEntry(this.context, partition); try { verifyEntry.RefreshCache(new string[] { "name" }); } catch (COMException e) { if (e.ErrorCode == unchecked ((int)0x80072020) | // dir_error on server side e.ErrorCode == unchecked ((int)0x80072030)) // object not exists { throw new ArgumentException(SR.DSNoObject, "objectPath"); } else if (e.ErrorCode == unchecked ((int)0x80005000) | // bad path name e.ErrorCode == unchecked ((int)0x80072032)) // ERROR_DS_INVALID_DN_SYNTAX { throw new ArgumentException(SR.DSInvalidPath, "objectPath"); } } } else { if (!Partitions.Contains(partition)) { throw new ArgumentException(SR.ServerNotAReplica, nameof(partition)); } } } throw ExceptionHelper.GetExceptionFromErrorCode(result, Name); } return(info); }
private ArrayList GetApplicationPartitions() { ArrayList appNCs = new ArrayList(); DirectoryEntry rootDSE = _directoryEntryMgr.GetCachedDirectoryEntry(WellKnownDN.RootDSE); DirectoryEntry partitionsEntry = _directoryEntryMgr.GetCachedDirectoryEntry(WellKnownDN.PartitionsContainer); // search for all the "crossRef" objects that have the // ADS_SYSTEMFLAG_CR_NTDS_NC set and the SYSTEMFLAG_CR_NTDS_DOMAIN flag not set // (one-level search is good enough) // setup the directory searcher object // build the filter StringBuilder str = new StringBuilder(100); str.Append("(&("); str.Append(PropertyManager.ObjectCategory); str.Append("=crossRef)("); str.Append(PropertyManager.SystemFlags); str.Append(":1.2.840.113556.1.4.804:="); str.Append((int)SystemFlag.SystemFlagNtdsNC); str.Append(")(!("); str.Append(PropertyManager.SystemFlags); str.Append(":1.2.840.113556.1.4.803:="); str.Append((int)SystemFlag.SystemFlagNtdsDomain); str.Append(")))"); string filter = str.ToString(); string[] propertiesToLoad = new string[2]; propertiesToLoad[0] = PropertyManager.NCName; propertiesToLoad[1] = PropertyManager.MsDSNCReplicaLocations; ADSearcher searcher = new ADSearcher(partitionsEntry, filter, propertiesToLoad, SearchScope.OneLevel); SearchResultCollection resCol = null; try { resCol = searcher.FindAll(); string schemaNamingContext = (string)PropertyManager.GetPropertyValue(_context, rootDSE, PropertyManager.SchemaNamingContext); string configurationNamingContext = (string)PropertyManager.GetPropertyValue(_context, rootDSE, PropertyManager.ConfigurationNamingContext); foreach (SearchResult res in resCol) { // add the name of the appNC only if it is not // the Schema or Configuration partition string nCName = (string)PropertyManager.GetSearchResultPropertyValue(res, PropertyManager.NCName); if ((!(nCName.Equals(schemaNamingContext))) && (!(nCName.Equals(configurationNamingContext)))) { ResultPropertyValueCollection replicaLocations = res.Properties[PropertyManager.MsDSNCReplicaLocations]; if (replicaLocations.Count > 0) { string replicaName = Utils.GetAdamDnsHostNameFromNTDSA(_context, (string)replicaLocations[Utils.GetRandomIndex(replicaLocations.Count)]); DirectoryContext appNCContext = Utils.GetNewDirectoryContext(replicaName, DirectoryContextType.DirectoryServer, _context); appNCs.Add(new ApplicationPartition(appNCContext, nCName, null, ApplicationPartitionType.ADAMApplicationPartition, new DirectoryEntryManager(appNCContext))); } } } } catch (COMException e) { throw ExceptionHelper.GetExceptionFromCOMException(_context, e); } finally { if (resCol != null) { // call dispose on search result collection resCol.Dispose(); } } return(appNCs); }
internal void SyncReplicaHelper(IntPtr dsHandle, bool isADAM, string partition, string sourceServer, int option, LoadLibrarySafeHandle libHandle) { int structSize = Marshal.SizeOf(typeof(Guid)); IntPtr unmanagedGuid = (IntPtr)0; Guid guid = Guid.Empty; AdamInstance adamServer = null; DomainController dcServer = null; unmanagedGuid = Marshal.AllocHGlobal(structSize); try { if (sourceServer != null) { DirectoryContext newContext = Utils.GetNewDirectoryContext(sourceServer, DirectoryContextType.DirectoryServer, context); if (isADAM) { adamServer = AdamInstance.GetAdamInstance(newContext); guid = adamServer.NtdsaObjectGuid; } else { dcServer = DomainController.GetDomainController(newContext); guid = dcServer.NtdsaObjectGuid; } Marshal.StructureToPtr(guid, unmanagedGuid, false); } // call DsReplicaSyncW IntPtr functionPtr = UnsafeNativeMethods.GetProcAddress(libHandle, "DsReplicaSyncW"); if (functionPtr == (IntPtr)0) { throw ExceptionHelper.GetExceptionFromErrorCode(Marshal.GetLastWin32Error()); } UnsafeNativeMethods.DsReplicaSyncW dsReplicaSyncW = (UnsafeNativeMethods.DsReplicaSyncW)Marshal.GetDelegateForFunctionPointer(functionPtr, typeof(UnsafeNativeMethods.DsReplicaSyncW)); int result = dsReplicaSyncW(dsHandle, partition, unmanagedGuid, (int)option); // check the result if (result != 0) { if (!Partitions.Contains(partition)) { throw new ArgumentException(SR.ServerNotAReplica, nameof(partition)); } string serverDownName = null; // this is the error returned when the server that we want to sync from is down if (result == ExceptionHelper.RPC_S_SERVER_UNAVAILABLE) { serverDownName = sourceServer; } // this is the error returned when the server that we want to get synced is down else if (result == ExceptionHelper.RPC_S_CALL_FAILED) { serverDownName = Name; } throw ExceptionHelper.GetExceptionFromErrorCode(result, serverDownName); } } finally { if (unmanagedGuid != (IntPtr)0) { Marshal.FreeHGlobal(unmanagedGuid); } if (adamServer != null) { adamServer.Dispose(); } if (dcServer != null) { dcServer.Dispose(); } } }
public static ActiveDirectorySchema GetSchema(DirectoryContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } // contexttype should be Forest, DirectoryServer or ConfigurationSet if ((context.ContextType != DirectoryContextType.Forest) && (context.ContextType != DirectoryContextType.ConfigurationSet) && (context.ContextType != DirectoryContextType.DirectoryServer)) { throw new ArgumentException(SR.NotADOrADAM, nameof(context)); } if ((context.Name == null) && (!context.isRootDomain())) { throw new ActiveDirectoryObjectNotFoundException(SR.ContextNotAssociatedWithDomain, typeof(ActiveDirectorySchema), null); } if (context.Name != null) { // the target should be a valid forest name or a server if (!((context.isRootDomain()) || (context.isADAMConfigSet()) || (context.isServer()))) { if (context.ContextType == DirectoryContextType.Forest) { throw new ActiveDirectoryObjectNotFoundException(SR.ForestNotFound, typeof(ActiveDirectorySchema), context.Name); } else if (context.ContextType == DirectoryContextType.ConfigurationSet) { throw new ActiveDirectoryObjectNotFoundException(SR.ConfigSetNotFound, typeof(ActiveDirectorySchema), context.Name); } else { throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.ServerNotFound, context.Name), typeof(ActiveDirectorySchema), null); } } } // work with copy of the context context = new DirectoryContext(context); DirectoryEntryManager directoryEntryMgr = new DirectoryEntryManager(context); string schemaNC = null; try { DirectoryEntry rootDSE = directoryEntryMgr.GetCachedDirectoryEntry(WellKnownDN.RootDSE); if ((context.isServer()) && (!Utils.CheckCapability(rootDSE, Capability.ActiveDirectoryOrADAM))) { throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.ServerNotFound, context.Name), typeof(ActiveDirectorySchema), null); } schemaNC = (string)PropertyManager.GetPropertyValue(context, rootDSE, PropertyManager.SchemaNamingContext); } catch (COMException e) { int errorCode = e.ErrorCode; if (errorCode == unchecked ((int)0x8007203a)) { if (context.ContextType == DirectoryContextType.Forest) { throw new ActiveDirectoryObjectNotFoundException(SR.ForestNotFound, typeof(ActiveDirectorySchema), context.Name); } else if (context.ContextType == DirectoryContextType.ConfigurationSet) { throw new ActiveDirectoryObjectNotFoundException(SR.ConfigSetNotFound, typeof(ActiveDirectorySchema), context.Name); } else { throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.ServerNotFound, context.Name), typeof(ActiveDirectorySchema), null); } } else { throw ExceptionHelper.GetExceptionFromCOMException(context, e); } } catch (ActiveDirectoryObjectNotFoundException) { if (context.ContextType == DirectoryContextType.ConfigurationSet) { // this is the case where the context is a config set and we could not find an ADAM instance in that config set throw new ActiveDirectoryObjectNotFoundException(SR.ConfigSetNotFound, typeof(ActiveDirectorySchema), context.Name); } else { throw; } } return(new ActiveDirectorySchema(context, schemaNC, directoryEntryMgr)); }
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; } }