Extended Permissions in AD

Does anyone know how to go about searching for users that have the ms-EXCH-EPI-May-Impersonate right in AD?
FHoldenAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Justin DurrantSr. Engineer - Windows Server/VirtualizationCommented:
0
FHoldenAuthor Commented:
I was thinking more a code solution, I have yet to find anyway using AD Services to find that particular permission.
0
PFoeckelerCommented:
Hi,

identifiying permissions is a quite complex area ;) I wrote a VB Script to demonstrate the permission detection. What you basicly need is:

- A mechanism to search all the objects in your domain. If you want to restrict the search to certain objects (for exampe: examine only the OUs for the searched permission), you have to change the LDAP filter in line 21    "(objectClass=*)"

- You have to know that user with your ms-EXCH-EPI-May-Impersonate permission have CA (Control Access Right) with the object GUID "bc39105d-9baa-477c-a34a-997cc25e3d60" - this is the rights GUID for this extended right (you can check this in your configuration partition in CN=Extended-Rights,CN=Configuration,DC=example,DC=org

- You need a bit ADSI magic to decode the permission attribute "ntSecurityDescriptor" (can only read by administrator, so be sure o start the script as administrator)

- If the trustee (the account which was granted to have this permission) is from another domain in your forest, you have to decode it's SID into a readable name....

That's all ;)

I stood on the shoulder of giants, here are the websites where you can get all these information:

Permission decoding:
http://www.rlmueller.net/Programs/DACL.txt 

LDAP Searches and LDAP Filters:
http://www.selfadsi.org/search.htm#ExampleADS
http://www.selfadsi.org/ldap-filter.htm

SID Translation into a readable name:
http://www.selfadsi.org/deep-inside/microsoft-sid-attributes.htm

Philipp

Const ADS_RIGHT_DS_CONTROL_ACCESS = &H100
Const msEXCHEPIMayImpersonate = "{bc39105d-9baa-477c-a34a-997cc25e3d60}"


'------------------------------------------------------------ [get the domain name]
set rootDSE = getObject("LDAP://rootDSE")
domainDN = rootDSE.Get("defaultNamingContext")

WSCript.Echo "Searching for Extended Right: ms-EXCH-EPI-MayImpersonate in domain " & domainDN
Wscript.Echo "..."

'------------------------------------------------------------ [search all objects in the domain]
Set ado = CreateObject("ADODB.Connection")
ado.Provider = "ADSDSOObject"
ado.Open "myPermSearch"

Set adoCmd = CreateObject("ADODB.Command")
adoCmd.ActiveConnection = ado
adoCmd.Properties("Page Size") = 1000
adoCmd.Properties("Cache Results") = True
adoCmd.CommandText = "<LDAP://" & domainDN & ">;(objectClass=*);ADsPath;subtree" 

Set objectList = adoCmd.Execute

While Not objectList.EOF
    objPath = objectList.Fields("ADsPath")
    CheckPermission(objPath) 

    objectList.MoveNext                                 'zum nächsten gefundenen Objekt 
Wend



'------------------------------------------------------ [this is the important part]
Sub checkPermission(adsPath)
    Set obj = GetObject(adsPath)
	
    'Bind to the security objects.
    Set objSecurityDescriptor = obj.Get("ntSecurityDescriptor")
    Set objDiscretionaryACL = objSecurityDescriptor.discretionaryACL
	
    'Enumerate each ACE in the DACL.
    For Each objACE In objDiscretionaryACL
	
        If ((objACE.AccessMask And ADS_RIGHT_DS_CONTROL_ACCESS) <> 0) Then
            If (LCase(CStr(objACE.objectType)) = msEXCHEPIMayImpersonate) Then
	        WScript.Echo "_______________________________________________"
                WScript.Echo "Permission set for " & obj.DistinguishedName
	        wscript.echo  "Trustee: " & sid_to_name(CStr(objACE.Trustee))
            End If
        End If
    Next
End Sub


'----------------------------------- [translate SIDs from other domains into user names]
Function sid_to_name(sidStr)
    On Error Resume NExt
    Set obj = GetObject("GC://<SID=" & sidStr & ">")
    If (Err.Number = 0) Then
        sid_to_name = obj.distinguishedName
    Else
        sid_to_name = sidStr
    End If
End Function

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Has Powershell sent you back into the Stone Age?

If managing Active Directory using Windows Powershell® is making you feel like you stepped back in time, you are not alone.  For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why.

Chris DentPowerShell DeveloperCommented:

> I was thinking more a code solution

Using what language?

I have a PowerShell script that will enumerate extended rights here:

http://www.indented.co.uk/index.php/2009/10/02/get-dsacl/

Chris
0
FHoldenAuthor Commented:
@PFoeckeler:  Thanks this was exactly what I was looking for, should be easy to translate to C#
@Chris-Dent:  This is a C# project, powershell is very usefull but not the enviornment that I'm dealing with just now.
0
Chris DentPowerShell DeveloperCommented:

Fair enough. If you have trouble translating do come back, I should be able to show you how to enumerate extended rights in C#.

Chris
0
PFoeckelerCommented:
If you want to translate the VBScript into a .NET language, the biggest difference will be the LDAP search, it is rather complicated in vbscript (-> ADO Search with ADSDSOObject), but rather easy with C#, C++, VB whatever... (-> System.DirectoryServices, use the DirectorySearcher here).

Philipp
0
Chris DentPowerShell DeveloperCommented:

If you're doing .NET you should be able to replace sid_to_name by loading the SID Byte Array into System.Security.Principal.SecurityIdentifier, then use the Translate method to get that to System.Security.Principal.NTAccount.

It'll save on connections to the domain and will work for both local and domain accounts :)

If you don't like that one, the WMI class Win32_SID is just as nice.

Chris
0
FHoldenAuthor Commented:
Thanks for the pointer Chris
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Databases

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.