Use stdio for keytab operations

Unlike the ccache, we can't lock less because of the way in which keytab
entries are removed: by negating their length.  Also unlike ccaches, we
hold locks across the entirety of keytab iteration.
This commit is contained in:
Nicolas Williams
2017-05-26 14:23:57 -05:00
committed by Viktor Dukhovni
parent 322b166c37
commit 48c137f355

View File

@@ -367,6 +367,7 @@ fkt_start_seq_get_int(krb5_context context,
int8_t pvno, tag; int8_t pvno, tag;
krb5_error_code ret; krb5_error_code ret;
struct fkt_data *d = id->data; struct fkt_data *d = id->data;
const char *stdio_mode = "rb";
c->fd = open (d->filename, flags); c->fd = open (d->filename, flags);
if (c->fd < 0) { if (c->fd < 0) {
@@ -382,9 +383,14 @@ fkt_start_seq_get_int(krb5_context context,
close(c->fd); close(c->fd);
return ret; return ret;
} }
c->sp = krb5_storage_from_fd(c->fd); if ((flags & O_ACCMODE) == O_RDWR && (flags & O_APPEND))
stdio_mode = "ab+";
else if ((flags & O_ACCMODE) == O_RDWR)
stdio_mode = "rb+";
else if ((flags & O_ACCMODE) == O_WRONLY)
stdio_mode = "wb+";
c->sp = krb5_storage_stdio_from_fd(c->fd, stdio_mode);
if (c->sp == NULL) { if (c->sp == NULL) {
_krb5_xunlock(context, c->fd);
close(c->fd); close(c->fd);
return krb5_enomem(context); return krb5_enomem(context);
} }
@@ -392,14 +398,12 @@ fkt_start_seq_get_int(krb5_context context,
ret = krb5_ret_int8(c->sp, &pvno); ret = krb5_ret_int8(c->sp, &pvno);
if(ret) { if(ret) {
krb5_storage_free(c->sp); krb5_storage_free(c->sp);
_krb5_xunlock(context, c->fd);
close(c->fd); close(c->fd);
krb5_clear_error_message(context); krb5_clear_error_message(context);
return ret; return ret;
} }
if(pvno != 5) { if(pvno != 5) {
krb5_storage_free(c->sp); krb5_storage_free(c->sp);
_krb5_xunlock(context, c->fd);
close(c->fd); close(c->fd);
krb5_clear_error_message (context); krb5_clear_error_message (context);
return KRB5_KEYTAB_BADVNO; return KRB5_KEYTAB_BADVNO;
@@ -407,7 +411,6 @@ fkt_start_seq_get_int(krb5_context context,
ret = krb5_ret_int8(c->sp, &tag); ret = krb5_ret_int8(c->sp, &tag);
if (ret) { if (ret) {
krb5_storage_free(c->sp); krb5_storage_free(c->sp);
_krb5_xunlock(context, c->fd);
close(c->fd); close(c->fd);
krb5_clear_error_message(context); krb5_clear_error_message(context);
return ret; return ret;
@@ -507,7 +510,6 @@ fkt_end_seq_get(krb5_context context,
krb5_kt_cursor *cursor) krb5_kt_cursor *cursor)
{ {
krb5_storage_free(cursor->sp); krb5_storage_free(cursor->sp);
_krb5_xunlock(context, cursor->fd);
close(cursor->fd); close(cursor->fd);
return 0; return 0;
} }
@@ -555,7 +557,7 @@ fkt_add_entry(krb5_context context,
close(fd); close(fd);
return ret; return ret;
} }
sp = krb5_storage_from_fd(fd); sp = krb5_storage_stdio_from_fd(fd, "wb+");
krb5_storage_set_eof_code(sp, KRB5_KT_END); krb5_storage_set_eof_code(sp, KRB5_KT_END);
ret = fkt_setup_keytab(context, id, sp); ret = fkt_setup_keytab(context, id, sp);
if(ret) { if(ret) {
@@ -572,7 +574,7 @@ fkt_add_entry(krb5_context context,
close(fd); close(fd);
return ret; return ret;
} }
sp = krb5_storage_from_fd(fd); sp = krb5_storage_stdio_from_fd(fd, "wb+");
krb5_storage_set_eof_code(sp, KRB5_KT_END); krb5_storage_set_eof_code(sp, KRB5_KT_END);
ret = krb5_ret_int8(sp, &pvno); ret = krb5_ret_int8(sp, &pvno);
if(ret) { if(ret) {
@@ -704,8 +706,8 @@ fkt_add_entry(krb5_context context,
memset(keytab.data, 0, keytab.length); memset(keytab.data, 0, keytab.length);
krb5_data_free(&keytab); krb5_data_free(&keytab);
out: out:
krb5_storage_fsync(sp);
krb5_storage_free(sp); krb5_storage_free(sp);
_krb5_xunlock(context, fd);
close(fd); close(fd);
return ret; return ret;
} }