Ticketzwischenspeicher: FILE:/tmp/krb5cc_722
Standard-Principal: osipovmi@EXAMPLE.COM
Valid starting Expires Service principal
06.04.2021 17:18:38 07.04.2021 03:18:38 krbtgt/EXAMPLE.COM@EXAMPLE.COM
erneuern bis 07.04.2021 17:18:35
06.04.2021 17:18:42 07.04.2021 03:18:38 HTTP/hostname.EXAMPLE.COM@EXAMPLE.COM
06.04.2021 17:18:42 07.04.2021 03:18:38 HTTP/hostname.EXAMPLE.COM@EXAMPLE.COM
06.04.2021 17:18:42 07.04.2021 03:18:38 HTTP/hostname.EXAMPLE.COM@EXAMPLE.COM
06.04.2021 17:18:42 07.04.2021 03:18:38 HTTP/hostname.EXAMPLE.COM@EXAMPLE.COM
06.04.2021 17:18:42 07.04.2021 03:18:38 HTTP/hostname.EXAMPLE.COM@EXAMPLE.COM
gssapi.raw.misc.GSSError: Major (851968): Unspecified GSS failure. Minor code may provide more information, Minor (100001): Failed to store credentials: Internal credentials cache error (filename: /tmp/krb5cc_1000)
gssapi.raw.acquire_cred_from(store={b"ccache":b"FILE:/tmp/<app>_<threadname>", b"client_keytab":b"/path/to/service.keytab"}, usage='initiate')but I'd like to avoid adding even more code to fix a symptom not the cause.
gssapi.raw.misc.GSSError: Major (851968): Unspecified GSS failure. Minor code may provide more information, Minor (100001): Failed to store credentials: Internal credentials cache error (filename: /tmp/krb5cc_1000)
On 4/6/21 11:48 AM, Osipov, Michael (LDA IT PLM) wrote:
gssapi.raw.misc.GSSError: Major (851968): Unspecified GSS failure. Minor code may provide more information, Minor (100001): Failed to store credentials: Internal credentials cache error (filename: /tmp/krb5cc_1000)
This is not expected, and bears investigation. It suggests an EINVAL, EEXIST, EFAULT, EBADF, or EWOULDBLOCK error from one of the I/O
operations performed by fcc_store(), none of which are expected. If
you're building libkrb5, you could try modifying interpret_error() to
pass those error codes through in order to find out which one is happening.
Getting multiple cache entries for a service is normal when multiple
threads or processes initiate contexts to the same (new) service within
a short window.
ret = interpret_errno(context, errno);reat and errno to std stream?
On 4/6/21 11:48 AM, Osipov, Michael (LDA IT PLM) wrote:
gssapi.raw.misc.GSSError: Major (851968): Unspecified GSS failure. Minor code may provide more information, Minor (100001): Failed to store credentials: Internal credentials cache error (filename: /tmp/krb5cc_1000)
This is not expected, and bears investigation. It suggests an EINVAL, EEXIST, EFAULT, EBADF, or EWOULDBLOCK error from one of the I/O
operations performed by fcc_store(), none of which are expected. If
you're building libkrb5, you could try modifying interpret_error() to
pass those error codes through in order to find out which one is happening.
Getting multiple cache entries for a service is normal when multiple
threads or processes initiate contexts to the same (new) service within
a short window.
$ git diff
diff --git a/src/lib/krb5/ccache/cc_file.c b/src/lib/krb5/ccache/cc_file.c index 9a9b45a6e..7f604c0f4 100644
--- a/src/lib/krb5/ccache/cc_file.c
+++ b/src/lib/krb5/ccache/cc_file.c
@@ -1000,8 +1000,9 @@ fcc_store(krb5_context context, krb5_ccache id, krb5_creds *creds)
if (ret)
goto cleanup;
nwritten = write(fileno(fp), buf.data, buf.len);
- if (nwritten == -1)
+ if (nwritten == -1) {
ret = interpret_errno(context, errno);
+ printf("errno: %d, ret: %d\n", errno, ret); }
if ((size_t)nwritten != buf.len)
ret = KRB5_CC_IO;
@@ -1293,6 +1294,7 @@ interpret_errno(krb5_context context, int errnum)I had exactly one faiure in the job and received exactly this:
case EWOULDBLOCK:
#endif
ret = KRB5_FCC_INTERNAL;
+ printf("errnum: %d, ret: %d\n", errnum, ret);
break;
/*
* The rest all map to KRB5_CC_IO. These errnos are listed to
errnum: 17, ret: -1765328188which maps to EEXIST
fcc_initialize()
errnum: 17, ret: -1765328188
fcc_initialize()
errnum: 17, ret: -1765328188
I am quite sure that this is a race condition where stat() is performed,
file does not exist, open() with write is performed, in parallel it is already created and the later call returns in EEXIST.
On 4/9/21 11:35 AM, Osipov, Michael (LDA IT PLM) wrote:
I am quite sure that this is a race condition where stat() is performed,
file does not exist, open() with write is performed, in parallel it is
already created and the later call returns in EEXIST.
I agree, except I think it's just unlink() and open(O_CREAT|O_EXCL)
calls with no stat(). I had erroneously assumed that the unexpected
error was happening inside fcc_store() because of "Failed to store credentials" in the message, but that string turns out to be from get_in_tkt.c in a block of code that also calls krb5_cc_initialize().
The fcc_initialize() EEXIST self-race has existed since 1.0. I'd
speculate that the original developers' assumption was that lots of
processes might be competing to use a file ccache, but that creating
ccaches would be a rare and one-at-a-time affair (happening at login or
when a user runs "kinit"). With client keytab support, that is no
longer the case; it's easy to have multiple threads or processes
competing to create or refresh a cache as part of gss_acquire_cred() or gss_init_sec_context().
Just fixing the fcc_initialize() race wouldn't really solve the problem; there would still be a window between krb5_cc_initialize() and krb5_cc_store_cred() where other threads (or processes) would see an initialized cache with no TGT in it, and would fail the gss_init_sec_context() call.
This ticket describes that problem and
some possible solutions:
https://krbdev.mit.edu/rt/Ticket/Display.html?id=7707
Heimdal has implemented option 5. I'm not wild about it and it won't
work with other ccache types, but it's a working stopgap and it can
always be backed out in favor of a different solution later.
spnego = gssapi.OID.from_int_seq("1.3.6.1.5.5.2")
if keytab_location:
store = {}
store[b"client_keytab"] = keytab_location.encode(sys.getdefaultencoding())
store[b"ccache"] = ("/tmp/krb5cc_%d_%s" % (os.getpid(), threading.get_ident())).encode(sys.getdefaultencoding())
creds = (gssapi.raw.acquire_cred_from(store=store, mechs=[spnego], usage="initiate")).creds
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 293 |
Nodes: | 16 (2 / 14) |
Uptime: | 237:24:07 |
Calls: | 6,624 |
Files: | 12,172 |
Messages: | 5,319,873 |