1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3*0Sstevel@tonic-gate * Use is subject to license terms. 4*0Sstevel@tonic-gate */ 5*0Sstevel@tonic-gate 6*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 7*0Sstevel@tonic-gate 8*0Sstevel@tonic-gate /* 9*0Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 10*0Sstevel@tonic-gate * 11*0Sstevel@tonic-gate * Openvision retains the copyright to derivative works of 12*0Sstevel@tonic-gate * this source code. Do *NOT* create a derivative of this 13*0Sstevel@tonic-gate * source code before consulting with your legal department. 14*0Sstevel@tonic-gate * Do *NOT* integrate *ANY* of this source code into another 15*0Sstevel@tonic-gate * product before consulting with your legal department. 16*0Sstevel@tonic-gate * 17*0Sstevel@tonic-gate * For further information, read the top-level Openvision 18*0Sstevel@tonic-gate * copyright which is contained in the top-level MIT Kerberos 19*0Sstevel@tonic-gate * copyright. 20*0Sstevel@tonic-gate * 21*0Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 22*0Sstevel@tonic-gate * 23*0Sstevel@tonic-gate */ 24*0Sstevel@tonic-gate 25*0Sstevel@tonic-gate 26*0Sstevel@tonic-gate /* 27*0Sstevel@tonic-gate * lib/kadm/str_conv.c 28*0Sstevel@tonic-gate * 29*0Sstevel@tonic-gate * Copyright 1995 by the Massachusetts Institute of Technology. 30*0Sstevel@tonic-gate * All Rights Reserved. 31*0Sstevel@tonic-gate * 32*0Sstevel@tonic-gate * Export of this software from the United States of America may 33*0Sstevel@tonic-gate * require a specific license from the United States Government. 34*0Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating 35*0Sstevel@tonic-gate * export to obtain such a license before exporting. 36*0Sstevel@tonic-gate * 37*0Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 38*0Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 39*0Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 40*0Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 41*0Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 42*0Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining 43*0Sstevel@tonic-gate * to distribution of the software without specific, written prior 44*0Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label 45*0Sstevel@tonic-gate * your software as modified software and not distribute it in such a 46*0Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software. 47*0Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of 48*0Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 49*0Sstevel@tonic-gate * or implied warranty. 50*0Sstevel@tonic-gate * 51*0Sstevel@tonic-gate */ 52*0Sstevel@tonic-gate 53*0Sstevel@tonic-gate /* 54*0Sstevel@tonic-gate * str_conv.c - Convert between strings and Kerberos internal data. 55*0Sstevel@tonic-gate */ 56*0Sstevel@tonic-gate 57*0Sstevel@tonic-gate /* 58*0Sstevel@tonic-gate * Table of contents: 59*0Sstevel@tonic-gate * 60*0Sstevel@tonic-gate * String decoding: 61*0Sstevel@tonic-gate * ---------------- 62*0Sstevel@tonic-gate * krb5_string_to_flags() - Convert string to krb5_flags. 63*0Sstevel@tonic-gate * 64*0Sstevel@tonic-gate * String encoding: 65*0Sstevel@tonic-gate * ---------------- 66*0Sstevel@tonic-gate * krb5_flags_to_string() - Convert krb5_flags to string. 67*0Sstevel@tonic-gate */ 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gate #include "k5-int.h" 70*0Sstevel@tonic-gate #include "admin_internal.h" 71*0Sstevel@tonic-gate 72*0Sstevel@tonic-gate /* 73*0Sstevel@tonic-gate * Local data structures. 74*0Sstevel@tonic-gate */ 75*0Sstevel@tonic-gate struct flags_lookup_entry { 76*0Sstevel@tonic-gate krb5_flags fl_flags; /* Flag */ 77*0Sstevel@tonic-gate krb5_boolean fl_sense; /* Sense of the flag */ 78*0Sstevel@tonic-gate const char * fl_specifier; /* How to recognize it */ 79*0Sstevel@tonic-gate const char * fl_output; /* How to spit it out */ 80*0Sstevel@tonic-gate }; 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate /* 83*0Sstevel@tonic-gate * Local strings 84*0Sstevel@tonic-gate */ 85*0Sstevel@tonic-gate 86*0Sstevel@tonic-gate static const char default_tupleseps[] = ", \t"; 87*0Sstevel@tonic-gate static const char default_ksaltseps[] = ":."; 88*0Sstevel@tonic-gate 89*0Sstevel@tonic-gate /* Keytype strings */ 90*0Sstevel@tonic-gate /* Flags strings */ 91*0Sstevel@tonic-gate static const char flags_pdate_in[] = "postdateable"; 92*0Sstevel@tonic-gate static const char flags_fwd_in[] = "forwardable"; 93*0Sstevel@tonic-gate static const char flags_tgtbased_in[] = "tgt-based"; 94*0Sstevel@tonic-gate static const char flags_renew_in[] = "renewable"; 95*0Sstevel@tonic-gate static const char flags_proxy_in[] = "proxiable"; 96*0Sstevel@tonic-gate static const char flags_dup_skey_in[] = "dup-skey"; 97*0Sstevel@tonic-gate static const char flags_tickets_in[] = "allow-tickets"; 98*0Sstevel@tonic-gate static const char flags_preauth_in[] = "preauth"; 99*0Sstevel@tonic-gate static const char flags_hwauth_in[] = "hwauth"; 100*0Sstevel@tonic-gate static const char flags_pwchange_in[] = "pwchange"; 101*0Sstevel@tonic-gate static const char flags_service_in[] = "service"; 102*0Sstevel@tonic-gate static const char flags_pwsvc_in[] = "pwservice"; 103*0Sstevel@tonic-gate static const char flags_md5_in[] = "md5"; 104*0Sstevel@tonic-gate static const char flags_pdate_out[] = "Not Postdateable"; 105*0Sstevel@tonic-gate static const char flags_fwd_out[] = "Not Forwardable"; 106*0Sstevel@tonic-gate static const char flags_tgtbased_out[] = "No TGT-based requests"; 107*0Sstevel@tonic-gate static const char flags_renew_out[] = "Not renewable"; 108*0Sstevel@tonic-gate static const char flags_proxy_out[] = "Not proxiable"; 109*0Sstevel@tonic-gate static const char flags_dup_skey_out[] = "No DUP_SKEY requests"; 110*0Sstevel@tonic-gate static const char flags_tickets_out[] = "All Tickets Disallowed"; 111*0Sstevel@tonic-gate static const char flags_preauth_out[] = "Preauthorization required"; 112*0Sstevel@tonic-gate static const char flags_hwauth_out[] = "HW Authorization required"; 113*0Sstevel@tonic-gate static const char flags_pwchange_out[] = "Password Change required"; 114*0Sstevel@tonic-gate static const char flags_service_out[] = "Service Disabled"; 115*0Sstevel@tonic-gate static const char flags_pwsvc_out[] = "Password Changing Service"; 116*0Sstevel@tonic-gate static const char flags_md5_out[] = "RSA-MD5 supported"; 117*0Sstevel@tonic-gate static const char flags_default_neg[] = "-"; 118*0Sstevel@tonic-gate static const char flags_default_sep[] = " "; 119*0Sstevel@tonic-gate 120*0Sstevel@tonic-gate /* 121*0Sstevel@tonic-gate * Lookup tables. 122*0Sstevel@tonic-gate */ 123*0Sstevel@tonic-gate 124*0Sstevel@tonic-gate static const struct flags_lookup_entry flags_table[] = { 125*0Sstevel@tonic-gate /* flag sense input specifier output string */ 126*0Sstevel@tonic-gate /*----------------------------- ------- ------------------ ------------------*/ 127*0Sstevel@tonic-gate { KRB5_KDB_DISALLOW_POSTDATED, 0, flags_pdate_in, flags_pdate_out }, 128*0Sstevel@tonic-gate { KRB5_KDB_DISALLOW_FORWARDABLE,0, flags_fwd_in, flags_fwd_out }, 129*0Sstevel@tonic-gate { KRB5_KDB_DISALLOW_TGT_BASED, 0, flags_tgtbased_in, flags_tgtbased_out}, 130*0Sstevel@tonic-gate { KRB5_KDB_DISALLOW_RENEWABLE, 0, flags_renew_in, flags_renew_out }, 131*0Sstevel@tonic-gate { KRB5_KDB_DISALLOW_PROXIABLE, 0, flags_proxy_in, flags_proxy_out }, 132*0Sstevel@tonic-gate { KRB5_KDB_DISALLOW_DUP_SKEY, 0, flags_dup_skey_in, flags_dup_skey_out}, 133*0Sstevel@tonic-gate { KRB5_KDB_DISALLOW_ALL_TIX, 0, flags_tickets_in, flags_tickets_out }, 134*0Sstevel@tonic-gate { KRB5_KDB_REQUIRES_PRE_AUTH, 1, flags_preauth_in, flags_preauth_out }, 135*0Sstevel@tonic-gate { KRB5_KDB_REQUIRES_HW_AUTH, 1, flags_hwauth_in, flags_hwauth_out }, 136*0Sstevel@tonic-gate { KRB5_KDB_REQUIRES_PWCHANGE, 1, flags_pwchange_in, flags_pwchange_out}, 137*0Sstevel@tonic-gate { KRB5_KDB_DISALLOW_SVR, 0, flags_service_in, flags_service_out }, 138*0Sstevel@tonic-gate { KRB5_KDB_PWCHANGE_SERVICE, 1, flags_pwsvc_in, flags_pwsvc_out }, 139*0Sstevel@tonic-gate { KRB5_KDB_SUPPORT_DESMD5, 1, flags_md5_in, flags_md5_out } 140*0Sstevel@tonic-gate }; 141*0Sstevel@tonic-gate static const int flags_table_nents = sizeof(flags_table)/ 142*0Sstevel@tonic-gate sizeof(flags_table[0]); 143*0Sstevel@tonic-gate 144*0Sstevel@tonic-gate 145*0Sstevel@tonic-gate krb5_error_code 146*0Sstevel@tonic-gate krb5_string_to_flags(string, positive, negative, flagsp) 147*0Sstevel@tonic-gate char * string; 148*0Sstevel@tonic-gate const char * positive; 149*0Sstevel@tonic-gate const char * negative; 150*0Sstevel@tonic-gate krb5_flags * flagsp; 151*0Sstevel@tonic-gate { 152*0Sstevel@tonic-gate int i; 153*0Sstevel@tonic-gate int found; 154*0Sstevel@tonic-gate const char *neg; 155*0Sstevel@tonic-gate size_t nsize, psize; 156*0Sstevel@tonic-gate int cpos; 157*0Sstevel@tonic-gate int sense; 158*0Sstevel@tonic-gate 159*0Sstevel@tonic-gate found = 0; 160*0Sstevel@tonic-gate /* We need to have a way to negate it. */ 161*0Sstevel@tonic-gate neg = (negative) ? negative : flags_default_neg; 162*0Sstevel@tonic-gate nsize = strlen(neg); 163*0Sstevel@tonic-gate psize = (positive) ? strlen(positive) : 0; 164*0Sstevel@tonic-gate 165*0Sstevel@tonic-gate cpos = 0; 166*0Sstevel@tonic-gate sense = 1; 167*0Sstevel@tonic-gate /* First check for positive or negative sense */ 168*0Sstevel@tonic-gate if (!strncasecmp(neg, string, nsize)) { 169*0Sstevel@tonic-gate sense = 0; 170*0Sstevel@tonic-gate cpos += (int) nsize; 171*0Sstevel@tonic-gate } 172*0Sstevel@tonic-gate else if (psize && !strncasecmp(positive, string, psize)) { 173*0Sstevel@tonic-gate cpos += (int) psize; 174*0Sstevel@tonic-gate } 175*0Sstevel@tonic-gate 176*0Sstevel@tonic-gate for (i=0; i<flags_table_nents; i++) { 177*0Sstevel@tonic-gate if (!strcasecmp(&string[cpos], flags_table[i].fl_specifier)) { 178*0Sstevel@tonic-gate found = 1; 179*0Sstevel@tonic-gate if (sense == (int) flags_table[i].fl_sense) 180*0Sstevel@tonic-gate *flagsp |= flags_table[i].fl_flags; 181*0Sstevel@tonic-gate else 182*0Sstevel@tonic-gate *flagsp &= ~flags_table[i].fl_flags; 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gate break; 185*0Sstevel@tonic-gate } 186*0Sstevel@tonic-gate } 187*0Sstevel@tonic-gate return((found) ? 0 : EINVAL); 188*0Sstevel@tonic-gate } 189*0Sstevel@tonic-gate 190*0Sstevel@tonic-gate krb5_error_code 191*0Sstevel@tonic-gate krb5_flags_to_string(flags, sep, buffer, buflen) 192*0Sstevel@tonic-gate krb5_flags flags; 193*0Sstevel@tonic-gate const char * sep; 194*0Sstevel@tonic-gate char * buffer; 195*0Sstevel@tonic-gate size_t buflen; 196*0Sstevel@tonic-gate { 197*0Sstevel@tonic-gate int i; 198*0Sstevel@tonic-gate krb5_flags pflags; 199*0Sstevel@tonic-gate const char *sepstring; 200*0Sstevel@tonic-gate char *op; 201*0Sstevel@tonic-gate int initial; 202*0Sstevel@tonic-gate krb5_error_code retval; 203*0Sstevel@tonic-gate 204*0Sstevel@tonic-gate retval = 0; 205*0Sstevel@tonic-gate op = buffer; 206*0Sstevel@tonic-gate pflags = 0; 207*0Sstevel@tonic-gate initial = 1; 208*0Sstevel@tonic-gate sepstring = (sep) ? sep : flags_default_sep; 209*0Sstevel@tonic-gate /* Blast through the table matching all we can */ 210*0Sstevel@tonic-gate for (i=0; i<flags_table_nents; i++) { 211*0Sstevel@tonic-gate if (flags & flags_table[i].fl_flags) { 212*0Sstevel@tonic-gate /* Found a match, see if it'll fit into the output buffer */ 213*0Sstevel@tonic-gate if ((op+strlen(flags_table[i].fl_output)+strlen(sepstring)) < 214*0Sstevel@tonic-gate (buffer + buflen)) { 215*0Sstevel@tonic-gate if (!initial) { 216*0Sstevel@tonic-gate strcpy(op, sep); 217*0Sstevel@tonic-gate op += strlen(sep); 218*0Sstevel@tonic-gate } 219*0Sstevel@tonic-gate initial = 0; 220*0Sstevel@tonic-gate strcpy(op, flags_table[i].fl_output); 221*0Sstevel@tonic-gate op += strlen(flags_table[i].fl_output); 222*0Sstevel@tonic-gate } 223*0Sstevel@tonic-gate else { 224*0Sstevel@tonic-gate retval = ENOMEM; 225*0Sstevel@tonic-gate break; 226*0Sstevel@tonic-gate } 227*0Sstevel@tonic-gate /* Keep track of what we matched */ 228*0Sstevel@tonic-gate pflags |= flags_table[i].fl_flags; 229*0Sstevel@tonic-gate } 230*0Sstevel@tonic-gate } 231*0Sstevel@tonic-gate if (!retval) { 232*0Sstevel@tonic-gate /* See if there's any leftovers */ 233*0Sstevel@tonic-gate if (flags & ~pflags) 234*0Sstevel@tonic-gate retval = EINVAL; 235*0Sstevel@tonic-gate else if (initial) 236*0Sstevel@tonic-gate *buffer = '\0'; 237*0Sstevel@tonic-gate } 238*0Sstevel@tonic-gate return(retval); 239*0Sstevel@tonic-gate } 240*0Sstevel@tonic-gate 241*0Sstevel@tonic-gate krb5_error_code 242*0Sstevel@tonic-gate krb5_input_flag_to_string(flag, buffer, buflen) 243*0Sstevel@tonic-gate int flag; 244*0Sstevel@tonic-gate char * buffer; 245*0Sstevel@tonic-gate size_t buflen; 246*0Sstevel@tonic-gate { 247*0Sstevel@tonic-gate if(flag < 0 || flag >= flags_table_nents) return ENOENT; /* End of list */ 248*0Sstevel@tonic-gate if(strlen(flags_table[flag].fl_specifier) > buflen) return ENOMEM; 249*0Sstevel@tonic-gate strcpy(buffer, flags_table[flag].fl_specifier); 250*0Sstevel@tonic-gate return 0; 251*0Sstevel@tonic-gate } 252*0Sstevel@tonic-gate 253*0Sstevel@tonic-gate /* 254*0Sstevel@tonic-gate * krb5_keysalt_is_present() - Determine if a key/salt pair is present 255*0Sstevel@tonic-gate * in a list of key/salt tuples. 256*0Sstevel@tonic-gate * 257*0Sstevel@tonic-gate * Salttype may be negative to indicate a search for only a enctype. 258*0Sstevel@tonic-gate */ 259*0Sstevel@tonic-gate krb5_boolean 260*0Sstevel@tonic-gate krb5_keysalt_is_present(ksaltlist, nksalts, enctype, salttype) 261*0Sstevel@tonic-gate krb5_key_salt_tuple *ksaltlist; 262*0Sstevel@tonic-gate krb5_int32 nksalts; 263*0Sstevel@tonic-gate krb5_enctype enctype; 264*0Sstevel@tonic-gate krb5_int32 salttype; 265*0Sstevel@tonic-gate { 266*0Sstevel@tonic-gate krb5_boolean foundit; 267*0Sstevel@tonic-gate int i; 268*0Sstevel@tonic-gate 269*0Sstevel@tonic-gate foundit = 0; 270*0Sstevel@tonic-gate if (ksaltlist) { 271*0Sstevel@tonic-gate for (i=0; i<nksalts; i++) { 272*0Sstevel@tonic-gate if ((ksaltlist[i].ks_enctype == enctype) && 273*0Sstevel@tonic-gate ((ksaltlist[i].ks_salttype == salttype) || 274*0Sstevel@tonic-gate (salttype < 0))) { 275*0Sstevel@tonic-gate foundit = 1; 276*0Sstevel@tonic-gate break; 277*0Sstevel@tonic-gate } 278*0Sstevel@tonic-gate } 279*0Sstevel@tonic-gate } 280*0Sstevel@tonic-gate return(foundit); 281*0Sstevel@tonic-gate } 282*0Sstevel@tonic-gate 283*0Sstevel@tonic-gate /* 284*0Sstevel@tonic-gate * krb5_string_to_keysalts() - Convert a string representation to a list 285*0Sstevel@tonic-gate * of key/salt tuples. 286*0Sstevel@tonic-gate */ 287*0Sstevel@tonic-gate krb5_error_code 288*0Sstevel@tonic-gate krb5_string_to_keysalts(string, tupleseps, ksaltseps, dups, ksaltp, nksaltp) 289*0Sstevel@tonic-gate char *string; 290*0Sstevel@tonic-gate const char *tupleseps; 291*0Sstevel@tonic-gate const char *ksaltseps; 292*0Sstevel@tonic-gate krb5_boolean dups; 293*0Sstevel@tonic-gate krb5_key_salt_tuple **ksaltp; 294*0Sstevel@tonic-gate krb5_int32 *nksaltp; 295*0Sstevel@tonic-gate { 296*0Sstevel@tonic-gate krb5_error_code kret; 297*0Sstevel@tonic-gate char *kp, *sp, *ep; 298*0Sstevel@tonic-gate char sepchar, trailchar; 299*0Sstevel@tonic-gate krb5_enctype ktype; 300*0Sstevel@tonic-gate krb5_int32 stype; 301*0Sstevel@tonic-gate krb5_key_salt_tuple *savep; 302*0Sstevel@tonic-gate const char *tseplist; 303*0Sstevel@tonic-gate const char *ksseplist; 304*0Sstevel@tonic-gate const char *septmp; 305*0Sstevel@tonic-gate size_t len; 306*0Sstevel@tonic-gate 307*0Sstevel@tonic-gate kret = 0; 308*0Sstevel@tonic-gate kp = string; 309*0Sstevel@tonic-gate tseplist = (tupleseps) ? tupleseps : default_tupleseps; 310*0Sstevel@tonic-gate ksseplist = (ksaltseps) ? ksaltseps : default_ksaltseps; 311*0Sstevel@tonic-gate while (kp) { 312*0Sstevel@tonic-gate /* Attempt to find a separator */ 313*0Sstevel@tonic-gate ep = (char *) NULL; 314*0Sstevel@tonic-gate if (*tseplist) { 315*0Sstevel@tonic-gate septmp = tseplist; 316*0Sstevel@tonic-gate for (ep = strchr(kp, (int) *septmp); 317*0Sstevel@tonic-gate *(++septmp) && !ep; 318*0Sstevel@tonic-gate ep = strchr(kp, (int) *septmp)); 319*0Sstevel@tonic-gate } 320*0Sstevel@tonic-gate 321*0Sstevel@tonic-gate if (ep) { 322*0Sstevel@tonic-gate trailchar = *ep; 323*0Sstevel@tonic-gate *ep = '\0'; 324*0Sstevel@tonic-gate ep++; 325*0Sstevel@tonic-gate } 326*0Sstevel@tonic-gate /* 327*0Sstevel@tonic-gate * kp points to something (hopefully) of the form: 328*0Sstevel@tonic-gate * <enctype><ksseplist><salttype> 329*0Sstevel@tonic-gate * or 330*0Sstevel@tonic-gate * <enctype> 331*0Sstevel@tonic-gate */ 332*0Sstevel@tonic-gate sp = (char *) NULL; 333*0Sstevel@tonic-gate /* Attempt to find a separator */ 334*0Sstevel@tonic-gate septmp = ksseplist; 335*0Sstevel@tonic-gate for (sp = strchr(kp, (int) *septmp); 336*0Sstevel@tonic-gate *(++septmp) && !sp; 337*0Sstevel@tonic-gate sp = strchr(kp, (int)*septmp)); 338*0Sstevel@tonic-gate 339*0Sstevel@tonic-gate if (sp) { 340*0Sstevel@tonic-gate /* Separate enctype from salttype */ 341*0Sstevel@tonic-gate sepchar = *sp; 342*0Sstevel@tonic-gate *sp = '\0'; 343*0Sstevel@tonic-gate sp++; 344*0Sstevel@tonic-gate } 345*0Sstevel@tonic-gate else 346*0Sstevel@tonic-gate stype = -1; 347*0Sstevel@tonic-gate 348*0Sstevel@tonic-gate /* 349*0Sstevel@tonic-gate * Attempt to parse enctype and salttype. If we parse well 350*0Sstevel@tonic-gate * then make sure that it specifies a unique key/salt combo 351*0Sstevel@tonic-gate */ 352*0Sstevel@tonic-gate if (!(kret = krb5_string_to_enctype(kp, &ktype)) && 353*0Sstevel@tonic-gate (!sp || !(kret = krb5_string_to_salttype(sp, &stype))) && 354*0Sstevel@tonic-gate (dups || 355*0Sstevel@tonic-gate !krb5_keysalt_is_present(*ksaltp, *nksaltp, ktype, stype))) { 356*0Sstevel@tonic-gate 357*0Sstevel@tonic-gate /* Squirrel away old keysalt array */ 358*0Sstevel@tonic-gate savep = *ksaltp; 359*0Sstevel@tonic-gate len = (size_t) *nksaltp; 360*0Sstevel@tonic-gate 361*0Sstevel@tonic-gate /* Get new keysalt array */ 362*0Sstevel@tonic-gate if (*ksaltp = (krb5_key_salt_tuple *) 363*0Sstevel@tonic-gate malloc((len + 1) * sizeof(krb5_key_salt_tuple))) { 364*0Sstevel@tonic-gate 365*0Sstevel@tonic-gate /* Copy old keysalt if appropriate */ 366*0Sstevel@tonic-gate if (savep) { 367*0Sstevel@tonic-gate memcpy(*ksaltp, savep, 368*0Sstevel@tonic-gate len * sizeof(krb5_key_salt_tuple)); 369*0Sstevel@tonic-gate krb5_xfree(savep); 370*0Sstevel@tonic-gate } 371*0Sstevel@tonic-gate 372*0Sstevel@tonic-gate /* Save our values */ 373*0Sstevel@tonic-gate (*ksaltp)[(*nksaltp)].ks_enctype = ktype; 374*0Sstevel@tonic-gate (*ksaltp)[(*nksaltp)].ks_salttype = stype; 375*0Sstevel@tonic-gate (*nksaltp)++; 376*0Sstevel@tonic-gate } 377*0Sstevel@tonic-gate else { 378*0Sstevel@tonic-gate *ksaltp = savep; 379*0Sstevel@tonic-gate break; 380*0Sstevel@tonic-gate } 381*0Sstevel@tonic-gate } 382*0Sstevel@tonic-gate /* 383*0Sstevel@tonic-gate * Solaris Kerberos 384*0Sstevel@tonic-gate * If the string did not yield a valid enctype/keysalt 385*0Sstevel@tonic-gate * just ignore it and continue on. MIT kerberos stops 386*0Sstevel@tonic-gate * searching when if finds an unknown string. 387*0Sstevel@tonic-gate */ 388*0Sstevel@tonic-gate if (sp) 389*0Sstevel@tonic-gate sp[-1] = sepchar; 390*0Sstevel@tonic-gate if (ep) 391*0Sstevel@tonic-gate ep[-1] = trailchar; 392*0Sstevel@tonic-gate kp = ep; 393*0Sstevel@tonic-gate 394*0Sstevel@tonic-gate /* Skip over extra separators - like spaces */ 395*0Sstevel@tonic-gate if (kp && *tseplist) { 396*0Sstevel@tonic-gate septmp = tseplist; 397*0Sstevel@tonic-gate while(*septmp && *kp) { 398*0Sstevel@tonic-gate if(*septmp == *kp) { 399*0Sstevel@tonic-gate /* Increment string - reset separator list */ 400*0Sstevel@tonic-gate kp++; 401*0Sstevel@tonic-gate septmp = tseplist; 402*0Sstevel@tonic-gate } else { 403*0Sstevel@tonic-gate septmp++; 404*0Sstevel@tonic-gate } 405*0Sstevel@tonic-gate } 406*0Sstevel@tonic-gate if (!*kp) kp = NULL; 407*0Sstevel@tonic-gate } 408*0Sstevel@tonic-gate } /* while kp */ 409*0Sstevel@tonic-gate return(kret); 410*0Sstevel@tonic-gate } 411*0Sstevel@tonic-gate 412*0Sstevel@tonic-gate /* 413*0Sstevel@tonic-gate * krb5_keysalt_iterate() - Do something for each unique key/salt 414*0Sstevel@tonic-gate * combination. 415*0Sstevel@tonic-gate * 416*0Sstevel@tonic-gate * If ignoresalt set, then salttype is ignored. 417*0Sstevel@tonic-gate */ 418*0Sstevel@tonic-gate krb5_error_code 419*0Sstevel@tonic-gate krb5_keysalt_iterate(ksaltlist, nksalt, ignoresalt, iterator, arg) 420*0Sstevel@tonic-gate krb5_key_salt_tuple *ksaltlist; 421*0Sstevel@tonic-gate krb5_int32 nksalt; 422*0Sstevel@tonic-gate krb5_boolean ignoresalt; 423*0Sstevel@tonic-gate krb5_error_code (*iterator) KRB5_NPROTOTYPE((krb5_key_salt_tuple *, 424*0Sstevel@tonic-gate krb5_pointer)); 425*0Sstevel@tonic-gate krb5_pointer arg; 426*0Sstevel@tonic-gate { 427*0Sstevel@tonic-gate int i; 428*0Sstevel@tonic-gate krb5_error_code kret; 429*0Sstevel@tonic-gate krb5_key_salt_tuple scratch; 430*0Sstevel@tonic-gate 431*0Sstevel@tonic-gate kret = 0; 432*0Sstevel@tonic-gate for (i=0; i<nksalt; i++) { 433*0Sstevel@tonic-gate scratch.ks_enctype = ksaltlist[i].ks_enctype; 434*0Sstevel@tonic-gate scratch.ks_salttype = (ignoresalt) ? -1 : ksaltlist[i].ks_salttype; 435*0Sstevel@tonic-gate if (!krb5_keysalt_is_present(ksaltlist, 436*0Sstevel@tonic-gate i, 437*0Sstevel@tonic-gate scratch.ks_enctype, 438*0Sstevel@tonic-gate scratch.ks_salttype)) { 439*0Sstevel@tonic-gate if (kret = (*iterator)(&scratch, arg)) 440*0Sstevel@tonic-gate break; 441*0Sstevel@tonic-gate } 442*0Sstevel@tonic-gate } 443*0Sstevel@tonic-gate return(kret); 444*0Sstevel@tonic-gate } 445