#define char2int(c) ((c) - '0')
\f
-/*
- * 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);
-}
-\f
/*
* keyword_value() - Find index of keyword value if keyword is present.
*
}
\f
/*
- * decode_kw_salttype() - Decode a keyword=<salttype> pair and fill in the
- * salt type values if the pair is present.
+ * decode_kw_tagged() - Decode a keyword=<taglist>...<data> 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<ntags; i++) {
+ if (&cp[sizeof(krb5_int32)] > 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);
}
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; i<nent; i++) {
break;
}
- /* Check for key version number */
- if (!(retval = decode_kw_integer(&data[i],
- KRB5_ADM_KW_KVNO,
- (krb5_ui_4 *) &dbentp->kvno))) {
- 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,
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,
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;
}
}
parsed_mask = 0;
}
+ if (correlators)
+ free(correlators);
*validp |= parsed_mask;
return(retval);
}
#include "adm.h"
#include "adm_proto.h"
-\f
-/*
- * 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);
-}
\f
/*
* format_kw_string() - Format a keyword=<string> pair.
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;
}
}
\f
/*
- * format_kw_salttype() - Format a keyword=<salttype> pair.
+ * format_kw_tagged() - Format a <tagged>=<taglist>...<value> 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<ntags; i++) {
+ cp[0] = (unsigned char) ((taglist[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);
}
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 */
(!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);
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],
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)) {
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) {
#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)
/*
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; i<tl->tl_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; i<in->n_key_data; i++) {
+ found = 0;
+ for (j=0; j<out->n_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; j<out->n_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; j<entp->n_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; i<entp->key_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; i<entp->key_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; i<entp->e_length; i++)
+ printf("%02x ", entp->e_data[i]);
+ printf("\n");
+}
+
/*
* Generate a database entry, either randomly, or using well known values.
*/
}
}
- /* 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) {
*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) {
}
}
- /* 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; j<kl; j++) {
+ dbentp->key_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; j<sl; j++) {
+ dbentp->key_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; j<dbentp->e_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)) {
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) ||
(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) ||
(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);
}
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);
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,
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);
}
/*
/* 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 {