[SCM] Samba Shared Repository - branch master updated -
release-4-0-0alpha7-2208-g8e1b848
Andrew Bartlett
abartlet at samba.org
Wed Jun 10 01:19:58 GMT 2009
The branch, master has been updated
via 8e1b848aed38a1e297a1b7df68b6a6b703fcd2ff (commit)
from 6836b16ddac590b9cb23c4c5497aacd3bc371968 (commit)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 8e1b848aed38a1e297a1b7df68b6a6b703fcd2ff
Author: Donald T. Davis <don at mit.edu>
Date: Wed Jun 10 11:16:09 2009 +1000
Clarify and expand the Kerberos notes made by Andrew Bartlett in 2005
Compiled with Andrew over a series of phone calls and gobby sessions
with Andrew, with the aim of documenting Kerberos requirements for
Samba to us an alternate (ie, MIT) Kerberos library.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
-----------------------------------------------------------------------
Summary of changes:
source4/auth/kerberos-notes.txt | 760 +++++++++++++++++++++++++++++++++++++++
1 files changed, 760 insertions(+), 0 deletions(-)
create mode 100644 source4/auth/kerberos-notes.txt
Changeset truncated at 500 lines:
diff --git a/source4/auth/kerberos-notes.txt b/source4/auth/kerberos-notes.txt
new file mode 100644
index 0000000..78efe17
--- /dev/null
+++ b/source4/auth/kerberos-notes.txt
@@ -0,0 +1,760 @@
+Copyright Andrew Bartlett <abartlet at samba.org> 2005-2009
+Copyright Donald T. Davis <don at mit.edu>
+
+Released under the GPLv3
+
+Important context for porting to MIT
+------------------------------------
+
+This document should be read in conjuction with the Samba4 source code.
+DAL and KDC requirements are expressed (as an implementation against Heimdal's
+HDB abstraction layer) in Samba4's source4/kdc/hdb-samba4.c in particular.
+hbd-samba4.c is the biggest piece of samba-to-krb glue layer, so the main
+part of the port to MIT is to replace hdb-samba4 with a similar glue layer
+that's designed for MIT's code.
+
+PAC requirements are implemeneted in source4/kdc/pac-glue.c
+
+The plugins (both of the above are Heimdal plugins) for the above are loaded
+in source4/kdc/kdc.c
+
+For GSSAPI requirements, see auth/gensec/gensec_gssapi.c (the consumer of
+GSSAPI in Samba4)
+
+For Kerberos requirements, see auth/kerberos/krb5_init_context.c .
+
+Samba has its own credentials system, wrapping GSS creds, just as GSS
+creds wrap around krb5 creds. For the interaction between Samba4 credentials
+system and GSSAPI and Kerberos see auth/credentials/credentials_krb5.c .
+
+AllowedWorkstationNames and Krb5
+--------------------------------
+
+Microsoft uses the clientAddresses *multiple value* field in the krb5
+protocol (particularly the AS_REQ) to communicate the client's netbios
+name (legacy undotted name, <14 chars)
+
+This is (my guess) to support the userWorkstations field (in user's AD record).
+The idea is to support client-address restrictions, as was standard in NT:
+The AD authentication server I imagine checks the netbios address against
+this userWorkstations value (BTW, the NetLogon server does this, too).
+
+The checking of this field implies a little of the next question:
+
+Is a DAL the layer we need?
+---------------------------
+
+Looking at what we need to pass around, I don't think
+the DAL is even the right layer; what we really want
+is to create an account-authorization abstraction layer
+(e.g., is this account permitted to login to this computer,
+at this time?).
+Here is how we ended up doing this in Heimdal:
+ * We created a separate plugin, with this API:
+ typedef struct hdb_entry_ex {
+ void *ctx;
+ hdb_entry entry;
+ void (*free_entry)(krb5_context, struct hdb_entry_ex *);
+ } hdb_entry_ex;
+
+ * The void *ctx is a "private pointer," provided by the 'get' method's
+ hdb_entry_ex retval. The APIs below use the void *ctx so as to find
+ additional information about the user, not contained in the hdb_entry
+ structure. Both the provider and the APIs below understand how to cast
+ the private void *ctx pointer.
+
+ typedef krb5_error_code
+ (*krb5plugin_windc_pac_generate)(void *, krb5_context,
+ struct hdb_entry_ex *, krb5_pac*);
+ typedef krb5_error_code
+ (*krb5plugin_windc_pac_verify)(void *, krb5_context,
+ const krb5_principal,
+ struct hdb_entry_ex *,
+ struct hdb_entry_ex *,
+ krb5_pac *);
+ typedef krb5_error_code
+ (*krb5plugin_windc_client_access)(void *,
+ krb5_context,
+ struct hdb_entry_ex *,
+ KDC_REQ *, krb5_data *);
+
+ * (The krb5_data* here is critical, so that samba's KDC can return
+ the right NTSTATUS code in the 'error string' returned to the client.
+ Otherwise, the windows client won't get the right error message to
+ the user (such as 'password expired' etc). The pure Kerberos error
+ is not enough)
+
+ typedef struct krb5plugin_windc_ftable {
+ int minor_version;
+ krb5_error_code (*init)(krb5_context, void **);
+ void (*fini)(void *);
+ rb5plugin_windc_pac_generate pac_generate;
+ krb5plugin_windc_pac_verify pac_verify;
+ krb5plugin_windc_client_access client_access;
+ } krb5plugin_windc_ftable;
+ This API has some heimdal-specific stuff, that'll have to change when we port the plugin to MIT krb.
+ * 1st callback (pac_generate) creates an initial PAC from the user's AD record.
+ * 2nd callback (pac_verify) check that a PAC is correctly signed, add additional groups (for cross-realm tickets) and re-sign with the key of the target kerberos service's account
+ * 3rd callback (client_access) perform additional access checks, such as allowedWorkstations and account expiry.
+ * for example, to register this plugin, use the kdc's standard
+ plugin-system at Samba4's initialisation:
+ /* first, setup the table of callback pointers */
+ /* Registar WinDC hooks */
+ ret = krb5_plugin_register(krb5_context,
+ PLUGIN_TYPE_DATA, "windc",
+ &windc_plugin_table);
+ /* once registered, the KDC will invoke the callbacks */
+ /* while preparing each new ticket (TGT or app-tkt) */
+ * an alternate way to register the plugin is with a config-file that names
+ a DSO (Dynamically Shared Object).
+
+
+This plugin helps bridge an important gap: The user's AD record is much
+richer than the Heimdal HDB format allows, so we do AD-specific access
+control checks in an AD-specific layer (ie, the plugin), not in the
+DB-agnostic KDC server.
+
+In Novell's pure DAL approach, the DAL only read in the principalName as
+the key, so it had trouble performing access-control decisions on things
+other than the name (like the addresses).
+
+There is another, currently unhandled challenge in this area - the need to handle
+bad password counts (and good password notification), so that a single policy can
+be applied against all means of checking a password (NTLM, Kerberos, LDAP Simple
+bind etc)
+
+The Original work by Novell in creating a DAL did not seem to provide a way to
+update the PW counts information. Nevertheless, we know that this is very much
+required (and may have been addressed in Simo's subsequent IPA-KDC design),
+because in Samba3+eDirectory, great lengths are taken to update this information.
+
+GSSAPI layer requirements
+-------------------------
+
+Welcome to the wonderful world of canonicalisation
+
+The MIT Krb5 libs (including GSSAPI) 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 too applies to the krb5 layer, not
+just gssapi.
+
+there's two kinds of name-canonicalization that can occur:
+ * lower-to-upper case conversion, because Windows domain names are
+ usually in upper case;
+ * an unrecognizable subsitution of names, such as might happen when
+ a user requests a ticket for a NetBIOS domain name, but gets back
+ a ticket for the corresponging FQDN.
+
+As developers, we should test if the AD KDC's name-canonicalisation
+can be turned off with the KDCOption flags in the AS-REQ or TGS-REQ;
+Windows clients always send the Canonicalize flags as KDCOption values.
+
+Old Clients (samba3 and HPUX clients) use 'selfmade' gssapi/krb5 tokens
+for use in the CIFS session setup. these hand-crafted ASN.1 packets don't
+follow rfc1964 perfectly, so server-side krblib code has to be flexible
+enough to accept these bent tokens.
+It turns out that Windows' GSSAPI server-side code is sloppy about checking
+some GSSAPI tokens' checksums. During initial work to implement an AD client,
+it was easier to make an acceptable solution (to Windows servers) than to
+correctly implement the GSSAPI specification, particularly on top of the
+(inflexible) MIT Kerberos API. It did not seem possible to write a correct,
+seperate GSSAPI implementation on top of MIT Kerberos's public krb5lib API,
+and at the time, the effort did not need to extend beyond what Windows would
+require.
+
+The upshot is that old Samba3 clients send GSSAPI tokens bearing incorrect
+checksums, which AD's Krb5lib cheerfully accepts (but accepts the good checksums,
+too). Similarly, Samba4's heimdal krb5lib accepts these incorrect checksums.
+Accordingly, if MIT's krb5lib wants to interoperate with the old Samba3 clients,
+then MIT's library will have to do the same.
+
+Because these old clients use krb5_mk_req()
+the app-servers get a chksum field depending on the encryption type, but that's
+wrong for GSSAPI (see rfc 1964 section 1.1.1). The Checksum type 8003 should
+be used in the Authenticator of the AP-REQ! That (correct use of the 8003 type)
+would allows the channel bindings, the GCC_C_* req_flags and optional delegation
+tickets to be passed from the client to the server. However windows doesn't
+seem to care whether the checksum is of the wrong type, and for CIFS SessionSetups,
+it seems that the req_flags are just set to 0.
+This deviant checksum can't work for LDAP connections with sign or seal, or
+for any DCERPC connection, because those connections do not require the
+negotiation of GSS-Wrap paraemters (signing or sealing of whole payloads).
+Note: CIFS has an independent SMB signing mechanism, using the Kerberos key.
+
+see heimdal/lib/gssapi/krb5/accept_sec_context.c, lines 390-450 or so.
+
+This bug-compatibility is likely to be controversial in the kerberos community,
+but a similar need for bug-compatibility arose around MIT's & Heimdal's both
+failing to support TGS_SUBKEYs correctly, and there are numerous other cases.
+see https://lists.anl.gov/pipermail/ietf-krb-wg/2009-May/007630.html
+
+So MIT's krb5lib needs to also support old clients!
+
+Principal Names, long and short names
+-------------------------------------
+
+As far as servicePrincipalNames are concerned, these are not
+canonicalised by AD's KDC, 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.
+Heimdal doesn't canonicalize names, but Samba4 does some canonicalization:
+For hostnames and usernames, Samba4 canonicalizes the requested name only
+for the LDAP principal-lookup, but then Samba4 returns the retrieved LDAP
+record with the request's original, uncanonicalized hostname replacing the
+canonicalized name that actually was retrieved.
+AB says that for usernames, Samba4 used to return the canonicalized username,
+as retrieved from LDAP. The reason for the different treatment was that
+the user needs to present his own canonicalized username to servers, for
+ACL-matching. For hostnames this isn't necessary.
+So, for bug-compatibility, we may need to optionally disable any
+namne-canonicalization that MIT's KDC does.
+
+The short name of the realm seems to be accepted for at least AS_REQ
+operations, but the AD KDC always performs realm-canonicalisation,
+which converts the short realm-name to the canonical long form.
+So, this causes pain for current krb client libraries.
+
+The canonicalisation of names matters not only for the KDC, but also
+for code that has to deal with keytabs.
+With credential-caches, when canonicalization leads to cache-misses,
+the client just asks for new credentials for the variant server-name.
+This could happen, for example, if the user asks to access the server
+twice, using different variants of the server-name.
+
+We also need to handle type 10 names (NT-ENTERPRISE), which are a full
+principal name in the principal field, unrelated to the realm.
+The principal field contains both principal & realm names, while the
+realm field contains a realm name, too, possibly different.
+For example, an NT-ENTERPRISE principal name might look like:
+joeblow at microsoft.com@NTDEV.MICROSOFT.COM ,
+<--principal field-->|<----realm name--->|
+
+Where joe at microsoft.com is the leading portion, and NTDEV.MICROSOFT.COM is
+the realm. This is used for the 'email address-like login-name' feature of AD.
+
+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 list is read & parsed by the AD KDC, so as to allow any of these
+aliased ticket-requests to use the HOST/ key.
+
+Samba4 currently has set:
+sPNMappings: host=ldap,dns,cifs,http (but dns's presence is a bug, somehow)
+
+AD actually has ~50 entries:
+
+sPNMappings: host=alerter,appmgmt,cisvc,clipsrv,browser,dhcp,dnscache,replicat
+ or,eventlog,eventsystem,policyagent,oakley,dmserver,dns,mcsvc,fax,msiserver,i
+ as,messenger,netlogon,netman,netdde,netddedsm,nmagent,plugplay,protectedstora
+ ge,rasman,rpclocator,rpc,rpcss,remoteaccess,rsvp,samss,scardsvr,scesrv,seclog
+ on,scm,dcom,cifs,spooler,snmp,schedule,tapisrv,trksvr,trkwks,ups,time,wins,ww
+ w,http,w3svc,iisadmin,msdtc
+
+Domain members that expect the longer list will break in damb4, as of 6/09.
+AB says he'll try to fix this right away.
+
+For example, this is how HTTP/, and CIFS/ can use HOST/ without
+any explicit entry in the servicePrincipalName attribute
+
+
+For example, the application-server might have (on its AD record):
+servicePrincipalName: HOST/my.computer at MY.REALM
+
+but the client asks for a ticket to cifs/my.computer at MY.REALM
+AD looks in LDAP for both name-variants
+AD then transposes cifs -> host after performing the lookup in the
+directory (for the original name), then looks for host/my.computer at MY.REALM
+
+for hostnames & usernames, alternate names appear as extra values in
+the multivalued "principal name" attributes:
+ - For hostnames, the other names (other than it's short name, implied
+ from the CN), is stored in the servicePrincipalName
+ - For usernames, the other names are stored in the userPrincipalName
+ attribute, and can be full e-mail address like names, such as
+ joe at microsoft.com (see above).
+
+Jean-Baptiste.Marchand at 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
+-----------------------------------
+AD's records for servers are keyed by CN or by servicePrincipalName,
+but for win2k boxes, these records don't include servicePrincipalName,
+so, the CN attribute is used instead.
+Despite not having 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 the computer's entry in the AD LDAP database
+(ie, be able to obtain tickets for that host name in the KDC).
+
+Returned Salt for PreAuthentication
+-----------------------------------
+
+When the KDC 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 the kerberos standard salt, kept in the 'Key'. The
+AD generation rules are found in a Mail from Luke Howard dated
+10 Nov 2004. The MIT glue layer doesn't really need to care about
+these salt-handling details; the samba4 code & the LDAP backend
+will conspire to make sure that MIT's KDC gets correct salts.
+
+
+From: Luke Howard <lukeh at padl.com>
+Organization: PADL Software Pty Ltd
+To: lukeh at padl.com
+Date: Wed, 10 Nov 2004 13:31:21 +1100
+Cc: huaraz at moeller.plus.com, samba-technical at lists.samba.org
+Subject: Re: Samba-3.0.7-1.3E Active Directory Issues
+-------
+
+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:
+[SAM name in this mail means the AD attribute samAccountName .
+ E.g., jbob for a user and jbcomputer$ for a computer.]
+
+[UPN is the AD userPrincipalName attribute. For example, jbob at mydomain.com]
+
+Type of account Principal for Salting
+========================================================================
+Computer Account host/<SAM-Name-Without-$>.realm at 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 at 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.
+
+Samba4's code originally tried internally to make it possible to use
+Heimdal's multi-realms-per-KDC ability, but this was ill-conceived,
+and AB has recently (6/09) ripped the last of that multi-realms
+stuff out of samba4. AB says that in AD, it's not really possible
+to make this work; several AD components structurally assume that
+there's one realm per KDC. However, we do use this to support
+canonicalization of realm-names: case variations, plus long-vs-short
+variants of realm-names.
+
+Other odd things:
+ - Heimdal supports multiple passwords on a client account: Samba4
+ seems to call hdb_next_enctype2key() in the pre-authentication
+ routines to allow multiple passwords per account in krb5.
+ (I think this was intended to allow multiple salts).
+ AD doesn't support this, so the MIT port shouldn't bother with
+ this.
+
+State Machine safety when using Kerberos and GSSAPI libraries
+-------------------------------------------------------------
+
+Samba's client-side & app-server-side libraries are built on 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). Samba's non-blocking I/O doesn't like
+waiting for libkrb5 to go away for awhile to talk to the KDC.
+
+Samba4 provides a hook 'send_to_kdc', that allows Samba4 to take over the
+IO handling, and run other events in the meantime. This uses a
+'nested event context' (which presents the challenges that the kerberos
+library might be called again, while still in the send_to_kdc hook).
+
+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 to tunnelling a ccache (containing a set of tickets)
+through the gssapi, by temporarily casting the ccache pointer to a
+gss credential pointer.
+This new API is Heimdal's samba4-requested gss_krb5_import_cred() fcn;
+this will have to be rewritten or ported in the MIT port.
+
+This replaces an older scheme using the KRB5_CCACHE
+environment variable to get the same job done. This tunnelling trick
+enables a command-line app-client to run kinit tacitly, before running
+GSSAPI for service-authentication. This tunnelling trick avoids the
+more usual approach of keeping the ccache pointer in a global variable.
+
+No longer true; the krb5_context global is gone now:
+[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 gss_krb5_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 about keytab & ccache.
+
+At a more theoritical level (simply counting static and global
+variables) Heimdal is not state machine safe for the GSSAPI layer.
+(Heimdal is now (6/09) much more nearly free of globals.)
+The Krb5 layer alone is much closer, as far as I can tell, blocking
+excepted. .
+
+
+As an alternate to fixing MIT Kerberos for better safety in this area,
+a new design might be implemented in Samba, where blocking read/write
+is made to the KDC in another (fork()ed) child process, and the results
+passed back to the parent process for use in other non-blocking operations.
+
+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.
+
+This approach has long been controversial in the Samba team.
+An alternate way would be to be implement E_AGAIN in libkrb5: similar
+to the way to way read() works with incomplete operations. to do this
+in libkrb5 would be difficult, but valuable.
+
+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.These thread-safety context-variables will
+probably present porting problems, during the MIT port. This will
+probably be most of the work in the port to MIT.
+
+
+
+GSSAPI and Kerberos extensions
+------------------------------
+
+This is a general list of the other extensions we have made to / need from
+the kerberos libraries
+
+ - DCE_STYLE : Microsoft's hard-coded 3-msg Challenge/Response handshake
+ emulates DCE's preference for C/R. Microsoft calls this DCE_STYLE.
+ MIT already has this nowadays (6/09).
+
+ - gsskrb5_get_initiator_subkey() (return the exact key that Samba3
+ has always asked for. gsskrb5_get_subkey() might do what we need
+ anyway). This is necessary, because in some spots, Microsoft uses
+ raw Kerberos keys, outside the Kerberos protocls, and not using Kerberos
+ wrappings etc. Ie, as a direct input to MD5 and ARCFOUR, without using
+ the make_priv() or make_safe() calls.
+
+ - gsskrb5_acquire_creds() (takes keytab and/or ccache as input
+ parameters, see keytab and state machine discussion in prev section)
+
+Not needed anymore, because MIT's code now handles PACs fully:
+ - 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)
--
Samba Shared Repository
More information about the samba-cvs
mailing list