/// <summary>
        ///  Check objectClass.
        /// </summary>
        /// <param name="obj">ModelObject.</param>
        public static void CheckObjectClass(ModelObject obj)
        {
            string dn          = (string)obj[StandardNames.shortName];
            Value  objectClass = obj[StandardNames.objectClass];

            if (objectClass == null)
            {
                Checks.Fail("'{0}' must have object class", dn);

                return;
            }

            // Check for resolution and last/first element compliance
            int           count     = 0;
            List <string> classes   = obj.GetAllClassIds().ToList();
            bool          resolveOk = true;

            foreach (string classId in classes)
            {
                ModelObject classObject;
                //The object must be present in Schema NC.
                if (!obj.dc.TryGetClass(classId, out classObject))
                {
                    Checks.Fail("'{0}' has undefined object class '{1}'", dn, classId);
                    resolveOk = false;
                    continue;
                }
                //Checking for the first class is Top
                if (count == 0 && classId != StandardNames.top)
                {
                    Checks.Fail("'{0}' first object class must be top", dn);
                    resolveOk = false;
                }
                //Checking for the last class is Structural class.
                if (count == objectClass.UnderlyingValues.Count - 1)
                {
                    ObjectClassCategory category = (ObjectClassCategory)(int)classObject[StandardNames.objectClassCategory];

                    if (category != ObjectClassCategory.StructuralClass)
                    {
                        Checks.Fail("'{0}' last object class must be structural");
                        resolveOk = false;
                    }
                }
                count++;
            }
            if (!resolveOk)
            {
                return;
            }

            // Check for superclass chaining
            // Checks that if the value of object class is [top,ac_1,...,ac_n,sc_1,...,sc_n],
            // then sc_n is the most specific structural class, sc_1...scn_(n-1) is the super class chain of sc_n (excluding top),
            // and ac_n is the next auxilary class before that, where ac_1...acn(n-1) is that classes chain excluding classes
            // which have been seen already before (where there can be a number of ac anchors here).
            List <string> includedClasses = new List <string>();
            int           i = classes.Count - 1;

            while (i > 0)
            {
                string classId = classes[i--];
                if (includedClasses.Contains(classId))
                {
                    Checks.Fail("'{0}' object class contains repeated entries", dn);
                    break;
                }
                includedClasses.Add(classId);
                ObjectClassCategory category = (ObjectClassCategory)(int)obj.dc.GetClass(classId)[StandardNames.objectClassCategory];
                if (i == classes.Count - 2)
                {
                    // Most specific class must be structural
                    if (category != ObjectClassCategory.StructuralClass)
                    {
                        Checks.Fail("'{0}' object class most specific class must be structural", dn);
                    }
                }

                //If the server is Pre Windows 2003.
                foreach (string clId in GetSuperClassChain(obj.dc, classId))
                {
                    if (includedClasses.Contains(clId))
                    {
                        // Already included in a previous chain
                        continue;
                    }
                    includedClasses.Add(clId);
                    if (i <= 0)
                    {
                        Checks.Fail(
                            "'{0}' object class does not contain chain of super classes of '{1}' (classes missing)",
                            dn,
                            classId);
                        break;
                    }
                    if (classes[i--] != clId)
                    {
                        Checks.Fail(
                            "'{0}' object class does not contain chain of super classes '{1}' (found unexpected '{2}')",
                            dn,
                            classId,
                            classes[i + 1]);
                        break;
                    }
                }
            }
        }
Exemple #2
0
        public void ValidateObjectClassRequirements(DirectoryEntries childrens, bool isADDS)
        {
            bool isObjectClassMultiValued = false;
            bool isObjectClassAppeared    = false;
            bool isObjectClassTop         = false;
            bool isObjectClassStructural  = false;

            foreach (DirectoryEntry child in childrens)
            {
                //Get objectClass value.
                PropertyValueCollection propValColln = child.Properties[StandardNames.objectClass];

                //If it is not existing Requirement 130 will fail.
                if (propValColln != null)
                {
                    isObjectClassAppeared = true;
                }

                //It is multivalued. so it should be more than one value.
                if (propValColln.Count >= 1)
                {
                    isObjectClassMultiValued = true;
                }

                //Get objectClassValue in array.
                string[] objectClassElements = new string[propValColln.Count];
                int      loopVariable        = 0;
                foreach (string propVal in (IEnumerable <object>)propValColln.Value)
                {
                    objectClassElements[loopVariable++] = propVal;
                }

                //The first element is always top.
                if (objectClassElements[0].ToLower().Equals("top"))
                {
                    isObjectClassTop = true;
                }

                //Get last element.
                string         structuralClassName = (string)child.Properties["objectCategory"].Value;
                DirectoryEntry lastClassObject;
                if (isADDS)
                {
                    if (!adAdapter.GetObjectByDN(structuralClassName, out lastClassObject))
                    {
                        DataSchemaSite.Assume.IsTrue(false, structuralClassName + " Object is not found in server");
                    }
                }
                else
                {
                    if (!adAdapter.GetLdsObjectByDN(structuralClassName, out lastClassObject))
                    {
                        DataSchemaSite.Assume.IsTrue(false, structuralClassName + " Object is not found in server");
                    }
                }
                ObjectClassCategory lastClassCategory = (ObjectClassCategory)(int)lastClassObject.
                                                        Properties[StandardNames.objectClassCategory.ToLower()][0];

                //The last element should be structural class.
                if (lastClassCategory == ObjectClassCategory.StructuralClass)
                {
                    isObjectClassStructural = true;
                }

                if (isObjectClassAppeared && isObjectClassMultiValued && isObjectClassStructural && isObjectClassTop)
                {
                    continue;
                }
                else
                {
                    break;
                }
            }
            //MS-ADTS-Schema_R143.
            DataSchemaSite.CaptureRequirementIfIsTrue(
                isObjectClassMultiValued &&
                isObjectClassAppeared,
                143,
                "Attribute objectClass is a multivalued attribute that appears on all the objects in the directory.");

            //MS-ADTS-Schema_R144.
            DataSchemaSite.CaptureRequirementIfIsTrue(
                isObjectClassMultiValued &&
                isObjectClassAppeared,
                144,
                @"When instantiating a structural class, the objectClass attribute of the new object contains a 
                sequence of class names");

            //MS-ADTS-Schema_R145.
            DataSchemaSite.CaptureRequirementIfIsTrue(
                isObjectClassTop,
                145,
                "In the ObjectClass first element is always class top.");

            //MS-ADTS-Schema_R146.
            DataSchemaSite.CaptureRequirementIfIsTrue(
                isObjectClassStructural,
                146,
                "In the ObjectClass last element is the name of the structural class that was instantiated.");
        }
        /// <summary>
        /// Inheritance is the ability to build new classes from existing classes.
        /// </summary>
        /// <param name="obj">The object of model.</param>
        public static void CheckInheritance(ModelObject obj)
        {
            string dn = (string)obj[StandardNames.shortName];
            //Get super class id.
            string superClassId = (string)obj[StandardNames.subClassOf];

            if (superClassId == null)
            {
                Checks.Fail("'{0}' must have a super class", dn);
            }
            else
            {
                ModelObject superClass;
                if (!obj.dc.TryGetClass(superClassId, out superClass))
                {
                    Checks.Fail("'{0}' has undefined super class '{1}'", dn, superClassId);
                }
                else
                {
                    string thisClassId = (string)obj[StandardNames.governsId];

                    if (thisClassId != StandardNames.topGovernsId && thisClassId == superClassId)
                    {
                        Checks.Fail("{0} cannot inherit from itself", dn);
                    }

                    //Get super class and current class category.
                    ObjectClassCategory thisCategory  = (ObjectClassCategory)(int)obj[StandardNames.objectClassCategory];
                    ObjectClassCategory superCategory = (ObjectClassCategory)(int)superClass[StandardNames.objectClassCategory];
                    bool categoryOk;

                    switch (thisCategory)
                    {
                    //Abstract Class must be inherited from Abstract Class.
                    case ObjectClassCategory.AbstractClass:
                        categoryOk = superCategory == ObjectClassCategory.AbstractClass;
                        break;

                    //Auxiliary Class must not be inherited from Structural Class
                    case ObjectClassCategory.AuxiliaryClass:
                        categoryOk = superCategory != ObjectClassCategory.StructuralClass;
                        break;

                    //Structural Class must not be inherited from Auxiliary Class
                    case ObjectClassCategory.StructuralClass:
                        categoryOk = superCategory != ObjectClassCategory.AuxiliaryClass;
                        break;

                    //Default.
                    default:
                        categoryOk = true;
                        break;
                    }

                    if (!categoryOk)
                    {
                        Checks.Fail("{0} must have object class category which is compatible with its super class", dn);
                    }
                }
            }
        }