From 9662104cb3a41811a90d8a143e44b094e04d4d78 Mon Sep 17 00:00:00 2001 From: John Kohl Date: Thu, 26 Apr 1990 17:21:48 +0000 Subject: [PATCH] fix comments; write implementation (needs some cleanup work, though) git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@598 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/keytab/file/ktf_util.c | 184 +++++++++++++++++++++++++++- 1 file changed, 180 insertions(+), 4 deletions(-) diff --git a/src/lib/krb5/keytab/file/ktf_util.c b/src/lib/krb5/keytab/file/ktf_util.c index 878a51292..2207d8bc5 100644 --- a/src/lib/krb5/keytab/file/ktf_util.c +++ b/src/lib/krb5/keytab/file/ktf_util.c @@ -21,16 +21,17 @@ * * There are no separators between fields of an entry or between entries. * A principal is a length-encoded array of length-encoded strings. The - * length is a krb5_length XXX in each case. The specific format, then, is + * length is a krb5_int16 in each case. The specific format, then, is * multiple entries concatinated with no separators. An entry has this * exact format: * - * sizeof(krb5_length) bytes for number of components in the principal; + * sizeof(krb5_int16) bytes for number of components in the principal; * then, each component listed in ordser. - * For each component, sizeof(krb5_length) bytes for the number of bytes + * For each component, sizeof(krb5_int16) bytes for the number of bytes * in the component, followed by the component. * sizeof(krb5_kvno) bytes for the key version number - * sizeof(krb5_key_block) bytes for the key + * sizeof(krb5_keytype) bytes for the keytype + * sizeof(krb5_int32) bytes for the key length, followed by the key * * Extra garbage at the end of a keytab will be not be searched for, but * @@ -44,6 +45,181 @@ static char rcsid_ktf_util_c[] = #include #include +#include +#include +#include +#include +#include +#include #include "ktfile.h" +extern int errno; + +static krb5_error_code +krb5_ktfileint_open(id, mode) +krb5_keytab id; +int mode; +{ + krb5_error_code kerror; + + if (!(KTFILEP(id) = fopen(KTFILENAME(id), + (mode == KRB5_LOCKMODE_EXCLUSIVE) ? "w" : "r"))) + return errno; + if (kerror = krb5_lock_file(KTFILEP(id), KTFILENAME(id), + mode)) { + (void) fclose(KTFILEP(id)); + KTFILEP(id) = 0; + return kerror; + } + /* assume ANSI or BSD-style stdio */ + setbuf(KTFILEP(id), NULL); + return 0; +} + +krb5_error_code +krb5_ktfileint_openr(id) +krb5_keytab id; +{ + return krb5_ktfileint_open(id, KRB5_LOCKMODE_SHARED); +} + +krb5_error_code +krb5_ktfileint_openw(id) +krb5_keytab id; +{ + return krb5_ktfileint_open(id, KRB5_LOCKMODE_EXCLUSIVE); +} + +krb5_error_code +krb5_ktfileint_close(id) +krb5_keytab id; +{ + krb5_error_code kerror; + + if (!KTFILEP(id)) + return 0; /* XXX? ordering */ + kerror = krb5_unlock_file(KTFILEP(id), KTFILENAME(id)); + (void) fclose(KTFILEP(id)); + KTFILEP(id) = 0; + return kerror; +} + +krb5_error_code +krb5_ktfileint_read_entry(id, entrypp) +krb5_keytab id; +krb5_keytab_entry **entrypp; +{ + register krb5_keytab_entry *ret_entry; + krb5_int16 count; + krb5_int16 princ_size; + register int i; + + if (!(ret_entry = (krb5_keytab_entry *)calloc(1, sizeof(*ret_entry)))) + return ENOMEM; + +#define xfread(a, b, c, d) fread((char *)a, b, c, d) + + /* deal with guts of parsing... */ + + /* first, int16 with #princ components */ + if (!xfread(&count, sizeof(count), 1, KTFILEP(id))) + return KRB5_KT_END; + if (!count || (count < 0)) + return KRB5_KT_END; /* XXX */ + if (!(ret_entry->principal = (krb5_data **)calloc(count, sizeof(krb5_data *)))) + return ENOMEM; + for (i = 0; i < count; i++) { + if (!xfread(&princ_size, sizeof(princ_size), 1, KTFILEP(id))) + return KRB5_KT_END; + if (!princ_size || (princ_size < 0)) + return KRB5_KT_END; /* XXX */ + + if (!(ret_entry->principal[i] = (krb5_data *)malloc(sizeof(krb5_data)))) + return ENOMEM; + ret_entry->principal[i]->length = princ_size; + ret_entry->principal[i]->data = malloc(princ_size); + if (!ret_entry->principal[i]->data) + return ENOMEM; + if (!xfread(ret_entry->principal[i]->data, sizeof(char), princ_size, + KTFILEP(id))) + return KRB5_KT_END; + } + if (!xfread(&ret_entry->vno, sizeof(ret_entry->vno), 1, KTFILEP(id))) + return KRB5_KT_END; + /* key type */ + if (!xfread(&ret_entry->key.keytype, sizeof(ret_entry->key.keytype), 1, + KTFILEP(id))) + return KRB5_KT_END; + /* key contents */ + if (!xfread(&count, sizeof(count), 1, KTFILEP(id))) + return KRB5_KT_END; + if (!count || (count < 0)) + return KRB5_KT_END; /* XXX */ + ret_entry->key.length = count; + if (!(ret_entry->key.contents = (krb5_octet *)malloc(count))) + return ENOMEM; + if (!xfread(ret_entry->key.contents, sizeof(krb5_octet), count, + KTFILEP(id))) + return KRB5_KT_END; + +#undef xfread + + *entrypp = ret_entry; + return 0; +} + +krb5_error_code +krb5_ktfileint_write_entry(id, entry) +krb5_keytab id; +krb5_keytab_entry *entry; +{ + krb5_data **princp; + krb5_int16 count, size; + krb5_error_code retval = 0; + char iobuf[BUFSIZ]; + + setbuf(KTFILEP(id), iobuf); + +#define xfwrite(a, b, c, d) fwrite((char *)a, b, c, d) + /* count up principal components */ + for (count = 0, princp = entry->principal; *princp; princp++, count++); + + if (!xfwrite(&count, sizeof(count), 1, KTFILEP(id))) { + abend: + setbuf(KTFILEP(id), 0); + return KRB5_KT_IOERR; + } + + for (princp = entry->principal; *princp; princp++) { + size = (*princp)->length; + if (!xfwrite(&size, sizeof(size), 1, KTFILEP(id))) { + goto abend; + } + if (!xfwrite((*princp)->data, sizeof(char *), size, KTFILEP(id))) { + goto abend; + } + } + if (!xfwrite(&entry->vno, sizeof(entry->vno), 1, KTFILEP(id))) { + goto abend; + } + if (!xfwrite(&entry->key.keytype, sizeof(entry->key.keytype), 1, + KTFILEP(id))) { + goto abend; + } + size = entry->key.length; + if (!xfwrite(&size, sizeof(size), 1, KTFILEP(id))) { + goto abend; + } + if (!xfwrite(entry->key.contents, sizeof(krb5_octet), size, KTFILEP(id))) { + bzero(iobuf, sizeof(iobuf)); + setbuf(KTFILEP(id), 0); + return KRB5_KT_IOERR; + } + if (fflush(KTFILEP(id)) == EOF) + retval = errno; + + bzero(iobuf, sizeof(iobuf)); + setbuf(KTFILEP(id), 0); + return retval; +} -- 2.26.2