From 910c37e40f179927e016bc9d0895f25c48441716 Mon Sep 17 00:00:00 2001 From: Paul Park Date: Mon, 31 Jul 1995 20:01:40 +0000 Subject: [PATCH] Update to new kadmin protocol git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@6363 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/kadm/adm_kw_dec.c | 315 ++++++++++++++++----------- src/lib/kadm/adm_kw_enc.c | 249 ++++++++++++---------- src/lib/kadm/t_dbentry.c | 432 ++++++++++++++++++++++++++------------ 3 files changed, 634 insertions(+), 362 deletions(-) diff --git a/src/lib/kadm/adm_kw_dec.c b/src/lib/kadm/adm_kw_dec.c index 4ee0d7bdd..925835375 100644 --- a/src/lib/kadm/adm_kw_dec.c +++ b/src/lib/kadm/adm_kw_dec.c @@ -31,37 +31,6 @@ #define char2int(c) ((c) - '0') -/* - * string_to_salt_type() - Convert from salt string to salt type. - */ -static krb5_int32 -string_to_salt_type(sstring, retp) - char *sstring; - krb5_error_code *retp; -{ - krb5_error_code kret; - krb5_int32 stype; - - kret = EINVAL; - stype = -1; - if (!strcmp(sstring, KRB5_ADM_SALTTYPE_NORMAL)) - stype = KRB5_KDB_SALTTYPE_NORMAL; - else if (!strcmp(sstring, KRB5_ADM_SALTTYPE_V4)) - stype = KRB5_KDB_SALTTYPE_V4; - else if (!strcmp(sstring, KRB5_ADM_SALTTYPE_NOREALM)) - stype = KRB5_KDB_SALTTYPE_NOREALM; - else if (!strcmp(sstring, KRB5_ADM_SALTTYPE_ONLYREALM)) - stype = KRB5_KDB_SALTTYPE_ONLYREALM; - else if (!strcmp(sstring, KRB5_ADM_SALTTYPE_SPECIAL)) - stype = KRB5_KDB_SALTTYPE_SPECIAL; - - if (stype != -1) - kret = 0; - - *retp = kret; - return(stype); -} - /* * keyword_value() - Find index of keyword value if keyword is present. * @@ -200,31 +169,59 @@ decode_kw_gentime(dataentp, keyword, gtimep) } /* - * decode_kw_salttype() - Decode a keyword= pair and fill in the - * salt type values if the pair is present. + * decode_kw_tagged() - Decode a keyword=... list and return + * the values of the tags and the data if the list is + * present. */ static krb5_error_code -decode_kw_salttype(dataentp, keyword, dbentp) +decode_kw_tagged(dataentp, keyword, ntags, taglist, lenp, datap) krb5_data *dataentp; char *keyword; - krb5_db_entry *dbentp; + krb5_int32 ntags; + krb5_int32 *taglist; + size_t *lenp; + krb5_octet **datap; { krb5_error_code kret; - char *saltstring; - char *sentp; + off_t valueoff; + size_t len2copy; + unsigned char *cp, *ep; + int i; - saltstring = (char *) NULL; - if (!(kret = decode_kw_string(dataentp, keyword, &saltstring))) { - kret = EINVAL; - if (sentp = strchr(saltstring, (int) ',')) { - *sentp = '\0'; - sentp++; - } - dbentp->salt_type = string_to_salt_type(saltstring, &kret); - if (!kret && sentp) { - dbentp->alt_salt_type = string_to_salt_type(sentp, &kret); + kret = ENOENT; + if ((valueoff = keyword_value(dataentp, keyword, 1)) >= 0) { + /* + * Blast through the tags. + */ + kret = 0; + cp = (unsigned char *) &dataentp->data[valueoff]; + ep = (unsigned char *) &dataentp->data[dataentp->length]; + for (i=0; i ep) { + kret = EINVAL; + break; + } + taglist[i] = (((krb5_int32) ((unsigned char) cp[0]) << 24) + + ((krb5_int32) ((unsigned char) cp[1]) << 16) + + ((krb5_int32) ((unsigned char) cp[2]) << 8) + + ((krb5_int32) ((unsigned char) cp[3]))); + cp += sizeof(krb5_int32); + } + if (!kret) { + /* + * If we were successful, copy out the remaining bytes for value. + */ + len2copy = (size_t) (ep - cp); + if (len2copy && + (*datap = (krb5_octet *) malloc(len2copy+1))) { + memcpy(*datap, cp, len2copy); + (*datap)[len2copy] = '\0'; + } + if (len2copy && !*datap) + kret = ENOMEM; + else + *lenp = len2copy; } - free(saltstring); } return(kret); } @@ -255,12 +252,21 @@ krb5_adm_proto_to_dbent(kcontext, nent, data, validp, dbentp, pwordp) int i; krb5_error_code retval; krb5_ui_4 parsed_mask; - char *modifier_name; + krb5_int32 taglist[4]; + size_t data_length; + krb5_octet *tagged_data; + struct key_tag_correlator { + krb5_int32 key_tag; + int key_data_index; + } *correlators, *correlation; + int ncorrelations; /* Initialize */ retval = 0; parsed_mask = 0; *pwordp = (char *) NULL; + correlators = (struct key_tag_correlator *) NULL; + ncorrelations = 0; /* Loop through all the specified keyword=value pairs. */ for (i=0; ikvno))) { - parsed_mask |= KRB5_ADM_M_KVNO; - continue; - } - else { - if (retval != ENOENT) - break; - } - /* Check for maximum lifetime */ if (!(retval = decode_kw_integer(&data[i], KRB5_ADM_KW_MAXLIFE, @@ -368,42 +362,6 @@ krb5_adm_proto_to_dbent(kcontext, nent, data, validp, dbentp, pwordp) break; } - /* Check for salttype */ - if (!(retval = decode_kw_salttype(&data[i], - KRB5_ADM_KW_SALTTYPE, - dbentp))) { - parsed_mask |= KRB5_ADM_M_SALTTYPE; - continue; - } - else { - if (retval != ENOENT) - break; - } - - /* Check for master key version number */ - if (!(retval = decode_kw_integer(&data[i], - KRB5_ADM_KW_MKVNO, - (krb5_ui_4 *) &dbentp->mkvno))) { - parsed_mask |= KRB5_ADM_M_MKVNO; - continue; - } - else { - if (retval != ENOENT) - break; - } - - /* Check for last password change */ - if (!(retval = decode_kw_gentime(&data[i], - KRB5_ADM_KW_LASTPWCHANGE, - &dbentp->last_pwd_change))) { - parsed_mask |= KRB5_ADM_M_LASTPWCHANGE; - continue; - } - else { - if (retval != ENOENT) - break; - } - /* Check for last successful password entry */ if (!(retval = decode_kw_gentime(&data[i], KRB5_ADM_KW_LASTSUCCESS, @@ -441,37 +399,158 @@ krb5_adm_proto_to_dbent(kcontext, nent, data, validp, dbentp, pwordp) break; } - /* Check for modification principal */ - if (!(retval = decode_kw_string(&data[i], - KRB5_ADM_KW_MODNAME, - &modifier_name))) { - krb5_principal modifier; - retval = krb5_parse_name(kcontext, modifier_name, &modifier); - free(modifier_name); - if (!retval) { - if (dbentp->mod_name) - krb5_free_principal(kcontext, dbentp->mod_name); - dbentp->mod_name = modifier; - parsed_mask |= KRB5_ADM_M_MODNAME; - continue; + /* Check for auxiliary data */ + if (!(retval = decode_kw_tagged(&data[i], + KRB5_ADM_KW_AUXDATA, + 1, + taglist, + &data_length, + &tagged_data))) { + krb5_tl_data **fixupp; + krb5_tl_data *tl_data, *new_tl; + + /* + * We've got a tagged data value here. We've got to do a little + * work to put it in the right place. First, find the right place. + */ + fixupp = &dbentp->tl_data; + for (tl_data = dbentp->tl_data; + tl_data; + tl_data = tl_data->tl_data_next) + fixupp = &tl_data->tl_data_next; + + /* Get memory */ + if (new_tl = (krb5_tl_data *) malloc(sizeof(krb5_tl_data))) { + /* Fill in the supplied values */ + new_tl->tl_data_type = (krb5_int16) taglist[0]; + new_tl->tl_data_length = (krb5_int16) data_length; + new_tl->tl_data_contents = tagged_data; + + /* Link in the right place */ + new_tl->tl_data_next= *fixupp; + *fixupp = new_tl; + + /* Update counters and flags */ + dbentp->n_tl_data++; + parsed_mask |= KRB5_ADM_M_AUXDATA; + } + else { + retval = ENOMEM; + break; + } + continue; + } + else { + if ((retval != ENOENT) && (retval != EINVAL)) + break; + } + + /* Check for key data */ + if (!(retval = decode_kw_tagged(&data[i], + KRB5_ADM_KW_KEYDATA, + 3, + taglist, + &data_length, + &tagged_data))) { + krb5_boolean corr_found; + int cindex, kindex; + krb5_key_data *kdata; + + /* + * See if we already have a correlation betwen our key-tag and + * an index into the key table. + */ + corr_found = 0; + for (cindex = 0; cindex < ncorrelations; cindex++) { + if (correlators[cindex].key_tag == taglist[0]) { + correlation = &correlators[cindex]; + corr_found = 1; + break; + } + } + + /* If not, then we had better make one up */ + if (!corr_found) { + /* Get a new list */ + if (correlation = (struct key_tag_correlator *) + malloc((ncorrelations+1)* + sizeof(struct key_tag_correlator))) { + /* Save the contents of the old one. */ + if (ncorrelations) { + memcpy(correlation, correlators, + ncorrelations* + sizeof(struct key_tag_correlator)); + /* Free the old one */ + free(correlators); + } + /* Point us at the new relation */ + correlators = correlation; + correlation = &correlators[ncorrelations]; + ncorrelations++; + correlation->key_tag = taglist[0]; + /* Make a new key data entry */ + if (kdata = (krb5_key_data *) + malloc((dbentp->n_key_data+1)*sizeof(krb5_key_data))) { + /* Copy the old list */ + if (dbentp->n_key_data) { + memcpy(kdata, dbentp->key_data, + dbentp->n_key_data*sizeof(krb5_key_data)); + free(dbentp->key_data); + } + dbentp->key_data = kdata; + correlation->key_data_index = dbentp->n_key_data; + memset(&kdata[dbentp->n_key_data], 0, + sizeof(krb5_key_data)); + kdata[dbentp->n_key_data].key_data_ver = 1; + dbentp->n_key_data++; + corr_found = 1; + } + else + retval = ENOMEM; + } + else + retval = ENOMEM; + } + + /* Check to see if we either found a correlation or made one */ + if (corr_found) { + /* Special case for key version number */ + if (taglist[1] == -1) { + dbentp->key_data[correlation->key_data_index]. + key_data_kvno = taglist[2]; + } + else { + dbentp->key_data[correlation->key_data_index]. + key_data_type[taglist[1]] = taglist[2]; + dbentp->key_data[correlation->key_data_index]. + key_data_length[taglist[1]] = (krb5_int16) data_length; + dbentp->key_data[correlation->key_data_index]. + key_data_contents[taglist[1]] = tagged_data; + } + parsed_mask |= KRB5_ADM_M_KEYDATA; } else break; + continue; } else { - if (retval != ENOENT) + if ((retval != ENOENT) && (retval != EINVAL)) break; } - /* Check for modification time */ - if (!(retval = decode_kw_gentime(&data[i], - KRB5_ADM_KW_MODDATE, - &dbentp->mod_date))) { - parsed_mask |= KRB5_ADM_M_MODDATE; + /* Check for extra data */ + if (!(retval = decode_kw_tagged(&data[i], + KRB5_ADM_KW_EXTRADATA, + 0, + taglist, + &data_length, + &dbentp->e_data))) { + dbentp->e_length = (krb5_int16) data_length; + parsed_mask |= KRB5_ADM_M_EXTRADATA; continue; } else { - if (retval != ENOENT) + if ((retval != ENOENT) && (retval != EINVAL)) break; } @@ -490,6 +569,8 @@ krb5_adm_proto_to_dbent(kcontext, nent, data, validp, dbentp, pwordp) } parsed_mask = 0; } + if (correlators) + free(correlators); *validp |= parsed_mask; return(retval); } diff --git a/src/lib/kadm/adm_kw_enc.c b/src/lib/kadm/adm_kw_enc.c index 9bc4c5cba..4e0318712 100644 --- a/src/lib/kadm/adm_kw_enc.c +++ b/src/lib/kadm/adm_kw_enc.c @@ -30,32 +30,6 @@ #include "adm.h" #include "adm_proto.h" - -/* - * salt_type_to_string() - Return a string for a given salt type. - * - * Add support for different salt types here. - */ -static char * -salt_type_to_string(stype) - krb5_int32 stype; -{ - char *retval = (char *) NULL; - - switch (stype) { - case KRB5_KDB_SALTTYPE_NORMAL: - retval = KRB5_ADM_SALTTYPE_NORMAL; break; - case KRB5_KDB_SALTTYPE_V4: - retval = KRB5_ADM_SALTTYPE_V4; break; - case KRB5_KDB_SALTTYPE_NOREALM: - retval = KRB5_ADM_SALTTYPE_NOREALM; break; - case KRB5_KDB_SALTTYPE_ONLYREALM: - retval = KRB5_ADM_SALTTYPE_ONLYREALM; break; - case KRB5_KDB_SALTTYPE_SPECIAL: - retval = KRB5_ADM_SALTTYPE_SPECIAL; break; - } - return(retval); -} /* * format_kw_string() - Format a keyword= pair. @@ -100,10 +74,10 @@ format_kw_integer(datap, kwordp, val) if (datap->data) { datap->length = strlen(fbuffer); strcpy(datap->data, fbuffer); - datap->data[datap->length] = (char) ((val >> 24) & 0xff); - datap->data[datap->length+1] = (char) ((val >> 16) & 0xff); - datap->data[datap->length+2] = (char) ((val >> 8) & 0xff); - datap->data[datap->length+3] = (char) (val & 0xff); + datap->data[datap->length] = (unsigned char) ((val >> 24) & 0xff); + datap->data[datap->length+1] = (unsigned char) ((val >> 16) & 0xff); + datap->data[datap->length+2] = (unsigned char) ((val >> 8) & 0xff); + datap->data[datap->length+3] = (unsigned char) (val & 0xff); datap->length += sizeof(krb5_ui_4); retval = 0; } @@ -143,29 +117,46 @@ format_kw_gentime(datap, kwordp, timep) } /* - * format_kw_salttype() - Format a keyword= pair. + * format_kw_tagged() - Format a =... list. */ static krb5_error_code -format_kw_salttype(datap, kwordp, dbentp) - krb5_data *datap; - char *kwordp; - krb5_db_entry *dbentp; +format_kw_tagged(datap, kwordp, ntags, taglist, vallen, val) + krb5_data *datap; + char *kwordp; + const int ntags; + krb5_int32 *taglist; + krb5_int32 vallen; + krb5_octet *val; { krb5_error_code retval; - char fbuffer[BUFSIZ]; - char *sstring; + unsigned char *cp; + int i; - retval = EINVAL; - sstring = salt_type_to_string(dbentp->salt_type); - if (sstring) { - strcpy(fbuffer, sstring); - /* Only add secondary salt type if it's different and valid */ - if ((dbentp->salt_type != dbentp->alt_salt_type) && - (sstring = salt_type_to_string(dbentp->alt_salt_type))) { - strcat(fbuffer,","); - strcat(fbuffer,sstring); + /* Calculate the size required: + * strlen(kwordp) + 1 for "kword"= + * 4 * ntags for tags + * vallen for value; + */ + datap->data = (char *) malloc(strlen(kwordp)+ + 1+ + (ntags*sizeof(krb5_int32))+ + vallen+1); + if (datap->data) { + datap->length = strlen(kwordp)+1+(ntags*sizeof(krb5_int32))+vallen; + cp = (unsigned char *) datap->data; + cp[datap->length] = '\0'; + sprintf((char *) cp, "%s=", kwordp); + cp += strlen((char *) cp); + for (i=0; i> 24) & 0xff); + cp[1] = (unsigned char) ((taglist[i] >> 16) & 0xff); + cp[2] = (unsigned char) ((taglist[i] >> 8) & 0xff); + cp[3] = (unsigned char) (taglist[i] & 0xff); + cp += sizeof(krb5_int32); } - retval = format_kw_string(datap, kwordp, fbuffer); + if (val && vallen) + memcpy(cp, val, vallen); + retval = 0; } return(retval); } @@ -199,6 +190,10 @@ krb5_adm_dbent_to_proto(kcontext, valid, dbentp, password, nentp, datap) size_t n2alloc; int outindex; krb5_boolean is_set; + krb5_ui_4 tmp; + krb5_int32 taglist[4]; + krb5_tl_data *tl_data; + int keyind, attrind; kret = 0; /* First check out whether this is a set or get and the mask */ @@ -208,8 +203,26 @@ krb5_adm_dbent_to_proto(kcontext, valid, dbentp, password, nentp, datap) (!is_set && ((valid & KRB5_ADM_M_GET) == 0))) return(EINVAL); - /* Allocate a new array of output data */ - n2alloc = (is_set) ? KRB5_ADM_KW_MAX_SET : KRB5_ADM_KW_MAX_GET; + /* + * Compute the number of elements to allocate. First count set bits. + */ + n2alloc = 0; + for (tmp = valid & ~(KRB5_ADM_M_SET|KRB5_ADM_M_GET); + tmp; + tmp >>= 1) { + if (tmp & 1) + n2alloc++; + } + if (valid & KRB5_ADM_M_AUXDATA) + n2alloc += (dbentp->n_tl_data - 1); + /* + * NOTE: If the number of per-key attributes increases, you must increase + * the 3 below. The 3 represents 1 for key version, 1 for key type and + * one for salt type. + */ + if (valid & KRB5_ADM_M_KEYDATA) + n2alloc += ((dbentp->n_key_data*3)-1); + n2alloc *= sizeof(krb5_data); outindex = 0; outlist = (krb5_data *) malloc(n2alloc); @@ -228,15 +241,6 @@ krb5_adm_dbent_to_proto(kcontext, valid, dbentp, password, nentp, datap) else outindex++; } - /* Handle key version number */ - if ((valid & KRB5_ADM_M_KVNO) != 0) { - if (kret = format_kw_integer(&outlist[outindex], - KRB5_ADM_KW_KVNO, - (krb5_ui_4) dbentp->kvno)) - goto choke; - else - outindex++; - } /* Handle maximum ticket lifetime */ if ((valid & KRB5_ADM_M_MAXLIFE) != 0) { if (kret = format_kw_integer(&outlist[outindex], @@ -292,35 +296,6 @@ krb5_adm_dbent_to_proto(kcontext, valid, dbentp, password, nentp, datap) else outindex++; } - /* Handle salt types */ - if ((valid & KRB5_ADM_M_SALTTYPE) != 0) { - if (kret = format_kw_salttype(&outlist[outindex], - KRB5_ADM_KW_SALTTYPE, - dbentp)) - goto choke; - else - outindex++; - } - /* Handle master key version number */ - if (!is_set && - ((valid & KRB5_ADM_M_MKVNO) != 0)) { - if (kret = format_kw_integer(&outlist[outindex], - KRB5_ADM_KW_MKVNO, - (krb5_ui_4) dbentp->mkvno)) - goto choke; - else - outindex++; - } - /* Handle last successful password change */ - if (!is_set && - ((valid & KRB5_ADM_M_LASTPWCHANGE) != 0)) { - if (kret = format_kw_gentime(&outlist[outindex], - KRB5_ADM_KW_LASTPWCHANGE, - &dbentp->last_pwd_change)) - goto choke; - else - outindex++; - } /* Handle last successful password entry */ if (!is_set && ((valid & KRB5_ADM_M_LASTSUCCESS) != 0)) { @@ -351,39 +326,89 @@ krb5_adm_dbent_to_proto(kcontext, valid, dbentp, password, nentp, datap) else outindex++; } - /* Handle last modification principal name */ - if (!is_set && - ((valid & KRB5_ADM_M_MODNAME) != 0)) { - char *modifier_name; - /* Flatten the name, format it then free it. */ - if (kret = krb5_unparse_name(kcontext, - dbentp->mod_name, - &modifier_name)) - goto choke; - - kret = format_kw_string(&outlist[outindex], - KRB5_ADM_KW_MODNAME, - modifier_name); - krb5_xfree(modifier_name); - if (kret) - goto choke; - else - outindex++; + /* Handle the auxiliary data */ + if ((valid & KRB5_ADM_M_AUXDATA) != 0) { + for (tl_data = dbentp->tl_data; tl_data; tl_data = + tl_data->tl_data_next) { + taglist[0] = (krb5_int32) tl_data->tl_data_type; + if (kret = format_kw_tagged(&outlist[outindex], + KRB5_ADM_KW_AUXDATA, + 1, + taglist, + (krb5_int32) tl_data-> + tl_data_length, + tl_data->tl_data_contents)) + goto choke; + else + outindex++; + } } - /* Handle last modification time */ + + /* Handle the key data */ if (!is_set && - ((valid & KRB5_ADM_M_MODDATE) != 0)) { - if (kret = format_kw_gentime(&outlist[outindex], - KRB5_ADM_KW_MODDATE, - &dbentp->mod_date)) + ((valid & KRB5_ADM_M_KEYDATA) != 0)) { + for (keyind = 0; keyind < dbentp->n_key_data; keyind++) { + /* + * First handle kvno + */ + taglist[0] = (krb5_int32) keyind; + taglist[1] = (krb5_int32) -1; + taglist[2] = (krb5_int32) dbentp->key_data[keyind]. + key_data_kvno; + if (kret = format_kw_tagged(&outlist[outindex], + KRB5_ADM_KW_KEYDATA, + 3, + taglist, + 0, + (krb5_octet *) NULL)) + goto choke; + else + outindex++; + + /* + * Then each attribute as supported. + */ + for (attrind = 0; + attrind < KRB5_KDB_V1_KEY_DATA_ARRAY; + attrind++) { + taglist[1] = (krb5_int32) attrind; + taglist[2] = (krb5_int32) dbentp->key_data[keyind]. + key_data_type[attrind]; + if (kret = format_kw_tagged(&outlist[outindex], + KRB5_ADM_KW_KEYDATA, + 3, + taglist, + (krb5_int32) dbentp-> + key_data[keyind]. + key_data_length[attrind], + dbentp->key_data[keyind]. + key_data_contents[attrind]) + ) + goto choke; + else + outindex++; + } + } + } + + /* Finally, handle the extra data */ + if ((valid & KRB5_ADM_M_EXTRADATA) != 0) { + if (kret = format_kw_tagged(&outlist[outindex], + KRB5_ADM_KW_EXTRADATA, + 0, + (krb5_int32 *) NULL, + (krb5_int32) dbentp->e_length, + dbentp->e_data)) goto choke; else outindex++; } } - else - kret = ENOMEM; + else { + if (n2alloc) + kret = ENOMEM; + } choke: if (kret) { if (outlist) { diff --git a/src/lib/kadm/t_dbentry.c b/src/lib/kadm/t_dbentry.c index c59bb9fa7..6c71234b3 100644 --- a/src/lib/kadm/t_dbentry.c +++ b/src/lib/kadm/t_dbentry.c @@ -73,6 +73,7 @@ There is no random number generator. #define FAILCOUNT_EVENT RANDOM_EVENT(2,5) #define MODNAME_EVENT RANDOM_EVENT(2,5) #define MODDATE_EVENT RANDOM_EVENT(2,5) +#define EXTRA_EVENT RANDOM_EVENT(1,5) #define SET_EVENT RANDOM_EVENT(1,4) /* @@ -90,6 +91,145 @@ time2string(ts) return(buf); } +static krb5_boolean +aux_data_inequal(in, out) + krb5_db_entry *in, *out; +{ + krb5_tl_data *intl, *outtl; + krb5_boolean found; + + if (in->n_tl_data != out->n_tl_data) + return(1); + found = 1; + for (intl = in->tl_data; intl; intl = intl->tl_data_next) { + found = 0; + for (outtl = out->tl_data; outtl; outtl = outtl->tl_data_next) { + if ((intl->tl_data_type == outtl->tl_data_type) && + (intl->tl_data_length == outtl->tl_data_length) && + !memcmp(intl->tl_data_contents, + outtl->tl_data_contents, + intl->tl_data_length)) { + outtl->tl_data_length = -outtl->tl_data_length; + found = 1; + } + } + if (!found) + break; + } + for (outtl = out->tl_data; outtl; outtl = outtl->tl_data_next) { + if (outtl->tl_data_length < 0) + outtl->tl_data_length = -outtl->tl_data_length; + } + return(!found); +} + +static void +print_auxdata(entp) + krb5_db_entry *entp; +{ + krb5_tl_data *tl; + int i; + + for (tl = entp->tl_data; tl; tl = tl->tl_data_next) { + printf("tl_data(%d)[len=%d] ", tl->tl_data_type, tl->tl_data_length); + for (i=0; itl_data_length; i++) + printf("%02x ", tl->tl_data_contents[i]); + printf("\n"); + } +} + +static krb5_boolean +key_data_inequal(in, out) + krb5_db_entry *in, *out; +{ + krb5_boolean found; + int i, j; + + if (in->n_key_data != out->n_key_data) + return(1); + found = 1; + for (i=0; in_key_data; i++) { + found = 0; + for (j=0; jn_key_data; j++) { + if ((in->key_data[i].key_data_kvno == + out->key_data[j].key_data_kvno) && + (in->key_data[i].key_data_type[0] == + out->key_data[j].key_data_type[0]) && + (in->key_data[i].key_data_type[1] == + out->key_data[j].key_data_type[1]) && + (in->key_data[i].key_data_length[0] == + out->key_data[j].key_data_length[0]) && + (in->key_data[i].key_data_length[1] == + out->key_data[j].key_data_length[1]) && + !memcmp(in->key_data[i].key_data_contents[0], + out->key_data[j].key_data_contents[0], + in->key_data[i].key_data_length[0]) && + (!in->key_data[i].key_data_length[1] || + !memcmp(in->key_data[i].key_data_contents[1], + out->key_data[j].key_data_contents[1], + in->key_data[i].key_data_length[1]))) { + out->key_data[j].key_data_length[0] = + -out->key_data[j].key_data_length[0]; + found = 1; + } + } + if (!found) + break; + } + for (j=0; jn_key_data; j++) { + if (out->key_data[j].key_data_length[0] < 0) + out->key_data[j].key_data_length[0] = + -out->key_data[j].key_data_length[0]; + } + return(!found); +} + +static void +print_keydata(entp) + krb5_db_entry *entp; +{ + int i, j; + + for (j=0; jn_key_data; j++) { + printf("key(vno=%d):key(type=%d)[contents= ", + entp->key_data[j].key_data_kvno, + entp->key_data[j].key_data_type[0]); + for (i=0; ikey_data[j].key_data_length[0]; i++) + printf("%02x ", entp->key_data[j].key_data_contents[0][i]); + printf("] salt(type=%d)", entp->key_data[j].key_data_type[1]); + if (entp->key_data[j].key_data_length[1]) { + printf("[contents= "); + for (i=0; ikey_data[j].key_data_length[1]; i++) + printf("%02x ", entp->key_data[j].key_data_contents[1][i]); + printf("]"); + } + printf("\n"); + } +} + +static krb5_boolean +extra_data_inequal(in, out) + krb5_db_entry *in, *out; +{ + if (in->e_length != out->e_length) + return(1); + if (in->e_length && memcmp(in->e_data, out->e_data, (size_t) in->e_length)) + return(1); + return(0); +} + +static void +print_extradata(entp) + krb5_db_entry *entp; +{ + int i; + + printf("extra:"); + for (i=0; ie_length; i++) + printf("%02x ", entp->e_data[i]); + printf("\n"); +} + /* * Generate a database entry, either randomly, or using well known values. */ @@ -134,18 +274,6 @@ gen_dbent(kcontext, dbentp, isrand, validp, pwdp, expectp) } } - /* Do kvno */ - if (isrand) { - if (KVNO_EVENT) { - dbentp->kvno = RAND(); - *validp |= KRB5_ADM_M_KVNO; - } - } - else { - dbentp->kvno = 1; - *validp |= KRB5_ADM_M_KVNO; - } - /* Do maxlife */ if (isrand) { if (MAXLIFE_EVENT) { @@ -211,47 +339,6 @@ gen_dbent(kcontext, dbentp, isrand, validp, pwdp, expectp) *validp |= KRB5_ADM_M_FLAGS; } - /* Do salts */ - if (isrand) { - if (SALT_EVENT) { - dbentp->salt_type = (RAND() % 1); - dbentp->alt_salt_type = (RAND() % 1); - *validp |= KRB5_ADM_M_SALTTYPE; - } - } - else { - dbentp->salt_type = dbentp->alt_salt_type = KRB5_KDB_SALTTYPE_NORMAL; - *validp |= KRB5_ADM_M_SALTTYPE; - } - - /* Do mkvno */ - if (isrand) { - if (MKVNO_EVENT) { - dbentp->mkvno = RAND(); - *validp |= KRB5_ADM_M_MKVNO; - } - } - else { - if (!is_set) { - dbentp->mkvno = 1; - *validp |= KRB5_ADM_M_MKVNO; - } - } - - /* Do lastpwchange */ - if (isrand) { - if (LASTPWCHANGE_EVENT) { - dbentp->last_pwd_change = RAND(); - *validp |= KRB5_ADM_M_LASTPWCHANGE; - } - } - else { - if (!is_set) { - dbentp->last_pwd_change = (krb5_timestamp) now - 3600; - *validp |= KRB5_ADM_M_LASTPWCHANGE; - } - } - /* Do lastsuccess */ if (isrand) { if (LASTSUCCESS_EVENT) { @@ -294,36 +381,139 @@ gen_dbent(kcontext, dbentp, isrand, validp, pwdp, expectp) } } - /* Do modname */ + /* + * Generate auxiliary data. + */ if (isrand) { - if (MODNAME_EVENT) { - if (!krb5_parse_name(kcontext, defprinc, &dbentp->mod_name)) { - *validp |= KRB5_ADM_M_MODNAME; + krb5_octet *lpw_change; + krb5_tl_data *tldata; + krb5_timestamp lpw; + krb5_tl_mod_princ mprinc; + int didone; + + didone = 0; + if (LASTPWCHANGE_EVENT) { + if ((tldata = (krb5_tl_data *) malloc(sizeof(krb5_tl_data))) && + (lpw_change = (krb5_octet *) malloc(sizeof(krb5_timestamp)))) { + lpw = (krb5_timestamp) RAND(); + lpw_change[0] = (unsigned char) ((lpw >> 24) & 0xff); + lpw_change[1] = (unsigned char) ((lpw >> 16) & 0xff); + lpw_change[2] = (unsigned char) ((lpw >> 8) & 0xff); + lpw_change[3] = (unsigned char) (lpw & 0xff); + tldata->tl_data_next = (krb5_tl_data *) NULL; + tldata->tl_data_type = KRB5_TL_LAST_PWD_CHANGE; + tldata->tl_data_length = sizeof(krb5_timestamp); + tldata->tl_data_contents = lpw_change; + dbentp->n_tl_data = 1; + dbentp->tl_data = tldata; + didone++; + } + } + if (MODNAME_EVENT || MODDATE_EVENT) { + mprinc.mod_date = (krb5_timestamp) RAND(); + if (!krb5_parse_name(kcontext, defprinc, &mprinc.mod_princ)) { + if (!krb5_dbe_encode_mod_princ_data(kcontext, &mprinc, dbentp)) + didone++; } } + if (didone) + *validp |= KRB5_ADM_M_AUXDATA; } else { - if (!is_set) { - if (!krb5_parse_name(kcontext, defprinc, &dbentp->mod_name)) { - *validp |= KRB5_ADM_M_MODNAME; - } + krb5_octet *lpw_change; + krb5_tl_data *tldata; + krb5_timestamp lpw; + krb5_tl_mod_princ mprinc; + + if ((tldata = (krb5_tl_data *) malloc(sizeof(krb5_tl_data))) && + (lpw_change = (krb5_octet *) malloc(sizeof(krb5_timestamp)))) { + lpw = (krb5_timestamp) now - 3600; + lpw_change[0] = (unsigned char) ((lpw >> 24) & 0xff); + lpw_change[1] = (unsigned char) ((lpw >> 16) & 0xff); + lpw_change[2] = (unsigned char) ((lpw >> 8) & 0xff); + lpw_change[3] = (unsigned char) (lpw & 0xff); + tldata->tl_data_next = (krb5_tl_data *) NULL; + tldata->tl_data_type = KRB5_TL_LAST_PWD_CHANGE; + tldata->tl_data_length = sizeof(krb5_timestamp); + tldata->tl_data_contents = lpw_change; + dbentp->n_tl_data = 1; + dbentp->tl_data = tldata; } + mprinc.mod_date = (krb5_timestamp) now; + if (!krb5_parse_name(kcontext, defprinc, &mprinc.mod_princ)) + krb5_dbe_encode_mod_princ_data(kcontext, &mprinc, dbentp); + *validp |= KRB5_ADM_M_AUXDATA; } - /* Do mod_date */ + /* Make key data */ if (isrand) { - if (MODDATE_EVENT) { - dbentp->mod_date = RAND(); - *validp |= KRB5_ADM_M_MODDATE; + int i, j, kl, sl; + + if (!is_set) { + for (i=0; i<(1+(RAND()%8)); i++) { + if (!krb5_dbe_create_key_data(kcontext, dbentp)) { + dbentp->key_data[i].key_data_kvno = RAND() % 32768; + dbentp->key_data[i].key_data_type[0] = RAND() % 32768; + dbentp->key_data[i].key_data_type[1] = RAND() % 32768; + kl = dbentp->key_data[i].key_data_length[0] = + 8 + (RAND() % 128); + sl = dbentp->key_data[i].key_data_length[1] = + 0 + (RAND() % 128); + if (dbentp->key_data[i].key_data_contents[0] = + (krb5_octet *) malloc(kl)) { + for (j=0; jkey_data[i].key_data_contents[0][j] = + RAND() % 256; + } + } + if (dbentp->key_data[i].key_data_contents[1] = + (krb5_octet *) malloc(sl)) { + for (j=0; jkey_data[i].key_data_contents[1][j] = + RAND() % 256; + } + } + *validp |= KRB5_ADM_M_KEYDATA; + } + } } } else { if (!is_set) { - dbentp->mod_date = (krb5_timestamp) now; - *validp |= KRB5_ADM_M_MODDATE; + if (!krb5_dbe_create_key_data(kcontext, dbentp)) { + int i; + + dbentp->key_data[0].key_data_kvno = 1; + dbentp->key_data[0].key_data_type[0] = 1; + dbentp->key_data[0].key_data_type[1] = 0; + dbentp->key_data[0].key_data_length[0] = 24; + dbentp->key_data[0].key_data_length[1] = 0; + if (dbentp->key_data[0].key_data_contents[0] = + (krb5_octet *) malloc(24)) { + for (i=0; i<24; i++) + dbentp->key_data[0].key_data_contents[0][i] = RAND() % 256; + } + dbentp->key_data[0].key_data_contents[1] = (krb5_octet *) NULL; + *validp |= KRB5_ADM_M_KEYDATA; + } } } + /* Make extra data */ + if (isrand && EXTRA_EVENT) { + dbentp->e_length = 8 + (RAND() % 504); + if (dbentp->e_data = (krb5_octet *) + malloc((size_t) dbentp->e_length)) { + int j; + for (j=0; je_length; j++) { + dbentp->e_data[j] = RAND() % 256; + } + *validp |= KRB5_ADM_M_EXTRADATA; + } + else + dbentp->e_length = 0; + } + if (is_set) { /* Only 25% may fail at most */ if (isrand && ((RAND() % 100) < 75)) { @@ -362,12 +552,6 @@ compare_entries(kcontext, ivalid, ientp, ipwd, ovalid, oentp, opwd) strcmp(ipwd, opwd))) return(0); - /* Handle/compare kvno */ - if (((ivalid & KRB5_ADM_M_KVNO) != 0) && - (((ovalid & KRB5_ADM_M_KVNO) == 0) || - (ientp->kvno != oentp->kvno))) - return(0); - /* Handle/compare maxlife */ if (((ivalid & KRB5_ADM_M_MAXLIFE) != 0) && (((ovalid & KRB5_ADM_M_MAXLIFE) == 0) || @@ -405,25 +589,6 @@ compare_entries(kcontext, ivalid, ientp, ipwd, ovalid, oentp, opwd) (ientp->attributes != oentp->attributes))) return(0); - /* Handle/compare salts */ - if (((ivalid & KRB5_ADM_M_SALTTYPE) != 0) && - (((ovalid & KRB5_ADM_M_SALTTYPE) == 0) || - (ientp->salt_type != oentp->salt_type) || - (ientp->alt_salt_type != oentp->alt_salt_type))) - return(0); - - /* Handle/compare mkvno */ - if (((ivalid & KRB5_ADM_M_MKVNO) != 0) && - (((ovalid & KRB5_ADM_M_MKVNO) == 0) || - (ientp->mkvno != oentp->mkvno))) - return(0); - - /* Handle/compare lastpwchange */ - if (((ivalid & KRB5_ADM_M_LASTPWCHANGE) != 0) && - (((ovalid & KRB5_ADM_M_LASTPWCHANGE) == 0) || - (ientp->last_pwd_change != oentp->last_pwd_change))) - return(0); - /* Handle/compare lastsuccess */ if (((ivalid & KRB5_ADM_M_LASTSUCCESS) != 0) && (((ovalid & KRB5_ADM_M_LASTSUCCESS) == 0) || @@ -442,17 +607,24 @@ compare_entries(kcontext, ivalid, ientp, ipwd, ovalid, oentp, opwd) (ientp->fail_auth_count != oentp->fail_auth_count))) return(0); - /* Handle/compare mod_name */ - if (((ivalid & KRB5_ADM_M_MODNAME) != 0) && - (((ovalid & KRB5_ADM_M_MODNAME) == 0) || - !krb5_principal_compare(kcontext, ientp->mod_name, oentp->mod_name))) + /* Handle/compare auxiliary data */ + if (((ivalid & KRB5_ADM_M_AUXDATA) != 0) && + (((ovalid & KRB5_ADM_M_AUXDATA) == 0) || + aux_data_inequal(ientp, oentp))) + return(0); + + /* Handle/compare key data */ + if (((ivalid & KRB5_ADM_M_KEYDATA) != 0) && + (((ovalid & KRB5_ADM_M_KEYDATA) == 0) || + key_data_inequal(ientp, oentp))) return(0); - /* Handle/compare mod_date */ - if (((ivalid & KRB5_ADM_M_MODDATE) != 0) && - (((ovalid & KRB5_ADM_M_MODDATE) == 0) || - (ientp->mod_date != oentp->mod_date))) + /* Handle/compare extra data */ + if (((ivalid & KRB5_ADM_M_EXTRADATA) != 0) && + (((ovalid & KRB5_ADM_M_EXTRADATA) == 0) || + extra_data_inequal(ientp, oentp))) return(0); + return(1); } @@ -472,10 +644,6 @@ print_dbent(kcontext, ivalid, ientp, ipwd) if ((ivalid & KRB5_ADM_M_PASSWORD) != 0) printf("Password:\t%s\n", ipwd); - /* Print kvno */ - if ((ivalid & KRB5_ADM_M_KVNO) != 0) - printf("kvno:\t\t%8d\t%08x\n", ientp->kvno, ientp->kvno); - /* Print maxlife */ if ((ivalid & KRB5_ADM_M_MAXLIFE) != 0) printf("max_life:\t%8d\t%08x\n", ientp->max_life, ientp->max_life); @@ -503,19 +671,6 @@ print_dbent(kcontext, ivalid, ientp, ipwd) if ((ivalid & KRB5_ADM_M_FLAGS) != 0) printf("flags:\t\t%8d\t%08x\n", ientp->attributes, ientp->attributes); - /* Print salts */ - if ((ivalid & KRB5_ADM_M_SALTTYPE) != 0) - printf("salts:\t\t%d, %d\n", ientp->salt_type, ientp->alt_salt_type); - - /* Print mkvno */ - if ((ivalid & KRB5_ADM_M_MKVNO) != 0) - printf("mkvno:\t\t%8d\t%08x\n", ientp->mkvno, ientp->mkvno); - - /* Print lastpwchange */ - if ((ivalid & KRB5_ADM_M_LASTPWCHANGE) != 0) - printf("lastpwchg:\t%8d\t%08x\t%s\n", ientp->last_pwd_change, - ientp->last_pwd_change, time2string(ientp->last_pwd_change)); - /* Print lastsuccess */ if ((ivalid & KRB5_ADM_M_LASTSUCCESS) != 0) printf("lastsucc:\t%8d\t%08x\t%s\n", ientp->last_success, @@ -531,20 +686,17 @@ print_dbent(kcontext, ivalid, ientp, ipwd) printf("failcount:\t%8d\t%08x\n", ientp->fail_auth_count, ientp->fail_auth_count); - /* Print mod_name */ - if ((ivalid & KRB5_ADM_M_MODNAME) != 0) { - char *mprinc; + /* Print auxiliary data */ + if ((ivalid & KRB5_ADM_M_AUXDATA) != 0) + print_auxdata(ientp); - if (!krb5_unparse_name(kcontext, ientp->mod_name, &mprinc)) { - printf("modname:\t%s\n", mprinc); - krb5_xfree(mprinc); - } - } + /* Print key data */ + if ((ivalid & KRB5_ADM_M_KEYDATA) != 0) + print_keydata(ientp); - /* Print mod_date */ - if ((ivalid & KRB5_ADM_M_MODDATE) != 0) - printf("moddate:\t%8d\t%08x\t%s\n", ientp->mod_date, - ientp->mod_date, time2string(ientp->mod_date)); + /* Print extra data */ + if ((ivalid & KRB5_ADM_M_EXTRADATA) != 0) + print_extradata(ientp); } /* @@ -714,11 +866,25 @@ do_test(pname, verbose, isrand, is_a_set, title, passno) /* Cleanup */ if (in_password) free(in_password); - if (in_dbent->mod_name) - krb5_free_principal(kcontext, in_dbent->mod_name); + if (in_dbent->tl_data) { + krb5_tl_data *xxx, *xxx1; + + for (xxx=in_dbent->tl_data; xxx; ) { + xxx1 = xxx; + xxx = xxx->tl_data_next; + free(xxx1); + } + } free(in_dbent); - if (out_dbent->mod_name) - krb5_free_principal(kcontext, out_dbent->mod_name); + if (out_dbent->tl_data) { + krb5_tl_data *xxx, *xxx1; + + for (xxx=out_dbent->tl_data; xxx; ) { + xxx1 = xxx; + xxx = xxx->tl_data_next; + free(xxx1); + } + } free(out_dbent); } else { -- 2.26.2