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?
source to share
ANSWER
ADS_SCHEMA_ID_GUID_USER GUID allows you to update base user class information including employee ID
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
source to share
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 #)
source to share