How to get the AD groups a user is member of (ASP)
Hi all,
The following ASP sample shows how to get all Active Directory groups of the user accessing the ASP page.
Note: I know ASP is quite old and people should be using ASP.NET instead. But I'm posting this sample because translating it to VBScript is pretty straightforward, and I still have many customers using VBScript.
<%
' Get domain\user from client
'
Response.Write "<b>FROM CLIENT</b><br><br>"
sLogonUser = Request.ServerVariables("Logon_User")
sDomain = Mid(sLogonUser, 1, Instr(1, sLogonUser, "\") - 1)
sLogonName = Mid(sLogonUser, Instr(1, sLogonUser, "\") + 1)
Response.Write "<b>Logon User:</b><br>" & sDomain & "\" & sLogonName & "<br><br>"
' Create ADO connection to Active Directory
'
Set oConnection = CreateObject("ADODB.Connection")
With oConnection
.Provider = "ADsDSOObject"
.Mode = "1" 'Read
.Properties("Encrypt Password") = True
.Open "Active Directory Provider"
End With
' Create command to search user in Active Directory
'
Set oCommand = CreateObject("ADODB.Command")
oCommand.ActiveConnection = oConnection
' Build the ADsPath element of the CommandText
'
Set oRoot = GetObject("LDAP://" & sDomain & "/rootdse")
Set oDomain = GetObject("LDAP://" & sDomain & "/" & oRoot.Get("defaultNamingContext"))
sADsPath = "<" & oDomain.ADsPath & ">"
' Build the filter element of the CommandText
'
sFilter = "(&(objectCategory=Person)(objectClass=user)(sAMAccountName=" & sLogonName & "))"
' Build the returned attributes element of the CommandText
'
sAttribsToReturn = "distinguishedName,memberOf,primaryGroupID,objectSID"
' Build the depth element of the CommandText
'
sDepth = "subTree"
' Assemble the CommandText
'
ocommand.CommandText = sADsPath & ";" & sFilter & ";" & sAttribsToReturn & ";" & sDepth
' Execute the query
'
Set oRS = ocommand.Execute
' Only one user should meet the criteria
'
If (oRS.RecordCount = 1) Then
Response.Write "<br><b>FROM ACTIVE DIRECTORY</b><br><br>"
' Get that user's info
'
oRS.MoveFirst
For i = 0 To oRS.Fields.Count - 1
' distinguishedName
'
If (oRS.Fields(i).Name = "distinguishedName") Then
' adVarWChar
'
Response.Write "<b>distinguishedName:</b><br>"
Response.Write oRS.Fields(i).Value & "<br>"
' memberOf
'
ElseIf (oRS.Fields(i).Name = "memberOf") Then
' adVariant
'
Response.Write "<b>memberOf:</b><br>"
For Each value In oRS.Fields(i).Value
Response.Write value & ";<br>"
Next
' primaryGroupID
'
ElseIf (oRS.Fields(i).Name = "primaryGroupID") Then
' adInteger
'
Response.Write "<b>primaryGroupID:</b><br>"
iPrimaryGroupID = oRS.Fields(i).Value
Response.Write CStr(iPrimaryGroupID) & "<br>"
' objectSID
'
ElseIf (oRS.Fields(i).Name = "objectSID") Then
' adVarBinary
'
Response.Write "<b>objectSID (binary):</b><br>"
vObjectSID = oRS.Fields(i).Value
Response.write Get_HexString(vObjectSID) & "<br>"
Response.Write "<b>objectSID (SDDL):</b><br>"
sObjectSID = SDDL_SID(vObjectSID)
Response.write sObjectSID & "<br>"
End If
Next
' The primary group is not included in memberOf...
' We have the SDDL form of the user's SID.
' Remove the user's RID ( the last sub authority)
' up to the "-"
'
sDomainSID = Mid(sObjectSID, 1, (InStrREV(sObjectSID,"-")))
' Build the SID of the Primary group
' from the domainSID and the Primary Group RID in
' the PrimaryGroupID.
'
sGroupRID = StrRID(iPrimaryGroupID)
sDomainSID = sDomainSID & sGroupRID
' Get the primary group
'
set oPrimaryGroup = GetObject("LDAP://" & sDomain & "/<SID=" & sDomainSID & ">")
Response.Write "<b>primaryGroup:</b><br>" & oPrimaryGroup.Get("DistinguishedName") & "<br>"
End If
'==============================================================================
'HELPER FUNCTIONS
'==============================================================================
'------------------------------------------------------------------------------
' Function that does all the magic.
' Using the definition of a SID structure from
' WinNT.H
'
' The binary SID is converted to its SDDL counterpart
'
function SDDL_SID ( oSID )
dim IssueAuthorities(11)
IssueAuthorities(0) = "-0-0"
IssueAuthorities(1) = "-1-0"
IssueAuthorities(2) = "-2-0"
IssueAuthorities(3) = "-3-0"
IssueAuthorities(4) = "-4"
IssueAuthorities(5) = "-5"
IssueAuthorities(6) = "-?"
IssueAuthorities(7) = "-?"
IssueAuthorities(8) = "-?"
IssueAuthorities(9) = "-?"
' First byte is the revision value
'
Revision = ascb(midB(osid,1,1))
' Second byte is the number of sub authorities in the
' SID
'
SubAuthorities = CInt(ascb(midb(oSID,2,1)))
strSDDL = "S-" & Revision
IssueIndex = CInt(ascb(midb(oSID,8,1)))
' BYtes 2 - 8 are the issueing authority structure
' Currently these values are in the form:
' { 0, 0, 0, 0, 0, X}
'
' We use this fact to retreive byte number 8 as the index
' then look up the authorities for an array of values
'
strSDDL = strSDDL & IssueAuthorities(IssueIndex)
' The sub authorities start at byte number 9. The are 4 bytes long and
' the number of them is stored in the SubAuthorities variable.
'
index = 9
i = index
for k = 1 to SubAuthorities
' Very simple formula, the sub authorites are stored in the
' following order:
' Byte Index Starting Bit
' Byte 0 - Index 0
' Byte 1 - Index + 1 7
' Byte 2 - Index + 2 15
' Byte 3 - Index + 3 23
' Bytes0 - 4 make a DWORD value in whole. We need to shift the bits
' bits in each byte and sum them all together by multipling by powers of 2
' So the sub authority would be built by the following formula:
'
' SUbAuthority = byte0*2^0 + Byte1*2^8 + byte2*2^16 + byte3*2^24
'
' this be done using a simple short loop, initializing the power of two
' variable ( p2 ) to 0 before the start an incrementing by 8 on each byte
' and summing them all together.
'
p2 = 0
subtotal = 0
for j = 1 to 4
dblSubAuth = CDbl(ascb(midb(osid,i,1))) * (2^p2)
subTotal = subTotal + dblSubAuth
p2 = p2 + 8
i = i + 1
next
' Convert the value to a string, add it to the SDDL Sid and continue
'
strSDDL = strSDDL & "-" & cstr(subTotal)
next
SDDL_SID = strSDDL
end function
'------------------------------------------------------------------------------
'------------------------------------------------------------------------------
' Build an HexString SID
'
function Get_HexString( oSID )
outStr = ""
for i = 0 to Ubound(oSid)
b = hex(ascb(midb(oSid,i+1,1)))
if( len(b) = 1 ) then b = "0" & b
outStr = outStr & b
next
Get_HexString = outStr
end function
'------------------------------------------------------------------------------
'------------------------------------------------------------------------------
' Function StrRID returns and unsigned long of
' the given RID value
'
' If the most significant bit is set in a VB Long
' then VB will interpret the value as a negative number
' and CStr will convert the unsigned long into a string with a leading
' "-" sign.
'
' This function checks to see if the most significant bit
' is set, then tricks the CStr function into outputting
' and unsigned long value by using a double float value
' to store the RID value, then uses the CStr function to get the
' string version.
'
function StrRID( inVal )
dim dLocal
if( (inVal and &H80000000) <> 0 ) then
dLocal = CDbl((inval and &H7FFFFFFF))
dLocal = dLocal + 2^31
StrRID = cstr(dLocal)
else
StrRID = Cstr(inVal)
end if
end function
'------------------------------------------------------------------------------
%>
Regards,
Alex (Alejandro Campos Magencio)
Comments
- Anonymous
March 17, 2014
I had been looking for something like this for a while for building an Intranet site for my work. This code is great, but I did find one issue with it. If the user is only in one group, then you get an error on the memberOf query.