From 7b2df0cb8d29ba835be5d645f8b4f70b74b2fcc4 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Wed, 18 Apr 2012 03:33:24 +0200 Subject: fripost-passwd is LDAP ready. --- fripost-passwd | 151 +++++++++++++++++++++++++++++++++++----- lib/Fripost/Schema.pm | 4 +- lib/Fripost/Schema/Type/User.pm | 2 +- 3 files changed, 137 insertions(+), 20 deletions(-) diff --git a/fripost-passwd b/fripost-passwd index bb67e44..9ae47d9 100755 --- a/fripost-passwd +++ b/fripost-passwd @@ -8,54 +8,171 @@ use strict; fripost-passwd - Change password of user +=head1 SYNOPSIS + +B [B<--debug>] [B<--pretend>] [I] +[B<--password=>I] + +=head1 DESCRIPTION + +B changes the password of I, unless B<--pretend> +is set. +If I or I are not given, the user is prompted for them. +If I is not fully qualified, C is appended. +If I is not an existing username, B raises an +error. + +=head1 OPTIONS + +=over 8 + +=item B<--pretend> + +Only simulates the insertion. (But still query the LDAP server to ensure +that I is a known user.) + +=item B<--password=>I + +By default, the user is prompted for his/her new password, which is +hashed, salted and then added to the LDAP entry. +By using B<--password>, I is inserted RAW in the database. +This can be useful if the user does not want to give the clear copy but +only a hash, for example. + +=item B<--server_host=>I + +The LDAP URI to connect to. +The default value is read from the configuration file, see B. + +=item B<--bind_dn=>I + +The Distinguished Name (DN) to bind to the LDAP directory. +(If not set, B binds anonymously.) +The default value is read from the configuration file, see B. + +=item B<--bind_pw=>I + +The password to to bind with. +The default value is read from the configuration file, see B. + +=item B<--base_dn=>I + +The root DN for everything done by B. +The default value is read from the configuration file, see B. + +=item B<--debug> + +Debug mode. + +=back + +=head1 CONFIGURATION + +The configuration is read from the file C<$HOME/.fripost.yml>. +Valid keys include: + +=over 4 + +=item I + +The LDAP URI to connect to. It has to be set, either in the +configuration file, or using the command line option B<--server_host>. + +=item I + +The Distinguished Name (DN) to bind to the LDAP directory. +(If not set, B binds anonymously.) + +=item I + +The password to to bind with. + +=item I + +The root DN for everything done by B. + +=back + =cut use FindBin qw($Bin); use lib "$Bin/lib"; +use Env qw /HOME/; +use File::Spec::Functions; + use Fripost::Password; use Fripost::Prompt; use Fripost::Schema; -use Getopt::Long; +use Getopt::Long qw /:config noauto_abbrev no_ignore_case + gnu_compat bundling permute nogetopt_compat + auto_version auto_help/; +use Pod::Usage; use YAML::Syck; ## Get command line options -our $conf = LoadFile('default.yml'); +our $conf = LoadFile( catfile ($HOME, '.fripost.yml') ); GetOptions( - 'dbi_dsn' => \$conf->{dbi_dsn}, - 'admuser=s' => \$conf->{admuser}, - 'admpass=s' => \$conf->{admpass}, - 'pretend' => \$conf->{pretend}, -) or die "Unable to get command line options."; + 'server_host' => \$conf->{server_host}, + 'base_dn=s' => \$conf->{base_dn}, + 'bind_dn=s' => \$conf->{bind_dn}, + 'bind_pw=s' => \$conf->{bind_pw}, + 'pretend' => \$conf->{pretend}, + 'debug' => \$conf->{debug}, + 'password=s' => \$conf->{password}, + 'man' => sub { pod2usage(-exitstatus => 0, + -verbose => 2) } +) or pod2usage(2); + + +# Connect to the LDAP server +my $ldap = Fripost::Schema->new( $conf ); + + +my $username; +if (defined $ARGV[0]) { + $username = fix_username ($ARGV[0]); + Email::Valid->address($username) + or die "Error: `" .$username. "' is not a valid e-mail.\n"; +} +else { + $username = prompt_email("New username: ", 'is_user'); +} +my $password = $conf->{password}; +$password //= hash( undef, undef, prompt_password() ); + + +# Ensure that the user exists. +die "Error: Unknown user `" .$username. "'.\n" + unless $ldap->user->search({ username => $username })->count; -my $username = fix_username($ARGV[0]); -$username //= prompt_email("New username: ", 'is_user'); -my $password = prompt_password(); if ($conf->{pretend}) { say "Nothing to do since we are pretending..."; exit 0; } -# Connect to the database -my $schema = Fripost::Schema->connect( - $conf->{dbi_dsn}, $conf->{admuser}, $conf->{admpass}, {} #\%dbi_params -); -my $row = $schema->resultset('Mailbox')->find($username); -$row->password($password); -$row->update; +# Change the password. +$ldap->user->passwd({ username => $username, userPassword => $password }); say "Updated password for $username."; +$ldap->unbind(); + + =head1 AUTHOR Stefan Kangas C<< >> +Guilhem Moulin C<< >> + =head1 COPYRIGHT Copyright 2010 Stefan Kangas. +Copyright 2012 Guilhem Moulin. + =head1 LICENSE This program is free software; you can redistribute it and/or modify it diff --git a/lib/Fripost/Schema.pm b/lib/Fripost/Schema.pm index 22c6064..288aa1e 100755 --- a/lib/Fripost/Schema.pm +++ b/lib/Fripost/Schema.pm @@ -92,10 +92,10 @@ sub add { } -sub password { +sub passwd { my $self = shift; if ( $self->{_type} == MAILBOX ) { - $self->Fripost::Schema::Type::User::pwd(@_); + $self->Fripost::Schema::Type::User::passwd(@_); } elsif ( $self->{_type} == DOMAIN ) { die "Cannot change the password of a domain."; diff --git a/lib/Fripost/Schema/Type/User.pm b/lib/Fripost/Schema/Type/User.pm index 544687c..b21c2e1 100644 --- a/lib/Fripost/Schema/Type/User.pm +++ b/lib/Fripost/Schema/Type/User.pm @@ -56,7 +56,7 @@ sub add { # Change password -sub pwd { +sub passwd { my $self = shift; my $user = shift; -- cgit v1.2.3