How to retrieve all Groups from LDAP with Perl - perl

I have a Perl script wich binds to an LDAP server and retrieves all users. So far it works good but I want to filter that search in order to gather all groups. Once I have all groups the user can select one of these groups and I'll show him only users that are member of that group. How can I do those queries? I tryed this one:
my $mesg = $ldap->search(
base => $base,
filter => '(objectclass=user)',
attrs => ['memberOf']
);
But then some groups are repeated and I will have to manually filter the result (and I'd like to avoid that). And what about the second query?

cnThe filter to get all groups is "(objectclass=group)" you can retreive groups in only one organizationalUnit (scope => 'one') or in all suborganization (scope => 'sub')
$mesg = $ldap->search( filter=>"(&(objectclass=group)(cn=the group choosen by the user)",
base=>"ou=Monou,dc=societe,dc=fr"
scope=>"sub"
attrs=> ['cn', 'member']);
#entries = $mesg->entries;
foreach $entry (#entries)
{
$entry->dump;
#member = $entry->get_value("member"); # returns all members
}
For more help see An Introduction to perl-ldap
Edited
So the filter you were looking for is :
(&(objectClass=user)(memberof=CN=Mongroupe,OU=MonOU,DC=societe,DC=fr))

Use objectclass=* to get all.
my $msg = $ldap->search(base => $dn,
scope => 'one',
filter => "(objectclass=*)");
$msg->all_entries;

Related

Fetch all user information with Net::LDAP

Currently have an small perl script what for the given username fetch his email address from the ActiveDirectory using Net::LDAP.
The search part is the following:
my $user = "myuser";
my $mesg = $ldap->search(
base => "dc=some,dc=example,dc=com",
filter => '(&(sAMAccountName=' . $user . ')(mail=*))', #?!?
);
for my $entry ($mesg->entries) {
my $val = $entry->get_value('mail');
say "==$val==";
}
Working ok.
How i should modify the above statement to fetch all available information for the given user myuser? I'm looking to get an perl-ish data structure, such something like next:
my $alldata = search(... all info for the given $user ... );
say Dumper $alldata; #hashref with all stored informations for the $user
It is probably dead simple - but i'm an total AD & LDAP-dumb person...
Edit: When I dump out the $msg->entries (what is an LADP::Entry object) got something, but i'm not sure than it contains everything or only the part of the stored data...
I've done something similar, and I use this to query LDAP:
my $ldapResponse = $ldap->search(base => $base, filter => $filter, attrs => $attrs);
And then this to parse it:
if ($ldapResponse && $ldapResponse->count()) {
$ldapResponse->code && die $ldapResponse->error;
my %domainNames = %{$ldapResponse->as_struct};
foreach my $domainName (keys %domainNames) {
my %ldapResponse;
my %dnHash = %{$domainNames{$domainName}};
foreach my $attr (sort(keys %dnHash)) {
# Note that the value for each key of %dnHash is an array,
# so join it together into a string.
my $value = join(" ", #{$dnHash{$attr}});
$ldapResponse{$attr} = $value;
}
// Dump/use %ldapResponse
}
}
I've never tried to use the ldap->entries in your code, but the above works for me!
I explicitly specify a(long) list of attributes ($attr), but perhaps that's optional as your example shows, and you can get ALL LDAP fields by just skipping that arg to search().

Query Jenkins for job list using a perl script

I am not sure if this question is a duplicate or not but I cannot find any example of how one would do this. Is there any way we can query jenkins for the list of jobs. I have tried using the Jenkins::API that cpan provides but $jenkins->current_status()->jobs() returns a list of hash values. I am not sure if i am supposed to somehow translate these to readable jobs in english. Any tips??
Have a look at http://metacpan.org/pod/Jenkins::API.
$jenkins->current_status() does indeed return hash values. Each job hash contains keys 'color','name', and 'url'. But they are nested in a list at several levels. I found Data::Dumper helpful in seeing the full structure.
current_status
Returns the current status of the server as returned by the API. This is a hash containing a fairly comprehensive list of what's going on.
$jenkins->current_status();
# {
# 'assignedLabels' => [
# {}
# ],
# 'description' => undef,
# 'jobs' => [
# {
# 'color' => 'blue',
# 'name' => 'Jenkins-API',
# 'url' => 'http://jenkins:8080/job/Jenkins-API/'
# },
# ...
# ]
Example:
use Jenkins::API;
$jenkins = Jenkins::API->new({ base_url => 'http://localhost:8080' });
#statuses = $jenkins->current_status();
for ($i = 0;$i <= $#{$statuses[0]{'jobs'}};$i++) {
print $statuses[0]{'jobs'}[$i]{'name'},"\n";
}

Perl LDAP search for user being a CN attribute

How to do a Perl LDAP search/authentication for user being an attribute in access group or it's subgroups?
All users (UIDs) are in:
ou=Users,o=company,c=com
Access group is:
cn=Site Full Access,ou=Access,o=company,c=com
Access group has users and subgroups as attributes like:
uniquemember | uid=usernameA,ou=Users,o=company,c=com
uniquemember | uid=usernameB,ou=Users,o=company,c=com
uniquemember | uid=usernameC,ou=Users,o=company,c=com
uniquemember | cn=Site Full Access Employees,ou=Access,o=company,c=com
(subgroup has its own uniquemember attributes)
Authentication script idea:
Bind user with his login/password (done).
If successful, create user's DN like uid=$username,ou=Users,o=company,c=com (done)
Iterate through attributes of cn=Site Full Access,ou=Access,o=company,c=com and compare them to user's DN
If encountered a group, search for user's DN inside this group too
I am using Net::LDAP, but there is not much code to show as what works is quite standard. This is the listing of uniquemember attributes:
my $mesg = $ldap->bind ($user_dn, password=>"$pass");
$mesg->code && return undef;
$mesg = $ldap->search(base=>$ldap_access_full, filter=>"(objectclass=*)");
$mesg->code && return undef;
my #entries = $mesg->entries;
my $entry;
foreach $entry ( #entries )
{
if ($entry->exists('uniquemember'))
{
my $ref = $entr->get_value('uniquemember', asref=>1);
for my $uid (#$ref)
{
print $uid . "<br/>";
}
}
}
This gives me an array of user DNs but also groups that will have to be listed and compared in some recursive function.
How do I approach this? Perhaps there is another way to check both password and access group, with user still being an attribute of access group or it's subgroups? I can't do any LDAP modifications.
This called nested groups. For AD here is one solution: How to retrieve all Groups from LDAP with Perl
One solution is to ignore groups, only allow direct user objects.
If you need to process sub groups you should retrieve the entry and check it is a group or people. In case you need to check this in many levels (sub groups of sub groups of..) then you needs to do the check recursivly.
For one level of nested groups. It is half complete and not tested but you got the idea.
Of course use subroutines, but I did not used for easier understanding (and lack of time)
$mesg = $ldap->search(base=>$ldap_access_full, filter=>"(objectclass=*)",attrs => [qw(uniquemember)]);
$mesg->code && die $mesg->code;
my #entries = $mesg->entries;
my $entry;
foreach $entry ( #entries ) {
my #uniquemembers = $entr->get_value('uniquemember');
foreach my $uniquemember (#uniquemembers){
#get entry
$mesg = $ldap->search(base=>$uniquemember, filter=>"(objectclass=*)", attrs => [qw(objectclass uid uniquemember)], scope => 'base');
$mesg->code && die $mesg->code;
#if is a group or user?
my $uniquemember_entry = ($mesg->entries)[0];
my #objectclasses = $uniquemember_entry->get_value('objectclass');
my $uid = $uniquemember_entry->get_value('uid');
if (grep {/user/i} #objectclasses || defined $uid){
print "$uniquemember has uid: $uid\n";
} elsif (grep {/group/i} #objectclasses){
print "it is a group: $uniquemember\n";
#get its members
my #nested_group_uniquemembers = $uniquemember_entry->get_value('uniquemember');
#get entries
foreach my $nested_group_uniquemember (#nested_group_uniquemembers){
$mesg = $ldap->search(base=>$nested_group_uniquemember, filter=>"(objectclass=*)", attrs => [qw(objectclass uid uniquemember)], scope => 'base');
$mesg->code && die $mesg->code;
}
#check it is an user or group...
} else {
}
}
}

Rose::DB::Object::Manager query with a list of object ids

I'm trying to write a Rose::DB::Object query string using either an Array or a Hash, however I'm unsure how to do it. I'm trying to write an update function based off of certain ID's in a list that are enumerated in the array. I unfortunately do not have any other unique key to filter on to build the query, so I need to query specific ID's.
Essentially I am trying to programatically write the follow:
my $list = My::DB::Manager->get_items(query => [
{id => 1},
{id => 14},
{id => 210},
{id => 1102},
{id => 3151},
]);
This is the code I have so far, but I haven't been able to successfully achieve what I am trying to do:
use My::DB::Manager;
my #ary;
foreach (#_) {
my %col = ("id", $_);
push (#ary, \%col);
}
my $list = My::DB::Manager->get_items(query => \#ary);
...
./test.pl
Now the script just hangs with no output indefinately.
I'm trying to avoid iterating through the DB::Manager and making a DB call on a per record basis as this script will be run via cron every 60 seconds and has the potential to return large sets.
The query parameter takes a reference to an array of name/value pairs, not a reference to an array of hash references. If you want objects where the value of the id column is one of a list of values, then use the name id and a reference to an array of ids as the value. This code should work (assuming the id values are in #_):
$list = My::DB::Manager->get_items(query => [ id => \#_ ]);
You push strings into #ary when you need to push perl structures:
use My::DB::Manager;
my #ary;
foreach (#_) {
push (#ary, { id => $_ });
}
my $list = My::DB::Manager->get_items(query => [#ary]);
...
However, I think you can use query => [ id => [$id1, $id2, ... ], ...]:
use My::DB::Manager;
my $list = My::DB::Manager->get_items(query => [ id => \#_ ]);
...
Never used Rose, this based on docs of the module.

How to list OU's in an OU?

I would like to output all the OU's that are in the test OU.
my $mesg = $ldap->search(
base => "OU=test,OU=company,DC=example,DC=com",
scope => 'sub',
filter => '(objectClass=*)',
attrs => ['*'],
);
print Dumper $mesg->entry;
When I do the search like so, I only get information about the test OU, and not which OU's it contain.
Any ideas how to do that?
$mesg will have array of entries. You are trying to print the first entry from the search result.
Try,
print Dumper $mesg
also change your filter to
filter => '(objectClass=organizationalUnit)'
ldapsearch start the search from the base dn and including basedn. Here OU=test,OU=company,DC=example,DC=com is also organizationalunit so this entry is coming as a first entry in the result for you and you are printing only that.