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 2 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 distinguish between different syntaxes uniquely, 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 |
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 series of bits representing how the attribute should be handled. The bits are cumulative so if bits 0 and 1 are set, the attribute will have the value of 3. New bit values can be defined any time that Microsoft updates the directory service binaries. This attribute is configured both on schema definitions of attributes and classes as well as on objects instantiated 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.
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) | |
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 handled by the directory service 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. These attributes:
Should not be replicated. They are constructed by each directory instance separately.
Cannot be used in server-side sorting.
Generally cannot be used for queries. The attribute
aNR
is an exception here as it is used for constructing the special ANR queries detailed in the section on search flags.May require a BASE scope query to be retrieved for some constructed attributes ; e.g.,
tokenGroups
can only be returned with a BASE scope query.
The searchFlags
attribute is generally 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-5 for all of the values as of Windows Server 2003 R2 and ADAM R2.
Table 4-5. Search flag bits
Value |
Description |
---|---|
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 (0x0002) |
Create an index for the attribute in each container. This is only useful for one-level LDAP queries. |
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. |
8 (0x0008) |
Preserve this attribute in a tombstone object. This flag controls what attributes are kept when an object is deleted. |
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. |
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 ( |
64 (0x0040) |
Create subtree index. This index is only available in ADAM R2 and is designed to increase performance of VLV queries. See the section "ADAM Schema" in Chapter 18. |
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. |
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.
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, due to internal implementation details, cannot be indexed. You can set the flag, but it will not create an index. This seems disheartening but all hope is not lost. Linked attributes are actually implicitly linked. Fortunately, Microsoft made this realization, and in Windows Server 2003 AD and ADAM, added the necessary logic to use these implicit indexes.
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 cleared up. This topic is most often raised in regards to the
objectClass
attribute and is stated as the reason why the attribute wasn't indexed by default by Microsoft. Although Microsoft didn't indexobjectClass
, it is an excellent candidate to be indexed and, in fact, early betas of the next server operating system haveobjectClass
indexed.
Ambiguous Name Resolution 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=hansknecht)
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 ADAM installation would expand that simple query to:
(| (displayName=hansknecht*) (physicalDeliveryOfficeName=hansknecht*) (proxyAddresses=hansknecht*) (name=hansknecht*) )
A Windows Server 2003 Active Directory domain with Exchange Server 2003 installed would expand the query to:
(| (displayName=hansknecht*) (mail=hansknecht*) (givenName=hansknecht*) (legacyExchangeDN=hansknecht) (msDS-AdditionalSamAccountName=hansknecht*) (mailNickname=hansknecht*) (physicalDeliveryOfficeName=hansknecht*) (proxyAddresses=hansknecht*) (name=hansknecht*) (sAMAccountName=hansknecht*) (sn=hansknecht*) )
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, where it remains for the length of the tombstone period. This allows the delete operation to replicate to all domain controllers holding a copy of the 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. Linked attributes are handled differently, and there is no way to force them to be retained. If you configure a linked attribute to be preserved, AD 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 first discover that information wasn't kept when you try to restore a critical 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 OK, 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 to specify that a tuple index should be created.
A tuple index is considered an expensive index, and it will increase the DIT size more than a "normal" index. In addition, new attribute insertion performance will be impacted slightly. The performance hit will not be so much you would notice it on a single attribute insertion, but large bulk insertions could be impacted more significantly.
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. 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 excessive rights in the directory. Obviously, if you have domain controllers in the domain (or GCs in the forest if you are dealing with a PAS-enabled attribute) that are not running Windows Server 2003 Service Pack 1, then any attributes marked as confidential will still be viewable on those DCs or GCs.
This 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 easily 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, etc. It seems the intent is simply to give AD administrators a way to better secure additional attributes they add to the directory, which drastically reduces the usefulness of this capability for companies that stick to the default schema.
Tip
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.
If you are adamant about setting a Category 1 attribute as confidential, there is an option available. You can move the Schema FSMO to a non-SP1 domain controller and change searchFlags
for the attribute on that domain controller. The validation is only performed on SP1 domain controllers, and once the value is set on any domain controller, it will replicate to the rest of the forest. Keep in mind that if you do this, you are directly going against the wishes of Microsoft for what should be set as confidential, which could have impact on the supportability of your environment. If you do choose to go forward, at the very least, avoid the attributes with systemFlags
bit 1 (value 2) set. Those attributes are some of the most critical attributes in the directory, and it is quite unsafe to manipulate them.
This new capability is almost wholly underwhelming for ADAM. The default security descriptors on all ADAM base schema objects are configured with no explicit 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.
Next, we need to discuss the tools that Microsoft has made available with Service Pack 1 to handle granular delegation to trustees to view 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.[*]The GUI tools available for assigning permissions not only do not have the ability to assign this type of permission, 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.
Property sets are described in our Chapter 11 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 controlAc-cessRight
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 either auto-generate linkIDs or request linkIDs from Microsoft for your use. Requesting linkIDs from Microsoft is quite easy once you have registered a schema prefix and Enterprise ID with Microsoft. Simply go to the web page http://msdn.microsoft.com/certification/ADLinkID.asp and follow the instructions.
If you don't want to request linkIDs from Microsoft and you are using Windows Server 2003 AD or ADAM, you have the alternate safe option of letting the directory service create a linkID
pair for you. Microsoft has not, to this point, officially documented this new capability. However, a Microsoft employee named Eric Fleischman has documented the capability on his blog at http://blogs.technet.com/efleis/archive/2004/10/12/241219.aspx. The process is quite simple; however, the linkID
pairs created are specific to the directory in which they are created. Do not copy the linkID
pair values to other Active Directory or ADAM instances; auto-generate new links in the new instances instead.
To auto-generate linkID
pair values, you first create the forward link attribute with any standard mechanism for extending the schema; for the linkID
attribute, you must specify the OID value 1.2.840.113556.1.2.50
. After the forward link attribute is created, you must refresh the schema cache. The next step is the creation of the back link attribute, for the linkID
attribute, you must specify the lDAPDisplayName
of the forward link. Finally, you must refresh the schema cache again. As you can see, the process is indeed quite simple and painless.
Get Active Directory, 3rd 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.