jp2code Absent Member.
Absent Member.
1177 views

eDir - How to Get User Groups?

Hi. We are a software shop that uses Active Directory to validate our users.

Recently, one of our Salesman sold our product to a company that only has Novell's eDirectory.

I am struggling to authenticate users on their product. I have been told not to use the Novell wrapper because they do not want that in their product. Instead, I am using System.DirectoryServices.Protocols, which still works on our Windows Forms applications and is usable in our Visual Studio 2015 project.

I don't have a way to debug the code on the Novell system. It has been recommended to me to use a Novell virtual machine. I tried creating one, but I don't know enough about Novell to even get this done. So, instead, I build something, FTP it to one of their IT guys, he executes the code, and he gets back with me on whether or not it worked.

The following bit of code (with my debug helping "steps") works to verify that a given user (specified by the Windows NTAccount, their Organizational Unit and something called O).


private String distinguishedName = String.Format("cn={0},ou={1},o={2}", NTAccount, objSDSP.OU, objSDSP.O);
private String filter = "(objectClass=*)";

private static SearchResponse Query(String distinguishedName, String filter, out String error)
{
SearchResponse result = null;
int step = 1;
error = String.Format("SDSP::Query Parameters: distinguishedName = [{0}]; ", distinguishedName);
var certPath = SdspData.CertificatePath;
if (File.Exists(certPath))
{
step = 2;
var server = GetHostName(SdspData.ServerIP);
step = 3;
var fullyQualifiedDnsHostname = (server.ToArray().Count(x => x == '.') == 2);
step = 4;
var identifier = new LdapDirectoryIdentifier(server, fullyQualifiedDnsHostname, false);
step = 5;
try
{
using (var connection = new LdapConnection(identifier))
{
step = 6;
connection.SessionOptions.ProtocolVersion = 3;
var cert = new X509Certificate();
step = 7;
cert.Import(certPath, SdspData.CertificatePwd, X509KeyStorageFlags.DefaultKeySet);
step = 8;
connection.ClientCertificates.Add(cert);
step = 9;
connection.AuthType = AuthType.External;
connection.AutoBind = false;
var request = new SearchRequest()
{
Filter = filter, //The type of entry we are looking for
Scope = System.DirectoryServices.Protocols.SearchScope.Subtree, //We want all entries below this ou
};
if (filter.IndexOf("uid=") == -1)
{
request.DistinguishedName = distinguishedName; //Find this person
}
step = 10;
result = (SearchResponse)connection.SendRequest(request); //Run the query and get results
step = 11;
}
} catch (System.DirectoryServices.Protocols.DirectoryOperationException err)
{
error = String.Format("SDSP::Query DirectoryOperationException (user = '{0}', step = '{1}'): {2}", distinguishedName, step, err.Message);
}
catch (Exception err)
{
error = String.Format("SDSP::Query {0} (step {1}): {2}", err.GetType(), step, err.Message);
}
}
else
{
error = "The application was unable to locate the Security Cryptography Certificate at the path specified in the configuration file.\r\n" +
"\r\n" +
"Operator membership cannot be validated without this certificate.\r\n" +
"\r\n" +
"This application will now exit.";
}
return result;
}


What I need help with is a way to modify distinguishedName and filter so that I can determine what Groups in eDirectory that the NTAccount is a member of.

Is there a way to do that?

Would it be simple enough to show me how to provide those 2 parameters?

Is there any other information that I need to provide?
Labels (1)
0 Likes
5 Replies
Knowledge Partner Knowledge Partner
Knowledge Partner

Re: eDir - How to Get User Groups?

What output do you get? Your eDirectory contact should be able to get you
some trace information from ndstrace, which would probably give you great
output in just a couple seconds. If they run this on their eDirectory box
(presumably Linux), it will help:


ldapconfig set 'LDAP Screen Level=all' #turn on more LDAP logging

ndstrace #load ndstrace for the actual tracing, then run these commands
set dstrace=nodebug
dstrace +time +tags +ldap
dstrace file on
set dstrace=*r
#perform test here with your application
dstrace file off
quit


Get the (by default) /var/opt/novell/eDirectory/log/ndstrace.log file and
post its contents here. It should show the connection attempt through the
search results (if applicable).

Otherwise, where in your code does it fail? Before or after the search?

eDirectory is an LDAPv3-compliance directory, just like most other things
(ApacheDS, OpenLADP, Ping DS, etc.) and therefore it plays by RFC-approved
LDAP rules. To make a connection you need a distinguished name (DN) which
you have, a target address, port, and then to probably supply a password.
Also, by default you must use encryption, either via a StartTLS extension
(similar to SMTP's StartTlS option) prior to the bind (authentication)
which is part of the LDAP spec, or else using TLS for the whole connection
(similar to how TLS/SSL is used for a web browser connection to any old
website).

If the client is a well-behaved client, it needs to trust the TLS/SSL
certificate in order to complete the TLS/SSL handshake, else you'll
usually get some kind of error. If you try to bind to eDirectory without
using encryption, it will usually return an LDAP 13 (Confidentiality
Required) error, which your client would see, as would the server logs
captured above.

O stands for and is the naming attribute for, Organization, the same way
that OU stands for Organizational Unit and CN stands for Common Name.
Even microsoft active directory (MAD) uses Os, but they do not let you
create them as far as I know, but htat's a limit of an inferior product.
They also force you to use DNS to make a domain at all, which is
ludicrous, but off-topic.

I think your comment on your step debugging lines may have been cut off;
the steps work to verify that a given user.... what? Was specified when
calling the program? Was able to bind? Was able to kick off a search?

An LDAP search usually has a base DN (context from which to search, a
scope (subtree, one-level, base, etc.) and a filter ('objectClass=*' in
your case). If not specified, the language may default, usually to a null
base (search everything), and a subtree scope (search everywhere from the
base), and the same filter you specified.

Group memberships are pretty standard, though the attribute names may
differ from one application to another. On the user side you have
groupmembership (MAD has memberOf, I think) and on the group side you have
'member'. To look to see if a user is a member of a particular group you
should, for max efficiency, specify either the user or the group as the
base DN, and then search for an attribute value of the other object, e.g.
specify group as base DN, and search for user in 'member', or specify user
as base DN and search for group as value in groupMembership. Either way,
if you get any objects back, you know it is a member, else it is not. You
could also, rather than using a search, use a compare operation, which
would then ideally return 'TRUE' or 'FALSE' back to you, and then you're
done without a lot of wasted bandwidth or time "searching". I presume
microsoft's APIs provide a way to do this like all others, but I do not
use them, so I'll let you Google for that if needed.

The more output you can provide, lots of debugging lines from your program
showing progress, or the ndstrace output mentioned above, the better we
can help.


--
Good luck.

If you find this post helpful and are logged into the web interface,
show your appreciation and click on the star below.

If you want to send me a private message, please let me know in the
forum as I do not use the web interface often.
jp2code Absent Member.
Absent Member.

Re: eDir - How to Get User Groups?

> What output do you get?

I was getting a null reference exception with step = 10, so the SendRequest didn't like the parameters I was providing.

In your question, it seems I should have proof read my question a little closer.

This line of text:
original wrote:
The following bit of code (with my debug helping "steps") works to verify that a given user (specified by the Windows NTAccount, their Organizational Unit and something called O).


Should have read:
correct wrote:
The following bit of code (with my debug helping "steps") works to verify a given user (specified by the Windows NTAccount, their Organizational Unit and something called O).


Or, it could have been written:
alternate wrote:
The following bit of code (with my debug helping "steps") works to verify that a given user (specified by the Windows NTAccount, their Organizational Unit and something called O) exists.


Sorry about that one! Basically, my first call to Query (which verified a User exists) was successful; the second call (to get group memberships) was not.

I sent the request to the company for the ndtrace, but I also lucked onto a configuration that they say is working.

private String distinguishedName = null;
private String filter = String.Format("(&(objectClass=user)(uid={0}))", NTAccount);


Since I stumbled upon something that is working for them, it is likely that I will not hear back until they have another problem.
0 Likes
Knowledge Partner Knowledge Partner
Knowledge Partner

Re: eDir - How to Get User Groups?

On 08/17/2018 03:54 PM, jp2code wrote:
>
>> What output do you get?

>
> I was getting a null reference exception with step = 10, so the
> *SendRequest* didn't like the parameters I was providing.
>
> Sorry about that one! Basically, my first call to Query (which verified
> a User exists) was successful; the second call (to get group
> memberships) was not.
>
> I sent the request to the company for the *ndtrace*, but I also lucked
> onto a configuration that they say is working.
>
> Code:
> --------------------
> private String distinguishedName = null;
> private String filter = String.Format("(&(objectClass=user)(uid={0}))", NTAccount);
> --------------------


That can work, though anything using LDAP should probably understand the
RFC-defined inetOrgPerson class rather than an alias like "User" which is
sometimes used underneath. Also, it would probably be better to use cn=
rather than uid= since cn is the mandatory attribute on a user and uid,
while usually there and usually the same (in eDirectory), is an optional.

> Since I stumbled upon something that is working for them, it is likely
> that I will not hear back until they have another problem.


I think at the end of the day the fewer assumptions, and particularly
assumptions that do not align with the RFCs, you can make the better any
software will be. If you do not not have access to the user's DN
directly, then searching for it makes sense, and usually that can be done
most-reliably by having a zero-length string as a base DN and then
searching for the naming attribute and value, or some other
uniquely-identifying attribute and its value. That s more or less what
you are doing with uid=username so that's a start. Some directories may
require you to specify a base DN, and that can usually be fetched
automatically by you via what is known as a "naming context" an dis
available at the base of a directory automatically too from the RootDSE.
There may be multiples of these, so you can query for them and iterate
over them searching for results from your filter string to avoid making
your users do a lot of upfront configuration of your application for their
environment.


--
Good luck.

If you find this post helpful and are logged into the web interface,
show your appreciation and click on the star below.

If you want to send me a private message, please let me know in the
forum as I do not use the web interface often.
0 Likes
cpedersen Outstanding Contributor.
Outstanding Contributor.

Re: eDir - How to Get User Groups?

On 17.08.18 23:54, jp2code wrote:
>
>> What output do you get?

>
> I was getting a null reference exception with step = 10, so the
> *SendRequest* didn't like the parameters I was providing.
>
> In your question, it seems I should have proof read my question a little
> closer.
>
> This line of text:
> original Wrote:
>> The following bit of code (with my debug helping "steps") works to
>> verify *that* a given user (specified by the Windows NTAccount, their
>> Organizational Unit and something called O).

>
> Should have read:
> correct Wrote:
>> The following bit of code (with my debug helping "steps") works to
>> verify a given user (specified by the Windows NTAccount, their
>> Organizational Unit and something called O).

>
> Or, it could have been written:
> alternate Wrote:
>> The following bit of code (with my debug helping "steps") works to
>> verify *that* a given user (specified by the Windows NTAccount, their
>> Organizational Unit and something called O) *exists*.

>
> Sorry about that one! Basically, my first call to Query (which verified
> a User exists) was successful; the second call (to get group
> memberships) was not.
>
> I sent the request to the company for the *ndtrace*, but I also lucked
> onto a configuration that they say is working.
>
>
> Code:
> --------------------
> private String distinguishedName = null;
> private String filter = String.Format("(&(objectClass=user)(uid={0}))", NTAccount);
> --------------------
>
>
> Since I stumbled upon something that is working for them, it is likely
> that I will not hear back until they have another problem.
>
>


One thing I was wondering was; have you tried using 'ldapsearch' to see
if you can get what you want with that. The filters from 'ldapsearch'
are more or less 1:1 with any LDAP API I have seen until now.


Casper
0 Likes
Knowledge Partner
Knowledge Partner

Re: eDir - How to Get User Groups?

eDirectory give you much more options to troubleshoot LDAP call.
Aaron already provided pretty good explanation how to enable LDAP trace in dstrace file.
With some limitations (size limitations), you can use iMonitor for the same purpose.

What I need help with is a way to modify distinguishedName and filter so that I can determine what Groups in eDirectory that the NTAccount is a member of.

If you looking for information about standard LDAP Groups in eDirectory - it can include standard user object (inetOrgPerson class).
What is your schema defenition for NTAccount?
Is it schema extension in your eDirectory? (I'm not aware about NTAccount class in standard eDirectory.
0 Likes
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.