dedicated keytab and need of machine account plain text password in pure Kerberos environment

Alexander Bokovoy ab at
Tue Nov 27 08:12:49 UTC 2018


I was looking the other day at making it easier to run Samba as a domain
member in FreeIPA domain. This is a configuration where a DC is another
Samba using LDAP-based storage with ipasam passdb module and 'security =
user'. It doesn't support client enrollment over DCE RPC but uses own
enrollment mechanism for IPA clients.

Previously, people took ipasam passdb module and configured it on the
clients pretty much how it is configured on IPA master itself:

	workgroup = IPA
	netbios name = IPA-CLIENT
	kerberos method = dedicated keytab
	dedicated keytab file = /etc/samba/samba.keytab
	create krb5 conf = no
	security = user
	passdb backend = ipasam:ldap://
	disable spoolss = yes
	ldapsam:trusted = yes
	ldap ssl = off
	ldap suffix = dc=ipa,dc=example,dc=com
	ldap user suffix = cn=users,cn=accounts
	ldap group suffix = cn=groups,cn=accounts
	ldap machine suffix = cn=computers,cn=accounts

'ipasam' passdb module uses GSSAPI to authenticate to LDAP so
effectively this is no different from IPA master itself. On IPA master
cifs/... principal has enough access rights to read NT hashes of users.
However, granting this level of access to IPA clients is highly
undesirable so I resisted to call this a supported configuration for
many years.

With recent Samba releases, we have consolidated all communication
between a domain member and a DC to winbindd. In a proper domain member
setup, winbindd would not need to have access to user's credentials as
authentication request would either be forwarded to a DC or a Kerberos
authentication would work if a client presented a service ticket. That,
indeed, works with a configuration where we use idmap_sss to handle user

	dedicated keytab file = FILE:/etc/samba/samba.keytab
	kerberos method = dedicated keytab
	server role = member server
	workgroup = IPA
	idmap config * : range = 10000-20000
	idmap config ipa : range = 1536000000-1536200000
	idmap config ipa : backend = sss
	idmap config * : backend = tdb

If you attempt to access a share on a system configured like this using
a password-based logon, smbclient will be smart enough to try GSSAPI and
locally generate a request to a service ticket, then use the service
ticket to talk to 

$ smbclient -s /dev/null -m SMB3 -d 4 -U admin at IPA.EXAMPLE.COM //`hostname`/shared
lp_load_ex: refreshing parameters
Initialising global parameters
rlimit_max: increasing rlimit_max (1024) to minimum Windows limit (16384)
pm_process() returned Yes
added interface ens3 ip=SOME-IPv6 bcast= netmask=ffff:ffff:ffff:ffff::
added interface ens3 ip=SOME-IPv4 bcast=... netmask=
added interface ens4 ip=SOME-IPv4 bcast=... netmask=
Client started (version 4.8.6).
Connecting to SOME-IPv6 at port 445
 session request ok
 negotiated dialect[SMB3_11] against server[]
got OID=1.2.840.48018.1.2.2
Enter admin at IPA.EXAMPLE.COM's password: 
GENSEC backend 'gssapi_spnego' registered
GENSEC backend 'gssapi_krb5' registered
GENSEC backend 'gssapi_krb5_sasl' registered
GENSEC backend 'spnego' registered
GENSEC backend 'schannel' registered
GENSEC backend 'naclrpc_as_system' registered
GENSEC backend 'sasl-EXTERNAL' registered
GENSEC backend 'ntlmssp' registered
GENSEC backend 'ntlmssp_resume_ccache' registered
GENSEC backend 'http_basic' registered
GENSEC backend 'http_ntlm' registered
GENSEC backend 'http_negotiate' registered
Starting GENSEC mechanism spnego
Starting GENSEC submechanism gse_krb5
 session setup ok
signed SMB2 message
signed SMB2 message
 tconx ok
Try "help" to get a list of possible commands.
smb: \> 

Unfortunately, that's about all it could do. The reason for this is
because Samba itself thinks it is not properly joined (no credentials in
the secrets.tdb), it has no machine password account credentials and
cannot talk to the DC. Never mind that we actually have our Kerberos key
available (cifs/ and can use those
credentials to authenticate our request to DC, since we have no domain
info in secrets.tdb, we are failing:

[2018/11/27 08:53:04.796386,  1, pid=1926, effective(0, 0), real(0, 0), class=auth] ../auth/credentials/credentials_secrets.c:413(cli_credentials_set_machine_account_db_ctx)
  Could not find machine account in secrets database: Failed to fetch
  machine account password for IPA from both secrets.ldb (Could not find
  entry to match filter: '(&(flatname=IPA)(objectclass=primaryDomain))' base: 'cn=Primary Domains': No such object: dsdb_search at ../source4/dsdb/common/util.c:4696) and from /var/lib/samba/private/secrets.tdb: NT_STATUS_CANT_ACCESS_DOMAIN_INFO
[2018/11/27 08:53:04.796469,  3, pid=1926, effective(0, 0), real(0, 0), class=winbind] ../source3/winbindd/winbindd_cm.c:667(cm_get_ipc_userpass)
  cm_get_ipc_userpass: No auth-user defined
[2018/11/27 08:53:04.796525,  5, pid=1926, effective(0, 0), real(0, 0), class=winbind] ../source3/winbindd/winbindd_cm.c:1144(cm_prepare_connection)
  connecting to (IPA, IPA.EXAMPLE.COM) with account [\] principal [(null)] and realm [IPA.EXAMPLE.COM]

Domain information cannot be set manually because it is only set during
the join time. If we were able to skip the actual join process and
define a 'fake' domain information, we might probably be able to utilize
our Kerberos credentials. However, there are still paths that require
plain-text machine account credentials. We also prefer using Kerberos
keys from secrets.tdb instead of a dedicated keytab if they are
available, making it potentially fragile when a dedicated keytab is

In past, Metze and Andreas tried to refactor this part of machine
account handling but since it was clearly getting too big effort at a
time, I'm looking for any additional suggestions how to do it here.

My current idea is to create a 'net ipa join' mode which only writes
down the details of a domain information in secrets.tdb and (re)generates
a Kerberos key for cifs/`hostname` -- a host principal on an IPA client has
permissions to manage Kerberos services on the same host by default, so
using host keytab, we are able to bootstrap ourselves. In FreeIPA one
can optionally specify actual key when generating a keytab for a
Kerberos service, so while this is undesirable in a general case, we can
make a random clear text that is sufficiently strong to be equal to what
FreeIPA produces on its end.

This mode can also automatically pick up idmap range and domain details
as host keytab is also enough to retrieve those details from IPA master.

My goal is to bring down creating a Samba setup on IPA client to a
following sequence:

# ipa-client-install
# net ipa join

where 'net ipa join' would automatically generate a default smb.conf, a
kerberos keytab for cifs/... service and would populate secrets.tdb with
all required details.

Technically, the sequence of operations described above doesn't require
anything but a use of existing tools on IPA client (ipa-getkeytab) and
normal Kerberos operations we have already supported in Samba, so
writing such mode should be easy. It would not need to have a compile
time dependency to IPA tools, though to test one needs those. But I'd
like to hear other opinions.

/ Alexander Bokovoy

More information about the samba-technical mailing list