The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Unix::Login - Customizable Unix login prompt and validation

SYNOPSIS

    use Unix::Login;
  
    # This will return the same thing as getpwnam() on
    # success, or will die automatically on failure
    my @pw = login;

DESCRIPTION

This is a simple yet flexible module that provides a Unix-esque login prompt w/ password validation. This is useful in custom applications that need to validate the username/password of the person using the app.

The above example is pretty much all you'll ever need (and all this module provides). Here are some specifics on the function provided:

login(option => value, option => value)

This prompts for the username and password and tries to validate the login. On success, it returns the same thing that getpwuid() does: the username in a scalar context, or the passwd struct as an array in a list context. It returns undef on failure.

You can pass it an optional set of parameters. These will specify options for that login prompt only. The parameters and their default values are:

    attempts      Max login attempts [3]
    failmesg      Print this on failure ["Login incorrect\n"]
    failsleep     And sleep for this many seconds [3]
    failexit      If can't login after (3) attempts, exit fatally [1]

    banner        Banner printed once up top ["Please Login\n"]
    bannerfile    File to print after banner (i.e. /etc/issue) []
    login         Prompt asking for username ["login: "]
    password      Prompt asking for password ["Password: "]

    sameuser      Take username from process? [0]
    passreq       Require a password for all users? [1]
    nohomemesg    Printed if no homedir ["No home directory! Setting HOME=/\n"]
    stripspaces   Strip spaces from username? [1]

    setenv        If true, setup HOME and other %ENV variables [1]
    clearenv      If true, first undef %ENV before setenv [0]
    path          If setenv, set PATH to this for non-root [/usr/bin:]
    supath        If setenv, set PATH to this for root [/usr/sbin:/usr/bin]
    maildir       If setenv, set MAIL to this dir/username [/var/mail]

    input         Where to read input from filehandle [STDIN]
    output        Where to write output to filehandle [STDOUT]

    pwent         Return a User::pwent struct in scalar context? [0]
    cdhome        Chdir to the person's homedir on success? [0]
    execshell     Execute the person's shell as login session? [0]

So, for example, you can create a fully-customized login screen like so:

    use Unix::Login;

    my @pwent = login(login => "User: ", password => "Pass: ")
       || die "Sorry, try remembering your password next time.\n";

Often, you just want the user to re-enter their password, though. In this case, specify the sameuser option:

    use Unix::Login;
    my @pwent = login(sameuser => 1);

Since login() will return true or die on exit, you can even just use it as a standalone line if you're just verifying their identity (and don't need the pw struct back). You may also want to turn off the banner for a better display:

    login(sameuser => 1, banner => 0);

If the pwent option is set, then User::pwent is used to provide an object in a scalar context:

    use Unix::Login;
    my $pwent = login(pwent => 1);

See the man page for User::pwent for more details.

If the execshell option is set, then if login() is successful the user's shell is forked and the current process is terminated, just like a real Unix login session.

Thus, with these options, you could create a very Unix-like login:

    use Unix::Login;

    my @pwent = login(bannerfile => '/etc/issue',
                      banner     => `uname -rs`,
                      clearenv   => 1,
                      cdhome     => 1,
                      execshell  => 1);

This will validate our login, clear our environment and reset it, then exec the shell as a login shell just like a real life Unix login.

new(option => value, option => value)

If you really like OO-calling styles, this module also provides an OO form, although I personally think it's rather silly.

The new() function creates a new Unix::Login object. It accepts the same parameters as listed above. Then, you call login() as a member function. So for example:

    use Unix::Login;

    my $ul = Unix::Login->new(setenv => 0, passreq => 0);

    my @pw = $ul->login;

Personally, I always just use login() as a function...

NOTES

This module automatically grabs control of the signals INT, TERM, and QUIT, just like DBI.pm, to make sure that a ^C causes the module to fail insted of accidentally succeed.

To use the input and output options, you must first open the filehandle yourself, and then pass in a glob ref to the filehandle. For example:

    # ... stuff to listen to SOCKET ...
    login(input => \*SOCKET, output => \*SOCKET);

These options are seldom used, so if this doesn't make any sense to you, don't sweat it.

ACKNOWLEDGEMENTS

Thanks to David Redmond to modernizing the crypt() stuff so that it's RedHat-friendly.

VERSION

$Id: Login.pm,v 1.8 2003/08/29 22:42:59 nwiger Exp $

SEE ALSO

User::pwent(3), login(1), perlfunc(1)

AUTHOR

Copyright (c) 2000-2003 Nathan Wiger <nate@wiger.org>. All Rights Reserved.

This module is free software; you may copy this under the terms of the GNU General Public License, or the Artistic License, copies of which should have accompanied your Perl kit.