469,621 Members | 1,678 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,621 developers. It's quick & easy.

Case sensitivity problem in using the Contains method in ResultPropertyValueCollection

I need to check whether a particular user is already a member of an Active
Directory Security Group.

The following code extract works but only if the user distinguished name is
exactly the same as that returned from Active Directory. For example using
'cn=' in the userdn string instead of 'CN=' does not work.

As far as I am aware Active Directory is not case sensitive and it is
therefore difficult to predict the case of a string.

Before I write code to extract all the strings (converted into either upper
or lower case) into a sorted list to be able to search for the user is there
a way to make the Contains method work more predictably?

The ResultPropertyValueCollection (result.Properties["member"]) contains
objects of type String.

DirectoryEntry parententry = new DirectoryEntry(LDAPParentPath);
DirectoryEntry groupentry = parententry.Children.Find(user.Group);
DirectorySearcher ds = new DirectorySearcher(groupentry);
SearchResult result;
ds.PropertiesToLoad.Add("member");
result = ds.FindOne();
if (result != null)
{
String userdn = String.Format("CN={0},{1}", user.User_logon_name,
user.Ldap_container);
if (!result.Properties["member"].Contains(userdn)) // NB Case Sensitive
{
// add user to group
groupentry.Properties["member"].Add(userdn);
groupentry.CommitChanges();
}
}
Mar 14 '07 #1
8 11710
Hello,

The obkect result.Properties["member"] is actually a ArryList object, its
Contains() method is Case sensitive here. Instead of the Contains method, I
think you may loop very items in this arraylist and compare lowercase value
of the items with your "userdn"'s lower case value.

Sincerely,

Luke Zhang

Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscripti...ult.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscripti...t/default.aspx.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.

Mar 15 '07 #2
"Chris Noble" <ch*********@newsgroup.nospamwrote in message
news:e2**************@TK2MSFTNGP05.phx.gbl...
>I need to check whether a particular user is already a member of an Active Directory
Security Group.

The following code extract works but only if the user distinguished name is exactly the
same as that returned from Active Directory. For example using 'cn=' in the userdn string
instead of 'CN=' does not work.

As far as I am aware Active Directory is not case sensitive and it is therefore difficult
to predict the case of a string.

Before I write code to extract all the strings (converted into either upper or lower case)
into a sorted list to be able to search for the user is there a way to make the Contains
method work more predictably?

The ResultPropertyValueCollection (result.Properties["member"]) contains objects of type
String.

DirectoryEntry parententry = new DirectoryEntry(LDAPParentPath);
DirectoryEntry groupentry = parententry.Children.Find(user.Group);
DirectorySearcher ds = new DirectorySearcher(groupentry);
SearchResult result;
ds.PropertiesToLoad.Add("member");
result = ds.FindOne();
if (result != null)
{
String userdn = String.Format("CN={0},{1}", user.User_logon_name,
user.Ldap_container);
if (!result.Properties["member"].Contains(userdn)) // NB Case Sensitive
{
// add user to group
groupentry.Properties["member"].Add(userdn);
groupentry.CommitChanges();
}
}

result.Properties["member"] returns the RDN in a directory attribute in upper case form, so
you need to use uppercased RDN's when comparing.
Howevr, there is no need to make it that complicated.

DirectoryEntry groupentry = parententry.Children.Find(user.Group);
String userdn = String.Format("CN={0}", user.User_logon_name);
DirectoryEntry tmpEntry;
try
{
tmpEntry = container.Children.Find(userdn , user.Ldap_container); //Find is case
agnostic, userdn may look like cn=...
}
finally
{
if(tmpEntry == null)
// no such entry found, add entry to container.
else
tmpEntry.Dispose();
}
.....

Willy.

RDN = "relative distinguished name" like DC, NC, E etc...
Mar 15 '07 #3
Thanks Willy
"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:%2****************@TK2MSFTNGP06.phx.gbl...
"Chris Noble" <ch*********@newsgroup.nospamwrote in message
news:e2**************@TK2MSFTNGP05.phx.gbl...
>>I need to check whether a particular user is already a member of an Active
Directory Security Group.

The following code extract works but only if the user distinguished name
is exactly the same as that returned from Active Directory. For example
using 'cn=' in the userdn string instead of 'CN=' does not work.

As far as I am aware Active Directory is not case sensitive and it is
therefore difficult to predict the case of a string.

Before I write code to extract all the strings (converted into either
upper or lower case) into a sorted list to be able to search for the user
is there a way to make the Contains method work more predictably?

The ResultPropertyValueCollection (result.Properties["member"]) contains
objects of type String.

DirectoryEntry parententry = new DirectoryEntry(LDAPParentPath);
DirectoryEntry groupentry = parententry.Children.Find(user.Group);
DirectorySearcher ds = new DirectorySearcher(groupentry);
SearchResult result;
ds.PropertiesToLoad.Add("member");
result = ds.FindOne();
if (result != null)
{
String userdn = String.Format("CN={0},{1}", user.User_logon_name,
user.Ldap_container);
if (!result.Properties["member"].Contains(userdn)) // NB Case
Sensitive
{
// add user to group
groupentry.Properties["member"].Add(userdn);
groupentry.CommitChanges();
}
}


result.Properties["member"] returns the RDN in a directory attribute in
upper case form, so you need to use uppercased RDN's when comparing.
Howevr, there is no need to make it that complicated.

DirectoryEntry groupentry = parententry.Children.Find(user.Group);
String userdn = String.Format("CN={0}", user.User_logon_name);
DirectoryEntry tmpEntry;
try
{
tmpEntry = container.Children.Find(userdn , user.Ldap_container); //Find
is case agnostic, userdn may look like cn=...
}
finally
{
if(tmpEntry == null)
// no such entry found, add entry to container.
else
tmpEntry.Dispose();
}
....

Willy.

RDN = "relative distinguished name" like DC, NC, E etc...


Mar 16 '07 #4
Thanks

Willys' suggestion looks like it will meet my needs

Chris Noble

"Luke Zhang [MSFT]" <lu******@online.microsoft.comwrote in message
news:KE*************@TK2MSFTNGHUB02.phx.gbl...
Hello,

The obkect result.Properties["member"] is actually a ArryList object, its
Contains() method is Case sensitive here. Instead of the Contains method,
I
think you may loop very items in this arraylist and compare lowercase
value
of the items with your "userdn"'s lower case value.

Sincerely,

Luke Zhang

Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscripti...ult.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscripti...t/default.aspx.
==================================================

This posting is provided "AS IS" with no warranties, and confers no
rights.

Mar 16 '07 #5
Willy

I have had a go with this but I am having a problem with the code you
provided in testing for a null instance of tmpEntry.
The line if(tmpEntry == null) will not compile without producing a 'use of
unassigned local variable' error
DirectoryEntry groupentry = parententry.Children.Find(user.Group);
String userdn = String.Format("CN={0}", user.User_logon_name);
DirectoryEntry tmpEntry;
try
{
tmpEntry = container.Children.Find(userdn , user.Ldap_container); //Find
is case agnostic, userdn may look like cn=...
}
finally
{
if(tmpEntry == null)
// no such entry found, add entry to container.
else
tmpEntry.Dispose();
}

Any suggestions

Chris
"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:%2****************@TK2MSFTNGP06.phx.gbl...
"Chris Noble" <ch*********@newsgroup.nospamwrote in message
news:e2**************@TK2MSFTNGP05.phx.gbl...
>>I need to check whether a particular user is already a member of an Active
Directory Security Group.

The following code extract works but only if the user distinguished name
is exactly the same as that returned from Active Directory. For example
using 'cn=' in the userdn string instead of 'CN=' does not work.

As far as I am aware Active Directory is not case sensitive and it is
therefore difficult to predict the case of a string.

Before I write code to extract all the strings (converted into either
upper or lower case) into a sorted list to be able to search for the user
is there a way to make the Contains method work more predictably?

The ResultPropertyValueCollection (result.Properties["member"]) contains
objects of type String.

DirectoryEntry parententry = new DirectoryEntry(LDAPParentPath);
DirectoryEntry groupentry = parententry.Children.Find(user.Group);
DirectorySearcher ds = new DirectorySearcher(groupentry);
SearchResult result;
ds.PropertiesToLoad.Add("member");
result = ds.FindOne();
if (result != null)
{
String userdn = String.Format("CN={0},{1}", user.User_logon_name,
user.Ldap_container);
if (!result.Properties["member"].Contains(userdn)) // NB Case
Sensitive
{
// add user to group
groupentry.Properties["member"].Add(userdn);
groupentry.CommitChanges();
}
}


result.Properties["member"] returns the RDN in a directory attribute in
upper case form, so you need to use uppercased RDN's when comparing.
Howevr, there is no need to make it that complicated.

DirectoryEntry groupentry = parententry.Children.Find(user.Group);
String userdn = String.Format("CN={0}", user.User_logon_name);
DirectoryEntry tmpEntry;
try
{
tmpEntry = container.Children.Find(userdn , user.Ldap_container); //Find
is case agnostic, userdn may look like cn=...
}
finally
{
if(tmpEntry == null)
// no such entry found, add entry to container.
else
tmpEntry.Dispose();
}
....

Willy.

RDN = "relative distinguished name" like DC, NC, E etc...


Apr 18 '07 #6
"Chris Noble" <ch*********@newsgroup.nospamwrote in message
news:OZ**************@TK2MSFTNGP02.phx.gbl...
Willy

I have had a go with this but I am having a problem with the code you provided in testing
for a null instance of tmpEntry.
The line if(tmpEntry == null) will not compile without producing a 'use of unassigned
local variable' error
DirectoryEntry groupentry = parententry.Children.Find(user.Group);
String userdn = String.Format("CN={0}", user.User_logon_name);
DirectoryEntry tmpEntry;
try
{
tmpEntry = container.Children.Find(userdn , user.Ldap_container); //Find is case
agnostic, userdn may look like cn=...
}
finally
{
if(tmpEntry == null)
// no such entry found, add entry to container.
else
tmpEntry.Dispose();
}

Any suggestions
Sorry my OE compiler did not catch this one ;-).

Make it ...
....
DirectoryEntry tmpEntry = null;;
try
{
...

Willy.

Apr 18 '07 #7
Willy
I spent too long writing C and C++ code and still assume unassigned
variables are automatically null.

My original method worked despite the case sensitivity problem but I am
still having problems with your suggestion.
The problem appears to be in using the line
' tmpEntry = container.Children.Find(userdn , user.Ldap_container); //Find
is case agnostic, userdn may look like cn=...'

No problems with the userdn but looking at the syntax for the Find method
the second parameter should be a schemaClassName.
container is the DirectoryEntry for a Security Group. I have tried "user" as
the schemaClassName but this does not work.
I can't see how this could work as the security group is not really a
container but it has properties one of which is 'members' that contains an
array of user names.
Am I missing something or do I need to back to my original approach and
solve the case problem

Chris
"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:%2****************@TK2MSFTNGP04.phx.gbl...
"Chris Noble" <ch*********@newsgroup.nospamwrote in message
news:OZ**************@TK2MSFTNGP02.phx.gbl...
>Willy

I have had a go with this but I am having a problem with the code you
provided in testing for a null instance of tmpEntry.
The line if(tmpEntry == null) will not compile without producing a 'use
of unassigned local variable' error
DirectoryEntry groupentry = parententry.Children.Find(user.Group);
String userdn = String.Format("CN={0}", user.User_logon_name);
DirectoryEntry tmpEntry;
try
{
tmpEntry = container.Children.Find(userdn , user.Ldap_container);
//Find is case agnostic, userdn may look like cn=...
}
finally
{
if(tmpEntry == null)
// no such entry found, add entry to container.
else
tmpEntry.Dispose();
}

Any suggestions

Sorry my OE compiler did not catch this one ;-).

Make it ...
...
DirectoryEntry tmpEntry = null;;
try
{
...

Willy.

Apr 19 '07 #8
Willy

Problem solved now. I used the Find method (case insensitive) to find the
security group directoryentry.

DirectoryEntry groupentry==null;
try
{
groupentry = parententry.Children.Find(GroupName); // case insensitive
}
finally
{
if (groupentry != null)
{
etc ......

If the groupentry is valid, then to check whether the user is already member
of the security group I can read the distinguishedName property for the user
and then search the member properties of the security group directoryentry

DirectorySearcher ds = new DirectorySearcher(groupentry);
SearchResult result;
ds.PropertiesToLoad.Add("member");
result = ds.FindOne();
if (result != null)
{
String userdn = entry.Properties["distinguishedName"].Value.ToString();
// Correct Case as stored in Active Directory
if (!result.Properties["member"].Contains(userdn)) // NB Case Sensitive
{
// add user to group
groupentry.Properties["member"].Add(userdn);
groupentry.CommitChanges();
}
}

Thanks for your help

Chris

"Chris Noble" <ch*********@newsgroup.nospamwrote in message
news:uB**************@TK2MSFTNGP04.phx.gbl...
Willy
I spent too long writing C and C++ code and still assume unassigned
variables are automatically null.

My original method worked despite the case sensitivity problem but I am
still having problems with your suggestion.
The problem appears to be in using the line
' tmpEntry = container.Children.Find(userdn , user.Ldap_container); //Find
is case agnostic, userdn may look like cn=...'

No problems with the userdn but looking at the syntax for the Find method
the second parameter should be a schemaClassName.
container is the DirectoryEntry for a Security Group. I have tried "user"
as the schemaClassName but this does not work.
I can't see how this could work as the security group is not really a
container but it has properties one of which is 'members' that contains an
array of user names.
Am I missing something or do I need to back to my original approach and
solve the case problem

Chris
"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:%2****************@TK2MSFTNGP04.phx.gbl...
>"Chris Noble" <ch*********@newsgroup.nospamwrote in message
news:OZ**************@TK2MSFTNGP02.phx.gbl...
>>Willy

I have had a go with this but I am having a problem with the code you
provided in testing for a null instance of tmpEntry.
The line if(tmpEntry == null) will not compile without producing a 'use
of unassigned local variable' error
DirectoryEntry groupentry = parententry.Children.Find(user.Group);
String userdn = String.Format("CN={0}", user.User_logon_name);
DirectoryEntry tmpEntry;
try
{
tmpEntry = container.Children.Find(userdn , user.Ldap_container);
//Find is case agnostic, userdn may look like cn=...
}
finally
{
if(tmpEntry == null)
// no such entry found, add entry to container.
else
tmpEntry.Dispose();
}

Any suggestions

Sorry my OE compiler did not catch this one ;-).

Make it ...
...
DirectoryEntry tmpEntry = null;;
try
{
...

Willy.


Apr 20 '07 #9

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

32 posts views Thread by Elliot Temple | last post: by
761 posts views Thread by Neo-LISPer | last post: by
5 posts views Thread by Jeff S | last post: by
14 posts views Thread by Christian Sell | last post: by
15 posts views Thread by gregory_may | last post: by
reply views Thread by devrayhaan | last post: by
reply views Thread by gheharukoh7 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.