source: heimdal/trunk/doc/init-creds@ 4

Last change on this file since 4 was 1, checked in by Paul Smedley, 10 years ago

Initial commit of Heimdal 1.5.3

File size: 15.0 KB
Line 
1Currently, getting an initial ticket for a user involves many function
2calls, especially when a full set of features including password
3expiration and challenge preauthentication is desired. In order to
4solve this problem, a new api is proposed.
5
6typedef struct _krb5_prompt {
7 char *prompt;
8 int hidden;
9 krb5_data *reply;
10} krb5_prompt;
11
12typedef int (*krb5_prompter_fct)(krb5_context context,
13 void *data,
14 const char *banner,
15 int num_prompts,
16 krb5_prompt prompts[]);
17
18typedef struct _krb5_get_init_creds_opt {
19 krb5_flags flags;
20 krb5_deltat tkt_life;
21 krb5_deltat renew_life;
22 int forwardable;
23 int proxiable;
24 krb5_enctype *etype_list;
25 int etype_list_length;
26 krb5_address **address_list;
27 /* XXX the next three should not be used, as they may be
28 removed later */
29 krb5_preauthtype *preauth_list;
30 int preauth_list_length;
31 krb5_data *salt;
32} krb5_get_init_creds_opt;
33
34#define KRB5_GET_INIT_CREDS_OPT_TKT_LIFE 0x0001
35#define KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE 0x0002
36#define KRB5_GET_INIT_CREDS_OPT_FORWARDABLE 0x0004
37#define KRB5_GET_INIT_CREDS_OPT_PROXIABLE 0x0008
38#define KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST 0x0010
39#define KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST 0x0020
40#define KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST 0x0040
41#define KRB5_GET_INIT_CREDS_OPT_SALT 0x0080
42
43void krb5_get_init_creds_opt_init(krb5_get_init_creds_opt *opt);
44
45void krb5_get_init_creds_opt_set_tkt_life(krb5_get_init_creds_opt *opt,
46 krb5_deltat tkt_life);
47void krb5_get_init_creds_opt_set_renew_life(krb5_get_init_creds_opt *opt,
48 krb5_deltat renew_life);
49void krb5_get_init_creds_opt_set_forwardable(krb5_get_init_creds_opt *opt,
50 int forwardable);
51void krb5_get_init_creds_opt_set_proxiable(krb5_get_init_creds_opt *opt,
52 int proxiable);
53void krb5_get_init_creds_opt_set_etype_list(krb5_get_init_creds_opt *opt,
54 krb5_enctype *etype_list,
55 int etype_list_length);
56void krb5_get_init_creds_opt_set_address_list(krb5_get_init_creds_opt *opt,
57 krb5_address **addresses);
58void krb5_get_init_creds_opt_set_preauth_list(krb5_get_init_creds_opt *opt,
59 krb5_preauthtype *preauth_list,
60 int preauth_list_length);
61void krb5_get_init_creds_opt_set_salt(krb5_get_init_creds_opt *opt,
62 krb5_data *salt);
63
64krb5_error_code
65krb5_get_init_creds_password(krb5_context context,
66 krb5_creds *creds,
67 krb5_principal client,
68 char *password,
69 krb5_prompter_fct prompter,
70 void *data,
71 krb5_deltat start_time,
72 char *in_tkt_service,
73 krb5_get_init_creds_opt *options);
74
75This function will attempt to acquire an initial ticket. The function
76will perform whatever tasks are necessary to do so. This may include
77changing an expired password, preauthentication.
78
79The arguments divide into two types. Some arguments are basically
80invariant and arbitrary across all initial tickets, and if not
81specified are determined by configuration or library defaults. Some
82arguments are different for each execution or application, and if not
83specified can be determined correctly from system configuration or
84environment. The former arguments are contained in a structure whose
85pointer is passed to the function. A bitmask specifies which elements
86of the structure should be used. In most cases, a NULL pointer can be
87used. The latter arguments are specified as individual arguments to
88the function.
89
90If a pointer to a credential is specified, the initial credential is
91filled in. If the caller only wishes to do a simple password check
92and will not be doing any other kerberos functions, then a NULL
93pointer may be specified, and the credential will be destroyed.
94
95If the client name is non-NULL, the initial ticket requested will be
96for that principal. Otherwise, the principal will be the username
97specified by the USER environment variable, or if the USER environment
98variable is not set, the username corresponding to the real user id of
99the caller.
100
101If the password is non-NULL, then this string is used as the password.
102Otherwise, the prompter function will be used to prompt the user for
103the password.
104
105If a prompter function is non-NULL, it will be used if additional user
106input is required, such as if the user's password has expired and
107needs to be changed, or if input preauthentication is necessary. If
108no function is specified and input is required, then the login will
109fail.
110
111 The context argument is the same as that passed to krb5_login.
112 The data argument is passed unmodified to the prompter
113 function and is intended to be used to pass application data
114 (such as a display handle) to the prompter function.
115
116 The banner argument, if non-NULL, will indicate what sort of
117 input is expected from the user (for example, "Password has
118 expired and must be changed" or "Enter Activcard response for
119 challenge 012345678"), and should be displayed accordingly.
120
121 The num_prompts argument indicates the number of values which
122 should be prompted for. If num_prompts == 0, then the banner
123 contains an informational message which should be displayed to
124 the user.
125
126 The prompts argument contains an array describing the values
127 for which the user should be prompted. The prompt member
128 indicates the prompt for each value ("Enter new
129 password"/"Enter it again", or "Challenge response"). The
130 hidden member is nonzero if the response should not be
131 displayed back to the user. The reply member is a pointer to
132 krb5_data structure which has already been allocated. The
133 prompter should fill in the structure with the NUL-terminated
134 response from the user.
135
136 If the response data does not fit, or if any other error
137 occurs, then the prompter function should return a non-zero
138 value which will be returned by the krb5_get_init_creds
139 function. Otherwise, zero should be returned.
140
141 The library function krb5_prompter_posix() implements
142 a prompter using a posix terminal for user in. This function
143 does not use the data argument.
144
145If the start_time is zero, then the requested ticket will be valid
146beginning immediately. Otherwise, the start_time indicates how far in
147the future the ticket should be postdated.
148
149If the in_tkt_service name is non-NULL, that principal name will be
150used as the server name for the initial ticket request. The realm of
151the name specified will be ignored and will be set to the realm of the
152client name. If no in_tkt_service name is specified,
153krbtgt/CLIENT-REALM@CLIENT-REALM will be used.
154
155For the rest of arguments, a configuration or library default will be
156used if no value is specified in the options structure.
157
158If a tkt_life is specified, that will be the lifetime of the ticket.
159The library default is 10 hours; there is no configuration variable
160(there should be, but it's not there now).
161
162If a renew_life is specified and non-zero, then the RENEWABLE option
163on the ticket will be set, and the value of the argument will be the
164the renewable lifetime. The configuration variable [libdefaults]
165"renew_lifetime" is the renewable lifetime if none is passed in. The
166library default is not to set the RENEWABLE option.
167
168If forwardable is specified, the FORWARDABLE option on the ticket will
169be set if and only if forwardable is non-zero. The configuration
170variable [libdefaults] "forwardable" is used if no value is passed in.
171The option will be set if and only if the variable is "y", "yes",
172"true", "t", "1", or "on", case insensitive. The library default is
173not to set the FORWARDABLE option.
174
175If proxiable is specified, the PROXIABLE option on the ticket will be
176set if and only if proxiable is non-zero. The configuration variable
177[libdefaults] "proxiable" is used if no value is passed in. The
178option will be set if and only if the variable is "y", "yes", "true",
179"t", "1", or "on", case insensitive. The library default is not to
180set the PROXIABLE option.
181
182If etype_list is specified, it will be used as the list of desired
183encryption algorithms in the request. The configuration variable
184[libdefaults] "default_tkt_enctypes" is used if no value is passed in.
185The library default is "des-cbc-md5 des-cbc-crc".
186
187If address_list is specified, it will be used as the list of addresses
188for which the ticket will be valid. The library default is to use all
189local non-loopback addresses. There is no configuration variable.
190
191If preauth_list is specified, it names preauth data types which will
192be included in the request. The library default is to interact with
193the kdc to determine the required preauth types. There is no
194configuration variable.
195
196If salt is specified, it specifies the salt which will be used when
197converting the password to a key. The library default is to interact
198with the kdc to determine the correct salt. There is no configuration
199variable.
200
201================================================================
202
203typedef struct _krb5_verify_init_creds_opt {
204 krb5_flags flags;
205 int ap_req_nofail;
206} krb5_verify_init_creds_opt;
207
208#define KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL 0x0001
209
210void krb5_verify_init_creds_opt_init(krb5_init_creds_opt *options);
211void krb5_verify_init_creds_opt_set_ap_req_nofail(krb5_init_creds_opt *options,
212 int ap_req_nofail);
213
214krb5_error_code
215krb5_verify_init_creds(krb5_context context,
216 krb5_creds *creds,
217 krb5_principal ap_req_server,
218 krb5_keytab ap_req_keytab,
219 krb5_ccache *ccache,
220 krb5_verify_init_creds_opt *options);
221
222This function will use the initial ticket in creds to make an AP_REQ
223and verify it to insure that the AS_REP has not been spoofed.
224
225If the ap_req_server name is non-NULL, then this service name will be
226used for the AP_REQ; otherwise, the default host key
227(host/hostname.domain@LOCAL-REALM) will be used.
228
229If ap_req_keytab is non-NULL, the service key for the verification
230will be read from that keytab; otherwise, the service key will be read
231from the default keytab.
232
233If the service of the ticket in creds is the same as the service name
234for the AP_REQ, then this ticket will be used directly. If the ticket
235is a tgt, then it will be used to obtain credentials for the service.
236Otherwise, the verification will fail, and return an error.
237
238Other failures of the AP_REQ verification may or may not be considered
239errors, as described below.
240
241If a pointer to a credential cache handle is specified, and the handle
242is NULL, a credential cache handle referring to all credentials
243obtained in the course of verifying the user will be returned. In
244order to avoid potential setuid race conditions and other problems
245related to file system access, this handle will refer to a memory
246credential cache. If the handle is non-NULL, then the credentials
247will be added to the existing ccache. If the caller only wishes to
248verify the password and will not be doing any other kerberos
249functions, then a NULL pointer may be specified, and the credentials
250will be deleted before the function returns.
251
252If ap_req_nofail is specified, then failures of the AP_REQ
253verification are considered errors if and only if ap_req_nofail is
254non-zero.
255
256Whether or not AP_REQ validation is performed and what failures mean
257depends on these inputs:
258
259 A) The appropriate keytab exists and contains the named key.
260
261 B) An AP_REQ request to the kdc succeeds, and the resulting AP_REQ
262can be decrypted and verified.
263
264 C) The administrator has specified in a configuration file that
265AP_REQ validation must succeed. This is basically a paranoid bit, and
266can be overridden by the application based on a command line flag or
267other application-specific info. This flag is especially useful if
268the admin is concerned that DNS might be spoofed while determining the
269host/FQDN name. The configuration variable [libdefaults]
270"verify_ap_req_nofail" is used if no value is passed in. The library
271default is not to set this option.
272
273Initial ticket verification will succeed if and only if:
274
275 - A && B or
276 - !A && !C
277
278================================================================
279
280For illustrative purposes, here's the invocations I expect some
281programs will use. Of course, error checking needs to be added.
282
283kinit:
284
285 /* Fill in client from the command line || existing ccache, and,
286 start_time, and options.{tkt_life,renew_life,forwardable,proxiable}
287 from the command line. Some or all may remain unset. */
288
289 krb5_get_init_creds(context, &creds, client,
290 krb5_initial_prompter_posix, NULL,
291 start_time, NULL, &options);
292 krb5_cc_store_cred(context, ccache, &creds);
293 krb5_free_cred_contents(context, &creds);
294
295login:
296
297 krb5_get_init_creds(context, &creds, client,
298 krb5_initial_prompter_posix, NULL,
299 0, NULL, NULL);
300 krb5_verify_init_creds(context, &creds, NULL, NULL, &vcc, NULL);
301 /* setuid */
302 krb5_cc_store_cred(context, ccache, &creds);
303 krb5_cc_copy(context, vcc, ccache);
304 krb5_free_cred_contents(context, &creds);
305 krb5_cc_destroy(context, vcc);
306
307xdm:
308
309 krb5_get_initial_creds(context, &creds, client,
310 krb5_initial_prompter_xt, (void *) &xtstuff,
311 0, NULL, NULL);
312 krb5_verify_init_creds(context, &creds, NULL, NULL, &vcc, NULL);
313 /* setuid */
314 krb5_cc_store_cred(context, ccache, &creds);
315 krb5_free_cred_contents(context, &creds);
316 krb5_cc_copy(context, vcc, ccache);
317 krb5_cc_destroy(context, vcc);
318
319passwd:
320
321 krb5_init_creds_opt_init(&options);
322 krb5_init_creds_opt_set_tkt_life = 300;
323 krb5_get_initial_creds(context, &creds, client,
324 krb5_initial_prompter_posix, NULL,
325 0, "kadmin/changepw", &options);
326 /* change password */
327 krb5_free_cred_contents(context, &creds);
328
329pop3d (simple password validator when no user interation possible):
330
331 krb5_get_initial_creds(context, &creds, client,
332 NULL, NULL, 0, NULL, NULL);
333 krb5_verify_init_creds(context, &creds, NULL, NULL, &vcc, NULL);
334 krb5_cc_destroy(context, vcc);
335
336================================================================
337
338password expiration has a subtlety. When a password expires and is
339changed, there is a delay between when the master gets the new key
340(immediately), and the slaves (propogation interval). So, when
341getting an in_tkt, if the password is expired, the request should be
342reissued to the master (this kind of sucks if you have SAM, oh well).
343If this says expired, too, then the password should be changed, and
344then the initial ticket request should be issued to the master again.
345If the master times out, then a message that the password has expired
346and cannot be changed due to the master being unreachable should be
347displayed.
348
349================================================================
350
351get_init_creds reads config stuff from:
352
353[libdefaults]
354 varname1 = defvalue
355 REALM = {
356 varname1 = value
357 varname2 = value
358 }
359
360typedef struct _krb5_get_init_creds_opt {
361 krb5_flags flags;
362 krb5_deltat tkt_life; /* varname = "ticket_lifetime" */
363 krb5_deltat renew_life; /* varname = "renew_lifetime" */
364 int forwardable; /* varname = "forwardable" */
365 int proxiable; /* varname = "proxiable" */
366 krb5_enctype *etype_list; /* varname = "default_tkt_enctypes" */
367 int etype_list_length;
368 krb5_address **address_list; /* no varname */
369 krb5_preauthtype *preauth_list; /* no varname */
370 int preauth_list_length;
371 krb5_data *salt;
372} krb5_get_init_creds_opt;
373
374
Note: See TracBrowser for help on using the repository browser.