155682Smarkm/*
2233294Sstas * Copyright (c) 1997-2005 Kungliga Tekniska H��gskolan
3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden).
4233294Sstas * All rights reserved.
555682Smarkm *
6233294Sstas * Redistribution and use in source and binary forms, with or without
7233294Sstas * modification, are permitted provided that the following conditions
8233294Sstas * are met:
955682Smarkm *
10233294Sstas * 1. Redistributions of source code must retain the above copyright
11233294Sstas *    notice, this list of conditions and the following disclaimer.
1255682Smarkm *
13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright
14233294Sstas *    notice, this list of conditions and the following disclaimer in the
15233294Sstas *    documentation and/or other materials provided with the distribution.
1655682Smarkm *
17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors
18233294Sstas *    may be used to endorse or promote products derived from this software
19233294Sstas *    without specific prior written permission.
2055682Smarkm *
21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24233294Sstas * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31233294Sstas * SUCH DAMAGE.
3255682Smarkm */
3355682Smarkm
3455682Smarkm#include "kadmin_locl.h"
35178825Sdfr#include "kadmin-commands.h"
3655682Smarkm#include <kadm5/private.h>
3755682Smarkm
3857416Smarkmstruct entry {
3955682Smarkm    char *principal;
4055682Smarkm    char *key;
4155682Smarkm    char *max_life;
4255682Smarkm    char *max_renew;
4355682Smarkm    char *created;
4455682Smarkm    char *modified;
4555682Smarkm    char *valid_start;
4655682Smarkm    char *valid_end;
4755682Smarkm    char *pw_end;
4855682Smarkm    char *flags;
4990926Snectar    char *generation;
50178825Sdfr    char *extensions;
5155682Smarkm};
5255682Smarkm
5355682Smarkmstatic char *
5455682Smarkmskip_next(char *p)
5555682Smarkm{
56233294Sstas    while(*p && !isspace((unsigned char)*p))
5755682Smarkm	p++;
5855682Smarkm    *p++ = 0;
5957416Smarkm    while(*p && isspace((unsigned char)*p))
6057416Smarkm	p++;
6155682Smarkm    return p;
6255682Smarkm}
6355682Smarkm
6457416Smarkm/*
6557416Smarkm * Parse the time in `s', returning:
6657416Smarkm * -1 if error parsing
6757416Smarkm * 0  if none  present
6857416Smarkm * 1  if parsed ok
6957416Smarkm */
7057416Smarkm
7157416Smarkmstatic int
7257416Smarkmparse_time_string(time_t *t, const char *s)
7355682Smarkm{
7455682Smarkm    int year, month, date, hour, minute, second;
7555682Smarkm    struct tm tm;
7657416Smarkm
7755682Smarkm    if(strcmp(s, "-") == 0)
7857416Smarkm	return 0;
79233294Sstas    if(sscanf(s, "%04d%02d%02d%02d%02d%02d",
8057416Smarkm	      &year, &month, &date, &hour, &minute, &second) != 6)
8157416Smarkm	return -1;
8257416Smarkm    tm.tm_year  = year - 1900;
8357416Smarkm    tm.tm_mon   = month - 1;
8457416Smarkm    tm.tm_mday  = date;
8557416Smarkm    tm.tm_hour  = hour;
8657416Smarkm    tm.tm_min   = minute;
8757416Smarkm    tm.tm_sec   = second;
8855682Smarkm    tm.tm_isdst = 0;
8955682Smarkm    *t = timegm(&tm);
9057416Smarkm    return 1;
9155682Smarkm}
9255682Smarkm
9357416Smarkm/*
9457416Smarkm * parse time, allocating space in *t if it's there
9557416Smarkm */
9657416Smarkm
9757416Smarkmstatic int
9857416Smarkmparse_time_string_alloc (time_t **t, const char *s)
9955682Smarkm{
10057416Smarkm    time_t tmp;
10157416Smarkm    int ret;
10257416Smarkm
10357416Smarkm    *t = NULL;
10457416Smarkm    ret = parse_time_string (&tmp, s);
10557416Smarkm    if (ret == 1) {
10657416Smarkm	*t = malloc (sizeof (**t));
10757416Smarkm	if (*t == NULL)
10857416Smarkm	    krb5_errx (context, 1, "malloc: out of memory");
10957416Smarkm	**t = tmp;
11057416Smarkm    }
11157416Smarkm    return ret;
11257416Smarkm}
11357416Smarkm
11457416Smarkm/*
11557416Smarkm * see parse_time_string for calling convention
11657416Smarkm */
11757416Smarkm
11857416Smarkmstatic int
119178825Sdfrparse_integer(unsigned int *u, const char *s)
12057416Smarkm{
12155682Smarkm    if(strcmp(s, "-") == 0)
12257416Smarkm	return 0;
12357416Smarkm    if (sscanf(s, "%u", u) != 1)
12457416Smarkm	return -1;
12557416Smarkm    return 1;
12655682Smarkm}
12755682Smarkm
12857416Smarkmstatic int
129178825Sdfrparse_integer_alloc (unsigned int **u, const char *s)
13057416Smarkm{
131178825Sdfr    unsigned int tmp;
13257416Smarkm    int ret;
13357416Smarkm
13457416Smarkm    *u = NULL;
13557416Smarkm    ret = parse_integer (&tmp, s);
13657416Smarkm    if (ret == 1) {
13757416Smarkm	*u = malloc (sizeof (**u));
13857416Smarkm	if (*u == NULL)
13957416Smarkm	    krb5_errx (context, 1, "malloc: out of memory");
14057416Smarkm	**u = tmp;
14157416Smarkm    }
14257416Smarkm    return ret;
14357416Smarkm}
14457416Smarkm
14557416Smarkm/*
14657416Smarkm * Parse dumped keys in `str' and store them in `ent'
14757416Smarkm * return -1 if parsing failed
14857416Smarkm */
14957416Smarkm
15057416Smarkmstatic int
15155682Smarkmparse_keys(hdb_entry *ent, char *str)
15255682Smarkm{
15357416Smarkm    krb5_error_code ret;
15455682Smarkm    int tmp;
15555682Smarkm    char *p;
156233294Sstas    size_t i;
157233294Sstas
15855682Smarkm    p = strsep(&str, ":");
15957416Smarkm    if (sscanf(p, "%d", &tmp) != 1)
16057416Smarkm	return 1;
16155682Smarkm    ent->kvno = tmp;
16255682Smarkm    p = strsep(&str, ":");
16355682Smarkm    while(p){
16455682Smarkm	Key *key;
165233294Sstas	key = realloc(ent->keys.val,
16655682Smarkm		      (ent->keys.len + 1) * sizeof(*ent->keys.val));
16755682Smarkm	if(key == NULL)
16857416Smarkm	    krb5_errx (context, 1, "realloc: out of memory");
16955682Smarkm	ent->keys.val = key;
17055682Smarkm	key = ent->keys.val + ent->keys.len;
17155682Smarkm	ent->keys.len++;
17255682Smarkm	memset(key, 0, sizeof(*key));
17355682Smarkm	if(sscanf(p, "%d", &tmp) == 1) {
17455682Smarkm	    key->mkvno = malloc(sizeof(*key->mkvno));
17555682Smarkm	    *key->mkvno = tmp;
17655682Smarkm	} else
17755682Smarkm	    key->mkvno = NULL;
17855682Smarkm	p = strsep(&str, ":");
17957416Smarkm	if (sscanf(p, "%d", &tmp) != 1)
18057416Smarkm	    return 1;
18155682Smarkm	key->key.keytype = tmp;
18255682Smarkm	p = strsep(&str, ":");
18357416Smarkm	ret = krb5_data_alloc(&key->key.keyvalue, (strlen(p) - 1) / 2 + 1);
18457416Smarkm	if (ret)
18557416Smarkm	    krb5_err (context, 1, ret, "krb5_data_alloc");
18657416Smarkm	for(i = 0; i < strlen(p); i += 2) {
18757416Smarkm	    if(sscanf(p + i, "%02x", &tmp) != 1)
18857416Smarkm		return 1;
18955682Smarkm	    ((u_char*)key->key.keyvalue.data)[i / 2] = tmp;
19055682Smarkm	}
19155682Smarkm	p = strsep(&str, ":");
19255682Smarkm	if(strcmp(p, "-") != 0){
19355682Smarkm	    unsigned type;
19455682Smarkm	    size_t p_len;
19557416Smarkm
19657416Smarkm	    if(sscanf(p, "%u/", &type) != 1)
19757416Smarkm		return 1;
19855682Smarkm	    p = strchr(p, '/');
19955682Smarkm	    if(p == NULL)
20057416Smarkm		return 1;
20155682Smarkm	    p++;
20255682Smarkm	    p_len = strlen(p);
20355682Smarkm
204233294Sstas	    key->salt = calloc(1, sizeof(*key->salt));
20557416Smarkm	    if (key->salt == NULL)
20657416Smarkm		krb5_errx (context, 1, "malloc: out of memory");
20755682Smarkm	    key->salt->type = type;
208233294Sstas
20955682Smarkm	    if (p_len) {
21057416Smarkm		if(*p == '\"') {
21157416Smarkm		    ret = krb5_data_copy(&key->salt->salt, p + 1, p_len - 2);
21257416Smarkm		    if (ret)
21357416Smarkm			krb5_err (context, 1, ret, "krb5_data_copy");
21457416Smarkm		} else {
21557416Smarkm		    ret = krb5_data_alloc(&key->salt->salt,
21657416Smarkm					  (p_len - 1) / 2 + 1);
21757416Smarkm		    if (ret)
21857416Smarkm			krb5_err (context, 1, ret, "krb5_data_alloc");
21955682Smarkm		    for(i = 0; i < p_len; i += 2){
22057416Smarkm			if (sscanf(p + i, "%02x", &tmp) != 1)
22157416Smarkm			    return 1;
22255682Smarkm			((u_char*)key->salt->salt.data)[i / 2] = tmp;
22355682Smarkm		    }
22455682Smarkm		}
22555682Smarkm	    } else
22655682Smarkm		krb5_data_zero (&key->salt->salt);
22755682Smarkm	}
22855682Smarkm	p = strsep(&str, ":");
22955682Smarkm    }
23057416Smarkm    return 0;
23155682Smarkm}
23255682Smarkm
23357416Smarkm/*
23457416Smarkm * see parse_time_string for calling convention
23557416Smarkm */
23657416Smarkm
23757416Smarkmstatic int
23857416Smarkmparse_event(Event *ev, char *s)
23955682Smarkm{
24057416Smarkm    krb5_error_code ret;
24155682Smarkm    char *p;
24257416Smarkm
24357416Smarkm    if(strcmp(s, "-") == 0)
24457416Smarkm	return 0;
24555682Smarkm    memset(ev, 0, sizeof(*ev));
24657416Smarkm    p = strsep(&s, ":");
24757416Smarkm    if(parse_time_string(&ev->time, p) != 1)
24857416Smarkm	return -1;
24957416Smarkm    p = strsep(&s, ":");
25057416Smarkm    ret = krb5_parse_name(context, p, &ev->principal);
25157416Smarkm    if (ret)
25257416Smarkm	return -1;
25357416Smarkm    return 1;
25455682Smarkm}
25555682Smarkm
25657416Smarkmstatic int
25757416Smarkmparse_event_alloc (Event **ev, char *s)
25855682Smarkm{
25957416Smarkm    Event tmp;
26057416Smarkm    int ret;
26155682Smarkm
26257416Smarkm    *ev = NULL;
26357416Smarkm    ret = parse_event (&tmp, s);
26457416Smarkm    if (ret == 1) {
26557416Smarkm	*ev = malloc (sizeof (**ev));
26657416Smarkm	if (*ev == NULL)
26757416Smarkm	    krb5_errx (context, 1, "malloc: out of memory");
26857416Smarkm	**ev = tmp;
26957416Smarkm    }
27057416Smarkm    return ret;
27155682Smarkm}
27255682Smarkm
27357416Smarkmstatic int
27457416Smarkmparse_hdbflags2int(HDBFlags *f, const char *s)
27557416Smarkm{
27657416Smarkm    int ret;
277178825Sdfr    unsigned int tmp;
27857416Smarkm
27957416Smarkm    ret = parse_integer (&tmp, s);
28057416Smarkm    if (ret == 1)
28157416Smarkm	*f = int2HDBFlags (tmp);
28257416Smarkm    return ret;
28357416Smarkm}
28457416Smarkm
28590926Snectarstatic int
28690926Snectarparse_generation(char *str, GENERATION **gen)
28755682Smarkm{
28890926Snectar    char *p;
28990926Snectar    int v;
29090926Snectar
291103423Snectar    if(strcmp(str, "-") == 0 || *str == '\0') {
29290926Snectar	*gen = NULL;
293103423Snectar	return 0;
294103423Snectar    }
29590926Snectar    *gen = calloc(1, sizeof(**gen));
29690926Snectar
29790926Snectar    p = strsep(&str, ":");
29890926Snectar    if(parse_time_string(&(*gen)->time, p) != 1)
29990926Snectar	return -1;
30090926Snectar    p = strsep(&str, ":");
30190926Snectar    if(sscanf(p, "%d", &v) != 1)
30290926Snectar	return -1;
30390926Snectar    (*gen)->usec = v;
30490926Snectar    p = strsep(&str, ":");
30590926Snectar    if(sscanf(p, "%d", &v) != 1)
30690926Snectar	return -1;
30790926Snectar    (*gen)->gen = v - 1; /* XXX gets bumped in _hdb_store */
30890926Snectar    return 0;
30955682Smarkm}
31055682Smarkm
311178825Sdfrstatic int
312178825Sdfrparse_extensions(char *str, HDB_extensions **e)
313178825Sdfr{
314178825Sdfr    char *p;
315178825Sdfr    int ret;
31690926Snectar
317178825Sdfr    if(strcmp(str, "-") == 0 || *str == '\0') {
318178825Sdfr	*e = NULL;
319178825Sdfr	return 0;
320178825Sdfr    }
321178825Sdfr    *e = calloc(1, sizeof(**e));
322178825Sdfr
323178825Sdfr    p = strsep(&str, ":");
324178825Sdfr
325178825Sdfr    while (p) {
326178825Sdfr	HDB_extension ext;
327178825Sdfr	ssize_t len;
328178825Sdfr	void *d;
329178825Sdfr
330178825Sdfr	len = strlen(p);
331178825Sdfr	d = malloc(len);
332178825Sdfr
333178825Sdfr	len = hex_decode(p, d, len);
334233294Sstas	if (len < 0) {
335233294Sstas	    free(d);
336178825Sdfr	    return -1;
337233294Sstas	}
338178825Sdfr
339178825Sdfr	ret = decode_HDB_extension(d, len, &ext, NULL);
340178825Sdfr	free(d);
341178825Sdfr	if (ret)
342178825Sdfr	    return -1;
343178825Sdfr	d = realloc((*e)->val, ((*e)->len + 1) * sizeof((*e)->val[0]));
344178825Sdfr	if (d == NULL)
345178825Sdfr	    abort();
346178825Sdfr	(*e)->val = d;
347178825Sdfr	(*e)->val[(*e)->len] = ext;
348178825Sdfr	(*e)->len++;
349178825Sdfr
350178825Sdfr	p = strsep(&str, ":");
351178825Sdfr    }
352178825Sdfr
353178825Sdfr    return 0;
354178825Sdfr}
355178825Sdfr
356178825Sdfr
35757416Smarkm/*
35857416Smarkm * Parse the dump file in `filename' and create the database (merging
35957416Smarkm * iff merge)
36057416Smarkm */
36157416Smarkm
36257416Smarkmstatic int
363178825Sdfrdoit(const char *filename, int mergep)
36455682Smarkm{
36555682Smarkm    krb5_error_code ret;
36655682Smarkm    FILE *f;
36790926Snectar    char s[8192]; /* XXX should fix this properly */
36855682Smarkm    char *p;
36955682Smarkm    int line;
37055682Smarkm    int flags = O_RDWR;
37155682Smarkm    struct entry e;
372178825Sdfr    hdb_entry_ex ent;
37355682Smarkm    HDB *db = _kadm5_s_get_db(kadm_handle);
37455682Smarkm
37555682Smarkm    f = fopen(filename, "r");
37655682Smarkm    if(f == NULL){
37755682Smarkm	krb5_warn(context, errno, "fopen(%s)", filename);
37857416Smarkm	return 1;
37955682Smarkm    }
38072445Sassar    ret = kadm5_log_truncate (kadm_handle);
38172445Sassar    if (ret) {
38272445Sassar	fclose (f);
38372445Sassar	krb5_warn(context, ret, "kadm5_log_truncate");
38472445Sassar	return 1;
38572445Sassar    }
38672445Sassar
387178825Sdfr    if(!mergep)
38855682Smarkm	flags |= O_CREAT | O_TRUNC;
389178825Sdfr    ret = db->hdb_open(context, db, flags, 0600);
39055682Smarkm    if(ret){
39155682Smarkm	krb5_warn(context, ret, "hdb_open");
39255682Smarkm	fclose(f);
39357416Smarkm	return 1;
39455682Smarkm    }
39555682Smarkm    line = 0;
39672445Sassar    ret = 0;
39772445Sassar    while(fgets(s, sizeof(s), f) != NULL) {
39855682Smarkm	line++;
399178825Sdfr
400178825Sdfr	p = s;
401178825Sdfr	while (isspace((unsigned char)*p))
402178825Sdfr	    p++;
403178825Sdfr
404178825Sdfr	e.principal = p;
40555682Smarkm	for(p = s; *p; p++){
40655682Smarkm	    if(*p == '\\')
40755682Smarkm		p++;
40855682Smarkm	    else if(isspace((unsigned char)*p)) {
40955682Smarkm		*p = 0;
41055682Smarkm		break;
41155682Smarkm	    }
41255682Smarkm	}
41355682Smarkm	p = skip_next(p);
414233294Sstas
41555682Smarkm	e.key = p;
41655682Smarkm	p = skip_next(p);
41755682Smarkm
41855682Smarkm	e.created = p;
41955682Smarkm	p = skip_next(p);
42055682Smarkm
42155682Smarkm	e.modified = p;
42255682Smarkm	p = skip_next(p);
42355682Smarkm
42455682Smarkm	e.valid_start = p;
42555682Smarkm	p = skip_next(p);
42655682Smarkm
42755682Smarkm	e.valid_end = p;
42855682Smarkm	p = skip_next(p);
42955682Smarkm
43055682Smarkm	e.pw_end = p;
43155682Smarkm	p = skip_next(p);
43255682Smarkm
43355682Smarkm	e.max_life = p;
43455682Smarkm	p = skip_next(p);
43555682Smarkm
43655682Smarkm	e.max_renew = p;
43755682Smarkm	p = skip_next(p);
43855682Smarkm
43955682Smarkm	e.flags = p;
44055682Smarkm	p = skip_next(p);
44155682Smarkm
44290926Snectar	e.generation = p;
44355682Smarkm	p = skip_next(p);
44455682Smarkm
445178825Sdfr	e.extensions = p;
446233294Sstas	skip_next(p);
447178825Sdfr
44855682Smarkm	memset(&ent, 0, sizeof(ent));
449178825Sdfr	ret = krb5_parse_name(context, e.principal, &ent.entry.principal);
45057416Smarkm	if(ret) {
451233294Sstas	    const char *msg = krb5_get_error_message(context, ret);
452233294Sstas	    fprintf(stderr, "%s:%d:%s (%s)\n",
453233294Sstas		    filename, line, msg, e.principal);
454233294Sstas	    krb5_free_error_message(context, msg);
45555682Smarkm	    continue;
45655682Smarkm	}
457233294Sstas
458178825Sdfr	if (parse_keys(&ent.entry, e.key)) {
45957416Smarkm	    fprintf (stderr, "%s:%d:error parsing keys (%s)\n",
46057416Smarkm		     filename, line, e.key);
46157416Smarkm	    hdb_free_entry (context, &ent);
46257416Smarkm	    continue;
46357416Smarkm	}
464233294Sstas
465178825Sdfr	if (parse_event(&ent.entry.created_by, e.created) == -1) {
46657416Smarkm	    fprintf (stderr, "%s:%d:error parsing created event (%s)\n",
46757416Smarkm		     filename, line, e.created);
46857416Smarkm	    hdb_free_entry (context, &ent);
46957416Smarkm	    continue;
47057416Smarkm	}
471178825Sdfr	if (parse_event_alloc (&ent.entry.modified_by, e.modified) == -1) {
47257416Smarkm	    fprintf (stderr, "%s:%d:error parsing event (%s)\n",
47357416Smarkm		     filename, line, e.modified);
47457416Smarkm	    hdb_free_entry (context, &ent);
47557416Smarkm	    continue;
47657416Smarkm	}
477178825Sdfr	if (parse_time_string_alloc (&ent.entry.valid_start, e.valid_start) == -1) {
47857416Smarkm	    fprintf (stderr, "%s:%d:error parsing time (%s)\n",
47957416Smarkm		     filename, line, e.valid_start);
48057416Smarkm	    hdb_free_entry (context, &ent);
48157416Smarkm	    continue;
48257416Smarkm	}
483178825Sdfr	if (parse_time_string_alloc (&ent.entry.valid_end,   e.valid_end) == -1) {
48457416Smarkm	    fprintf (stderr, "%s:%d:error parsing time (%s)\n",
48557416Smarkm		     filename, line, e.valid_end);
48657416Smarkm	    hdb_free_entry (context, &ent);
48757416Smarkm	    continue;
48857416Smarkm	}
489178825Sdfr	if (parse_time_string_alloc (&ent.entry.pw_end,      e.pw_end) == -1) {
49057416Smarkm	    fprintf (stderr, "%s:%d:error parsing time (%s)\n",
49157416Smarkm		     filename, line, e.pw_end);
49257416Smarkm	    hdb_free_entry (context, &ent);
49357416Smarkm	    continue;
49457416Smarkm	}
49557416Smarkm
496178825Sdfr	if (parse_integer_alloc (&ent.entry.max_life,  e.max_life) == -1) {
49757416Smarkm	    fprintf (stderr, "%s:%d:error parsing lifetime (%s)\n",
49857416Smarkm		     filename, line, e.max_life);
49957416Smarkm	    hdb_free_entry (context, &ent);
50057416Smarkm	    continue;
50157416Smarkm
50257416Smarkm	}
503178825Sdfr	if (parse_integer_alloc (&ent.entry.max_renew, e.max_renew) == -1) {
50457416Smarkm	    fprintf (stderr, "%s:%d:error parsing lifetime (%s)\n",
50557416Smarkm		     filename, line, e.max_renew);
50657416Smarkm	    hdb_free_entry (context, &ent);
50757416Smarkm	    continue;
50857416Smarkm	}
50957416Smarkm
510178825Sdfr	if (parse_hdbflags2int (&ent.entry.flags, e.flags) != 1) {
51157416Smarkm	    fprintf (stderr, "%s:%d:error parsing flags (%s)\n",
51257416Smarkm		     filename, line, e.flags);
51357416Smarkm	    hdb_free_entry (context, &ent);
51457416Smarkm	    continue;
51557416Smarkm	}
51690926Snectar
517178825Sdfr	if(parse_generation(e.generation, &ent.entry.generation) == -1) {
51890926Snectar	    fprintf (stderr, "%s:%d:error parsing generation (%s)\n",
51990926Snectar		     filename, line, e.generation);
52090926Snectar	    hdb_free_entry (context, &ent);
52190926Snectar	    continue;
52255682Smarkm	}
52355682Smarkm
524178825Sdfr	if(parse_extensions(e.extensions, &ent.entry.extensions) == -1) {
525178825Sdfr	    fprintf (stderr, "%s:%d:error parsing extension (%s)\n",
526178825Sdfr		     filename, line, e.extensions);
527178825Sdfr	    hdb_free_entry (context, &ent);
528178825Sdfr	    continue;
529178825Sdfr	}
530178825Sdfr
531178825Sdfr	ret = db->hdb_store(context, db, HDB_F_REPLACE, &ent);
53255682Smarkm	hdb_free_entry (context, &ent);
53372445Sassar	if (ret) {
53472445Sassar	    krb5_warn(context, ret, "db_store");
53572445Sassar	    break;
53672445Sassar	}
53755682Smarkm    }
538178825Sdfr    db->hdb_close(context, db);
53955682Smarkm    fclose(f);
54072445Sassar    return ret != 0;
54155682Smarkm}
54255682Smarkm
54372445Sassar
544178825Sdfrextern int local_flag;
54572445Sassar
546178825Sdfrstatic int
547178825Sdfrloadit(int mergep, const char *name, int argc, char **argv)
54872445Sassar{
549178825Sdfr    if(!local_flag) {
550178825Sdfr	krb5_warnx(context, "%s is only available in local (-l) mode", name);
55155682Smarkm	return 0;
55255682Smarkm    }
55372445Sassar
554178825Sdfr    return doit(argv[0], mergep);
55555682Smarkm}
556233294Sstas
55755682Smarkmint
558178825Sdfrload(void *opt, int argc, char **argv)
55955682Smarkm{
560178825Sdfr    return loadit(0, "load", argc, argv);
56155682Smarkm}
562233294Sstas
563178825Sdfrint
564178825Sdfrmerge(void *opt, int argc, char **argv)
565178825Sdfr{
566178825Sdfr    return loadit(1, "merge", argc, argv);
567178825Sdfr}
568