Hide Forgot
+++ This bug was initially created as a clone of Bug #667654 +++ Description of problem: I can mount two CIFS shares that are on the same server, each for a different user who has valid krb5 credentials. However only the user who's share is mounted first can access his data. I experimented with '-o multiuser' and /proc/fs/cifs/MultiuserMount but that changed nothing. cifs.upcall uses the '-l' flag in request-key.conf. What I do is to login as two users 'walteste' and 'suuchan' and get a TGT for each of them. Then I do # mount.cifs -o user=walteste,uid=walteste,sec=krb5 '//nas-nethz-users.d.ethz.ch/share-w-$' /mnt/1 # mount.cifs -o user=suuchan,uid=suuchan,sec=krb5 '//nas-nethz-users.d.ethz.ch/share-s-$' /mnt/2 as 'root' to mount the two shares. The one I mount first can be accessed by the corresponding user (user sees files). The share mounted last is empty (user sees no files). What I notice is that with cifsFYI set to 3, I see that the first mount invokes cifs.upcall and it finds the ticket. The second mount does not trigger cifs.upcall so I assume the kernel thinks it already has the right key even though it has not. The reproducer below is for a case where the second user does not even have a ticket so the issue may be in the kernel. Version-Release number of selected component (if applicable): cifs-utils-4.7-4.el6.i686 kernel-2.6.32-71.7.1.el6.i686 How reproducible: Always Steps to Reproduce: 1. Login with user a and get a TGT 2. mount a CIFS share from a server using 'sec=krb5,uid=a,user=a' 3. mount a CIFS share from a server using 'sec=krb5,uid=b,user=b' Actual results: Second share is mounted even though user b does not have a ticket. Expected results: Second mount should fail. --- Additional comment from pm-rhel on 2011-01-06 06:13:27 EST --- Since this issue was entered in bugzilla, the release flag has been set to ? to ensure that it is properly evaluated for this release. --- Additional comment from jlayton on 2011-01-06 08:45:03 EST --- The new multiuser mount code should be in 6.1... The cifs code tries to aggressively "share" different server objects between mounts. For krb5 SMB sessions, it does this by checking to see whether the credential uid (i.e. the real uid of the user doing the mount) is the same as that of an existing session. Also, the username field is unused for krb5 mounts (the server only cares about the krb5 ticket). Because you're performing both mounts as the same user (root) it's matching the same session for both mounts. The idea here is that "borrowing" the credential cache of another user as cifs used to do is a bad thing. What we really need to know when doing a mount is whether the (real) user doing the mount has the proper credentials. What I could use here is some clarification of your use case. How exactly are you planning to use this in practice? Doing a kinit as one user and performing the mount as another (root) seems a bit cumbersome... --- Additional comment from walteste.ch on 2011-01-06 09:30:07 EST --- Thanks for the clarifications. I saw you mentioning that the the multiuser support will be in 6.1 elsewhere but didn't consider it relevant for this case. What I actually want to do is use autofs to mount the shares. This seems to work for one user but we need this to work for multiple users on the same system. Alternatively I was considering to use pam-script and mount the shares during login but then again I would mount them as root to avoid the SUID bit for mount.cifs. --- Additional comment from jlayton on 2011-01-06 11:06:08 EST --- Another option to consider is pam_mount which is geared toward this sort of thing, but it looks like it hasn't made it into EPEL yet: https://admin.fedoraproject.org/pkgdb/acls/name/pam_mount It might be worth opening a bug against it to see if the maintainer of it would build it for epel6. Note that I gave a talk on cifs and krb5 at the RH summit this year, so you may want to look over that as you design this solution: https://access.redhat.com/knowledge/videos/player?id=013 autofs is rather problematic for this sort of thing. I assume that you were going to do something like have autofs pass in '-o uid=$UID'? If so, then how will you ensure that the "right" user is the one that walks into the mountpoint and triggers the mount? We can probably solve this by adding a cred_uid= mount option that's only settable when the real uid is root. I'm not sure I'm entirely comfortable with such a solution however, and that would need to pass review upstream first. --- Additional comment from walteste.ch on 2011-01-06 12:57:22 EST --- I'll give pam_mount a try and watch the video tomorrow. Thanks for the input. Autofs would have worked nicely for us because if we also use DFS we could use an auto.home map like this: * -fstype=cifs,user=&,uid=&,gid=users,sec=krb5 ://d/dfs/users/all/& The mounts are for home directories so dir == uid == user. The only thing that could go wrong is that 'cifs.upcall -l' would not find a ticket if someone tries to mount the home of another user who is not logged in and only if autofs does some negative caching. This could probably be addressed with a program map: #!/bin/sh user="$1"; uid=`id -ru -- "$user"` || exit 1 # <-- insert check here if there is a krb5cc_(uid)_* owned by (uid) initial=`echo "$user" | cut -c1` echo "-fstype=cifsuid=$user,gid=users,sec=krb5 \ ://nas-nethz-users.d.ethz.ch/share-$initial-\$/$user" Anyway, if you think that the multiuser support will solve all of this I'll go for that as soon as 6.1 is there. Is there already a test kernel with this feature around? The solution with a 'cred_uid' option would at least be consistent with the '-l' flag for cifs.upcall because that flag makes only 50% sense if the kerner does not call it. A 'legacy' option that would force the kernel to honour the 'user' option would also do. BTW, I have seen FC13 systems that mount multiple CIFS shares as root during login. Does that already have the multiuser code? --- Additional comment from jlayton on 2011-01-06 13:14:43 EST --- Multiuser mounts may solve this for you. You should be able to just mount this once: //d/dfs/users/all ...and all accesses to things under that mount would be done using the user's own krb5 creds. I have the code backported to RHEL6, so if you're willing to test it out that would be great. The best way would be for you to open a support case and get it attached to this bug, and then I'll have the support folks make the kernel available to you. --- Additional comment from walteste.ch on 2011-01-06 14:19:43 EST --- OK, case 00399988 opened. This sounds nice although that initial mount would probably require some 'machine' credentials (hidden password or keytab). I can live with that but with our AD its fabulously easy to lock that account out. :( --- Additional comment from jlayton on 2011-01-06 14:49:48 EST --- Thanks for opening the case. A keytab is probably your best bet, I need to verify however that cifs.upcall will access the keytab when the credcache is expired or not present however. The situation is a little different from NFS where root is generally mapped to the machine creds. Machine creds in AD have no capability for filesystem access, so that sort of rules them out for this purpose. One thing I've been struggling with (even upstream) is trying to determine a "best-practice" for the credentials that root should use for mounting and accessing the share. I've generally just created a user that equates to "root". Note that that user needn't have any special permissions. It can even be mapped to a generic "nobody" user or something. --- Additional comment from walteste.ch on 2011-01-07 06:15:49 EST --- I did some testing on a FC13 system. This already has the multiuser code. If I do the tests in the report it all works, *without* the multiuser option and *without* the -l switch for cifs.upcall: # mount.cifs -o user=walteste,uid=walteste,sec=krb5 \ '//nas-nethz-users.d.ethz.ch/share-w-$' /mnt/1 # mount.cifs -o user=suuchan,uid=suuchan,sec=krb5 \ '//nas-nethz-users.d.ethz.ch/share-s-$' /mnt/2 * I can mount both shares as root and each of the users can access his files. * If one of the ticket is missing I get 'mount error(126): Required key not available' for the respective mount, even if one share is already mounted. * I can leave the '-l' option for cifs.upcall away and it will use the right ticket for each mount: cifs.upcall: find_krb5_cc: considering /tmp/krb5cc_501 cifs.upcall: find_krb5_cc: FILE:/tmp/krb5cc_501 is valid ccache ... cifs.upcall: find_krb5_cc: considering /tmp/krb5cc_501 cifs.upcall: find_krb5_cc: /tmp/krb5cc_501 is owned by 501, not 500 According to https://bugzilla.redhat.com/show_bug.cgi?id=667382 that should have failed and use /tmp/krb5cc_0. * If root also has a ticket with rights to browse DFS, then automounting both shares with * -fstype=cifs,user=&,uid=&,gid=users,sec=krb5 ://d/dfs/users/all/& also works (and autofs indeed caches failed mounts due to missing credentials for a short while). It seems that the patches for the multiuser support fix the issues of this bug as a side effect. One reason more for me to want this as soon as possible in RHEL6. :) --- Additional comment from jlayton on 2011-01-07 08:21:58 EST --- (In reply to comment #13) > I did some testing on a FC13 system. This already has the multiuser code. > If I do the tests in the report it all works, *without* the multiuser option > and *without* the -l switch for cifs.upcall: > No, f13 does not have the multiuser code. It just now went upstream in 2.6.37. That kernel probably still matches smb sessions by username which is incorrect for krb5. That bug however is probably papering over the problem that you're hitting here. --- Additional comment from walteste.ch on 2011-01-07 09:04:54 EST --- OK, 'man mount.cifs' describes the 'multiuser' option so I assumed its implemented, especially because the stock rhel6 cifs-utils-4.4-5 does not have that section. The FC13 kernel is 2.6.34.7-66, on RHEL6 its 2.6.32-71.7.1. If I understand you right they *should* both behave the same regarding the way the credential is selected because neither has the new code. In 2.6.33 or 2.6.34 something must have been added that changes the behavior in favor of what I want to do but that is actually a bug. Without knowing the internals of mount.cifs, the kernel and the problems of how to correctly determine to mount as who, it is still my belief that when the 'user' option is specified with mount.cifs then the credentials of that user should be used and not the one that were cached for the user 'root'. In this respect I think the behavior if FC13 is correct and the one for RHEL6 is not. What I do not understand yet is how CIFS mounts will behave in the future if the 'multiuser' option is not used, e.g., for FC15 or RHEL7. Will it behave like FC13 or RHEL 6.0? Where I want to lead this is that even if the 'multiuser' functionality is there you still want a more or less consistent behavior if you leave it off (unless you make multiuser mandatory). If I can choose I would rather see the FC13 behavior in the future and it would make sense to back-port it to RHEL6. Anyway, I'll give pam_mount a try but if the problem is in the kernel then it shouldn't succeed where mount.cifs fails. --- Additional comment from jlayton on 2011-01-07 10:08:20 EST --- (In reply to comment #15) Keeping the manpage and kernel in sync is pretty much impossible. It would be nice if cifs code in the kernel would reject options that it doesn't recognize but the option parsing code is a real mess. It's not specifically the multiuser code that changed that behavior. It was some earlier patches. RHEL6 has those patches, and F13 does not. The problem is this: we want to avoid establishing more than one SMB session per user, as that's a waste of resources on the server and client and causes a number of other problems that can lead to the client holding fewer oplocks. So, we need some mechanism to say that we want to use *this* session to talk to the server (and hence *this* set of credentials) and not that session. Matching by username is problematic since we can't reliably count on the username being set to anything meaningful. The username is mostly ignored in the case of a krb5 mount. The only exception is the case of keytabs, but we don't even really *have* to use it for that. In the case of a session established from kernel space (the multiuser mount case) it definitely won't be set to anything meaningful. What we really want to do is match existing sessions based on credential cache, but we are not able to easily get at that info in kernel space (we'd have to upcall for it). The best we can reasonably do is match by the uid of the credential cache owner. Later revisions will act more like RHEL6.0 as it stands now, but that's not to say that we can't accommodate this use-case. Matching krb5 sessions based on username is wrong, even if it happened to work for you in this situation. The simplest fix is to add a "creduid" mount option, but I'd like to consider the problem a little more before I try to push anything upstream. --- Additional comment from walteste.ch on 2011-01-07 15:36:16 EST --- Thanks for the detailed background information, I understand now how this came to happen. I am all in favour of the 'creduid' option. Basically its just what I was asking for. The only difference is that you propose to put it in a separate option while I was assuming that the 'user' option will change namespace and semantic with the authentication scheme. For krb5 that can only be the uname (or uid) of the local user having the tickets to use. That only root can choose the user and for all others the UID of the caller must match the 'creduid' was implicit to me. My only other point is that for root and root only the choice to cache the credentials for the caller is a bad idea. Of course that works for all users who can only mount shares using their own credentials anyway. But you would expect root to be able to mount on behalf of other local users. Since mounting shares as root with sec=krb5 does not really work now in RHEL6 as it stands, how about a quick fix where you disable the aggressive caching and just open a new session every time when root is the caller? That would leave an admin at least the choice to use the feature as long as his servers support the load. Of course I do not know what would break if you add an 'if (uid != 0) { }' arond the cache lookup code but it's an idea. It will also not be a solution for people toying with SELinux and roles but there are not too many of those. :) --- Additional comment from jlayton on 2011-01-07 16:30:51 EST --- > But you would expect root to be able to mount on behalf of other local users. No, I don't expect that at all. The bottom line is that allowing anyone (even root) to "borrow" another user's credcache is just wrong. It's true that the krb5 implementation in cifs used to do that, but that was a bad design (and my fault too). The root of the problem here however is *really* that cifs has had a built in design limitation of a single set of credentials per mount. That limitation has caused the implementation of a number of hacks to deal with it. The multiuser mount code changes that, but we've had to "shoehorn" that in to some degree since the code was not originally designed for it. That said, people will still want to use the old single-credential per mount model for some time, so we need to be able to accommodate that use-case. > Since mounting shares as root with sec=krb5 does not really work now in RHEL6 > as it stands, how about a quick fix where you disable the aggressive caching > and just open a new session every time when root is the caller? I'm steadfastly against putting in hacks that are not upstream. Down that path lies madness... We'll fix this in RHEL6 eventually, but that fix needs to pass the muster upstream first. The creduid option is probably a reasonable fix, but as I said, I need to consider the problem a little more. There may be a better approach that we just haven't thought of yet. --- Additional comment from walteste.ch on 2011-01-07 18:21:27 EST --- We should probably leave the discussion here, this could go on for a while. My goal (for which I have a quite tight deadline) is to get multiple CIFS home directories mounted on RHEL 6.0 workstations. For the moment the simplest seems to use pam_script, make mount.cifs SUID and use 'su' to mount the directory as the user. I'll opt for that because it will definitely work. If 'multiuser' support will make it into 6.1 I will be happy and rather leave this issue unresolved and leave you more time to port Minshall+French symlink support back into RHEL6. :) --- Additional comment from jlayton on 2011-01-07 20:01:33 EST --- Understood. It's technically a regression (at least upstream) so I am on the hook to fix this there anyway, but that may not happen within your timeframe. Once support hooks up the a.r.c to this BZ, I'll ask them to pass along a test kernel to you with all of the patches that I have queued up for 6.1 so far. Also, mfsymlink support is already being proposed for 6.1 (see bug 651878). The test kernel should have that as well. --- Additional comment from jlayton on 2011-01-10 09:02:37 EST --- Created attachment 472594 [details] patch -- add creduid= mount option Here's the patch I'm considering. I'll add this to my RHEL6 patch stack for testing as well. --- Additional comment from jlayton on 2011-01-11 10:37:46 EST --- Created attachment 472835 [details] patch -- add cruid= mount option That patch won't work -- mount.cifs allows for "abbreviations" and "creduid=" collides with "credentials=". So, I'll plan to propose this patch instead which does work. The mount option will be called 'cruid='. --- Additional comment from jlayton on 2011-01-12 11:16:41 EST --- Stefan, do you have a support case open against this (specific) problem? I'd like to pass on a kernel for you to test if you do... --- Additional comment from walteste.ch on 2011-01-13 03:12:59 EST --- I have opened case 00402003 where I explicitly ask for the --cruid option. I didn;t expect this to be implemented so fast. A test kernel is warmly welcome.
Opening this bug to track the userspace changes needed for this. I've already posted a couple of patches upstream for it. If we put the kernel piece in 6.1, we'll also want the userspace mount.cifs patches and manpage fix. http://thread.gmane.org/gmane.linux.kernel.cifs/2270
Committed in cifs-utils-4.8-1.el6.
hi Jeff, I try to reproduce the problem on RHEL6.1, but seems mount failed during test, could you help me to find out what's the problem? I set up KDC and get the ticket for user1 # klist Ticket cache: FILE:/tmp/krb5cc_0 Default principal: user1.REDHAT.COM Valid starting Expires Service principal 03/31/11 02:41:53 04/01/11 02:41:53 krbtgt/LAB.BOS.REDHAT.COM.REDHAT.COM renew until 03/31/11 02:41:53 03/31/11 02:41:57 04/01/11 02:41:53 host/hp-xw6400-02.lab.bos.redhat.com.REDHAT.COM renew until 03/31/11 02:41:53 # cat /etc/krb5.conf [logging] default = FILE:/var/log/krb5libs.log kdc = FILE:/var/log/krb5kdc.log admin_server = FILE:/var/log/kadmind.log [libdefaults] default_realm = LAB.BOS.REDHAT.COM dns_lookup_realm = false dns_lookup_kdc = false ticket_lifetime = 24h renew_lifetime = 7d forwardable = true allow_weak_crypto = true [realms] LAB.BOS.REDHAT.COM = { kdc = hp-xw6400-02.lab.bos.redhat.com admin_server = hp-xw6400-02.lab.bos.redhat.com } [domain_realm] .lab.bos.redhat.com = LAB.BOS.REDHAT.COM lab.bos.redhat.com = LAB.BOS.REDHAT.COM my smb.conf snippet: [global] security = ads use kerberos keytab = yes realm = LAB.BOS.REDHAT.COM server signing = auto [public] comment = Public Stuff path = /tmp writable = yes printable = no # cat /etc/request-key.conf: ... create cifs.spnego * * /usr/sbin/cifs.upcall %k create dns_resolver * * /usr/sbin/cifs.upcall %k # mount.cifs -o user=user1,uid=user1,sec=krb5 //hp-xw6400-02.lab.bos.redhat.com/public /mnt -vvv mount.cifs kernel mount options: ip=10.16.42.210,unc=\\hp-xw6400-02.lab.bos.redhat.com\public,sec=krb5,uid=501,ver=1,user=user1,pass=******** mount error(13): Permission denied Refer to the mount.cifs(8) manual page (e.g. man mount.cifs) and the log detail pls refer to below: fs/cifs/cifsfs.c: Devname: //hp-xw6400-02.lab.bos.redhat.com/public/ flags: 0 fs/cifs/connect.c: CIFS VFS: in cifs_mount as Xid: 46 with uid: 0 fs/cifs/connect.c: Username: user1 fs/cifs/connect.c: UNC: \\hp-xw6400-02.lab.bos.redhat.com\public ip: 10.16.42.210 fs/cifs/connect.c: Socket created fs/cifs/connect.c: sndbuf 50748 rcvbuf 87584 rcvtimeo 0x1b58 fs/cifs/connect.c: CIFS VFS: in cifs_get_smb_ses as Xid: 47 with uid: 0 fs/cifs/connect.c: Existing smb sess not found fs/cifs/connect.c: Demultiplex PID: 31614 fs/cifs/cifssmb.c: secFlags 0x8 fs/cifs/cifssmb.c: Kerberos only mechanism, enable extended security fs/cifs/transport.c: For smb_command 114 fs/cifs/transport.c: Sending smb: total_len 82 fs/cifs/connect.c: rfc1002 length 0xcc fs/cifs/cifssmb.c: Dialect: 2 fs/cifs/asn1.c: OID len = 7 oid = 0x1 0x2 0x348 0x1bb92 fs/cifs/asn1.c: OID len = 7 oid = 0x1 0x2 0x348 0xbb92 fs/cifs/asn1.c: OID len = 10 oid = 0x1 0x3 0x6 0x1 fs/cifs/asn1.c: Need to call asn1_octets_decode() function for cifs/hp-xw6400-02.lab.bos.redhat.com.REDHAT.COM fs/cifs/cifssmb.c: Signing disabled fs/cifs/cifssmb.c: negprot rc 0 fs/cifs/connect.c: Security Mode: 0x3 Capabilities: 0x8080f3fc TimeAdjust: 14400 fs/cifs/sess.c: sess setup type 4 fs/cifs/cifs_spnego.c: key description = ver=0x2;host=hp-xw6400-02.lab.bos.redhat.com;ip4=10.16.42.210;sec=krb5;uid=0x1f5;creduid=0x0;user=user1;pid=0x7b7c fs/cifs/transport.c: For smb_command 115 fs/cifs/transport.c: Sending smb: total_len 800 fs/cifs/connect.c: rfc1002 length 0x27 Status code returned 0xc000006d NT_STATUS_LOGON_FAILURE fs/cifs/netmisc.c: Mapping smb error code 5 to POSIX err -13 fs/cifs/misc.c: Null buffer passed to cifs_small_buf_release fs/cifs/sess.c: ssetup rc from sendrecv2 is -13 fs/cifs/sess.c: ssetup freeing small buf ffff8800018b3300 CIFS VFS: Send error in SessSetup = -13 fs/cifs/connect.c: CIFS VFS: leaving cifs_get_smb_ses (xid = 47) rc = -13 fs/cifs/connect.c: CIFS VFS: leaving cifs_mount (xid = 46) rc = -13 CIFS VFS: cifs_mount failed w/return code = -13
btw, This is my test enviroment: [root@hp-xw6400-02 ~]# uname -a Linux hp-xw6400-02.lab.bos.redhat.com 2.6.32-122.el6.x86_64 #1 SMP Wed Mar 9 23:54:34 EST 2011 x86_64 x86_64 x86_64 GNU/Linux [root@hp-xw6400-02 ~]# rpm -qa|grep nfs-utils nfs-utils-1.2.3-4.el6.x86_64 nfs-utils-lib-1.1.5-3.el6.x86_64 [root@hp-xw6400-02 ~]# rpm -qa|grep cifs-utils cifs-utils-4.8.1-1.el6.x86_64 [root@hp-xw6400-02 ~]# rpm -qa|grep samba samba-client-3.5.6-86.el6.x86_64 samba-winbind-clients-3.5.6-86.el6.x86_64 samba-3.5.6-86.el6.x86_64 samba-common-3.5.6-86.el6.x86_64 [root@hp-xw6400-02 ~]# rpm -qa|grep keyutils keyutils-libs-devel-1.4-1.el6.x86_64 keyutils-1.4-1.el6.x86_64 keyutils-libs-1.4-1.el6.x86_64 [root@hp-xw6400-02 ~]# rpm -qa|grep krb5 krb5-devel-1.9-6.el6.x86_64 krb5-libs-1.9-6.el6.x86_64 krb5-server-1.9-6.el6.x86_64 krb5-workstation-1.9-6.el6.x86_64
The cifs stuff looks fine. The server didn't like your credentials though: Status code returned 0xc000006d NT_STATUS_LOGON_FAILURE Is the server also a RHEL6 machine? If so, then you probably need to update the smb.conf -- the krb5 settings have changed in more recent samba versions. See smb.conf(5) for these options: dedicated keytab file kerberos method
An advisory has been issued which should help the problem described in this bug report. This report is therefore being closed with a resolution of ERRATA. For more information on therefore solution and/or where to find the updated files, please follow the link below. You may reopen this bug report if the solution does not work for you. http://rhn.redhat.com/errata/RHBA-2011-0569.html