Share via


Security Descriptor Management

Not all tasks can be performed by modifying an object's attributes. Sometimes it is necessary to modify the security descriptor of an object. For example, by default, a regular user can read most of their attributes, but cannot modify them. You may want to allow a user to be able to both read and write their telephone number. This is accomplished by adding an access control entry (ACE) to the discretionary access control list (DACL) of the user object. This ACE is an allow ACE that allows write access to the telephoneNumber property. For more information about the telephoneNumber property, see the telephoneNumber topic or the Telephone-Number topic in the MSDN Library at https://go.microsoft.com/fwlink/?LinkID=27252.

In version 1.0 and 1.1 of the .NET Framework, there is no native support for modifying the security descriptors of Active Directory objects. The security descriptor of an Active Directory object can be manipulated by invoking ADSI and using the IADsSecurityDescriptor and associated interfaces. For more information, see Invoking ADSI. For more information about the IADsSecurityDescriptor interface, see the topic IADsSecurityDescriptor topic in the MSDN Library at https://go.microsoft.com/fwlink/?LinkID=27252.

In .NET Framework 2.0, the System.DirectoryServices namespace contains several classes to allow the manipulation of a security descriptor without having to invoke ADSI. The primary class used with Active Directory object security descriptors is ActiveDirectorySecurity. You can obtain an ActiveDirectorySecurity object that represents the security descriptor of an Active Directory object with the ObjectSecurity property.

The ActiveDirectorySecurity class has methods and properties that allow the discretionary access control list and secondary access control list of an object to be read and modified.

An access control entry on a discretionary access control list is known as an access rule. The primary class that represents an access rule is the ActiveDirectoryAccessRule class. There are also several classes that are derived from the ActiveDirectoryAccessRule class and are used to represent specific types of access rules. The following table lists these specific classes and their usage.

Class Usage

CreateChildAccessRule

Represents an access rule that is used to allow or deny an Active Directory object the right to create child objects.

DeleteChildAccessRule

Represents an access rule that is used to allow or deny an Active Directory object the right to delete child objects.

DeleteTreeAccessRule

Represents an access rule that is used to allow or deny an Active Directory object the right to delete all child objects.

ExtendedRightAccessRule

Represents an access rule that is used to allow or deny an Active Directory object an extended right.

ListChildrenAccessRule

Represents an access rule that is used to allow or deny an Active Directory object the right to list child objects.

PropertyAccessRule

Represents an access rule that is used to allow or deny access to an Active Directory property.

PropertySetAccessRule

Represents an access rule that is used to allow or deny access to an Active Directory property set.

An access control entry on a system access control list is known as an audit rule, which is represented by the ActiveDirectoryAuditRule class.

In many cases, it is not practical to add an access rule to each individual object to allow or deny access to something. In these cases, it is better to modify the security descriptor of the container and make the access rule inheritable. This also ensures that when new objects are created, they will automatically get the appropriate permissions. In the telephoneNumber example given above, you may want to allow all users write access to their telephone number. The easiest way to do this is add an inheritable access rule to a container, such as an organizational unit, and place all users under the organizational unit. The following code examples demonstrate how to do this.

Example

The following Visual Basic .NET example shows how to add an access rule to a container that will give all of the container's children that are user objects write access to the telephoneNumber property. For more information about the telephoneNumber property, see the telephoneNumber topic or the Telephone-Number topic in the MSDN Library at https://go.microsoft.com/fwlink/?LinkID=27252.

Sub SetWritePhonePermission(ByVal container As DirectoryEntry)
    Try
        ' Get the ActiveDirectorySecurity for the container.
        Dim containerSecurity As ActiveDirectorySecurity
        containerSecurity = container.ObjectSecurity

        ' Create a SecurityIdentifier object for "self".
        Dim selfSid As New SecurityIdentifier(WellKnownSidType.SelfSid, _
            Nothing)

        ' Get the schema for the currently logged on user.
        Dim schema As ActiveDirectorySchema
        schema = ActiveDirectorySchema.GetCurrentSchema()

        ' Get the telephoneNumber schema property object.
        Dim phoneProperty As ActiveDirectorySchemaProperty
        phoneProperty = schema.FindProperty("telephoneNumber")

        ' Get the user schema class object.
        Dim userClass As ActiveDirectorySchemaClass
        userClass = schema.FindClass("user")

        ' Create a property access rule to allow a user to write to their own telephoneNumber property.
        Dim allowWritePhoneRule As New PropertyAccessRule(selfSid, _
            AccessControlType.Allow, _
            PropertyAccess.Write, _
            phoneProperty.SchemaGuid, _
            ActiveDirectorySecurityInheritance.Descendents, _
            userClass.SchemaGuid)

        ' Add the access rule to the DACL.
        container.ObjectSecurity.AddAccessRule(allowWritePhoneRule)

        ' Commit the changes.
        container.CommitChanges()

    Catch notFoundEx As ActiveDirectoryObjectNotFoundException
        ' The schema class or property could not be found.
    End Try

End Sub 'SetWritePhonePermission

The following C# example shows how to add an access rule to a container that will give all of the container's children that are user objects write access to the telephoneNumber property. For more information about the telephoneNumber property, see the telephoneNumber topic or the Telephone-Number topic in the MSDN Library at https://go.microsoft.com/fwlink/?LinkID=27252.

static void SetWritePhonePermission(DirectoryEntry container)
{
    try
    {
        // Get the ActiveDirectorySecurity for the container.
        ActiveDirectorySecurity containerSecurity = container.ObjectSecurity;

        // Create a SecurityIdentifier object for "self".
        SecurityIdentifier selfSid =
            new SecurityIdentifier(WellKnownSidType.SelfSid, null);

        // Get the schema for the currently logged on user.
        ActiveDirectorySchema schema = ActiveDirectorySchema.GetCurrentSchema();

        // Get the telephoneNumber schema property object.
        ActiveDirectorySchemaProperty phoneProperty = schema.FindProperty("telephoneNumber");

        // Get the user schema class object.
        ActiveDirectorySchemaClass userClass = schema.FindClass("user");

        // Create a property access rule to allow a user to write to their own telephoneNumber property.
        PropertyAccessRule allowWritePhoneRule =
            new PropertyAccessRule(
                selfSid,
                AccessControlType.Allow,
                PropertyAccess.Write,
                phoneProperty.SchemaGuid,
                ActiveDirectorySecurityInheritance.Descendents,
                userClass.SchemaGuid);

        // Add the access rule to the DACL.
        container.ObjectSecurity.AddAccessRule(allowWritePhoneRule);

        // Commit the changes.
        container.CommitChanges();
    }
    catch (ActiveDirectoryObjectNotFoundException)
    {
        // The schema class or property could not be found.
    }
}

See Also

Reference

System.DirectoryServices
ActiveDirectorySecurity
ActiveDirectoryAccessRule
ActiveDirectoryAuditRule

Concepts

System Administration Tasks

Send comments about this topic to Microsoft.

Copyright © 2007 by Microsoft Corporation. All rights reserved.