Recent kerberos refactoring
ab at samba.org
Fri Apr 13 04:49:05 MDT 2012
On Fri, Apr 13, 2012 at 12:51, Andrew Bartlett <abartlet at samba.org> wrote:
> On Fri, 2012-04-13 at 12:13 +0300, Alexander Bokovoy wrote:
>> On Fri, Apr 13, 2012 at 11:21, Andrew Bartlett <abartlet at samba.org> wrote:
>> > On Fri, 2012-04-13 at 08:05 +0300, Alexander Bokovoy wrote:
>> >> What is more important here is a logic that pulls server-side code
>> >> into client-side libraries. For example, in source4/auth/, there are
>> >> auth_session, auth4_sam, and pyauth subsystems that require
>> >> server-side code. auth_session is pulled into gensec_schannel and that
>> >> one is pulled into libnet, a pure client side library now that I
>> >> separated extract_keytab code which was only used in python bindings
>> >> to libnet and which took HDB driver in, together with Heimdal KDC
>> >> code.
>> > This is probably best resolved by making gensec_schannel a plugin.
>> > That's why gensec accepts plugins, to break silly dependency chains like
>> > this.
>> Could you please convert it to a plugin?
> Removing 'internal_module=True' from the gensec_schannel build rule
> should to it.
>> Talking about plugins, there is another issue. Which plugins are
>> selected by gensec is affected by the order in which modules are
> In gensec_init the plugins are sorted. This sorts by the declared
> priority. Are you finding any plugins in our build that are changing in
> order? If so, adding a strcmp() to the gensec_sort() should fix it.
Here is how it looks on my test system:
GENSEC backend 'gssapi_spnego' registered
GENSEC backend 'gssapi_krb5' registered
GENSEC backend 'gssapi_krb5_sasl' registered
GENSEC backend 'sasl-DIGEST-MD5' registered
GENSEC backend 'schannel' registered
GENSEC backend 'spnego' registered
GENSEC backend 'ntlmssp' registered
GENSEC backend 'krb5' registered
GENSEC backend 'fake_gssapi_krb5' registered
is this the correct order you have envisioned?
>> > I have been slowly working towards this. For example, gensec shouldn't
>> > need the client or server databases, it should be handled by either the
>> > supplied cli_credentials or auth4_context.
>> auth_generate_session_info() wants ldb context to optionally unroll
>> nested groups using dsdb code (samdb). Some callers from client side
>> access it directly and those do it with NULL ldb context. But few
>> others it are going through auth_context_create_methods() first and
>> all but one pass NULL, asking for a system session. This also means it
>> will try to connect to ldb instance regardless whether it is there or
>> not. I think this is one place where you could go further and remove
>> ldb context from auth_generate_session_info() signature, replacing it
>> by a structure that would be initialized by server or client
>> environment differently, passing callbacks and proper data for them
>> within a structure. This way dsdb-calling code could be isolated into
>> a callback that only used when there is a need for it (client running
>> on server or pure server code) and direct linking is also avoided.
> Where is auth_generate_session_info() being called from that is a
> problem, aside from the schannel server (and we already discussed how to
> deal with that).
> I'm happy to help, but I'm having trouble getting to specifics here.
source4/auth/pyauth.c: nt_status =
auth_context_create_methods(mem_ctx, methods, ev,
source4/utils/ntlm_auth.c: nt_status =
auth_context_create_methods() calls directly to
auth_generate_session_info() with potentially uninitialized ldb
pointer passed from py_auth_context_new(), asking for a crash. This is
easy to fix.
However, for Python bindings to auth subsystem I'd love to see it
separated as it brings auth_generate_session_info() and samdb
dependency into a client code that doesn't need it. Client code is not
always supposed to be run with root privileges.
>> >> Or split libraries even more. For
>> >> example, credentials_secrets.c operates on server side and it is
>> >> folded into pycredentials, Python bindings for credentials library
>> >> which is necessary for client operations on any Python client. I'd
>> >> rather separated it, as well as POPT_CREDENTIALS subsystem which in
>> >> addition is pulled into WMI sample client which is definitely not
>> >> supposed to be running only on Samba4 server.
>> > credentials_secrets is also used on the client, as you can (including in
>> > the python bindings) obtain credentials as the local machine account.
>> I'd rather separated this specific use case into a different library
>> or even module and loaded it dynamically. In python code you can
>> easily achieve that, see how I moved extract_keytab to a separate
>> submodule that goes and affixes the method back into the net.Net
> Why is the credentials code using ldb a problem? I understand the other
> issues, and have been working to resolve them for some time, but bare
> ldb seems a reasonable dependency for a client lib, given the
You seem to assume that client code only runs under root privileges
and therefore can get access to the ldb. It is not really a case.
However, these seems to be minor points, I can live with this
>> > I agree that this area is tricky, but with patience and co-operation I'm
>> > quite certain we can find an acceptable way though this.
>> Yes, let's fix immediate problems discussed above, this will allow us
>> to cleanly separate client and server code. As next step we would do
>> better distinction between client and client-on-server side code.
>> We also need to look over Kerberos code and see what could be updated
>> to use as much GSSAPI as possible to avoid going deep into raw
>> Kerberos libraries details, at least on the client side. It should be
>> easier now we have decided to define MIT krb5 baseline that supports
>> most of required functionality.
> Yes, this needs to be done in the Samba3 SMB client. It needs to be
> upgraded to use gensec for GSSAPI and SPNEGO, just like the RPC client
> already does. To do that, we preferably need to unify the ntlmssp
> client modules, importing the 'ask winbind' credential cache code into a
> common ntlmssp client (as a flag on the cli_credentials I think).
We also need to unify all credential caches used around in samba
daemons. The situation when root's default credentials cache is in use
and affected by Samba isn't really ideal. We need to make it simpler
by using per-daemon credential caches maintained globally.
>> I'd like to get to the point that client libraries provided by
>> source4/ and source3/ code base could be compiled against
>> system-provided MIT krb5 libraries where possible (barring
>> functionality that requires accessing HDB). Right now even with
>> linking scripts source3/ gets embedded heimdal libraries linked and
>> then linked against system libldap libraries which are using system
>> MIT krb5 libraries -- as result, I can't really use GSSAPI with a
>> keytab produced by MIT krb5 as described in another thread where I
>> tried to get to authenticate to LDAP with keytab only.
> I thought the problem in the other thread was mixing calls between the
> two libraries (calling a function that wasn't implemented in Heimdal).
> The default 'FILE' credential cache format is compatible btw. If not,
> I'm sorry I don't understand exactly what the problem is here. We
> successfully run dlz_bind9 based on Samba4 and Heimdal in a MIT-linked
I'd love to see suggestion how to accomplish that task (load specific
key from a keytab and use it for GSSAPI) both in MIT and Heimdal.
However, the real issue for my case will be the fact that MIT and
Heimdal use different methods to store S4U2Proxy information so a
ticket obtained by a client via S4U2Proxy mechanism in MIT environment
(httpd with mod_auth_kerb) and used to talk to Heimdal-linked smbd via
Heimdal-linked samba4 python bindings is not recognized properly. That
is what killing my cross-realm trusts work right now. The only real
solution to that is to be able to link source3/ and python bindings
against system-provided MIT krb5 libraries.
/ Alexander Bokovoy
More information about the samba-technical