Bug 748757
| Summary: | RFE: Improve selection of SPNs with cifs.upcall | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Red Hat Enterprise Linux 6 | Reporter: | Marko Myllynen <myllynen> | ||||
| Component: | cifs-utils | Assignee: | Jeff Layton <jlayton> | ||||
| Status: | CLOSED ERRATA | QA Contact: | Jian Li <jiali> | ||||
| Severity: | medium | Docs Contact: | |||||
| Priority: | medium | ||||||
| Version: | 6.2 | CC: | jiali, nmurray, schlichting, ssorce, steved, yanwang | ||||
| Target Milestone: | rc | Keywords: | FutureFeature, Reopened | ||||
| Target Release: | --- | ||||||
| Hardware: | Unspecified | ||||||
| OS: | Unspecified | ||||||
| Whiteboard: | |||||||
| Fixed In Version: | Doc Type: | Enhancement | |||||
| Doc Text: |
The cifs.upcall utility did not optimally determine the correct service principal name (SPN) used for Kerberos authentication. Which occasionally caused krb5 authentication to fail when mounting a server's unqualified domain name. This update improves cifs.upcall so that the method used to determine the SPN is now more versatile.
|
Story Points: | --- | ||||
| Clone Of: | Environment: | ||||||
| Last Closed: | 2012-06-20 07:27:46 UTC | Type: | --- | ||||
| Regression: | --- | Mount Type: | --- | ||||
| Documentation: | --- | CRM: | |||||
| Verified Versions: | Category: | --- | |||||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||
| Cloudforms Team: | --- | Target Upstream Version: | |||||
| Embargoed: | |||||||
| Attachments: |
|
||||||
|
Description
Marko Myllynen
2011-10-25 09:52:03 UTC
Samba/net bug for invalid principals in the keytab is https://bugzilla.redhat.com/show_bug.cgi?id=749142. Since RHEL 6.2 External Beta has begun, and this bug remains unresolved, it has been rejected as it is not proposed as exception or blocker. Red Hat invites you to ask your support representative to propose this request, if appropriate and relevant, in the next release of Red Hat Enterprise Linux. Created attachment 531106 [details]
patch -- try AD-style HPN's first in SPNEGO upcall
Rather than doing anything that complicated, how about something like this (untested) patch instead? This makes the cifs.upcall program try to use an AD-style HPN first (e.g. "hostname.example.com$"), and only then fall back to cifs/hostname.example.com or then to host/hostname.example.com.
Thoughts?
Yes, the proposal to try the AD-style HPN first sounds good. However, the form of the principal is HOSTNAME$ not hostname.example.com$. I tried this locally with a hard-coded principal name in cifs.upcall.c of the form HOSTNAME$ and HOSTNAME$@REALM and they both worked ok (the longer form didn't work as expected). Thanks. cc'ing Simo to have him help sanity check this plan. Simo, any thoughts?
Ok, it shouldn't be too hard to use a short name here instead if that's necessary, but I have to wonder why using the FQDN here didn't work.
btw: can you outline what sort of setup you're testing against here?
I was under the impression that AD generally added service principals for all
possible hostnames, but perhaps AD and the client have a different idea about
the domain name here?
For instance, I suppose there could be a problem if this host is known as:
server.example.com
...in AD, but the client knows it as:
server.foo.example.com
...and AD doesn't have a SPN for that.
> Ok, it shouldn't be too hard to use a short name here instead if that's > necessary, but I have to wonder why using the FQDN here didn't work. There's a bug reported against Samba / net ads join about the principals not working (bug 749142 which might actually be caused by bug 748831). So if it turns out to be something that could be fixed in Samba (and not being something on AD side which Samba can't workaround) then the need for this would of course go away mostly if not altogether. Make it simple. Scan the keytab and use in preference anything that matches the form hostname$@REALM, and as a second choice anything that matches host/fqdn@REALM. Do not use gethostname() or anything like that to find out what fqdn to use, just scan the keytab. Whatever you find there is right. If it is not there you can't use it anyways. HTH. Simo. (In reply to comment #7) > > Ok, it shouldn't be too hard to use a short name here instead if that's > > necessary, but I have to wonder why using the FQDN here didn't work. > > There's a bug reported against Samba / net ads join about the principals not > working (bug 749142 which might actually be caused by bug 748831). So if it > turns out to be something that could be fixed in Samba (and not being something > on AD side which Samba can't workaround) then the need for this would of course > go away mostly if not altogether. Even if samba changes the way it generates keytabs we should still use whatever is in the keytab with a preference order instead of trying to guess the right name. We have no need to guess all we can use is already in the keytab and we can't use anything else. I'm not sure what you mean by scanning the keytab here.
There's not necessarily any keytab involved on the client in this situation.
It's commonly the case that the user has a TGT already and we just need to
get a service ticket for the hostname sent by the kernel. The kernel generally
gets that from the host portion of the UNC.
For example, the kernel may send "host=server.example.com" in the upcall
string. The existing code just takes that name and tries to get service
tickets for the following, until one succeeds or they all fail:
cifs/server.example.com
host/server.example.com
...to be clear, you're saying we should try these (in this order):
server$
host/server.example.com
cifs/server.example.com
...is that correct?
ok, so we have 2 cases here: you want to use a keytab, or you have a suer's credential cache. In case you need to get a TGT because you want to use a keytab then I would do what I posted below. In the case you mention in comment 10, then I would use some heuristics. If the name being passed down has no dots in it then I would uppercase the name, slap a $ sign at the end and try name$@REALM first If the name has dots I would consider it a fqdn and try cifs/fqdn@REALM If any of these fail I am not sure what is the best fallback method. In case you were not passed a fqdn, then perhaps it is better to just fail. If you were passed a fqdn I would try to truncate the string to the first element and try the hostname$@REALM first, and host/fqdn only as the final fallback. So to summarize: INPUT: fooo TRY in order: FOOO$@REALM cifs/fooo.<guessed domain ?>@REALM host/fooo.<guessed domain ?>@REALM INPUT: bar.example.com TRY in order: cifs/bar.example.com@REALM BAR$@REALM host/bar.example.com@REALM Ok, thanks Simo. I think I need to do some code cleanup in cifs.upcall before we can reasonably do this. It should be doable to implement that scheme though. I did a patchset with Simo suggestion and posted it. Then Andrew Bartlett chimed in and said that there should be no need to do this as FOOO$ and cifs/fooo are really synonyms.
What was the situation that prompted you to request this? Were you testing against AD and "cifs/shortname" didn't work? If so, I have to wonder if there is something misconfigured in your environment.
Read here for more info:
http://thread.gmane.org/gmane.linux.kernel.cifs/4929
Ok, I've posted a new patchset today that I think is what we need. The concensus from the discussion seems to be that we should not try to use AD-style SPNs, and instead should stick to using cifs/ SPN's.
The proposed patchset is here. This should work fine in most AD-environments.
http://thread.gmane.org/gmane.linux.kernel.cifs/4969
If this won't work for your environment, then please comment as to why and I'll see what we can do to accomodate it.
> What was the situation that prompted you to request this? Were you testing > against AD and "cifs/shortname" didn't work? If so, I have to wonder if there > is something misconfigured in your environment. Yes, indeed it seems that there was something misconfigured on the AD side - once the last 2003R2 DC in the local domain was decommissioned the issues with host/fqdn@REALM principals reported in bug 749142 vanished, thus the need to use the CLIENT$@REALM principal went away. The new patchset look good, thanks for doing this. Fixed in cifs-utils-4.8.1-7.el6. In the upstream discussion around this, it turned out that the algorithm in comment #11 was wrong. This is the one that we finally settled on: /* * Andrew Bartlett's suggested scheme for picking a principal * name, based on a supplied hostname. * * INPUT: fooo * TRY in order: * cifs/fooo@REALM * cifs/fooo.<guessed domain ?>@REALM * * INPUT: bar.example.com * TRY only: * cifs/bar.example.com@REALM */ Basically we only attempt to find a cifs/<host> principal. If <host> is unqualified, then we also attempt to guess the domain name if getting a principal with just the raw hostname fails. Jeff, I still couldn't make the mode: foo => cifs/foo What I did is that: On server, setup krb5 server and create principal root, cifs/foo On client, add "ip-address foo" to /etc/hosts (and prepare /etc/krb5.conf|krb5.keytab) # kinit -k root # mount.cifs //foo/export /mnt -o sec=krb5 mount error(13): Permission denied Through scanning cifs debug info, find there is some message containing cifs/`server hostname`@REALM . Please give some suggestion, thanks lijian (In reply to comment #24) > Jeff, > I still couldn't make the mode: > foo => cifs/foo > > What I did is that: > On server, setup krb5 server and create principal root, cifs/foo > > On client, add "ip-address foo" to /etc/hosts (and prepare > /etc/krb5.conf|krb5.keytab) That's probably the problem. cifs.upcall uses the ai_canonname field from getaddrinfo to guess the domain name. That field is typically not populated when resolving from /etc/hosts, so we have no way to make that guess. In order to verify that, you'll need to add a DNS record for it. thank you jeff, I adapt system, stop it looking up host, and modify its hostname, cifs mount could use this case.
[root@fooo ~]# mount.cifs //fooo/export /mnt -o sec=krb5
[root@fooo ~]# dmesg | grep cifs/fooo
fs/cifs/asn1.c: Need to call asn1_octets_decode() function for cifs/fooo.RDU.REDHAT.COM
[root@fooo ~]# klist -k
Keytab name: WRFILE:/etc/krb5.keytab
KVNO Principal
---- --------------------------------------------------------------------------
3 root.RDU.REDHAT.COM
3 root.RDU.REDHAT.COM
3 root.RDU.REDHAT.COM
3 root.RDU.REDHAT.COM
4 cifs/fooo.RDU.REDHAT.COM
4 cifs/fooo.RDU.REDHAT.COM
4 cifs/fooo.RDU.REDHAT.COM
4 cifs/fooo.RDU.REDHAT.COM
[root@fooo ~]# kinit
Password for root.RDU.REDHAT.COM:
kinit: Password read interrupted while getting initial credentials
[root@fooo ~]# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: root.RDU.REDHAT.COM
Valid starting Expires Service principal
04/19/12 04:51:36 04/20/12 04:51:36 krbtgt/RHTS.ENG.RDU.REDHAT.COM.RDU.REDHAT.COM
renew until 04/19/12 04:51:36
04/19/12 04:51:41 04/20/12 04:51:36 cifs/fooo.RDU.REDHAT.COM
renew until 04/19/12 04:51:36
Technical note added. If any revisions are required, please edit the "Technical Notes" field
accordingly. All revisions will be proofread by the Engineering Content Services team.
New Contents:
The cifs.upcall utility did not optimally determine the correct service principal name (SPN) used for Kerberos authentication. Which occasionally caused krb5 authentication to fail when mounting a server's unqualified domain name. This update improves cifs.upcall so that the method used to determine the SPN is now more versatile.
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. http://rhn.redhat.com/errata/RHSA-2012-0902.html |