Monday, August 10, 2009

ASP: Secure LDAP Query for User Properties

For those of you working in an environment where anonymous LDAP queries are disabled, you may find that trying to perform “standard” queries against Active Directory from an ASP page doesn’t work.  This is usually the result of the IIS service account not having domain access.  The default configuration of IIS is to run as IUSR_Name which is a local account and has no domain group memberships. 

You could modify IIS to use a domain “service” (aka “proxy”) account, but that’s not a panacea either.  To get around this safely, you can use a secure LDAP query with a domain proxy account instead.  This way, your web server remains secure, while you allow your application to open up specific connections for specific needs.  If you secure the folder and share permissions to your web application code you should be in good shape.  If you pick through this code, you’ll notice I picked a pipe symbol “|” as my delimiter within each field=value pairing.  That was arbitrary and there’s nothing wrong with picking a different character.  In fact, you can use whatever you like as long as you separate each pair with a different symbol that whatever you use to separate the field=value matching pairs.  I don’t recommend a comma or semi-colon since those can often occur with data values and could cause weirdness (nothing wrong with weirdness, but not within programming results).

'----------------------------------------------------------------
' example:
' x = GetUserData("abc00", "Name, ADsPath, mail, department, givenName, sn")
'
' For each v in Split(x, vbTab)
' response.write v & "
"
' Next
'----------------------------------------------------------------


Const ldap_user = "domain\proxy_user"
Const ldap_pwd = "P@ssw0rD##123"
Const ADS_SCOPE_SUBTREE = 2

Function GetUserData(uid, fields)
Dim objConnection, objComment, objRecordSet
Dim retval : retval = ""
Dim i, fieldname, strvalue
On Error Resume Next
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Properties("User ID") = ldap_user
objConnection.Properties("Password") = ldap_pwd
objConnection.Properties("Encrypt Password") = TRUE
objConnection.Properties("ADSI Flag") = 1
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
objCommand.CommandText = "SELECT " & fields & _
" FROM 'LDAP://DC=nns,DC=com' " & _
"WHERE objectCategory='user' AND sAMAccountName='" & uid & "'"
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst
Do Until objRecordSet.EOF
For i = 0 to objRecordSet.Fields.Count -1
fieldname = objRecordSet.Fields(i).Name
strvalue = objRecordSet.Fields(i).Value
If retval <> "" Then
retval = retval & vbTab & fieldname & "|" & strValue
Else
retval = fieldname & "|" & strValue
End If
Next
objRecordSet.MoveNext
Loop
GetUserData = retval
End Function

1 comment:

skatterbrainz said...

The example line appears broken within the For each loop, but the <br/> tag got processed instead of displayed, so just put a BR tag in between the empty double-quotes.