示例#1
0
 protected override void BeginProcessing()
 {
     // TODO: Debug output
     this.WriteDebug("Opening the Active Directory database.");
     try
     {
         // Resolve possibly relative paths to absolute paths:
         string dbPathResolved = this.ResolveSinglePath(this.DBPath);
         string logPathResolved = this.ResolveSinglePath(this.LogPath);
         this.DirectoryContext = new DirectoryContext(dbPathResolved, this.ReadOnly, logPathResolved);
     }
     catch(SessionStateException ex)
     {
         // This may be DriveNotFoundException, ItemNotFoundException, ProviderNotFoundException, etc.
         // Terminate on this error:
         this.ThrowTerminatingError(new ErrorRecord(ex.ErrorRecord, ex));
     }
     catch (Exception ex)
     {
         ErrorRecord error = new ErrorRecord(ex, "DBContextError", ErrorCategory.OpenError, null);
         // Terminate on this error:
         this.ThrowTerminatingError(error);
     }
 }
示例#2
0
 protected virtual void Dispose(bool disposing)
 {
     if (disposing && this.DirectoryContext != null)
     {
         this.DirectoryContext.Dispose();
         this.DirectoryContext = null;
     }
 }
示例#3
0
 public DirectoryAgent(DirectoryContext context, bool ownsContext = false)
 {
     this.context         = context;
     this.ownsContext     = ownsContext;
     this.dataTableCursor = context.OpenDataTable();
 }
 public DatastoreObject(Cursor datatableCursor, DirectoryContext context)
 {
     this.cursor  = datatableCursor;
     this.context = context;
 }
示例#5
0
        public DomainController(DirectoryContext context)
        {
            // TODO: Split to different methods.

            // Open the hiddentable
            this.systemTableCursor = context.OpenSystemTable();

            // Go to the first and only record in the hiddentable:
            this.systemTableCursor.MoveToFirst();

            // Load attributes from the hiddentable:
            this.NTDSSettingsDNT = this.systemTableCursor.RetrieveColumnAsInt(ntdsSettingsCol).Value;

            if (this.systemTableCursor.TableDefinition.Columns.Contains(osVersionMajorCol))
            {
                // Some databases like the initial adamntds.dit or ntds.dit on Windows Server 2003 do not contain the OS Version
                this.OSVersionMinor = this.systemTableCursor.RetrieveColumnAsUInt(osVersionMinorCol);
                this.OSVersionMajor = this.systemTableCursor.RetrieveColumnAsUInt(osVersionMajorCol);
            }

            if (this.systemTableCursor.TableDefinition.Columns.Contains(epochCol))
            {
                // This is a new feature since Windows Server 2008
                this.epochCache = this.systemTableCursor.RetrieveColumnAsInt(epochCol);
            }

            if (this.systemTableCursor.TableDefinition.Columns.Contains(usnAtIfmCol))
            {
                this.UsnAtIfm = this.systemTableCursor.RetrieveColumnAsLong(usnAtIfmCol);
            }

            // Load and cache the backup expiration time
            this.backupExpirationCache = this.systemTableCursor.RetrieveColumnAsGeneralizedTime(backupExpirationCol);

            this.BackupUsn = this.systemTableCursor.RetrieveColumnAsLong(backupUsnCol);
            this.State     = (DatabaseState)this.systemTableCursor.RetrieveColumnAsInt(stateCol).Value;
            byte[] binaryFlags   = this.systemTableCursor.RetrieveColumnAsByteArray(flagsCol);
            var    databaseFlags = new DatabaseFlags(binaryFlags);

            this.IsADAM = databaseFlags.ADAMDatabase;
            // TODO: Export other database flags, not just IsADAM.
            // TODO: Load database health
            this.highestUSNCache = this.systemTableCursor.RetrieveColumnAsLong(highestCommitedUsnCol).Value;

            // Now we can load the Invocation ID and other information from the datatable:
            using (var dataTableCursor = context.OpenDataTable())
            {
                // Goto NTDS Settings object:
                DirectorySchema schema = context.Schema;
                dataTableCursor.CurrentIndex = schema.FindIndexName(CommonDirectoryAttributes.DNTag);
                bool ntdsFound = dataTableCursor.GotoKey(Key.Compose(this.NTDSSettingsDNT));

                // Load data from the NTDS Settings object
                this.InvocationId = dataTableCursor.RetrieveColumnAsGuid(schema.FindColumnId(CommonDirectoryAttributes.InvocationId)).Value;
                this.DsaGuid      = dataTableCursor.RetrieveColumnAsGuid(schema.FindColumnId(CommonDirectoryAttributes.ObjectGUID)).Value;
                this.Options      = dataTableCursor.RetrieveColumnAsDomainControllerOptions(schema.FindColumnId(CommonDirectoryAttributes.Options));
                string ntdsName = dataTableCursor.RetrieveColumnAsString(schema.FindColumnId(CommonDirectoryAttributes.CommonName));

                // Retrieve Configuration Naming Context
                this.ConfigurationNamingContextDNT = dataTableCursor.RetrieveColumnAsDNTag(schema.FindColumnId(CommonDirectoryAttributes.NamingContextDNTag)).Value;
                this.ConfigurationNamingContext    = context.DistinguishedNameResolver.Resolve(this.ConfigurationNamingContextDNT);

                // Retrieve Schema Naming Context
                this.SchemaNamingContextDNT = dataTableCursor.RetrieveColumnAsDNTag(schema.FindColumnId(CommonDirectoryAttributes.SchemaLocation)).Value;
                this.SchemaNamingContext    = context.DistinguishedNameResolver.Resolve(this.SchemaNamingContextDNT);

                // Goto DC object (parent of NTDS):
                bool dcFound = dataTableCursor.GotoParentObject(schema);

                // Load data from the DC object

                // Load DC name:
                string dcName = dataTableCursor.RetrieveColumnAsString(schema.FindColumnId(CommonDirectoryAttributes.CommonName));

                // DC name is null in the initial database, so use NTDS Settings object's CN instead
                this.Name = dcName ?? ntdsName;

                // Load DNS Host Name
                this.DNSHostName = dataTableCursor.RetrieveColumnAsString(schema.FindColumnId(CommonDirectoryAttributes.DNSHostName));

                // Load server reference to domain partition:
                int dcDNTag = dataTableCursor.RetrieveColumnAsDNTag(schema.FindColumnId(CommonDirectoryAttributes.DNTag)).Value;
                this.ServerReferenceDNT = context.LinkResolver.GetLinkedDNTag(dcDNTag, CommonDirectoryAttributes.ServerReference);

                // Goto Servers object (parent of DC):
                bool serversFound = dataTableCursor.GotoParentObject(schema);

                // Goto Site object (parent of servers):
                bool siteFound = dataTableCursor.GotoParentObject(schema);

                // Load data from the Site object
                if (siteFound)
                {
                    this.SiteName = dataTableCursor.RetrieveColumnAsString(schema.FindColumnId(CommonDirectoryAttributes.CommonName));
                }

                // Load partitions (linked multivalue attribute)
                // TODO: Does not return PAS partitions on RODCs
                IEnumerable <int> partitionDNTags = context.LinkResolver.GetLinkedDNTags(this.NTDSSettingsDNT, CommonDirectoryAttributes.MasterNamingContexts);
                this.WritablePartitions = context.DistinguishedNameResolver.Resolve(partitionDNTags).Select(dn => dn.ToString()).ToArray();

                // Load domain (linked multivalue attribute)
                // TODO: Test this against a GC and RODC:
                this.DomainNamingContextDNT = context.LinkResolver.GetLinkedDNTag(this.NTDSSettingsDNT, CommonDirectoryAttributes.DomainNamingContexts);
                if (this.DomainNamingContextDNT.HasValue)
                {
                    // Move cursor to domain:
                    bool domainObjectFound = dataTableCursor.GotoKey(Key.Compose(this.DomainNamingContextDNT.Value));

                    // Load domain SID
                    this.DomainSid = dataTableCursor.RetrieveColumnAsSid(schema.FindColumnId(CommonDirectoryAttributes.ObjectSid));

                    // Load domain naming context:
                    this.DomainNamingContext = context.DistinguishedNameResolver.Resolve(this.DomainNamingContextDNT.Value);

                    // Load the domain functional level
                    this.DomainMode = dataTableCursor.RetrieveColumnAsFunctionalLevel(schema.FindColumnId(CommonDirectoryAttributes.FunctionalLevel));
                }

                // Goto server object in domain partition
                if (this.ServerReferenceDNT.HasValue)
                {
                    bool serverFound = dataTableCursor.GotoKey(Key.Compose(this.ServerReferenceDNT.Value));
                    this.OSName          = dataTableCursor.RetrieveColumnAsString(schema.FindColumnId(CommonDirectoryAttributes.OperatingSystemName));
                    this.ServerReference = context.DistinguishedNameResolver.Resolve(this.ServerReferenceDNT.Value);
                }

                // Construct crossRefContainer DN (CN=Partitions,CN=Configuration,...)
                var crossRefContainer = new DistinguishedName(CrossRefContainerRDN);
                crossRefContainer.AddParent(this.ConfigurationNamingContext);

                // Goto crossRefContainer
                var  crossRefContainerDNT   = context.DistinguishedNameResolver.Resolve(crossRefContainer);
                bool crossRefContainerFound = dataTableCursor.GotoKey(Key.Compose(crossRefContainerDNT));

                // Read the forest functional level from the crossRefContainer object we just located
                this.ForestMode = dataTableCursor.RetrieveColumnAsFunctionalLevel(schema.FindColumnId(CommonDirectoryAttributes.FunctionalLevel));

                // Go through all crossRef objects (children of the crossRefContainer)
                dataTableCursor.FindChildren(schema);
                while (dataTableCursor.MoveNext())
                {
                    // Find the directory partition that is associated with the current crossRef object
                    var partitionNCNameDNT = dataTableCursor.RetrieveColumnAsDNTag(schema.FindColumnId(CommonDirectoryAttributes.NamingContextName));

                    // Note that foreign crossRef objects do not have nCName set
                    if (partitionNCNameDNT.HasValue)
                    {
                        // Get the DN of the target directory partition
                        var partitionNCName = context.DistinguishedNameResolver.Resolve(partitionNCNameDNT.Value);

                        // We are only interested in domain partition
                        if (partitionNCName.Equals(this.DomainNamingContext))
                        {
                            // This must be the DC's domain crossRef object, so we can retrieve its NetBIOS name
                            this.NetBIOSDomainName = dataTableCursor.RetrieveColumnAsString(schema.FindColumnId(CommonDirectoryAttributes.NetBIOSName));
                        }
                    }
                }
            }
        }
示例#6
0
        public DomainController(DirectoryContext context)
        {
            // TODO: Split to different methods.

            // Open the hiddentable
            this.systemTableCursor = context.OpenSystemTable();
            // Go to the first and only record in the hiddentable:
            this.systemTableCursor.MoveToFirst();
            // Load attributes from the hiddentable:
            this.NTDSSettingsDNT = this.systemTableCursor.RetrieveColumnAsInt(ntdsSettingsCol).Value;
            if(this.systemTableCursor.TableDefinition.Columns.Contains(osVersionMajorCol))
            {
                // Some databases like the initial adamntds.dit or ntds.dit on Windows Server 2003 do not contain the OS Version
                this.OSVersionMinor = this.systemTableCursor.RetrieveColumnAsUInt(osVersionMinorCol);
                this.OSVersionMajor = this.systemTableCursor.RetrieveColumnAsUInt(osVersionMajorCol);
            }
            if (this.systemTableCursor.TableDefinition.Columns.Contains(epochCol))
            {
                // This is a new feature since Windows Server 2008
                this.epochCache = this.systemTableCursor.RetrieveColumnAsInt(epochCol);
            }
            if (this.systemTableCursor.TableDefinition.Columns.Contains(usnAtIfmCol))
            {
                this.UsnAtIfm = this.systemTableCursor.RetrieveColumnAsLong(usnAtIfmCol);
            }
            this.BackupExpiration = this.systemTableCursor.RetrieveColumnAsGeneralizedTime(backupExpirationCol);
            this.BackupUsn = this.systemTableCursor.RetrieveColumnAsLong(backupUsnCol);
            this.State = (DatabaseState) this.systemTableCursor.RetrieveColumnAsInt(stateCol).Value;
            byte[] binaryFlags = this.systemTableCursor.RetrieveColumnAsByteArray(flagsCol);
            var databaseFlags = new DatabaseFlags(binaryFlags);
            this.IsADAM = databaseFlags.ADAMDatabase;
            // TODO: Export other database flags, not just IsADAM.
            // TODO: Load database health
            this.highestUSNCache = this.systemTableCursor.RetrieveColumnAsLong(highestCommitedUsnCol).Value;

            // Now we can load the Invocation ID and other information from the datatable:
            using (var dataTableCursor = context.OpenDataTable())
            {
                // Goto NTDS Settings object:
                DirectorySchema schema = context.Schema;
                dataTableCursor.CurrentIndex = schema.FindIndexName(CommonDirectoryAttributes.DNTag);
                bool ntdsFound = dataTableCursor.GotoKey(Key.Compose(this.NTDSSettingsDNT));
                // Load data from the NTDS Settings object
                this.InvocationId = dataTableCursor.RetrieveColumnAsGuid(schema.FindColumnId(CommonDirectoryAttributes.InvocationId)).Value;
                this.DsaGuid = dataTableCursor.RetrieveColumnAsGuid(schema.FindColumnId(CommonDirectoryAttributes.ObjectGUID)).Value;
                this.Options = dataTableCursor.RetrieveColumnAsDomainControllerOptions(schema.FindColumnId(CommonDirectoryAttributes.Options));
                string ntdsName = dataTableCursor.RetrieveColumnAsString(schema.FindColumnId(CommonDirectoryAttributes.CommonName));

                // Retrieve Configuration Naming Context
                this.ConfigurationNamingContextDNT = dataTableCursor.RetrieveColumnAsDNTag(schema.FindColumnId(CommonDirectoryAttributes.NamingContextDNTag)).Value;
                this.ConfigurationNamingContext = context.DistinguishedNameResolver.Resolve(this.ConfigurationNamingContextDNT);

                // Retrieve Schema Naming Context
                this.SchemaNamingContextDNT = dataTableCursor.RetrieveColumnAsDNTag(schema.FindColumnId(CommonDirectoryAttributes.SchemaLocation)).Value;
                this.SchemaNamingContext = context.DistinguishedNameResolver.Resolve(this.SchemaNamingContextDNT);

                // Goto DC object (parent of NTDS):
                bool dcFound = dataTableCursor.GotoToParentObject(schema);
                // Load data from the DC object
                // Load DC name:
                string dcName = dataTableCursor.RetrieveColumnAsString(schema.FindColumnId(CommonDirectoryAttributes.CommonName));
                // DC name is null in the initial database, so use NTDS Settings object's CN instead
                this.Name = dcName ?? ntdsName;

                // Load DNS Host Name
                this.DNSHostName = dataTableCursor.RetrieveColumnAsString(schema.FindColumnId(CommonDirectoryAttributes.DNSHostName));

                // Load server reference to domain partition:
                int dcDNTag = dataTableCursor.RetrieveColumnAsDNTag(schema.FindColumnId(CommonDirectoryAttributes.DNTag)).Value;
                this.ServerReferenceDNT = context.LinkResolver.GetLinkedDNTag(dcDNTag, CommonDirectoryAttributes.ServerReference);

                // Goto Servers object (parent of DC):
                bool serversFound = dataTableCursor.GotoToParentObject(schema);
                // Goto Site object (parent of servers):
                bool siteFound = dataTableCursor.GotoToParentObject(schema);
                // Load data from the Site object
                if(siteFound)
                {
                    this.SiteName = dataTableCursor.RetrieveColumnAsString(schema.FindColumnId(CommonDirectoryAttributes.CommonName));
                }

                // Load partitions (linked multivalue attribute)
                // TODO: Does not return PAS partitions on RODCs
                IEnumerable<int> partitionDNTags = context.LinkResolver.GetLinkedDNTags(this.NTDSSettingsDNT, CommonDirectoryAttributes.MasterNamingContexts);
                this.WritablePartitions = context.DistinguishedNameResolver.Resolve(partitionDNTags).Select(dn => dn.ToString()).ToArray();

                // Load domain (linked multivalue attribute)
                // TODO: Test this against a GC and RODC:
                this.DomainNamingContextDNT = context.LinkResolver.GetLinkedDNTag(this.NTDSSettingsDNT, CommonDirectoryAttributes.DomainNamingContexts);
                if (this.DomainNamingContextDNT.HasValue)
                {
                    // Move cursor to domain:
                    bool domainObjectFound = dataTableCursor.GotoKey(Key.Compose(this.DomainNamingContextDNT.Value));

                    // Load domain SID
                    this.DomainSid = dataTableCursor.RetrieveColumnAsSid(schema.FindColumnId(CommonDirectoryAttributes.ObjectSid));

                    // Load domain naming context:
                    this.DomainNamingContext = context.DistinguishedNameResolver.Resolve(this.DomainNamingContextDNT.Value);
                }

                // Goto server object in domain partition
                if (this.ServerReferenceDNT.HasValue)
                {
                    bool serverFound = dataTableCursor.GotoKey(Key.Compose(this.ServerReferenceDNT.Value));
                    this.OSName = dataTableCursor.RetrieveColumnAsString(schema.FindColumnId(CommonDirectoryAttributes.OperatingSystemName));
                    this.ServerReference = context.DistinguishedNameResolver.Resolve(this.ServerReferenceDNT.Value);
                }
            }
        }
示例#7
0
 protected virtual void Dispose(bool disposing)
 {
     if (!disposing)
     {
         return;
     }
     if (this.dataTableCursor != null)
     {
         this.dataTableCursor.Dispose();
         this.dataTableCursor = null;
     }
     if (this.ownsContext && this.context != null)
     {
         this.context.Dispose();
         this.context = null;
     }
 }
示例#8
0
 public DirectoryAgent(DirectoryContext context, bool ownsContext = false)
 {
     this.context = context;
     this.ownsContext = ownsContext;
     this.dataTableCursor = context.OpenDataTable();
 }