App-LDAP

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

          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

MANIFEST  view on Meta::CPAN

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

README.md  view on Meta::CPAN

    $ 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,



( run in 0.919 second using v1.01-cache-2.11-cpan-49f99fa48dc )