cifs-utils, Linux cifs kernel client and gssproxy
by Weiser, Michael
Hello,
I have a use-case for authentication of Linux cifs client mounts without the user being present (e.g. from batch jobs) using gssproxy's impersonation feature with Kerberos Constrained Delegation similar to how it can be done for NFS[1].
My understanding is that currently neither the Linux cifs kernel client nor cifs-utils userland tools support acquiring credentials using gssproxy. The former uses a custom upcall interface to talk to cifs.spnego from cifs-utils. The latter then goes looking for Kerberos ticket caches using libkrb5 functions, not GSSAPI, which prevents gssproxy from interacting with it.[2]
From what I understand, the preferred method would be to switch the Linux kernel client upcall to the RPC protocol defined by gssproxy[3] (as has been done for the Linux kernel NFS server already replacing rpc.svcgssd[4]). The kernel could then, at least optionally, talk to gssproxy directly to try and obtain credentials.
Failing that, cifs-utils' cifs.spnego could be switched to GSSAPI so that gssproxy's interposer plugin could intercept GSSAPI calls and provide them with the required credentials (similar to the NFS client rpc.gssd[5]).
Assuming my understanding is correct so far:
Is anyone doing any work on this and could use some help (testing, coding)?
What would be expected complexity and possible roadblocks when trying to make a start at implementing this?
Or is the idea moot due to some constraint or recent development I'm not aware of?
I have found a recent discussion of the topic on linux-cifs[6] which provided no definite answer though.
As a crude attempt at an explicit userspace workaround I tried but failed to trick smbclient into initialising a ticket cache using gssproxy for cifs.spnego to find later on.
Is this something that could be implemented without too much redundant effort (or should already work, perhaps using a different tool)?
[1] https://github.com/gssapi/gssproxy/blob/main/docs/NFS.md#user-impersonati...
[2] https://pagure.io/gssproxy/issue/56
[3] https://github.com/gssapi/gssproxy/blob/main/docs/ProtocolDocumentation.md
[4] https://github.com/gssapi/gssproxy/blob/main/docs/NFS.md#nfs-server
[5] https://github.com/gssapi/gssproxy/blob/main/docs/NFS.md#nfs-client
[6] https://www.spinics.net/lists/linux-cifs/msg20182.html
--
Thanks,
Michael
1 year, 7 months
Released 0.8.4
by Robbie Harwood
Michael Weiser (1):
- Handle impersonation of oneself
Robbie Harwood (11):
- Document config file non-merging
- Initialize our epoll\_event structures
- Avoid leak of special mechs in gss\_mech\_interposer()
- Fix leak of mech OID in gssi\_inquire\_context()
- Make syslog of call status configurable
- Fix order of socket ev update in init\_sockets()
- Eliminate some leftover dead code
- Update EXTRA\_DIST for missing test files
- Fix warnings in configure programs
- Update vendored ax\_pthread.m4
- Switch to calling distcheck in CI
Simo Sorce (19):
- Silence gcc on truncation of debug messages
- Work around incorrect gcc restrict warning on asprintf
- Add testlib method to wait for gssproxy reconfiguration
- Expand use of global static mechs to conform to SPI
- Initialize interposed mech list without allocation
- Make sure to free also the remote ctx struct
- Use the correct function to free unused creds
- Fix leaks in our test suite itself
- Always free ciphertext data in gp\_encrypt\_buffer
- Return static oids for naming functions
- Avoid unnecessary allocation in gpm\_inquire\_mechs\_for\_name()
- Use static OIDs in gss\_inquire\_context()
- Add a hidden debug tool to gssproxy
- Implement remoting gss\_localname function.
- Add new test unit for name functions
- Fix various test issues
- Update .gitignore file
- Always shortcircuit mech\_invoke to the local mech
- Clarify mech\_for\_saslname implementation note
Thanks,
--Robbie
2 years, 4 months
[gssapi/gssproxy] 5ba3c4: Handle impersonation of oneself
by mw-a
Branch: refs/heads/main
Home: https://github.com/gssapi/gssproxy
Commit: 5ba3c4cf173824ec61db2886ef2c6b654a1e54be
https://github.com/gssapi/gssproxy/commit/5ba3c4cf173824ec61db2886ef2c6b6...
Author: Michael Weiser <michael.weiser(a)atos.net>
Date: 2021-01-12 (Tue, 12 Jan 2021)
Changed paths:
M src/gp_creds.c
Log Message:
-----------
Handle impersonation of oneself
When trying to impersonate the user which has been selected as impersonation
credential, MIT krb5 returns error:
GSSX_RES_ACQUIRE_CRED( status: { 851968 { 1 2 840 113554 1 2 2 } 2529638928
"Unspecified GSS failure. Minor code may provide more information" "KDC has no
support for padata type" [ ] } output_cred_handle: <Null> )
An attempt to impersonate oneself is not allowed. Also, it is likely not even
necessary: If we can get impersonation credentials from credstores, we can at
least try to short circuit and get actual user credentials the same way.
With this patch it becomes possible to delegate the acquisition of e.g. cifs
mount credentials from cifs.upcall into gssproxy and use the host identity
(e.g. HOSTNAME$@REALM of AD) while it is also being selected as impersonation
credential due to the order of keys in the keytab.
Signed-off-by: Michael Weiser <michael.weiser(a)atos.net>
2 years, 4 months
Re: cifs-utils, Linux cifs kernel client and gssproxy
by Simo
Adding back missing people in CC, as I incorrectly pressed reply-to-
list and lost them.
On Thu, 2021-01-07 at 08:37 -0500, Simo via samba-technical wrote:
> On Thu, 2021-01-07 at 11:04 +0000, Weiser, Michael via samba-
> technical
> wrote:
> > Hello Simo,
> > Hello Steve,
> >
> > > If something is needed in the short term, I thjink the quickest
> > > course
> > > of action is indeed to change the userspace helper to use gssapi
> > > function calls, so that they can be intercepted like we do for
> > > rpc.gssd
> > > (nfs client's userspace helper).
> >
> > To get the ball rolling and give people (including myself and
> > client)
> > something to play with I went that route and extended cifs.upcall
> > to
> > fall back to GSS-API if no ticket cache nor keytab can be found for
> > the user. An unpolished PoC patch is attached. (Sorry, for not
> > putting it inline, have to rock the groupware at work. I will try
> > to
> > sort that once we've agreed this is the/a way to go.)
> >
> > With that patch applied, I can do a multiuser cifs mount using the
> > system keytab and machine identity as usual and then have users
> > access the mount using impersonated credentials from gssproxy.
> > Quick
> > demo:
> >
> > [root@fedora33 ~]# umount /mnt
> > [root@fedora33 ~]# mount -o sec=krb5,multiuser,user=FEDORA33\$
> > //dc/share /mnt
> > [root@fedora33 ~]# ls -la /mnt
> > total 0
> > drwxr-xr-x. 2 root root 0 Jan 7 10:20 .
> > dr-xr-xr-x. 18 root root 238 Jan 6 13:59 ..
> > -rwxr-xr-x. 1 root root 0 Jan 5 17:02 bar
> > [root@fedora33 ~]# klist
> > klist: Credentials cache keyring 'persistent:0:krb_ccache_WZh7W8n'
> > not found
> > [root@fedora33 ~]#
> >
> > [adsuser@fedora33 ~]$ kdestroy
> > [adsuser@fedora33 ~]$ echo test > /mnt/test
> > [adsuser@fedora33 ~]$ cat /mnt/test
> > test
> > [adsuser@fedora33 ~]$ klist
> > klist: Credentials cache keyring
> > 'persistent:1618201110:krb_ccache_SrGqT3F' not found
> > [adsuser@fedora33 ~]$
> >
> > Server-side permissions are enforced:
> >
> > [m@fedora33 ~]$ cat /mnt/test
> > test
> > [m@fedora33 ~]$ echo mytest > /mnt/test
> > -bash: /mnt/test: Permission denied
> > [m@fedora33 ~]$ klist
> > klist: Credentials cache keyring 'persistent:1000:1000' not found
> > [m@fedora33 ~]$
> >
> > The gssproxy config for this configures a cifs-specific socket and
> > enables impersonation for any user id:
> >
> > [root@fedora33 ~]# cat /etc/gssproxy/99-cifs.conf
> > [service/cifs]
> > mechs = krb5
> > socket = /var/lib/gssproxy/cifs.sock
> > cred_store = keytab:/etc/krb5.keytab
> > cred_usage = initiate
> > euid = 0
> > impersonate = yes
> > allow_any_uid = yes
> >
> > And request-key config for cifs.spnego enables use of gssproxy and
> > the service-specific socket through environment variables:
> >
> > [root@fedora33 ~]# cat /etc/request-key.d/cifs.spnego.conf
> > create cifs.spnego * * /usr/bin/env GSS_USE_PROXY=yes
> > GSSPROXY_SOCKET=/var/lib/gssproxy/cifs.sock /usr/sbin/cifs.upcall
> > %k
> >
> > (I see that nfs-utils' gssd does the same by setting the variables
> > itself based on command line options. That could easily be done
> > here
> > as well.)
> >
> > User FEDORA33$ (the computer object) needs to be enabled for
> > delegation to service cifs. I've tested with a Fedora 33 client and
> > Windows 2016 Active Directory server.
> >
> > The patch is against current cifs-utils HEAD. It is lacking all the
> > autoconf trimmings and intentionally forgoes reindents of existing
> > code for clarity of what's being touched.
> >
> > What do you think?
>
> Sounds great!
>
> > > Unfortunately I do not have the cycles to work on that myself at
> > > this
> > > time :-(
> >
> > I have a client in very tangible need of this functionality who is
> > a
> > RedHat customer. Would it be helpful if they were to open a case
> > with
> > Redhat on this?
>
> Yes!
> CC me if you need to.
>
> > As an extension the above (but not to distract from the focus of
> > getting something to work at all first):
> >
> > I rather accidentally also played around with delegating retrieval
> > of
> > the mount credentials into gssproxy as well (due to not realising
> > that username=FEDORA33$ would just activate the keytab codepath in
> > cifs.upcall).
> >
> > This can be done by leaving out the username from the mount
> > command,
> > marking euid 0 as trusted for access to the keytab in gssproxy and
> > adding a fallback principal to the gssproxy config (because
> > cifs.upcall in this case does not submit a desired name for the
> > credential):
> >
> > [root@fedora33 ~]# mount -o sec=krb5,multiuser //dc/share /mnt
> > [root@fedora33 ~]# cat /etc/gssproxy/99-cifs.conf
> > [service/cifs]
> > mechs = krb5
> > socket = /var/lib/gssproxy/cifs.sock
> > cred_store = keytab:/etc/krb5.keytab
> > cred_usage = initiate
> > euid = 0
> > trusted = yes
> > impersonate = yes
> > krb5_principal = cifs-mount
> > allow_any_uid = yes
> >
> > While this works, it requires a separate user who would then
> > carefully need to be kept out of any sensitive file access groups.
> >
> > When trying to use the machine identity FEDORA33$ instead, I ran
> > into
> > a peculiar error from the AD KDC:
> >
> > [root@fedora33 ~]# cat /etc/gssproxy/99-cifs.conf
> > [service/cifs]
> > mechs = krb5
> > socket = /var/lib/gssproxy/cifs.sock
> > cred_store = keytab:/etc/krb5.keytab
> > cred_usage = initiate
> > euid = 0
> > trusted = yes
> > impersonate = yes
> > krb5_principal = FEDORA33$
> > allow_any_uid = yes
> > [root@fedora33 ~]# gssproxy -i -d &
> > [2] 3814
> > [root@fedora33 ~]# [2021/01/07 10:01:10]: Debug Enabled (level: 1)
> > [2021/01/07 10:01:10]: Service: nfs-server, Keytab:
> > /etc/krb5.keytab,
> > Enctype: 17
> > [2021/01/07 10:01:10]: Service: cifs, Keytab: /etc/krb5.keytab,
> > Enctype: 17
> > [2021/01/07 10:01:10]: Service: nfs-client, Keytab:
> > /etc/krb5.keytab,
> > Enctype: 17
> > [2021/01/07 10:01:10]: Client [2021/01/07 10:01:10]:
> > (/usr/sbin/gssproxy) [2021/01/07 10:01:10]: connected (fd =
> > 11)[2021/01/07 10:01:10]: (pid = 3814) (uid = 0) (gid =
> > 0)[2021/01/07 10:01:10]: (context =
> > system_u:system_r:kernel_t:s0)[2021/01/07 10:01:10]:
> >
> > [root@fedora33 ~]# mount -o sec=krb5,multiuser //dc/share /mnt
> > [2021/01/07 10:01:13]: Client [2021/01/07 10:01:13]:
> > (/usr/sbin/cifs.upcall) [2021/01/07 10:01:13]: connected (fd =
> > 12)[2021/01/07 10:01:13]: (pid = 3824) (uid = 0) (gid =
> > 0)[2021/01/07 10:01:13]: (context =
> > system_u:system_r:kernel_t:s0)[2021/01/07 10:01:13]:
> > [CID 12][2021/01/07 10:01:13]: gp_rpc_execute: executing 6
> > (GSSX_ACQUIRE_CRED) for service "cifs", euid: 0,socket:
> > /var/lib/gssproxy/cifs.sock
> > gssproxy[3814]: (OID: { 1 2 840 113554 1 2 2 }) Unspecified GSS
> > failure. Minor code may provide more information, KDC has no
> > support
> > for padata type
> > [CID 12][2021/01/07 10:01:13]: gp_rpc_execute: executing 8
> > (GSSX_INIT_SEC_CONTEXT) for service "cifs", euid: 0,socket:
> > /var/lib/gssproxy/cifs.sock
> > gssproxy[3814]: (OID: { 1 2 840 113554 1 2 2 }) Unspecified GSS
> > failure. Minor code may provide more information, KDC has no
> > support
> > for padata type
> > [CID 12][2021/01/07 10:01:13]: gp_rpc_execute: executing 6
> > (GSSX_ACQUIRE_CRED) for service "cifs", euid: 0,socket:
> > /var/lib/gssproxy/cifs.sock
> > gssproxy[3814]: (OID: { 1 2 840 113554 1 2 2 }) Unspecified GSS
> > failure. Minor code may provide more information, KDC has no
> > support
> > for padata type
> > [CID 12][2021/01/07 10:01:13]: gp_rpc_execute: executing 8
> > (GSSX_INIT_SEC_CONTEXT) for service "cifs", euid: 0,socket:
> > /var/lib/gssproxy/cifs.sock
> > gssproxy[3814]: (OID: { 1 2 840 113554 1 2 2 }) Unspecified GSS
> > failure. Minor code may provide more information, KDC has no
> > support
> > for padata type
> > mount error(126): Required key not available
> > Refer to the mount.cifs(8) manual page (e.g. man mount.cifs) and
> > kernel log messages (dmesg)
> >
> > With more debugging it appears that gssproxy tries to impersonate
> > user FEDORA33$ with a credential which is also for FEDORA33$. After
> > further testing it seems this is generally not allowed or just not
> > working due to never being tested because it is unnecessary: If we
> > can acquire a impersonation credential for that identity we should
> > also be able to get the actual access credential as well.
>
> Sounds like a bug in gss-proxy, can you file a github issue/PR ?
> We should certainly shortcut the impersonation if we already have a
> valid credential.
>
> > From looking at the nfs-utils gssd code it appears the only reason
> > it
> > hasn't run into this case yet is because it handles the machine
> > credentials itself using krb5 functions.
> >
> > The second attached patch against current gssproxy HEAD adds that
> > distinction and makes this case work as an optional extension with
> > fallback into the default codepath on error.
> >
> > Does that make sense?
>
> Yes the patch looks good!
>
> > Is it sane, security wise, do you think?
>
> Sane, you are just avoiding a useless call in a special case.
>
> Simo.
>
>
2 years, 5 months