diff --git a/lib/hdb/print.c b/lib/hdb/print.c index a56fcf48c..559c83929 100644 --- a/lib/hdb/print.c +++ b/lib/hdb/print.c @@ -55,37 +55,42 @@ RCSID("$Id$"); max ticket life max renewable life flags + generation number */ -static void -append_hex(char *str, krb5_data *data) +static krb5_error_code +append_string(krb5_storage *sp, const char *fmt, ...) { - int i, s = 1; + krb5_error_code ret; + char *s; + va_list ap; + va_start(ap, fmt); + vasprintf(&s, fmt, ap); + va_end(ap); + if(s == NULL) + return ENOMEM; + ret = sp->store(sp, s, strlen(s)); + free(s); + return ret; +} + +static krb5_error_code +append_hex(krb5_storage *sp, krb5_data *data) +{ + int i, printable = 1; char *p; p = data->data; for(i = 0; i < data->length; i++) if(!isalnum((unsigned char)p[i]) && p[i] != '.'){ - s = 0; + printable = 0; break; } - if(s){ - p = calloc(1, data->length + 2 + 1); - p[0] = '\"'; - p[data->length + 1] = '\"'; - memcpy(p + 1, data->data, data->length); - }else{ - const char *xchars = "0123456789abcdef"; - char *q = p = malloc(data->length * 2 + 1); - for(i = 0; i < data->length; i++) { - unsigned char c = ((u_char*)data->data)[i]; - *q++ = xchars[(c & 0xf0) >> 4]; - *q++ = xchars[(c & 0xf)]; - } - *q = '\0'; - } - strcat(str, p); - free(p); + if(printable) + return append_string(sp, "\"%.*s\"", data->length, data->data); + for(i = 0; i < data->length; i++) + append_string(sp, "%02x", ((unsigned char*)data->data)[i]); + return 0; } static char * @@ -97,38 +102,26 @@ time2str(time_t t) } static krb5_error_code -event2string(krb5_context context, Event *ev, char **str) +append_event(krb5_context context, krb5_storage *sp, Event *ev) { - char *p; - char *pr; + char *pr = NULL; krb5_error_code ret; - if(ev == NULL){ - *str = strdup("-"); - return (*str == NULL) ? ENOMEM : 0; - } - if (ev->principal == NULL) { - pr = strdup("UNKNOWN"); - if (pr == NULL) - return ENOMEM; - } else { + if(ev == NULL) + return append_string(sp, "- "); + if (ev->principal != NULL) { ret = krb5_unparse_name(context, ev->principal, &pr); if(ret) return ret; } - ret = asprintf(&p, "%s:%s", time2str(ev->time), pr); + ret = append_string(sp, "%s:%s ", time2str(ev->time), pr ? pr : "UNKNOWN"); free(pr); - if(ret < 0) - return ENOMEM; - *str = p; - return 0; + return ret; } -krb5_error_code -hdb_entry2string(krb5_context context, hdb_entry *ent, char **str) +static krb5_error_code +entry2string_int (krb5_context context, krb5_storage *sp, hdb_entry *ent) { char *p; - char buf[1024] = ""; - char tmp[32]; int i; krb5_error_code ret; @@ -136,90 +129,101 @@ hdb_entry2string(krb5_context context, hdb_entry *ent, char **str) ret = krb5_unparse_name(context, ent->principal, &p); if(ret) return ret; - strlcat(buf, p, sizeof(buf)); - strlcat(buf, " ", sizeof(buf)); + append_string(sp, "%s ", p); free(p); /* --- kvno */ - snprintf(tmp, sizeof(tmp), "%d", ent->kvno); - strlcat(buf, tmp, sizeof(buf)); + append_string(sp, "%d", ent->kvno); /* --- keys */ for(i = 0; i < ent->keys.len; i++){ /* --- mkvno, keytype */ if(ent->keys.val[i].mkvno) - snprintf(tmp, sizeof(tmp), ":%d:%d:", - *ent->keys.val[i].mkvno, - ent->keys.val[i].key.keytype); + append_string(sp, ":%d:%d:", + *ent->keys.val[i].mkvno, + ent->keys.val[i].key.keytype); else - snprintf(tmp, sizeof(tmp), "::%d:", - ent->keys.val[i].key.keytype); - strlcat(buf, tmp, sizeof(buf)); + append_string(sp, "::%d:", + ent->keys.val[i].key.keytype); /* --- keydata */ - append_hex(buf, &ent->keys.val[i].key.keyvalue); - strlcat(buf, ":", sizeof(buf)); + append_hex(sp, &ent->keys.val[i].key.keyvalue); + append_string(sp, ":"); /* --- salt */ if(ent->keys.val[i].salt){ - snprintf(tmp, sizeof(tmp), "%u/", ent->keys.val[i].salt->type); - strlcat(buf, tmp, sizeof(buf)); - append_hex(buf, &ent->keys.val[i].salt->salt); + append_string(sp, "%u/", ent->keys.val[i].salt->type); + append_hex(sp, &ent->keys.val[i].salt->salt); }else - strlcat(buf, "-", sizeof(buf)); + append_string(sp, "-"); } - strlcat(buf, " ", sizeof(buf)); + append_string(sp, " "); /* --- created by */ - event2string(context, &ent->created_by, &p); - strlcat(buf, p, sizeof(buf)); - strlcat(buf, " ", sizeof(buf)); - free(p); + append_event(context, sp, &ent->created_by); /* --- modified by */ - event2string(context, ent->modified_by, &p); - strlcat(buf, p, sizeof(buf)); - strlcat(buf, " ", sizeof(buf)); - free(p); + append_event(context, sp, ent->modified_by); /* --- valid start */ if(ent->valid_start) - strlcat(buf, time2str(*ent->valid_start), sizeof(buf)); + append_string(sp, "%s ", time2str(*ent->valid_start)); else - strlcat(buf, "-", sizeof(buf)); - strlcat(buf, " ", sizeof(buf)); + append_string(sp, "- "); /* --- valid end */ if(ent->valid_end) - strlcat(buf, time2str(*ent->valid_end), sizeof(buf)); + append_string(sp, "%s ", time2str(*ent->valid_end)); else - strlcat(buf, "-", sizeof(buf)); - strlcat(buf, " ", sizeof(buf)); + append_string(sp, "- "); /* --- password ends */ if(ent->pw_end) - strlcat(buf, time2str(*ent->pw_end), sizeof(buf)); + append_string(sp, "%s ", time2str(*ent->pw_end)); else - strlcat(buf, "-", sizeof(buf)); - strlcat(buf, " ", sizeof(buf)); + append_string(sp, "- "); /* --- max life */ - if(ent->max_life){ - snprintf(tmp, sizeof(tmp), "%d", *ent->max_life); - strlcat(buf, tmp, sizeof(buf)); - }else - strlcat(buf, "-", sizeof(buf)); - strlcat(buf, " ", sizeof(buf)); + if(ent->max_life) + append_string(sp, "%d ", *ent->max_life); + else + append_string(sp, "- "); /* --- max renewable life */ - if(ent->max_renew){ - snprintf(tmp, sizeof(tmp), "%d", *ent->max_renew); - strlcat(buf, tmp, sizeof(buf)); - }else - strlcat(buf, "-", sizeof(buf)); + if(ent->max_renew) + append_string(sp, "%d ", *ent->max_renew); + else + append_string(sp, "- "); - strlcat(buf, " ", sizeof(buf)); - /* --- flags */ - snprintf(tmp, sizeof(tmp), "%d", HDBFlags2int(ent->flags)); - strlcat(buf, tmp, sizeof(buf)); + append_string(sp, "%d ", HDBFlags2int(ent->flags)); + + /* --- generation number */ + if(ent->generation) { + append_string(sp, "%s:%d:%d", time2str(ent->generation->time), + ent->generation->usec, + ent->generation->gen); + } else + append_string(sp, "-"); - *str = strdup(buf); + return 0; +} + +krb5_error_code +hdb_entry2string (krb5_context context, hdb_entry *ent, char **str) +{ + krb5_error_code ret; + krb5_data data; + krb5_storage *sp; + + sp = krb5_storage_emem(); + if(sp == NULL) + return ENOMEM; + ret = entry2string_int(context, sp, ent); + if(ret) { + krb5_storage_free(sp); + return ret; + } + + sp->store(sp, "\0", 1); + krb5_storage_to_data(sp, &data); + krb5_storage_free(sp); + *str = data.data; return 0; } @@ -228,9 +232,23 @@ hdb_entry2string(krb5_context context, hdb_entry *ent, char **str) krb5_error_code hdb_print_entry(krb5_context context, HDB *db, hdb_entry *entry, void *data) { - char *p; - hdb_entry2string(context, entry, &p); - fprintf((FILE*)data, "%s\n", p); - free(p); + krb5_error_code ret; + krb5_storage *sp; + + FILE *f = data; + + fflush(f); + sp = krb5_storage_from_fd(fileno(f)); + if(sp == NULL) + return ENOMEM; + + ret = entry2string_int(context, sp, entry); + if(ret) { + krb5_storage_free(sp); + return ret; + } + + sp->store(sp, "\n", 1); + krb5_storage_free(sp); return 0; }