From e9cd245973400b80f4d3d6935d57138b981d5109 Mon Sep 17 00:00:00 2001 From: Tom Yu Date: Sat, 4 Aug 2007 00:05:21 +0000 Subject: [PATCH] back-port r19749 from trunk If mkstemp() is available, the new ccache file gets created but the subsequent open(O_CREAT|O_EXCL) call fails because the file was already created by mkstemp(). Apply patch from Apple to keep the file descriptor open. ticket: 5624 version_fixed: 1.6.3 git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-6@19750 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/ccache/cc_file.c | 95 ++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 46 deletions(-) diff --git a/src/lib/krb5/ccache/cc_file.c b/src/lib/krb5/ccache/cc_file.c index c87fef4e0..250bf70af 100644 --- a/src/lib/krb5/ccache/cc_file.c +++ b/src/lib/krb5/ccache/cc_file.c @@ -1954,6 +1954,9 @@ krb5_fcc_generate_new (krb5_context context, krb5_ccache *id) char scratch[sizeof(TKT_ROOT)+6+1]; /* +6 for the scratch part, +1 for NUL */ krb5_fcc_data *data; + krb5_int16 fcc_fvno = htons(context->fcc_default_format); + krb5_int16 fcc_flen = 0; + int errsave, cnt; /* Allocate memory */ lid = (krb5_ccache) malloc(sizeof(struct _krb5_ccache)); @@ -1968,13 +1971,20 @@ krb5_fcc_generate_new (krb5_context context, krb5_ccache *id) ret = mkstemp(scratch); if (ret == -1) { return krb5_fcc_interpret(context, errno); - } else close(ret); + } #else /*HAVE_MKSTEMP*/ mktemp(scratch); + /* Make sure the file name is reserved */ + ret = THREEPARAMOPEN(scratch, O_CREAT | O_EXCL | O_WRONLY | O_BINARY, 0); + if (ret == -1) { + return krb5_fcc_interpret(context, errno); + } #endif lid->data = (krb5_pointer) malloc(sizeof(krb5_fcc_data)); if (lid->data == NULL) { + close(ret); + unlink(scratch); krb5_xfree(lid); return KRB5_CC_NOMEM; } @@ -1982,6 +1992,8 @@ krb5_fcc_generate_new (krb5_context context, krb5_ccache *id) ((krb5_fcc_data *) lid->data)->filename = (char *) malloc(strlen(scratch) + 1); if (((krb5_fcc_data *) lid->data)->filename == NULL) { + close(ret); + unlink(scratch); krb5_xfree(((krb5_fcc_data *) lid->data)); krb5_xfree(lid); return KRB5_CC_NOMEM; @@ -1996,63 +2008,54 @@ krb5_fcc_generate_new (krb5_context context, krb5_ccache *id) data = (krb5_fcc_data *) lid->data; retcode = k5_mutex_init(&data->lock); - if (retcode) + if (retcode) { + close(ret); + unlink(scratch); goto err_out; + } /* Set up the filename */ strcpy(((krb5_fcc_data *) lid->data)->filename, scratch); - /* Make sure the file name is reserved */ - ret = THREEPARAMOPEN(((krb5_fcc_data *) lid->data)->filename, - O_CREAT | O_EXCL | O_WRONLY | O_BINARY, 0); - if (ret == -1) { - retcode = krb5_fcc_interpret(context, errno); - goto err_out; - } else { - krb5_int16 fcc_fvno = htons(context->fcc_default_format); - krb5_int16 fcc_flen = 0; - int errsave, cnt; - - /* Ignore user's umask, set mode = 0600 */ + /* Ignore user's umask, set mode = 0600 */ #ifndef HAVE_FCHMOD #ifdef HAVE_CHMOD - chmod(((krb5_fcc_data *) lid->data)->filename, S_IRUSR | S_IWUSR); + chmod(((krb5_fcc_data *) lid->data)->filename, S_IRUSR | S_IWUSR); #endif #else - fchmod(ret, S_IRUSR | S_IWUSR); + fchmod(ret, S_IRUSR | S_IWUSR); #endif - if ((cnt = write(ret, (char *)&fcc_fvno, sizeof(fcc_fvno))) - != sizeof(fcc_fvno)) { - errsave = errno; - (void) close(ret); - (void) unlink(((krb5_fcc_data *) lid->data)->filename); - retcode = (cnt == -1) ? krb5_fcc_interpret(context, errsave) : KRB5_CC_IO; - goto err_out; - } - /* For version 4 we save a length for the rest of the header */ - if (context->fcc_default_format == KRB5_FCC_FVNO_4) { - if ((cnt = write(ret, (char *)&fcc_flen, sizeof(fcc_flen))) - != sizeof(fcc_flen)) { - errsave = errno; - (void) close(ret); - (void) unlink(((krb5_fcc_data *) lid->data)->filename); - retcode = (cnt == -1) ? krb5_fcc_interpret(context, errsave) : KRB5_CC_IO; - goto err_out; - } - } - if (close(ret) == -1) { - errsave = errno; - (void) unlink(((krb5_fcc_data *) lid->data)->filename); - retcode = krb5_fcc_interpret(context, errsave); - goto err_out; + if ((cnt = write(ret, (char *)&fcc_fvno, sizeof(fcc_fvno))) + != sizeof(fcc_fvno)) { + errsave = errno; + (void) close(ret); + (void) unlink(((krb5_fcc_data *) lid->data)->filename); + retcode = (cnt == -1) ? krb5_fcc_interpret(context, errsave) : KRB5_CC_IO; + goto err_out; + } + /* For version 4 we save a length for the rest of the header */ + if (context->fcc_default_format == KRB5_FCC_FVNO_4) { + if ((cnt = write(ret, (char *)&fcc_flen, sizeof(fcc_flen))) + != sizeof(fcc_flen)) { + errsave = errno; + (void) close(ret); + (void) unlink(((krb5_fcc_data *) lid->data)->filename); + retcode = (cnt == -1) ? krb5_fcc_interpret(context, errsave) : KRB5_CC_IO; + goto err_out; } - *id = lid; - /* default to open/close on every trn - otherwise destroy - will get as to state confused */ - ((krb5_fcc_data *) lid->data)->flags = KRB5_TC_OPENCLOSE; - krb5_change_cache (); - return KRB5_OK; } + if (close(ret) == -1) { + errsave = errno; + (void) unlink(((krb5_fcc_data *) lid->data)->filename); + retcode = krb5_fcc_interpret(context, errsave); + goto err_out; + } + *id = lid; + /* default to open/close on every trn - otherwise destroy + will get as to state confused */ + ((krb5_fcc_data *) lid->data)->flags = KRB5_TC_OPENCLOSE; + krb5_change_cache (); + return KRB5_OK; err_out: krb5_xfree(((krb5_fcc_data *) lid->data)->filename); -- 2.26.2