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