NetBSD/lib/libutil/pw_policy.3

357 lines
8.5 KiB
Groff

.\" $NetBSD: pw_policy.3,v 1.8 2006/03/23 19:31:37 wiz Exp $
.\"
.\" Copyright 2005, 2006 Elad Efrat <elad@NetBSD.org>
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. The name of the Author may not be used to endorse or promote
.\" products derived from this software without specific prior written
.\" permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd March 19, 2006
.Dt PW_POLICY 3
.Os
.Sh NAME
.Nm pw_policy_load ,
.Nm pw_policy_test
.Nd password policy enforcement
.Sh LIBRARY
.Lb libutil
.Sh SYNOPSIS
.In util.h
.Ft pw_policy_t
.Fn pw_policy_load "void *key" "int how"
.Ft int
.Fn pw_policy_test "pw_policy_t policy" "char *pw"
.Ft void
.Fn pw_policy_free "pw_policy_t policy"
.Sh DESCRIPTION
The
.Fn pw_policy_load ,
.Fn pw_policy_test ,
and
.Fn pw_policy_free
functions are used as an interface to the system's password policy
as specified in
.Pa /etc/passwd.conf .
.Pp
.Fn pw_policy_load
will load a password policy and return a pointer to a
.Ar pw_policy_t
containing it.
It is the caller's responsibility to free this pointer using
.Fn pw_policy_free .
.Pp
Using
.Xr pw_getconf 3
terminology,
.Fn pw_policy_load
accepts a
.Ar key
to be used when searching
.Pa /etc/passwd.conf
for a password policy.
This key contains various options describing different policies.
Some built-in ones are described along with their syntax below.
.Pp
To allow calling from various program contexts
and using various password policy retrieval schemes,
.Ar how
tells
.Fn pw_policy_load
how to treat
.Ar key .
.Pp
Possible values for
.Ar how
are:
.Pp
.Bl -tag -width kungfuninja -compact
.It Li PW_POLICY_BYSTRING
.Ar key
is used as a
.Ft char * ,
looking up the string it contains in
.Pa /etc/passwd.conf .
.Pp
.It Li PW_POLICY_BYPASSWD
.Ar key
is used as a
.Ft struct passwd * ,
first looking up the username in
.Ft pw_name ,
and if no key can be found, it will try the login class in
.Ft pw_class .
.Pp
.It Li PW_POLICY_BYGROUP
.Ar key
is used as a
.Ft struct group * ,
looking up the group name in
.Ft gr_name .
.El
.Pp
If
.Ar key
is
.Dv NULL ,
or no specified key can be found, the default key,
.Dq pw_policy ,
is used.
If even the default key can't be found,
the password is accepted as no policy is defined.
.Pp
.Fn pw_policy_test
can be used to check if the password in
.Ar pw
is compliant with the policy in
.Ar policy .
.Sh BUILT-IN POLICY SYNTAX
Available built-in policy options include the following:
.Pp
.Bl -tag -width kungfuninja -compact
.It length
Length of the password.
.It uppercase
Number of upper-case characters in the password.
.It lowercase
Number of lower-case characters in the password.
.It digits
Number of digits in the password.
.It punctuation
Number of punctuation characters in the password.
.It nclasses
Number of different character classes in the password.
.It ntoggles
How often a user has to toggle between character classes in the password.
.El
.Pp
Options are used inside keys.
An option uses a format of
.Dq option = value .
For the built-in options, we use either
.Dq N
or
.Dq N-M
for the value.
.Pp
The first,
.Dq N
format, specifies a single length.
For example, the following option specifies that the password should
have exactly 3 upper-case characters:
.Bd -literal -offset indent
uppercase = 3
.Ed
.Pp
The second,
.Dq N-M
format, can be used to specify a range.
Forcing a policy for number of digits between 1 and 4 would be:
.Bd -literal -offset indent
digits = 1-4
.Ed
.Pp
The characters
.Sq 0
and
.Sq *
can also be used to indicate
.Dq not allowed
and
.Dq any number ,
respectively.
To illustrate, the following example states that the number of
punctuation characters should be at least two:
.Bd -literal -offset indent
punctuation = 2-*
.Ed
.Pp
No more than 7 digits:
.Bd -literal -offset indent
digits = *-7
.Ed
.Pp
Any number of lower-case characters:
.Bd -literal -offset indent
lowercase = *
.Ed
.Pp
Upper-case characters not allowed:
.Bd -literal -offset indent
uppercase = 0
.Ed
.Pp
To specify that the password must be at least 8 characters long:
.Bd -literal -offset indent
length = 8-*
.Ed
.Pp
Specifying a password must have at least 3 different character classes:
.Bd -literal -offset indent
nclasses = 3-*
.Ed
.Pp
And that the user must change character class every 2 characters:
.Bd -literal -offset indent
ntoggles = *-2
.Ed
.Pp
Note that when using the
.Dq nclasses
directive, the policy will be initialized to allow any number of characters
from all classes.
If desired, this should be overridden after the
.Dq nclasses
option.
.Sh RETURN VALUES
.Fn pw_policy_load
returns a
.Ar pw_policy_t
on success, or
.Dv NULL
on failure, in which case the
.Va errno
variable will be set to any of the following values indicating the
reason for the failure:
.Bl -tag -width Er
.It Bq Er ENOENT
The
.Pa /etc/passwd.conf
is missing.
.It Bq Er EINVAL
Invalid value for the
.Ar how
parameter or an invalid value in the password policy specification.
.El
.Pp
.Fn pw_policy_load
can also set
.Va errno
to a value returned by the called handlers and/or
.Xr malloc 3 .
.Pp
.Fn pw_policy_test
returns 0 if the password follows the policy, or \-1 if it doesn't,
.Va errno
can be set to any of the following values:
.Bl -tag -width Er
.It Bq Er EPERM
The password does not follow the password policy.
.It Bq Er EINVAL
.Dv NULL
pointer was passed as the password.
.El
.Pp
In addition,
.Va errno
can be set to any error code returned by the handlers.
.Sh FILES
.Bl -tag -width /etc/passwd.conf -compact
.It Pa /etc/passwd.conf
password configuration file.
.El
.Sh EXAMPLES
Declare a password policy storage:
.Bd -literal -offset indent
pw_policy_t policy;
.Ed
.Pp
Load the system global password policy into
.Ar policy :
.Bd -literal -offset indent
policy = pw_policy_load(NULL, 0);
if (policy == NULL)
errx(1, "Can't load password policy");
.Ed
.Pp
Load a policy for a user whose password database entry is in
.Ar pw_entry
into
.Ar policy :
.Bd -literal -offset indent
policy = pw_policy_load(pw_entry, PW_POLICY_BYPASSWD);
if (policy == NULL)
errx(1, "Can't load password policy for \e"%s\e"", pw_entry-\*[Gt]pw_name);
.Ed
.Pp
Note that
.Fn pw_policy_load
will first look for a password policy for the username in
.Ar pw_entry-\*[Gt]pw_name ,
if not found, it will try looking for a policy for the login class in
.Ar pw_entry-\*[Gt]pw_class ,
and if it can't find such either it will fallback to the default key,
.Dq pw_policy .
.Pp
Load the password policy for a group
whose group database entry is in
.Ar grent ,
into
.Ar policy :
.Bd -literal -offset indent
policy = pw_policy_load(grent, PW_POLICY_BYGROUP);
if (policy == NULL)
errx(1, "Can't load password policy for \e"%s\e"", grent-\*[Gt]gr_name);
.Ed
.Pp
Check if
.Ar the_password
follows the policy in
.Ar policy :
.Bd -literal -offset indent
if (pw_policy_test(policy, the_password) != 0)
warnx("Please refer to the password policy");
.Ed
.Pp
After finished using the password policy, free it:
.Bd -literal -offset indent
pw_policy_free(policy);
.Ed
.Pp
An example for a common default password policy in
.Pa /etc/passwd.conf :
.Bd -literal -offset indent
pw_policy:
length = 8-* # At least 8 characters long,
lowercase = 1-* # combining lowercase,
uppercase = 1-* # uppercase,
digits = 1-* # and digits.
punctuation = * # Punctuation is optional.
.Ed
.Pp
A different policy that might be used:
.Bd -literal -offset indent
nclasses = 3-* # At least 3 different character classes,
ntoggles = *-2 # not more than 2 same class in a row.
.Ed
.Sh SEE ALSO
.Xr pw_getconf 3 ,
.Xr passwd.conf 5
.Sh HISTORY
The
.Fn pw_policy_load ,
.Fn pw_policy_test ,
and
.Fn pw_policy_free
functions first appeared in
.Nx 4.0 .
.Sh AUTHORS
.An Elad Efrat
.Aq elad@NetBSD.org