This page contains an annotated program in Visual Basic
that gets data from ldap.rutgers.edu. This is intended to be a
model for people who are using Microsoft ASP or similar technologies.
The author has no easy way to debug ASP, but hopes that a
VB program will be close enough to ASP to be useful.
Note that the proper way to use LDAP is as follows:
1. Start by opening an SSL connection, and binding it to
the special service DN and password that you are issued by
ldap-support@rutgers.edu. If you don't do this, you're limited to
data that is visible to the public.
2. Take the user's NetID and look it up, using a query
like (uid=XXX) where XXX is the NetID. The lookup will return
the actual DN for the user. This is typically
uid=XXX,ou=people,dc=rutgers,dc=edu. However your code should
not assume that it knows the format of the DN. You always want
to lookup uid=XXX and let the directory return the DN.
3. The search will also return attributes of the user's directory entry. You may need to check them to make sure that the user is allowed to use your service, or to get information that will help you serve the user.
4. Given the DN returned by the search, you can now check the user's password. To do this, attempt to bind with the DN and the password that the user supplied.
These steps are really easy to do in LDAP or using most Unix tools. Unfortunately Microsoft seems to have gone out of their way to make it hard to deal with LDAP from ASP.
In the following example, "results.Additem" happens to be the way I display output. Your code will probably use a different approach.
Dim con
Dim command
Dim rs
Dim dso
Dim cont
Dim path
Dim user
' The following path is the right search base for normal people, i.e. people
' with data in the PDB.
ADsPath = "LDAP://ldap.rutgers.edu/ou=People,dc=rutgers,dc=edu"
' The following magic creates and opens a connection to the LDAP server.
' The userid and password should be replaced with the service DN and
' password that you are issued for your service. You might check it
' using your NetID as xxxx and your password as yyyy. That won't let you
' see all the data, but it will let you start making sure this works.
' The flag of 34 means to use SSL (which we require for any connection
' that sends passwords) and "fast bind". Note that in LDAP when you
' login, it wants a full dn, not just a username.
Set con = CreateObject("ADODB.Connection")
con.Provider = "ADsDSOObject"
con.Properties("User ID") = "uid=xxxx,ou=people,dc=rutgers,dc=edu"
con.Properties("Password") = "yyyy"
con.Properties("ADSI Flag") = 34
con.Open "ADSI"
' OK, now we're going to do 3 things: search for a user by uid (i.e. netid),
' check their password, and print some data that came from the directory.
Set com = CreateObject("ADODB.Command")
Set com.ActiveConnection = con
' Make up an LDAP query. the format is
' <ldap://ldap.rutgers.edu/ou=people,dc=rutgers,dc=edu>;(query);attrs;subtree
' The first defines the LDAP search base
' Then you have the actual query, using the usual LDAP filter format
' to look for someone by netid it is (uid=xxxx)
' attrs is a list of the attributes you want to be returned.
' You'll want to see the DN itself. Unfortunately they don't give you the
' actual DN. They give you the "adspath". E.g. if the dn is
' uid=netid,ou=people,dc=rutgers,dc=edu, they return an adspath of
' ldap://ldap.rutgers.edu/uid=netid,ou=people,dc=rutgers,dc=edu
' So the following query looks up a person by uid, and gets the
' adspath, cn and postaladdress. "netid" and "password" are presumed
' to be supplied by the user.
com.CommandText = "<" & ADsPath & ">;(uid=" & netid &
");Adspath,cn,postaladdress,rulinkRutgersEduIID;subtree"
Set rs = com.Execute
' Now you have to decide what to do with the results. It's returned as
' a result set, in this case rs. Several entries can match a query, although
' in this particular case there had better only be one person with a given netid.
' Anyway, you call rs.movenext to cycle through all the entries that matched
' your query. In the code below I look through all the entries, checking the
' password and displaying cn and postaladdress. Of course there should be
' only one entry in this case, but I thought you'd want to see how to process more
' general queries, e.g. (cn=*name*), which might return more than one entry.
While Not (rs.EOF)
path = rs.fields("ADsPath")
results.AddItem path
' Ok, we have to convert the adspath to a DN, because password checking
' is done with a DN and password. Look for the last / and take everything
' after it. What we're trying to do here is set "user" to be the DN
' for the user. That's what we'll use to check the user's password.
user = InStrRev(path, "/")
user = Mid(path, user + 1)
results.AddItem user
' This actually opens a new connection to check the user's password.
' This opens the connection, checks the password, and doesn't do
' anything else. "user" is actually the dn that we got after looking
' up the user. As usual 34 means to do SSL and fast bind.
Set dso = GetObject("LDAP:")
Set cont = dso.OpenDSObject(ADsPath, user, password, 34)
' See if the user's password worked. If not print error message
If Err.Number <> 0 Then
results.AddItem Err.Description
Else
results.AddItem "Password OK"
End If
Err.Clear
' Now show three of the attributes
' Note that the IID is single-valued, so you don't want the (0).
' ADSI checks the schema to see which attributes are multivalued,
' and returns arrays only for them.
v = rs.fields("cn")
results.AddItem v(0)
v = rs.fields("postaladdress")
results.AddItem v(0)
v = rs.fields("rulinkRutgersEduIID")
results.AddItem v
' Here's another approach that may be safer:
v = rs.fields("rulinkRutgersEduIID")
If (isarray(v)) Then
results.AddItem v(0)
Else
results.AddItem v
End If
' Go look at the next entry returned from the directory.
' In this case there shouldn't be any, since there should
' only be one entry with a given NetID
rs.MoveNext
Wend
Note that attributes are returned as arrays, because a given attribute can have more than one value. That's why you see the (0) in
v = rs.fields("cn")
results.AddItem v(0)
The code above simply prints the first value of the attribute.
You will probably want to look at Microsoft's examples of how to do LDAP queries to see more general ways of processing the results.
In the Microsoft example, what you should look at is the code following
Set rs = Com.Execute
You should use my example for setting up the connection. Microsoft's example is useful for seeing more general approaches to processing the results. These are returned in "rs" in both my example and theirs.