Initial import
[samba] / examples / misc / check_multiple_LDAP_entries.pl
diff --git a/examples/misc/check_multiple_LDAP_entries.pl b/examples/misc/check_multiple_LDAP_entries.pl
new file mode 100644 (file)
index 0000000..00c197a
--- /dev/null
@@ -0,0 +1,201 @@
+#!/usr/bin/perl -w
+# Guenther Deschner <gd@samba.org>
+#
+# check for multiple LDAP entries
+
+use strict;
+
+use Net::LDAP;
+use Getopt::Std;
+
+my %opts;
+
+if (!@ARGV) {
+       print "usage: $0 -h host -b base -D admindn -w password [-l]\n";
+       print "\tperforms checks for multiple sid, uid and gid-entries on your LDAP server\n";
+       print "\t-l adds additional checks against the local /etc/passwd and /etc/group file\n";
+       exit 1;
+}
+
+getopts('b:h:D:w:l', \%opts);
+
+my $host =   $opts{h}  || "localhost";
+my $suffix = $opts{b}  || die "please set base with -b";
+my $binddn = $opts{D}  || die "please set basedn with -D";
+my $bindpw = $opts{w}  || die "please set password with -w";
+my $check_local_files = $opts{l} || 0;
+
+########################
+
+
+my ($ldap, $res);
+my (%passwd_h, %group_h);
+my $bad_uids = 0;
+my $bad_gids = 0;
+my $bad_sids = 0;
+my $ret = 0;
+
+if ($check_local_files) {
+       my @uids = `cut -d ':' -f 3 /etc/passwd`;
+       my @gids = `cut -d ':' -f 3 /etc/group`;
+       foreach my $uid (@uids) {
+               chomp($uid);
+               $passwd_h{$uid} = $uid;
+       }
+
+       foreach my $gid (@gids) {
+               chomp($gid);
+               $group_h{$gid} = $gid;
+       }
+}
+
+########
+# bind #
+########
+
+$ldap = Net::LDAP->new($host, version => '3');
+
+$res = $ldap->bind( $binddn, password => $bindpw);
+$res->code && die "failed to bind: ", $res->error;
+
+
+
+###########################
+# check for double sids   #
+###########################
+
+print "\ntesting for multiple sambaSids\n";
+
+$res = $ldap->search( 
+       base => $suffix, 
+       filter => "(objectclass=sambaSamAccount)");
+
+$res->code && die "failed to search: ", $res->error;
+
+foreach my $entry ($res->all_entries) {
+
+       my $sid = $entry->get_value('sambaSid');
+
+       my $local_res = $ldap->search( 
+               base => $suffix, 
+               filter => "(&(objectclass=sambaSamAccount)(sambaSid=$sid))");
+       
+       $local_res->code && die "failed to search: ", $local_res->error;
+       if ($local_res->count > 1) {
+               print "A SambaSamAccount with sambaSid [$sid] must exactly exist once\n";
+               print "You have ", $local_res->count, " entries:\n";
+               foreach my $loc_entry ($local_res->all_entries) {
+                       printf "\t%s\n", $loc_entry->dn;
+               }
+               ++$bad_sids;
+       }
+}
+
+if ($bad_sids) {
+       $ret = -1;
+       print "You have $bad_sids bad sambaSids in your system. You might need to repair them\n";
+} else {
+       print "No multiple sambaSids found in your system\n";
+}
+
+print "-" x 80, "\n";
+
+###########################
+# check for double groups #
+###########################
+
+print "\ntesting for multiple gidNumbers\n";
+
+$res = $ldap->search( 
+       base => $suffix, 
+       filter => "(objectclass=posixGroup)");
+
+$res->code && die "failed to search: ", $res->error;
+
+foreach my $entry ($res->all_entries) {
+
+       my $gid = $entry->get_value('gidNumber');
+       my $dn  = $entry->dn;
+
+       my $local_res = $ldap->search( 
+               base => $suffix, 
+               filter => "(&(objectclass=posixGroup)(gidNumber=$gid))");
+       
+       $local_res->code && die "failed to search: ", $local_res->error;
+       if ($local_res->count > 1) {
+               print "A PosixGroup with gidNumber [$gid] must exactly exist once\n";
+               print "You have ", $local_res->count, " entries:\n";
+               foreach my $loc_entry ($local_res->all_entries) {
+                       printf "\t%s\n", $loc_entry->dn;
+               }
+               ++$bad_gids;
+               next;
+       }
+
+       if ($check_local_files && exists $group_h{$gid}) {
+               print "Warning: There is a group in /etc/group that has gidNumber [$gid] as well\n";
+               print "This entry may conflict with $dn\n";
+               ++$bad_gids;
+       }
+}
+
+if ($bad_gids) {
+       $ret = -1;
+       print "You have $bad_gids bad gidNumbers in your system. You might need to repair them\n";
+} else {
+       print "No multiple gidNumbers found in your system\n";
+}
+
+print "-" x 80, "\n";
+
+
+###########################
+# check for double users  #
+###########################
+
+print "\ntesting for multiple uidNumbers\n";
+
+$res = $ldap->search( 
+       base => $suffix, 
+       filter => "(objectclass=posixAccount)");
+
+$res->code && die "failed to search: ", $res->error;
+
+
+foreach my $entry ($res->all_entries) {
+
+       my $uid = $entry->get_value('uidNumber');
+       my $dn  = $entry->dn;
+
+       my $local_res = $ldap->search( 
+               base => $suffix, 
+               filter => "(&(objectclass=posixAccount)(uidNumber=$uid))");
+       
+       $local_res->code && die "failed to search: ", $local_res->error;
+       if ($local_res->count > 1) {
+               print "A PosixAccount with uidNumber [$uid] must exactly exist once\n";
+               print "You have ", $local_res->count, " entries:\n";
+               foreach my $loc_entry ($local_res->all_entries) {
+                       printf "\t%s\n", $loc_entry->dn;
+               }
+               ++$bad_uids;
+               next;
+       }
+       if ($check_local_files && exists $passwd_h{$uid}) {
+               print "Warning: There is a user in /etc/passwd that has uidNumber [$uid] as well\n";
+               print "This entry may conflict with $dn\n";
+               ++$bad_uids;
+       }
+}
+
+if ($bad_uids) {
+       $ret = -1;
+       print "You have $bad_uids bad uidNumbers in your system. You might need to repair them\n";
+} else {
+       print "No multiple uidNumbers found in your system\n";
+}
+
+$ldap->unbind;
+
+exit $ret;