NAME
    Unix::Passwd::File - Manipulate /etc/{passwd,shadow,group,gshadow}
    entries

VERSION
    version 0.01

SYNOPSIS
     use Unix::Passwd::Files;

     # by default uses files in /etc (/etc/passwd, /etc/shadow, et al)
     my $res = list_users(); # [200, "OK", ["root", ...]]

     # change location of files, return details
     $res = list_users(etc_dir=>"/some/path");
         # [200, "OK", [{user=>"root", uid=>0, ...}, ...]]

     # getting user/group
     $res = get_group(user=>"buzz"); # [200, "OK", {user=>"buzz", uid=>501, ...}]
     $res = get_user(user=>"neil");  # [404, "Not found"]

     # adding user/group, by default adding user will also add a group with the same
     # name
     $res = add_user (user =>"steven", ...); # [200, "OK", {uid=>540, gid=>541}]
     $res = add_group(group=>"steven", ...); # [412, "Group already exists"]

     # modify user/group
     $res = modify_user(user=>"steven", home=>"/newhome/steven"); # [200, "OK"]
     $res = modify_group(group=>"neil"); # [404, "Not found"]

     # deleting user will also delete user's group, except using delete_group=>0
     $res = delete_user(user=>"neil");

     # change user password
     $res = set_user_password(user=>"steven", pass=>"foobar");

     # add/delete user to/from group
     $res = add_user_to_group(user=>"steven", group=>"wheel");
     $res = delete_user_from_group(user=>"steven", group=>"wheel");

     # others
     $res = get_max_uid();
     $res = get_max_gid();

DESCRIPTION
    This module can be used to read and manipulate entries in Unix system
    password files (/etc/passwd, /etc/group, /etc/group, /etc/gshadow; but
    can also be told to search in custom location, for testing purposes).

SEE ALSO
    Old modules on CPAN which do not support shadow files are pretty useless
    to me (e.g. Unix::ConfigFile). Shadow passwords have been around since
    1988 (and in Linux since 1992), FFS!

    Passwd::Unix. I created a fork of Passwd::Unix v0.52 called
    Passwd::Unix::Alt in 2011 to fix some of the deficiencies/quirks in
    Passwd::Unix, including: lack of tests, insistence of running as root
    (despite allowing custom passwd files), use of not-so-ubiquitous bzip2,
    etc. Then in 2012 I decided to create Unix::Passwd::File. Here are how
    Unix::Passwd::File differs compared to Passwd::Unix (and
    Passwd::Unix::Alt):

    *   tests in distribution

    *   no need to run as root

    *   no need to be able to read the shadow file for some operations

        For example, "list_users()" will simply not return the "encpass"
        field if the shadow file is unreadable. Of course, access to shadow
        file is required when getting or setting password.

    *   strictly procedural (non-OO) interface

        I consider this a feature :-)

    *   detailed error message for each operation

    *   removal of global error variable

    *   working locking

        Locking is done by locking "passwd.lock" file.

    Setup::Unix::User and Setup::Unix::Group, which use this module.

    Rinci

DESCRIPTION
    This module has Rinci metadata.

FUNCTIONS
    None are exported by default, but they are exportable.

  add_group(%args) -> [status, msg, result, meta]
    Add a new group.

    Arguments ('*' denotes required arguments):

    *   etc_dir => *str* (default: "/etc")

        Specify location of passwd files.

    *   gid => *any*

        Pick a specific new GID.

    *   group* => *any*

    *   max_gid => *any*

        Pick a range for new GID.

    *   members => *any*

        Fill initial members.

    *   min_gid => *any*

        Pick a range for new GID.

    Return value:

    Returns an enveloped result (an array). First element (status) is an
    integer containing HTTP status code (200 means OK, 4xx caller error, 5xx
    function error). Second element (msg) is a string containing error
    message, or 'OK' if status is 200. Third element (result) is optional,
    the actual result. Fourth element (meta) is called result metadata and
    is optional, a hash that contains extra information.

  add_user(%args) -> [status, msg, result, meta]
    Add a new user.

    Arguments ('*' denotes required arguments):

    *   encpass => *str*

        Encrypted password.

    *   etc_dir => *str* (default: "/etc")

        Specify location of passwd files.

    *   expire_date => *int*

        The date of expiration of the account, expressed as the number of
        days since Jan 1, 1970.

    *   gecos => *str*

        Usually, it contains the full username.

    *   gid => *any*

        Pick a specific new GID.

    *   group* => *any*

    *   home => *str*

        User's home directory.

    *   last_pwchange => *int*

        The date of the last password change, expressed as the number of
        days since Jan 1, 1970.

    *   max_gid => *any*

        Pick a range for new GID.

    *   max_pass_age => *int*

        The number of days after which the user will have to change her
        password.

    *   max_uid => *any*

        Pick a range for new UID.

    *   min_gid => *any*

        Pick a range for new GID.

    *   min_pass_age => *int*

        The number of days the user will have to wait before she will be
        allowed to change her password again.

    *   min_uid => *any*

        Pick a range for new UID.

    *   pass => *str*

        Password, generally should be "x" which means password is encrypted
        in shadow.

    *   pass_inactive_period => *int*

        The number of days after a password has expired (see max_pass_age)
        during which the password should still be accepted (and user should
        update her password during the next login).

    *   pass_warn_period => *int*

        The number of days before a password is going to expire (see
        max_pass_age) during which the user should be warned.

    *   shell => *str*

        User's home directory.

    *   uid => *any*

        Pick a specific new UID.

    Return value:

    Returns an enveloped result (an array). First element (status) is an
    integer containing HTTP status code (200 means OK, 4xx caller error, 5xx
    function error). Second element (msg) is a string containing error
    message, or 'OK' if status is 200. Third element (result) is optional,
    the actual result. Fourth element (meta) is called result metadata and
    is optional, a hash that contains extra information.

  get_group(%args) -> [status, msg, result, meta]
    Get group details by group name or gid.

    Either "group" OR "gid" must be specified.

    The function is not dissimilar to Unix's "getgrnam()" or "getgrgid()".

    Arguments ('*' denotes required arguments):

    *   etc_dir => *str* (default: "/etc")

        Specify location of passwd files.

    *   gid => *int*

    *   group => *str*

    *   with_field_names => *bool* (default: 1)

        If false, don't return hash.

        By default, a hashref is returned containing field names and its
        values, e.g. "{group=""neil", pass=>"x", gid=>500, ...}>. With
        "with_field_names="0>, an arrayref is returned instead: "["neil",
        "x", 500, ...]".

    Return value:

    Returns an enveloped result (an array). First element (status) is an
    integer containing HTTP status code (200 means OK, 4xx caller error, 5xx
    function error). Second element (msg) is a string containing error
    message, or 'OK' if status is 200. Third element (result) is optional,
    the actual result. Fourth element (meta) is called result metadata and
    is optional, a hash that contains extra information.

  get_max_gid(%args) -> [status, msg, result, meta]
    Get maximum GID used.

    Arguments ('*' denotes required arguments):

    *   etc_dir => *str* (default: "/etc")

        Specify location of passwd files.

    Return value:

    Returns an enveloped result (an array). First element (status) is an
    integer containing HTTP status code (200 means OK, 4xx caller error, 5xx
    function error). Second element (msg) is a string containing error
    message, or 'OK' if status is 200. Third element (result) is optional,
    the actual result. Fourth element (meta) is called result metadata and
    is optional, a hash that contains extra information.

  get_max_uid(%args) -> [status, msg, result, meta]
    Get maximum UID used.

    Arguments ('*' denotes required arguments):

    *   etc_dir => *str* (default: "/etc")

        Specify location of passwd files.

    Return value:

    Returns an enveloped result (an array). First element (status) is an
    integer containing HTTP status code (200 means OK, 4xx caller error, 5xx
    function error). Second element (msg) is a string containing error
    message, or 'OK' if status is 200. Third element (result) is optional,
    the actual result. Fourth element (meta) is called result metadata and
    is optional, a hash that contains extra information.

  get_user(%args) -> [status, msg, result, meta]
    Get user details by username or uid.

    Either "user" OR "uid" must be specified.

    The function is not dissimilar to Unix's "getpwnam()" or "getpwuid()".

    Arguments ('*' denotes required arguments):

    *   etc_dir => *str* (default: "/etc")

        Specify location of passwd files.

    *   uid => *int*

    *   user => *str*

    *   with_field_names => *bool* (default: 1)

        If false, don't return hash.

        By default, a hashref is returned containing field names and its
        values, e.g. "{user=""neil", pass=>"x", uid=>500, ...}>. With
        "with_field_names="0>, an arrayref is returned instead: "["neil",
        "x", 500, ...]".

    Return value:

    Returns an enveloped result (an array). First element (status) is an
    integer containing HTTP status code (200 means OK, 4xx caller error, 5xx
    function error). Second element (msg) is a string containing error
    message, or 'OK' if status is 200. Third element (result) is optional,
    the actual result. Fourth element (meta) is called result metadata and
    is optional, a hash that contains extra information.

  list_groups(%args) -> [status, msg, result, meta]
    List Unix groups in group file.

    Arguments ('*' denotes required arguments):

    *   detail => *bool* (default: 0)

        If true, return all fields instead of just group names.

    *   etc_dir => *str* (default: "/etc")

        Specify location of passwd files.

    *   with_field_names => *bool* (default: 1)

        If false, don't return hash for each entry.

        By default, when "detail="1>, a hashref is returned for each entry
        containing field names and its values, e.g. "{group=""neil",
        pass=>"x", gid=>500, ...}>. With "with_field_names="0>, an arrayref
        is returned instead: "["neil", "x", 500, ...]".

    Return value:

    Returns an enveloped result (an array). First element (status) is an
    integer containing HTTP status code (200 means OK, 4xx caller error, 5xx
    function error). Second element (msg) is a string containing error
    message, or 'OK' if status is 200. Third element (result) is optional,
    the actual result. Fourth element (meta) is called result metadata and
    is optional, a hash that contains extra information.

  list_users(%args) -> [status, msg, result, meta]
    List Unix users in passwd file.

    Arguments ('*' denotes required arguments):

    *   detail => *bool* (default: 0)

        If true, return all fields instead of just usernames.

    *   etc_dir => *str* (default: "/etc")

        Specify location of passwd files.

    *   with_field_names => *bool* (default: 1)

        If false, don't return hash for each entry.

        By default, when "detail="1>, a hashref is returned for each entry
        containing field names and its values, e.g. "{user=""neil",
        pass=>"x", uid=>500, ...}>. With "with_field_names="0>, an arrayref
        is returned instead: "["neil", "x", 500, ...]".

    Return value:

    Returns an enveloped result (an array). First element (status) is an
    integer containing HTTP status code (200 means OK, 4xx caller error, 5xx
    function error). Second element (msg) is a string containing error
    message, or 'OK' if status is 200. Third element (result) is optional,
    the actual result. Fourth element (meta) is called result metadata and
    is optional, a hash that contains extra information.

AUTHOR
    Steven Haryanto <stevenharyanto@gmail.com>

COPYRIGHT AND LICENSE
    This software is copyright (c) 2012 by Steven Haryanto.

    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.

