Recent kerberos refactoring

Alexander Bokovoy ab at
Fri Apr 13 03:13:18 MDT 2012

On Fri, Apr 13, 2012 at 11:21, Andrew Bartlett <abartlet at> 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?

Talking about plugins, there is another issue. Which plugins are
selected by gensec is affected by the order in which modules are

Static registration of modules in samba4 is done via
buildtools/wafsamba/ which generates
-DSTATIC_foo_MODULES= define per module subsystem. The order depends
on Python implementation as waf uses dictionary to store
INIT_FUNCTIONS. Dictionaries do not guarantee fixed ordering and you
can't really predict that on all platforms all Python implementations
behave the same way. As result, there is no guarantee all functions
are ordered properly.

This needs to be fixed in add_init_functions() by first ordering
subsystems deterministically.

In case of dynamic modules loading, the ordering depends on file
system behavior. Unfortunately, POSIX does not enforce specific
behavior on opendir() and file systems are not required to give
alphabetical or any other specific ordering. This especially true with
advanced Linux file systems which use B*-tree variants to store inode
information, there is no guarantee of ordering at all.

> If that isn't enough, we can call
> auth4_context->get_user_info_dc_principal with a DN of <SID=S-1-5-7> and
> have the implementation of that function pointer look for the special DN
> and create the anonymous token there.
Might work as well.

>> Moving further, auth/gensec now requires auth_system_session which
>> requires auth_session and pulls samdb from Samba4 server-side which,
>> again, links in auth_session and auth4_sam. Besides being cyclic, it
>> pulls samdb linking into libsmb in source3.
> This (auth_system_session) appears not to be a required dependency of
> gensec, and I certainly worked to avoid gensec depending on samdb
> directly in that way.  That is why the auth4_context has such odd extra
> function pointers.  I'll push the removal with some real patches if you
> don't get to it first.
Please do it. I'll have time for this part probably next week only,
need to clean up my other queue.

>> These dependencies need to be fixed. In most cases a solution could be
>> in making interfaces clear of server-specific arguments and instead
>> either pass a callback where required or allow using an "object" that
>> encapsulates proper callbacks and states and two initializers: for
>> server-side and client-side uses.
> 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.

>> 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

> 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.

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.
/ Alexander Bokovoy

More information about the samba-technical mailing list