Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

file 293 lines (203 sloc) 6.555 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
#!/usr/local/bin/perl

#printMembers.pl
#given the name of a group (assume object class is groupOfUniqueNames) will
#display the members of the group including members of any groups that may be a member
#of the original group

#*Now Handles Netscape Dynamic Groups*
#
#By default it will display the DN of the member entries, you can specify a particular
#attribute you wish to display instead (e.g. mail attribute)

#example: printMembers.pl -n "Accounting Managers"


#optionally you can also specify the host, port, binded search and search base.

#Mark Wilcox mark@mjwilcox.com
#
#first version: August 8, 1999
#second version: August 15, 1999

use strict;
use Carp;
use Net::LDAP;
use URI;
use vars qw($opt_h $opt_p $opt_D $opt_w $opt_b $opt_n $opt_a );
use Getopt::Std;

my $usage = "usage: $0 [-hpDwba] -n group_name";

die $usage unless @ARGV;

getopts('h:p:D:w:b:n:a:');

die $usage unless ($opt_n);


my $DEBUG = 0; #DEBUG 1 if you want debugging info
#get configuration setup
$opt_h = "airwolf" unless $opt_h;
$opt_p = 389 unless $opt_p;
$opt_b = "o=airius.com" unless $opt_b;


my $isGroup = 0; #checks for group or not

my $ldap = new Net::LDAP ($opt_h, port=> $opt_p);

#will bind as specific user if specified else will be binded anonymously
$ldap->bind(DN => $opt_D, password=> $opt_p) || die "failed to bind as $opt_D";


#get the group DN
my @attrs = ['dn'];
eval
{
   my $mesg = $ldap->search(
               base => $opt_b,
filter => "(&(cn=$opt_n)(objectclass=groupOfUniqueNames))",
attrs => @attrs
);

   die $mesg->error if $mesg->code;

   my $entry = $mesg->pop_entry();

   my $groupDN = $entry->dn();

   &printMembers($groupDN,$opt_a);
   $isGroup = 1;
};

print "$opt_n is not a group" unless ($isGroup);

$ldap->unbind();


sub printMembers
{
  my ($dn,$attr) = @_;

  my @attrs = ["uniquemember","memberurl"];

  my $mesg = $ldap->search(
               base => $dn,
scope => 'base',
filter => "objectclass=*",
attrs => @attrs
);

  die $mesg->error if $mesg->code;

  #eval protects us if nothing is returned in the search

  eval
  {

     #should only be 1 entry
     my $entry = $mesg->pop_entry();

     print "\nMembers of group: $dn\n";

     #returns an array reference
     my $values = $entry->get("uniquemember");

     foreach my $val (@{$values})
     {
       my $isGroup = 0; #lets us know if the entry is also a group, default no

       #change val variable to attribute

       #now get entry of each member
       #is a bit more efficient since we use the DN of the member
       #as our search base, greatly reducing the number of entries we
       #must search through for a match to 1 :)

       my @entryAttrs = ["objectclass","memberurl",$attr];

       $mesg = $ldap->search(
               base => $val,
scope => 'base',
filter => "objectclass=*",
attrs => @entryAttrs
);

      die $mesg->error if $mesg->code;

      eval
     {
        my $entry = $mesg->pop_entry();


        if ($attr)
{
          my $values = $entry->get($attr);

           foreach my $vals (@{$values})
           {
             print $vals,"\n";
           }
}
        else
{
           print "$val\n";
}

        my $values = $entry->get("objectclass");

        # This value is also a group, print the members of it as well


        &printMembers($entry->dn(),$attr) if (grep /groupOfUniqueNames/i, @{$values});
     };
   }
        my $urls = $entry->get("memberurl");
&printDynamicMembers($entry->dn(),$urls,$attr) if ($urls);
 };
    return 0;
  }



#prints out a search results
#for members of dynamic group (as supported by the Netscape Directory Server)

#*Note this may or may not return all of the resulting members and their attribute values
#depending on how the LDAP connection is binded. Normally users who are not binded as the Directory Manager
#are restricted to 2000 or less total search results.

#In theory a dynamic group could have a million or more entries
sub printDynamicMembers
{
   my ($entryDN,$urls,$attr) = @_;

   print "\nMembers of dynamic group: $entryDN\n";


   foreach my $url (@{$urls})
   {
     print "url is $url\n" if $DEBUG;
     my $uri;
     eval
     {
      $uri = URI->new($url);
     } ;

     print "ref ",ref($uri),"\n" if $DEBUG;

     my $base = $uri->dn();

     print "base is $base\n" if $DEBUG;
     my $scope = $uri->scope();

     my $filter = $uri->filter();

     my @attrs = [$attr];

     my $mesg = $ldap->search(
               base => $base,
scope => $scope,
filter => $filter,
attrs => @attrs
);
 
     #print results

     my $entry;
     while ($entry = $mesg->pop_entry())
     {

        if ($attr)
{
          my $values = $entry->get($attr);

           foreach my $vals (@{$values})
           {
             print $vals,"\n";
           }
}
        else
{
           print $entry->dn(),"\n";
}
     }

    }
  return 0;
}



=head1 NAME

printMembers.pl


=head1 DESCRIPTION

Prints out the members of a given group, including members of groups that are also members of the given group.

Defaults to printing out members by DN, but you can specify other attributes for display

=head1 USAGE

perl printMembers.pl -n "Accounting Managers"

Members of group: cn=Accounting Managers,ou=groups,o=airius.com
uid=scarter, ou=People, o=airius.com
uid=tmorris, ou=People, o=airius.com
cn=HR Managers,ou=groups,o=airius.com

Members of group: cn=HR Managers,ou=groups,o=airius.com
uid=kvaughan, ou=People, o=airius.com
uid=cschmith, ou=People, o=airius.com
cn=PD Managers,ou=groups,o=airius.com

Members of group: cn=PD Managers,ou=groups,o=airius.com
uid=kwinters, ou=People, o=airius.com
uid=trigden, ou=People, o=airius.com

Here's an example of the same group but instead print the cn attribute
of each entry:

Members of group: cn=Accounting Managers,ou=groups,o=airius.com
Sam Carter
Ted Morris
HR Managers

Members of group: cn=HR Managers,ou=groups,o=airius.com
Kirsten Vaughan
Chris Schmith
PD Managers

Members of group: cn=PD Managers,ou=groups,o=airius.com
Kelly Winters
Torrey Rigden

And same group but with the mail attribute:

Members of group: cn=Accounting Managers,ou=groups,o=airius.com
scarter@airius.com
tmorris@airius.com

Members of group: cn=HR Managers,ou=groups,o=airius.com
kvaughan@airius.com
cschmith@airius.com

Members of group: cn=PD Managers,ou=groups,o=airius.com
kwinters@airius.com
trigden@airius.com

=cut
Something went wrong with that request. Please try again.