15e9cd1aeSAssar Westerlund /*
2*ae771770SStanislav Sedov * Copyright (c) 2000 Kungliga Tekniska Högskolan
35e9cd1aeSAssar Westerlund * (Royal Institute of Technology, Stockholm, Sweden).
45e9cd1aeSAssar Westerlund * All rights reserved.
55e9cd1aeSAssar Westerlund *
65e9cd1aeSAssar Westerlund * Redistribution and use in source and binary forms, with or without
75e9cd1aeSAssar Westerlund * modification, are permitted provided that the following conditions
85e9cd1aeSAssar Westerlund * are met:
95e9cd1aeSAssar Westerlund *
105e9cd1aeSAssar Westerlund * 1. Redistributions of source code must retain the above copyright
115e9cd1aeSAssar Westerlund * notice, this list of conditions and the following disclaimer.
125e9cd1aeSAssar Westerlund *
135e9cd1aeSAssar Westerlund * 2. Redistributions in binary form must reproduce the above copyright
145e9cd1aeSAssar Westerlund * notice, this list of conditions and the following disclaimer in the
155e9cd1aeSAssar Westerlund * documentation and/or other materials provided with the distribution.
165e9cd1aeSAssar Westerlund *
175e9cd1aeSAssar Westerlund * 3. Neither the name of the Institute nor the names of its contributors
185e9cd1aeSAssar Westerlund * may be used to endorse or promote products derived from this software
195e9cd1aeSAssar Westerlund * without specific prior written permission.
205e9cd1aeSAssar Westerlund *
215e9cd1aeSAssar Westerlund * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
225e9cd1aeSAssar Westerlund * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
235e9cd1aeSAssar Westerlund * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
245e9cd1aeSAssar Westerlund * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
255e9cd1aeSAssar Westerlund * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
265e9cd1aeSAssar Westerlund * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
275e9cd1aeSAssar Westerlund * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
285e9cd1aeSAssar Westerlund * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
295e9cd1aeSAssar Westerlund * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
305e9cd1aeSAssar Westerlund * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
315e9cd1aeSAssar Westerlund * SUCH DAMAGE.
325e9cd1aeSAssar Westerlund */
335e9cd1aeSAssar Westerlund
345e9cd1aeSAssar Westerlund #include "hprop.h"
355e9cd1aeSAssar Westerlund
365e9cd1aeSAssar Westerlund /*
375e9cd1aeSAssar Westerlund can have any number of princ stanzas.
385e9cd1aeSAssar Westerlund format is as follows (only \n indicates newlines)
395e9cd1aeSAssar Westerlund princ\t%d\t (%d is KRB5_KDB_V1_BASE_LENGTH, always 38)
405e9cd1aeSAssar Westerlund %d\t (strlen of principal e.g. shadow/foo@ANDREW.CMU.EDU)
415e9cd1aeSAssar Westerlund %d\t (number of tl_data)
425e9cd1aeSAssar Westerlund %d\t (number of key data, e.g. how many keys for this user)
435e9cd1aeSAssar Westerlund %d\t (extra data length)
445e9cd1aeSAssar Westerlund %s\t (principal name)
455e9cd1aeSAssar Westerlund %d\t (attributes)
465e9cd1aeSAssar Westerlund %d\t (max lifetime, seconds)
475e9cd1aeSAssar Westerlund %d\t (max renewable life, seconds)
485e9cd1aeSAssar Westerlund %d\t (expiration, seconds since epoch or 2145830400 for never)
495e9cd1aeSAssar Westerlund %d\t (password expiration, seconds, 0 for never)
505e9cd1aeSAssar Westerlund %d\t (last successful auth, seconds since epoch)
515e9cd1aeSAssar Westerlund %d\t (last failed auth, per above)
525e9cd1aeSAssar Westerlund %d\t (failed auth count)
535e9cd1aeSAssar Westerlund foreach tl_data 0 to number of tl_data - 1 as above
545e9cd1aeSAssar Westerlund %d\t%d\t (data type, data length)
555e9cd1aeSAssar Westerlund foreach tl_data 0 to length-1
565e9cd1aeSAssar Westerlund %02x (tl data contents[element n])
575e9cd1aeSAssar Westerlund except if tl_data length is 0
585e9cd1aeSAssar Westerlund %d (always -1)
595e9cd1aeSAssar Westerlund \t
605e9cd1aeSAssar Westerlund foreach key 0 to number of keys - 1 as above
615e9cd1aeSAssar Westerlund %d\t%d\t (key data version, kvno)
625e9cd1aeSAssar Westerlund foreach version 0 to key data version - 1 (a key or a salt)
635e9cd1aeSAssar Westerlund %d\t%d\t(data type for this key, data length for this key)
645e9cd1aeSAssar Westerlund foreach key data length 0 to length-1
655e9cd1aeSAssar Westerlund %02x (key data contents[element n])
665e9cd1aeSAssar Westerlund except if key_data length is 0
675e9cd1aeSAssar Westerlund %d (always -1)
685e9cd1aeSAssar Westerlund \t
695e9cd1aeSAssar Westerlund foreach extra data length 0 to length - 1
705e9cd1aeSAssar Westerlund %02x (extra data part)
715e9cd1aeSAssar Westerlund unless no extra data
725e9cd1aeSAssar Westerlund %d (always -1)
735e9cd1aeSAssar Westerlund ;\n
745e9cd1aeSAssar Westerlund
755e9cd1aeSAssar Westerlund */
765e9cd1aeSAssar Westerlund
775e9cd1aeSAssar Westerlund static int
hex_to_octet_string(const char * ptr,krb5_data * data)785e9cd1aeSAssar Westerlund hex_to_octet_string(const char *ptr, krb5_data *data)
795e9cd1aeSAssar Westerlund {
80*ae771770SStanislav Sedov size_t i;
815e9cd1aeSAssar Westerlund unsigned int v;
825e9cd1aeSAssar Westerlund for(i = 0; i < data->length; i++) {
835e9cd1aeSAssar Westerlund if(sscanf(ptr + 2 * i, "%02x", &v) != 1)
845e9cd1aeSAssar Westerlund return -1;
855e9cd1aeSAssar Westerlund ((unsigned char*)data->data)[i] = v;
865e9cd1aeSAssar Westerlund }
875e9cd1aeSAssar Westerlund return 2 * i;
885e9cd1aeSAssar Westerlund }
895e9cd1aeSAssar Westerlund
905e9cd1aeSAssar Westerlund static char *
nexttoken(char ** p)915e9cd1aeSAssar Westerlund nexttoken(char **p)
925e9cd1aeSAssar Westerlund {
935e9cd1aeSAssar Westerlund char *q;
945e9cd1aeSAssar Westerlund do {
955e9cd1aeSAssar Westerlund q = strsep(p, " \t");
965e9cd1aeSAssar Westerlund } while(q && *q == '\0');
975e9cd1aeSAssar Westerlund return q;
985e9cd1aeSAssar Westerlund }
995e9cd1aeSAssar Westerlund
1005e9cd1aeSAssar Westerlund static size_t
getdata(char ** p,unsigned char * buf,size_t len)1015e9cd1aeSAssar Westerlund getdata(char **p, unsigned char *buf, size_t len)
1025e9cd1aeSAssar Westerlund {
1035e9cd1aeSAssar Westerlund size_t i;
1045e9cd1aeSAssar Westerlund int v;
1055e9cd1aeSAssar Westerlund char *q = nexttoken(p);
1065e9cd1aeSAssar Westerlund i = 0;
1075e9cd1aeSAssar Westerlund while(*q && i < len) {
1085e9cd1aeSAssar Westerlund if(sscanf(q, "%02x", &v) != 1)
1095e9cd1aeSAssar Westerlund break;
1105e9cd1aeSAssar Westerlund buf[i++] = v;
1115e9cd1aeSAssar Westerlund q += 2;
1125e9cd1aeSAssar Westerlund }
1135e9cd1aeSAssar Westerlund return i;
1145e9cd1aeSAssar Westerlund }
1155e9cd1aeSAssar Westerlund
1165e9cd1aeSAssar Westerlund static int
getint(char ** p)1175e9cd1aeSAssar Westerlund getint(char **p)
1185e9cd1aeSAssar Westerlund {
1195e9cd1aeSAssar Westerlund int val;
1205e9cd1aeSAssar Westerlund char *q = nexttoken(p);
1215e9cd1aeSAssar Westerlund sscanf(q, "%d", &val);
1225e9cd1aeSAssar Westerlund return val;
1235e9cd1aeSAssar Westerlund }
1245e9cd1aeSAssar Westerlund
1255e9cd1aeSAssar Westerlund #include <kadm5/admin.h>
1265e9cd1aeSAssar Westerlund
1275e9cd1aeSAssar Westerlund static void
attr_to_flags(unsigned attr,HDBFlags * flags)1285e9cd1aeSAssar Westerlund attr_to_flags(unsigned attr, HDBFlags *flags)
1295e9cd1aeSAssar Westerlund {
1305e9cd1aeSAssar Westerlund flags->postdate = !(attr & KRB5_KDB_DISALLOW_POSTDATED);
1315e9cd1aeSAssar Westerlund flags->forwardable = !(attr & KRB5_KDB_DISALLOW_FORWARDABLE);
1325e9cd1aeSAssar Westerlund flags->initial = !!(attr & KRB5_KDB_DISALLOW_TGT_BASED);
1335e9cd1aeSAssar Westerlund flags->renewable = !(attr & KRB5_KDB_DISALLOW_RENEWABLE);
1345e9cd1aeSAssar Westerlund flags->proxiable = !(attr & KRB5_KDB_DISALLOW_PROXIABLE);
1355e9cd1aeSAssar Westerlund /* DUP_SKEY */
1365e9cd1aeSAssar Westerlund flags->invalid = !!(attr & KRB5_KDB_DISALLOW_ALL_TIX);
1375e9cd1aeSAssar Westerlund flags->require_preauth = !!(attr & KRB5_KDB_REQUIRES_PRE_AUTH);
138*ae771770SStanislav Sedov flags->require_hwauth = !!(attr & KRB5_KDB_REQUIRES_HW_AUTH);
1395e9cd1aeSAssar Westerlund flags->server = !(attr & KRB5_KDB_DISALLOW_SVR);
1405e9cd1aeSAssar Westerlund flags->change_pw = !!(attr & KRB5_KDB_PWCHANGE_SERVICE);
1415e9cd1aeSAssar Westerlund flags->client = 1; /* XXX */
1425e9cd1aeSAssar Westerlund }
1435e9cd1aeSAssar Westerlund
1445e9cd1aeSAssar Westerlund #define KRB5_KDB_SALTTYPE_NORMAL 0
1455e9cd1aeSAssar Westerlund #define KRB5_KDB_SALTTYPE_V4 1
1465e9cd1aeSAssar Westerlund #define KRB5_KDB_SALTTYPE_NOREALM 2
1475e9cd1aeSAssar Westerlund #define KRB5_KDB_SALTTYPE_ONLYREALM 3
1485e9cd1aeSAssar Westerlund #define KRB5_KDB_SALTTYPE_SPECIAL 4
1495e9cd1aeSAssar Westerlund #define KRB5_KDB_SALTTYPE_AFS3 5
1505e9cd1aeSAssar Westerlund
1515e9cd1aeSAssar Westerlund static krb5_error_code
fix_salt(krb5_context context,hdb_entry * ent,int key_num)1525e9cd1aeSAssar Westerlund fix_salt(krb5_context context, hdb_entry *ent, int key_num)
1535e9cd1aeSAssar Westerlund {
1545e9cd1aeSAssar Westerlund krb5_error_code ret;
1555e9cd1aeSAssar Westerlund Salt *salt = ent->keys.val[key_num].salt;
1565e9cd1aeSAssar Westerlund /* fix salt type */
1575e9cd1aeSAssar Westerlund switch((int)salt->type) {
1585e9cd1aeSAssar Westerlund case KRB5_KDB_SALTTYPE_NORMAL:
1595e9cd1aeSAssar Westerlund salt->type = KRB5_PADATA_PW_SALT;
1605e9cd1aeSAssar Westerlund break;
1615e9cd1aeSAssar Westerlund case KRB5_KDB_SALTTYPE_V4:
1625e9cd1aeSAssar Westerlund krb5_data_free(&salt->salt);
1635e9cd1aeSAssar Westerlund salt->type = KRB5_PADATA_PW_SALT;
1645e9cd1aeSAssar Westerlund break;
1655e9cd1aeSAssar Westerlund case KRB5_KDB_SALTTYPE_NOREALM:
1665e9cd1aeSAssar Westerlund {
1675e9cd1aeSAssar Westerlund size_t len;
168*ae771770SStanislav Sedov size_t i;
1695e9cd1aeSAssar Westerlund char *p;
1705e9cd1aeSAssar Westerlund
1715e9cd1aeSAssar Westerlund len = 0;
1725e9cd1aeSAssar Westerlund for (i = 0; i < ent->principal->name.name_string.len; ++i)
1735e9cd1aeSAssar Westerlund len += strlen(ent->principal->name.name_string.val[i]);
1745e9cd1aeSAssar Westerlund ret = krb5_data_alloc (&salt->salt, len);
1755e9cd1aeSAssar Westerlund if (ret)
1765e9cd1aeSAssar Westerlund return ret;
1775e9cd1aeSAssar Westerlund p = salt->salt.data;
1785e9cd1aeSAssar Westerlund for (i = 0; i < ent->principal->name.name_string.len; ++i) {
1795e9cd1aeSAssar Westerlund memcpy (p,
1805e9cd1aeSAssar Westerlund ent->principal->name.name_string.val[i],
1815e9cd1aeSAssar Westerlund strlen(ent->principal->name.name_string.val[i]));
1825e9cd1aeSAssar Westerlund p += strlen(ent->principal->name.name_string.val[i]);
1835e9cd1aeSAssar Westerlund }
1845e9cd1aeSAssar Westerlund
1855e9cd1aeSAssar Westerlund salt->type = KRB5_PADATA_PW_SALT;
1865e9cd1aeSAssar Westerlund break;
1875e9cd1aeSAssar Westerlund }
1885e9cd1aeSAssar Westerlund case KRB5_KDB_SALTTYPE_ONLYREALM:
1895e9cd1aeSAssar Westerlund krb5_data_free(&salt->salt);
1905e9cd1aeSAssar Westerlund ret = krb5_data_copy(&salt->salt,
1915e9cd1aeSAssar Westerlund ent->principal->realm,
1925e9cd1aeSAssar Westerlund strlen(ent->principal->realm));
1935e9cd1aeSAssar Westerlund if(ret)
1945e9cd1aeSAssar Westerlund return ret;
1955e9cd1aeSAssar Westerlund salt->type = KRB5_PADATA_PW_SALT;
1965e9cd1aeSAssar Westerlund break;
1975e9cd1aeSAssar Westerlund case KRB5_KDB_SALTTYPE_SPECIAL:
1985e9cd1aeSAssar Westerlund salt->type = KRB5_PADATA_PW_SALT;
1995e9cd1aeSAssar Westerlund break;
2005e9cd1aeSAssar Westerlund case KRB5_KDB_SALTTYPE_AFS3:
2015e9cd1aeSAssar Westerlund krb5_data_free(&salt->salt);
2025e9cd1aeSAssar Westerlund ret = krb5_data_copy(&salt->salt,
2035e9cd1aeSAssar Westerlund ent->principal->realm,
2045e9cd1aeSAssar Westerlund strlen(ent->principal->realm));
2055e9cd1aeSAssar Westerlund if(ret)
2065e9cd1aeSAssar Westerlund return ret;
2075e9cd1aeSAssar Westerlund salt->type = KRB5_PADATA_AFS3_SALT;
2085e9cd1aeSAssar Westerlund break;
2095e9cd1aeSAssar Westerlund default:
2105e9cd1aeSAssar Westerlund abort();
2115e9cd1aeSAssar Westerlund }
2125e9cd1aeSAssar Westerlund return 0;
2135e9cd1aeSAssar Westerlund }
2145e9cd1aeSAssar Westerlund
2155e9cd1aeSAssar Westerlund int
mit_prop_dump(void * arg,const char * file)2165e9cd1aeSAssar Westerlund mit_prop_dump(void *arg, const char *file)
2175e9cd1aeSAssar Westerlund {
2185e9cd1aeSAssar Westerlund krb5_error_code ret;
219c19800e8SDoug Rabson char line [2048];
2205e9cd1aeSAssar Westerlund FILE *f;
2215e9cd1aeSAssar Westerlund int lineno = 0;
222c19800e8SDoug Rabson struct hdb_entry_ex ent;
2235e9cd1aeSAssar Westerlund
2245e9cd1aeSAssar Westerlund struct prop_data *pd = arg;
2255e9cd1aeSAssar Westerlund
2265e9cd1aeSAssar Westerlund f = fopen(file, "r");
2275e9cd1aeSAssar Westerlund if(f == NULL)
2285e9cd1aeSAssar Westerlund return errno;
2295e9cd1aeSAssar Westerlund
230c19800e8SDoug Rabson while(fgets(line, sizeof(line), f)) {
231c19800e8SDoug Rabson char *p = line, *q;
2325e9cd1aeSAssar Westerlund
2335e9cd1aeSAssar Westerlund int i;
2345e9cd1aeSAssar Westerlund
2355e9cd1aeSAssar Westerlund int num_tl_data;
2365e9cd1aeSAssar Westerlund int num_key_data;
237*ae771770SStanislav Sedov int high_kvno;
2385e9cd1aeSAssar Westerlund int attributes;
2395e9cd1aeSAssar Westerlund
2405e9cd1aeSAssar Westerlund int tmp;
2415e9cd1aeSAssar Westerlund
2425e9cd1aeSAssar Westerlund lineno++;
2435e9cd1aeSAssar Westerlund
2445e9cd1aeSAssar Westerlund memset(&ent, 0, sizeof(ent));
2455e9cd1aeSAssar Westerlund
2465e9cd1aeSAssar Westerlund q = nexttoken(&p);
2475e9cd1aeSAssar Westerlund if(strcmp(q, "kdb5_util") == 0) {
2485e9cd1aeSAssar Westerlund int major;
2495e9cd1aeSAssar Westerlund q = nexttoken(&p); /* load_dump */
2505e9cd1aeSAssar Westerlund if(strcmp(q, "load_dump"))
2515e9cd1aeSAssar Westerlund errx(1, "line %d: unknown version", lineno);
2525e9cd1aeSAssar Westerlund q = nexttoken(&p); /* load_dump */
2535e9cd1aeSAssar Westerlund if(strcmp(q, "version"))
2545e9cd1aeSAssar Westerlund errx(1, "line %d: unknown version", lineno);
2555e9cd1aeSAssar Westerlund q = nexttoken(&p); /* x.0 */
2565e9cd1aeSAssar Westerlund if(sscanf(q, "%d", &major) != 1)
2575e9cd1aeSAssar Westerlund errx(1, "line %d: unknown version", lineno);
258*ae771770SStanislav Sedov if(major != 4 && major != 5 && major != 6)
259*ae771770SStanislav Sedov errx(1, "unknown dump file format, got %d, expected 4-6",
260*ae771770SStanislav Sedov major);
261*ae771770SStanislav Sedov continue;
262*ae771770SStanislav Sedov } else if(strcmp(q, "policy") == 0) {
2635e9cd1aeSAssar Westerlund continue;
2645e9cd1aeSAssar Westerlund } else if(strcmp(q, "princ") != 0) {
2655e9cd1aeSAssar Westerlund warnx("line %d: not a principal", lineno);
2665e9cd1aeSAssar Westerlund continue;
2675e9cd1aeSAssar Westerlund }
2685e9cd1aeSAssar Westerlund tmp = getint(&p);
2695e9cd1aeSAssar Westerlund if(tmp != 38) {
2705e9cd1aeSAssar Westerlund warnx("line %d: bad base length %d != 38", lineno, tmp);
2715e9cd1aeSAssar Westerlund continue;
2725e9cd1aeSAssar Westerlund }
273*ae771770SStanislav Sedov nexttoken(&p); /* length of principal */
2745e9cd1aeSAssar Westerlund num_tl_data = getint(&p); /* number of tl-data */
2755e9cd1aeSAssar Westerlund num_key_data = getint(&p); /* number of key-data */
276*ae771770SStanislav Sedov getint(&p); /* length of extra data */
2775e9cd1aeSAssar Westerlund q = nexttoken(&p); /* principal name */
278c19800e8SDoug Rabson krb5_parse_name(pd->context, q, &ent.entry.principal);
2795e9cd1aeSAssar Westerlund attributes = getint(&p); /* attributes */
280c19800e8SDoug Rabson attr_to_flags(attributes, &ent.entry.flags);
2815e9cd1aeSAssar Westerlund tmp = getint(&p); /* max life */
2825e9cd1aeSAssar Westerlund if(tmp != 0) {
283c19800e8SDoug Rabson ALLOC(ent.entry.max_life);
284c19800e8SDoug Rabson *ent.entry.max_life = tmp;
2855e9cd1aeSAssar Westerlund }
2865e9cd1aeSAssar Westerlund tmp = getint(&p); /* max renewable life */
2875e9cd1aeSAssar Westerlund if(tmp != 0) {
288c19800e8SDoug Rabson ALLOC(ent.entry.max_renew);
289c19800e8SDoug Rabson *ent.entry.max_renew = tmp;
2905e9cd1aeSAssar Westerlund }
2915e9cd1aeSAssar Westerlund tmp = getint(&p); /* expiration */
2925e9cd1aeSAssar Westerlund if(tmp != 0 && tmp != 2145830400) {
293c19800e8SDoug Rabson ALLOC(ent.entry.valid_end);
294c19800e8SDoug Rabson *ent.entry.valid_end = tmp;
2955e9cd1aeSAssar Westerlund }
2965e9cd1aeSAssar Westerlund tmp = getint(&p); /* pw expiration */
2975e9cd1aeSAssar Westerlund if(tmp != 0) {
298c19800e8SDoug Rabson ALLOC(ent.entry.pw_end);
299c19800e8SDoug Rabson *ent.entry.pw_end = tmp;
3005e9cd1aeSAssar Westerlund }
301*ae771770SStanislav Sedov nexttoken(&p); /* last auth */
302*ae771770SStanislav Sedov nexttoken(&p); /* last failed auth */
303*ae771770SStanislav Sedov nexttoken(&p); /* fail auth count */
3045e9cd1aeSAssar Westerlund for(i = 0; i < num_tl_data; i++) {
3055e9cd1aeSAssar Westerlund unsigned long val;
3065e9cd1aeSAssar Westerlund int tl_type, tl_length;
3075e9cd1aeSAssar Westerlund unsigned char *buf;
3085e9cd1aeSAssar Westerlund krb5_principal princ;
3095e9cd1aeSAssar Westerlund
3105e9cd1aeSAssar Westerlund tl_type = getint(&p); /* data type */
3115e9cd1aeSAssar Westerlund tl_length = getint(&p); /* data length */
3125e9cd1aeSAssar Westerlund
313c19800e8SDoug Rabson #define mit_KRB5_TL_LAST_PWD_CHANGE 1
314c19800e8SDoug Rabson #define mit_KRB5_TL_MOD_PRINC 2
3155e9cd1aeSAssar Westerlund switch(tl_type) {
316*ae771770SStanislav Sedov case mit_KRB5_TL_LAST_PWD_CHANGE:
317*ae771770SStanislav Sedov buf = malloc(tl_length);
318*ae771770SStanislav Sedov if (buf == NULL)
319*ae771770SStanislav Sedov errx(ENOMEM, "malloc");
320*ae771770SStanislav Sedov getdata(&p, buf, tl_length); /* data itself */
321*ae771770SStanislav Sedov val = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
322*ae771770SStanislav Sedov free(buf);
323*ae771770SStanislav Sedov ALLOC(ent.entry.extensions);
324*ae771770SStanislav Sedov ALLOC_SEQ(ent.entry.extensions, 1);
325*ae771770SStanislav Sedov ent.entry.extensions->val[0].mandatory = 0;
326*ae771770SStanislav Sedov ent.entry.extensions->val[0].data.element
327*ae771770SStanislav Sedov = choice_HDB_extension_data_last_pw_change;
328*ae771770SStanislav Sedov ent.entry.extensions->val[0].data.u.last_pw_change = val;
329*ae771770SStanislav Sedov break;
330c19800e8SDoug Rabson case mit_KRB5_TL_MOD_PRINC:
3315e9cd1aeSAssar Westerlund buf = malloc(tl_length);
332c19800e8SDoug Rabson if (buf == NULL)
333c19800e8SDoug Rabson errx(ENOMEM, "malloc");
3345e9cd1aeSAssar Westerlund getdata(&p, buf, tl_length); /* data itself */
3355e9cd1aeSAssar Westerlund val = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
336c19800e8SDoug Rabson ret = krb5_parse_name(pd->context, (char *)buf + 4, &princ);
337*ae771770SStanislav Sedov if (ret)
338*ae771770SStanislav Sedov krb5_err(pd->context, 1, ret,
339*ae771770SStanislav Sedov "parse_name: %s", (char *)buf + 4);
3405e9cd1aeSAssar Westerlund free(buf);
341c19800e8SDoug Rabson ALLOC(ent.entry.modified_by);
342c19800e8SDoug Rabson ent.entry.modified_by->time = val;
343c19800e8SDoug Rabson ent.entry.modified_by->principal = princ;
3445e9cd1aeSAssar Westerlund break;
3455e9cd1aeSAssar Westerlund default:
3465e9cd1aeSAssar Westerlund nexttoken(&p);
3475e9cd1aeSAssar Westerlund break;
3485e9cd1aeSAssar Westerlund }
3495e9cd1aeSAssar Westerlund }
350c19800e8SDoug Rabson ALLOC_SEQ(&ent.entry.keys, num_key_data);
351*ae771770SStanislav Sedov high_kvno = -1;
3525e9cd1aeSAssar Westerlund for(i = 0; i < num_key_data; i++) {
3535e9cd1aeSAssar Westerlund int key_versions;
354*ae771770SStanislav Sedov int kvno;
3555e9cd1aeSAssar Westerlund key_versions = getint(&p); /* key data version */
356*ae771770SStanislav Sedov kvno = getint(&p);
3575e9cd1aeSAssar Westerlund
358*ae771770SStanislav Sedov /*
359*ae771770SStanislav Sedov * An MIT dump file may contain multiple sets of keys with
360*ae771770SStanislav Sedov * different kvnos. Since the Heimdal database can only represent
361*ae771770SStanislav Sedov * one kvno per principal, we only want the highest set. Assume
362*ae771770SStanislav Sedov * that set will be given first, and discard all keys with lower
363*ae771770SStanislav Sedov * kvnos.
364*ae771770SStanislav Sedov */
365*ae771770SStanislav Sedov if (kvno > high_kvno && high_kvno != -1)
366*ae771770SStanislav Sedov errx(1, "line %d: high kvno keys given after low kvno keys",
367*ae771770SStanislav Sedov lineno);
368*ae771770SStanislav Sedov else if (kvno < high_kvno) {
369*ae771770SStanislav Sedov nexttoken(&p); /* key type */
370*ae771770SStanislav Sedov nexttoken(&p); /* key length */
371*ae771770SStanislav Sedov nexttoken(&p); /* key */
372*ae771770SStanislav Sedov if (key_versions > 1) {
373*ae771770SStanislav Sedov nexttoken(&p); /* salt type */
374*ae771770SStanislav Sedov nexttoken(&p); /* salt length */
375*ae771770SStanislav Sedov nexttoken(&p); /* salt */
376*ae771770SStanislav Sedov }
377*ae771770SStanislav Sedov ent.entry.keys.len--;
378*ae771770SStanislav Sedov continue;
379*ae771770SStanislav Sedov }
380*ae771770SStanislav Sedov ent.entry.kvno = kvno;
381*ae771770SStanislav Sedov high_kvno = kvno;
382c19800e8SDoug Rabson ALLOC(ent.entry.keys.val[i].mkvno);
383*ae771770SStanislav Sedov *ent.entry.keys.val[i].mkvno = 1;
3845e9cd1aeSAssar Westerlund
3855e9cd1aeSAssar Westerlund /* key version 0 -- actual key */
386c19800e8SDoug Rabson ent.entry.keys.val[i].key.keytype = getint(&p); /* key type */
3875e9cd1aeSAssar Westerlund tmp = getint(&p); /* key length */
3885e9cd1aeSAssar Westerlund /* the first two bytes of the key is the key length --
3895e9cd1aeSAssar Westerlund skip it */
390c19800e8SDoug Rabson krb5_data_alloc(&ent.entry.keys.val[i].key.keyvalue, tmp - 2);
3915e9cd1aeSAssar Westerlund q = nexttoken(&p); /* key itself */
392c19800e8SDoug Rabson hex_to_octet_string(q + 4, &ent.entry.keys.val[i].key.keyvalue);
3935e9cd1aeSAssar Westerlund
3945e9cd1aeSAssar Westerlund if(key_versions > 1) {
3955e9cd1aeSAssar Westerlund /* key version 1 -- optional salt */
396c19800e8SDoug Rabson ALLOC(ent.entry.keys.val[i].salt);
397c19800e8SDoug Rabson ent.entry.keys.val[i].salt->type = getint(&p); /* salt type */
3985e9cd1aeSAssar Westerlund tmp = getint(&p); /* salt length */
3995e9cd1aeSAssar Westerlund if(tmp > 0) {
400c19800e8SDoug Rabson krb5_data_alloc(&ent.entry.keys.val[i].salt->salt, tmp - 2);
4015e9cd1aeSAssar Westerlund q = nexttoken(&p); /* salt itself */
402c19800e8SDoug Rabson hex_to_octet_string(q + 4,
403c19800e8SDoug Rabson &ent.entry.keys.val[i].salt->salt);
4045e9cd1aeSAssar Westerlund } else {
405c19800e8SDoug Rabson ent.entry.keys.val[i].salt->salt.length = 0;
406c19800e8SDoug Rabson ent.entry.keys.val[i].salt->salt.data = NULL;
407*ae771770SStanislav Sedov getint(&p); /* -1, if no data. */
4085e9cd1aeSAssar Westerlund }
409c19800e8SDoug Rabson fix_salt(pd->context, &ent.entry, i);
4105e9cd1aeSAssar Westerlund }
4115e9cd1aeSAssar Westerlund }
412*ae771770SStanislav Sedov nexttoken(&p); /* extra data */
4135e9cd1aeSAssar Westerlund v5_prop(pd->context, NULL, &ent, arg);
4145e9cd1aeSAssar Westerlund }
415c19800e8SDoug Rabson fclose(f);
4165e9cd1aeSAssar Westerlund return 0;
4175e9cd1aeSAssar Westerlund }
418