]> eyrie.org Git - kerberos/krb5-strength.git/blob - tools/heimdal-history.1
New upstream version 3.2
[kerberos/krb5-strength.git] / tools / heimdal-history.1
1 .\" Automatically generated by Pod::Man 4.11 (Pod::Simple 3.35)
2 .\"
3 .\" Standard preamble:
4 .\" ========================================================================
5 .de Sp \" Vertical space (when we can't use .PP)
6 .if t .sp .5v
7 .if n .sp
8 ..
9 .de Vb \" Begin verbatim text
10 .ft CW
11 .nf
12 .ne \\$1
13 ..
14 .de Ve \" End verbatim text
15 .ft R
16 .fi
17 ..
18 .\" Set up some character translations and predefined strings.  \*(-- will
19 .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
20 .\" double quote, and \*(R" will give a right double quote.  \*(C+ will
21 .\" give a nicer C++.  Capital omega is used to do unbreakable dashes and
22 .\" therefore won't be available.  \*(C` and \*(C' expand to `' in nroff,
23 .\" nothing in troff, for use with C<>.
24 .tr \(*W-
25 .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
26 .ie n \{\
27 .    ds -- \(*W-
28 .    ds PI pi
29 .    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
30 .    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
31 .    ds L" ""
32 .    ds R" ""
33 .    ds C` ""
34 .    ds C' ""
35 'br\}
36 .el\{\
37 .    ds -- \|\(em\|
38 .    ds PI \(*p
39 .    ds L" ``
40 .    ds R" ''
41 .    ds C`
42 .    ds C'
43 'br\}
44 .\"
45 .\" Escape single quotes in literal strings from groff's Unicode transform.
46 .ie \n(.g .ds Aq \(aq
47 .el       .ds Aq '
48 .\"
49 .\" If the F register is >0, we'll generate index entries on stderr for
50 .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
51 .\" entries marked with X<> in POD.  Of course, you'll have to process the
52 .\" output yourself in some meaningful fashion.
53 .\"
54 .\" Avoid warning from groff about undefined register 'F'.
55 .de IX
56 ..
57 .nr rF 0
58 .if \n(.g .if rF .nr rF 1
59 .if (\n(rF:(\n(.g==0)) \{\
60 .    if \nF \{\
61 .        de IX
62 .        tm Index:\\$1\t\\n%\t"\\$2"
63 ..
64 .        if !\nF==2 \{\
65 .            nr % 0
66 .            nr F 2
67 .        \}
68 .    \}
69 .\}
70 .rr rF
71 .\"
72 .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
73 .\" Fear.  Run.  Save yourself.  No user-serviceable parts.
74 .    \" fudge factors for nroff and troff
75 .if n \{\
76 .    ds #H 0
77 .    ds #V .8m
78 .    ds #F .3m
79 .    ds #[ \f1
80 .    ds #] \fP
81 .\}
82 .if t \{\
83 .    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
84 .    ds #V .6m
85 .    ds #F 0
86 .    ds #[ \&
87 .    ds #] \&
88 .\}
89 .    \" simple accents for nroff and troff
90 .if n \{\
91 .    ds ' \&
92 .    ds ` \&
93 .    ds ^ \&
94 .    ds , \&
95 .    ds ~ ~
96 .    ds /
97 .\}
98 .if t \{\
99 .    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
100 .    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
101 .    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
102 .    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
103 .    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
104 .    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
105 .\}
106 .    \" troff and (daisy-wheel) nroff accents
107 .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
108 .ds 8 \h'\*(#H'\(*b\h'-\*(#H'
109 .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
110 .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
111 .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
112 .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
113 .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
114 .ds ae a\h'-(\w'a'u*4/10)'e
115 .ds Ae A\h'-(\w'A'u*4/10)'E
116 .    \" corrections for vroff
117 .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
118 .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
119 .    \" for low resolution devices (crt and lpr)
120 .if \n(.H>23 .if \n(.V>19 \
121 \{\
122 .    ds : e
123 .    ds 8 ss
124 .    ds o a
125 .    ds d- d\h'-1'\(ga
126 .    ds D- D\h'-1'\(hy
127 .    ds th \o'bp'
128 .    ds Th \o'LP'
129 .    ds ae ae
130 .    ds Ae AE
131 .\}
132 .rm #[ #] #H #V #F C
133 .\" ========================================================================
134 .\"
135 .IX Title "HEIMDAL-HISTORY 1"
136 .TH HEIMDAL-HISTORY 1 "2020-05-17" "3.2" "krb5-strength"
137 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
138 .\" way too many mistakes in technical documents.
139 .if n .ad l
140 .nh
141 .SH "NAME"
142 heimdal\-history \- Password history via Heimdal external strength checking
143 .SH "SYNOPSIS"
144 .IX Header "SYNOPSIS"
145 \&\fBheimdal-history\fR [\fB\-chmq\fR] [\fB\-b\fR \fItarget-time\fR] [\fB\-d\fR \fIdatabase\fR]
146     [\fB\-S\fR \fIlength-stats-db\fR] [\fB\-s\fR \fIstrength-program\fR] [\fBprincipal\fR]
147 .SH "DESCRIPTION"
148 .IX Header "DESCRIPTION"
149 \&\fBheimdal-history\fR is an implementation of password history via the Heimdal
150 external password strength checking interface.  It stores separate history for
151 each principal, hashed using Crypt::PBKDF2 with randomly-generated salt.  (The
152 randomness is from a weak pseudorandom number generator, not strongly random.)
153 Password history is stored indefinitely (implementing infinite history); older
154 password hashes are never removed by this program.
155 .PP
156 Password history is stored in a BerkeleyDB \s-1DB_HASH\s0 file.  The key is the
157 principal.  The value is a \s-1JSON\s0 array of objects, each of which has two keys.
158 \&\f(CW\*(C`timestamp\*(C'\fR contains the time when the history entry was added (in \s-1POSIX\s0
159 seconds since \s-1UNIX\s0 epoch), and \f(CW\*(C`hash\*(C'\fR contains the hash of a previously-used
160 password in the Crypt::PBKDF2 LDAP-compatible format.  Passwords are hashed
161 using \s-1PBKDF2\s0 (from PKCS#5) with \s-1SHA\-256\s0 as the underlying hash function using
162 a number of rounds configured in this script.  See Crypt::PBKDF2 for more
163 information.
164 .PP
165 \&\fBheimdal-history\fR also checks password strength before checking history.  It
166 does so by invoking another program that also uses the Heimdal external
167 password strength checking interface.  By default, it runs
168 \&\fB/usr/bin/heimdal\-strength\fR.  Only if that program approves the password does
169 it hash it and check history.
170 .PP
171 For more information on how to set up password history, see \*(L"\s-1CONFIGURATION\*(R"\s0
172 below.
173 .PP
174 As with any implementation of the Heimdal external password strength checking
175 protocol, \fBheimdal-history\fR expects, on standard input:
176 .PP
177 .Vb 3
178 \&    principal: <principal>
179 \&    new\-password: <password>
180 \&    end
181 .Ve
182 .PP
183 (with no leading whitespace).  <principal> is the principal changing its
184 password (passed to the other password strength checking program but otherwise
185 unused here), and <password> is the new password.  There must be exactly one
186 space after the colon.  Any subsequent spaces are taken to be part of the
187 principal or password.
188 .PP
189 If the password is accepted, \fBheimdal-history\fR will assume that it will be
190 used and will update the history database to record the new password.  It will
191 also update the password length statistics database to account for the new
192 password.
193 .PP
194 If invoked as root, \fBheimdal-history\fR will run the external strength checking
195 program as user \f(CW\*(C`nobody\*(C'\fR and group \f(CW\*(C`nogroup\*(C'\fR, and will check and write to
196 the history database as user \f(CW\*(C`_history\*(C'\fR and group \f(CW\*(C`_history\*(C'\fR.  These users
197 must exist on the system if it is run as root.
198 .PP
199 The result of each password check will be logged to syslog (priority \s-1LOG_INFO,\s0
200 facility \s-1LOG_AUTH\s0).  Each log line will be a set of key/value pairs in the
201 format \f(CW\*(C`\f(CIkey\f(CW=\f(CIvalue\f(CW\*(C'\fR.  The keys are:
202 .IP "action" 4
203 .IX Item "action"
204 The action performed (currently always \f(CW\*(C`check\*(C'\fR).
205 .IP "principal" 4
206 .IX Item "principal"
207 The principal for which a password was checked.
208 .IP "error" 4
209 .IX Item "error"
210 An internal error message that did not stop the history check, but which may
211 indicate that something is wrong with the history database (such as corrupted
212 entries or invalid hashes).  If this key is present, neither \f(CW\*(C`result\*(C'\fR nor
213 \&\f(CW\*(C`reason\*(C'\fR will be present.  There will be a subsequent log message from the
214 same invocation giving the final result of the history check (assuming
215 \&\fBheimdal-history\fR doesn't exit with a fatal error).
216 .IP "result" 4
217 .IX Item "result"
218 Either \f(CW\*(C`accepted\*(C'\fR or \f(CW\*(C`rejected\*(C'\fR.
219 .IP "reason" 4
220 .IX Item "reason"
221 If the password was rejected, the reason for the rejection.
222 .PP
223 The value will be surrounded with double quotes if it contains a double quote
224 or space.  Any double quotes in the value will be doubled, so \f(CW\*(C`"\*(C'\fR becomes
225 \&\f(CW""\fR.
226 .SH "OPTIONS"
227 .IX Header "OPTIONS"
228 .IP "\fB\-b\fR \fItarget-time\fR, \fB\-\-benchmark\fR=\fItarget-time\fR" 4
229 .IX Item "-b target-time, --benchmark=target-time"
230 Do not do a password history check.  Instead, benchmark the hash algorithm
231 with various possible iteration counts and find an iteration count that
232 results in \fItarget-time\fR seconds of computation time required to hash a
233 password (which should be a real number).  A result will be considered
234 acceptable if it is within 0.005 seconds of the target time.  The results will
235 be printed to standard output and then \fBheimdal-history\fR will exit
236 successfully.
237 .IP "\fB\-c\fR, \fB\-\-check\-only\fR" 4
238 .IX Item "-c, --check-only"
239 Check password history and password strength and print the results as normal,
240 but do not update the history or length statistics databases.  This is a
241 read-only mode of operation that will not make any changes to the underlying
242 database, only report if a password would currently be accepted.
243 .IP "\fB\-d\fR \fIdatabase\fR, \fB\-\-database\fR=\fIdatabase\fR" 4
244 .IX Item "-d database, --database=database"
245 Use \fIdatabase\fR as the history database file instead of the default
246 (\fI/var/lib/heimdal\-history/history.db\fR).  Primarily used for testing, since
247 Heimdal won't pass this argument.
248 .IP "\fB\-h\fR, \fB\-\-help\fR" 4
249 .IX Item "-h, --help"
250 Print a short usage message and exit.
251 .IP "\fB\-m\fR, \fB\-\-manual\fR, \fB\-\-man\fR" 4
252 .IX Item "-m, --manual, --man"
253 Display this manual and exit.
254 .IP "\fB\-q\fR, \fB\-\-quiet\fR" 4
255 .IX Item "-q, --quiet"
256 Suppress logging to syslog and only return the results on standard output and
257 standard error.  Primarily used for testing, since Heimdal won't pass this
258 argument.
259 .IP "\fB\-S\fR \fIlength-stats-db\fR, \fB\-\-stats\fR=\fIlength-stats-db\fR" 4
260 .IX Item "-S length-stats-db, --stats=length-stats-db"
261 Use \fIlength-stats-db\fR as the database file for password length statistics
262 instead of the default (\fI/var/lib/heimdal\-history/lengths.db\fR).  Primarily
263 used for testing, since Heimdal won't pass this argument.
264 .IP "\fB\-s\fR \fIstrength-program\fR, \fB\-\-strength\fR=\fIstrength-program\fR" 4
265 .IX Item "-s strength-program, --strength=strength-program"
266 Run \fIstrength-program\fR as the external strength-checking program instead of
267 the default (\fI/usr/bin/heimdal\-strength\fR).  Primarily used for testing, since
268 Heimdal won't pass this argument.
269 .SH "CONFIGURATION"
270 .IX Header "CONFIGURATION"
271 Additional setup is required to use this history implementation with your
272 Heimdal \s-1KDC.\s0
273 .PP
274 First, ensure that its dependencies are installed, and then examine the local
275 configuration settings at the top of the \fBheimdal-history\fR program.  By
276 default, it requires a \f(CW\*(C`_history\*(C'\fR user and \f(CW\*(C`_history\*(C'\fR group be present on
277 the system, and all history information will be read and written as that user
278 and group.  It also requires a \f(CW\*(C`nobody\*(C'\fR user and \f(CW\*(C`nogroup\*(C'\fR group to be
279 present (this should be the default with most variants of \s-1UNIX\s0), and all
280 strength checking will be done as that user and group.  It uses various files
281 in \fI/var/lib/heimdal\-history\fR to store history and statistical information by
282 default, so if using the defaults, create that directory and ensure it is
283 writable by the \f(CW\*(C`_history\*(C'\fR user.
284 .PP
285 Once that setup is done, change your \f(CW\*(C`[password_quality]\*(C'\fR configuration in
286 \&\fIkrb5.conf\fR or \fIkdc.conf\fR to:
287 .PP
288 .Vb 3
289 \&    [password_quality]
290 \&        policies         = external\-check
291 \&        external_program = /usr/local/bin/heimdal\-history
292 .Ve
293 .PP
294 The \fBheimdal-history\fR program will automatically also run \fBheimdal-strength\fR
295 as well, looking for it in \fI/usr/bin\fR.  Change the \f(CW$STRENGTH_PROGRAM\fR
296 setting at the top of the script if you have that program in a different
297 location.  You should continue to configure \fBheimdal-strength\fR as if you were
298 running it directly.
299 .SH "RETURN STATUS"
300 .IX Header "RETURN STATUS"
301 On approval of the password, \fBheimdal-history\fR will print \f(CW\*(C`APPROVED\*(C'\fR and a
302 newline to standard output and exit with status 0.
303 .PP
304 If the password is rejected by the strength checking program or if it (or a
305 version with a single character removed) matches one of the hashes stored in
306 the password history, \fBheimdal-history\fR will print the reason for rejection
307 to standard error and exit with status 0.
308 .PP
309 On any internal error, \fBheimdal-history\fR will print the error to standard
310 error and exit with a non-zero status.
311 .SH "FILES"
312 .IX Header "FILES"
313 .IP "\fI/usr/bin/heimdal\-strength\fR" 4
314 .IX Item "/usr/bin/heimdal-strength"
315 The default password strength checking program.  This program must follow the
316 Heimdal external password strength checking \s-1API.\s0
317 .IP "\fI/var/lib/heimdal\-history/history.db\fR" 4
318 .IX Item "/var/lib/heimdal-history/history.db"
319 The default database path.  If \fBheimdal-strength\fR is run as root, this file
320 needs to be readable and writable by user \f(CW\*(C`_history\*(C'\fR and group \f(CW\*(C`_history\*(C'\fR.
321 If it doesn't exist, it will be created with mode 0600.
322 .IP "\fI/var/lib/heimdal\-history/history.db.lock\fR" 4
323 .IX Item "/var/lib/heimdal-history/history.db.lock"
324 The lock file used to synchronize access to the history database.  As with the
325 history database, if \fBheimdal-strength\fR is run as root, this file needs to be
326 readable and writable by user \f(CW\*(C`_history\*(C'\fR and group \f(CW\*(C`_history\*(C'\fR.
327 .IP "\fI/var/lib/heimdal\-history/lengths.db\fR" 4
328 .IX Item "/var/lib/heimdal-history/lengths.db"
329 The default length statistics path, which will be a BerkeleyDB \s-1DB_HASH\s0 file of
330 password lengths to counts of passwords with that length.  If
331 \&\fBheimdal-strength\fR is run as root, this file needs to be readable and
332 writable by user \f(CW\*(C`_history\*(C'\fR and group \f(CW\*(C`_history\*(C'\fR.  If it doesn't exist, it
333 will be created with mode 0600.
334 .IP "\fI/var/lib/heimdal\-history/lengths.db.lock\fR" 4
335 .IX Item "/var/lib/heimdal-history/lengths.db.lock"
336 The lock file used to synchronize access to the length statistics database.
337 As with the length statistics database, if \fBheimdal-strength\fR is run as root,
338 this file needs to be readable and writable by user \f(CW\*(C`_history\*(C'\fR and group
339 \&\f(CW\*(C`_history\*(C'\fR.
340 .SH "AUTHOR"
341 .IX Header "AUTHOR"
342 Russ Allbery <eagle@eyrie.org>
343 .SH "COPYRIGHT AND LICENSE"
344 .IX Header "COPYRIGHT AND LICENSE"
345 Copyright 2016\-2017, 2020 Russ Allbery <eagle@eyrie.org>
346 .PP
347 Copyright 2013\-2014 The Board of Trustees of the Leland Stanford Junior
348 University
349 .PP
350 Permission is hereby granted, free of charge, to any person obtaining a copy
351 of this software and associated documentation files (the \*(L"Software\*(R"), to deal
352 in the Software without restriction, including without limitation the rights
353 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
354 copies of the Software, and to permit persons to whom the Software is
355 furnished to do so, subject to the following conditions:
356 .PP
357 The above copyright notice and this permission notice shall be included in all
358 copies or substantial portions of the Software.
359 .PP
360 \&\s-1THE SOFTWARE IS PROVIDED \*(L"AS IS\*(R", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
361 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
362 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\s0  \s-1IN NO EVENT SHALL THE
363 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
364 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
365 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
366 SOFTWARE.\s0
367 .PP
368 SPDX-License-Identifier: \s-1MIT\s0
369 .SH "SEE ALSO"
370 .IX Header "SEE ALSO"
371 Crypt::PBKDF2, \fBheimdal\-strength\fR\|(1)