2006-03-23 22:31:37 +03:00
|
|
|
.\" $NetBSD: pw_policy.3,v 1.8 2006/03/23 19:31:37 wiz Exp $
|
2005-09-14 15:36:52 +04:00
|
|
|
.\"
|
2006-02-18 13:52:48 +03:00
|
|
|
.\" Copyright 2005, 2006 Elad Efrat <elad@NetBSD.org>
|
2005-09-14 15:36:52 +04:00
|
|
|
.\"
|
|
|
|
.\" 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.
|
|
|
|
.\"
|
2006-03-20 01:58:21 +03:00
|
|
|
.Dd March 19, 2006
|
2005-09-14 15:36:52 +04:00
|
|
|
.Dt PW_POLICY 3
|
|
|
|
.Os
|
|
|
|
.Sh NAME
|
2006-02-18 13:52:48 +03:00
|
|
|
.Nm pw_policy_load ,
|
2005-09-14 15:36:52 +04:00
|
|
|
.Nm pw_policy_test
|
|
|
|
.Nd password policy enforcement
|
|
|
|
.Sh LIBRARY
|
|
|
|
.Lb libutil
|
|
|
|
.Sh SYNOPSIS
|
|
|
|
.In util.h
|
2006-02-18 19:32:45 +03:00
|
|
|
.Ft pw_policy_t
|
|
|
|
.Fn pw_policy_load "void *key" "int how"
|
2005-09-14 15:36:52 +04:00
|
|
|
.Ft int
|
2006-02-18 19:32:45 +03:00
|
|
|
.Fn pw_policy_test "pw_policy_t policy" "char *pw"
|
|
|
|
.Ft void
|
|
|
|
.Fn pw_policy_free "pw_policy_t policy"
|
2005-09-14 15:36:52 +04:00
|
|
|
.Sh DESCRIPTION
|
|
|
|
The
|
2006-02-18 19:32:45 +03:00
|
|
|
.Fn pw_policy_load ,
|
|
|
|
.Fn pw_policy_test ,
|
2006-02-18 13:52:48 +03:00
|
|
|
and
|
2006-02-18 19:32:45 +03:00
|
|
|
.Fn pw_policy_free
|
2006-02-18 13:52:48 +03:00
|
|
|
functions are used as an interface to the system's password policy
|
|
|
|
as specified in
|
2005-09-14 15:36:52 +04:00
|
|
|
.Pa /etc/passwd.conf .
|
|
|
|
.Pp
|
2006-02-18 13:52:48 +03:00
|
|
|
.Fn pw_policy_load
|
2006-02-18 19:32:45 +03:00
|
|
|
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 .
|
2006-02-18 13:52:48 +03:00
|
|
|
.Pp
|
2005-09-14 15:36:52 +04:00
|
|
|
Using
|
|
|
|
.Xr pw_getconf 3
|
|
|
|
terminology,
|
2006-02-18 13:52:48 +03:00
|
|
|
.Fn pw_policy_load
|
2005-09-14 15:36:52 +04:00
|
|
|
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
|
2006-02-18 13:52:48 +03:00
|
|
|
.Fn pw_policy_load
|
2005-09-14 15:36:52 +04:00
|
|
|
how to treat
|
|
|
|
.Ar key .
|
|
|
|
.Pp
|
2006-02-18 13:52:48 +03:00
|
|
|
Possible values for
|
2005-09-14 15:36:52 +04:00
|
|
|
.Ar how
|
2006-02-18 13:52:48 +03:00
|
|
|
are:
|
|
|
|
.Pp
|
|
|
|
.Bl -tag -width kungfuninja -compact
|
|
|
|
.It Li PW_POLICY_BYSTRING
|
2005-09-14 15:36:52 +04:00
|
|
|
.Ar key
|
2006-02-18 13:52:48 +03:00
|
|
|
is used as a
|
2005-09-14 15:36:52 +04:00
|
|
|
.Ft char * ,
|
|
|
|
looking up the string it contains in
|
|
|
|
.Pa /etc/passwd.conf .
|
|
|
|
.Pp
|
2006-02-18 13:52:48 +03:00
|
|
|
.It Li PW_POLICY_BYPASSWD
|
2005-09-14 15:36:52 +04:00
|
|
|
.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
|
2006-02-18 13:52:48 +03:00
|
|
|
.It Li PW_POLICY_BYGROUP
|
2005-09-14 15:36:52 +04:00
|
|
|
.Ar key
|
2006-02-18 13:52:48 +03:00
|
|
|
is used as a
|
2005-09-14 15:36:52 +04:00
|
|
|
.Ft struct group * ,
|
|
|
|
looking up the group name in
|
|
|
|
.Ft gr_name .
|
2006-02-18 13:52:48 +03:00
|
|
|
.El
|
2005-09-14 15:36:52 +04:00
|
|
|
.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.
|
2006-02-18 13:52:48 +03:00
|
|
|
.Pp
|
|
|
|
.Fn pw_policy_test
|
|
|
|
can be used to check if the password in
|
|
|
|
.Ar pw
|
|
|
|
is compliant with the policy in
|
|
|
|
.Ar policy .
|
2005-09-14 15:36:52 +04:00
|
|
|
.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
|
2006-02-18 19:45:01 +03:00
|
|
|
.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.
|
2005-09-14 15:36:52 +04:00
|
|
|
.Sh RETURN VALUES
|
2006-02-18 13:52:48 +03:00
|
|
|
.Fn pw_policy_load
|
2006-02-18 19:32:45 +03:00
|
|
|
returns a
|
2006-02-25 00:07:29 +03:00
|
|
|
.Ar pw_policy_t
|
2006-02-25 00:06:50 +03:00
|
|
|
on success, or
|
|
|
|
.Dv NULL
|
|
|
|
on failure, in which case the
|
2006-03-23 22:31:37 +03:00
|
|
|
.Va errno
|
2006-02-18 19:32:45 +03:00
|
|
|
variable will be set to any of the following values indicating the
|
|
|
|
reason for the failure:
|
2005-09-14 15:36:52 +04:00
|
|
|
.Bl -tag -width Er
|
|
|
|
.It Bq Er ENOENT
|
2006-02-18 13:52:48 +03:00
|
|
|
The
|
2005-09-14 15:36:52 +04:00
|
|
|
.Pa /etc/passwd.conf
|
2006-02-18 13:52:48 +03:00
|
|
|
is missing.
|
2005-09-14 15:36:52 +04:00
|
|
|
.It Bq Er EINVAL
|
2006-02-18 13:52:48 +03:00
|
|
|
Invalid value for the
|
2005-09-14 15:36:52 +04:00
|
|
|
.Ar how
|
2006-02-18 13:52:48 +03:00
|
|
|
parameter or an invalid value in the password policy specification.
|
2005-09-14 15:36:52 +04:00
|
|
|
.El
|
2006-02-18 13:52:48 +03:00
|
|
|
.Pp
|
2006-02-18 19:32:45 +03:00
|
|
|
.Fn pw_policy_load
|
|
|
|
can also set
|
2006-03-23 22:31:37 +03:00
|
|
|
.Va errno
|
2006-02-18 19:32:45 +03:00
|
|
|
to a value returned by the called handlers and/or
|
|
|
|
.Xr malloc 3 .
|
|
|
|
.Pp
|
2006-02-18 13:52:48 +03:00
|
|
|
.Fn pw_policy_test
|
2006-03-23 22:31:37 +03:00
|
|
|
returns 0 if the password follows the policy, or \-1 if it doesn't,
|
|
|
|
.Va errno
|
2006-03-20 01:58:21 +03:00
|
|
|
can be set to any of the following values:
|
2006-02-18 13:52:48 +03:00
|
|
|
.Bl -tag -width Er
|
|
|
|
.It Bq Er EPERM
|
|
|
|
The password does not follow the password policy.
|
2006-03-20 01:58:21 +03:00
|
|
|
.It Bq Er EINVAL
|
2006-02-25 00:06:50 +03:00
|
|
|
.Dv NULL
|
|
|
|
pointer was passed as the password.
|
2006-02-18 13:52:48 +03:00
|
|
|
.El
|
|
|
|
.Pp
|
|
|
|
In addition,
|
2006-03-23 22:31:37 +03:00
|
|
|
.Va errno
|
2006-03-20 01:58:21 +03:00
|
|
|
can be set to any error code returned by the handlers.
|
2005-09-14 15:36:52 +04:00
|
|
|
.Sh FILES
|
|
|
|
.Bl -tag -width /etc/passwd.conf -compact
|
|
|
|
.It Pa /etc/passwd.conf
|
|
|
|
password configuration file.
|
|
|
|
.El
|
|
|
|
.Sh EXAMPLES
|
2006-02-18 19:32:45 +03:00
|
|
|
Declare a password policy storage:
|
2005-09-14 15:36:52 +04:00
|
|
|
.Bd -literal -offset indent
|
2006-02-18 19:32:45 +03:00
|
|
|
pw_policy_t policy;
|
2006-02-18 13:52:48 +03:00
|
|
|
.Ed
|
|
|
|
.Pp
|
|
|
|
Load the system global password policy into
|
|
|
|
.Ar policy :
|
|
|
|
.Bd -literal -offset indent
|
2006-02-18 19:32:45 +03:00
|
|
|
policy = pw_policy_load(NULL, 0);
|
|
|
|
if (policy == NULL)
|
2006-02-18 13:52:48 +03:00
|
|
|
errx(1, "Can't load password policy");
|
2005-09-14 15:36:52 +04:00
|
|
|
.Ed
|
|
|
|
.Pp
|
2006-02-18 13:52:48 +03:00
|
|
|
Load a policy for a user whose password database entry is in
|
2005-09-14 15:36:52 +04:00
|
|
|
.Ar pw_entry
|
2006-02-18 13:52:48 +03:00
|
|
|
into
|
|
|
|
.Ar policy :
|
2005-09-14 15:36:52 +04:00
|
|
|
.Bd -literal -offset indent
|
2006-02-18 19:32:45 +03:00
|
|
|
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);
|
2005-09-14 15:36:52 +04:00
|
|
|
.Ed
|
|
|
|
.Pp
|
|
|
|
Note that
|
2006-02-18 13:52:48 +03:00
|
|
|
.Fn pw_policy_load
|
2005-09-14 15:36:52 +04:00
|
|
|
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
|
2006-02-18 13:52:48 +03:00
|
|
|
Load the password policy for a group
|
|
|
|
whose group database entry is in
|
|
|
|
.Ar grent ,
|
|
|
|
into
|
|
|
|
.Ar policy :
|
2006-02-18 19:32:45 +03:00
|
|
|
.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);
|
2006-02-18 13:52:48 +03:00
|
|
|
.Ed
|
|
|
|
.Pp
|
|
|
|
Check if
|
|
|
|
.Ar the_password
|
|
|
|
follows the policy in
|
|
|
|
.Ar policy :
|
|
|
|
.Bd -literal -offset indent
|
2006-03-20 01:58:21 +03:00
|
|
|
if (pw_policy_test(policy, the_password) != 0)
|
2006-02-18 13:52:48 +03:00
|
|
|
warnx("Please refer to the password policy");
|
|
|
|
.Ed
|
|
|
|
.Pp
|
2006-02-18 19:32:45 +03:00
|
|
|
After finished using the password policy, free it:
|
|
|
|
.Bd -literal -offset indent
|
|
|
|
pw_policy_free(policy);
|
|
|
|
.Ed
|
|
|
|
.Pp
|
2005-09-14 15:36:52 +04:00
|
|
|
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
|
2006-02-18 19:32:45 +03:00
|
|
|
.Fn pw_policy_load ,
|
|
|
|
.Fn pw_policy_test ,
|
2006-02-18 13:52:48 +03:00
|
|
|
and
|
2006-02-18 19:32:45 +03:00
|
|
|
.Fn pw_policy_free
|
2006-02-18 13:52:48 +03:00
|
|
|
functions first appeared in
|
2005-09-14 15:36:52 +04:00
|
|
|
.Nx 4.0 .
|
|
|
|
.Sh AUTHORS
|
|
|
|
.An Elad Efrat
|
|
|
|
.Aq elad@NetBSD.org
|