128 lines
2.2 KiB
Perl
Executable File
128 lines
2.2 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
# SPDX-License-Identifier: MIT
|
|
#
|
|
# Check for multi-value attributes in LDIF file
|
|
# written by Jan Engelhardt, 2015
|
|
#
|
|
use strict;
|
|
use warnings;
|
|
use Getopt::Long;
|
|
|
|
our @wl = qw(
|
|
ACL objectClass member equivalentToMe DirXML-Associations
|
|
groupMembership securityEquals DirXML-PasswordSyncStatus
|
|
zarafaSendAsPrivilege zarafaAliases
|
|
departmentNumber
|
|
);
|
|
our $do_color = -t 1;
|
|
|
|
&main();
|
|
|
|
sub main
|
|
{
|
|
&Getopt::Long::Configure(qw(bundling));
|
|
&GetOptions(
|
|
"C" => \$do_color,
|
|
);
|
|
|
|
my $attrcount = &parse_ldif();
|
|
&print_stats($attrcount);
|
|
}
|
|
|
|
sub parse_ldif
|
|
{
|
|
my $dn;
|
|
my $attrcount = {};
|
|
|
|
while (defined(my $line = <STDIN>)) {
|
|
chomp($line);
|
|
if (substr($line, 0, 1) eq "#") {
|
|
next;
|
|
}
|
|
if ($line =~ /^dn:\s*/) {
|
|
$dn = $';
|
|
$attrcount->{$dn} = {};
|
|
}
|
|
my($key, $value) = &parse_line($line);
|
|
if (!defined($key) || &whitelisted($key)) {
|
|
# Blank lines and other unparsable lines get filtered
|
|
# here.
|
|
next;
|
|
}
|
|
++$attrcount->{$dn}->{$key};
|
|
}
|
|
close(STDIN);
|
|
return $attrcount;
|
|
}
|
|
|
|
sub parse_line
|
|
{
|
|
return (shift(@_) =~ /^([^:]+):+(?:\s*)?(.*)/);
|
|
}
|
|
|
|
sub whitelisted
|
|
{
|
|
my $needle = shift @_;
|
|
return scalar grep { $_ eq $needle } @wl;
|
|
}
|
|
|
|
sub print_stats
|
|
{
|
|
my $attrcount = shift @_;
|
|
my $dncount = {};
|
|
my $crapdn;
|
|
my $globattr = {};
|
|
|
|
foreach my $dn (keys %$attrcount) {
|
|
my $count = 0;
|
|
my $dh = $attrcount->{$dn};
|
|
|
|
foreach my $key (keys %$dh) {
|
|
if ($dh->{$key} < 2) {
|
|
next;
|
|
}
|
|
$count += $dh->{$key};
|
|
}
|
|
$dncount->{$dn} = $count;
|
|
}
|
|
|
|
foreach my $dn (sort { $dncount->{$b} <=> $dncount->{$a} }
|
|
keys %$dncount)
|
|
{
|
|
my $dh = $attrcount->{$dn};
|
|
|
|
if ($dncount->{$dn} == 0) {
|
|
next;
|
|
}
|
|
|
|
if ($do_color) {
|
|
print "\e[1;31m";
|
|
}
|
|
print $dncount->{$dn};
|
|
if ($do_color) {
|
|
print "\e[0;31m";
|
|
}
|
|
print "\t$dn\n";
|
|
print "\t";
|
|
foreach my $key (sort {
|
|
$dh->{$b} <=> $dh->{$a} || $a cmp $b }
|
|
keys %$dh)
|
|
{
|
|
if ($dh->{$key} < 2) {
|
|
next;
|
|
}
|
|
if ($do_color) {
|
|
print "\e[32m", substr($key, 0, 1), "\e[0m",
|
|
substr($key, 1);
|
|
} else {
|
|
print $key;
|
|
}
|
|
print "(", $attrcount->{$dn}->{$key}, ") ";
|
|
$globattr->{$dn} += $dh->{$key};
|
|
}
|
|
print "\n\n";
|
|
++$crapdn;
|
|
}
|
|
print $crapdn, " DNs\n";
|
|
}
|