diff --git a/kadmin/load.c b/kadmin/load.c index b69a8099b..c21e2189d 100644 --- a/kadmin/load.c +++ b/kadmin/load.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -36,7 +36,7 @@ RCSID("$Id$"); -struct entry{ +struct entry { char *principal; char *key; char *max_life; @@ -56,52 +56,108 @@ skip_next(char *p) while(*p && !isspace((unsigned char)*p)) p++; *p++ = 0; - while(*p && isspace((unsigned char)*p)) p++; + while(*p && isspace((unsigned char)*p)) + p++; return p; } -static time_t* -parse_time_string(time_t *t, char *s) +/* + * Parse the time in `s', returning: + * -1 if error parsing + * 0 if none present + * 1 if parsed ok + */ + +static int +parse_time_string(time_t *t, const char *s) { int year, month, date, hour, minute, second; struct tm tm; + if(strcmp(s, "-") == 0) - return NULL; - if(t == NULL) - t = malloc(sizeof(*t)); - sscanf(s, "%04d%02d%02d%02d%02d%02d", - &year, &month, &date, &hour, &minute, &second); - tm.tm_year = year - 1900; - tm.tm_mon = month - 1; - tm.tm_mday = date; - tm.tm_hour = hour; - tm.tm_min = minute; - tm.tm_sec = second; + return 0; + if(sscanf(s, "%04d%02d%02d%02d%02d%02d", + &year, &month, &date, &hour, &minute, &second) != 6) + return -1; + tm.tm_year = year - 1900; + tm.tm_mon = month - 1; + tm.tm_mday = date; + tm.tm_hour = hour; + tm.tm_min = minute; + tm.tm_sec = second; tm.tm_isdst = 0; *t = timegm(&tm); - return t; + return 1; } -static unsigned* -parse_integer(unsigned *u, char *s) +/* + * parse time, allocating space in *t if it's there + */ + +static int +parse_time_string_alloc (time_t **t, const char *s) +{ + time_t tmp; + int ret; + + *t = NULL; + ret = parse_time_string (&tmp, s); + if (ret == 1) { + *t = malloc (sizeof (**t)); + if (*t == NULL) + krb5_errx (context, 1, "malloc: out of memory"); + **t = tmp; + } + return ret; +} + +/* + * see parse_time_string for calling convention + */ + +static int +parse_integer(unsigned *u, const char *s) { if(strcmp(s, "-") == 0) - return NULL; - if(u == NULL) - u = malloc(sizeof(*u)); - sscanf(s, "%u", u); - return u; + return 0; + if (sscanf(s, "%u", u) != 1) + return -1; + return 1; } -static void +static int +parse_integer_alloc (int **u, const char *s) +{ + unsigned tmp; + int ret; + + *u = NULL; + ret = parse_integer (&tmp, s); + if (ret == 1) { + *u = malloc (sizeof (**u)); + if (*u == NULL) + krb5_errx (context, 1, "malloc: out of memory"); + **u = tmp; + } + return ret; +} + +/* + * Parse dumped keys in `str' and store them in `ent' + * return -1 if parsing failed + */ + +static int parse_keys(hdb_entry *ent, char *str) { + krb5_error_code ret; int tmp; char *p; int i; p = strsep(&str, ":"); - sscanf(p, "%d", &tmp); + if (sscanf(p, "%d", &tmp) != 1) + return 1; ent->kvno = tmp; p = strsep(&str, ":"); while(p){ @@ -109,7 +165,7 @@ parse_keys(hdb_entry *ent, char *str) key = realloc(ent->keys.val, (ent->keys.len + 1) * sizeof(*ent->keys.val)); if(key == NULL) - abort(); + krb5_errx (context, 1, "realloc: out of memory"); ent->keys.val = key; key = ent->keys.val + ent->keys.len; ent->keys.len++; @@ -120,37 +176,49 @@ parse_keys(hdb_entry *ent, char *str) } else key->mkvno = NULL; p = strsep(&str, ":"); - sscanf(p, "%d", &tmp); + if (sscanf(p, "%d", &tmp) != 1) + return 1; key->key.keytype = tmp; p = strsep(&str, ":"); - krb5_data_alloc(&key->key.keyvalue, (strlen(p) - 1) / 2 + 1); - for(i = 0; i < strlen(p); i += 2){ - sscanf(p + i, "%02x", &tmp); + ret = krb5_data_alloc(&key->key.keyvalue, (strlen(p) - 1) / 2 + 1); + if (ret) + krb5_err (context, 1, ret, "krb5_data_alloc"); + for(i = 0; i < strlen(p); i += 2) { + if(sscanf(p + i, "%02x", &tmp) != 1) + return 1; ((u_char*)key->key.keyvalue.data)[i / 2] = tmp; } p = strsep(&str, ":"); if(strcmp(p, "-") != 0){ unsigned type; size_t p_len; - if(sscanf(p, "%u/", &type) != 1){ - abort (); - } + + if(sscanf(p, "%u/", &type) != 1) + return 1; p = strchr(p, '/'); if(p == NULL) - abort (); + return 1; p++; p_len = strlen(p); key->salt = malloc(sizeof(*key->salt)); + if (key->salt == NULL) + krb5_errx (context, 1, "malloc: out of memory"); key->salt->type = type; if (p_len) { - if(*p == '\"'){ - krb5_data_copy(&key->salt->salt, p + 1, p_len - 2); - }else{ - krb5_data_alloc(&key->salt->salt, (p_len - 1) / 2 + 1); + if(*p == '\"') { + ret = krb5_data_copy(&key->salt->salt, p + 1, p_len - 2); + if (ret) + krb5_err (context, 1, ret, "krb5_data_copy"); + } else { + ret = krb5_data_alloc(&key->salt->salt, + (p_len - 1) / 2 + 1); + if (ret) + krb5_err (context, 1, ret, "krb5_data_alloc"); for(i = 0; i < p_len; i += 2){ - sscanf(p + i, "%02x", &tmp); + if (sscanf(p + i, "%02x", &tmp) != 1) + return 1; ((u_char*)key->salt->salt.data)[i / 2] = tmp; } } @@ -159,31 +227,59 @@ parse_keys(hdb_entry *ent, char *str) } p = strsep(&str, ":"); } + return 0; } -static Event* -parse_event(Event *ev, char *str) +/* + * see parse_time_string for calling convention + */ + +static int +parse_event(Event *ev, char *s) { + krb5_error_code ret; char *p; - if(strcmp(str, "-") == 0) - return NULL; - if(ev == NULL) - ev = malloc(sizeof(*ev)); + + if(strcmp(s, "-") == 0) + return 0; memset(ev, 0, sizeof(*ev)); - p = strsep(&str, ":"); - parse_time_string(&ev->time, p); - p = strsep(&str, ":"); - krb5_parse_name(context, p, &ev->principal); - return ev; + p = strsep(&s, ":"); + if(parse_time_string(&ev->time, p) != 1) + return -1; + p = strsep(&s, ":"); + ret = krb5_parse_name(context, p, &ev->principal); + if (ret) + return -1; + return 1; } -static HDBFlags -parse_hdbflags2int(char *str) +static int +parse_event_alloc (Event **ev, char *s) { - unsigned i; - parse_integer(&i, str); + Event tmp; + int ret; - return int2HDBFlags(i); + *ev = NULL; + ret = parse_event (&tmp, s); + if (ret == 1) { + *ev = malloc (sizeof (**ev)); + if (*ev == NULL) + krb5_errx (context, 1, "malloc: out of memory"); + **ev = tmp; + } + return ret; +} + +static int +parse_hdbflags2int(HDBFlags *f, const char *s) +{ + int ret; + unsigned tmp; + + ret = parse_integer (&tmp, s); + if (ret == 1) + *f = int2HDBFlags (tmp); + return ret; } #if 0 @@ -205,8 +301,13 @@ parse_etypes(char *str, unsigned **val, unsigned *len) } #endif -static void -doit(char *filename, int merge) +/* + * Parse the dump file in `filename' and create the database (merging + * iff merge) + */ + +static int +doit(const char *filename, int merge) { krb5_error_code ret; FILE *f; @@ -221,7 +322,7 @@ doit(char *filename, int merge) f = fopen(filename, "r"); if(f == NULL){ krb5_warn(context, errno, "fopen(%s)", filename); - return; + return 1; } if(!merge) flags |= O_CREAT | O_TRUNC; @@ -229,7 +330,7 @@ doit(char *filename, int merge) if(ret){ krb5_warn(context, ret, "hdb_open"); fclose(f); - return; + return 1; } line = 0; while(fgets(s, sizeof(s), f)){ @@ -277,7 +378,7 @@ doit(char *filename, int merge) memset(&ent, 0, sizeof(ent)); ret = krb5_parse_name(context, e.principal, &ent.principal); - if(ret){ + if(ret) { fprintf(stderr, "%s:%d:%s (%s)\n", filename, line, @@ -286,16 +387,64 @@ doit(char *filename, int merge) continue; } - parse_keys(&ent, e.key); + if (parse_keys(&ent, e.key)) { + fprintf (stderr, "%s:%d:error parsing keys (%s)\n", + filename, line, e.key); + hdb_free_entry (context, &ent); + continue; + } - parse_event(&ent.created_by, e.created); - ent.modified_by = parse_event(NULL, e.modified); - ent.valid_start = parse_time_string(NULL, e.valid_start); - ent.valid_end = parse_time_string(NULL, e.valid_end); - ent.pw_end = parse_time_string(NULL, e.pw_end); - ent.max_life = parse_integer(NULL, e.max_life); - ent.max_renew = parse_integer(NULL, e.max_renew); - ent.flags = parse_hdbflags2int(e.flags); + if (parse_event(&ent.created_by, e.created) == -1) { + fprintf (stderr, "%s:%d:error parsing created event (%s)\n", + filename, line, e.created); + hdb_free_entry (context, &ent); + continue; + } + if (parse_event_alloc (&ent.modified_by, e.modified) == -1) { + fprintf (stderr, "%s:%d:error parsing event (%s)\n", + filename, line, e.modified); + hdb_free_entry (context, &ent); + continue; + } + if (parse_time_string_alloc (&ent.valid_start, e.valid_start) == -1) { + fprintf (stderr, "%s:%d:error parsing time (%s)\n", + filename, line, e.valid_start); + hdb_free_entry (context, &ent); + continue; + } + if (parse_time_string_alloc (&ent.valid_end, e.valid_end) == -1) { + fprintf (stderr, "%s:%d:error parsing time (%s)\n", + filename, line, e.valid_end); + hdb_free_entry (context, &ent); + continue; + } + if (parse_time_string_alloc (&ent.pw_end, e.pw_end) == -1) { + fprintf (stderr, "%s:%d:error parsing time (%s)\n", + filename, line, e.pw_end); + hdb_free_entry (context, &ent); + continue; + } + + if (parse_integer_alloc (&ent.max_life, e.max_life) == -1) { + fprintf (stderr, "%s:%d:error parsing lifetime (%s)\n", + filename, line, e.max_life); + hdb_free_entry (context, &ent); + continue; + + } + if (parse_integer_alloc (&ent.max_renew, e.max_renew) == -1) { + fprintf (stderr, "%s:%d:error parsing lifetime (%s)\n", + filename, line, e.max_renew); + hdb_free_entry (context, &ent); + continue; + } + + if (parse_hdbflags2int (&ent.flags, e.flags) != 0) { + fprintf (stderr, "%s:%d:error parsing flags (%s)\n", + filename, line, e.flags); + hdb_free_entry (context, &ent); + continue; + } #if 0 ALLOC(ent.etypes); parse_etypes(e.etypes, &ent.etypes->val, &ent.etypes->len); @@ -310,6 +459,7 @@ doit(char *filename, int merge) } db->close(context, db); fclose(f); + return 0; } int