Looping through hashtable and comparing values

G

Guest

Hi all

I'm creating a hashtable of a list of users in AD. The keys are UserID and
Password. I want to loop through the table to compare the userID and password
with values that a user has entered. Ideally I'd want to run through the
records until I find one that matches with the entered UserID and then
compare passwords.

I've googled and I can't really find any examples of how to do this.

Anyone got any ideas? Thanks in advance!

Julia
 
M

Mark Rae [MVP]

I'm creating a hashtable of a list of users in AD. The keys are UserID and
Password. I want to loop through the table to compare the userID and
password
with values that a user has entered. Ideally I'd want to run through the
records until I find one that matches with the entered UserID and then
compare passwords.

I've googled and I can't really find any examples of how to do this.

Anyone got any ideas? Thanks in advance!

Slightly puzzled...

Although user passwords are stored in ActiveDirectory, you certainly can't
retrieve them in the same way as e.g. you can retrieve a user's email
address etc...

Where are you getting UserID and Password from to populate your
Hashtable...?
 
G

Guest

Sorry, let me be more specific. No there wouldn't be more than one user with
the same id. I'm just trying to find a user based on user entered text. My
problem is that I can't seem to work out how to go through the hashtable
"rows". Hashtable doesn't have a row property so how do you loop through? Or
do you loop through keys? If so, what are they declared as? i.e.

dim key as ????
for each key in hashtable
if key = "userid" then
if value = "xxxx" then
end if
end if
next

The problem is that, although I am able to declare a variable as a
hashtable, hashtables appear to have no members/properties/functions
associated with them on my intellisense. Code is below.

Hope that makes a bit more sense.

Julia

Public Function ValidateIDPassword(ByVal enteredNetworkID As String, ByVal
enteredPassword As String) As Boolean
Dim usersTable As Hashtable = GetAllUsers("ukntdc01.rcuk.com:389")
'now loop through the usersTable and check if there's a matching user
'this is where I have no idea what to do

End Function

Public Function GetAllUsers(ByVal ldapServerName As String) As Hashtable
'this function returns all the ldap ad users for searching in the
validated id
Dim oRoot As DirectoryServices.DirectoryEntry = New
DirectoryServices.DirectoryEntry _
("LDAP://" & ldapServerName &
"/OU=EVOII,DC=rcuknet,DC=rockwellcollins,DC=com")
Dim oSearcher As DirectoryServices.DirectorySearcher = New
DirectoryServices.DirectorySearcher(oRoot)
Dim oResults As DirectoryServices.SearchResultCollection
Dim oResult As DirectoryServices.SearchResult
Dim RetArray As Hashtable

oSearcher.PropertiesToLoad.Add("SAMAccountName")
oSearcher.PropertiesToLoad.Add("userPassword")
oResults = oSearcher.FindAll

For Each oResult In oResults

If Not
oResult.GetDirectoryEntry().Properties("SAMAccountName").Value = "" Then
RetArray.Add("UserID",
oResult.GetDirectoryEntry().Properties("SAMAccountName").Value)
RetArray.Add("Password",
oResult.GetDirectoryEntry().Properties("userPassword").Value)
End If

Next

Return RetArray

End Function
 
G

Guest

Thanks Mark, well that's interesting. I got some code from a website and I
made an assumption that password was just another property you could
retrieve. I haven't tested any of my code out yet, so perhaps I won't even
get as far as the hashtable!!

I have an intranet application with a sign on page that has networkID and
password text entry boxes. I want to compare the entries in the text boxes to
ensure that (a) there is a matching user id and (b) the user has entered the
correct password.

Should I rethink my approach and, if so, how?

My (obviously incorrect) code is:

Public Function GetAllUsers(ByVal ldapServerName As String, ByVal networkID
As String) As Hashtable
'this function returns all the ldap ad users for searching in the
validated id
Dim oRoot As DirectoryServices.DirectoryEntry = New
DirectoryServices.DirectoryEntry _
("LDAP://" & ldapServerName &
"/OU=EVOII,DC=rcuknet,DC=rockwellcollins,DC=com")
Dim oSearcher As DirectoryServices.DirectorySearcher = New
DirectoryServices.DirectorySearcher(oRoot)
Dim oResults As DirectoryServices.SearchResultCollection
Dim oResult As DirectoryServices.SearchResult
Dim RetArray As Hashtable

oSearcher.PropertiesToLoad.Add("SAMAccountName")
oSearcher.PropertiesToLoad.Add("userPassword")
oResults = oSearcher.FindAll

For Each oResult In oResults

If Not
oResult.GetDirectoryEntry().Properties("SAMAccountName").Value = "" Then
RetArray.Add("UserID",
oResult.GetDirectoryEntry().Properties("SAMAccountName").Value)
RetArray.Add("Password",
oResult.GetDirectoryEntry().Properties("userPassword").Value)
End If

Next

Return RetArray

End Function

Julia
 
P

Patrice

You don't have to loop. Try :
Dim h As New System.Collections.Hashtable
h.Add("A", "PasswordA")
h.Add("B", "PasswordB")
MsgBox(h("A"))
MsgBox(h.Contains("A"))
MsgBox(h.Contains("Z"))

You should see :
- PasswordA (value retrieved from the collection for the "A" key)
- True (the "A" key is part of the collection)
- False (the "Z" key is not part of the collection)
 
M

Mark Rae [MVP]

Thanks Mark, well that's interesting. I got some code from a website and I
made an assumption that password was just another property you could
retrieve. I haven't tested any of my code out yet, so perhaps I won't even
get as far as the hashtable!!

User passwords are stored in a hashed state and can't be retrieved directly,
for fairly obvious security reasons!
http://www.velocityreviews.com/forums/t104443-getting-user-password-from-active-directory.html
I have an intranet application with a sign on page that has networkID and
password text entry boxes. I want to compare the entries in the text boxes
to
ensure that (a) there is a matching user id and (b) the user has entered
the
correct password.

Ah, well that's a breeze!
Should I rethink my approach and, if so, how?

Yup, as below. This code is in C# (I never go anywhere near VB.NET...), but
it should be fairly easy to convert:

using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.DirectoryServices.Protocols;
using System.Net;

bool Logon(string pstrUser, string pstrPassword)
{
try
{
string strDomain = System.Environment.UserDomainName; // modify
as required
using (LdapConnection objLDAP = new LdapConnection(strDomain))
{
objLDAP.AuthType = AuthType.Kerberos;
objLDAP.Bind(new NetworkCredential(pstrUser, pstrPassword,
strDomain));
return true;
}
}
catch (System.Runtime.InteropServices.COMException)
{
return false;
}
catch (Exception)
{
return false;
}
}
 
G

Guest

Patrice,

I'm really sorry, I just don't understand that.

My hashtable has 2 keys - "UserID" and "Password". There are multiple
records/rows. I'm assuming a hashtable has something similar to a row and
there's a record where userid and password go together. So I want to find a
userid from the first key then on the same row/record check if the value in
the matching key entitled "password" is a certain value.

I can't see how you could do that with your example.

Sorry if I'm being stupid!

Julia
 
M

Mark Rae [MVP]

My hashtable has 2 keys - "UserID" and "Password". There are multiple
records/rows. I'm assuming a hashtable has something similar to a row and
there's a record where userid and password go together. So I want to find
a
userid from the first key then on the same row/record check if the value
in
the matching key entitled "password" is a certain value.

This isn't going to be of any use to you anyway, because you can't fetch
passwords out of ActiveDirectory...
 
G

George Ter-Saakov

I am a bit confused by what you want but here is some help.

1. To iterate through Hashtable use GetEnumerator
sample:
Hashtable myTable;
IDictionaryEnumerator en = myTable.GetEnumerator();
while(en.MoveNext)
{
string sKey = en.Key;
string sValue = en.Value;
}

2. Just to get value if you know key simply access it as array. (You can
use any type like string instead of clsMyValue )
clsMyValue objValue = (clsMyValue)myTable[objKey];
if( objValue != null )
{
.....
}


George
 
P

Patrice

Ah ok. I didn't noticed this.

IMO the problem is that the hastable is used in an unsual manner. Currently
it looks like you store all users with a "UserID" key and all passwords with
a "Password" key (so you have just two distinct keys).

It IMO defeats the purpose of using such a collection as this way you just
have a bunch of data in which you have to explicitely browse to find out
something (basically no advantage compared with an array).

Instead you could use the user id as a key and the password as a value. Note
that you can even store an object for the value (and as a key thought it's
perhaps a bit less usefull) making then possible to store any amout of data
for a single key. IMO this is not yet needed in this particular case. You
could just use the User ID as a key and the password as a value.
 
G

Guest

Thanks for that. I guess that was my lack of understanding of hashtables. It
turns out that I'm not going to be able to use the hashtable now anyway. Mark
Rae has explained that I can't get user passwords from Ad anyway and has
shown me a more appropriate solution.

Thanks for your help anyway. It's certainly given me a better understanding
of hashtables for use in the future.

Julia
 
G

Guest

Hi Mark

Thanks very much for this. It's much appreciated. I'll give this a go and
let you know if I come across any problems.

Julia
 
M

Mark Rae [MVP]

Thanks very much for this. It's much appreciated. I'll give this a go and
let you know if I come across any problems.

No problem.

And back to the original question, you should seriously consider using
generics rather than hashtables and arrays etc...

Won't help you in this particular case, though, but they're well worth
investigating for the future...
 
G

Guest

Mark,

I've hit a problem. I should have explained that I'm using .net 1.1. It
would seem that System.Collections.Generic and
System.DirectoryServices.Protocols are not available to me. I'm getting some
errors after converting the code (ldapconnection object and authtype).

Julia
 
M

Mark Rae [MVP]

I should have explained that I'm using .net 1.1.

Ah - yes you should... :) v2.0 has been out for almost two years now, and
the next version is just round the corner, so if you don't explicitly say
you're not using the current version, people will automatically assume that
you are...

I would suggest that you ask in the microsoft.public.adsi.general newsgroup
for how to convert the code I posted back to v1.1 of the Framework...

Apologies, but I don't know enough about ADSI to help in this respect - in
fact, the code I gave you was pretty much pinched from Joe Kaplan, ADSI MVP
and absolute Active Directory guru...
 
G

Guest

Mark, thanks again for your help and time on this! My aplogies again for not
mentioning the version issue - we're a bit slow here to upgrade! I will post
on the group you suggested.

Julia
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top