コード例 #1
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 GUID
                    this.DomainGuid = dataTableCursor.RetrieveColumnAsGuid(schema.FindColumnId(CommonDirectoryAttributes.ObjectGUID));

                    // 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));

                    // Load DC OS
                    this.OSName = dataTableCursor.RetrieveColumnAsString(schema.FindColumnId(CommonDirectoryAttributes.OperatingSystemName));

                    // Load DC GUID
                    this.Guid = dataTableCursor.RetrieveColumnAsGuid(schema.FindColumnId(CommonDirectoryAttributes.ObjectGUID));

                    // Load DC SID
                    this.Sid = dataTableCursor.RetrieveColumnAsSid(schema.FindColumnId(CommonDirectoryAttributes.ObjectSid));

                    // Load DC DN
                    this.ServerReference = context.DistinguishedNameResolver.Resolve(this.ServerReferenceDNT.Value);
                }

                // The crossRefContainer does not exist in initial DBs, as it is created during dcpromo.
                if (this.State != DatabaseState.Boot)
                {
                    // 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 == this.DomainNamingContextDNT)
                        {
                            // This must be the DC's domain crossRef object, so we can retrieve its NetBIOS name.
                            this.NetBIOSDomainName = dataTableCursor.RetrieveColumnAsString(schema.FindColumnId(CommonDirectoryAttributes.NetBIOSName));
                        }

                        if (partitionNCNameDNT == this.ConfigurationNamingContextDNT)
                        {
                            // This must be the configuration partition's crossRef object, so we can retrieve the forest DNS name.
                            this.ForestName = dataTableCursor.RetrieveColumnAsString(schema.FindColumnId(CommonDirectoryAttributes.DNSRoot));
                        }
                    }
                }
            }
        }
コード例 #2
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);
                }
            }
        }
コード例 #3
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);
                }
            }
        }