In the world of Identity and Access Management, and in virtually every MIIS implementation, it is expected that you will be flowing some sort of interesting data OUT to a data source. In most situations this will involve populating Active Directory and in many cases you’re flowing data out that doesn’t fit inside a ready-built AD schema attribute. If you’re tired of writing data to Extension Attributes because you’re afraid of extending the schema then read on! But most importantly, we often take for granted the fact that we’re writing and publishing that information out to a public data source for the world, or at least everyone in your company, to see. In many situations the data we’re allowed to get from HR or other data sources is public anyway, so it’s not typically an issue, but in certain cases the need to protect confidential or private data is critical. I was just faced with this challenge recently and I thought I’d share what I’ve learned given that information and practical experience was a little short in the community.
Prerequisites
Before you even think about extending your schema, you will want to complete the following:
Enterprise OID Assignment - If you don’t already have one, obtain an Enterprise OID extension for your company; you must have a unique OID number for every extension you add. Registration with IANA is free and typically takes a few days. Here is their registration page: http://www.iana.org/cgi-bin/enterprise.pl
OID Assignment Management - Create a process and or team to manage your OID extension. You will need to plan on how your assignment will be allocated or else you’ll be in trouble later on. Also, make sure there is one place to go to register internally for extensions whether they are for applications developed internally, extensions marketed externally, or schema attributes used internally.
Documentation - Read the documentation! See the Reference section at the end for the important links to the AD Schema documentation. You may not understand everything the first time through, but you need to be exposed to it. When building your extensions you will refer often to several of the decode tables in order to determine the proper settings for bitmasks like searchFlags and systemFlags.
Tools
You’ll want to have the following tools handy to complete the extension planning and implementation:
Windows Server 2003 Administration Tools (Adminpak.msi) - You will need the Active Directory Schema and Active Directory Users and Computers snap-ins at least. If you do a full install of the AdminPak it will install all of the snap-ins but you can install them independently if you have the patience (I’m lazy).
Windows Server 2003 Support Tools - You’ll need the ADSI Edit snap-in and LDP.EXE for some operations.
ADAM SP1/R2 (optional) - Download and install ADAM SP1, or if you have Windows 2003 Server R2, install the version of ADAM that ships with it. ADAM SP1/R2 ships with an updated version of LDP.EXE that you can use to set Control Access permissions if you end up using the Confidentiality Bit.
GUID Converter Tool (http://directoryprogramming.net/files/default.aspx) – Provided by the authors of “The .NET Developer’s Guide to Directory Services Programming”, this little gem is invaluable if you’re going to build Property Sets or document/script your extensions in LDIF. Get it (the tool and the book)!
Planning
When you’re dealing with your schema and attributes that you’ll have to live with for the life of your forest, you’ll want to make sure you spend more than a few minutes planning it out. Stop to consider the following items:
Confidentiality - Decide whether or not you have confidential data you need protected. If you do not have to protect against Read access to attributes then the entire process is much simpler. If all of your Domain Controllers are Windows 2003 with Service Pack 1 applied then you can make use of a new featured called the confidentiality bit!
Usage - Review the current usage of schema by applications both Microsoft and 3rd party. For example, if you intend on placing an employee number in your directory but applications expect it to be in employeeID or employeeNumber and you’re planning on creating a new attribute to store it then you will limit the value of your extensions. Find out if any applications make use of the already provided schema attributes for any enhanced features – chances are you may already be aware of these if you’re working with MIIS anyway. Also, don’t forget that LDAP directories are tuned for efficient reads not writes. If you’re going to be writing information to these attributes frequently then consider moving them to a specialized ADAM instance or better yet, a SQL table.
Indexing – Indexing frequently used or searched for attribute can dramatically affect the performance of the directory. If you think your applications will be frequently searching for particular attributes, then you’ll want to index them. Windows 2003 also introduces some new indexing types that will improve containerized and wildcard searches that you’ll want to evaluate. Also, if you’re in a multi-domain environment you will want to consider whether or not these attributes should be replicated to a Global Catalog. Replicating additional attributes to the GC will increase the size of the partial NC the other domain GCs will need to host.
Typing & Capacity - Plan your extensions diligently – both for the size and data type of each extension as well as its usefulness. You’ll want to make sure the size of the data you’re placing in the object you’re extending won’t increase the size of the object to greatly. You should have a rough idea of how much data you’ll be adding and per extended object in order to assess the impact on both initial replication of that data as well as increased storage requirements for the NTDS.DIT file. When choosing your data type (syntax in schema terms), don’t over think this – if you find yourself unsure as to which one to use you can generally pick Unicode String (2.5.5.12) as a fallback. Unicode string is both case-insensitive (nice for searches) and is capable of holding anything from the Unicode character set so you’re making sure it’s regionalization friendly. The other ones you’ll typically use are: Boolean (2.5.5.8), Distinguished Name (2.5.5.1), and Integer (2.5.5.9).
Extending Existing Object Types
I’m going to focus the subject of this posting to the extension of existing objects in AD – primarily the user object as that will generally be the most common type of administrative extension. If you’re an ISV and writing your own AD-integrated applications then you’re likely working with completely new object types and are beyond the scope of this post.
So, when extending the User class object, you’re really talking about modifying an object of class classSchema of the structural object category (objectClass = classSchema, objectCategoryType: 1). There are three category types here – structural, abstract, and auxiliary (all classes). We can add new or existing attributes (objectClass: attributeSchema) to an existing structural type (like User, Group, or Computer), or create our own abstract or auxiliary type class to hold the new attributes and then add the new class to the structural class (classes can inherit the attributes of a sub-class and anything that hold or defines something else is considered a class). I can’t say whether or not using another class to hold your attributes is necessarily best practice or not, but I would recommend doing so and not adding attributes directly to any pre-built classes. This should serve to make your extensions a bit friendlier and easier to add to other classes should you have the need to. After all, adding one auxiliary class with 40 attributes is easier than adding 40 attributes to the user class! We’re not going to talk about the abstract class or what it’s used for, so we’re going to concentrate on using the auxiliary class exclusively because of the added options it gives us.
Figure 1
As shown in Figure 1, the user schema object can directly contain attributes or contain auxiliary classes which in turn contain attributes of their own (Figure 2). Note that object classes have a defaultSecurityDescriptor which dictates the default security an object of this type will inherit when it is initially created – this does not affect security on existing objects.
Figure 2
In Figure 2 we see that an auxiliary class looks much like a structural class but we add our attributes here instead. Also, make note of the schemaIDGUID property – you’re going to need to know more about this if you’re using Property Sets later on.
Figure 3
In Figure 3 we see the attributes themselves defined with all of its bitmasks and type settings to well define the use of this particular attribute. Note that attributes themselves do not have defaultSecurityDescriptors as they cannot exist on their own.
In parts 2 and 3 we will discuss the use of Property Sets and talk more about what default security aspects of Active Directory will confound your ability to restrict access to certain attributes.