HOWTO - Set Active Directory Delegated Privileges

I created a C # web service that allows our foreground support teams to view and update multiple selected Active Directory values ​​using system.directoryservices

The fields I want to update are [job] title, department, telephone and employeeid.

I can use the "delegate" service account to update the [job], department, phone, etc., but when I try to update the employeeid, I get an "not authorized" error.

If I am using a domain admin account then the same code works fine.

I don't want to use a domain admin account for this web service, so what privileges do I need?

0


source to share


3 answers


ANSWER

ADS_SCHEMA_ID_GUID_USER GUID allows you to update base user class information including employee ID

Based on MSDN article



vbscript is used to grant the user the service account of the selected delegated rights:

REM #
REM # Delegate AD property set admin rights to named account
REM # Based on: http://www.microsoft.com/technet/scriptcenter/topics/security/propset.mspx
REM #

Const TRUSTEE_ACCOUNT_SAM           = "ad\ADStaffUpdates"

Const ADS_ACETYPE_ACCESS_ALLOWED_OBJECT     = &H5
Const ADS_RIGHT_DS_READ_PROP            = &H10
Const ADS_RIGHT_DS_WRITE_PROP           = &H20
Const ADS_FLAG_OBJECT_TYPE_PRESENT      = &H1
Const ADS_FLAG_INHERITED_OBJECT_TYPE_PRESENT    = &H2
Const ADS_ACEFLAG_INHERIT_ACE           = &H2

Const ADS_SCHEMA_ID_GUID_USER           = "{bf967aba-0de6-11d0-a285-00aa003049e2}"
Const ADS_SCHEMA_ID_GUID_PS_PERSONAL        = "{77b5b886-944a-11d1-aebd-0000f80367c1}"
Const ADS_SCHEMA_ID_GUID_PS_PUBLIC      = "{e48d0154-bcf8-11d1-8702-00c04fb96050}"

ad_setUserDelegation    "OU=USERS, DC=AD, DC=COM", TRUSTEE_ACCOUNT_SAM, ADS_SCHEMA_ID_GUID_PS_USER
ad_setUserDelegation    "OU=USERS, DC=AD, DC=COM", TRUSTEE_ACCOUNT_SAM, ADS_SCHEMA_ID_GUID_PS_PERSONAL
ad_setUserDelegation    "OU=USERS, DC=AD, DC=COM", TRUSTEE_ACCOUNT_SAM, ADS_SCHEMA_ID_GUID_PS_PUBLIC

Function ad_setUserDelegation(          _
        ByVal   strOU           _
        ,ByVal  strTrusteeAccount   _
        ,ByVal  strSchema_GUID      _
        )

    Set objSdUtil           = GetObject( "LDAP://" & strOU )

    Set objSD           = objSdUtil.Get( "ntSecurityDescriptor" )
    Set objDACL             = objSD.DiscretionaryACL

    Set objAce          = CreateObject( "AccessControlEntry" )

    objAce.Trustee          = strTrusteeAccount
    objAce.AceFlags         = ADS_ACEFLAG_INHERIT_ACE
    objAce.AceType          = ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
    objAce.Flags            = ADS_FLAG_OBJECT_TYPE_PRESENT OR ADS_FLAG_INHERITED_OBJECT_TYPE_PRESENT

    objAce.ObjectType       = strSchema_GUID

    objACE.InheritedObjectType  = ADS_SCHEMA_ID_GUID_USER
    objAce.AccessMask       = ADS_RIGHT_DS_READ_PROP OR ADS_RIGHT_DS_WRITE_PROP
    objDacl.AddAce          objAce

    objSD.DiscretionaryAcl      = objDacl

    objSDUtil.Put           "ntSecurityDescriptor", Array( objSD )
    objSDUtil.SetInfo

End Function


Function ad_revokeUserDelegation(       _
        ByVal   strOU           _
        ,ByVal  strTrusteeAccount   _
        )

    Set objSdUtil           = GetObject( "LDAP://" & strOU )

    Set objSD           = objSdUtil.Get( "ntSecurityDescriptor" )
    Set objDACL             = objSD.DiscretionaryACL

    For Each objACE in objDACL
        If UCase(objACE.Trustee) = UCase(strTrusteeAccount) Then
                objDACL.RemoveAce objACE
        End If
    Next

    objSDUtil.Put           "ntSecurityDescriptor", Array(objSD)
    objSDUtil.SetInfo

End Function

      

+3


source


Sample code (at least moving parts)

string distinguishedname = "CN=Wicks\, Guy,OU=Users,DC=ad,DC=com"
using (DirectoryEntry myDirectoryEntry = new DirectoryEntry(string.Format("LDAP://{0}", distinguishedname), null, null, AuthenticationTypes.Secure))
{
    try
    {
        myDirectoryEntry.Username   = "serviceaccount";
        myDirectoryEntry.Password   = "pa55word";

        myDirectoryEntry.Properties["employeeid"][0]    = employeeID;
        myDirectoryEntry.CommitChanges();
        setresult.result        = myDirectoryEntry.Properties["employeeid"][0].ToString();
    }
    catch   ( Exception ex )
    {
        setresult.result        = ex.Message;
    }
} // end using

      



(I am sorry for my C #)

0


source


Do your service users have permission to change these fields through AD users and computers? if they are then maybe you can use impersonation and just making your service host machine "trusted for delegation" (in the AD properties for it) has always worked fine for me.

0


source







All Articles