Rework the kerberos-notes.txt in order and format
authorDon Davis <dodavis@redhat.com>
Tue, 30 Jun 2009 08:12:02 +0000 (18:12 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 30 Jun 2009 08:12:02 +0000 (18:12 +1000)
This reworks the notes file to be less stream-of-consciousness and more
task for porting, with a very particular focus on a potential port of
Samba4 to use MIT Kerberos.

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
source4/auth/kerberos/kerberos-porting-to-mit-notes.txt [new file with mode: 0644]

diff --git a/source4/auth/kerberos/kerberos-porting-to-mit-notes.txt b/source4/auth/kerberos/kerberos-porting-to-mit-notes.txt
new file mode 100644 (file)
index 0000000..bad17a7
--- /dev/null
@@ -0,0 +1,803 @@
+Copyright Andrew Bartlett <abartlet@samba.org> 2005-2009
+Copyright Donald T. Davis <don@mit.edu>        2009
+
+Released under the GPLv3
+"Porting Samba4 to MIT-Krb"
+
+
+         From Idmwiki
+
+
+IPA v3 will use a version of Samba4 built on top of MIT's Kerberos
+implementation, instead of Heimdal's version of Kerberos.
+
+Task list summary for porting changes needed, from Andrew Bartlett:
+
+      * Rewrite or extend the LDAP driver that MIT-KDC will use.
+      * MIT KDC changes:  rewrite DAL, add TGS-KBAC, enable PACs,...
+      * Full thread-safety for MIT's library code,
+      * Many small changes
+
+Task list, without explanations (the list with explanations is in the
+later sections of this document):
+
+Porting Samba4 to MIT-krb comprises four main chunks of work:
+     1. Rewrite or extend the LDAP driver that MIT-KDC will use:
+          a. Our LDAP driver for the KDB needs to know how to do
+             Samba4's intricate canonicalization of server names,
+             user-names, and realm names.
+          b. AD-style aliases for HOST/ service names.
+          c. Implicit names for Win2k accounts.
+          d. Principal "types":  client / server / krbtgs
+          e. Most or all of this code is in 3 source files,
+             ~1000 lines in all;
+     2. MIT KDC changes
+          a. Rewrite the MIT KDC's Data-Abstraction Layer (DAL),
+             mostly because he MIT KDC needs to see&   manipulate
+             more LDAP detail, on Samba4's behalf;
+          b. Add HBAC to the KDC's TGT-issuance, so that Samba4
+             can refuse TGTs to kinit, based on time-of-day&
+             IP-addr constraints;
+          c. turn on MIT-krb 1.7's PAC handling
+          d. add bad-password counts, for unified account-lockouts
+             across all authT methods (Krb, NTLM, LDAP simple bind,
+             etc)
+     3. Make sure MIT's library code is more fully thread-safe,
+        by replacing all global and static variables with context
+        parameters for the library routines.  This may already be
+        done.
+     4. Many small changes (~15)
+          a. some extensions to MIT's libkrb5&   GSSAPI libraries,
+             including GSSAPI ticket-forwarding
+          b. some refitting in Samba4's use of the MIT libraries;
+          c. make sure Samba4's portable socket API works,
+             including "packet too large" errors;
+          d. MIT's GSSAPI code should support some legacy Samba3
+             clients that present incorrectly-calculated checksums;
+          e. Samba4 app-server-host holds aUTF-16 PW, plus a
+             key bitstring;
+          f. in-memory-only credentials cache;
+          g. in-memory-only keytab (nice to have);
+          h. get OSS NTLM authT library (Likewise Software?);
+          i. special Heimdal-specific functions;
+          j. principal-manipulation functions;
+          k. special check for misconfigured Samba4 hostnames;
+          l. improved krb error-messages;
+          m. improved krb logging
+          n. MS GSSMonger test-suite
+          o. testsuite for kpasswd daemon
+
+0. Introduction: This document should be read alongside the Samba4
+source code, as follows:
+
+    * For DAL and KDC requirements, please see Samba4's
+      source4/kdc/hdb-samba4.c in particular.  This file
+      is an implementation against Heimdal's HDB abstraction
+      layer, and is the biggest part of the 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.
+    * Samba4's PAC requirements are implemeneted in
+      source4/kdc/pac-glue.c
+    * Both of the above two layers are Heimdal plugins, and
+      both get loaded in source4/kdc/kdc.c
+    * For GSSAPI requirements, see auth/gensec/gensec_gssapi.c
+      (the consumer of GSSAPI in Samba4)
+    * For Kerberos library 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 credential system and GSSAPI
+      and Kerberos, see auth/credentials/credentials_krb5.
+
+1. Rewrite or extend the LDAP driver that MIT-KDC will use.
+
+     a. IPA'sLDAP driver for the KDB needs to know how to do
+        Samba4's intricate canonicalization of server names,
+        user-names, and realm names.
+        For hostnames&   usernames, alternate names appear in
+        LDAP as extra values in the multivalued "principal name"
+        attributes:
+          * For a hostname, the alternate names (other than
+            the short name, implied from the CN), are stored in
+            the servicePrincipalName
+          * For a username, the alternate names are stored in
+            the userPrincipalName attribute, and can be long
+            email-address-like names, such as joe@microsoft.com
+            (see "Type 10 names," below).
+        GSSAPI layer requirements:  Welcome to the wonderful
+        world of canonicalisation.  The MIT Krb5 libs (including
+        GSSAPI) do not enable the AS to send kinit a TGT containing
+        a different realm-name than what the client asked for,
+        even in U/L case differences.  Heimdal has the same problem,
+        and this applies to the krb5 layer too, not just GSSAPI.
+        There are two kinds of name-canonicalization that can
+        occur on Windows:
+          * 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-canonical-
+        isation 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.
+        Principal Names, long and short names:
+        AD's KDC does not canonicalize servicePrincipalNames, except
+        for the realm in the KDC reply.  That is, the client gets
+        back the principal it asked for, with the realm portion
+        'fixed' to uppercase, long form.
+        Samba4 does some canonicalization, though Heimdal doesn't
+        canonicalize names itself:  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 found.
+        Usernames:  AndrewB says that Samba4 used to return
+        the canonicalized username exactly as retrieved from LDAP.
+        The reason Samba4 treated usernames differently was that
+        the user needs to present his own canonicalized username
+        to servers, for ACL-matching.  For hostnames this isn't
+        necessary.
+        Realm-names:  AD seems to accept a realm's short name
+        in krb-requests, at least for 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.
+        Punchline:  For bug-compatibility, we may need to
+        selectively or optionally disable the MIT-KDC's name-
+        canonicalization.
+        Application-code:
+        Name-canonicalisation matters not only for the KDC, but
+        also for app-server-code that has to deal with keytabs.
+        Further, with credential-caches, canonicalization can
+        lead to cache-misses, but then 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.
+        Doubled realm-names:  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@microsoft.com@NTDEV.MICROSOFT.COM ,
+                          <--principal field-->|<----realm name--->|
+        Where joe@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.
+     b.AD-style aliases for HOST/ service names.
+        AD keeps a list of service-prefixed aliases for the host's
+        principal name.  The AD KDC reads&   parses this list, so
+        as to allow the aliased services to share the HOST/ key.
+        This means that every ticket-request for a service-alias
+        gets a service-ticket encrypted in the HOST/ key.
+        For example, this is how HTTP/ and CIFS/ can use the
+        HOST/ AD-LDAP entry, without any explicitly CIFS-prefixed
+        entry in the host's servicePrincipalName attribute. In the
+        app-server host's AD record, the servicePrincipalName says
+        only HOST/my.computer@MY.REALM , but the client asks
+        for  CIFS/my.omputer@MY.REALM tickets.  So, AD looks in
+        LDAP for both name-variants, and finds the HOST/ version,
+        In AD's reply, AD replaces the HOST/ prefix with CIFS/ .
+        We implement this in hdb-ldb.
+        (TBD: Andrew, is this correct?:)
+        List of HOST/ aliases:  Samba4 currently uses only a small
+        set of  HOST/ aliases: sPNMappings: host=ldap,dns,cifs,http .
+        Also, dns's presence in this list is a bug, somehow.
+        AD's real list has 53 entries:
+        sPNMappings: host=alerter,appmgmt,cisvc,clipsrv,browser,
+          dhcp,dnscache,replicator,eventlog,eventsystem,policyagent,
+          oakley,dmserver,dns,mcsvc,fax,msiserver,ias,messenger,
+          netlogon,netman,netdde,netddedsm,nmagent,plugplay,
+          protectedstorage,rasman,rpclocator,rpc,rpcss,remoteaccess,
+          rsvp,samss,scardsvr,scesrv,seclogon,scm,dcom,cifs,spooler,
+          snmp,schedule,tapisrv,trksvr,trkwks,ups,time,wins,www,
+          http,w3svc,iisadmin,msdtc
+        Domain members that expect the longer list will break in
+        Samba4, as of 6/09.  AB says he'll try to fix this right
+        away.  There is another post somewhere (ref lost for the
+        moment) that details where in active directory the long
+        list  of stored  aliases for HOST/ is.
+     c.Implicit names for Win2000 Accounts:  AD keys its
+        server-records by CN or by servicePrincipalName, but a
+        win2k box's server-entry in LDAP doesn't include the
+        servicePrincipalName attribute,  So, win2k server-accounts
+        are keyed by the CN attribute instead.  Because AD's LDAP
+        doesn't have a servicePrincipalName for win2k servers'
+        entries, Samba4 has to have an implicit mapping from
+        host/computer.full.name and from host/computer, to the
+        computer's CN-keyed entry in the AD LDAP database, so to
+        be able to find the win2k server's host name in the KDB.
+     d.Principal "types":
+        We have modified Heimdal's 'hdb' interface to specify
+        the 'class' of Principal being requested.  This allows
+        us to correctly behave with the different 'classes' of
+        Principal name.  This is necessary because of AD's LDAP
+        structure, which uses very different record-structures
+        for user-principals, trust principals&   server-principals.
+        We currently define 3 classes:
+           * client (kinit)
+           * server (tgt)
+           * krbtgt  the TGS's own ldap record
+        Samba4 also now specifies the kerberos principal as an
+        explicit parameter to LDB_fetch(), not an in/out value
+        on the struct hdb_entry parameter itself.
+     e. Most or all of this LDAP driver code is in three source
+        files, ~1000 lines in all.  These files are in
+        samba4/kdc :
+           * hdb-samba4.c  (samba4-to-kdb glue-layer plugin)
+           * pac-glue.c    (samba4's pac  glue-layer plugin)
+           * kdc.c         (loads the above two plugins).
+
+2. MIT KDC changes
+
+     a.Data-Abstraction Layer (DAL): It would be good to
+        rewrite or circumvent the MIT KDC's DAL, mostly because
+        the MIT KDC needs to see&   manipulate more LDAP detail,
+        on Samba4's behalf.  AB says the MIT DAL may serve well-
+        enough, though, mostly as is.  AB says Samba4 will need
+        the private pointer part of the KDC plugin API, though,
+        or the PAC generation won't work (see sec.2.c, below).
+        * MIT's DAL calls lack context parameters (as of 2006),
+          so presumably they rely instead on global storage, and
+          aren't fully thread-safe.
+        * 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 user's
+          name (like the addresses).
+        * Here's why Samba4 needs more entry detail than the DAL
+          provides:  The AS needs to have ACL rules that will allow
+          a TGT to a user only when the user logs in from the
+          right desktop addresses, and at the right times of day.
+          This coarse-granularity access-control could be enforced
+          directly by the KDC's LDAP driver, without Samba having
+          to see the entry's pertinent authZ attributes.  But,
+          there's a notable exception:  a user whose TGT has
+          expired, and who wants to change his password, should
+          be allowed a restricted-use TGT that gives him access
+          to the kpasswd service.  This ACL-logic could be buried
+          in the LDAP driver, in the same way as the TGS ACL could
+          be enforced down there, but to do so would just be even
+          uglier than it was to put the TGS's ACL-logic in the driver.
+        * Yet another complaint is that the DAL always pulls an
+          entire LDAP entry, non-selectively.  The current DAL
+          is OK for Samba4's purposes, because Samba4 only reads,
+          and doesn't write, the KDB.  But this all-or-nothing
+          retrieval hurts the KDC's performance, and would do so
+          even more, if Samba had to use the DAL to change KDB
+          entries.
+     b.Add HBAC to the KDC's TGT-issuance, so that Samba4 can
+        refuse TGTs to kinit, based on time-of-day&   IP-address
+        constraints.  AB asks, "Is a DAL the layer we need?"
+        Looking at what we need to pass around, AB doesn't think
+        the DAL is the right layer; what we really want instead
+        is to create an account-authorization abstraction layer
+        (e.g., is this account permitted to login to this computer,
+        at this time?).  Samba4 ended up doing account-authorization
+        inside Heimdal, via a specialized KDC plugin.  For a summary
+        description of this plugin API, see Appendix 2.
+     c. Turn on MIT-krb 1.7'sPAC handling.
+        In addition, I have added a new interface hdb_fetch_ex(),
+        which returns a structure including a private data-pointer,
+        which may be used by the windc plugin inferface functions.
+        The windc plugin provides the hook for the PAC.
+     d. Samba4 needsaccess control hooks in the Heimdal&   MIT
+        KDCs.  We need to lockout accounts (eg, after 10 failed PW-
+        attemps), and perform other controls.  This is standard
+        AD behavior, that Samba4 needs to get right, whether
+        Heimdal or MIT-krb is doing the ticket work.
+        - If PADL doesn't publish their patch for this,
+          we'll need to write our own.
+        - The windc plugin proivides a function for the main
+          access control routines.  A new windc plugin function
+          should be added to increment the bad password counter
+          on failure.
+        - Samba4 doesn't yet handle bad password counts (or good
+          password notification), so that a single policy can be
+          applied against all means of checking a password (NTLM,
+          Kerberos, LDAP Simple Bind, etc).  Novell's original DAL
+          did not provide a way to update the PW counts information.
+        - Nevertheless, we know that this is very much required in
+          AD, because Samba3 + eDirectory goes to great lengths to
+          update this information.  This may have been addressed in
+          Simo's subsequent IPA-KDC design),
+        * 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)
+          AB guesses that this is 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 probably checks the netbios
+          address against this userWorkstations value (BTW, the
+          NetLogon server does this, too).
+
+3. 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
+      necessarily mean "thread safe," and an application could be
+      thread safe, but not state machine safe (if it instead used
+      thread-local variables).  so, if MIT's libraries were made
+      thread-safe only by inserting spinlock() code, then the MIT
+      libraries aren't yet "state machine safe."
+    * 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
+      Samba4's lorikeet branch to improve this behaviour, 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 tunnelling trick replaces an older scheme using the KRB5_CCACHE
+      environment variable to get the same job done.  The tunnelling trick
+      enables a command-line app-client to run kinit tacitly, before running
+      GSSAPI for service-authentication.  The tunnelling trick avoids the
+      more usual approach of keeping the ccache pointer in a global variable.
+    * [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. (No longer true,
+      because the krb5_context global is gone now.)]
+    * 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 theoretical level (simply counting static and global
+      variables) Heimdal is not state machine safe for the GSSAPI layer.
+      (But 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.
+      This may require more thorough thread-safe-ing work on the MIT libraries.
+
+4. Many small changes (~15)
+
+   a. Some extensions to MIT'slibkrb5&   GSSAPI libraries, including
+      GSSAPI ticket-forwarding:  This is a general list of the other
+      extensions Samba4 has 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 routine is necessary, because in some spots,
+        Microsoft uses raw Kerberos keys, outside the Kerberos protocols,
+        as a direct input to MD5 and ARCFOUR, without using the make_priv()
+        or make_safe() calls, and without GSSAPI wrappings etc.
+      * gsskrb5_acquire_creds() (takes keytab and/or ccache as input
+        parameters, see keytab and state machine discussion in prev section)
+      * The new function to handle the PAC fully
+        gsskrb5_extract_authz_data_from_sec_context()
+        need to test that MIT's PAC-handling code checks the PAC's signature.
+      * gsskrb5_wrap_size (Samba still needs this one, for finding out how
+        big the wrapped packet will be, given input length).
+   b. Some refitting in Samba4's use of the MIT libraries;
+   c. Make sure Samba4'sportable socket API   works:
+      * An important detail in the use of libkdc is that we use samba4's
+        own socket lib.  This allows the KDC code to be as portable as
+        the rest of samba, but more importantly it ensures 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, samba4 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).
+        send_to_kdc()  presents to its caller the samba-style socket interface,
+        but the MIT port will reimplement send_to_kdc(), and this routine will
+        use internally the same socket library that MIT-krb uses.
+      * The interface we have defined for libkdc allows 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.
+      * Samba4 socket-library's 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 (SSL-armored kinit,
+        by Leif Johansson<leifj@it.su.se>), but is currently unsupported
+        in both Heimdal and MIT.
+   d. MIT's GSSAPI code should support some legacy Samba3
+      clients that presentincorrectly-calculated checksums.
+    * 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
+      (GSSAPI) 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 (acceptable 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, separate 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
+      GSSAPI library 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 allow
+      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.
+    * For the code that handles the incorrect&   correct
+      checksums, 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.
+      seehttps://lists.anl.gov/pipermail/ietf-krb-wg/2009-May/007630.html
+    * So, MIT's krb5lib needs to also support old clients!
+   e. Samba4 app-server-host holds aUTF-16 PW, plus a key bitstring;
+      See Appendix 1, "Keytab Requirements."
+   f.In-memory-only credentials cache   for forwarded tickets
+      Samba4 extracts forwarded tickets from the GSSAPI layer,
+      and puts them into the memory-based credentials cache.
+      We can then use them for proxy work.  This needs to be
+      ported, if the MIT library doesn't do it yet.
+   g.In-memory-only keytab   (nice to have):
+      Heimdal used to offer "in-memory keytabs" for servers that use
+      passwords.  These server-side passwords were held in a Samba LDB
+      database called secrets.ldb .  The heimdal library would fetch
+      the server's password from the ldb file and would construct an
+      in-memory keytab struct containing the password, somewhat as if
+      the library had read an MIT-style keytab file.  Unfortunately,
+      only later, at recv_auth() time, would the Heimdal library convert
+      the server-PW into a salted-&-hashed AES key, by hashing 10,000
+      times with SHA-1.  Naturally, this is really too slow for recv_auth(),
+      which runs when an app-server authenticates a client's app-service-
+      request.  So, nowadays, this password-based in-memory keytab  is
+      falling into disuse.
+   h. Get OSSNTLM   authT library: AB says Likewise software
+      probably will give us their freeware "NTLM for MIT-krb"
+      implementation.
+   i. Special Heimdal-specific functions;  These functions didn't
+      exist in the MIT code, years ago, when Samba started.  AB
+      will try to build a final list of these functions:
+      * krb5_free_keyblock_contents()
+      *
+   j.Principal-manipulation functions:  Samba makes extensive
+      use of the principal manipulation functions in Heimdal,
+      including the known structure behind krb_principal and
+      krb5_realm (a char *).  For example,
+      * krb5_parse_name_flags(smb_krb5_context->krb5_context, name,
+                              KRB5_PRINCIPAL_PARSE_REQUIRE_REALM,&principal);
+      * krb5_unparse_name_flags(smb_krb5_context->krb5_context,    principal,
+                              KRB5_PRINCIPAL_UNPARSE_NO_REALM,&new_princ);
+      * krb5_principal_get_realm()
+      * krb5_principal_set_realm()
+      These are needed for juggling the AD variant-structures
+      for server names.
+   k. SpecialShort name rules   check for misconfigured Samba4
+      hostnames;  Samba is highly likely to be misconfigured, in
+      many weird and interesting ways.  So, 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.
+      (This errors need to be caught in MIT's library.)
+   l.Improved krb error-messages;
+      krb5_get_error_string():  This Heimdal-specific function
+      does a lot to reduce the 'administrator pain' level, by
+      providing specific, English text-string error messages
+      instead of just error code translations.  (This isn't
+      necessary for the port, but it's more useful than MIT's
+      default err-handling;  Make sure this works for MIT-krb)
+   m.Improved Kerberos logging support:
+      krb5_log_facility(): Samba4 now uses this Heimdal function,
+      which allows us to redirect the warnings and status from
+      the KDC (and client/server Kerberos code) to Samba's DEBUG()
+      system.  Samba uses this logging routine optionally in the
+      main code, but it's required for KDC errors.
+   n. MSGSSMonger   test-suite:  Microsoft has released a krb-specific
+      testsuite called gssmonger, which tests interoperability.  We
+      should compile it against lorikeet-heimdal&   MIT and see if we
+      can build a 'Samba4' server for it.  GSSMonger wasn't intended
+      to be Windows-specific.
+   o.Testsuite for kpasswd daemon:  I have a partial kpasswd server
+      which needs finishing, and a Samba4 needs a client testsuite
+      written, either via the krb5 API or directly against GENSEC and
+      the ASN.1 routines.  Samba4 likes to test failure-modes, not
+      just successful behavior.  Currently Samba4's kpasswd only works
+      for Heimdal, not MIT clients.  This may be due to call-ordering
+      constraints.
+
+
+Appendix 1: Keytab Requirements
+
+    Traditional 'MIT' keytab operation is very different from AD's
+    account-handling for application-servers:
+    a. Host PWs vs service-keys:
+       * Traditional 'MIT' behaviour is for the app-server to use a keytab
+         containing several named random-bitstring service-keys, created
+         by the KDC.  An MIT-style keytab holds a different service-key
+         for every kerberized application-service that the server offers
+         to clients.  Heimdal also implements this behaviour.  MIT's model
+         doesn't use AD's UTF-16 'service password', and no salting is
+         necessary for service-keys, because each service-key is random
+         enough to withstand an exhaustive key-search attack.
+       * In the Windows model, the server key's construction is very
+         different:  The app-server itself, not the KDC, generates a
+         random UTF-16 pseudo-textual password, and sends this password
+         to the KDC using SAMR, a DCE-RPC "domain-joining" protocol (but
+         for windows 7, see below).  Then, the KDC shares this server-
+         password with every application service on the whole machine.
+       * Only when the app-server uses kerberos does the password get
+         salted by the member server (ie, an AD server-host).  (That
+         is, no salt information appears to be conveyed from the AD KDC
+         to the member server, and the member server must use the rules
+         described in Luke's mail, in Appendix 3, below).  The salted-
+         and-hashed version of the server-host's PW gets stored in the
+         server-host's keytab.
+       * Samba file-servers can have many server-names simultaneously
+         (kind of like web servers' software-virtual-hosting), but since
+         these servers are running in AD, these names can be set up to
+         all share the same secret key.  In AD, co-located server names
+         almost always share a secret key like this.  In samba3, this
+         key-sharing was optional, so some samba3 hosts' keytabs did
+         hold multiple keys.  Samba4 abandons this traditional "old MIT"
+         style of keytab, and only supports one key per keytab, and
+         multiple server-names can use that keytab key in common.  In
+         dealing with this model, Samba4 uses both the traditional file
+         keytab and an in-MEMORY keytabs.
+       * Pre-Windows7 AD and samba3/4 both use SAMR, an older protocol,
+         to jumpstart the member server's PW-sharing with AD (the "windows
+         domain-join process").  This PW-sharing transfers only the PW's
+         UTF-16 text, without any salting or hashing, so that non-krb
+         security mechanisms can use the same utf-16 text PW.  For
+         Windows 7, this domain-joining uses LDAP for PW-setting.
+    b. Flexible server-naming
+       * The other big difference between AD's keytabs and MIT's is that
+         Windows offers a lot more flexibility about service-principals'
+         names. When the kerberos server-side library receives Windows-style tickets
+         from an app-client, MIT's krb library (or GSSAPI) must accommodate
+         Windows' flexibility about case-sensitivity and canonicalization.
+         This means that an incoming application-request to a member server
+         may use a wide variety of service-principal names.  These include:
+               machine$@REALM      (samba clients)
+           HOST/foo.bar@realm      (win2k clients)
+           cifs/foo.bar@realm      (winxp clients)
+               HOST/foo@realm      (win2k clients, using netbios)
+               cifs/foo@realm      (winxp clients, using netbios),
+         as well as all upper/lower-case variations on the above.
+    c. Keytabs&   Name-canonicalization
+       * Heimdal's GSSAPI expects to to be called with a principal-name&   a keytab,
+         possibly containing multiple principals' different keys.  However, AD has
+         a different problem to solve, which is that the client may know the member-
+         server by a non-canonicalized principal name, yet AD knows the keytab
+         contains exactly one key, indexed by the canonical name.  So, GSSAPI is
+         unprepared to canonicalize the server-name that the cliet requested, and
+         is also overprepared to do an unnecessary search through the keytab by
+         principal-name.  So Samba's server-side GSSAPI calls have to "game" the
+         GSSAPI, by supplying the server's known canonical name, with the one-key
+         keytab. This doesn't really affect IPA's port of Samba4 to MIT-krb.
+       * Because the number of U/L case combinations 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.
+
+Appendix 2: KDC Plugin for Account-Authorization
+
+Here is how Samba4 ended up doing account-authorization in
+Heimdal, via a specialized KDC plugin.  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 the plugin's AD-specific layer,
+not in the DB-agnostic KDC server:
+    * We created a separate KDC 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 *);
+                                        krb5plugin_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 this KDC plugin to MIT krb.
+    * 1st callback (pac_generate)  creates an initial PAC from the user's AD record.
+    * 2nd callback (pac_verify)    checks that a PAC is correctly signed,
+                                   adds additional groups (for cross-realm tickets)
+                                   and re-signs with the key of the target kerberos
+                                   service's account
+    * 3rd callback (client_access) performs 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 alternative way to register the plugin is with a
+      config-file that names a DSO (Dynamically Shared Object).
+
+Appendix 3: Samba4 stuff that doesn't need to get ported.
+
+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.  No MIT porting task here, as long as MIT kdc
+    doesn't refuse to do some LDAP lookups (eg, alias' realm-name looks
+    wrong).
+* 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.
+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)
+* gsskrb5_extract_authz_data_from_sec_context (get authdata from
+    ticket, ie the PAC.  Must unwrap the data if in an AD-IFRELEVANT)]
+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-IFRELEVANT container.  This doesn't need to be ported to MIT.
+    This should be obsoleted by MIT's new PAC code.
+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.
+* But, libkdc doesn't matter for IPA; Samba invokes the Heimdal kdc
+    as a library call, but this is just a convenience, and the MIT
+    port can do otherwise w/o trouble.)
+Returned Salt for PreAuthentication
+    When the AD-KDC replies to 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@padl.com>
+    >    Organization: PADL Software Pty Ltd
+    >    To: lukeh@padl.com
+    >    Date: Wed, 10 Nov 2004 13:31:21 +1100
+    >    Cc: huaraz@moeller.plus.com, samba-technical@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@mydomain.com]
+    >    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