The schema is the blueprint for data storage in Active Directory. Each object in Active Directory is an instance of a class in the schema. A user object, for example, exists as an instance of the user class. Attributes define the pieces of information that a class, and thus an instance of that class, can hold. Syntaxes define the type of data that can be placed into an attribute. As an example, if an attribute is defined with a syntax of Boolean, it can store True or False as its value, or it can be null. A null value has an implementation-specific meaning; it could mean True or False depending on the application using the value.
Active Directory contains many attributes and classes in the default schema, some of which are based on standards and some of which Microsoft needed for its own use. Each release of Active Directory since Windows 2000 has included updates to the default schema. For background information on schema versions, see the sidebar Schema Versions,” next. However, the Active Directory schema was designed to be extensible, so that administrators could add classes or attributes they deemed necessary. In fact, extending the schema is not a difficult task; it is often more difficult to design the changes that you would like to incorporate. Schema design issues are covered in Chapter 14, and in Chapter 26, we cover how to extend the schema programmatically. In this chapter, we’re concerned only with the fundamentals of the schema.
Table 4-1. Active Directory default schema versions
Schema version | Release |
---|---|
13 | Windows 2000 |
30 | Windows Server 2003 |
31 | Windows Server 2003 R2 |
44 | Windows Server 2008 |
The Schema Container is located in Active Directory under the
Configuration Container. For example, the distinguished name of the Schema
Container in the http://mycorp.com forest would be
cn=schema,cn=Configuration,dc=mycorp,dc=com
. You
can view the contents of the container directly by pointing an Active
Directory viewer such as ADSIEdit or LDP at it. You can also use the Active
Directory Schema MMC snap-in, which splits the classes and attributes in
separate containers for easy viewing, even though in reality all the
schema objects are stored directly in the Schema Container.
Note
The Active Directory Schema MMC snap-in is not fully enabled by
default. In order to enable the schema management snap-in on a domain
controller, you must first register the DLL which it depends on. To do
that, run this command: regsvr32
schmmgmt.dll
.
The schema itself is made up of two types of Active Directory
objects: classes and attributes. In Active Directory, these are known respectively as
classSchema
(Class-Schema) and attributeSchema
(Attribute-Schema)
objects. The two distinct forms of the same names result from the
fact that the cn
(Common-Name)
attribute of a class contains the hyphenated easy-to-read name of the
class, and the lDAPDisplayName
(LDAP-Display-Name) attribute of a class contains the concatenated string format that is
used when querying Active Directory with LDAP or ADSI. In the schema, the
lDAPDisplayName
attribute of each object is normally made by capitalizing the first letter
of each word of the Common-Name, and then removing the hyphens and
concatenating all the words together. Finally, the first letter is made
lowercase.[3] This creates simple names like user
, as well as the more unusual sAMAccountName
and lDAPDisplayName
. We’ll specify the more commonly
used LDAP display name format from now on.
Whenever you need to create new types of objects in Active
Directory, you must first create a classSchema
object, defining the class of the
object and the attributes it contains. Once the class is properly designed
and added to the schema, you can then create objects in Active Directory
that use the class. If the class you are adding will have custom
attributes that are required to be populated when new instances of that
class are created, you must define the attributeSchema
objects first. If you just want
to add a new attribute to an existing class, you must create the attributeSchema
object and associate the
attribute with whatever classes you want to use it with.
Before we delve into what makes up an Active Directory class or attribute, we need to explain how each class that you create is unique not just within your Active Directory but also throughout the world.
Active Directory is based on LDAP, which was originally based on the X.500 standard created by the ISO (International Organization for Standardization) and ITU (International Telecommunications Union) organizations in 1988. To properly understand how the Active Directory schema works, you really need to understand some of the basics of X.500; we’ll run through them next.
The X.500 standard specifies that individual object classes in an organization can be uniquely defined using a special identifying process. The process has to be able to take into account the fact that classes can inherit from one another, as well as the potential need for any organization in the world to define and export a class of their own design.
To that end, the X.500 standard defined an Object Identifier (OID) to uniquely identify every schema object. This OID is composed of two parts:
The first part indicates the unique path to the branch holding the object in the X.500 tree-like structure.
The second part uniquely indicates the object in that branch.
OID notation uses integers for each branch and object, as in the following example OID for an object:
1.3.6.1.4.1.3385.12.497
This uniquely references object 497 in branch 1.3.6.1.4.1.3385.12. The 1.3.6.1.4.1.3385.12 branch is contained in a branch whose OID is 1.3.6.1.4.1.3385, and so on.
Note
Each branch within an OID number also corresponds to a name. This means that the dotted notation 1.3.6.1.4.1, for example, is equivalent to iso.org.dod.internet.private.enterprise. As the names are of no relevance to us with Active Directory, we don’t cover them in this book.
This notation continues today and is used in the Active Directory schema. If you wish to create a schema object, you need to obtain a unique OID branch for your organization. Using this as your root, you can then create further branches and leaf nodes within the root, as your organization requires.
The Internet Assigned Numbers Authority (IANA) maintains the main set of root branches and defines itself as “the central coordinator for the assignment of unique parameter values for Internet protocols.” The IANA says of its mission:
The IANA is chartered by the Internet Society (ISOC) and the Federal Network Council (FNC) to act as the clearinghouse to assign and coordinate the use of numerous Internet protocol parameters. The Internet protocol suite, as defined by the Internet Engineering Task Force (IETF) and its steering group (the IESG), contains numerous parameters, such as Internet addresses, domain names, autonomous system numbers (used in some routing protocols), protocol numbers, port numbers, management information base object identifiers, including private enterprise numbers, and many others. The common use of the Internet protocols by the Internet community requires that the particular values used in these parameter fields be assigned uniquely. It is the task of the IANA to make those unique assignments as requested and to maintain a registry of the currently assigned values. The IANA is located at and operated by the Information Sciences Institute (ISI) of the University of Southern California (USC).
You can find the IANA web page at http://www.iana.org.
You can request an OID namespace—i.e., a root OID number from which you can create your own branches—directly from the IANA if you like. These numbers are known as Enterprise Numbers. The entire list of Enterprise Numbers assigned by the IANA can be found at http://www.iana.org/assignments/enterprise-numbers. This list of numbers is updated every time a new one is added.
At the top of the file, you can see that the root that the IANA uses is 1.3.6.1.4.1. If you look down the list, you will see that Microsoft has been allocated branch 311 of that part of the tree, so Microsoft’s OID namespace is 1.3.6.1.4.1.311. Leicester University’s OID namespace is 1.3.6.1.4.1.3385. As each number also has a contact email address alongside it in the list, you can search through the file for any member of your organization that has already been allocated a number. It is likely that large organizations that already have an X.500 directory or that have developed SNMP MIBs will have obtained an OID.
Note
In addition to Enterprise Numbers, country-specific OIDs can be purchased as well. An organization’s Enterprise Number registration has no bearing on whether it has obtained a country-based OID namespace to use. If you don’t see the company listed in the Enterprise Numbers list, don’t be fooled; the organization could still have a number.
For example, Microsoft has been issued the Enterprise Number 1.3.6.1.4.1.311, yet all of its new schema classes use a U.S.-issued OID namespace of 1.2.840.113556 as their root. The 1.2.840 part is uniquely allotted to the United States. In other words, Microsoft has obtained two OID namespaces that it can use but is choosing to use only the U.S.-issued namespace.
If you want to obtain an Enterprise Number, fill in the online form at at http://pen.iana.org/pen/PenApplication.page. If this URL changes, you can navigate to it from the main IANA web page.
Microsoft used to issue unique OID namespaces to customers on request; however, they no longer do this. Instead, Microsoft provides a script that will generate a statistically unique OID branch each time it is run. This script is available from http://go.microsoft.com/fwlink/?LinkId=100725.
Note
Using a unique prefix for schema extensions may not seem important at first glance. The benefit of unique prefixes comes into play if a company finds out another company is also using the same prefix. This can become extremely problematic if the other company is an application vendor.
For example, say that MyCorp Financial Services is prefixing
their schema extensions with the “mycorp” prefix. MyCorp Financial has
extended their schema with two new attributes: mycorpAttrib1
and mycorpAttrib2
. MyCorp Financial purchases a
software package from another company, MyCorp Software Solutions, who
also chose to use attribute names of mycorpAttrib1
and mycorpAttrib2
.
In this scenario, MyCorp Financial Services would be in a very bad position. MyCorp Financial’s only option would be changing all previous uses of their attributes so that the names could be reused by the application. If MyCorp Financial did not rename their attributes, they would not be able to use the application that they purchased.
Once an organization has an OID namespace, it can add unique branches and leaves in any manner desired under the root. For example, Leicester University could decide to have no branches underneath and just give any new object an incrementing integer starting from 1 underneath the 1.3.6.1.4.1.3385 root. Alternatively, they could decide to make a series of numbered branches starting from 1, each corresponding to a certain set of classes or attributes that they wish to create. Thus, the fifth object under the third branch would have an OID of 1.3.6.1.4.1. 3385.3.5.
Warning
The range of values in any part of an OID namespace for the Active Directory schema goes from 1 to 268,435,455, i.e., from 20 through 228 – 1.
This limitation has caused issues with schema extensions for some companies in Australia. Australia has the OID 1.2.36, and according to the Australia Standards document MP-75, companies may use their Australian Company Number (excluding leading zeros) to formulate their OID without needing to request an OID. Unfortunately the ACN is nine digits, so it could easily exceed the limitation listed above. This has been filed as a bug and Microsoft is aware of the issue.
To reinforce this point, let’s look at a couple of examples
directly from the Active Directory schema. If you open the Active
Directory Schema snap-in, you can look at the schema class OIDs very
easily. Navigating through the classes when we open the property page
for the printQueue
class, we get
Figure 4-1. You can see that
the unique OID is 1.2.840.113556.1.5.23. This tells us that the number
is a defined part of Microsoft’s
object class hierarchy.
Figure 4-2 shows
the property page for the organizationalPerson
class. Here, you can see
that the unique OID 2.5.6.7 is very different, because within the
original X.500 standard, a set of original classes was defined. One was
organizationalPerson
, and this is a
copy of that class. Microsoft included the entire set of base X.500
classes within Active Directory.
Note
The OID numbering notation has nothing to do with inheritance. Numbering a set of objects a certain way does nothing other than create a structure for you to reference the objects; it does not indicate how objects inherit from one another.
Let’s dissect an example attribute and class to see what they contain. With that information, you will be able to see what is required when you create a new schema object.
Just as class information is stored in Active Directory as instances
of the class called classSchema
,
attributes are represented by instances of the class called attributeSchema
. As with
all objects, the attributeSchema
class
has a number of attributes that can be set when specifying a new instance.
The attributeSchema
class inherits
attributes from the class called top
.
However, most of the top
attributes are
not relevant here. All of the attributes of the attributeSchema
class are documented in the
Platforms SDK at http://msdn2.microsoft.com/en-us/library/ms680969(VS.85).aspx.
The userPrincipalName
(UPN)
attribute is used on user objects to provide a unique method of
identifying each user across a forest. Users can log on to a workstation
in any domain in the forest using the UPN if they so desire. The UPN
attribute, in fact, accepts valid RFC 2822 (email) addresses, so the UPN
for user tpood in the http://europe.mycorp.com domain could be
tpood@mycorp.com or
tpood@europe.mycorp.com, or even
tpood@logon.local. In fact, any UPN suffix, such as
@mycorp.com, can be used in a forest. The only
requirement is that the UPN value for a user is unique across all users
in a forest.
Note
Active Directory does not enforce uniqueness of a UPN when it is set. If two different users in the same forest are assigned the same UPN, neither will be able to log on using the UPN. When duplicate UPNs are detected, domain controllers will log an event from source Key Distribution Center (KDC) with event ID 11. Many large organizations implement scripts or other tools to scan their directories on a regular basis to check for duplicate UPNs.
To dissect the attribute, we need to find out what values had been
set for it. Table 4-2 shows a
subset of the values of attributes that have been set for the userPrincipalName
attributeSchema instance.
Table 4-2. userPrincipalName’s attributes
Attribute lDAPDisplayName | Attribute syntax | Attribute value |
---|---|---|
| CASE_IGNORE_STRING | User-Principal-Name |
| CASE_IGNORE_STRING | User-Principal-Name |
| CASE_IGNORE_STRING | 1.2.840.113556.1.4.656 |
| CASE_IGNORE_STRING | 2.5.5.12 |
| CASE_IGNORE_STRING | User-Principal-Name |
| BOOLEAN | True |
| BOOLEAN | True |
| CASE_IGNORE_STRING | userPrincipalName |
| CASE_IGNORE_STRING | User-Principal-Name |
| DN_STRING | cn=Attribute-Schema, cn=Schema, cn=Configuration, dc=mycorp,dc=com |
| CASE_IGNORE_STRING | top; attributeSchema (two values of a multivalued attribute) |
| INTEGER | 64 |
| INTEGER | 1 (Indexed) |
| BOOLEAN | True |
| INTEGER | 18 (Category 1 attribute, replicated to GC) |
| BOOLEAN | False |
We can see that the name of the attribute is User-Principal-Name
(adminDescription, adminDisplayName, cn, name
),
that it is an instance of the attributeSchema
class (ob-jectCategory
and objectClass
), that it inherits attributes from
both top
and attributeSchema
(objectClass
), and that the UPN attribute is
not visible to casual browsing (showInAdvancedViewOnly
).
The userPrincipalName
attributes show the following:
It is to be stored in the GC (
isMemberOfPartialAttributeSet
andsystemFlags
).It is to be indexed (
searchFlags
).It has an OID of 1.2.840.113556.1.4.656 (
attributeID
).We should use
userPrincipalName
(lDAPDisplayName
) when binding to it with ADSI.Instances can be created by anyone (
systemOnly
).It stores single (
isSingleValued
) Unicode strings (attributeSyntax
andoMSyntax
).
In Figure 4-3, you can see many of the values for the UPN attribute. We have indicated which attributes are changed by checking or unchecking each checkbox.
There are several properties on attributes that have significant and varied impact on attribute use and functionality. Here we give a little more detailed information on a few of these attributes that you need to understand when modifying the schema.
The syntax of an attribute represents the kind of data it can hold; people with a programming background are probably more familiar with the term “data type.” Unlike attributes and classes, the supported syntaxes are not represented as objects in Active Directory. Instead, Microsoft has coded these syntaxes internally into Active Directory itself. Consequently, any new attributes you create in the schema must use one of the predefined syntaxes.
Whenever you create a new attribute, you must specify its syntax. To uniquely identify the syntax among the total set of 21 syntaxes, you must specify two pieces of information: the OID of the syntax and a so-called OM syntax. This pair of values must be set together and correctly correlate with Table 4-3. More than one syntax has the same OID, which may seem strange; and to uniquely distinguish between different syntaxes, you thus need a second identifier. This is the result of Microsoft requiring some syntaxes that X.500 did not provide. Table 4-3 shows the 21 expanded syntaxes, including the name of the syntax with alternate names followed in parentheses.
Table 4-3. Syntax definitions
Syntax | OID | OM syntax | Description |
---|---|---|---|
Address | 2.5.5.13 | 127 | Used internally by the system. |
Boolean | 2.5.5.8 | 1 | True or false. |
Case-insensitive string | 2.5.5.4 | 20 | A string that does not differentiate between uppercase and lowercase. |
Case-sensitive string | 2.5.5.3 | 27 | A string that differentiates between uppercase and lowercase. |
Distinguished name | 2.5.5.1 | 127 | The Fully Qualified Domain Name (FQDN) of an object in Active Directory. |
DN-Binary | 2.5.5.7 | 127 | Octet string with binary value and DN. Format: B:<char count>:<binary value>:<object DN>. |
DN-String | 2.5.5.14 | 127 | Octet string with string value and DN. Format: S:<char count>:<string value>:<object DN>. |
Generalized-Time | 2.5.5.11 | 24 | ASN1.1 time format, e.g., 20040625234417.0Z. |
Integer (enumeration) | 2.5.5.9 | 10 | A 32-bit number. |
Integer (integer) | 2.5.5.9 | 2 | A 32-bit number. |
Large integer | 2.5.5.16 | 65 | A 64-bit number. |
NT Security Descriptor | 2.5.5.15 | 66 | A Security Descriptor (SD). |
Numeric string | 2.5.5.6 | 18 | A string of digits. |
Object ID | 2.5.5.2 | 6 | OID. |
Octet string (Octet-String) | 2.5.5.10 | 4 | A byte string. |
Print case string (IA5-String) | 2.5.5.5 | 22 | A normal printable string. |
Print case string (Printable-String) | 2.5.5.5 | 19 | A normal printable string. |
Replica-Link | 2.5.5.10 | 127 | Replication information. |
SID | 2.5.5.17 | 4 | A security identifier (SID). |
Undefined | 2.5.5.0 | N/A | Not a valid syntax. |
Unicode | 2.5.5.12 | 64 | A wide string. |
UTC-Time | 2.5.5.11 | 23 | The number of seconds elapsed since 1 January 1970. |
Most of these are standard programming types. If you’re not sure
which syntax to use, take a look at a preexisting attribute and see if
you can find an appropriate syntax for the attribute you wish to create.
For example, the userPrincipalName
attribute has an attributeSyntax
of
2.5.5.12 and an oMSyntax
of 64, so it
must contain Unicode strings.
The systemFlags
attribute is an
often overlooked but important attribute. The attribute is a bitmask
that represents how the attribute should be handled. For more
information on bitmasks, see the upcoming sidebar How to Work with Bitmasks.” New bit values can be defined
any time that Microsoft updates the directory service binaries. The
systemFlags
attribute is configured both on schema definitions of attributes and
classes as well as on any instantiated object throughout the forest.
This can be confusing, but the various bits in the attribute can mean
various things depending on the object the attribute applies to. Table 4-4 lists only the
values for systemFlags
on attributeSchema
and
classSchema
objects. A complete
listing of valid systemFlags
settings
is available in the Platform SDK at http://msdn2.microsoft.com/en-us/library/ms680022(VS.85).aspx.
Table 4-4. System flag values for class and attributes objects
Value | Description |
---|---|
1 (0x0001) | Attribute is not replicated. |
2 (0x0002) | Attribute will be replicated to the global catalog.
This value should only be set by Microsoft; do not use. Instead,
use |
4 (0x0004) | Attribute is constructed, not stored in the database. This should only be set by Microsoft; do not use. |
16 (0x0010) | Category 1 attribute or class. Category 1 objects are classes and attributes that are included in the base schema with the system. Note that not all classes and attributes included in the base schema are marked as category 1. |
134217728 (0x08000000) | The schema object cannot be renamed. |
Most attributes are directly stored in the Active Directory
database. Constructed attributes are the exception, and they are
handled by the directory service in order to offer special
functionality. This functionality can range from telling you
approximately how many objects are contained directly under a
container type object (msDS-Approx-Immed-Subordinates
) to telling
you the types of objects that can be instantiated under a given object
(possibleInferiors
) to telling you
which attributes you have write access to on a given object (allowedAttributesEffective
), and many other
things. These attributes, because they are special, have some rules
you should be aware of:
Constructed attributes are not replicated. They are constructed by each directory instance separately.
Constructed attributes cannot be used in server-side sorting.
Constructed attributes generally cannot be used for queries. The attribute
aNR
is an exception here as it is used for constructing the special ANR queries. ANR is covered in the section Ambiguous Name Resolution.”In some cases, a BASE scope query may be required to retrieve certain constructed attributes; e.g.,
tokenGroups
can only be returned with a BASE scope query.
The schemaFlagsEx
attribute is
an attribute that has existed since Windows 2000 but was not put into
use until Windows Server 2008. The schemaFlagsEx
attribute is designed to hold
flags that further define the properties of an attribute. There is
currently only one flag implemented in this bitmask as outlined in Table 4-5.
The searchFlags
attribute is
another bitmask that is best known as the attribute used to control
indexing, but it is a little more involved than that. As indicated by
the name, searchFlags
is similar to
systemFlags
in that it is a series of
bits representing how the attribute should be handled. Unlike systemFlags
, searchFlags
are only set on schema attribute
definitions. See Table 4-6 for all of the
values as of Windows Server 2008.
Table 4-6. Search flag bits
Bit Number | Value | Description |
---|---|---|
1 | 1 (0x0001) | Create an index for the attribute. All other index-based flags require this flag to be enabled as well. Marking linked attributes to be indexed has no effect. |
2 | 2 (0x0002) | Create an index for the attribute in each container. This is only useful for one-level LDAP queries. |
3 | 4 (0x0004) | Add attribute to Ambiguous Name Resolution (ANR) set. ANR queries are primarily used for Exchange and other address book tools. ANR attributes must be indexed and must be either UNICODE or Teletex string attribute syntax. Adding attributes to this set can have performance implications on Microsoft Exchange. |
4 | 8 (0x0008) | Preserve this attribute in a tombstone object. This flag controls what attributes are kept when an object is deleted. |
5 | 16 (0x0010) | Copy this value when the object is copied. This flag doesn’t do anything in Active Directory; tools such as Active Directory Users and Computers that copy objects can look at this flag to determine what attributes should be copied. |
6 | 32 (0x0020) | Create tuple index. Tuple indexing is useful for
medial searches. A medial search has a wildcard at the beginning
or in the middle of the search string. For example, the medial
search ( |
7 | 64 (0x0040) | Create subtree index. This index is only available in ADAM R2 or newer and is designed to increase performance of VLV queries. See the section ADAM Schema” in Chapter 20. |
8 | 128 (0x0080) | Mark attribute as confidential. Only users with both read property and Control Access right to the attribute so marked can view it when it is so marked. This is a new feature as of Windows Server 2003 SP1. SP1 domain controllers will not allow you to mark Category 1 attributes with this flag. |
9 | 256 (0x0100) | Never audit changes to this attribute. This flag is new in Windows Server 2008. Windows Server 2008 auditing enhancements are covered in Chapter 13. |
10 | 512 (0x0200) | Include this attribute in the RODC filtered attribute set. RODCs and the filtered attribute set are covered in Chapter 7. |
Attribute indexing is available to boost performance of queries.
When an attribute is indexed, the values are placed in a special table
in a sorted order so that a query using the attribute can be completed
by looking at a subset of all the information in the directory. The
type of index created can be modified by additional bit flags
configured in the searchFlags
attribute. There are several points to know about indexes:
A query that contains bitwise operations on an indexed attribute diminishes the usefulness of the index. A bitwise operation can’t be directly looked up in the index table and the entire set of values in the index will have to be enumerated and tested. Bitwise queries are queries that query a bitmask, for example, the
systemFlags
oruserAccountControl
attributes.A query that contains a NOT of an indexed attribute negates the use of the index for that portion of the query. A NOT of an attribute requires enumerating all objects in the search scope to determine which objects don’t have the attribute or which objects have permissions applied that disallow the trustee to view the attribute value.
Linked attributes are implicitly indexed, and beginning with Windows Server 2003, the necessary logic to use these indexes was implemented. If you modify the flag, it will have no effect due to the implicit indexing behavior.
It is often assumed that indexes cannot be built or do not work well for attributes with multiple values or non-unique values. This is incorrect. In the early days of the original Active Directory beta, there was concern about multiple values and non-unique values, but the issues surrounding them were addressed. This topic is most often raised in regards to the
objectClass
attribute and is stated as the reason why Microsoft didn’t index the attribute by default prior to Windows Server 2008.If you have installed the Exchange Server 2007 schema extensions in your forest,
objectClass
is indexed as part of this schema extension.Windows Server 2008 domain controllers implement a special behavior that indexes
objectClass
by default regardless of thesearchFlags
setting in Active Directory. Note that this is considered a special behavior because the attribute will not be indexed on Windows 2000 or Windows Server 2003 domain controllers once you import the Windows Server 2008 schema extensions; however, the attribute will be indexed on any Windows Server 2008 servers. This could cause performance deltas in applications that randomly select domain controllers for use. You may consider indexingobjectclass
when you apply the Windows Server 2008 schema updates so that you will have a consistent LDAP query experience across your enterprise once Windows Server 2008 domain controllers are introduced.
While indexing attributes can very frequently improve the performance of LDAP queries, it is important to realize that indexes also consume disk space. Adding an index to an attribute that is populated across a large percentage of directory objects may consume a substantial amount of disk space.
Domain controller performance will also be impacted while indexes are being generated. Index data is not replicated, so every domain controller in the forest must build its own copy of an index when it detects a new attribute index must be created. The speed at which an index is created is dependent on how much data must be indexed and also the hardware the domain controller is running on.
Ambiguous Name Resolution (ANR) is used for
address book look-ups. It allows a single small query to be expanded
into searching as many fields as the administrator would like searched
so that users can enter a single piece of information and hopefully
find all possible “hits” on the value they are interested in. When an
ANR query such as (anr=brian)
is submitted, the Active
Directory Query Processor expands the simple filter into a more
complex OR wildcard filter that contains all attributes marked as part
of the ANR set. The specified filter on a default Windows Server 2008
Active Directory would expand that simple query to:
(| (displayName=brian*) (givenName=brian*) (legacyExchangeDN=brian*) (msDS-AdditionalSamAccountName=brian*) (msDS-PhoneticCompanyName=brian*) (msDS-PhoneticDepartment=brian*) (msDS-PhoneticDisplayName=brian*) (msDS-PhoneticFirstName=brian*) (msDS-PhoneticLastName=brian*) (physicalDeliveryOfficeName=brian*) (proxyAddresses=brian*) (name=brian*) (sAMAccountName=brian*) (sn=brian*) )
A Windows Server 2008 Active Directory domain with Exchange Server 2007 SP1 installed would expand the query to:
(| (displayName=brian*) (givenName=brian*) (legacyExchangeDN=brian*) (msDS-AdditionalSamAccountName=brian*) (msDS-PhoneticCompanyName=brian*) (msDS-PhoneticDepartment=brian*) (msDS-PhoneticDisplayName=brian*) (msDS-PhoneticFirstName=brian*) (msDS-PhoneticLastName=brian*) (physicalDeliveryOfficeName=brian*) (proxyAddresses=brian*) (name=brian*) (sAMAccountName=brian*) (sn=brian*) (mail=brian*) (mailNickname=brian*) (msExchResourceSearchProperties=brian*) )
As you can see, a very simple query can quickly be expanded into a very large query. For this reason, you should avoid adding additional ANR attributes.
When a delete request is processed for an object, the object is not immediately deleted. Instead, the object is stripped of most of its attributes and moved to the Deleted Objects container of the partition the object exists in. Deleted objects that have been moved to the Deleted Objects containers are referred to as tombstones. Tombstones remain in the Deleted Objects container for the length of the tombstone period. The default tombstone periods or lifetimes for new forests are documented in Table 4-7. Tombstoning an object allows the delete operation to replicate to all domain controllers holding a copy of the object. The process of undeleting an object in Active Directory is known as tombstone reanimation.
Note
Administrators can modify the tombstone lifetime for a forest
by changing the tombstoneLifetime
attribute of the CN=Directory Service,
CN=Windows NT,
CN=Services,CN=Configuration,DC=mycorp,DC=com
object.
The attributes that are retained when an object is tombstoned
are configured through a combination of the searchFlags
setting and some hard-coded
internal functionality. The preserve on tombstone
searchFlags
setting is configurable
by administrators so they can choose to add more attributes to what is
kept on a tombstoned object. The purpose of keeping more attributes on
tombstones is directly related to the new capability available in ADAM
and Windows Server 2003 Active Directory to reanimate tombstoned
objects. The more attributes you allow the directory to retain on the
tombstoned object, the fewer attributes you have to recover through
other means after the object is reanimated.
Unfortunately, not all attributes can successfully be added to
the tombstone when the proper searchFlags
bit is set. The most obvious
examples are linked attributes such as group membership. Linked
attributes are handled differently by the directory, and thus there is
no way to force them to be retained. If you configure a linked
attribute to be preserved, Active Directory will simply ignore the
setting. This is unfortunate, as it means that critical information
such as group membership must be either manually maintained in an
additional attribute that can survive the tombstone process, or else
the group membership must be maintained outside of AD.
While some attributes won’t survive the tombstone regardless of
what you set, some attributes will survive the tombstone but will not
survive the reanimation process. The attribute pwdLastSet
attribute, for example, falls
into this category. When you reanimate an object with pwdLastSet
, even though the attribute may be
preserved in the tombstone, it will be overwritten when the object is
reanimated.
Unfortunately, Microsoft has not documented what can and cannot survive a tombstone and subsequent reanimation. So make sure you test any attributes you have configured to be retained to make sure they can actually be reanimated. You don’t want to find yourself in a situation where you discover that an attribute didn’t survive reanimation when it comes time to reanimate an object.
When you create an index, it is optimized for direct look-ups
and, if the attribute syntax supports it, trailing wildcards—e.g.,
(name=joe*)
. If you use medial queries—that is, queries with
wildcards anywhere but the end of the string, such as (name=*oe)
—performance tends to be rather less than
optimal. Generally, this is okay, but in the cases where an
important application is being significantly impacted due to poor
medial query performance, you may want to consider enabling a tuple
index for the attribute. This is just like enabling a normal index;
you simply enable another bit on the attribute’s searchFlags mask to
specify that a tuple index should be created.
A tuple index is considered an expensive index, and it will increase the Active Directory database (ntds.dit) size more than a “normal” index. In addition, new attribute insertion performance will be impacted slightly. This performance hit will not be noticeable for single attribute insertions, but if you are updating a large number of attributes at once, the performance hit may be more noticeable.
A new bit for the searchFlags
attribute was defined for Windows Server 2003 Service Pack 1: the
confidential attribute flag. Any attribute that has this flag enabled requires two
permissions in order to be viewed by a trustee (trustees are the
security principals who are granted permissions). The trustee needs
read property for the attribute and also needs
control access for the attribute. This
functionality was put into place primarily to protect sensitive user
attributes such as Social Security numbers and other personal
information. By default, only the administrators and account operators
have full control on all user objects, which means they will be able
to view any confidential attributes. Anyone else who has full control
over a user object will also be able to view the confidential data, so
this is yet another reason to not grant unnecessary rights in the
directory. If you have domain controllers in the domain (or global
catalogs in the forest if you are dealing with an attribute in the
partial attribute set) that are not running Windows Server 2003
Service Pack 1 or newer, then any attributes marked as confidential
will still be viewable without the special access rights on those
domain controllers or global catalogs.
The confidential attribute capability was added as a workaround to issues that exist in the current security model in Active Directory. Unfortunately, there are a large number of explicit read property grant permissions on objects in Active Directory that are terribly difficult to override. This new flag allows you to step in despite all the default grant permissions and quickly deny access to an attribute.
This new function was welcomed with open arms in the Active Directory community until administrators started to realize that Microsoft purposely crippled the functionality by not allowing you to set Category 1 attributes as confidential. Category 1 attributes are many of the attributes defined in the default AD schema, and that list of attributes contains many of the attributes you probably want to make confidential such as telephone numbers, addresses, employee IDs, and so on. It seems the intent is simply to give AD administrators a way to better secure custom attributes they have added to the directory with schema extensions. This limitation drastically reduces the usefulness of this capability for companies that stick to the default schema.
Note
As mentioned, modification of searchFlags
to enable confidential
functions on Category 1 attributes is strictly disallowed by Windows
Server 2003 SP1 domain controllers. If you try to change searchFlags
on one of these DCs so that
the confidential flag is set, you will get either an “Unwilling to
perform” or a poorly worded “The search flags for the attribute are
invalid. The ANR bit is valid only on attributes of Unicode or
Teletex strings” error for your troubles.
This new capability is almost wholly underwhelming for AD LDS. The default security descriptors on all AD LDS base schema objects are configured with no explicit Access Control Entries (ACEs). The result is very few explicit read property grant permissions on objects when they are instantiated, which means you can more easily secure attributes with inherited deny permissions and will not need to depend on the confidential attribute functionality.
Next, we need to discuss the tools that Microsoft has made available starting with Windows Server 2003 Service Pack 1 to handle managing access to confidential attributes. The answer is easy: none. In order to grant a trustee the ability to view a specific confidential attribute on an attribute, a grant ACE with control access permission for the specific attribute needs to be added to the ACL of the object. For more information on modifying the ACL of an object, see Chapter 13.
The GUI tools available for assigning permissions not only do not have the ability to assign this type of permission, but they can’t even display the permission if something else grants it. The command-line tool dsacls.exe is only marginally better; it can display the permission, but cannot grant the permission. The best that the GUI and dsacls.exe tool can do is assign either full control to the object or ALL control access rights to the object, but neither of these is optimal if you prefer to give minimum rights necessary to get the job done. In Windows Server 2003 SP1, the only way to set granular permissions to view a specific confidential attribute is to write a custom program or script to handle the delegation.
Note
Beginning with Windows Server 2003 R2, there is a GUI tool to handle this delegation. The new version of LDP that is loaded in the %windir%\adam directory when you install R2 ADAM has a new ACL editor. This version of updated version of LDP is also available in the free download of ADAM SP1. The version of LDP that is installed with Windows Server 2008 also includes this functionality. If you need to modify this delegation, we recommend you use one of the updated versions of the LDP tool.
The Windows Server 2008 auditing infrastructure has been substantially updated compared to its predecessors. In Windows 2000 Server and Windows Server 2003, there was a single domain-wide directory service auditing setting called Audit Directory Service Access. When this setting was enabled, all directory services auditing events were enabled. In a busy environment, the consequence of this was a substantial amount of security audit traffic in the event logs, to the point that it could easily become unmanageable and thus impractical to have enabled.
Windows Server 2008 domain controllers separate directory services auditing into four subcategories:
Directory Service Access
Directory Service Changes
Directory Service Replication
Detailed Directory Service Replication
Of particular interest to us right now is the Directory Service Changes subcategory. We will discuss the new auditing infrastructure in much more detail in Chapter 13.
By default, all attribute changes will continue to be audited as
required by the System ACL (SACL). In order to
control noise, however, you can set bit 9 on an attribute’s searchFlags
mask to disable all change
audits for that attribute. The Windows Server 2008 GUI tools do not
expose an interactive method to easily set this bit. For directions on
setting this bit, reference the sidebar Controlling Attribute Change Auditing,” next.
The filtered attribute set is part of the overall new Read-Only Domain Controller (RODC) functionality in Windows Server 2008 Active Directory. RODCs can be configured to not replicate certain attributes in the Active Directory schema. There is an in depth discussion of the RODC in Chapter 7; however, we will discuss RODCs briefly in the context of the filtered attribute set here.
RODCs were designed with the mentality that the server that they are running on is compromised by default. Consequentially there are some attributes that we might not wish to have stored on an RODC as they could contain sensitive information. Examples might be schema extensions that contain application-specific secrets, confidential data such as Social Security numbers, and so forth.
You can apply the process illustrated in the sidebar
“Controlling Attribute Change Auditing” to control whether or not
attributes are included in the filtered attribute set. Instead of
toggling bit 0x100
, you should
toggle bit 0x200
.
Property sets are described in our Chapter 13 discussion on
Active Directory security. We mention them here because the creation,
modification, and identification of property sets involve the schema
partition. Part of the information for a property set is maintained in
the configuration container in the cn=extended-rights
sub-container, and the rest
is maintained in the schema.
The property sets are defined in the cn=extended-rights
sub-container as controlAccessRight
objects. Two of the attributes of the controlAccessRight
object link it to the
schema. The first attribute is the appliesTo
attribute; the second is the
rightsGuid
. The
appliesTo
attribute is the string
representation of the schemaIDGUID
attribute of the classSchema
objects
that the property set applies to. The rightsGuid
is the string representation of the
binary GUID stamped on the attributeSecurityGUID
attribute of attributeSchema
objects to identify them as
members of the property set.
Microsoft allows distinguished name attributes with attributeSyntax
values of 2.5.5.1, 2.5.5.7,
and 2.5.5.14 to be linked to attributes with an attributeSyntax
of 2.5.5.1. These are called
linked attributes and consist of a forward link and a back link. An
example of a pair of linked attributes is member
and memberOf
.
Attributes are linked by setting the linkID
attributes of two attributeSchema
objects to valid link values.
The values must be unique for all attributeSchema
objects. The value of the
forward link is a positive even value and the back link is the forward
linkID
value plus one to make it a
positive odd value. Attributes must be linked when they are first
defined in the schema.
You can use any random linkID
values as long as they result in a unique linkID
pair; however, it is
highly recommended that you auto-generate link IDs.
You cannot use auto-generated link IDs in the case that you need your
schema extension to support Windows 2000. If you need to support Windows
2000, you should email schemreg@microsoft.com to request
unique link IDs.
In order to auto-generate link ID pairs, there are four steps you must follow:
Create the forward link attribute and populate the
linkID
attribute with the value1.2.840.113556.1.2.50
.Reload the schema cache.
Create the back link attribute and populate the
linkID
attribute with thelDAPDisplayName
of the forward link attribute you created in step 1.Reload the schema cache.
Schema classes are defined as instances of the classSchema
class. A complete listing of the
attributes on the classSchema
class is
available from the Platform SDK at http://msdn2.microsoft.com/en-us/library/ms680982(VS.85).aspx.
Classes are special in that they can inherit from one another. For
example, let’s say that we wanted to store two new types of objects in
the schema, representing a marketing user and a finance user,
respectively. These users both need all the attributes of the existing
user
class as a base. However, the
finance user needs three special attributes, while the marketing user
needs seven. The extra attributes required by both users do not match in
any way. In this example, we can create a Marketing-User
class, a Finance-User
class, and 10 distinctly
new attributes. However, rather than having to specify that the
Marketing-User and Finance-User classes have each of the attributes of
the original user
class individually,
all we need to do is specify that the new classes inherit from the
user
class by setting the subClassOf
attribute to user
. When we do this, both of the new classes
inherit every single attribute that the user
class had. We can then add the extra
attributes to each class and we have two new classes. This example is
outlined in Figure 4-4.
Note
You have another option when using Windows Server 2003 Forest Functional Mode or ADAM to resolve this issue. First, define the additional attributes and then create two auxiliary classes and assign the attributes to the classes. Then you can dynamically assign the auxiliary classes to users on ad hoc basis. This is far more flexible in that you can easily reconfigure individual users as necessary. If a user moves from Marketing to Finance, using special inherited classes would require deleting the user and recreating the user with the finance-user class. With dynamic auxiliary classes, you would simply clear the marketing attributes, remove the Marketing auxiliary class, and add the Finance auxiliary class and attributes.
You can think of the Active Directory schema as a treelike
structure, with multiple classes branching down or inheriting from one
base class at the top that has the attributes all objects need to begin
with. This class, unsurprisingly enough, is called top
, which was originally defined in the X.500
specification. Some classes inherit directly from top
, while others exist much lower down the
tree. While each class may have only one parent in this layout, each
class may also inherit attributes from other classes. This is possible
because you can create three categories of classSchema
object, also known as the objectClassCategory
: structural,
abstract, and auxiliary:
- Structural
If a class is structural, you can directly create objects of its type in Active Directory. The user and group classes are examples of structural classes.
- Abstract
It is possible that you would want to create a class that inherits from other classes and has certain attributes, but that is not one you will ever need to create instances of directly. This type of class is known as abstract. Abstract classes can inherit from other classes and can have attributes defined on them directly. The only difference between abstract and structural classes is that an object that is an instance of an abstract class cannot be created in Active Directory. If you are familiar with an object-oriented programming language, abstract schema classes in Active Directory are analogous to abstract classes in the programming language.
- Auxiliary
An auxiliary class is used to store sets of attributes that other classes can inherit. Auxiliary classes are a way for structural and abstract classes to inherit collections of attributes that do not have to be defined directly within the classes themselves. Auxiliary classes are primarily a grouping mechanism.
The X.500 specifications indicate that an auxiliary class cannot inherit from a structural class, and an abstract class can inherit only from another abstract class.
Note
To comply with the X.500 standards, there are actually four
types of objectClassCategory
. While
objects are required to be classified as one of structural, abstract,
or auxiliary by the 1993 X.500 specifications, objects defined before
1993 using the 1988 specifications are not required to comply with
these categories. Such objects have no corresponding 1993 category and
so are defined in the schema as having a special category known as the
88-Class.
Let’s take a look at the user
and computer
classes that are used to
create user and computer accounts within Active Directory. The computer
class and user
class are each structural, which means
that you can instantiate objects of those classes directly in Active
Directory. The computer
class
inherits from the user
class, so the
computer
class is a special type of
user in a way. The user
class
inherits from the organizationalPerson
Type 88 class. This
means that the total attributes available to objects of class computer
include not only the attributes
defined specifically on the computer
and user
classes themselves, but also
all the attributes that are inherited from the organizationalPerson
class. The organizationalPerson
class is a subclass of
the person
abstract class, which is a
subclass of the abstract top
class.
Recall that there are no classes above top
; it is the root class. This relationship
is outlined in Figure 4-5.
The user
class that Microsoft
needed to define in Active Directory had to be more than just the sum of
the X.500 standard parts. After all, Microsoft uses Security
Identifiers (SIDs) to identify users, and these were not
contained in the original X.500 standards. So, to extend the attributes
that make up a user, Microsoft defined some auxiliary classes and
included these in the user class makeup. The auxiliary classes are
mailRecipient
,
securityPrincipal
, posixAccount
, and shadowAccount
. mailRecipient
is a collection of attributes
that allow a user to hold information relating to the email address and
mail account associated with that user. The securityPrincipal
attribute is used to hold
the SID and other user-related security attributes that Microsoft
needed. The shadowAccount
and
posixAccount
auxiliary classes were
added in Windows Server 2003 R2 to support Microsoft Services
for UNIX.
If you were to use a tool such as ADSI Edit, you could see the
inheritance and class relationships quite clearly. For example, looking
at the objectClass
attribute of any
user object, you would see that at a minimum, the values held in this
attribute were top
, person
, organizationalPerson
, and user
. In other words, this attribute indicates
that each user object inherits attributes from all these classes.
Similarly, for any computer object, the objectClass
attribute holds top
, person
, organizationalPerson
, user
, and computer
. If you were to look at the subclassOf
attribute on the computer
class object itself in the schema,
you would see the user
class. The
user
class has a subClassOf
attribute that
indicates organizationalPerson
, and
so on. You can see this relationship in Figure 4-5.
Let’s now look at the user
class in a little more depth. Using a tool like ADSIEdit, we can see the
values of each attribute for the user classSchema
object. Table 4-8 contains a partial
listing of the attributes and values.
Table 4-8. Partial listing of attributes and values for the user class
User attribute’s LDAP-Display-Name | User attribute’s syntax | Value contained in user’s attribute |
---|---|---|
| CASE_IGNORE_STRING | User |
| CASE_IGNORE_STRING | User |
| CASE_IGNORE_STRING | |
| CASE_IGNORE_STRING | User |
| BOOLEAN | False |
| CASE_IGNORE_STRING | SDDL text-encoded representation of the default security descriptor |
| CASE_IGNORE_STRING | 1.2.840.113556.1.5.9 |
| CASE_IGNORE_STRING | |
| CASE_IGNORE_STRING | User |
| SECURITY_DESCRIPTOR | Binary representation of the Security Descriptor for the class |
| DN_STRING | cn=Class-Schema, cn=Schema, cn=Configuration, dc=mycorp, dc=com |
| CASE_IGNORE_STRING |
|
| INTEGER | 1 |
| CASE_IGNORE_STRING | |
| OCTET_STRING | <GUID> that uniquely identifies this class |
| BOOLEAN | True |
| CASE_IGNORE_STRING | |
| CASE_IGNORE_STRING | |
| CASE_IGNORE_STRING | Various attributes. See discussion. |
| CASE_IGNORE_STRING | |
You can learn the following about the user class by inspecting these attribute values:
The name of the class is User (
adminDescription
,adminDisplayName
,cn
,name
).It is an instance of the
classSchema
class (objectCategory
andobjectClass
).It inherits attributes from both
top
andclassSchema
(objectClass
).This object class has a security descriptor governing who can access and manipulate it (
nTSecurityDescriptor
).A default Security Descriptor should be applied to new instances of the user class if one is not specified on creation (
defaultSecurityDescriptor
).The instances of the user class are visible in normal browsing (
defaultHidingValue
).The user class itself is not hidden from casual browsing (
showInAdvancedViewOnly
).The
user
class has an OID of 1.2.840.113556.1.5.9 (governsID
).It inherits attributes not only from
top
andclassSchema
but also fromsecurity-Principal
andmailRecipient
(objectClass
andsystemAuxiliaryClass
).The
shadowAccount
andposixAccount
auxiliary classes can be associated withuser
objects.The user class is a direct subclass of the
organizationalPerson
class (subClassOf
).When connecting to instances of the class via LDAP, the two-letter prefix used should be
cn
(rDNAttID
).This class can be created directly under only three different parents in Active Directory (
systemPossSuperiors
).The class is structural (
objectClassCategory
).There are a large number of attributes that instances of the user class can have values for (
systemMayContain
).
Let’s look at the mustContain
, mayContain
, auxiliaryClass
, possSuperiors
, and their system attribute
pairs. You can see that the only values set are systemPossSuperiors
,
systemMayContain
, and systemAuxiliaryClass
. These were the values
set on the initial creation of the user class and cannot be changed.
Note that there were no mandatory attributes set at the creation of
the original class because the attribute systemMustContain
is not listed. If you
later wished to add an extra set of attributes or a new optional
attribute to the user class, you could use auxiliaryClass
or mayContain
and modify the base
definition. This occurs if, for example, you install the Exchange
schema updates in your forest. If you were to do this, the user class
would be directly modified to include three of these Exchange-related
auxiliary classes in the auxiliaryClass
attribute:
msExchMailStorage
msExchCustomAttributes
msExchCertificateInformation
Exchange is discussed in more detail in Chapter 19.
The attributes that are required when you create a new user are
not listed in the mustContain
attribute. That’s because
objectSID
, sAMAccountName
, and the other attributes are inherited from other
classes that make up this one. The mustContain
attributes can be defined
directly in auxiliaryClass
or
systemAuxiliaryClass
, or they can
be defined on the classes inherited from further up the tree. Both
sAMAccountName
and objectSID
, for example,
are defined on the securityPrincipal
class.
Warning
Do not mistake attributes that a class must contain with the attributes that you must explicitly set on object instantiation. Unfortunately there is no effective way to programmatically determine what attributes you need to set on an object when you create an instance of the class. Some of the attributes that an object must contain are system-owned and can only be set by the system; other attributes are optional and will be populated automatically; and finally some attributes are actually required to be specified by the objects creator. To confuse the situation even more, various versions of the OS or AD LDS change the requirements.
The same principle applies to the mayContain
attribute. The entire set of
these attributes is available only when you recurse back up the tree
and identify all the inherited mayContain
attributes on all inherited
classes.
The possSuperiors
attribute,
on the other hand, can be made up of only those items defined directly
on the class, those defined on the class in the subClassOf
attribute, or any inherited
classes defined on any other subClassOf
attributes up the subClassOf
tree. If that was too confusing,
try this: an instance of the user class can have possSuperiors
from
itself, from the organizationalPerson
class defined in the
subClassOf
attribute, from the
person
class (the organizationalPerson
class’s subClassOf
attribute), and from top
(the person class’s subClassOf
attribute).
Take a look at Figure 4-6. This shows the
user
class viewed with the Active
Directory Schema snap-in. You can see the relevant general user
data.
Notice that quite a bit of the user class is not configurable after the initial configuration, including:
governsID
subClassOf
schemaIDGUID
systemMustContain
rDNAttID
systemPossSuperiors
objectClassCategory
systemMayContain
systemOnly
systemAuxiliaryClass
objectClass
subClassOf
To see the so-called relationship settings (subClassOf
, auxiliaryClass
, possSuperiors
, systemAuxiliaryClass
, systemPossSuperiors
), look at Figure 4-7. In this screen,
you can see that the user class in this schema is inheriting
attributes from the four auxiliary classes.
The third and final screen is the Attributes tab for the
user
class and is displayed in
Figure 4-8. This
shows the mustContain
, systemMustContain
, mayContain
, and systemMayContain
attributes of the
user
class.
With Windows 2000, auxiliary classes were statically linked to
structural classes via the auxiliaryClass
and systemAuxiliaryClass
attributes. This went
against how most directory services implemented auxiliary classes, which
was typically allowing dynamically assigned auxiliary classes on
instances of objects. A new feature in Windows Server 2003 is the
ability to dynamically assign auxiliary classes to individual objects
instead of to an entire class of objects in the schema. Having the
dynamic auxiliary class mechanism provides much more flexibility for
application developers who may want to utilize existing structural and
auxiliary classes, but do not want to extend the schema to define such
relationships.
Warning
Dynamic linking of auxiliary classes requires Windows Server 2003 Forest Functional Level, or higher.
To dynamically link an auxiliary class to an object, you only need
to modify the objectClass
attribute of the object to
include the name of the auxiliary class. Any auxiliary class can be
used, provided that all mustContain
and systemMustContain
attributes
contained within the auxiliary class are set at the same time. You can
also remove a dynamically linked auxiliary class by clearing any values
that have been set for attributes defined by the auxiliary class and
then removing the auxiliary class name from the object’s objectClass
attribute.
Now let’s illustrate why dynamically linking auxiliary classes is
a good idea. Assume we have a forest with several domains, each
representing divisions within a company. Each division manages its own
user objects. One of the divisions, named Toasters, wants to assign
additional attributes to their user objects. These new attributes would
only apply to employees within the Toasters division. Under Windows
2000, the only way to accomplish this would be to create the new
attributes in the schema, create a new auxiliary class, and include the
new attributes in the auxiliary class. At that point, the new auxiliary
class could be added to the auxiliaryClass
of the user classSchema
object. That means every user
object contained within the forest would then have the new attributes
available. If each division wanted to do something similar, you can see
how the number of attributes on all user objects within the forest could
grow very quickly and unnecessarily. With Windows Server 2003, you would
still create the new attributes and auxiliary classes in the schema, but
you would not modify the auxiliaryClass
of the user object.
Instead, each division would dynamically link their auxiliary class to
their user objects. This provides for a cleaner and
much more efficient implementation than was possible under Windows
2000.
Warning
When you dynamically link an auxiliary class to an object, the
auxiliary class is listed in the objectClass
attribute for the object. When
an auxiliary class is statically linked, the auxiliary class is not
listed in the objectClass
listing.
This can cause issues with applications that determine available
attributes on an object and only look at the schema definitions of an
object class or at the objectClass
attribute of the object itself.
In this chapter, we’ve shown you how the internal blueprint for all objects in Active Directory, known as the schema, was derived from the X.500 directory service. We explained the purpose of the OID numbering system and how it can be used as well as the various elements that must be unique in an Active Directory schema extension such as prefix names and link IDs.
We then detailed how an attribute and its syntax are structured in
the schema as attributeSchema
objects,
using the userPrincipalName
attribute
as an example. We showed how attributes are added to classes by detailing
how classes are stored in the schema as instances of classSchema
objects. To make this clearer we dug
into the details of the user class to see how it was constructed. Finally,
we covered how auxiliary classes can be dynamically linked starting in
Windows Server 2003 and why it is significant.
Chapter 14 builds on what you’ve learned here to demonstrate how you can design and implement schema extensions.
[3] Names defined by the X.500 standard don’t tend to follow this method. For example, the Common-Name attribute has an LDAP-Display-Name of cn, and the Surname attribute has an LDAP-Display-Name of sn.
Get Active Directory, 4th Edition now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.