Philippe Lacoude Homepage

Add Attributes to your Active Directory Schema and Manage their Permissions Efficiently

Philippe Lacoude & Rajnish Sinha
Washington, D.C.
April 2005  (Version 1.1)


Summary

This paper shows how to create a new Active Directory attribute, add it to an existing container (user class), and configure its security using Active Directory control access rights.

To perform each of the steps, the paper employs four different techniques: administration via the GUI, administration via the command line, scripting using the COM ADSI interfaces in VBScript, and programming using the DirectoryServices library in Visual Basic .NET.


 Download This Article in
 PDF Format

 Creating and Securing Active Directory Attributes using Control Access Rights 

Contents

Managing the Active Directory Schema
   Active Directory and its Schema
   Schema Master Role
   Schema Administrator
   Transferring the Schema Master Role
   Enabling Schema Administration
Creating an Attribute
   Creating an Attribute using ldifde.exe
   Adding an Attribute using the MMC
   Adding an Attribute Programmatically
Adding an Attribute to a Container Class
   Adding an Attribute to a Container Class using ldifde.exe
   Adding an Attribute to a Container Class using the MMC
   Adding an Attribute to a Container Class Programmatically
Setting the New Attributes Permissions using Control Access Rights
   Control Access Rights
   Property Sets
   The Relation between Attributes and Property Sets
   Adding the New Attribute to a Property Set
Conclusion

Managing the Active Directory Schema

Active Directory and its Schema

The Microsoft Windows 2000 Active Directory is the central repository that stores all enterprise objects such as user accounts, computer accounts, or other network devices data.  By design, Active Directory can store hundreds of million of like objects.


Objects are organized in a tree-like manner, similar in many respects to folders on a drive. Each object is uniquely defined by its position in the tree, a.k.a. its “distinguished name”. For example, the path to the default Guest account of a directory called MyDomain would be:


CN=Guest,CN=Users,DC=MyDomain


This string is also known as the Lightweight Directory Access Protocol [1] (LDAP) path.  LDAP is a standard way of connecting to enterprise directory services from the Internet Engineering Task Force (IETF).  Active Directory is an LDAP-compliant application.  The distinguished name is also defined by an IETF standard [2].


Each object is made of a collection of attributes.  Each object's nature is defined by its Object-Class attribute.  Each class groups attributes together, defining which ones are mandatory and which others are optional.  Well-known classes include user, computer, group and contact.


Classes can be derived from other classes using inheritance.  For example, the user class is derived from the organizationalPerson class, which is in turn derived from the person class, whose definition derives from the top class.


All these classes' definitions constitute the “schema”.  The schema contains formal definitions of every object class that can be created in an Active Directory forest.  The schema also contains formal definitions of every attribute that can exist in an Active Directory object.  The classes and attributes simply are objects (whose type or Object-Class attribute is equal to classSchema and attributeSchema respectively.)


The schema is thus made of a collection of directory objects and it is stored in the directory itself.  For e.g., a directory called MyDomain has a configuration located at


CN=Configuration,DC=MyDomain


The configuration contains the schema:


CN=Schema,CN=Configuration,DC=MyDomain


Schema Master Role

Active Directory is a hierarchical database, which relies on a customized high-performance version of the Jet database engine.  It is capable of storing millions of objects across several servers, called domain controllers (DC).  It supports multi-master changes, which means that changes to one of the databases can be processed at any given DC in the enterprise regardless of whether the DC is connected or disconnected from the network.


This advantage introduces the possibility of conflicts that can potentially lead to problems once the altered data is replicated to the other domain controllers.  This is the case when two administrators modify the same user's telephone number while connected to two different DC servers.  In Windows 2000, the conflict resolution algorithm handles discrepancies in values by keeping the latest written data.  In other words, the “last writer wins”.


An exception to this conflict resolution rule was made for changes that are less frequent but have far reaching consequences like schema changes.  Obviously, if the definition of the user objects were changed one way on one server and another way on a second DC, the “last writer wins” approach would potentially lead to nightmares.


Windows 2000 prevents conflicting Active Directory updates from occurring in some cases.  It thus defines five roles that are granted only once per domain.  These roles operate under the single-master model, in a manner similar to the primary domain controller (PDC) role in the earlier versions of Windows.  In Windows NT 3.51 and 4.0, the PDC was responsible for processing all updates in a given domain.


Because Active Directory roles are not bound to a single DC, they are referred to as the Flexible Single Master Operation (FSMO) roles.  Windows 2000 has five FSMO roles:

  • Schema master
  • Domain naming master
  • RID master
  • PDC emulator
  • Infrastructure master

The first Active Directory domain controller in a forest is granted all five FSMO roles.  The Schema Master FSMO role holder is the DC responsible for performing updates to the directory schema.  This schema master sends updates to all other DC in the directory.  Like the domain master role, the schema master role is forest-wide and granted once per forest.  This is a consequence of the fact that child domains share their parent's schema in Windows 2000.

Schema Administrator

Before being permitted to administer the schema, a user account must be added to the “Schema Admins” group.  On Windows 2000, a security measure also requires a special value called “Schema Updated Allowed” in the Registry of the machine that runs the Schema console [3].

Transferring the Schema Master Role

Before modifying the schema, it is necessary to be able to connect to the schema master DC.  It may be necessary to change what computer holds this role.  It may even be necessary to force the assignment of this role if the original domain controller is no longer online: it sometimes happens to have Active Directory forests without a schema master because the first server was decommissioned and the administrators only transferred the RID, PDC and infrastructure FSMO roles as only those show in the “Active Directory Users and Computers” MMC snap-in dialog box.


Two different methods allow moving the schema FSMO role from one computer to another:

  • The recommended method is a transfer.  It can only be used if both DC are running.
  • The second method is to seize the role and can be used if the FSMO roles holder is offline.  It can be used if the DC previously holding the role has been lost [4].

The first method can be performed through the “Active Directory Schema” MMC snap-in.  This snap-in can be installed by running the adminpak.msi program [5] located in the \I386 folder on the Windows 2000 Installation CD.  After installation, simply run the schmmgmt.msc file from the Start menu.  The file is located in the %System32% folder.




Figure 1 - Change Schema Master Dialog (Windows 2000)




Figure 2 - Change Schema Master Dialog (Windows 2003)


The second method requires you to use the ntdsutil.exe tool to seize the roles [6].  The tool can be run from the command line of any DC although it is recommended to do so on the domain controller that is taking the schema master role.  The FSMO role seizure procedure runs as follows from the command line:

  1. After starting ntdsutil.exe, type roles and press enter.  This instruction switches to the fsmo maintenance mode.
  2. At the fsmo maintenance: prompt, type connections, and press enter.  This instruction switches to the server connections mode.
  3. At the server connections: mode, type connect to server <servername>, where servername is the name of the server you want to use as the new schema master, and then press enter.
  4. At the server connections: prompt, type quit, and then press enter again.  This returns you to the fsmo maintenance mode.
  5. At the fsmo maintenance: prompt, type seize schema master [7].  A dialog box appears and prompts the user for confirmation.  Upon clicking on the Yes option, the ntdsutil.exe displays the following message:


Attempting safe transfer of schema FSMO before seizure.

FSMO transferred successfully - seizure not required.

Server "WEST" knows about 5 roles

Schema - CN=NTDS Settings,CN=WEST,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=MyDomain

Domain - CN="NTDS Settings

DEL:fde9d42c-78a0-40a8-b71f-c0694b712abd",CN="WEST

DEL:dbcc4f5c-c8ae-4771-ba7d-0ff5442f593b",CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=MyDomain

PDC - CN=NTDS Settings,CN=WEST,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=MyDomain

RID - CN=NTDS Settings,CN=WEST,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=MyDomain

Infrastructure - CN=NTDS Settings,CN=WEST,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=MyDomain


  1. After you seize the schema master role, type quit, and then press enter (twice) to exit the ntdsutil.exe tool.

Enabling Schema Administration

Before any schema extension is performed, schema updates must be enabled.  There are two ways of performing this operation:

  • Using the “Active Directory Schema” MMC console, open the “Operations Masters” dialog [8].  Click on the checkbox reading “The Schema may be modified on this Domain Controller” [9].
  • Using the registry editor, add the following value:


Key: HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Parameters

Value: “Schema Update Allowed” = 0x1


Creating an Attribute

Creating an Attribute using ldifde.exe

Microsoft provides a small utility named LDIFDE that allows the import and export of data in or out of Active Directory.  The name stands for LDIF Data Exchange.  The LDAP Data Interchange Format (LDIF) is a technical specification of the IETF [10].  It defines a file format to store LDAP-compliant data.


Although LDIFDE is mostly useful for doing batch operations that require accessing numerous Active Directory objects, it can also be used efficiently for schema modifications: it ensures that schema modifications are scripted and can be reproduced.  It is very important since they cannot be rolled back.  It is strongly recommended to perform schema changes in a test environment before attempting to implement them in production.


An LDIF file is made of sections separated by hyphens.  The file is hyphen-terminated.  Each section starts with the dn: tag followed by the distinguished name of the object to which the section applies.  On the next line, the changetype: tag informs the utility of which type of change needs to be performed.  The changes can be either add or modify.   The following lines follow this syntax:


operation: attribute_on_which_the_operation_applies

attribute_on_which_the_operation_applies: the_old_or_the_new_value

-


The operation can be replace, add or delete.


Let us create an LDIFDE file containing instructions to add a personal identification number attribute to Active Directory.  The file will be saved as PIN.LDIF.


# Create single-valued PIN attribute

dn: CN=Personal-ID-Number,CN=Schema,CN=Configuration,DC=MyDomain

changetype: add

objectClass: attributeSchema

cn: Personal-ID-Number

distinguishedName: CN=Personal-ID-Number,CN=Schema,CN=Configuration,DC=MyDomain

instanceType: 4

attributeID: 1.2.840.113556.1.4.7000.233.28688.28684.8.51404.45879.8978.98567.7

attributeSyntax: 2.5.5.12

isSingleValued: TRUE

showInAdvancedViewOnly: TRUE

adminDisplayName: Personal-ID-Number

adminDescription: Personal-ID-Number

oMSyntax: 64

lDAPDisplayName: pIN

name: pIN

objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=MyDomain

rangeLower: 1

rangeUpper: 4

 

# Instruct Active Directory to reload the schema cache.  This must

# be done or the creation of the class fails.  The schemaUpdateNow

# is an operational attribute of the RootDSE.

DN:

changeType: modify

add: schemaUpdateNow

schemaUpdateNow: 1

-


A notable point in the above script is the attributeID of the new pIN attribute.  This number is an “object identifier” (OID).  The OID is an assigned number from the ANSI standards board to make sure that no two schemas additions ever collide.  The collision can be avoided by following one of two methods:

  • You can go to http://www.iana.org/ to claim a root OID number to assign to your schema extension.  This step is an absolute must for any software publisher.
  • For in house applications, however, it is simpler to run OIDGEN, a tool available in the Windows 2000 Resource Kit, which circumvents the previous step.  OIDGEN creates a random unique identifier such as the one in the above code.

The command to run the script is


ldifde -i -f pin.ldif -v -j


The new attribute can be seen in the “Active Directory Schema” MMC snap-in:




Figure 3 - Personal Identification Number Attribute


Adding an Attribute using the MMC

It is also possible to add the attribute through the “Active Directory Schema” MMC snap-in (located in the %System32% folder):




Figure 4 - Create New Attribute


This step does not have the advantage to be easily reproduced when moving from a test environment to production.  However, it may be a smart short cut to generate the LDIF file: after creating the attribute in a test environment, simply export the new attribute using the LDIFDE utility to generate the LDIF code:


ldifde -f pin -d "CN=Personal-ID-Number,CN=Schema,CN=Configuration,DC=MyDomain"


The file is ready to import following the procedure described in the previous section.

Adding an Attribute Programmatically

The following Visual Basic Script adds the attribute programmatically using the ADSI library interfaces.


An advantage of this solution is that there is no need to specify the domain name as it was done in the LDIF script.  By querying the root of the directory (rootDSE), the script is able to locate a domain controller and its supporting schema.  This built-in capability helps migrating scripts from development to production.


Once the schema is found, the only task left is to add a new container of type attributeSchema, populate its attributes, and commit the changes (using the SetInfo() method.)


Option Explicit

 

On Error Resume Next

Err.Clear()

 

' Get the root Directory Service Entry (rootDSE)

Dim adsRootDSE, adsSchema, adsAttribute

Set adsRootDSE = GetObject("LDAP://rootDSE")

 

' Access the schema

Set adsSchema = GetObject("LDAP://" & adsRootDSE.Get("SchemaNamingContext"))

 

' Add and populate attribute

Set adsAttribute = adsSchema.Create("attributeSchema", "CN=Personal-ID-Number")

 

' Naming

adsAttribute.Put "adminDescription", "Personal-ID-Number"

adsAttribute.Put "adminDisplayName", "Personal-ID-Number"

adsAttribute.Put "lDAPDisplayName", "pIN"

adsAttribute.Put "name", "Personal-ID-Number"

 

' Object ID (created by OIDGen.exe)

adsAttribute.Put "attributeID", _

 "1.2.840.113556.1.4.7000.233.28688.28684.8.51404.45879.8978.98567.7"

 

' Unicode string

adsAttribute.Put "attributeSyntax", "2.5.5.12"

adsAttribute.Put "oMSyntax", 64

 

' Defaults to FALSE if not specified

adsAttribute.Put "isSingleValued", True

 

' Attribute size

adsAttribute.Put "rangeLower", 1

adsAttribute.Put "rangeUpper", 4

 

' Commit changes

adsAttribute.SetInfo

 

' Check for errors

Dim sMsg

If Err.number <> 0 Then

  sMsg = "Unexpected error creating attribute." & vbNewLine & _

    Err.Description & " (" & Hex(Err.number) & ")"

  WScript.Echo sMsg

End If


The same operation can be carried out using the DirectoryServices namespace classes in Visual Basic .Net:


Imports System.DirectoryServices

 

Module Add_Attribute

  Sub Main()

    ' Get the root Directory Service Entry (rootDSE)

    Dim adsRootDSE As New DirectoryEntry("LDAP://rootDSE")

 

    ' Access the schema

    Dim sSchema As String = _

      adsRootDSE.Properties.Item("SchemaNamingContext").Value

    Dim adsSchema As New DirectoryEntry("LDAP://" & sSchema)

 

    ' Add and populate attribute

    Dim adsAttribute As DirectoryEntry = _

      adsSchema.Children.Add("CN=Personal-ID-Number", "attributeSchema")

 

    ' Naming

    adsAttribute.Properties("adminDescription").Value = "Personal-ID-Number"

    adsAttribute.Properties("adminDisplayName").Value = "Personal-ID-Number"

    adsAttribute.Properties("lDAPDisplayName").Value = "pIN"

    adsAttribute.Properties("name").Value = "Personal-ID-Number"

 

    ' Object ID (created by OIDGen.exe)

    adsAttribute.Properties("attributeID").Value = _

      "1.2.840.113556.1.4.7000.233.28688.28684.8.51404.45879.8978.98567.7"

 

    ' Unicode string

    adsAttribute.Properties("attributeSyntax").Value = "2.5.5.12"

    adsAttribute.Properties("oMSyntax").Value = 64

 

    ' Defaults to FALSE if not specified

    adsAttribute.Properties("isSingleValued").Value = True

 

    ' Attribute size

    adsAttribute.Properties("rangeLower").Value = 1

    adsAttribute.Properties("rangeUpper").Value = 4

 

    ' Commit changes

    adsAttribute.CommitChanges()

  End Sub

End Module


Adding an Attribute to a Container Class

At this point, we need to add the attribute as one of the optional ones on the user class.  This way, users will have the ability to store a 4-digit PIN in their Active Directory profile.  To do so, we must add one more value (pIN) to the multi-valued mayContain attribute of the user class.

Adding an Attribute to a Container Class using ldifde.exe

This can be done using the LDIFDE tool in a fashion similar to the previous LDIF script.  We save the following script as user.ldif:


# Add the new attributes to the User class

dn: CN=User,CN=Schema,CN=Configuration,DC=MyDomain

changetype: modify

add: mayContain

mayContain: pIN

-

 

# Reload the schema

DN:

changeType: modify

add: schemaUpdateNow

schemaUpdateNow: 1

-


The above LDIF script is executed by running the following command:


ldifde -i -f user.ldif -v -j


This completes adding the new attribute to the user class.

Adding an Attribute to a Container Class using the MMC

The operation can also be achieved via the “Active Directory Schema” MMC snap-in.  To do so, simply open the user class properties by double-clicking on the class.  This brings up the following dialog box:




Figure 5 - User Class Properties


The third tab, “Attributes”, displays an “Add” button allowing an Administrator to add an attribute to the existing list.




Figure 6 - Adding Attributes to the User Class


Adding an Attribute to a Container Class Programmatically

Before we can modify or assign a PIN to a user, we must alter the user's class.  Specifically, we need to add the new pIN attribute to the list of attributes that a user instance “mayContain.”  The Visual Basic Script used to perform this task is very similar to the one above:


Option Explicit

 

On Error Resume Next

Err.Clear()

 

' Get the root Directory Service Entry (rootDSE)

Dim adsRootDSE, adsUserClass

Set adsRootDSE = GetObject("LDAP://rootDSE")

 

' Access the user class in the schema

Set adsUserClass = GetObject("LDAP://CN=User," & _

  adsRootDSE.Get("SchemaNamingContext"))

 

' Add the new attribute to the user class

adsUserClass.Put "mayContain", "pIN"

 

' Commit changes

adsUserClass.SetInfo

 

' Check for errors

Dim sMsg

If Err.number <> 0 Then

  sMsg = "Unexpected error adding the attribute." & _

    vbNewLine & Err.Description & " (" & Hex(Err.Number) & ")"

  WScript.Echo sMsg

End If


The same operation can be carried out using the DirectoryServices namespace classes in Visual Basic .Net:


Imports System.DirectoryServices

 

Module Add_Attribute

  Sub Main()

    ' Get the root Directory Service Entry (rootDSE)

    Dim adsRootDSE As New DirectoryEntry("LDAP://rootDSE")

 

    ' Access the user class in the schema

    Dim sSchema As String = _

      adsRootDSE.Properties.Item("SchemaNamingContext").Value

    Dim adsUserClass As New DirectoryEntry("LDAP://CN=User," & sSchema)

 

    ' Add the new attribute to the user class

    adsUserClass.Properties("mayContain").Add("pIN")

 

    ' Commit changes

    adsUserClass.CommitChanges()

  End Sub

End Module


Setting the New Attributes Permissions using Control Access Rights

After adding the pIN attribute as a potential one for the user class, it is now possible to add that field to any instance of the user class (using LDIFDE, ADSI Edit, or a custom Visual Basic program.)  However, only Domain Administrators have the permission to do so.  A user cannot update the pIN attribute of his own container.


On the contrary, a user can update some of the other user class attributes, such as telephoneNumber or street.


The difference between the new pIN and the native telephoneNumber attributes is that the latter is part of a group of attributes called Personal-Information.  This object is called a control access right.

Control Access Rights

Active Directory control-Access-Right objects define the Control Access Rights.  These objects are located in the CN=Configuration,DC=<domain> container and come in three flavors:

  • Extended Rights
  • Validated Writes
  • Property Sets

Extended rights cover special permissions beyond the standard set of rights.  They are used by external applications, such as Exchange Server, that rely heavily of Active Directory and its advanced security.


Validated Writes rights are validation logic applied to Active Directory and set conditions on data prior to writing to the disk.


The last ones, property sets, are used to control access to a subset of an object's attributes, skipping the necessity to define individual attributes permissions.  The Personal-Information falls in this later category.

Property Sets

Property sets are used to group schema attributes in a business logic manner.  Once a property set is defined, it is possible to set the access right on the entire property set at once rather than on each of the properties of the set.


Active Directory pre-defines the following property sets:

  • DNS-Host-Name-Attributes
  • Domain-Other-Parameters
  • Domain-Password
  • Email-Information
  • General-Information
  • Membership
  • Personal-Information
  • Public-Information
  • RAS-Information
  • User-Account-Restrictions
  • User-Logon
  • Web-Information

The Email-Information property set contains user attributes that describe user email related information.  The Public-Information property set contains attributes that describe public information for the user, computer or inetOrgPerson classes. 


The Personal-Information property set contains attributes that describe personal information for the user, contact, computer or inetOrgPerson classes.


Users can change the content of all the attributes that are part of the Personal-Information property set because that set's permissions contains read/write for the self account.  The self is a surrogate for the entry itself and is used to give access to an entry to itself.

The Relation between Attributes and Property Sets

Like other objects, control-Access-Right have attributes, including the following two:

  • rightsGUID that uniquely identifies a control access right
  • validAccesses that sets the access to be granted by the extended right


All the attributes that belong to a property set have the same attribute-Security-GUID property value.  This GUID matches the rightsGUID of the control-Access-Right object that represents their property set.




Figure 7 - Key Relationships


Restrictions are imposed on modification of existing schema objects.   The schema is divided into two categories.   The schema objects that ship with Microsoft Windows 2000 in the base schema belong to Category 1.  All schema objects added later by other applications or users through dynamic schema extension belong to Category 2.  The 0x10 bit set in the systemFlags attribute determines the category of a schema object.   This bit is only set on Category 1 objects, and cannot be altered, nor can it be set on any Category 2 object.

Adding the New Attribute to a Property Set

This leads us to our final step which is the setup of the security of the new attribute.  In order to give it the permission set forth in the Personal-Information extended right, we can simply copy the attributeSecurityGUID field of another attribute (for e.g. Street-Address) that relies on this same extended right.


Using the ADSI Edit MMC snap-in, it is easy to open the new attribute and copy the proper value to the attributeSecurityGUID field.


To perform the task with an LDIF script, a single line needs to be added to the PIN.LDIF file:


attributeSecurityGUID: 0x86 0xB8 ............. 0x67 0xC1


In Visual Basic Scripting, the code is a follows:


' Get the root Directory Service Entry (rootDSE)

Dim rootdse

Set rootdse = GetObject("LDAP://rootDSE")

 

' Get the CN=Street-Address located in the schema

Dim sStreet, oStreet

sStreet = "LDAP://CN=Street-Address," & rootdse.Get("SchemaNamingContext")

Set oStreet = GetObject(sStreet)

 

' Get the CN=Personal-ID-Number located in the schema

Dim sPIN, oPIN

sPIN= "LDAP://CN=Personal-ID-Number," & rootdse.Get("SchemaNamingContext")

Set oPIN = GetObject(sPIN)

 

' Copy the attributeSecurityGUID value from the CN=Street-Address

' to the CN=Personal-ID-Number attribute

oPIN.Put "attributeSecurityGUID", oStreet.Get("attributeSecurityGUID")

oPIN.SetInfo


An alternative would be to copy the rightsGUID field of the Personal-Information extended right.  However, we would have to perform a type conversion and the above code is thus simpler.


In Visual Basic .Net, the same code looks as follows:


Imports System.DirectoryServices

 

Module Copy_Security

  Const sSource As String = "Street-Address"

  Const sDestination As String = "Personal-ID-Number"

 

  Sub Main()

    ' Get the rootDSE and open the configuration container

    Dim rootdse As New DirectoryEntry("LDAP://rootDSE")

 

    Dim sSourceDN As String, oSource As DirectoryEntry

    sSourceDN = "LDAP://CN=" & sSource & "," & _

      rootdse.Properties("SchemaNamingContext").Value

    oSource = New DirectoryEntry(sSourceDN)

    oSource.RefreshCache()

 

    Dim sDestinationDN As String, oDestination As DirectoryEntry

    sDestinationDN = "LDAP://CN=" & sDestination & "," & _

      rootdse.Properties("SchemaNamingContext").Value

    oDestination = New DirectoryEntry(sDestinationDN)

    oDestination.RefreshCache()

 

    Dim oGUID As Byte()

    oGUID = CType(oSource.Properties("attributeSecurityGUID").Value, Byte())

 

    oDestination.Properties("attributeSecurityGUID").Clear()

    oDestination.Properties("attributeSecurityGUID").Add(oGUID)

    oDestination.CommitChanges()

  End Sub

End Module


Conclusion

The pIN attribute is now part of the user class and can be self-edited by any user logged on to the domain.  This would allow changes to that attribute by any application using integrated security to connect to the directory.  By virtue of the Personal-Information control access right, other users can read but not change each other's pIN data.


Microsoft Active Directory offers a large range of pre-defined control access rights that should generally cover the needs of solution architects.  In the rare cases when the requirements do not fall in this category, one can simply add a new controlAccessRight container in the domain's configuration using a script, the ADSI Edit MMC snap-in, LDIFDE, or Visual Basic .Net.


So far we have learned, how to create a new Active Directory attribute, add it to an existing container (user class), and configure its security using Active Directory control access rights by Visual Basic script, programmatically using Visual Basic .Net and manually using MMC.


[1] Cf. IETF, “Lightweight Directory Access Protocol”, RFC #1777.

[2] Cf. IETF, “A String Representation of Distinguished Names”, RFC #1779.

[3] This is no longer true on Windows Server 2003.

[4] After seizing the FSMO role of a lost server, its container needs to be removed from Active Directory following a procedure with numerous steps.  Cf. Microsoft, “How to remove data in active directory after an unsuccessful domain controller demotion”, KB 216498.

[5] This package also installs the other Active Directory snap-ins on workstations and member servers.

[6] Cf. Microsoft, “Using Ntdsutil.exe to seize or transfer FSMO roles to a domain controller”, KB 255504.

[7] If the former schema master server is still online, you can type transfer schema master instead of seizing the role.

[8] Cf. figure 1.

[9] Cf. Microsoft, “HOW TO: View and Transfer FSMO Roles in the Graphical User Interface”, KB 255690.

[10] Cf. IETF, “The LDAP Data Interchange Format (LDIF) - Technical Specification”, RFC #2849.






 (c) 2004 - Philippe Lacoude, Rajnish Sinha


 April 2005  (Version 1.1) - First web publication
 August 2004  (Version 1.0) - Final draft