Re: Searching for entries with expired ppolicy controlled passwords
[email protected] (Nick Urbanik) Fri, 2 Dec 2011 10:40:22 +1100
| Newsgroups | perl.ldap |
|---|---|
| Message-ID | <[email protected]> |
Dear Chris,
On 01/12/11 07:12 +0000, Chris Ridd wrote:
>
>On 30 Nov 2011, at 22:21, Nick Urbanik wrote:
>
>> Dear Folks,
>>
>> I am writing Perl software to manage our OpenLDAP cluster using the
>> slapo.ppolicy overlay to manage password policy. I'm hoping to get
>> this into production very soon.
>>
>> My problem: how to efficiently search for users who have expired?
>>
>> I have seen the code written by Buchan Milne at
>> http://staff.telkomsa.net/~bgmilne/ldap/, but he is munging with the
>> operational attributes directly. The code I've written so far has
>> mostly avoided working with these directly; I've been using
>> Net::LDAP::Control::PasswordPolicy so far, and am trying to understand
>> how to construct a suitable filter using this control.
>>
>> Can anyone point me in the right direction?
>
>The PP control is very much meant for telling a user about *his*
>password status. If you combined it with proxy auth, you could
>imagine writing something that iterated through every user, and did
>some kind of operation (something simple like whoami perhaps)
>proxying as that user and requesting PP status back.
>
>That may give you what you want. It may even work! :-)
Well, I have thousands of users, and simply want to create a filter
that will fetch the unexpired users who match various other criteria.
>I suspect Buchan's approach is better as it doesn't involve iterating
>through each user and the attributes it is using are defined in the
>same draft as the PP control, i.e. reasonably standardised.
The problem is that I cannot construct one filter that works for
everyone, because I have multiple policies; I have code like this:
sub _read_ppolicy_times {
my ( $self ) = @_;
my $ldap = _ldapopen $self or return;
my $search = _search $self, $ldap, $POLICY_DN, '(objectclass=pwdPolicy)',
'sub', [ qw( cn pwdMaxAge pwdExpireWarning pwdGraceAuthnLimit ) ]
or return;
if ( $search->code() or $search->count() == 0 ) {
_log_trans_fail $self, $ERR_LDAP_SEARCH_FAIL, 'cannot find ANY ppolicy';
return;
}
my %expires;
foreach my $entry ( $search->entries() ) {
my $pwd_max_age = $entry->get_value( 'pwdMaxAge' ) or next;
$expires{ $entry->get_value( 'cn' ) }
= strftime '%Y%m%d%H%M%SZ', gmtime( time - $pwd_max_age );
}
return \%expires;
}
And then I conduct a search, and loop through the entries removing
those that are expired, like this:
foreach my $entry ( $search->entries() ) {
my $ppolicy = _dns_to_cns $entry->get_value( 'pwdPolicySubentry' );
my $last_changed = $entry->get_value( 'pwdChangedTime' );
if ( exists $expires->{$ppolicy} ) {
next if $no_expired and $expires->{$ppolicy} > $last_changed;
}
else {
$self->log( "Cannot find '$ppolicy' in " . Dumper( $expires ) )
}
push @entries, $entry;
}
This is ugly, especially when I want to have other code to fetch only
users who *have* expired. Do I really need to do this sort of thing?
The server knows which ones have expired; it would be great if I had a
way of asking it to filter them out for me.
--
Nick Urbanik http://nicku.org 808-71011 [email protected]
GPG: 7FFA CDC7 5A77 0558 DC7A 790A 16DF EC5B BB9D 2C24 ID: BB9D2C24
I disclaim, therefore I am.