gensec_krb5: Implement smb_krb5_rd_req_decoded() with MIT Kerberos
authorAndreas Schneider <asn@samba.org>
Thu, 11 Aug 2016 09:29:53 +0000 (11:29 +0200)
committerGünther Deschner <gd@samba.org>
Thu, 29 Sep 2016 09:56:41 +0000 (11:56 +0200)
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
Autobuild-User(master): Günther Deschner <gd@samba.org>
Autobuild-Date(master): Thu Sep 29 11:56:41 CEST 2016 on sn-devel-144

source4/auth/gensec/gensec_krb5.c
source4/auth/gensec/gensec_krb5_mit.c [new file with mode: 0644]
source4/auth/gensec/wscript_build

index 24b556f8bf28dd6141595d43d94e986fb13e2f5a..e1ac73675429f8e64784e0569527f5aac2b58d81 100644 (file)
@@ -664,6 +664,7 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security,
                                              &gensec_krb5_state->keyblock);
 
                if (ret) {
+                       DBG_WARNING("smb_krb5_rd_req_decoded failed\n");
                        return NT_STATUS_LOGON_FAILURE;
                }
                unwrapped_out.data = (uint8_t *)outbuf.data;
diff --git a/source4/auth/gensec/gensec_krb5_mit.c b/source4/auth/gensec/gensec_krb5_mit.c
new file mode 100644 (file)
index 0000000..f7b3129
--- /dev/null
@@ -0,0 +1,102 @@
+
+#include "includes.h"
+#include "system/kerberos.h"
+#include "auth/kerberos/kerberos.h"
+#include "gensec_krb5.h"
+
+static krb5_error_code smb_krb5_get_longterm_key(krb5_context context,
+                                                krb5_const_principal server,
+                                                krb5_kvno kvno,
+                                                krb5_enctype etype,
+                                                krb5_keytab keytab,
+                                                krb5_keyblock **keyblock_out)
+{
+       krb5_error_code code = EINVAL;
+
+       krb5_keytab_entry kt_entry;
+
+       code = krb5_kt_get_entry(context,
+                                keytab,
+                                server,
+                                kvno,
+                                etype,
+                                &kt_entry);
+       if (code != 0) {
+               return code;
+       }
+
+       code = krb5_copy_keyblock(context,
+                                 &kt_entry.key,
+                                 keyblock_out);
+       krb5_free_keytab_entry_contents(context, &kt_entry);
+
+       return code;
+}
+
+krb5_error_code smb_krb5_rd_req_decoded(krb5_context context,
+                                       krb5_auth_context *auth_context,
+                                       const krb5_data *request,
+                                       krb5_keytab keytab,
+                                       krb5_principal acceptor_principal,
+                                       krb5_data *reply,
+                                       krb5_ticket **pticket,
+                                       krb5_keyblock **pkeyblock)
+{
+       krb5_error_code code;
+       krb5_flags ap_req_options = 0;
+       krb5_ticket *ticket = NULL;
+       krb5_keyblock *keyblock = NULL;
+
+       *pticket = NULL;
+       *pkeyblock = NULL;
+       reply->length = 0;
+       reply->data = NULL;
+
+       code = krb5_rd_req(context,
+                          auth_context,
+                          request,
+                          acceptor_principal,
+                          keytab,
+                          &ap_req_options,
+                          &ticket);
+       if (code != 0) {
+               DBG_ERR("krb5_rd_req failed: %s\n",
+                       error_message(code));
+               return code;
+       }
+
+       /*
+        * Get the long term key from the keytab to be able to verify the PAC
+        * signature.
+        *
+        * FIXME: Use ticket->enc_part.kvno ???
+        * Getting the latest kvno with passing 0 fixes:
+        * make -j test TESTS="samba4.winbind.pac.ad_member"
+        */
+       code = smb_krb5_get_longterm_key(context,
+                                        ticket->server,
+                                        0, /* kvno */
+                                        ticket->enc_part.enctype,
+                                        keytab,
+                                        &keyblock);
+       if (code != 0) {
+               DBG_ERR("smb_krb5_get_longterm_key failed: %s\n",
+                       error_message(code));
+               krb5_free_ticket(context, ticket);
+
+               return code;
+       }
+
+       code = krb5_mk_rep(context, *auth_context, reply);
+       if (code != 0) {
+               DBG_ERR("krb5_mk_rep failed: %s\n",
+                       error_message(code));
+               krb5_free_ticket(context, ticket);
+               krb5_free_keyblock(context, keyblock);
+       }
+
+       *pticket = ticket;
+       *pkeyblock = keyblock;
+
+       return code;
+}
index c4e69183b28af2c65d95a5f544a3316b0f3103c7..a1d30a94af9bd214e4003d0e5c2f22daa84c9aba 100755 (executable)
@@ -5,13 +5,17 @@ bld.SAMBA_SUBSYSTEM('gensec_util',
                     deps='tevent-util tevent samba-util LIBTSOCKET',
                     autoproto='gensec_proto.h')
 
+gensec_krb5_sources = 'gensec_krb5_heimdal.c'
+if bld.CONFIG_SET('SAMBA_USES_MITKDC'):
+    gensec_krb5_sources = 'gensec_krb5_mit.c'
+
 bld.SAMBA_MODULE('gensec_krb5',
-       source='gensec_krb5.c gensec_krb5_heimdal.c',
+       source='gensec_krb5.c ' + gensec_krb5_sources,
        subsystem='gensec',
        init_function='gensec_krb5_init',
        deps='samba-credentials authkrb5 com_err gensec_util',
        internal_module=False,
-        enabled=bld.AD_DC_BUILD_IS_ENABLED() and bld.CONFIG_SET('SAMBA4_USES_HEIMDAL')
+        enabled=bld.AD_DC_BUILD_IS_ENABLED()
        )