Also, when I find out that they have used a valid user name and password, I need to look them up in the LDAP and find their employee id to use as the key for database lookups, etc.
I thought maybe I could do all of this in one step by using the OpenDSObject() method. In other words:
lcUserId = * user name from POST of webpage *
lcPassword = * password from POST of webpage *
oDSO = GetObject("LDAP:")
oUser = oDSO.OpenDSObject("LDAP://server1.domain1.com/cn=Mike Test,cn=Users,dc=domain1,dc=com",lcUserId,lcPassword,0x1)
This code works, in that it uses the user's id and password for authentication for the OpenDSObject command and returns the user object from which I can pull the employee id.
However, my problem with this is that the the user's login id may be something like m.test but in order to grab his user object, I have to reference the object name (cn=Mike Test).
I've thought of using ADO to do a search for the user but I have had 2 problems.
1) I keep getting a "Table does not exist" error. (I'll list my code below)
2) Even if the user is found and a recordset returned, I still haven't verified his password and user id.
Any ideas on what I can do? Thanks so much for your help!
The code I've been using for ADO: (Visual Foxpro)
oConn = createobject("ADODB.Connection")
oComm = createobject("ADODB.Command")
oConn.Provider = "ADSDSOObject"
oConn.Open()
oComm.ActiveConnection = oConn
oComm.CommandText = "select name, employeeid from 'LDAP://dc=domain1,dc=com' where objectclass='user' and samaccountname='m.test'"
oRS = oComm.Execute()
I've also tried the following in place of 'LDAP://dc=domain1, ...'
'LDAP://domain1.com/dc=domain1,dc=com'
'LDAP://domain1.com'
'LDAP://server1.domain1.com/dc=domain1,dc=com'
'LDAP://server1.domain1.com/dc=server1,dc=domain1,dc=com'
'LDAP://server1.domain1.com'
you need to exchange the line with the CommandText. Since you need multiple
filters (better performance) I'd prefer the following format:
oComm.CommandText = "<LDAP://dc=domain1,dc=com>;" & _
"(&(objectCategory=Person)(objectClass=user)" & _
"(sAMAccountName=" & lcUserId & _
"));distinguishedName,employeeid;subtree"
Then make sure that you received just one result in oRS after executing the
Command.
This will provide you with the distinguishedName in oRS.Fields(0).Value and the
employeeid in oRS.Fields(1).Value.
Afterward you can add your prior code (remove the line wrap):
oDSO = GetObject("LDAP:")
oUser = oDSO.OpenDSObject("LDAP://" & oRS.Fields(0).Value
,lcUserId,lcPassword,0x1)
If you don't get a error here the user is verified, and you already got his
employeeid.
Good thing about using this method is that it is not important where in the
directory the user is, your query would assume it's always in the same OU.
Gruesse - Sincerely,
Ulf B. Simon-Weidner
Hi,
Although I prefer Ulf's syntax, the original code works for me in VBScript.
However, I must use the "Set" statement when binding to all objects. Is this
not requried in FoxPro? For example:
Set oConn = CreateObject("ADODB.Connection")
Set oComm = CreateObject("ADODB.Command")
Set oRS = oComm.Execute()
I get your error only if the base of the search is wrong, in your case
'LDAP://dc=domain1,dc=com'.
Again, I'm using VBScript, but perhaps you could retrieve the DNS domain
name from the RootDSE object. For example:
Set oRoot = CreateObject("LDAP://RootDSE")
sDomain = oRoot.Get("defaultNamingContext")
oComm.CommandText = "select name, employeeid from 'LDAP://" & sDomain _
& "' where objectclass='user' and samaccountname='m.test'"
Next, it would be more straightforward to use the NameTranslate object to
convert the NT logon name (sAMAccountName), in conjuction with the NetBIOS
domain name, to the Distinguished Name. For example, in VBScript:
' Constants for the NameTranslate object.
Const ADS_NAME_INITTYPE_DOMAIN = 1
Const ADS_NAME_TYPE_NT4 = 3
Const ADS_NAME_TYPE_1179 = 1
' Specify NT logon name of user.
strNTName = "m.test"
' Determine DNS domain name from RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
' Use the NameTranslate object to find the NetBIOS domain name from the
' DNS domain name.
Set objTrans = CreateObject("NameTranslate")
objTrans.Init ADS_NAME_TYPE_NT4, strDNSDomain
objTrans.Set ADS_NAME_TYPE_1179, strDNSDomain
strNetBIOSDomain = objTrans.Get(ADS_NAME_TYPE_NT4)
' Remove trailing backslash.
strNetBIOSDomain = Left(strNetBIOSDomain, Len(strNetBIOSDomain) - 1)
' Use the NameTranslate object to convert the NT user name to the
' Distinguished Name required for the LDAP provider.
objTrans.Init ADS_NAME_INITTYPE_DOMAIN, strNetBIOSDomain
objTrans.Set ADS_NAME_TYPE_NT4, strNetBIOSDomain & "\" & strNTName
strUserDN = objTrans.Get(ADS_NAME_TYPE_1179)
' Bind to the user object in Active Directory with the LDAP provider.
Set objUser = GetObject("LDAP://" & strUserDN)
In your case, you could use the OpenDSObject method to pass alternate
credentials, as suggested by Ulf, if that is your intent. Hopefully it is
simple to convert this to FoxPro. I hope it helps.
--
Richard
Microsoft MVP Scripting and ADSI
HilltopLab web site - http://www.rlmueller.net
--
Thanks so much for your willingness to help. I tried what you suggested with the same result. I'll include my code just in case I messed up in my translation from VB to VFP. (In VFP '+' concatinates lines and ';' is the line continuation character -- if it's not inside the quotes as part of the string).
oComm.CommandText = "<LDAP://dc=domain1,dc=com>; " + ;
"(&(objectCategory=person)(objectClass=user)(sAMAccountName=m.test));" + ;
"distinguishedname,employeeid;subtee"
I also tried replacing the //dc=domain1,dc=com with:
//dc=servername,dc=domain1,dc=com
//dc=domain1,dc=com,dc=servername
//servername.domain1.com/dc=domain1,dc=com
//domain1.com/dc=domain1,dc=com
Every single command yielded the following:
OLE Idispatch exception code 0 from the Provider: Table does not exist ...
And yet the following code works fine:
oDSO = getobject("LDAP://")
oUser = oDSO.OpenDSObject("LDAP://servername.domain1.com/cn=M Test,cn=Users,dc=domain1,dc=com","m.test",password,0x1)
In this case, contact is made with the server no problem and the user info is returned. I don't understand how it can find it in one case and not the other.
Any ideas? I might mention also, that the machine on which I'm running my code is an XP workstation on the same network as the domain. I don't know if that makes a difference or not.
I'm at a loss. Your syntax looks good to me. I get a similar error only if
the base of the search is wrong. If "servername" is the name of a server,
and the bind with OpenDSObject worked, then I would expect any of the
following to work:
<LDAP://dc=domain1,dc=com>
<LDAP://servername.domain1.com/dc=domain1,dc=com>
However, "dc=servername" would not work. Perhaps
"domain1.com/dc=domain1,dc=com" would work as well.
--
Richard
Microsoft MVP Scripting and ADSI
HilltopLab web site - http://www.rlmueller.net
--
"RHNewbie" <anon...@discussions.microsoft.com> wrote in message
news:961BACF4-F49D-4B73...@microsoft.com...
sorry, just some guesses:
- you have a space in the first LDAP-Line - not sure if that's an issue
(and to lazy to try right now - already late here)
- the LDAP-Path you provided should work, it's either
LDAP://company.com/dc=company,dc=com
LDAP://server1/dc=company,dc=com
LDAP://server1.company.com/dc=company,dc=com
all of those are working
- Permissions: Your statement which works tells the system which user +
password to take to connect to the server, mine assumes that you have
sufficient rights with your logged in account
- Foxpro - don't know anything about it. Would it be possible for you to
take out the critic part for tests only into a vbs? Just do the query
and print the result.
I have tried 4 times now (this being the fifth) to reply to your first post. Something keeps my posts from going through. Anyhow, I do appreciate your help.
In answer to your first question, no, VFP (Visual FoxPro) does not require the SET command when assigning variable values.
I tried following the steps you gave me in regards to using NameTranslate with limited success. That means I was able to at least instantiate a few of the objects. <g> I did the following:
' In your example, you used createobject ... that did not work for me. I had to use getobject.
oRoot = getobject("LDAP://servername.domain1.com/RootDSE")
cDomain = oRoot.Get("defaultNamingContext")
'cDomain now = "DC=domain1,DC=com"
oTrans = createobject("NameTranslate")
All the above worked. From here, things fell apart. When I tried the following:
= oTrans.Init(3,cDomain)
OR
= oTrans.Set(1,cDomain)
I received the following error: 'The specified domain either does not exist or could not be contacted.'
Does it matter that the machine I'm using is not part of the domain or something?
Thanks again for all your input.
Thank you both SO much for your help! You have definitely helped me tons!
I finally have things working. I honestly think that most of my problems stemmed from the fact that I'm working on a computer that is not part of the domain. I'm guessing that you both were part of the domain.
Anyhow, I was able to run Ulf's ADO query by changing: <LDAP://dc=domain1,dc=com> to <LDAP://servername.domain1.com/dc=domain1,dc=com>.
Then, I was able to get the NameTranslate to work using the following code:
oTrans = createobject("NameTranslate")
= oTran.Init(2,"servername.domain1.com")
= oTran.Set(3,"domain1/m.test")
cName = oTran.Get(4)
Thanks again to you both for getting me going in the right direction!
First, my mistake. I should have used GetObject when binding to the RootDSE
object.
I think the key might be that you are not authenticated to the domain. The
RootDSE object allows anonymous access. You have to be authenticated to bind
to the domain. Perhaps you can use alternate credentials and the
OpenDSObject method.
When I am not authenticated, I can use RootDSE to determine the domain name
and bind to the domain object with alternate credentials. However, I don't
know how to use alternate credentials with the NameTranslate object. I get a
permission denied error. And, I don't remember seeing examples using ADO
with alternate credentials.
--
Richard
Microsoft MVP Scripting and ADSI
HilltopLab web site - http://www.rlmueller.net
--
"Rharris" <anon...@discussions.microsoft.com> wrote in message
news:195B8D5E-B712-463A...@microsoft.com...