k5_cc_mutex krb5int_cc_file_mutex = K5_CC_MUTEX_PARTIAL_INITIALIZER;
+/* Add fname to the standard error message for ret. */
+static krb5_error_code
+set_errmsg_filename(krb5_context context, krb5_error_code ret,
+ const char *fname)
+{
+ k5_setmsg(context, ret, "%s (filename: %s)", error_message(ret), fname);
+ return ret;
+}
+
/* Get the size of the cache file as a size_t, or SIZE_MAX if it is too
* large to be represented as a size_t. */
static krb5_error_code
flags = writable ? (O_RDWR | O_APPEND) : O_RDONLY;
fd = open(filename, flags | O_BINARY | O_CLOEXEC, 0600);
- if (fd == -1) {
- if (errno == ENOENT) {
- ret = KRB5_FCC_NOFILE;
- k5_setmsg(context, ret, _("Credentials cache file '%s' not found"),
- filename);
- return ret;
- } else {
- return interpret_errno(context, errno);
- }
- }
+ if (fd == -1)
+ return interpret_errno(context, errno);
set_cloexec_fd(fd);
lockmode = writable ? KRB5_LOCKMODE_EXCLUSIVE : KRB5_LOCKMODE_SHARED;
close(fd);
k5_cc_mutex_unlock(context, &data->lock);
krb5_change_cache();
- return ret;
+ return set_errmsg_filename(context, ret, data->filename);
}
/* Release an fcc_data object. */
free(id);
krb5_change_cache();
- return ret;
+ return set_errmsg_filename(context, ret, data->filename);
}
extern const krb5_cc_ops krb5_fcc_ops;
free(fcursor);
krb5_free_principal(context, princ);
k5_cc_mutex_unlock(context, &data->lock);
- return ret;
+ return set_errmsg_filename(context, ret, data->filename);
}
/* Get the next credential from the cache file. */
(void)krb5_unlock_file(context, fileno(fcursor->fp));
k5_cc_mutex_unlock(context, &data->lock);
k5_buf_free(&buf);
- return ret;
+ return set_errmsg_filename(context, ret, data->filename);
}
/* Release an iteration cursor. */
k5_cc_mutex_destroy(&data->lock);
free(data->filename);
free(data);
- return ret;
+ return set_errmsg_filename(context, ret, data->filename);
}
/*
cleanup:
(void)close_cache_file(context, fp);
k5_cc_mutex_unlock(context, &data->lock);
- return ret;
+ return set_errmsg_filename(context, ret, data->filename);
}
/* Search for a credential within the cache file. */
fcc_retrieve(krb5_context context, krb5_ccache id, krb5_flags whichfields,
krb5_creds *mcreds, krb5_creds *creds)
{
- return k5_cc_retrieve_cred_default(context, id, whichfields, mcreds,
- creds);
+ krb5_error_code ret;
+
+ ret = k5_cc_retrieve_cred_default(context, id, whichfields, mcreds, creds);
+ return set_errmsg_filename(context, ret, ((fcc_data *)id->data)->filename);
}
/* Store a credential in the cache file. */
k5_buf_free(&buf);
ret2 = close_cache_file(context, fp);
k5_cc_mutex_unlock(context, &data->lock);
- return ret ? ret : ret2;
+ return set_errmsg_filename(context, ret ? ret : ret2, data->filename);
}
/* Non-functional stub for removing a cred from the cache file. */
ret = krb5_cc_resolve(context, defname, &cache);
if (ret)
- return ret;
+ return set_errmsg_filename(context, ret, defname);
*cache_out = cache;
return 0;
}
k5_cc_mutex_unlock(context, &data->lock);
- return ret;
+ return set_errmsg_filename(context, ret, data->filename);
}
/* Lock the cache handle against other threads. (This does not lock the cache
switch (errnum) {
case ENOENT:
+ case ENOTDIR:
+#ifdef ELOOP
+ case ELOOP:
+#endif
+#ifdef ENAMETOOLONG
+ case ENAMETOOLONG:
+#endif
ret = KRB5_FCC_NOFILE;
break;
case EPERM:
#ifdef EISDIR
case EISDIR: /* Mac doesn't have EISDIR */
#endif
- case ENOTDIR:
-#ifdef ELOOP
- case ELOOP: /* Bad symlink is like no file. */
-#endif
-#ifdef ETXTBSY
- case ETXTBSY:
-#endif
- case EBUSY:
case EROFS:
ret = KRB5_FCC_PERM;
break;
case EEXIST:
case EFAULT:
case EBADF:
-#ifdef ENAMETOOLONG
- case ENAMETOOLONG:
-#endif
#ifdef EWOULDBLOCK
case EWOULDBLOCK:
#endif
ret = KRB5_FCC_INTERNAL;
break;
-#ifdef EDQUOT
- case EDQUOT:
-#endif
- case ENOSPC:
- case EIO:
- case ENFILE:
- case EMFILE:
- case ENXIO:
+ /*
+ * The rest all map to KRB5_CC_IO. These errnos are listed to
+ * document that they've been considered explicitly:
+ *
+ * - EDQUOT
+ * - ENOSPC
+ * - EIO
+ * - ENFILE
+ * - EMFILE
+ * - ENXIO
+ * - EBUSY
+ * - ETXTBSY
+ */
default:
ret = KRB5_CC_IO;
- k5_setmsg(context, ret,
- _("Credentials cache I/O operation failed (%s)"),
- strerror(errnum));
+ break;
}
return ret;
}
# Test kdestroy and klist of a non-existent ccache.
realm.run([kdestroy])
output = realm.run([klist], expected_code=1)
-if ' not found' not in output:
+if 'No credentials cache found' not in output:
fail('Expected error message not seen in klist output')
# Test kinit with an inaccessible ccache.
realm.run([klist, '-A', '-s'])
realm.run([kdestroy])
output = realm.run([klist], expected_code=1)
- if ' not found' not in output:
+ if 'No credentials cache' not in output and 'not found' not in output:
fail('Initial kdestroy failed to destroy primary cache.')
output = realm.run([klist, '-l'], expected_code=1)
if not output.endswith('---\n') or output.count('\n') != 2:
conf1 = {'libdefaults': {'err_fmt': fmt1}}
e1 = realm.special_env('fmt1', False, krb5_conf=conf1)
out = realm.run([klist, '-c', 'testdir/xx/yy'], env=e1, expected_code=1)
-if out != ("klist: FOO Error: Credentials cache file 'testdir/xx/yy' not "
- "found (see http://localhost:1234/-1765328189 for more "
- "information)\n"):
+if out != ('klist: FOO Error: No credentials cache found (filename: '
+ 'testdir/xx/yy) (see http://localhost:1234/-1765328189 for more '
+ 'information)\n'):
fail('err_fmt expansion failed')
conf2 = {'libdefaults': {'err_fmt': '%M - %C'}}
e2 = realm.special_env('fmt2', False, krb5_conf=conf2)
out = realm.run([klist, '-c', 'testdir/xx/yy'], env=e2, expected_code=1)
-if out != ("klist: Credentials cache file 'testdir/xx/yy' not found - "
- "-1765328189\n"):
+if out != ('klist: No credentials cache found (filename: testdir/xx/yy) - '
+ '-1765328189\n'):
fail('err_fmt expansion failed')
conf3 = {'libdefaults': {'err_fmt': '%%%M %-% %C%'}}
e3 = realm.special_env('fmt3', False, krb5_conf=conf3)
out = realm.run([klist, '-c', 'testdir/xx/yy'], env=e3, expected_code=1)
-if out != ("klist: %Credentials cache file 'testdir/xx/yy' not found %-% "
- "-1765328189%\n"):
+if out != ('klist: %No credentials cache found (filename: testdir/xx/yy) %-% '
+ '-1765328189%\n'):
fail('err_fmt expansion failed')
success('error message tests')