-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multi-homed NFS client does not select correct service principal #65
Comments
The target is generally controlled by the calling code. In this case I assume rpc.gssd is being invoked. Gss-proxy has no idea what interface is used because it is removed from direct knowledge of which interfaces its client is working with. Can you identify exactly what path is being used? |
Just to be clear gssproxy does not use uname -a, either it gets a gss_name for the credential to acquire, or it will parse the keytab and select the first appropriate principal. |
I can't tell who is making the request to acquire the credential. gssd appears to have the correct principal name: "manet.ib.1015granger.net" but the argument for the ACQUIRE_CRED call is "manet.1015granger.net". I can't determine who is the caller. (This is from an earlier session; I can't recall if debug_level was set to 2 or 3 at this time).
|
Ths is the caller: rpc.gssd process 1004 Do not know why rpc.gssd is crawling the keytab and then calling the wrong name. can you: klist -kt /et/krb5.keytab ? |
It's a mystery. find_keytab_entry() claims to be picking up nfs/manet.ib.1015granger.net, which is the correct principal for this context.
|
I added a debugging printf just after the krb5_unparse_name() call site in gssd_get_single_krb5_cred(). Seems to confirm that gssd has the correct principal name.
|
Can you point me at the place you see this in the code? |
I've instrumented gssd. gssd_get_single_krb5_cred() invokes the library function krb5_get_init_creds_keytab() with the longer, correct principal as the third argument. Subsequently I see in the log the GSSX_ARG_ACQUIRE_CRED call with the shorter, incorrect principal. So at this point I believe that gssd is not invoking gss_acquire_cred() directly for client side context establishment. |
That's what I thought, this is a gssd bug. |
Not a gssd bug, it’s a library bug. As I said, gssd provides the exact principal it wants to krb5_get_init_creds_keytab(). |
If you open a bug somwhere against it would be nice if you could link it here, so I can turn this issue into a discussion for other with the same issue to discover. |
Understood. I'm first looking for possible library configuration settings that might help. |
Fedora bugzilla 2128804 has been filed to seek assistance with debugging the mysterious API behavior. |
We're seeing a very similar issue; if /etc/krb5.keytab has a bunch of SPNs (including e.g. This happens even if we set |
The call chain here seems to be: gp_rpc_execute() → gp_acquire_cred() → gp_add_krb5_creds() → gss_acquire_cred_from() → gss_add_cred_from() → acquire_cred_from() → acquire_init_cred(), and acquire_init_cred() looks at whether cred->name is set or not, and it not calls get_name_from_client_keytab(), which calls k5_kt_get_principal(), which has this comment:
So that explains why the first one is chosen (with really bad consequences if it's an SPN and not the actual computer principal!). Now, why desired_name isn't set, I don't know. Even more so when I have set krb5_principal in the config file. That should happen in gp_add_krb5_creds() (via gp_get_cred_environment()). But I wonder if the logic in gp_get_cred_environment() specifies that we don't actually use svc->krb5.principal (the parsed value of krb5_principal) when impersonation is used. Someone who actually knows the code will have to understand that better… |
OK, it's a completely separate bug; apologies for hijacking this thread. This patch seemingly works for me (in the sense that it makes krb5_principal work for impersonation, not that it makes the right thing by default): diff --git a/src/gp_creds.c b/src/gp_creds.c
index 1a0258a..b615b9b 100644
--- a/src/gp_creds.c
+++ b/src/gp_creds.c
@@ -668,7 +668,22 @@ uint32_t gp_add_krb5_creds(uint32_t *min,
} else { /* impersonation */
switch (acquire_type) {
case ACQ_NORMAL:
- ret_maj = gss_acquire_cred_from(&ret_min, GSS_C_NO_NAME,
+ struct gp_service *svc = gpcall->service;
+ gss_name_t host_principal = GSS_C_NO_NAME;
+ if (svc->krb5.principal) {
+ /* configuration dictates to use a specific name */
+ gss_buffer_desc const_buf;
+ const_buf.value = svc->krb5.principal;
+ const_buf.length = strlen(svc->krb5.principal) + 1;
+
+ ret_maj = gss_import_name(&ret_min, &const_buf,
+ discard_const(GSS_KRB5_NT_PRINCIPAL_NAME),
+ &host_principal);
+ if (ret_maj) {
+ goto done;
+ }
+ }
+ ret_maj = gss_acquire_cred_from(&ret_min, host_principal,
GSS_C_INDEFINITE,
&desired_mechs, GSS_C_BOTH,
&cred_store, &impersonator_cred, It probably breaks some coding style rules, but should hopefully be easy enough to adjust. :-) |
Could you submit a PR? |
#111 sent :-) |
The NFSv4.0 callback client in the Linux NFS server invokes gssproxy (somehow) to acquire the credential for its callback channel.
On multi-homed systems, GSSX_ARG_ACQUIRE_CRED always selects the principal associated with "uname -n". When creating an NFS client on alternate network interfaces, GSSX_ARG_ACQUIRE_CRED needs to select the principal associated with that interface, not the one associated with "uname -n".
The text was updated successfully, but these errors were encountered: