use Date::Parse qw(str2time);
use File::Basename qw(basename);
use Getopt::Long qw(GetOptions :config bundling no_ignore_case);
+use Perl6::Slurp qw(slurp);
##############################################################################
# User filtering
# Check various filter rules.
if ($filter_ref->{disabled} && $disabled) {
return;
- } elsif ($filter_ref->{expired} && $expires > 0 && $expires < time) {
- return;
- } elsif ($filter_ref->{'last-change'} > 0) {
+ }
+ if ($filter_ref->{expired} > 0) {
+ if ($expires > 0 && $expires < $filter_ref->{expired}) {
+ return;
+ }
+ }
+ if ($filter_ref->{'last-change'} > 0) {
if ($lastchange > $filter_ref->{'last-change'}) {
return;
}
local $0 = basename($0);
# Parse command-line options.
+my %config;
my @options = qw(
- disabled|d exclude|x=s expired|e
- help|h last-change|l=s realm|r=s
+ disabled|d exclude|x=s expired|e=s help|h
+ last-change|l=s principals|p=s realm|r=s
);
-my %config;
if (!GetOptions(\%config, @options)) {
exit(1);
}
die "Usage: $0 -l <last-change-date> -r <realm>\n";
}
+# Parse the expiration cutoff date.
+if ($config{expired}) {
+ my $expired = str2time($config{expired});
+ if (!defined($expired)) {
+ die "$0: cannot parse time specification '$config{expired}'\n";
+ }
+ $config{expired} = $expired;
+}
+
# Parse the last changed date.
my $lastchange = str2time($config{'last-change'});
if (!defined($lastchange)) {
};
my $kadmin = Authen::Kerberos::Kadmin->new($options);
-# Retrieve a list of all principals.
-my @principals = $kadmin->list(q{*});
+# Retrieve the list of principals.
+my @principals;
+if ($config{principals}) {
+ @principals = slurp($config{principals}, { chomp => 1 });
+} else {
+ @principals = $kadmin->list(q{*});
+}
# Filter the principals against the configuration and output the ones that
# pass through the filter.
=head1 SYNOPSIS
-B<password-change-report> [B<-deh>] [B<-x> I<exclude-pattern>]
- B<-l> I<last-change> B<-r> I<realm>
+B<password-change-report> [B<-dh>] [B<-x> I<exclude-pattern>]
+ [B<-p> I<principals-file>] [B<-e> I<expiration-cutoff>]
+ B<-l> I<last-change> B<-r> I<realm>
=head1 REQUIREMENTS
all service principals with random keys might be C<-x />, which excludes
all principals containing a C</> in the name.
-=item B<-e>, B<--expired>
+=item B<-e> I<date>, B<--expired>=I<date>
-Exclude all principals with expired passwords.
+Exclude all principals with passwords that expire before the given date.
+If I<date> is the current time, this will exclude all principals with
+expired passwords. This only checks the password expiration, not any
+expiration date on the principal itself.
=item B<-h>, B<--help>
Print out this documentation (which is done simply by feeding the script
to C<perldoc -t>).
-=item B<-l> I<date>, B<--last-change> I<date>
+=item B<-l> I<date>, B<--last-change>=I<date>
Exclude all principals whose keys were changed after I<date>, where
I<date> is a date and time in some format that Date::Parse can understand.
This option is required.
-=item B<-r> I<realm>, B<--realm> I<realm>
+=item B<-p> I<file>, B<--principals>=I<file>
+
+Rather than scanning the entire contents of the Kerberos KDC database for
+that realm, read the list of principals to check from I<file>. The file
+should contain one principal per line.
+
+=item B<-r> I<realm>, B<--realm>=I<realm>
The realm of principals to report on.