Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / lib / libutil / pw_policy.3
blobc96acc1ae5901844e06291725fdd1592fcfbb92d
1 .\" $NetBSD: pw_policy.3,v 1.8 2006/03/23 19:31:37 wiz Exp $
2 .\"
3 .\" Copyright (c) 2005, 2006 Elad Efrat <elad@NetBSD.org>
4 .\" All rights reserved.
5 .\"
6 .\" Redistribution and use in source and binary forms, with or without
7 .\" modification, are permitted provided that the following conditions
8 .\" are met:
9 .\" 1. Redistributions of source code must retain the above copyright
10 .\"    notice, this list of conditions and the following disclaimer.
11 .\" 2. Redistributions in binary form must reproduce the above copyright
12 .\"    notice, this list of conditions and the following disclaimer in the
13 .\"    documentation and/or other materials provided with the distribution.
14 .\" 3. The name of the author may not be used to endorse or promote products
15 .\"    derived from this software without specific prior written permission.
16 .\"
17 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 .\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 .\"
28 .Dd March 19, 2006
29 .Dt PW_POLICY 3
30 .Os
31 .Sh NAME
32 .Nm pw_policy_load ,
33 .Nm pw_policy_test
34 .Nd password policy enforcement
35 .Sh LIBRARY
36 .Lb libutil
37 .Sh SYNOPSIS
38 .In util.h
39 .Ft pw_policy_t
40 .Fn pw_policy_load "void *key" "int how"
41 .Ft int
42 .Fn pw_policy_test "pw_policy_t policy" "char *pw"
43 .Ft void
44 .Fn pw_policy_free "pw_policy_t policy"
45 .Sh DESCRIPTION
46 The
47 .Fn pw_policy_load ,
48 .Fn pw_policy_test ,
49 and
50 .Fn pw_policy_free
51 functions are used as an interface to the system's password policy
52 as specified in
53 .Pa /etc/passwd.conf .
54 .Pp
55 .Fn pw_policy_load
56 will load a password policy and return a pointer to a
57 .Ar pw_policy_t
58 containing it.
59 It is the caller's responsibility to free this pointer using
60 .Fn pw_policy_free .
61 .Pp
62 Using
63 .Xr pw_getconf 3
64 terminology,
65 .Fn pw_policy_load
66 accepts a
67 .Ar key
68 to be used when searching
69 .Pa /etc/passwd.conf
70 for a password policy.
71 This key contains various options describing different policies.
72 Some built-in ones are described along with their syntax below.
73 .Pp
74 To allow calling from various program contexts
75 and using various password policy retrieval schemes,
76 .Ar how
77 tells
78 .Fn pw_policy_load
79 how to treat
80 .Ar key .
81 .Pp
82 Possible values for
83 .Ar how
84 are:
85 .Pp
86 .Bl -tag -width kungfuninja -compact
87 .It Li PW_POLICY_BYSTRING
88 .Ar key
89 is used as a
90 .Ft char * ,
91 looking up the string it contains in
92 .Pa /etc/passwd.conf .
93 .Pp
94 .It Li PW_POLICY_BYPASSWD
95 .Ar key
96 is used as a
97 .Ft struct passwd * ,
98 first looking up the username in
99 .Ft pw_name ,
100 and if no key can be found, it will try the login class in
101 .Ft pw_class .
103 .It Li PW_POLICY_BYGROUP
104 .Ar key
105 is used as a
106 .Ft struct group * ,
107 looking up the group name in
108 .Ft gr_name .
112 .Ar key
114 .Dv NULL ,
115 or no specified key can be found, the default key,
116 .Dq pw_policy ,
117 is used.
118 If even the default key can't be found,
119 the password is accepted as no policy is defined.
121 .Fn pw_policy_test
122 can be used to check if the password in
123 .Ar pw
124 is compliant with the policy in
125 .Ar policy .
126 .Sh BUILT-IN POLICY SYNTAX
127 Available built-in policy options include the following:
129 .Bl -tag -width kungfuninja -compact
130 .It length
131 Length of the password.
132 .It uppercase
133 Number of upper-case characters in the password.
134 .It lowercase
135 Number of lower-case characters in the password.
136 .It digits
137 Number of digits in the password.
138 .It punctuation
139 Number of punctuation characters in the password.
140 .It nclasses
141 Number of different character classes in the password.
142 .It ntoggles
143 How often a user has to toggle between character classes in the password.
146 Options are used inside keys.
147 An option uses a format of
148 .Dq option = value .
149 For the built-in options, we use either
150 .Dq N
152 .Dq N-M
153 for the value.
155 The first,
156 .Dq N
157 format, specifies a single length.
158 For example, the following option specifies that the password should
159 have exactly 3 upper-case characters:
160 .Bd -literal -offset indent
161 uppercase = 3
164 The second,
165 .Dq N-M
166 format, can be used to specify a range.
167 Forcing a policy for number of digits between 1 and 4 would be:
168 .Bd -literal -offset indent
169 digits = 1-4
172 The characters
173 .Sq 0
175 .Sq *
176 can also be used to indicate
177 .Dq not allowed
179 .Dq any number ,
180 respectively.
181 To illustrate, the following example states that the number of
182 punctuation characters should be at least two:
183 .Bd -literal -offset indent
184 punctuation = 2-*
187 No more than 7 digits:
188 .Bd -literal -offset indent
189 digits = *-7
192 Any number of lower-case characters:
193 .Bd -literal -offset indent
194 lowercase = *
197 Upper-case characters not allowed:
198 .Bd -literal -offset indent
199 uppercase = 0
202 To specify that the password must be at least 8 characters long:
203 .Bd -literal -offset indent
204 length = 8-*
207 Specifying a password must have at least 3 different character classes:
208 .Bd -literal -offset indent
209 nclasses = 3-*
212 And that the user must change character class every 2 characters:
213 .Bd -literal -offset indent
214 ntoggles = *-2
217 Note that when using the
218 .Dq nclasses
219 directive, the policy will be initialized to allow any number of characters
220 from all classes.
221 If desired, this should be overridden after the
222 .Dq nclasses
223 option.
224 .Sh RETURN VALUES
225 .Fn pw_policy_load
226 returns a
227 .Ar pw_policy_t
228 on success, or
229 .Dv NULL
230 on failure, in which case the
231 .Va errno
232 variable will be set to any of the following values indicating the
233 reason for the failure:
234 .Bl -tag -width Er
235 .It Bq Er ENOENT
237 .Pa /etc/passwd.conf
238 is missing.
239 .It Bq Er EINVAL
240 Invalid value for the
241 .Ar how
242 parameter or an invalid value in the password policy specification.
245 .Fn pw_policy_load
246 can also set
247 .Va errno
248 to a value returned by the called handlers and/or
249 .Xr malloc 3 .
251 .Fn pw_policy_test
252 returns 0 if the password follows the policy, or \-1 if it doesn't,
253 .Va errno
254 can be set to any of the following values:
255 .Bl -tag -width Er
256 .It Bq Er EPERM
257 The password does not follow the password policy.
258 .It Bq Er EINVAL
259 .Dv NULL
260 pointer was passed as the password.
263 In addition,
264 .Va errno
265 can be set to any error code returned by the handlers.
266 .Sh FILES
267 .Bl -tag -width /etc/passwd.conf -compact
268 .It Pa /etc/passwd.conf
269 password configuration file.
271 .Sh EXAMPLES
272 Declare a password policy storage:
273 .Bd -literal -offset indent
274 pw_policy_t policy;
277 Load the system global password policy into
278 .Ar policy :
279 .Bd -literal -offset indent
280 policy = pw_policy_load(NULL, 0);
281 if (policy == NULL)
282         errx(1, "Can't load password policy");
285 Load a policy for a user whose password database entry is in
286 .Ar pw_entry
287 into
288 .Ar policy :
289 .Bd -literal -offset indent
290 policy = pw_policy_load(pw_entry, PW_POLICY_BYPASSWD);
291 if (policy == NULL)
292         errx(1, "Can't load password policy for \e"%s\e"", pw_entry-\*[Gt]pw_name);
295 Note that
296 .Fn pw_policy_load
297 will first look for a password policy for the username in
298 .Ar pw_entry-\*[Gt]pw_name ,
299 if not found, it will try looking for a policy for the login class in
300 .Ar pw_entry-\*[Gt]pw_class ,
301 and if it can't find such either it will fallback to the default key,
302 .Dq pw_policy .
304 Load the password policy for a group
305 whose group database entry is in
306 .Ar grent ,
307 into
308 .Ar policy :
309 .Bd -literal -offset indent
310 policy = pw_policy_load(grent, PW_POLICY_BYGROUP);
311 if (policy == NULL)
312         errx(1, "Can't load password policy for \e"%s\e"", grent-\*[Gt]gr_name);
315 Check if
316 .Ar the_password
317 follows the policy in
318 .Ar policy :
319 .Bd -literal -offset indent
320 if (pw_policy_test(policy, the_password) != 0)
321         warnx("Please refer to the password policy");
324 After finished using the password policy, free it:
325 .Bd -literal -offset indent
326 pw_policy_free(policy);
329 An example for a common default password policy in
330 .Pa /etc/passwd.conf :
331 .Bd -literal -offset indent
332 pw_policy:
333   length = 8-*          # At least 8 characters long,
334   lowercase = 1-*       # combining lowercase,
335   uppercase = 1-*       # uppercase,
336   digits = 1-*          # and digits.
337   punctuation = *       # Punctuation is optional.
340 A different policy that might be used:
341 .Bd -literal -offset indent
342   nclasses = 3-*        # At least 3 different character classes,
343   ntoggles = *-2        # not more than 2 same class in a row.
345 .Sh SEE ALSO
346 .Xr pw_getconf 3 ,
347 .Xr passwd.conf 5
348 .Sh HISTORY
350 .Fn pw_policy_load ,
351 .Fn pw_policy_test ,
353 .Fn pw_policy_free
354 functions first appeared in
355 .Nx 4.0 .
356 .Sh AUTHORS
357 .An Elad Efrat
358 .Aq elad@NetBSD.org