diff options
Diffstat (limited to 'source4/heimdal/lib/krb5/fcache.c')
-rw-r--r-- | source4/heimdal/lib/krb5/fcache.c | 216 |
1 files changed, 126 insertions, 90 deletions
diff --git a/source4/heimdal/lib/krb5/fcache.c b/source4/heimdal/lib/krb5/fcache.c index fc11893452..b745c67e11 100644 --- a/source4/heimdal/lib/krb5/fcache.c +++ b/source4/heimdal/lib/krb5/fcache.c @@ -1,34 +1,34 @@ /* - * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ #include "krb5_locl.h" @@ -90,14 +90,17 @@ _krb5_xlock(krb5_context context, int fd, krb5_boolean exclusive, case 0: break; case EINVAL: /* filesystem doesn't support locking, let the user have it */ - ret = 0; + ret = 0; break; case EAGAIN: - krb5_set_error_message(context, ret, "timed out locking cache file %s", + krb5_set_error_message(context, ret, + N_("timed out locking cache file %s", "file"), filename); break; default: - krb5_set_error_message(context, ret, "error locking cache file %s: %s", + krb5_set_error_message(context, ret, + N_("error locking cache file %s: %s", + "file, error"), filename, strerror(ret)); break; } @@ -124,11 +127,11 @@ _krb5_xunlock(krb5_context context, int fd) case 0: break; case EINVAL: /* filesystem doesn't support locking, let the user have it */ - ret = 0; + ret = 0; break; default: krb5_set_error_message(context, ret, - "Failed to unlock file: %s", + N_("Failed to unlock file: %s", ""), strerror(ret)); break; } @@ -144,7 +147,7 @@ write_storage(krb5_context context, krb5_storage *sp, int fd) ret = krb5_storage_to_data(sp, &data); if (ret) { - krb5_set_error_message(context, ret, "malloc: out of memory"); + krb5_set_error_message(context, ret, N_("malloc: out of memory", "")); return ret; } sret = write(fd, data.data, data.length); @@ -153,7 +156,7 @@ write_storage(krb5_context context, krb5_storage *sp, int fd) if (ret) { ret = errno; krb5_set_error_message(context, ret, - "Failed to write FILE credential data"); + N_("Failed to write FILE credential data", "")); return ret; } return 0; @@ -180,14 +183,14 @@ fcc_resolve(krb5_context context, krb5_ccache *id, const char *res) f = malloc(sizeof(*f)); if(f == NULL) { krb5_set_error_message(context, KRB5_CC_NOMEM, - "malloc: out of memory"); + N_("malloc: out of memory", "")); return KRB5_CC_NOMEM; } f->filename = strdup(res); if(f->filename == NULL){ free(f); krb5_set_error_message(context, KRB5_CC_NOMEM, - "malloc: out of memory"); + N_("malloc: out of memory", "")); return KRB5_CC_NOMEM; } f->version = 0; @@ -303,20 +306,20 @@ fcc_gen_new(krb5_context context, krb5_ccache *id) f = malloc(sizeof(*f)); if(f == NULL) { krb5_set_error_message(context, KRB5_CC_NOMEM, - "malloc: out of memory"); + N_("malloc: out of memory", "")); return KRB5_CC_NOMEM; } asprintf (&file, "%sXXXXXX", KRB5_DEFAULT_CCFILE_ROOT); if(file == NULL) { free(f); krb5_set_error_message(context, KRB5_CC_NOMEM, - "malloc: out of memory"); + N_("malloc: out of memory", "")); return KRB5_CC_NOMEM; } fd = mkstemp(file); if(fd < 0) { int ret = errno; - krb5_set_error_message(context, ret, "mkstemp %s", file); + krb5_set_error_message(context, ret, N_("mkstemp %s failed", ""), file); free(f); free(file); return ret; @@ -348,7 +351,7 @@ storage_set_flags(krb5_context context, krb5_storage *sp, int vno) case KRB5_FCC_FVNO_4: break; default: - krb5_abortx(context, + krb5_abortx(context, "storage_set_flags called with bad vno (%x)", vno); } krb5_storage_set_flags(sp, flags); @@ -369,12 +372,12 @@ fcc_open(krb5_context context, fd = open(filename, flags, mode); if(fd < 0) { ret = errno; - krb5_set_error_message(context, ret, "open(%s): %s", filename, - strerror(ret)); + krb5_set_error_message(context, ret, N_("open(%s): %s", "file, error"), + filename, strerror(ret)); return ret; } rk_cloexec(fd); - + if((ret = fcc_lock(context, id, fd, exclusive)) != 0) { close(fd); return ret; @@ -394,12 +397,12 @@ fcc_initialize(krb5_context context, char *filename = f->filename; unlink (filename); - + ret = fcc_open(context, id, &fd, O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC, 0600); if(ret) return ret; { - krb5_storage *sp; + krb5_storage *sp; sp = krb5_storage_emem(); krb5_storage_set_eof_code(sp, KRB5_CC_END); if(context->fcache_vno != 0) @@ -431,7 +434,7 @@ fcc_initialize(krb5_context context, if (close(fd) < 0) if (ret == 0) { ret = errno; - krb5_set_error_message (context, ret, "close %s: %s", + krb5_set_error_message (context, ret, N_("close %s: %s", ""), FILENAME(id), strerror(ret)); } return ret; @@ -485,7 +488,7 @@ fcc_store_cred(krb5_context context, if (close(fd) < 0) { if (ret == 0) { ret = errno; - krb5_set_error_message (context, ret, "close %s: %s", + krb5_set_error_message (context, ret, N_("close %s: %s", ""), FILENAME(id), strerror(ret)); } } @@ -506,10 +509,10 @@ init_fcc (krb5_context context, ret = fcc_open(context, id, &fd, O_RDONLY | O_BINARY | O_CLOEXEC, 0); if(ret) return ret; - + sp = krb5_storage_from_fd(fd); if(sp == NULL) { - krb5_clear_error_string(context); + krb5_clear_error_message(context); ret = ENOMEM; goto out; } @@ -518,18 +521,19 @@ init_fcc (krb5_context context, if(ret != 0) { if(ret == KRB5_CC_END) { ret = ENOENT; - krb5_set_error_message(context, ret, - "Empty credential cache file: %s", + krb5_set_error_message(context, ret, + N_("Empty credential cache file: %s", ""), FILENAME(id)); } else - krb5_set_error_message(context, ret, "Error reading pvno in " - "cache file: %s", FILENAME(id)); + krb5_set_error_message(context, ret, N_("Error reading pvno " + "in cache file: %s", ""), + FILENAME(id)); goto out; } if(pvno != 5) { ret = KRB5_CCACHE_BADVNO; - krb5_set_error_message(context, ret, "Bad version number in " - "credential cache file: %s", + krb5_set_error_message(context, ret, N_("Bad version number in credential " + "cache file: %s", ""), FILENAME(id)); goto out; } @@ -549,9 +553,9 @@ init_fcc (krb5_context context, ret = krb5_ret_int16 (sp, &length); if(ret) { ret = KRB5_CC_FORMAT; - krb5_set_error_message(context, ret, - "Error reading tag length in " - "cache file: %s", FILENAME(id)); + krb5_set_error_message(context, ret, + N_("Error reading tag length in " + "cache file: %s", ""), FILENAME(id)); goto out; } while(length > 0) { @@ -562,15 +566,18 @@ init_fcc (krb5_context context, ret = krb5_ret_int16 (sp, &dtag); if(ret) { ret = KRB5_CC_FORMAT; - krb5_set_error_message(context, ret, "Error reading dtag in " - "cache file: %s", FILENAME(id)); + krb5_set_error_message(context, ret, N_("Error reading dtag in " + "cache file: %s", ""), + FILENAME(id)); goto out; } ret = krb5_ret_int16 (sp, &data_len); if(ret) { ret = KRB5_CC_FORMAT; - krb5_set_error_message(context, ret, "Error reading dlength in " - "cache file: %s", FILENAME(id)); + krb5_set_error_message(context, ret, + N_("Error reading dlength " + "in cache file: %s",""), + FILENAME(id)); goto out; } switch (dtag) { @@ -578,15 +585,19 @@ init_fcc (krb5_context context, ret = krb5_ret_int32 (sp, &context->kdc_sec_offset); if(ret) { ret = KRB5_CC_FORMAT; - krb5_set_error_message(context, ret, "Error reading kdc_sec in " - "cache file: %s", FILENAME(id)); + krb5_set_error_message(context, ret, + N_("Error reading kdc_sec in " + "cache file: %s", ""), + FILENAME(id)); goto out; } ret = krb5_ret_int32 (sp, &context->kdc_usec_offset); if(ret) { ret = KRB5_CC_FORMAT; - krb5_set_error_message(context, ret, "Error reading kdc_usec in " - "cache file: %s", FILENAME(id)); + krb5_set_error_message(context, ret, + N_("Error reading kdc_usec in " + "cache file: %s", ""), + FILENAME(id)); goto out; } break; @@ -596,8 +607,8 @@ init_fcc (krb5_context context, if(ret) { ret = KRB5_CC_FORMAT; krb5_set_error_message(context, ret, - "Error reading unknown " - "tag in cache file: %s", + N_("Error reading unknown " + "tag in cache file: %s", ""), FILENAME(id)); goto out; } @@ -614,14 +625,15 @@ init_fcc (krb5_context context, break; default : ret = KRB5_CCACHE_BADVNO; - krb5_set_error_message(context, ret, "Unknown version number (%d) in " - "credential cache file: %s", + krb5_set_error_message(context, ret, + N_("Unknown version number (%d) in " + "credential cache file: %s", ""), (int)tag, FILENAME(id)); goto out; } *ret_sp = sp; *ret_fd = fd; - + return 0; out: if(sp != NULL) @@ -645,7 +657,7 @@ fcc_get_principal(krb5_context context, return ret; ret = krb5_ret_principal(sp, principal); if (ret) - krb5_clear_error_string(context); + krb5_clear_error_message(context); krb5_storage_free(sp); fcc_unlock(context, fd); close(fd); @@ -667,12 +679,12 @@ fcc_get_first (krb5_context context, *cursor = malloc(sizeof(struct fcc_cursor)); if (*cursor == NULL) { - krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } memset(*cursor, 0, sizeof(struct fcc_cursor)); - ret = init_fcc (context, id, &FCC_CURSOR(*cursor)->sp, + ret = init_fcc (context, id, &FCC_CURSOR(*cursor)->sp, &FCC_CURSOR(*cursor)->fd); if (ret) { free(*cursor); @@ -681,7 +693,7 @@ fcc_get_first (krb5_context context, } ret = krb5_ret_principal (FCC_CURSOR(*cursor)->sp, &principal); if(ret) { - krb5_clear_error_string(context); + krb5_clear_error_message(context); fcc_end_get(context, id, cursor); return ret; } @@ -702,7 +714,7 @@ fcc_get_next (krb5_context context, ret = krb5_ret_creds(FCC_CURSOR(*cursor)->sp, creds); if (ret) - krb5_clear_error_string(context); + krb5_clear_error_message(context); fcc_unlock(context, FCC_CURSOR(*cursor)->fd); return ret; @@ -775,7 +787,7 @@ fcc_get_version(krb5_context context, { return FCACHE(id)->version; } - + struct fcache_iter { int first; }; @@ -787,9 +799,9 @@ fcc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor) iter = calloc(1, sizeof(*iter)); if (iter == NULL) { - krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; - } + } iter->first = 1; *cursor = iter; return 0; @@ -804,14 +816,14 @@ fcc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id) char *expandedfn = NULL; if (!iter->first) { - krb5_clear_error_string(context); + krb5_clear_error_message(context); return KRB5_CC_END; } iter->first = 0; fn = krb5_cc_default_name(context); if (strncasecmp(fn, "FILE:", 5) != 0) { - ret = _krb5_expand_default_cc_name(context, + ret = _krb5_expand_default_cc_name(context, KRB5_DEFAULT_CCNAME_FILE, &expandedfn); if (ret) @@ -820,7 +832,7 @@ fcc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id) ret = krb5_cc_resolve(context, fn, id); if (expandedfn) free(expandedfn); - + return ret; } @@ -841,7 +853,8 @@ fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to) if (ret && errno != EXDEV) { ret = errno; krb5_set_error_message(context, ret, - "Rename of file from %s to %s failed: %s", + N_("Rename of file from %s " + "to %s failed: %s", ""), FILENAME(from), FILENAME(to), strerror(ret)); return ret; @@ -857,7 +870,7 @@ fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to) unlink(FILENAME(to)); - ret = fcc_open(context, to, &fd2, + ret = fcc_open(context, to, &fd2, O_WRONLY | O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC, 0600); if(ret) goto out1; @@ -867,16 +880,16 @@ fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to) if (sz1 != sz2) { ret = EIO; krb5_set_error_message(context, ret, - "Failed to write data from one file " - "credential cache to the other"); + N_("Failed to write data from one file " + "credential cache to the other", "")); goto out2; } } if (sz1 < 0) { ret = EIO; krb5_set_error_message(context, ret, - "Failed to read data from one file " - "credential cache to the other"); + N_("Failed to read data from one file " + "credential cache to the other", "")); goto out2; } out2: @@ -903,18 +916,39 @@ fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to) krb5_storage_free(sp); fcc_unlock(context, fd); close(fd); - } + } return ret; } static krb5_error_code -fcc_default_name(krb5_context context, char **str) +fcc_get_default_name(krb5_context context, char **str) { - return _krb5_expand_default_cc_name(context, + return _krb5_expand_default_cc_name(context, KRB5_DEFAULT_CCNAME_FILE, str); } +static krb5_error_code +fcc_lastchange(krb5_context context, krb5_ccache id, krb5_timestamp *mtime) +{ + krb5_error_code ret; + struct stat sb; + int fd; + + ret = fcc_open(context, id, &fd, O_RDONLY | O_BINARY | O_CLOEXEC, 0); + if(ret) + return ret; + ret = fstat(fd, &sb); + close(fd); + if (ret) { + ret = errno; + krb5_set_error_message(context, ret, N_("Failed to stat cache file", "")); + return ret; + } + *mtime = sb.st_mtime; + return 0; +} + /** * Variable containing the FILE based credential cache implemention. * @@ -943,5 +977,7 @@ KRB5_LIB_VARIABLE const krb5_cc_ops krb5_fcc_ops = { fcc_get_cache_next, fcc_end_cache_get, fcc_move, - fcc_default_name + fcc_get_default_name, + NULL, + fcc_lastchange }; |