.\" $NetBSD: pw_policy.3,v 1.9 2007/01/09 14:04:44 elad Exp $ .\" .\" Copyright (c) 2005, 2006 Elad Efrat .\" All rights reserved. .\" .\" 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. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. 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