1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Net; 6 using System.ComponentModel; 7 using System.Collections; 8 using System.Globalization; 9 using System.Runtime.InteropServices; 10 using System.Diagnostics; 11 12 namespace System.DirectoryServices.ActiveDirectory 13 { 14 [Flags] 15 public enum SyncFromAllServersOptions 16 { 17 None = 0, 18 AbortIfServerUnavailable = 1, 19 SyncAdjacentServerOnly = 2, 20 CheckServerAlivenessOnly = 0x8, 21 SkipInitialCheck = 0x10, 22 PushChangeOutward = 0x20, 23 CrossSite = 0x40 24 } 25 public enum SyncFromAllServersEvent 26 { 27 Error = 0, 28 SyncStarted = 1, 29 SyncCompleted = 2, 30 Finished = 3 31 } 32 public enum SyncFromAllServersErrorCategory 33 { 34 ErrorContactingServer = 0, 35 ErrorReplicating = 1, 36 ServerUnreachable = 2 37 } SyncUpdateCallback(SyncFromAllServersEvent eventType, string targetServer, string sourceServer, SyncFromAllServersOperationException exception)38 public delegate bool SyncUpdateCallback(SyncFromAllServersEvent eventType, string targetServer, string sourceServer, SyncFromAllServersOperationException exception); SyncReplicaFromAllServersCallback(IntPtr data, IntPtr update)39 internal delegate bool SyncReplicaFromAllServersCallback(IntPtr data, IntPtr update); 40 41 public class DomainController : DirectoryServer 42 { 43 private IntPtr _dsHandle = IntPtr.Zero; 44 private IntPtr _authIdentity = IntPtr.Zero; 45 private readonly string[] _becomeRoleOwnerAttrs = null; 46 private bool _disposed = false; 47 48 // internal variables for the public properties 49 private string _cachedComputerObjectName = null; 50 private string _cachedOSVersion = null; 51 private double _cachedNumericOSVersion = 0; 52 private Forest _currentForest = null; 53 private Domain _cachedDomain = null; 54 private ActiveDirectoryRoleCollection _cachedRoles = null; 55 private bool _dcInfoInitialized = false; 56 57 internal SyncUpdateCallback userDelegate = null; 58 internal readonly SyncReplicaFromAllServersCallback syncAllFunctionPointer = null; 59 60 // this is twice the maximum allowed RIDPool size which is 15k 61 internal const int UpdateRidPoolSeizureValue = 30000; 62 63 #region constructors 64 65 // Internal constructors DomainController()66 protected DomainController() 67 { 68 } 69 DomainController(DirectoryContext context, string domainControllerName)70 internal DomainController(DirectoryContext context, string domainControllerName) 71 : this(context, domainControllerName, new DirectoryEntryManager(context)) 72 { 73 } 74 DomainController(DirectoryContext context, string domainControllerName, DirectoryEntryManager directoryEntryMgr)75 internal DomainController(DirectoryContext context, string domainControllerName, DirectoryEntryManager directoryEntryMgr) 76 { 77 this.context = context; 78 this.replicaName = domainControllerName; 79 this.directoryEntryMgr = directoryEntryMgr; 80 81 // initialize the transfer role owner attributes 82 _becomeRoleOwnerAttrs = new String[5]; 83 _becomeRoleOwnerAttrs[0] = PropertyManager.BecomeSchemaMaster; 84 _becomeRoleOwnerAttrs[1] = PropertyManager.BecomeDomainMaster; 85 _becomeRoleOwnerAttrs[2] = PropertyManager.BecomePdc; 86 _becomeRoleOwnerAttrs[3] = PropertyManager.BecomeRidMaster; 87 _becomeRoleOwnerAttrs[4] = PropertyManager.BecomeInfrastructureMaster; 88 89 // initialize the callback function 90 syncAllFunctionPointer = new SyncReplicaFromAllServersCallback(SyncAllCallbackRoutine); 91 } 92 #endregion constructors 93 94 #region IDisposable 95 ~DomainController()96 ~DomainController() => Dispose(false); 97 98 // private Dispose method Dispose(bool disposing)99 protected override void Dispose(bool disposing) 100 { 101 if (!_disposed) 102 { 103 try 104 { 105 // if there are any managed or unmanaged 106 // resources to be freed, those should be done here 107 // if disposing = true, only unmanaged resources should 108 // be freed, else both managed and unmanaged. 109 FreeDSHandle(); 110 _disposed = true; 111 } 112 finally 113 { 114 base.Dispose(); 115 } 116 } 117 } 118 #endregion IDisposable 119 120 #region public methods 121 GetDomainController(DirectoryContext context)122 public static DomainController GetDomainController(DirectoryContext context) 123 { 124 string dcDnsName = null; 125 DirectoryEntryManager directoryEntryMgr = null; 126 127 // check that the context argument is not null 128 if (context == null) 129 throw new ArgumentNullException("context"); 130 131 // target should be DC 132 if (context.ContextType != DirectoryContextType.DirectoryServer) 133 { 134 throw new ArgumentException(SR.TargetShouldBeDC, "context"); 135 } 136 137 // target should be a server 138 if (!(context.isServer())) 139 { 140 throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.DCNotFound , context.Name), typeof(DomainController), context.Name); 141 } 142 143 // work with copy of the context 144 context = new DirectoryContext(context); 145 146 try 147 { 148 // Get dns name of the dc 149 // by binding to root dse and getting the "dnsHostName" attribute 150 directoryEntryMgr = new DirectoryEntryManager(context); 151 DirectoryEntry rootDSE = directoryEntryMgr.GetCachedDirectoryEntry(WellKnownDN.RootDSE); 152 if (!Utils.CheckCapability(rootDSE, Capability.ActiveDirectory)) 153 { 154 throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.DCNotFound , context.Name), typeof(DomainController), context.Name); 155 } 156 dcDnsName = (string)PropertyManager.GetPropertyValue(context, rootDSE, PropertyManager.DnsHostName); 157 } 158 catch (COMException e) 159 { 160 int errorCode = e.ErrorCode; 161 162 if (errorCode == unchecked((int)0x8007203a)) 163 { 164 throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.DCNotFound , context.Name), typeof(DomainController), context.Name); 165 } 166 else 167 { 168 throw ExceptionHelper.GetExceptionFromCOMException(context, e); 169 } 170 } 171 172 return new DomainController(context, dcDnsName, directoryEntryMgr); 173 } 174 FindOne(DirectoryContext context)175 public static DomainController FindOne(DirectoryContext context) 176 { 177 if (context == null) 178 { 179 throw new ArgumentNullException("context"); 180 } 181 182 if (context.ContextType != DirectoryContextType.Domain) 183 { 184 throw new ArgumentException(SR.TargetShouldBeDomain, "context"); 185 } 186 187 return FindOneWithCredentialValidation(context, null, 0); 188 } 189 FindOne(DirectoryContext context, string siteName)190 public static DomainController FindOne(DirectoryContext context, string siteName) 191 { 192 if (context == null) 193 { 194 throw new ArgumentNullException("context"); 195 } 196 197 if (context.ContextType != DirectoryContextType.Domain) 198 { 199 throw new ArgumentException(SR.TargetShouldBeDomain, "context"); 200 } 201 202 if (siteName == null) 203 { 204 throw new ArgumentNullException("siteName"); 205 } 206 207 return FindOneWithCredentialValidation(context, siteName, 0); 208 } 209 FindOne(DirectoryContext context, LocatorOptions flag)210 public static DomainController FindOne(DirectoryContext context, LocatorOptions flag) 211 { 212 if (context == null) 213 { 214 throw new ArgumentNullException("context"); 215 } 216 217 if (context.ContextType != DirectoryContextType.Domain) 218 { 219 throw new ArgumentException(SR.TargetShouldBeDomain, "context"); 220 } 221 222 return FindOneWithCredentialValidation(context, null, flag); 223 } 224 FindOne(DirectoryContext context, string siteName, LocatorOptions flag)225 public static DomainController FindOne(DirectoryContext context, string siteName, LocatorOptions flag) 226 { 227 if (context == null) 228 { 229 throw new ArgumentNullException("context"); 230 } 231 232 if (context.ContextType != DirectoryContextType.Domain) 233 { 234 throw new ArgumentException(SR.TargetShouldBeDomain, "context"); 235 } 236 237 if (siteName == null) 238 { 239 throw new ArgumentNullException("siteName"); 240 } 241 242 return FindOneWithCredentialValidation(context, siteName, flag); 243 } 244 FindAll(DirectoryContext context)245 public static DomainControllerCollection FindAll(DirectoryContext context) 246 { 247 if (context == null) 248 { 249 throw new ArgumentNullException("context"); 250 } 251 252 if (context.ContextType != DirectoryContextType.Domain) 253 { 254 throw new ArgumentException(SR.TargetShouldBeDomain, "context"); 255 } 256 257 // work with copy of the context 258 context = new DirectoryContext(context); 259 260 return FindAllInternal(context, context.Name, false /* isDnsDomainName */, null); 261 } 262 FindAll(DirectoryContext context, string siteName)263 public static DomainControllerCollection FindAll(DirectoryContext context, string siteName) 264 { 265 if (context == null) 266 { 267 throw new ArgumentNullException("context"); 268 } 269 270 if (context.ContextType != DirectoryContextType.Domain) 271 { 272 throw new ArgumentException(SR.TargetShouldBeDomain, "context"); 273 } 274 275 if (siteName == null) 276 { 277 throw new ArgumentNullException("siteName"); 278 } 279 280 // work with copy of the context 281 context = new DirectoryContext(context); 282 283 return FindAllInternal(context, context.Name, false /* isDnsDomainName */, siteName); 284 } 285 EnableGlobalCatalog()286 public virtual GlobalCatalog EnableGlobalCatalog() 287 { 288 CheckIfDisposed(); 289 290 try 291 { 292 // bind to the server object 293 DirectoryEntry serverNtdsaEntry = directoryEntryMgr.GetCachedDirectoryEntry(NtdsaObjectName); 294 // set the NTDSDSA_OPT_IS_GC flag on the "options" property 295 int options = 0; 296 if (serverNtdsaEntry.Properties[PropertyManager.Options].Value != null) 297 { 298 options = (int)serverNtdsaEntry.Properties[PropertyManager.Options].Value; 299 } 300 serverNtdsaEntry.Properties[PropertyManager.Options].Value = options | 1; 301 serverNtdsaEntry.CommitChanges(); 302 } 303 catch (COMException e) 304 { 305 throw ExceptionHelper.GetExceptionFromCOMException(context, e); 306 } 307 // return a GlobalCatalog object 308 return new GlobalCatalog(context, Name); 309 } 310 IsGlobalCatalog()311 public virtual bool IsGlobalCatalog() 312 { 313 CheckIfDisposed(); 314 315 try 316 { 317 DirectoryEntry serverNtdsaEntry = directoryEntryMgr.GetCachedDirectoryEntry(NtdsaObjectName); 318 serverNtdsaEntry.RefreshCache(); 319 // check if the NTDSDSA_OPT_IS_GC flag is set in the 320 // "options" attribute (lowest bit) 321 int options = 0; 322 if (serverNtdsaEntry.Properties[PropertyManager.Options].Value != null) 323 { 324 options = (int)serverNtdsaEntry.Properties[PropertyManager.Options].Value; 325 } 326 if ((options & (1)) == 1) 327 { 328 return true; 329 } 330 else 331 { 332 return false; 333 } 334 } 335 catch (COMException e) 336 { 337 throw ExceptionHelper.GetExceptionFromCOMException(context, e); 338 } 339 } 340 TransferRoleOwnership(ActiveDirectoryRole role)341 public void TransferRoleOwnership(ActiveDirectoryRole role) 342 { 343 CheckIfDisposed(); 344 345 if (role < ActiveDirectoryRole.SchemaRole || role > ActiveDirectoryRole.InfrastructureRole) 346 { 347 throw new InvalidEnumArgumentException("role", (int)role, typeof(ActiveDirectoryRole)); 348 } 349 350 try 351 { 352 // set the appropriate attribute on the rootDSE 353 DirectoryEntry rootDSE = directoryEntryMgr.GetCachedDirectoryEntry(WellKnownDN.RootDSE); 354 rootDSE.Properties[_becomeRoleOwnerAttrs[(int)role]].Value = 1; 355 rootDSE.CommitChanges(); 356 } 357 catch (COMException e) 358 { 359 throw ExceptionHelper.GetExceptionFromCOMException(context, e); ; 360 } 361 362 // invalidate the role collection so that it gets loaded again next time 363 _cachedRoles = null; 364 } 365 SeizeRoleOwnership(ActiveDirectoryRole role)366 public void SeizeRoleOwnership(ActiveDirectoryRole role) 367 { 368 // set the "fsmoRoleOwner" attribute on the appropriate role object 369 // to the NTDSAObjectName of this DC 370 string roleObjectDN = null; 371 372 CheckIfDisposed(); 373 374 switch (role) 375 { 376 case ActiveDirectoryRole.SchemaRole: 377 { 378 roleObjectDN = directoryEntryMgr.ExpandWellKnownDN(WellKnownDN.SchemaNamingContext); 379 break; 380 } 381 case ActiveDirectoryRole.NamingRole: 382 { 383 roleObjectDN = directoryEntryMgr.ExpandWellKnownDN(WellKnownDN.PartitionsContainer); 384 break; 385 } 386 case ActiveDirectoryRole.PdcRole: 387 { 388 roleObjectDN = directoryEntryMgr.ExpandWellKnownDN(WellKnownDN.DefaultNamingContext); 389 break; 390 } 391 case ActiveDirectoryRole.RidRole: 392 { 393 roleObjectDN = directoryEntryMgr.ExpandWellKnownDN(WellKnownDN.RidManager); 394 break; 395 } 396 case ActiveDirectoryRole.InfrastructureRole: 397 { 398 roleObjectDN = directoryEntryMgr.ExpandWellKnownDN(WellKnownDN.Infrastructure); 399 break; 400 } 401 default: 402 throw new InvalidEnumArgumentException("role", (int)role, typeof(ActiveDirectoryRole)); 403 } 404 405 DirectoryEntry roleObjectEntry = null; 406 try 407 { 408 roleObjectEntry = DirectoryEntryManager.GetDirectoryEntry(context, roleObjectDN); 409 410 // For RID FSMO role 411 // Increment the RIDAvailablePool by 30k. 412 if (role == ActiveDirectoryRole.RidRole) 413 { 414 System.DirectoryServices.Interop.UnsafeNativeMethods.IADsLargeInteger ridPool = (System.DirectoryServices.Interop.UnsafeNativeMethods.IADsLargeInteger)roleObjectEntry.Properties[PropertyManager.RIDAvailablePool].Value; 415 416 // check the overflow of the low part 417 if (ridPool.LowPart + UpdateRidPoolSeizureValue < ridPool.LowPart) 418 { 419 throw new InvalidOperationException(SR.UpdateAvailableRIDPoolOverflowFailure); 420 } 421 ridPool.LowPart += UpdateRidPoolSeizureValue; 422 roleObjectEntry.Properties[PropertyManager.RIDAvailablePool].Value = ridPool; 423 } 424 roleObjectEntry.Properties[PropertyManager.FsmoRoleOwner].Value = NtdsaObjectName; 425 roleObjectEntry.CommitChanges(); 426 } 427 catch (COMException e) 428 { 429 throw ExceptionHelper.GetExceptionFromCOMException(context, e); 430 } 431 finally 432 { 433 if (roleObjectEntry != null) 434 { 435 roleObjectEntry.Dispose(); 436 } 437 } 438 439 // invalidate the role collection so that it gets loaded again next time 440 _cachedRoles = null; 441 } 442 GetDirectorySearcher()443 public virtual DirectorySearcher GetDirectorySearcher() 444 { 445 CheckIfDisposed(); 446 447 return InternalGetDirectorySearcher(); 448 } 449 CheckReplicationConsistency()450 public override void CheckReplicationConsistency() 451 { 452 if (_disposed) 453 throw new ObjectDisposedException(GetType().Name); 454 455 // get the handle 456 GetDSHandle(); 457 458 // call private helper function 459 CheckConsistencyHelper(_dsHandle, DirectoryContext.ADHandle); 460 } 461 GetReplicationCursors(string partition)462 public override ReplicationCursorCollection GetReplicationCursors(string partition) 463 { 464 IntPtr info = (IntPtr)0; 465 int context = 0; 466 bool advanced = true; 467 468 if (_disposed) 469 throw new ObjectDisposedException(GetType().Name); 470 471 if (partition == null) 472 throw new ArgumentNullException("partition"); 473 474 if (partition.Length == 0) 475 throw new ArgumentException(SR.EmptyStringParameter, "partition"); 476 477 // get the handle 478 GetDSHandle(); 479 info = GetReplicationInfoHelper(_dsHandle, (int)DS_REPL_INFO_TYPE.DS_REPL_INFO_CURSORS_3_FOR_NC, (int)DS_REPL_INFO_TYPE.DS_REPL_INFO_CURSORS_FOR_NC, partition, ref advanced, context, DirectoryContext.ADHandle); 480 return ConstructReplicationCursors(_dsHandle, advanced, info, partition, this, DirectoryContext.ADHandle); 481 } 482 GetReplicationOperationInformation()483 public override ReplicationOperationInformation GetReplicationOperationInformation() 484 { 485 IntPtr info = (IntPtr)0; 486 bool advanced = true; 487 488 if (_disposed) 489 throw new ObjectDisposedException(GetType().Name); 490 491 // get the handle 492 GetDSHandle(); 493 info = GetReplicationInfoHelper(_dsHandle, (int)DS_REPL_INFO_TYPE.DS_REPL_INFO_PENDING_OPS, (int)DS_REPL_INFO_TYPE.DS_REPL_INFO_PENDING_OPS, null, ref advanced, 0, DirectoryContext.ADHandle); 494 return ConstructPendingOperations(info, this, DirectoryContext.ADHandle); 495 } 496 GetReplicationNeighbors(string partition)497 public override ReplicationNeighborCollection GetReplicationNeighbors(string partition) 498 { 499 IntPtr info = (IntPtr)0; 500 bool advanced = true; 501 502 if (_disposed) 503 throw new ObjectDisposedException(GetType().Name); 504 505 if (partition == null) 506 throw new ArgumentNullException("partition"); 507 508 if (partition.Length == 0) 509 throw new ArgumentException(SR.EmptyStringParameter, "partition"); 510 511 // get the handle 512 GetDSHandle(); 513 info = GetReplicationInfoHelper(_dsHandle, (int)DS_REPL_INFO_TYPE.DS_REPL_INFO_NEIGHBORS, (int)DS_REPL_INFO_TYPE.DS_REPL_INFO_NEIGHBORS, partition, ref advanced, 0, DirectoryContext.ADHandle); 514 return ConstructNeighbors(info, this, DirectoryContext.ADHandle); 515 } 516 GetAllReplicationNeighbors()517 public override ReplicationNeighborCollection GetAllReplicationNeighbors() 518 { 519 IntPtr info = (IntPtr)0; 520 bool advanced = true; 521 522 if (_disposed) 523 throw new ObjectDisposedException(GetType().Name); 524 525 // get the handle 526 GetDSHandle(); 527 info = GetReplicationInfoHelper(_dsHandle, (int)DS_REPL_INFO_TYPE.DS_REPL_INFO_NEIGHBORS, (int)DS_REPL_INFO_TYPE.DS_REPL_INFO_NEIGHBORS, null, ref advanced, 0, DirectoryContext.ADHandle); 528 return ConstructNeighbors(info, this, DirectoryContext.ADHandle); 529 } 530 GetReplicationConnectionFailures()531 public override ReplicationFailureCollection GetReplicationConnectionFailures() 532 { 533 return GetReplicationFailures(DS_REPL_INFO_TYPE.DS_REPL_INFO_KCC_DSA_CONNECT_FAILURES); 534 } 535 GetReplicationMetadata(string objectPath)536 public override ActiveDirectoryReplicationMetadata GetReplicationMetadata(string objectPath) 537 { 538 IntPtr info = (IntPtr)0; 539 bool advanced = true; 540 541 if (_disposed) 542 throw new ObjectDisposedException(GetType().Name); 543 544 if (objectPath == null) 545 throw new ArgumentNullException("objectPath"); 546 547 if (objectPath.Length == 0) 548 throw new ArgumentException(SR.EmptyStringParameter, "objectPath"); 549 550 // get the handle 551 GetDSHandle(); 552 info = GetReplicationInfoHelper(_dsHandle, (int)DS_REPL_INFO_TYPE.DS_REPL_INFO_METADATA_2_FOR_OBJ, (int)DS_REPL_INFO_TYPE.DS_REPL_INFO_METADATA_FOR_OBJ, objectPath, ref advanced, 0, DirectoryContext.ADHandle); 553 return ConstructMetaData(advanced, info, this, DirectoryContext.ADHandle); 554 } 555 SyncReplicaFromServer(string partition, string sourceServer)556 public override void SyncReplicaFromServer(string partition, string sourceServer) 557 { 558 if (_disposed) 559 throw new ObjectDisposedException(GetType().Name); 560 561 if (partition == null) 562 throw new ArgumentNullException("partition"); 563 564 if (partition.Length == 0) 565 throw new ArgumentException(SR.EmptyStringParameter, "partition"); 566 567 if (sourceServer == null) 568 throw new ArgumentNullException("sourceServer"); 569 570 if (sourceServer.Length == 0) 571 throw new ArgumentException(SR.EmptyStringParameter, "sourceServer"); 572 573 // get the dsHandle 574 GetDSHandle(); 575 SyncReplicaHelper(_dsHandle, false, partition, sourceServer, 0, DirectoryContext.ADHandle); 576 } 577 TriggerSyncReplicaFromNeighbors(string partition)578 public override void TriggerSyncReplicaFromNeighbors(string partition) 579 { 580 if (_disposed) 581 throw new ObjectDisposedException(GetType().Name); 582 583 if (partition == null) 584 throw new ArgumentNullException("partition"); 585 586 if (partition.Length == 0) 587 throw new ArgumentException(SR.EmptyStringParameter, "partition"); 588 589 // get the dsHandle 590 GetDSHandle(); 591 SyncReplicaHelper(_dsHandle, false, partition, null, DS_REPSYNC_ASYNCHRONOUS_OPERATION | DS_REPSYNC_ALL_SOURCES, DirectoryContext.ADHandle); 592 } 593 SyncReplicaFromAllServers(string partition, SyncFromAllServersOptions options)594 public override void SyncReplicaFromAllServers(string partition, SyncFromAllServersOptions options) 595 { 596 if (_disposed) 597 throw new ObjectDisposedException(GetType().Name); 598 599 if (partition == null) 600 throw new ArgumentNullException("partition"); 601 602 if (partition.Length == 0) 603 throw new ArgumentException(SR.EmptyStringParameter, "partition"); 604 605 // get the dsHandle 606 GetDSHandle(); 607 SyncReplicaAllHelper(_dsHandle, syncAllFunctionPointer, partition, options, SyncFromAllServersCallback, DirectoryContext.ADHandle); 608 } 609 #endregion public methods 610 611 #region public properties 612 613 public Forest Forest 614 { 615 get 616 { 617 CheckIfDisposed(); 618 if (_currentForest == null) 619 { 620 DirectoryContext forestContext = Utils.GetNewDirectoryContext(Name, DirectoryContextType.DirectoryServer, context); 621 _currentForest = Forest.GetForest(forestContext); 622 } 623 return _currentForest; 624 } 625 } 626 627 public DateTime CurrentTime 628 { 629 get 630 { 631 CheckIfDisposed(); 632 633 DirectoryEntry rootDSE = DirectoryEntryManager.GetDirectoryEntry(context, WellKnownDN.RootDSE); 634 string serverUTCTime = null; 635 636 try 637 { 638 serverUTCTime = (string)PropertyManager.GetPropertyValue(context, rootDSE, PropertyManager.CurrentTime); 639 } 640 finally 641 { 642 rootDSE.Dispose(); 643 } 644 return ParseDateTime(serverUTCTime); 645 } 646 } 647 648 public Int64 HighestCommittedUsn 649 { 650 get 651 { 652 CheckIfDisposed(); 653 654 DirectoryEntry rootDSE = DirectoryEntryManager.GetDirectoryEntry(context, WellKnownDN.RootDSE); 655 string serverHighestCommittedUsn = null; 656 657 try 658 { 659 serverHighestCommittedUsn = (string)PropertyManager.GetPropertyValue(context, rootDSE, PropertyManager.HighestCommittedUSN); 660 } 661 finally 662 { 663 rootDSE.Dispose(); 664 } 665 return Int64.Parse(serverHighestCommittedUsn, NumberFormatInfo.InvariantInfo); 666 } 667 } 668 669 public string OSVersion 670 { 671 get 672 { 673 CheckIfDisposed(); 674 if (_cachedOSVersion == null) 675 { 676 // get the operating system version attribute 677 DirectoryEntry computerEntry = directoryEntryMgr.GetCachedDirectoryEntry(ComputerObjectName); 678 // is in the form Windows Server 2003 679 _cachedOSVersion = (string)PropertyManager.GetPropertyValue(context, computerEntry, PropertyManager.OperatingSystem); 680 } 681 return _cachedOSVersion; 682 } 683 } 684 685 internal double NumericOSVersion 686 { 687 get 688 { 689 CheckIfDisposed(); 690 if (_cachedNumericOSVersion == 0) 691 { 692 // get the operating system version attribute 693 DirectoryEntry computerEntry = directoryEntryMgr.GetCachedDirectoryEntry(ComputerObjectName); 694 695 // is in the form Windows Server 2003 696 string osVersion = (string)PropertyManager.GetPropertyValue(context, computerEntry, PropertyManager.OperatingSystemVersion); 697 698 // this could be in the form 5.2 (3790), so we need to take out the (3790) 699 int index = osVersion.IndexOf('('); 700 if (index != -1) 701 { 702 osVersion = osVersion.Substring(0, index); 703 } 704 _cachedNumericOSVersion = (double)Double.Parse(osVersion, NumberFormatInfo.InvariantInfo); 705 } 706 707 return _cachedNumericOSVersion; 708 } 709 } 710 711 public ActiveDirectoryRoleCollection Roles 712 { 713 get 714 { 715 CheckIfDisposed(); 716 if (_cachedRoles == null) 717 { 718 _cachedRoles = new ActiveDirectoryRoleCollection(GetRoles()); 719 } 720 return _cachedRoles; 721 } 722 } 723 724 public Domain Domain 725 { 726 get 727 { 728 CheckIfDisposed(); 729 if (_cachedDomain == null) 730 { 731 string domainName = null; 732 try 733 { 734 string defaultNCName = directoryEntryMgr.ExpandWellKnownDN(WellKnownDN.DefaultNamingContext); 735 domainName = Utils.GetDnsNameFromDN(defaultNCName); 736 } 737 catch (COMException e) 738 { 739 throw ExceptionHelper.GetExceptionFromCOMException(context, e); 740 } 741 // For domain controllers this is always the 742 // domain naming context 743 // create a new domain context for the domain 744 DirectoryContext domainContext = Utils.GetNewDirectoryContext(Name, DirectoryContextType.DirectoryServer, context); 745 _cachedDomain = new Domain(domainContext, domainName); 746 } 747 return _cachedDomain; 748 } 749 } 750 751 public override string IPAddress 752 { 753 get 754 { 755 CheckIfDisposed(); 756 757 IPHostEntry hostEntry = Dns.GetHostEntry(Name); 758 if (hostEntry.AddressList.GetLength(0) > 0) 759 { 760 return (hostEntry.AddressList[0]).ToString(); 761 } 762 else 763 { 764 return null; 765 } 766 } 767 } 768 769 public override String SiteName 770 { 771 get 772 { 773 CheckIfDisposed(); 774 if (!_dcInfoInitialized || siteInfoModified) 775 { 776 GetDomainControllerInfo(); 777 } 778 if (cachedSiteName == null) 779 { 780 throw new ActiveDirectoryOperationException(SR.Format(SR.SiteNameNotFound , Name)); 781 } 782 783 return cachedSiteName; 784 } 785 } 786 787 internal String SiteObjectName 788 { 789 get 790 { 791 CheckIfDisposed(); 792 if (!_dcInfoInitialized || siteInfoModified) 793 { 794 GetDomainControllerInfo(); 795 } 796 if (cachedSiteObjectName == null) 797 { 798 throw new ActiveDirectoryOperationException(SR.Format(SR.SiteObjectNameNotFound , Name)); 799 } 800 return cachedSiteObjectName; 801 } 802 } 803 804 internal String ComputerObjectName 805 { 806 get 807 { 808 CheckIfDisposed(); 809 if (!_dcInfoInitialized) 810 { 811 GetDomainControllerInfo(); 812 } 813 if (_cachedComputerObjectName == null) 814 { 815 throw new ActiveDirectoryOperationException(SR.Format(SR.ComputerObjectNameNotFound , Name)); 816 } 817 return _cachedComputerObjectName; 818 } 819 } 820 821 internal String ServerObjectName 822 { 823 get 824 { 825 CheckIfDisposed(); 826 if (!_dcInfoInitialized || siteInfoModified) 827 { 828 GetDomainControllerInfo(); 829 } 830 if (cachedServerObjectName == null) 831 { 832 throw new ActiveDirectoryOperationException(SR.Format(SR.ServerObjectNameNotFound , Name)); 833 } 834 return cachedServerObjectName; 835 } 836 } 837 838 internal String NtdsaObjectName 839 { 840 get 841 { 842 CheckIfDisposed(); 843 if (!_dcInfoInitialized || siteInfoModified) 844 { 845 GetDomainControllerInfo(); 846 } 847 if (cachedNtdsaObjectName == null) 848 { 849 throw new ActiveDirectoryOperationException(SR.Format(SR.NtdsaObjectNameNotFound , Name)); 850 } 851 return cachedNtdsaObjectName; 852 } 853 } 854 855 internal Guid NtdsaObjectGuid 856 { 857 get 858 { 859 CheckIfDisposed(); 860 if (!_dcInfoInitialized || siteInfoModified) 861 { 862 GetDomainControllerInfo(); 863 } 864 if (cachedNtdsaObjectGuid.Equals(Guid.Empty)) 865 { 866 throw new ActiveDirectoryOperationException(SR.Format(SR.NtdsaObjectGuidNotFound , Name)); 867 } 868 return cachedNtdsaObjectGuid; 869 } 870 } 871 872 public override SyncUpdateCallback SyncFromAllServersCallback 873 { 874 get 875 { 876 if (_disposed) 877 throw new ObjectDisposedException(GetType().Name); 878 879 return userDelegate; 880 } 881 882 set 883 { 884 if (_disposed) 885 throw new ObjectDisposedException(GetType().Name); 886 887 userDelegate = value; 888 } 889 } 890 891 public override ReplicationConnectionCollection InboundConnections => GetInboundConnectionsHelper(); 892 893 public override ReplicationConnectionCollection OutboundConnections => GetOutboundConnectionsHelper(); 894 895 internal IntPtr Handle 896 { 897 get 898 { 899 GetDSHandle(); 900 return _dsHandle; 901 } 902 } 903 904 #endregion public properties 905 906 #region private methods 907 ValidateCredential(DomainController dc, DirectoryContext context)908 internal static void ValidateCredential(DomainController dc, DirectoryContext context) 909 { 910 DirectoryEntry de; 911 912 de = new DirectoryEntry("LDAP://" + dc.Name + "/RootDSE", context.UserName, context.Password, Utils.DefaultAuthType | AuthenticationTypes.ServerBind); 913 914 de.Bind(true); 915 } 916 FindOneWithCredentialValidation(DirectoryContext context, string siteName, LocatorOptions flag)917 internal static DomainController FindOneWithCredentialValidation(DirectoryContext context, string siteName, LocatorOptions flag) 918 { 919 DomainController dc; 920 bool retry = false; 921 bool credsValidated = false; 922 923 // work with copy of the context 924 context = new DirectoryContext(context); 925 926 // authenticate against this DC to validate the credentials 927 dc = FindOneInternal(context, context.Name, siteName, flag); 928 try 929 { 930 ValidateCredential(dc, context); 931 credsValidated = true; 932 } 933 catch (COMException e) 934 { 935 if (e.ErrorCode == unchecked((int)0x8007203a)) 936 { 937 // server is down , so try again with force rediscovery if the flags did not already contain force rediscovery 938 if ((flag & LocatorOptions.ForceRediscovery) == 0) 939 { 940 retry = true; 941 } 942 else 943 { 944 throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.DCNotFoundInDomain , context.Name), typeof(DomainController), null); 945 } 946 } 947 else 948 { 949 throw ExceptionHelper.GetExceptionFromCOMException(context, e); 950 } 951 } 952 finally 953 { 954 if (!credsValidated) 955 { 956 dc.Dispose(); 957 } 958 } 959 960 if (retry) 961 { 962 credsValidated = false; 963 dc = FindOneInternal(context, context.Name, siteName, flag | LocatorOptions.ForceRediscovery); 964 try 965 { 966 ValidateCredential(dc, context); 967 credsValidated = true; 968 } 969 catch (COMException e) 970 { 971 if (e.ErrorCode == unchecked((int)0x8007203a)) 972 { 973 // server is down 974 throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.DCNotFoundInDomain , context.Name), typeof(DomainController), null); 975 } 976 else 977 { 978 throw ExceptionHelper.GetExceptionFromCOMException(context, e); 979 } 980 } 981 finally 982 { 983 if (!credsValidated) 984 { 985 dc.Dispose(); 986 } 987 } 988 } 989 990 return dc; 991 } 992 FindOneInternal(DirectoryContext context, string domainName, string siteName, LocatorOptions flag)993 internal static DomainController FindOneInternal(DirectoryContext context, string domainName, string siteName, LocatorOptions flag) 994 { 995 DomainControllerInfo domainControllerInfo; 996 int errorCode = 0; 997 998 if (siteName != null && siteName.Length == 0) 999 { 1000 throw new ArgumentException(SR.EmptyStringParameter, "siteName"); 1001 } 1002 1003 // check that the flags passed have only the valid bits set 1004 if (((long)flag & (~((long)LocatorOptions.AvoidSelf | (long)LocatorOptions.ForceRediscovery | (long)LocatorOptions.KdcRequired | (long)LocatorOptions.TimeServerRequired | (long)LocatorOptions.WriteableRequired))) != 0) 1005 { 1006 throw new ArgumentException(SR.InvalidFlags, "flag"); 1007 } 1008 1009 if (domainName == null) 1010 { 1011 domainName = DirectoryContext.GetLoggedOnDomain(); 1012 } 1013 1014 // call DsGetDcName 1015 errorCode = Locator.DsGetDcNameWrapper(null, domainName, siteName, (long)flag | (long)PrivateLocatorFlags.DirectoryServicesRequired, out domainControllerInfo); 1016 1017 if (errorCode == NativeMethods.ERROR_NO_SUCH_DOMAIN) 1018 { 1019 throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.DCNotFoundInDomain , domainName), typeof(DomainController), null); 1020 } 1021 // this can only occur when flag is being explicitly passed (since the flags that we pass internally are valid) 1022 if (errorCode == NativeMethods.ERROR_INVALID_FLAGS) 1023 { 1024 throw new ArgumentException(SR.InvalidFlags, "flag"); 1025 } 1026 else if (errorCode != 0) 1027 { 1028 throw ExceptionHelper.GetExceptionFromErrorCode(errorCode); 1029 } 1030 1031 // create a DomainController object 1032 Debug.Assert(domainControllerInfo.DomainControllerName.Length > 2); 1033 string domainControllerName = domainControllerInfo.DomainControllerName.Substring(2); 1034 1035 // create a new context object for the domain controller 1036 DirectoryContext dcContext = Utils.GetNewDirectoryContext(domainControllerName, DirectoryContextType.DirectoryServer, context); 1037 1038 return new DomainController(dcContext, domainControllerName); 1039 } 1040 FindAllInternal(DirectoryContext context, string domainName, bool isDnsDomainName, string siteName)1041 internal static DomainControllerCollection FindAllInternal(DirectoryContext context, string domainName, bool isDnsDomainName, string siteName) 1042 { 1043 ArrayList dcList = new ArrayList(); 1044 1045 if (siteName != null && siteName.Length == 0) 1046 { 1047 throw new ArgumentException(SR.EmptyStringParameter, "siteName"); 1048 } 1049 1050 if (domainName == null || !isDnsDomainName) 1051 { 1052 // get the dns name of the domain 1053 DomainControllerInfo domainControllerInfo; 1054 int errorCode = Locator.DsGetDcNameWrapper(null, (domainName != null) ? domainName : DirectoryContext.GetLoggedOnDomain(), null, (long)PrivateLocatorFlags.DirectoryServicesRequired, out domainControllerInfo); 1055 1056 if (errorCode == NativeMethods.ERROR_NO_SUCH_DOMAIN) 1057 { 1058 // return an empty collection 1059 return new DomainControllerCollection(dcList); 1060 } 1061 else if (errorCode != 0) 1062 { 1063 throw ExceptionHelper.GetExceptionFromErrorCode(errorCode); 1064 } 1065 1066 Debug.Assert(domainControllerInfo.DomainName != null); 1067 domainName = domainControllerInfo.DomainName; 1068 } 1069 1070 foreach (string dcName in Utils.GetReplicaList(context, Utils.GetDNFromDnsName(domainName), siteName, true /* isDefaultNC */, false /* isADAM */, false /* mustBeGC */)) 1071 { 1072 DirectoryContext dcContext = Utils.GetNewDirectoryContext(dcName, DirectoryContextType.DirectoryServer, context); 1073 dcList.Add(new DomainController(dcContext, dcName)); 1074 } 1075 1076 return new DomainControllerCollection(dcList); 1077 } 1078 GetDomainControllerInfo()1079 private void GetDomainControllerInfo() 1080 { 1081 int result = 0; 1082 int dcCount = 0; 1083 IntPtr dcInfoPtr = IntPtr.Zero; 1084 int dcInfoLevel = 0; 1085 bool initialized = false; 1086 1087 // get the handle 1088 GetDSHandle(); 1089 1090 // call DsGetDomainControllerInfo 1091 IntPtr functionPtr = UnsafeNativeMethods.GetProcAddress(DirectoryContext.ADHandle, "DsGetDomainControllerInfoW"); 1092 if (functionPtr == (IntPtr)0) 1093 { 1094 throw ExceptionHelper.GetExceptionFromErrorCode(Marshal.GetLastWin32Error()); 1095 } 1096 NativeMethods.DsGetDomainControllerInfo dsGetDomainControllerInfo = (NativeMethods.DsGetDomainControllerInfo)Marshal.GetDelegateForFunctionPointer(functionPtr, typeof(NativeMethods.DsGetDomainControllerInfo)); 1097 1098 // try DsDomainControllerInfoLevel3 first which supports Read only DC (RODC) 1099 dcInfoLevel = NativeMethods.DsDomainControllerInfoLevel3; 1100 result = dsGetDomainControllerInfo(_dsHandle, Domain.Name, dcInfoLevel, out dcCount, out dcInfoPtr); 1101 1102 if (result != 0) 1103 { 1104 // fallback to DsDomainControllerInfoLevel2 1105 dcInfoLevel = NativeMethods.DsDomainControllerInfoLevel2; 1106 result = dsGetDomainControllerInfo(_dsHandle, Domain.Name, dcInfoLevel, out dcCount, out dcInfoPtr); 1107 } 1108 1109 if (result == 0) 1110 { 1111 try 1112 { 1113 IntPtr currentDc = dcInfoPtr; 1114 for (int i = 0; i < dcCount; i++) 1115 { 1116 if (dcInfoLevel == NativeMethods.DsDomainControllerInfoLevel3) 1117 { 1118 DsDomainControllerInfo3 domainControllerInfo3 = new DsDomainControllerInfo3(); 1119 Marshal.PtrToStructure(currentDc, domainControllerInfo3); 1120 // check if this is the same as "this" DC 1121 if (domainControllerInfo3 != null) 1122 { 1123 if (Utils.Compare(domainControllerInfo3.dnsHostName, replicaName) == 0) 1124 { 1125 initialized = true; 1126 1127 // update all the fields 1128 cachedSiteName = domainControllerInfo3.siteName; 1129 cachedSiteObjectName = domainControllerInfo3.siteObjectName; 1130 _cachedComputerObjectName = domainControllerInfo3.computerObjectName; 1131 cachedServerObjectName = domainControllerInfo3.serverObjectName; 1132 cachedNtdsaObjectName = domainControllerInfo3.ntdsaObjectName; 1133 cachedNtdsaObjectGuid = domainControllerInfo3.ntdsDsaObjectGuid; 1134 } 1135 } 1136 currentDc = IntPtr.Add(currentDc, Marshal.SizeOf(domainControllerInfo3)); 1137 } 1138 else 1139 { //NativeMethods.DsDomainControllerInfoLevel2 1140 DsDomainControllerInfo2 domainControllerInfo2 = new DsDomainControllerInfo2(); 1141 Marshal.PtrToStructure(currentDc, domainControllerInfo2); 1142 // check if this is the same as "this" DC 1143 if (domainControllerInfo2 != null) 1144 { 1145 if (Utils.Compare(domainControllerInfo2.dnsHostName, replicaName) == 0) 1146 { 1147 initialized = true; 1148 1149 // update all the fields 1150 cachedSiteName = domainControllerInfo2.siteName; 1151 cachedSiteObjectName = domainControllerInfo2.siteObjectName; 1152 _cachedComputerObjectName = domainControllerInfo2.computerObjectName; 1153 cachedServerObjectName = domainControllerInfo2.serverObjectName; 1154 cachedNtdsaObjectName = domainControllerInfo2.ntdsaObjectName; 1155 cachedNtdsaObjectGuid = domainControllerInfo2.ntdsDsaObjectGuid; 1156 } 1157 } 1158 currentDc = IntPtr.Add(currentDc, Marshal.SizeOf(domainControllerInfo2)); 1159 } 1160 } 1161 } 1162 finally 1163 { 1164 // free the domain controller info structure 1165 if (dcInfoPtr != IntPtr.Zero) 1166 { 1167 // call DsFreeDomainControllerInfo 1168 functionPtr = UnsafeNativeMethods.GetProcAddress(DirectoryContext.ADHandle, "DsFreeDomainControllerInfoW"); 1169 if (functionPtr == (IntPtr)0) 1170 { 1171 throw ExceptionHelper.GetExceptionFromErrorCode(Marshal.GetLastWin32Error()); 1172 } 1173 NativeMethods.DsFreeDomainControllerInfo dsFreeDomainControllerInfo = (NativeMethods.DsFreeDomainControllerInfo)Marshal.GetDelegateForFunctionPointer(functionPtr, typeof(NativeMethods.DsFreeDomainControllerInfo)); 1174 dsFreeDomainControllerInfo(dcInfoLevel, dcCount, dcInfoPtr); 1175 } 1176 } 1177 1178 // if we couldn't get this DC's info, throw an exception 1179 if (!initialized) 1180 { 1181 throw new ActiveDirectoryOperationException(SR.DCInfoNotFound); 1182 } 1183 1184 _dcInfoInitialized = true; 1185 siteInfoModified = false; 1186 } 1187 else 1188 { 1189 throw ExceptionHelper.GetExceptionFromErrorCode(result, Name); 1190 } 1191 } 1192 GetDSHandle()1193 internal void GetDSHandle() 1194 { 1195 if (_disposed) 1196 { 1197 // cannot bind to the domain controller as the object has been 1198 // disposed (finalizer has been suppressed) 1199 throw new ObjectDisposedException(GetType().Name); 1200 } 1201 1202 // this part of the code needs to be synchronized 1203 lock (this) 1204 { 1205 if (_dsHandle == IntPtr.Zero) 1206 { 1207 // get the credentials object 1208 if (_authIdentity == IntPtr.Zero) 1209 { 1210 _authIdentity = Utils.GetAuthIdentity(context, DirectoryContext.ADHandle); 1211 } 1212 1213 // DsBind 1214 _dsHandle = Utils.GetDSHandle(replicaName, null, _authIdentity, DirectoryContext.ADHandle); 1215 } 1216 } 1217 } 1218 FreeDSHandle()1219 internal void FreeDSHandle() 1220 { 1221 lock (this) 1222 { 1223 // DsUnbind 1224 Utils.FreeDSHandle(_dsHandle, DirectoryContext.ADHandle); 1225 // free the credentials object 1226 Utils.FreeAuthIdentity(_authIdentity, DirectoryContext.ADHandle); 1227 } 1228 } 1229 GetReplicationFailures(DS_REPL_INFO_TYPE type)1230 internal ReplicationFailureCollection GetReplicationFailures(DS_REPL_INFO_TYPE type) 1231 { 1232 IntPtr info = (IntPtr)0; 1233 bool advanced = true; 1234 1235 if (_disposed) 1236 throw new ObjectDisposedException(GetType().Name); 1237 1238 // get the handle 1239 GetDSHandle(); 1240 info = GetReplicationInfoHelper(_dsHandle, (int)type, (int)type, null, ref advanced, 0, DirectoryContext.ADHandle); 1241 return ConstructFailures(info, this, DirectoryContext.ADHandle); 1242 } 1243 GetRoles()1244 private ArrayList GetRoles() 1245 { 1246 ArrayList roleList = new ArrayList(); 1247 int result = 0; 1248 IntPtr rolesPtr = IntPtr.Zero; 1249 1250 GetDSHandle(); 1251 // Get the roles 1252 // call DsListRoles 1253 IntPtr functionPtr = UnsafeNativeMethods.GetProcAddress(DirectoryContext.ADHandle, "DsListRolesW"); 1254 if (functionPtr == (IntPtr)0) 1255 { 1256 throw ExceptionHelper.GetExceptionFromErrorCode(Marshal.GetLastWin32Error()); 1257 } 1258 NativeMethods.DsListRoles dsListRoles = (NativeMethods.DsListRoles)Marshal.GetDelegateForFunctionPointer(functionPtr, typeof(NativeMethods.DsListRoles)); 1259 1260 result = dsListRoles(_dsHandle, out rolesPtr); 1261 if (result == 0) 1262 { 1263 try 1264 { 1265 DsNameResult dsNameResult = new DsNameResult(); 1266 Marshal.PtrToStructure(rolesPtr, dsNameResult); 1267 IntPtr currentItem = dsNameResult.items; 1268 for (int i = 0; i < dsNameResult.itemCount; i++) 1269 { 1270 DsNameResultItem dsNameResultItem = new DsNameResultItem(); 1271 Marshal.PtrToStructure(currentItem, dsNameResultItem); 1272 1273 // check if the role owner is this dc 1274 if (dsNameResultItem.status == NativeMethods.DsNameNoError) 1275 { 1276 if (dsNameResultItem.name.Equals(NtdsaObjectName)) 1277 { 1278 // add this role to the array 1279 // the index of the item in the result signifies 1280 // which role owner it is 1281 roleList.Add((ActiveDirectoryRole)i); 1282 } 1283 } 1284 currentItem = IntPtr.Add(currentItem, Marshal.SizeOf(dsNameResultItem)); 1285 } 1286 } 1287 finally 1288 { 1289 // free the DsNameResult structure 1290 if (rolesPtr != IntPtr.Zero) 1291 { 1292 // call DsFreeNameResult 1293 functionPtr = UnsafeNativeMethods.GetProcAddress(DirectoryContext.ADHandle, "DsFreeNameResultW"); 1294 if (functionPtr == (IntPtr)0) 1295 { 1296 throw ExceptionHelper.GetExceptionFromErrorCode(Marshal.GetLastWin32Error()); 1297 } 1298 UnsafeNativeMethods.DsFreeNameResultW dsFreeNameResult = (UnsafeNativeMethods.DsFreeNameResultW)Marshal.GetDelegateForFunctionPointer(functionPtr, typeof(UnsafeNativeMethods.DsFreeNameResultW)); 1299 dsFreeNameResult(rolesPtr); 1300 } 1301 } 1302 } 1303 else 1304 { 1305 throw ExceptionHelper.GetExceptionFromErrorCode(result, Name); 1306 } 1307 return roleList; 1308 } 1309 ParseDateTime(string dateTime)1310 private DateTime ParseDateTime(string dateTime) 1311 { 1312 int year = (int)Int32.Parse(dateTime.Substring(0, 4), NumberFormatInfo.InvariantInfo); 1313 int month = (int)Int32.Parse(dateTime.Substring(4, 2), NumberFormatInfo.InvariantInfo); 1314 int day = (int)Int32.Parse(dateTime.Substring(6, 2), NumberFormatInfo.InvariantInfo); 1315 int hour = (int)Int32.Parse(dateTime.Substring(8, 2), NumberFormatInfo.InvariantInfo); 1316 int min = (int)Int32.Parse(dateTime.Substring(10, 2), NumberFormatInfo.InvariantInfo); 1317 int sec = (int)Int32.Parse(dateTime.Substring(12, 2), NumberFormatInfo.InvariantInfo); 1318 1319 // this is the UniversalTime 1320 return new DateTime(year, month, day, hour, min, sec, 0); 1321 } 1322 InternalGetDirectorySearcher()1323 private DirectorySearcher InternalGetDirectorySearcher() 1324 { 1325 DirectoryEntry de = new DirectoryEntry("LDAP://" + Name); 1326 1327 de.AuthenticationType = Utils.DefaultAuthType | AuthenticationTypes.ServerBind; 1328 1329 de.Username = context.UserName; 1330 de.Password = context.Password; 1331 1332 return new DirectorySearcher(de); 1333 } 1334 #endregion private methods 1335 } 1336 } 1337