diff options
Diffstat (limited to 'crypto/heimdal/lib/krb5/keytab_keyfile.c')
-rw-r--r-- | crypto/heimdal/lib/krb5/keytab_keyfile.c | 83 |
1 files changed, 57 insertions, 26 deletions
diff --git a/crypto/heimdal/lib/krb5/keytab_keyfile.c b/crypto/heimdal/lib/krb5/keytab_keyfile.c index aca930f..77455ba 100644 --- a/crypto/heimdal/lib/krb5/keytab_keyfile.c +++ b/crypto/heimdal/lib/krb5/keytab_keyfile.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keytab_keyfile.c,v 1.15 2002/10/21 15:42:06 joda Exp $"); +RCSID("$Id: keytab_keyfile.c 20695 2007-05-30 14:09:09Z lha $"); /* afs keyfile operations --------------------------------------- */ @@ -63,8 +63,7 @@ struct akf_data { */ static int -get_cell_and_realm (krb5_context context, - struct akf_data *d) +get_cell_and_realm (krb5_context context, struct akf_data *d) { FILE *f; char buf[BUFSIZ], *cp; @@ -94,6 +93,8 @@ get_cell_and_realm (krb5_context context, f = fopen (AFS_SERVERMAGICKRBCONF, "r"); if (f != NULL) { if (fgets (buf, sizeof(buf), f) == NULL) { + free (d->cell); + d->cell = NULL; fclose (f); krb5_set_error_string (context, "no realm in %s", AFS_SERVERMAGICKRBCONF); @@ -104,11 +105,12 @@ get_cell_and_realm (krb5_context context, } /* uppercase */ for (cp = buf; *cp != '\0'; cp++) - *cp = toupper(*cp); + *cp = toupper((unsigned char)*cp); d->realm = strdup (buf); if (d->realm == NULL) { free (d->cell); + d->cell = NULL; krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; } @@ -288,9 +290,16 @@ akf_add_entry(krb5_context context, krb5_storage *sp; - if (entry->keyblock.keyvalue.length != 8 - || entry->keyblock.keytype != ETYPE_DES_CBC_MD5) + if (entry->keyblock.keyvalue.length != 8) return 0; + switch(entry->keyblock.keytype) { + case ETYPE_DES_CBC_CRC: + case ETYPE_DES_CBC_MD4: + case ETYPE_DES_CBC_MD5: + break; + default: + return 0; + } fd = open (d->filename, O_RDWR | O_BINARY); if (fd < 0) { @@ -329,50 +338,72 @@ akf_add_entry(krb5_context context, return ret; } } + + /* + * Make sure we don't add the entry twice, assumes the DES + * encryption types are all the same key. + */ + if (len > 0) { + int32_t kvno; + int i; + + for (i = 0; i < len; i++) { + ret = krb5_ret_int32(sp, &kvno); + if (ret) { + krb5_set_error_string (context, "Failed to get kvno "); + goto out; + } + if(krb5_storage_seek(sp, 8, SEEK_CUR) < 0) { + krb5_set_error_string (context, "seek: %s", strerror(ret)); + goto out; + } + if (kvno == entry->vno) { + ret = 0; + goto out; + } + } + } + len++; if(krb5_storage_seek(sp, 0, SEEK_SET) < 0) { ret = errno; - krb5_storage_free(sp); - close(fd); krb5_set_error_string (context, "seek: %s", strerror(ret)); - return ret; + goto out; } ret = krb5_store_int32(sp, len); if(ret) { - krb5_storage_free(sp); - close(fd); + krb5_set_error_string(context, "keytab keyfile failed new length"); return ret; } - if(krb5_storage_seek(sp, (len - 1) * (8 + 4), SEEK_CUR) < 0) { ret = errno; - krb5_storage_free(sp); - close(fd); - krb5_set_error_string (context, "seek: %s", strerror(ret)); - return ret; + krb5_set_error_string (context, "seek to end: %s", strerror(ret)); + goto out; } ret = krb5_store_int32(sp, entry->vno); if(ret) { - krb5_storage_free(sp); - close(fd); - return ret; + krb5_set_error_string(context, "keytab keyfile failed store kvno"); + goto out; } ret = krb5_storage_write(sp, entry->keyblock.keyvalue.data, entry->keyblock.keyvalue.length); if(ret != entry->keyblock.keyvalue.length) { - krb5_storage_free(sp); - close(fd); - if(ret < 0) - return errno; - return ENOTTY; + if (ret < 0) + ret = errno; + else + ret = ENOTTY; + krb5_set_error_string(context, "keytab keyfile failed to add key"); + goto out; } + ret = 0; +out: krb5_storage_free(sp); close (fd); - return 0; + return ret; } const krb5_kt_ops krb5_akf_ops = { |