[Patches] avoid krb5_ccache ccselect magic (bug #12480)
ab at samba.org
Fri Dec 30 07:43:30 UTC 2016
On pe, 30 joulu 2016, Stefan Metzmacher wrote:
> Am 30.12.2016 um 00:02 schrieb Stefan Metzmacher:
> > Hi Alexander,
> >>> From 69723ac36d31effd5c1949de0ce693d2face7b2c Mon Sep 17 00:00:00 2001
> >>> From: Stefan Metzmacher <metze at samba.org>
> >>> Date: Thu, 22 Dec 2016 08:49:38 +0100
> >>> Subject: [PATCH 3/3] s3:librpc/gse: make use of gss_krb5_import_cred() instead
> >>> of gss_acquire_cred()
> >>> This avoids the usage of the ccselect_realm logic in MIT krb5,
> >>> which leads to unpredictable results.
> >>> The problem is the usage of gss_acquire_cred(), that just creates
> >>> a credential handle without ccache.
> >>> As result gss_init_sec_context() will trigger a code path
> >>> where it use "ccselect" plugins. And the ccselect_realm
> >>> module just chooses a random ccache from a global list
> >>> where the realm of the provides target principal matches
> >>> the realm of the ccache user principal.
> >>> In the winbindd case we're using MEMORY:cliconnect to setup
> >>> the smb connection to the DC. For ldap connections we use
> >>> MEMORY:winbind_ccache.
> >>> The typical case is that we do the smb connection first.
> >>> If we try to create a new ldap connection, while the
> >>> credentials in MEMORY:cliconnect are expired,
> >>> we'll do the required kinit into MEMORY:winbind_ccache,
> >>> but the ccselect_realm module will select MEMORY:cliconnect
> >>> and tries to get a service ticket for the ldap server
> >>> using the already expired TGT from MEMORY:cliconnect.
> >>> The solution will be to use gss_krb5_import_cred() and explicitly
> >>> pass the desired ccache, which avoids the ccselect logic.
> >>> We could also use gss_acquire_cred_from(), but that's only available
> >>> in modern MIT krb5 versions, while gss_krb5_import_cred() is available
> >>> in heimdal and all supported MIT versions (>=1.9).
> >>> As far as I can see both call the same internal function in MIT
> >>> (at least for the ccache case).
> >>> BUG: https://bugzilla.samba.org/show_bug.cgi?id=12480
> >>> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> >>> Reviewed-by: Andreas Schneider <asn at samba.org>
> >> This is because memory credentials cache in MIT Kerberos implements
> >> collection traversal API and has no way to toggle the behavior to stick
> >> to a single ccache instead of traversing sequentially the whole
> >> collection. I guess this was known to core MIT developers since 2005
> >> when Tom Yu implemented cursor API in the memory ccache backend but
> >> wasn't really realized by external community when MIT Kerberos 1.10
> >> officially added support for credentials collection based on the
> >> collection traversal API. The documentation (doc/basic/ccache_def.rst)
> >> claims that
> >> =============
> >> Credential cache collections are new in release 1.10, with support
> >> from the **DIR** and **API** ccache types. Starting in release 1.12,
> >> collections are also supported by the **KEYRING** ccache type.
> >> Collections are supported by the **KCM** ccache type in release 1.13.
> >> =============
> >> So MEMORY ccache type should not be treated as the collection but it
> >> is. I guess we have to raise this question to the MIT Kerberos
> >> development team and see how can we fix it.
> >> API ccache type is a Windows-only thing.
> >> Until there is a fix in MIT Kerberos for MEMORY ccache type not being
> >> treated as a credentials caches collection, I fear we have to include
> >> this patch.
> > I guess for some application it might be useful to use all available
> > credential caches. If the application runs as one logical user
> > which has multiple identities in multiple independed realms.
> > And I don't think this should change.
> I guess the application needs to explicitly open all individual
> ccaches which will together form the global collection.
> Is that correct? Or is it possible to specify something like
> that magically opens more than one cache at a time?
There is no such support and application does not need to open them,
ccache backend does. If ccache type supports collection traversal,
specifying the collection is enough. FILE does not support collection
traversal, DIR is, so specifying KRB5CCNAME=DIR:/tmp/user2_realmB.ccache_dir
is all you need. Same with KEYRING -- the scope is defined by the
Starting with release 1.12 the *KEYRING* type supports collections.
The following new residual forms were added:
* KEYRING:session:name - session keyring
* KEYRING:user:name - user keyring
* KEYRING:persistent:uidnumber - persistent per-UID collection.
Unlike the user keyring, this collection survives
after the user logs out, until the cache credentials expire.
This type of ccache requires support from the kernel;
otherwise, it will fall back to the user keyring.
The collection cache traversal for selection of the closest realm is part
of GSSAPI logic. If you are using plain krb5 API, you have to explicitly
switch the ccache in the collection or otherwise you'd be dealing with
the default principal from the default ccache in the collection as would
the ccache backend see it.
In some sense, ccache backends that support collections exhibit few
form of persistency (over a process execution run time). You cannot
manipulate MEMORY ccaches with external tools like kswitch/kinit/klist
because you'd then would be addressing something in their own address
space, not tangible enough to survive over their execution period. So
there is little sense to have user-accessible MEMORY ccache collections.
As for application being able to organize its MEMORY ccaches into a
collection that could be affected by the GSSAPI ccselect modules to
choose the ccache to use for GSSAPI operation, that is a different
topic -- this might be useful, indeed, but at the very least current
behavior is undocumented and very unexpected. Most applications I saw
used MEMORY ccaches as temporary ones when there is no need to share
them with other processes and considered them isolated from each other
/ Alexander Bokovoy
More information about the samba-technical