view release on metacpan or search on metacpan
current_user(), config() and ldap()
0.06 Sun Apr 08 00:58:20 2012
- replace App::CLI with Namespace::Dispatch
- drop Rubyish::Attribute. adopt Moose
- all new LDIF::* with Moose
- use MooseX::Getopt
- new implementation in Add::User
0.05 Fri Dec 03 14:11:24 2010
- use Crypt::Password to crypt password
0.04 Fri Dec 03 13:25:12 2010
- be able to $ ldap add user <username>
0.03 Thu Dec 02 11:56:34 2010
- be able to $ ldap del user <username>
0.02 Thu Dec 02 01:34:20 2010
- verify user via UID
- be able to $ ldap import ldif_files
README.md
schema/cn=idnext.ldif
schema/cn=sudo.ldif
t/00_compile.t
t/commands/add.t
t/commands/del.t
t/commands/export.t
t/commands/help.t
t/commands/import.t
t/commands/migrate.t
t/commands/password.t
t/config.t
t/data/ldap.conf
t/ldif/group.t
t/ldif/host.t
t/ldif/orgunit.t
t/ldif/sudoer.t
t/ldif/user.t
t/objectclass/inetorgperson.t
t/objectclass/organizationalperson.t
t/objectclass/person.t
$ sudo ldap add ou test # add organizational unit ou=test,dc=example,dc=com
### delete
Every schema is also supported to be deleted from command line.
$ sudo ldap del user shelling # delete posixAccount uid=shelling,ou=people,dc=example,dc=com
$ sudo ldap del group maintainer # delete posixGroup cn=maintainer,dc=groups,dc=example,dc=com
### password
App::LDAP can guess your role from your UID, and help you to change your password.
$ ldap passwd # change password of yourself
$ sudo ldap passwd shelling # using priviledge of ldap admin to change passwd of shelling
$ sudo ldap passwd shelling --lock # lock shelling
$ sudo ldap passwd shelling --unlock # unlock shelling
### backup and restoring
Doing backup and restoring are also supported.
lib/App/LDAP/Command/Add/User.pm view on Meta::CPAN
die "user $username already exists" if App::LDAP::LDIF::User->search(
base => config()->{nss_base_passwd}->[0],
scope => config()->{nss_base_passwd}->[1],
filter => "uid=$username",
);
my $user = App::LDAP::LDIF::User->new(
base => $self->base // config()->{nss_base_passwd}->[0],
uid => $username,
userPassword => encrypt(new_password()),
uidNumber => $uid->get_value("uidNumber"),
gidNumber => $self->gid_of( $self->group ),
sn => $self->surname,
mail => $self->mail,
);
$user->loginShell ( $self->shell ) if $self->shell;
$user->homeDirectory ( $self->home ) if $self->home;
$user->save;
lib/App/LDAP/Command/Export.pm view on Meta::CPAN
=head1 NAME
App::LDAP::Command::Export
=head1 SYNOPSIS
$ sudo ldap export backup.ldif
backup whole DIT
$ ldap export people.ldif --base ou=people,dc=example,dc=com
dump user information without password
$ sudo ldap export people.ldif --base ou=people,dc=example,dc=com
dump user information with password
=cut
lib/App/LDAP/Command/Passwd.pm view on Meta::CPAN
my ($self,) = @_;
my $name = $self->extra_argv->[1];
my $user = $name ? find_user(uid => $name) : current_user();
if ( $< == 0 ) {
$self->distinguish->($user);
} else {
if ($name and ( find_user(uid => $name)->dn ne current_user->dn ) ) {
die "you may not view or modify password information for " . $user->dn;
}
$self->distinguish->($user);
}
}
sub distinguish {
my $self = shift;
if ($self->lock && $self->unlock) {
say "I'm dazzled with your key :p";
lib/App/LDAP/Command/Passwd.pm view on Meta::CPAN
if ($self->unlock) {
return \&unlock_user if $> == 0;
die "Permission denied";
}
if ($self->lock) {
return \&lock_user if $> == 0;
die "Permission denied";
}
return \&change_password;
}
sub change_password {
my $user = shift;
use Date::Calc qw(Today Delta_Days);
$user->replace(
userPassword => encrypt(new_password()),
shadowLastChange => Delta_Days(1970, 1, 1, Today()),
)->update(ldap());
}
sub lock_user {
my $user = shift;
my $password = $user->get_value("userPassword");
$password =~ s{{crypt}\$}{{crypt}!\$};
$user->replace(
userPassword => $password,
)->update(ldap());
}
sub unlock_user {
my $user = shift;
my $password = $user->get_value("userPassword");
$password =~ s{{crypt}!\$}{{crypt}\$};
$user->replace(
userPassword => $password,
)->update(ldap());
}
use Net::LDAP;
use Net::LDAP::Extension::WhoAmI;
sub current_user {
my $dn = ldap()->who_am_i->response;
$dn =~ s{dn:}{};
my $search = ldap()->search(
lib/App/LDAP/Command/Passwd.pm view on Meta::CPAN
__PACKAGE__->meta->make_immutable;
no Moose;
1;
=pod
=head1 NAME
App::LDAP::Command::Passwd - manage the password in LDAP server
=head1 SYNOPSIS
$ ldap passwd # change your own password
$ sudo ldap passwd # change password of ldap admin
$ sudo ldap passwd shelling # sudo the privilege of admin to change password of shelling
$ sudo ldap passwd shelling -l # lock shelling
$ sudo ldap passwd shelling -u # unlock shelling
=cut
lib/App/LDAP/Connection.pm view on Meta::CPAN
App::LDAP::Connection->new(
"ldap://localhost",
port => 389,
version => 3,
onerror => "die",
);
App::LDAP::Connection->instance->bind(
"cn=admin,dc=example,dc=org",
password => "password",
);
App::LDAP::Connection->instance->search(
base => "ou=People,dc=example,dc=org",
scope => "sub",
filter => "uid=foo",
);
=cut
lib/App/LDAP/LDIF/User.pm view on Meta::CPAN
=head1 NAME
App::LDAP::LDIF::User - the representation of users in LDAP
=head1 SYNOPSIS
my $user = App::LDAP::LDIF::User->new(
base => $base, # the OU (organization unit) which the user belongs to
uid => $name, # user name
userPassword => $password, # the password used by the user
uidNumber => $uid, # the uid of the user
gidNumber => $gid, # the gid of the user
sn => [$sn], # the surname of this user
);
# these 6 parameters are required
# extra parameters of attributes such as title of User can be provided in constructor, too.
$user->loginShell("/bin/zsh")
# set zsh as the user's shell
lib/App/LDAP/LDIF/User.pm view on Meta::CPAN
=head2 cn
required attributes. default [ $self->uid ]
=head2 loginShell
default /bin/bash
=head2 shadowLastChange
the days from Unix Epoch that last time you changed password.
default value is calculated via Date::Calc::Delta_Days().
=head2 shadowMin
the minimum days that user can change their password.
default 0
=head2 shadowMax
the maximun days that user have to change their password.
default 99999
=head2 shadowWarning
the day that user would be warned before password to be expired
default 7
=head2 homeDirectory
default "/home/" . $self->uid
=cut
lib/App/LDAP/ObjectClass/ShadowAccount.pm view on Meta::CPAN
=head1 NAME
App::LDAP::ObjectClass::ShadowAccount - schema of shadowAccount
=head1 DEFINITION
objectclass (
1.3.6.1.1.1.2.1
NAME 'shadowAccount'
DESC 'Additional attributes for shadow passwords'
SUP top
AUXILIARY
MUST uid
MAY ( userPassword $ shadowLastChange $ shadowMin $
shadowMax $ shadowWarning $ shadowInactive $
shadowExpire $ shadowFlag $ description )
)
=cut
lib/App/LDAP/Role/Bindable.pm view on Meta::CPAN
my $self = shift;
($< == 0) ? bindroot() : binduser();
$self->$orig(@_);
};
sub bindroot {
ldap()->bind(
config()->{rootbinddn},
password => secret() // read_password("ldap admin password: "),
);
}
sub binduser {
ldap()->bind(
find_user("uidNumber", $<)->dn,
password => secret() // read_password("your password: "),
);
}
no Moose::Role;
1;
=pod
=head1 NAME
lib/App/LDAP/Role/Command.pm view on Meta::CPAN
$class->has_leaf('name');
=head2 leaves
the wrapper of Namespace::Dispatch::leaves()
$submodules = $class->leaves();
=head2 encrypt($plain)
given a plain text password, the helper returns an encrypted one.
$hashed = encrypt($plain);
=cut
use Crypt::Password;
sub encrypt {
my $plain = shift;
"{crypt}".password($plain, undef, "sha512");
}
=head2 new_password()
read and confirm the new password from terminal.
die if failing to confirm.
$plain = new_password();
=cut
use Term::ReadPassword;
sub new_password {
my $password = read_password("password: ");
my $comfirm = read_password("comfirm password: ");
if ($password eq $comfirm) {
return $password;
} else {
die "not the same";
}
}
no Moose::Role;
1;
lib/App/LDAP/Secret.pm view on Meta::CPAN
1;
=pod
=head1 NAME
App::LDAP::Secret - loader of secret file
=head1 DESCRIPTION
this module would be called automatically in App::LDAP::run() to load the password for binding
=cut
t/data/ldap.conf view on Meta::CPAN
uri ldap://localhost
port 389
ldap_version 3
scope sub
timelimit 30
rootbinddn cn=admin,dc=example,dc=com
pam_login_attribute uid
pam_filter posixAccount
pam_password crypt
nss_base_passwd ou=People,dc=example,dc=com?one
nss_base_shadow ou=People,dc=example,dc=com?one
nss_base_group ou=Group,dc=example,dc=com?one
nss_base_hosts ou=Hosts,dc=example,dc=com?one
sudoers_base ou=SUDOers,dc=example,dc=com
t/ldif/user.t view on Meta::CPAN
is_deeply (
$user->objectClass,
[qw(inetOrgPerson posixAccount top shadowAccount)],
"objectClass has default",
);
is (
$user->userPassword,
"appldap0000",
"password should be assigned",
);
ok (
$user->shadowLastChange,
"shadowLastChange has default",
);
is (
$user->shadowMin,
0,