/// <summary>
        ///
        /// </summary>
        /// <param name="dnTag"></param>
        /// <returns></returns>
        /// <exception cref="DirectoryObjectNotFoundException"></exception>
        public DistinguishedName Resolve(int dnTag)
        {
            if (dnTag < ADConstants.RootDNTag)
            {
                throw new ArgumentOutOfRangeException("dnTag");
            }
            if (dnTag == ADConstants.RootDNTag)
            {
                // TODO: or null?
                return(new DistinguishedName());
            }
            // TODO: Move to constructor?
            var dntColId     = schema.FindColumnId(CommonDirectoryAttributes.DNTag);
            var pdntColId    = schema.FindColumnId(CommonDirectoryAttributes.ParentDNTag);
            var rdnColId     = schema.FindColumnId(CommonDirectoryAttributes.RDN);
            var rdnTypeColId = schema.FindColumnId(CommonDirectoryAttributes.RDNType);

            DistinguishedName dn = new DistinguishedName();

            cursor.CurrentIndex = schema.FindIndexName(CommonDirectoryAttributes.DNTag);
            int currentDNTag = dnTag;

            do
            {
                bool found = cursor.GotoKey(Key.Compose(currentDNTag));
                if (!found)
                {
                    throw new DirectoryObjectNotFoundException(dnTag);
                }
                string name    = cursor.RetrieveColumnAsString(rdnColId);
                int    rdnType = cursor.RetrieveColumnAsInt(rdnTypeColId).Value;
                string rdnAtt  = schema.FindAttribute(rdnType).Name.ToUpper();
                dn.AddParent(rdnAtt, name);
                currentDNTag = cursor.RetrieveColumnAsDNTag(pdntColId).Value;
            } while (currentDNTag != ADConstants.RootDNTag);

            // TODO: Parent DN Caching
            return(dn);
        }
示例#2
0
        /// <summary>
        /// Recursively resolves a DN Tag to a full distinguished name.
        /// </summary>
        /// <param name="dnTag">Distinguished name tag</param>
        /// <returns>Resolved DN</returns>
        /// <exception cref="DirectoryObjectNotFoundException" />
        public DistinguishedName Resolve(int dnTag)
        {
            // Check the DN cache first
            DistinguishedName dnFromCache = this.TryResolveFromCache(dnTag);

            if (dnFromCache != null)
            {
                // We just return the DN from cache.
                return(dnFromCache);
            }

            if (dnTag < ADConstants.RootDNTag)
            {
                // Minimum DN Tag is 2.
                throw new ArgumentOutOfRangeException("dnTag");
            }

            // Cache column IDs
            var dntColId     = schema.FindColumnId(CommonDirectoryAttributes.DNTag);
            var pdntColId    = schema.FindColumnId(CommonDirectoryAttributes.ParentDNTag);
            var rdnColId     = schema.FindColumnId(CommonDirectoryAttributes.RDN);
            var rdnTypeColId = schema.FindColumnId(CommonDirectoryAttributes.RDNType);

            // Set index to the Distinguished Name Tag (~primary key)
            cursor.CurrentIndex = schema.FindIndexName(CommonDirectoryAttributes.DNTag);

            // We will build the DN from leaf to root
            DistinguishedName result = new DistinguishedName();
            int currentDNTag         = dnTag;

            while (currentDNTag != ADConstants.RootDNTag)
            {
                // Move cursor to the current object
                bool found = cursor.GotoKey(Key.Compose(currentDNTag));
                if (!found)
                {
                    throw new DirectoryObjectNotFoundException(dnTag);
                }

                // Retrieve the current object's RDN, e.g. CN=Administrator
                string name       = cursor.RetrieveColumnAsString(rdnColId);
                int    rdnType    = cursor.RetrieveColumnAsInt(rdnTypeColId).Value;
                string rdnAtt     = schema.FindAttribute(rdnType).Name.ToUpper();
                var    currentRDN = new DistinguishedNameComponent(rdnAtt, name);

                // Concat the current RDN with the child RDN in result
                result.AddParent(currentRDN);

                // Identify the current object's parent
                int parentDNTag = cursor.RetrieveColumnAsDNTag(pdntColId).Value;

                // Check the DN cache
                DistinguishedName parentDN = this.TryResolveFromCache(parentDNTag);
                if (parentDN != null)
                {
                    // We have found the parent object in DN cache.
                    result.AddParent(parentDN);

                    // Add the current object to cache if the parent is DC or root.
                    bool shoulCache = parentDN.Components.Count == 0 ||
                                      String.Equals(parentDN.Components[0].Name, CommonDirectoryAttributes.DomainComponent, StringComparison.OrdinalIgnoreCase);
                    if (shoulCache)
                    {
                        var currentDN = new DistinguishedName(currentRDN);
                        currentDN.AddParent(parentDN);
                        this.dnCache.Add(currentDNTag, currentDN);
                    }

                    // We can stop the recursion as we have resolved the entire DN using cache.
                    break;
                }

                // Move upwards to the object's parent as we have not found it in the DN cache.
                currentDNTag = parentDNTag;
            }

            return(result);
        }