Tim S.
Tim S.

Reputation: 2257

Group membership of a specific user in Perl using Net::LDAPS

I've been searching various sites for some help on this, but not getting very far. My goal is to check group membership once a login is successful. The login part works fine, but I want to get a list of groups of the logged in user to compare it to a particular one. If they are not a member of that group, they are logged out, the session is deleted and they are returned to the login page, otherwise they can continue.

Here is the code:

my $base = "ou=Groups,ou=Services,dc=example,cd=com";
my $mesg = $ldap->search(
                         filter=>"(uid=$userid)",
                         base=>"$base",
                         scope=>'children',
    );

my @entries = $mesg->entries;

print("mesg = <BR>");
print(Dumper($mesg));

And here is the output of $mesg:

$VAR1 = bless( {
    'parent' => bless( {
        'net_ldap_version' => 3,
        'net_ldap_scheme' => 'ldaps',
        'net_ldap_debug' => 0,
        'net_ldap_socket' => bless( \*Symbol::GEN0, 'IO::Socket::SSL' ),
        'net_ldap_host' => 'ldap.example.com',
        'net_ldap_uri' => 'ldap.example.com',
        'net_ldap_resp' => {},
        'net_ldap_mesg' => {},
        'net_ldap_async' => 0,
        'net_ldap_port' => '636',
        'net_ldap_refcnt' => 1
    }, 'Net::LDAPS' ),
   'errorMessage' => 'NDS error: no such entry (-601)',
   'ctrl_hash' => undef,
   'resultCode' => 32,
   'callback' => undef,
   'mesgid' => 2,
   'matchedDN' => '',
   'controls' => undef,
   'raw' => undef
}, 'Net::LDAP::Search' ); 

I can see the NDS message that says there's no such entry, so I'm assuming my search query is where the error lies, but the mistake is escaping me. Any suggestions? I've also tried without the scope=>'children' line, without any change.

Thanks.

Update:

This is what I ended up doing, and was successful.. had to tweak one of the other person's answers a bit, but ended up getting what I was looking for.

my $mesg = $ldap->search(
    filter=>"(&(objectClass=group)(memberUid=$userid)(member=$userdn))",
    base=>"$base",
    scope=>'subtree',
    attrs=>[qw(memberUid)],
 );

my $searchresults = $mesg->as_struct;                                                                      
my %searchhash = %$searchresults;       # dereference the hash

my @members = @ { $searchhash{$base}{memberuid} };   # pick out just the memberuid array from the hash

Then I basically iterated over the users in that group (@members) and if the logged in user was in there, they were authenticated, if not, their session info got deleted and the script exited.

Not exactly the same answer as was given below, but we don't have uniquemember in our tree. Either way, hope this helps someone.

Upvotes: 3

Views: 1284

Answers (1)

Dave Bennett
Dave Bennett

Reputation: 11216

When you log the user in I presume you are performing a successful bind with their distinguished name.

I would search for the user in the group instead of searching for all of the users groups and looking for the specific group. I am also presuming that you are using the groupOfUniqueNames group objectclass to group your users. I would do something like this...

# assuming you already have this value in a variable from the authN step
my $user_dn = "cn=dave,ou=people,dc=example,dc=com"

my $base = "cn=GroupToCheck,ou=Groups,ou=Services,dc=example,cd=com";
my $mesg = $ldap->search(
                         filter=>"(uniquemember=$user_dn)",
                         base=>"$base",
                         scope=>'base'
);

If you get a result then the user is in the group. If you don't get any results then the user is not in the group.


If you really do want to get all of the groups though then this will return the group name from all of the group(s) for which the user is a member.

# assuming you already have this value in a variable from the authN step
my $user_dn = "cn=dave,ou=people,dc=example,dc=com"

my $base = "ou=Groups,ou=Services,dc=example,cd=com";
my $mesg = $ldap->search(
                         filter=>"(uniquemember=$user_dn)",
                         base=>"$base",
                         scope=>'sub',
                         attrs => ['cn']
);

Upvotes: 4

Related Questions