From 582aabf279c16a3a55cc44c958130ada29e46e41 Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Fri, 24 Apr 2009 21:15:04 +0000 Subject: [PATCH] Simplify and shorten krb5_ktfileint_find_slot, and properly handle the commit_point output parameter. ticket: 6475 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@22279 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/keytab/kt_file.c | 139 ++++++++++------------------------ 1 file changed, 40 insertions(+), 99 deletions(-) diff --git a/src/lib/krb5/keytab/kt_file.c b/src/lib/krb5/keytab/kt_file.c index 79728cee0..7fe4dcfc8 100644 --- a/src/lib/krb5/keytab/kt_file.c +++ b/src/lib/krb5/keytab/kt_file.c @@ -1643,123 +1643,64 @@ krb5_ktfileint_size_entry(krb5_context context, krb5_keytab_entry *entry, krb5_i * block in the file rather than the size of the actual entry) */ static krb5_error_code -krb5_ktfileint_find_slot(krb5_context context, krb5_keytab id, krb5_int32 *size_needed, krb5_int32 *commit_point) +krb5_ktfileint_find_slot(krb5_context context, krb5_keytab id, krb5_int32 *size_needed, krb5_int32 *commit_point_ptr) { - krb5_int32 size; - krb5_int32 remainder; - krb5_int32 zero_point; - krb5_kt_vno kt_vno; - krb5_boolean found = FALSE; - char iobuf[BUFSIZ]; + FILE *fp; + krb5_int32 size, zero_point, commit_point; + krb5_kt_vno kt_vno; KTCHECKLOCK(id); - /* - * Skip over file version number - */ - if (fseek(KTFILEP(id), 0, SEEK_SET)) { + fp = KTFILEP(id); + /* Skip over file version number. */ + if (fseek(fp, 0, SEEK_SET)) + return errno; + if (!fread(&kt_vno, sizeof(kt_vno), 1, fp)) return errno; - } - if (!fread(&kt_vno, sizeof(kt_vno), 1, KTFILEP(id))) { - return KRB5_KT_IOERR; - } - while (!found) { - *commit_point = ftell(KTFILEP(id)); - if (!fread(&size, sizeof(size), 1, KTFILEP(id))) { - /* - * Hit the end of file, reserve this slot. - */ + for (;;) { + commit_point = ftell(fp); + if (!fread(&size, sizeof(size), 1, fp)) { + /* Hit the end of file, reserve this slot. */ + /* htonl(0) is 0, so no need to worry about byte order */ size = 0; - - /* fseek to synchronise buffered I/O on the key table. */ - /* XXX Without the weird setbuf hack, can we nuke this now? */ - if (fseek(KTFILEP(id), 0L, SEEK_CUR) < 0) - { + if (!fwrite(&size, sizeof(size), 1, fp)) return errno; - } - -#ifdef notdef - /* We don't have to do this because htonl(0) == 0 */ - if (KTVERSION(id) != KRB5_KT_VNO_1) - size = htonl(size); -#endif - - if (!fwrite(&size, sizeof(size), 1, KTFILEP(id))) { - return KRB5_KT_IOERR; - } - found = TRUE; + break; } if (KTVERSION(id) != KRB5_KT_VNO_1) - size = ntohl(size); + size = ntohl(size); if (size > 0) { - if (fseek(KTFILEP(id), size, SEEK_CUR)) { + /* Non-empty record; seek past it. */ + if (fseek(fp, size, SEEK_CUR)) return errno; - } - } else if (!found) { - size = -size; + } else if (size < 0) { + /* Empty record; use if it's big enough, seek past otherwise. */ + size = -size; if (size >= *size_needed) { *size_needed = size; - found = TRUE; - } else if (size > 0) { - /* - * The current hole is not large enough, so skip it - */ - if (fseek(KTFILEP(id), size, SEEK_CUR)) { - return errno; - } - } else { - - /* fseek to synchronise buffered I/O on the key table. */ - - if (fseek(KTFILEP(id), 0L, SEEK_CUR) < 0) - { - return errno; - } - - /* - * Found the end of the file (marked by a 0 length buffer) - * Make sure we zero any trailing data. - */ - zero_point = ftell(KTFILEP(id)); - if (zero_point < 0) { - return errno; - } - while ((size = fread(iobuf, 1, sizeof(iobuf), KTFILEP(id)))) { - if (size != sizeof(iobuf)) { - remainder = size % sizeof(krb5_int32); - if (remainder) { - size += sizeof(krb5_int32) - remainder; - } - } - - if (fseek(KTFILEP(id), 0L, SEEK_CUR) < 0) - { - return errno; - } - - memset(iobuf, 0, (size_t) size); - fwrite(iobuf, 1, (size_t) size, KTFILEP(id)); - fflush(KTFILEP(id)); - if (feof(KTFILEP(id))) { - break; - } - - if (fseek(KTFILEP(id), 0L, SEEK_CUR) < 0) - { - return errno; - } - - } - if (fseek(KTFILEP(id), zero_point, SEEK_SET)) { + break; + } else { + if (fseek(fp, size, SEEK_CUR)) return errno; - } - found = TRUE; - } - } + } + } else { + /* Empty record at end of file; use it. */ + /* Ensure the new record will be followed by another 0. */ + zero_point = ftell(fp); + if (fseek(fp, *size_needed, SEEK_CUR)) + return errno; + /* htonl(0) is 0, so no need to worry about byte order */ + if (!fwrite(&size, sizeof(size), 1, fp)) + return errno; + if (fseek(fp, zero_point, SEEK_SET)) + return errno; + break; + } } + *commit_point_ptr = commit_point; return 0; } #endif /* LEAN_CLIENT */ -- 2.26.2