mirror of
https://github.com/samba-team/samba.git
synced 2024-12-28 07:21:54 +03:00
26421fb2dc
We do need the gsskrb5_get_initiator_subkey() routine. But we should
ensure that we do always get a valid key, to prevent any segfaults.
Without this code, we get a different session key compared with
Win2k3, and so kerberised smb signing fails.
Andrew Bartlett
(This used to be commit cfd0df16b7
)
467 lines
17 KiB
Plaintext
467 lines
17 KiB
Plaintext
AllowedWorkstationNames and Krb5
|
|
--------------------------------
|
|
|
|
Microsoft uses the clientAddresses *multiple value* field in the krb5
|
|
protocol (particularly the AS_REQ) to communicate it's netbios name.
|
|
This is (my guess) to permit the userWorkstations field to work.
|
|
|
|
The KDC I imagine checks the netbios address against this value, in
|
|
the same way that the Samba server does this.
|
|
|
|
The checking of this implies a little of the next question:
|
|
|
|
Is a DAL the layer we need?
|
|
---------------------------
|
|
|
|
Looking at what we need to pass around, I start to seriously wonder if
|
|
the DAL is even the right layer - we seem to want to create an account
|
|
authorization abstraction layer - is this account permitted to login to
|
|
this computer, at this time?
|
|
|
|
This information in AD is much richer than the Heimdal HDB, and it
|
|
seems to make sense to do AD-specific access control checks in an
|
|
AD-specific layer, not in the back-end agnostic server.
|
|
|
|
Because the DAL only reads in the principalName as the key, it has
|
|
trouble performing access control decisions on things other than the
|
|
name.
|
|
|
|
I'll be very interested if the DAL really works for eDirectory too.
|
|
Perhaps all we need to do is add in the same kludges as we have in
|
|
Samba 3.0 for eDirectory. Hmm...
|
|
|
|
That said, the current layer provides us with a very good start, and
|
|
any redefinition would occour from that basis.
|
|
|
|
|
|
GSSAPI layer requirements
|
|
-------------------------
|
|
|
|
Welcome to the wonderful world of canonicalisation
|
|
|
|
The MIT GSSAPI libs do not support kinit returning a different
|
|
realm to what the client asked for, even just in case differences.
|
|
|
|
Heimdal has the same problem, and this applies to the krb5 layer, not
|
|
just gssapi.
|
|
|
|
We need to test if the canonicalisation is controlled by the KDCOption
|
|
flags, windows always sends the Canonicalize flags
|
|
|
|
Old Clients (samba3 and HPUX clients) uses 'selfmade' gssapi/krb5
|
|
for using it in the CIFS session setup. Because they use krb5_mk_req()
|
|
they get a chksum field depending on the encryption type, but that's wrong
|
|
for GSSAPI (see rfc 1964 section 1.1.1). The Cheksum type 8003
|
|
should be used in the Authenticator of the AP-REQ! That allows the channel bindings,
|
|
the GCC_C_* req_flags and optional delegation tickets to be passed from the client to the server.
|
|
Hower windows doesn't seems to care about if the checksum is of the wrong type,
|
|
for CIFS SessionSetups, it seems that the req_flags are just set to 0.
|
|
So this can't work for LDAP connections with sign or seal, or for any DCERPC
|
|
connection.
|
|
|
|
So we need to also support old clients!
|
|
|
|
Principal Names, long and short names
|
|
-------------------------------------
|
|
|
|
As far as servicePrincipalNames are concerned, these are not
|
|
canonicalised, except as regards the realm in the reply. That is, the
|
|
client gets back the principal it asked for, with the realm portion
|
|
'fixed' to uppercase, long form.
|
|
|
|
The short name of the realm seems to be accepted for at least AS_REQ
|
|
operations, but because the server performs canonicalisation, this
|
|
causes pain for current client libraries.
|
|
|
|
The canonicalisation of names matters not only for the KDC, but also
|
|
for code that has to deal with keytabs.
|
|
|
|
We also need to handle type 10 names (NT-ENTERPRISE), which are a full
|
|
principal name in the principal field, unrelated to the realm.
|
|
|
|
HOST/ Aliases
|
|
-------------
|
|
|
|
There is another post somewhere (ref lost for the moment) that details
|
|
where in active directory the list of stored aliases for HOST/ is.
|
|
This should be read, parsed and used to allow any of these requests to
|
|
use the HOST/ key.
|
|
|
|
For example, this is how HTTP/, DNS/ and CIFS/ can use HOST/ without
|
|
any explicit entry.
|
|
|
|
|
|
Jean-Baptiste.Marchand@hsc.fr reminds me:
|
|
|
|
> This is the SPNMappings attribute in Active Directory:
|
|
|
|
> http://msdn.microsoft.com/library/en-us/adschema/adschema/a_spnmappings.asp
|
|
|
|
We implement this in hdb-ldb.
|
|
|
|
Implicit names for Win2000 Accounts
|
|
-----------------------------------
|
|
|
|
Despite not having a DNS name, nor a servicePrincipalName on accounts
|
|
created by computers running win2000, it appears we are expected to
|
|
have an implicit mapping from host/computer.full.name and
|
|
host/computer to it's entry.
|
|
|
|
Returned Salt for PreAuthentication
|
|
-----------------------------------
|
|
|
|
When the server replies for pre-authentication, it returns the Salt,
|
|
which may be in the form of a principalName that is in no way
|
|
connected with the current names. (ie, even if the userPrincipalName
|
|
and samAccountName are renamed, the old salt is returned).
|
|
|
|
This is probably the kerberos standard salt, kept in the 'Key'. The
|
|
standard generation rules are found in a Mail from Luke Howard dated
|
|
10 Nov 2004:
|
|
|
|
|
|
From: Luke Howard <lukeh@padl.com>
|
|
Message-Id: <200411100231.iAA2VLUW006101@au.padl.com>
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=US-ASCII
|
|
Organization: PADL Software Pty Ltd
|
|
To: lukeh@padl.com
|
|
Date: Wed, 10 Nov 2004 13:31:21 +1100
|
|
Versions: dmail (bsd44) 2.6d/makemail 2.10
|
|
Cc: huaraz@moeller.plus.com, samba-technical@lists.samba.org
|
|
Subject: Re: Samba-3.0.7-1.3E Active Directory Issues
|
|
X-BeenThere: samba-technical@lists.samba.org
|
|
X-Mailman-Version: 2.1.4
|
|
Precedence: list
|
|
Reply-To: lukeh@padl.com
|
|
|
|
Did some more testing, it appears the behaviour has another
|
|
explanation. It appears that the standard Kerberos password salt
|
|
algorithm is applied in Windows 2003, just that the source principal
|
|
name is different.
|
|
|
|
Here is what I've been able to deduce from creating a bunch of
|
|
different accounts:
|
|
|
|
Type of account Principal for Salting
|
|
========================================================================
|
|
Computer Account host/<SAM-Name-Without-$>.realm@REALM
|
|
User Account Without UPN <SAM-Name>@REALM
|
|
User Account With UPN <LHS-Of-UPN>@REALM
|
|
|
|
Note that if the computer account's SAM account name does not include
|
|
the trailing '$', then the entire SAM account name is used as input to
|
|
the salting principal. Setting a UPN for a computer account has no
|
|
effect.
|
|
|
|
It seems to me odd that the RHS of the UPN is not used in the salting
|
|
principal. For example, a user with UPN foo@mydomain.com in the realm
|
|
MYREALM.COM would have a salt of MYREALM.COMfoo. Perhaps this is to
|
|
allow a user's UPN suffix to be changed without changing the salt. And
|
|
perhaps using the UPN for salting signifies a move away SAM names and
|
|
their associated constraints.
|
|
|
|
For more information on how UPNs relate to the Kerberos protocol,
|
|
see:
|
|
|
|
http://www.ietf.org/proceedings/01dec/I-D/draft-ietf-krb-wg-kerberos-referrals-02.txt
|
|
|
|
-- Luke
|
|
|
|
--
|
|
|
|
|
|
|
|
|
|
Heimdal oddities
|
|
----------------
|
|
|
|
Heimdal is built such that it should be able to serve multiple realms
|
|
at the same time. This isn't relevant for Samba's use, but it shows
|
|
up in a lot of generalisations throughout the code.
|
|
|
|
Other odd things:
|
|
- Support for multiple passwords on a client account: we seem to
|
|
call hdb_next_enctype2key() in the pre-authentication routines to
|
|
allow multiple passwords per account in krb5. (I think this was
|
|
intened to allow multiple salts)
|
|
|
|
State Machine safety
|
|
--------------------
|
|
|
|
Samba is a giant state machine, and as such have very different
|
|
requirements to those traditionally expressed for kerberos and GSSAPI
|
|
libraries.
|
|
|
|
Samba requires all of the libraries it uses to be state machine safe in
|
|
their use of internal data. This does not mean thread safe, and an
|
|
application could be thread safe, but not state machine safe (if it
|
|
instead used thread-local variables).
|
|
|
|
So, what does it mean for a library to be state machine safe? This is
|
|
mostly a question of context, and how the library manages whatever
|
|
internal state machines it has. If the library uses a context
|
|
variable, passed in by the caller, which contains all the information
|
|
about the current state of the library, then it is safe. An example
|
|
of this state is the sequence number and session keys for an ongoing
|
|
encrypted session).
|
|
|
|
The other issue affecting state machines is 'blocking' (waiting for a
|
|
read on a network socket).
|
|
|
|
Heimdal has this 'state machine safety' in parts, and we have modified
|
|
the lorikeet branch to improve this behviour, when using a new,
|
|
non-standard API.
|
|
|
|
Heimdal uses a per-context variable for the 'krb5_auth_context', which
|
|
controls the ongoing encrypted connection, but does use global
|
|
variables for the ubiquitous krb5_context parameter.
|
|
|
|
The modification that has added most to 'state machine safety' of
|
|
GSSAPI is the addition of the gsskrb5_acquire_creds function. This
|
|
allows the caller to specify a keytab and ccache, for use by the
|
|
GSSAPI code. Therefore there is no need to use global variables to
|
|
communicate this information.
|
|
|
|
At a more theoritical level (simply counting static and global
|
|
variables) Heimdal is not state machine safe for the GSSAPI layer.
|
|
The Krb5 layer alone is much closer, as far as I can tell, blocking
|
|
excepted. .
|
|
|
|
To deal with blocking, we could have a fork()ed child per context,
|
|
using the 'GSSAPI export context' function to transfer
|
|
the GSSAPI state back into the main code for the wrap()/unwrap() part
|
|
of the operation. This will still hit issues of static storage (one
|
|
gss_krb5_context per process, and multiple GSSAPI encrypted sessions
|
|
at a time) but these may not matter in practice.
|
|
|
|
In the short-term, we deal with blocking by taking over the network
|
|
send() and recv() functions, therefore making them 'semi-async'. This
|
|
doens't apply to DNS yet.
|
|
|
|
GSSAPI and Kerberos extensions
|
|
------------------------------
|
|
|
|
This is a general list of the other extensions we have made to / need from
|
|
the kerberos libraries
|
|
|
|
- DCE_STYLE
|
|
|
|
- gsskrb5_get_initiator_subkey() (return the exact key that Samba3
|
|
has always asked for. gsskrb5_get_subkey() might do what we need
|
|
anyway)
|
|
|
|
- gsskrb5_acquire_creds() (takes keytab and/or ccache as input
|
|
parameters, see keytab and state machine discussion)
|
|
|
|
- gss_krb5_copy_service_keyblock() (get the key used to actually
|
|
encrypt the ticket to the server, because the same key is used for
|
|
the PAC validation).
|
|
- gsskrb5_extract_authtime_from_sec_context (get authtime from
|
|
kerberos ticket)
|
|
- gsskrb5_extract_authz_data_from_sec_context (get authdata from
|
|
ticket, ie the PAC. Must unwrap the data if in an AD-IFRELEVENT)
|
|
- gsskrb5_wrap_size (find out how big the wrapped packet will be,
|
|
given input length).
|
|
|
|
Keytab requirements
|
|
-------------------
|
|
|
|
Because windows machine account handling is very different to the
|
|
tranditional 'MIT' keytab operation. This starts when we look at the
|
|
basis of the secrets handling:
|
|
|
|
Traditional 'MIT' behaviour is to use a keytab, continaing salted key
|
|
data, extracted from the KDC. (In this modal, there is no 'service
|
|
password', instead the keys are often simply application of random
|
|
bytes). Heimdal also implements this behaviour.
|
|
|
|
The windows modal is very different - instead of sharing a keytab with
|
|
each member server, a password is stored for the whole machine. The
|
|
password is set with non-kerberos mechanisms (particularly SAMR, a
|
|
DCE-RPC service) and when interacting on a kerberos basis, the
|
|
password is salted by the client. (That is, no salt infromation
|
|
appears to be convayed from the KDC to the member).
|
|
|
|
In dealing with this modal, we leverage both the traditional file
|
|
keytab and in-MEMORY keytabs.
|
|
|
|
When dealing with a windows KDC, the behaviour regarding case
|
|
sensitivity and canonacolisation must be accomidated. This means that
|
|
an incoming request to a member server may have a wide variety of
|
|
service principal names. These include:
|
|
|
|
machine$@REALM (samba clients)
|
|
HOST/foo.bar@realm (win2k clients)
|
|
HOST/foo@realm (win2k clients, using netbios)
|
|
cifs/foo.bar@realm (winxp clients)
|
|
cifs/foo@realm (winxp clients, using netbios)
|
|
|
|
as well as all case variations on the above.
|
|
|
|
Because that all got 'too hard' to put into a keytab in the
|
|
traditional way (with the client to specify the name), we either
|
|
pre-compute the keys into a traditional keytab or make an in-MEMORY
|
|
keytab at run time. In both cases we specifiy the principal name to
|
|
GSSAPI, which avoids the need to store duplicate principals.
|
|
|
|
We use a 'private' keytab in our private dir, referenced from the
|
|
secrets.ldb by default.
|
|
|
|
Extra Heimdal functions used
|
|
----------------------------
|
|
(an attempt to list some of the Heimdal-specific functions I know we use)
|
|
|
|
krb5_free_keyblock_contents()
|
|
|
|
also a raft of prinicpal manipulation functions:
|
|
|
|
Prncipal Manipulation
|
|
---------------------
|
|
|
|
Samba makes extensive use of the principal manipulation functions in
|
|
Heimdal, including the known structure behind krb_principal and
|
|
krb5_realm (a char *).
|
|
|
|
Authz data extraction
|
|
---------------------
|
|
|
|
We use krb5_ticket_get_authorization_data_type(), and expect it to
|
|
return the correct authz data, even if wrapped in an AD-IFRELEVENT container.
|
|
|
|
|
|
KDC/hdb Extensions
|
|
--------------
|
|
|
|
We have modified Heimdal's 'hdb' interface to specify the 'type' of
|
|
Principal being requested. This allows us to correctly behave with
|
|
the different 'classes' of Principal name.
|
|
|
|
We currently define 2 classes:
|
|
- client (kinit)
|
|
- server (tgt)
|
|
|
|
I also now specify the kerberos principal as an explict parameter, not
|
|
an in/out value on the entry itself.
|
|
|
|
Inside hdb-ldb, we add krbtgt as a special class of principal, because
|
|
of particular special-case backend requirements.
|
|
|
|
Callbacks:
|
|
In addition, I have added a new interface hdb_fetch_ex(), which
|
|
returns a structure including callbacks, which provide the hook for
|
|
the PAC, as well as a callback into the main access control routines.
|
|
|
|
A new callback should be added to increment the bad password counter
|
|
on failure.
|
|
|
|
Another possability for a callback is to obtain the keys. This would
|
|
allow the plaintext password to only be hashed into the encryption
|
|
types we need. This idea from the eDirectory/MIT DAL work.
|
|
|
|
This probably should be combined with storing the hashed passwords in
|
|
the supplementalCredentials attribute. If combined with a kvno
|
|
parameter, this could also allow changing of the krbtgt password
|
|
(valuable for security).
|
|
|
|
libkdc
|
|
------
|
|
|
|
Samba4 needs to be built as a single binary (design requirement), and
|
|
this should include the KDC. Samba also (and perhaps more
|
|
importantly) needs to control the configuration environment of the
|
|
KDC.
|
|
|
|
The interface we have defined for libkdc allow for packet injection
|
|
into the post-socket layer, with a defined krb5_context and
|
|
kdb5_kdc_configuration structure. These effectively redirect the
|
|
kerberos warnings, logging and database calls as we require.
|
|
|
|
Using our socket lib
|
|
--------------------
|
|
|
|
An important detail in the use of libkdc is that we use our own socket
|
|
lib. This allows the KDC code to be as portable as the rest of samba
|
|
(this cuts both ways), but far more importantly it ensures a
|
|
consistancy in the handling of requests, binding to sockets etc.
|
|
|
|
To handle TCP, we use of our socket layer in much the same way as
|
|
we deal with TCP for CIFS. Tridge created a generic packet handling
|
|
layer for this.
|
|
|
|
For the client, we likewise must take over the socket functions, so
|
|
that our single thread smbd will not lock up talking to itself. (We
|
|
allow processing while waiting for packets in our socket routines).
|
|
|
|
Kerberos logging support
|
|
------------------------
|
|
|
|
Samba now (optionally in the main code, required for the KDC) uses the
|
|
krb5_log_facility from Heimdal. This allows us to redirect the
|
|
warnings and status from the KDC (and client/server kerberos code) to
|
|
Samba's DEBUG() system.
|
|
|
|
Similarly important is the Heimdal-specific krb5_get_error_string()
|
|
function, which does a lot to reduce the 'administrator pain' level,
|
|
by providing specific, english text-string error messages instead of
|
|
just error code translations.
|
|
|
|
|
|
Short name rules
|
|
----------------
|
|
|
|
Samba is highly likely to be misconfigured, in many weird and
|
|
interesting ways. As such, we have a patch for Heimdal that avoids
|
|
DNS lookups on names without a . in them. This should avoid some
|
|
delay and root server load.
|
|
|
|
PAC Correctness
|
|
---------------
|
|
|
|
We now put the PAC into the TGT, not just the service ticket.
|
|
|
|
Forwarded tickets
|
|
-----------------
|
|
|
|
We extract forwarded tickets from the GSSAPI layer, and put
|
|
them into the credentials. We can then use them for proxy work.
|
|
|
|
|
|
Kerberos TODO
|
|
=============
|
|
|
|
(Feel free to contribute to any of these tasks, or ask
|
|
abartlet@samba.org about them).
|
|
|
|
Lockout Control
|
|
--------------
|
|
|
|
We need to get (either if PADL publishes their patch, or write our
|
|
own) access control hooks in the Heimdal KDC. We need to lockout
|
|
accounts, and perform other controls.
|
|
|
|
Gssmonger
|
|
---------
|
|
|
|
Microsoft has released a testsuite called gssmonger, which tests
|
|
interop. We should compile it against lorikeet-heimdal, MIT and see
|
|
if we can build a 'Samba4' server for it.
|
|
|
|
Kpasswd server
|
|
--------------
|
|
|
|
I have a partial kpasswd server which needs finishing, and a we need a
|
|
client testsuite written, either via the krb5 API or directly against
|
|
GENSEC and the ASN.1 routines.
|
|
|
|
Currently it only works for Heimdal, not MIT clients. This may be due
|
|
to call ordering constraints.
|
|
|
|
|
|
Correct TCP support
|
|
-------------------
|
|
|
|
Our current TCP support does not send back 'too large' error messages
|
|
if the high bit is set. This is needed for a proposed extension
|
|
mechanism, but is likewise unsupported in both current Heimdal and MIT.
|