s3-gse: Allow the GSSAPI wrapper to load a keytab using gss_krb5_import_cred()
authorAndrew Bartlett <abartlet@samba.org>
Fri, 15 Apr 2011 22:50:53 +0000 (08:50 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 20 Apr 2011 02:31:07 +0000 (04:31 +0200)
This Heimdal function does not set the global state, and allows the
GSSAPI server to progress further when compiled against Heimdal (such
as in the top level build).

The ability to specify a keytab has been removed from the API as it is
unused, and and the Heimdal function (avoiding setting global
variables) works with an open keytab.

Andrew Bartlett

source3/configure.in
source3/librpc/crypto/gse.c
source3/librpc/crypto/gse.h
source3/rpc_server/dcesrv_gssapi.c
source3/wscript

index c9518280c75aac97674c561de7e4b0b4b51c9f85..b2c1856beccd2c9c2402f4609a094c4accb10398 100644 (file)
@@ -3860,6 +3860,7 @@ if test x"$with_ads_support" != x"no"; then
   AC_CHECK_FUNC_EXT(krb5_get_credentials_for_user, $KRB5_LIBS)
   AC_CHECK_FUNC_EXT(krb5_get_host_realm, $KRB5_LIBS)
   AC_CHECK_FUNC_EXT(krb5_free_host_realm, $KRB5_LIBS)
+  AC_CHECK_FUNC_EXT(gss_krb5_import_cred, $KRB5_LIBS)
 
   # MIT krb5 1.8 does not expose this call (yet)
   AC_CHECK_DECLS(krb5_get_credentials_for_user, [], [], [#include <krb5.h>])
index 6e3066a9d05117f3f3b319d7ddd2041f642a48a7..0d9eead082edc7f985900e96e6b2e45f5ab09f02 100644 (file)
@@ -342,15 +342,14 @@ done:
 NTSTATUS gse_init_server(TALLOC_CTX *mem_ctx,
                         bool do_sign, bool do_seal,
                         uint32_t add_gss_c_flags,
-                        const char *keytab_name,
                         struct gse_context **_gse_ctx)
 {
        struct gse_context *gse_ctx;
        OM_uint32 gss_maj, gss_min;
-       gss_OID_set_desc mech_set;
        krb5_error_code ret;
-       const char *ktname;
        NTSTATUS status;
+       const char *ktname;
+       gss_OID_set_desc mech_set;
 
        status = gse_context_init(mem_ctx, do_sign, do_seal,
                                  NULL, add_gss_c_flags, &gse_ctx);
@@ -358,27 +357,36 @@ NTSTATUS gse_init_server(TALLOC_CTX *mem_ctx,
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (!keytab_name) {
-               ret = gse_krb5_get_server_keytab(gse_ctx->k5ctx,
-                                                &gse_ctx->keytab);
-               if (ret) {
-                       status = NT_STATUS_INTERNAL_ERROR;
-                       goto done;
-               }
-               ret = smb_krb5_keytab_name(gse_ctx, gse_ctx->k5ctx,
-                                          gse_ctx->keytab, &ktname);
-               if (ret) {
-                       status = NT_STATUS_INTERNAL_ERROR;
-                       goto done;
-               }
-       } else {
-               ktname = keytab_name;
+       ret = gse_krb5_get_server_keytab(gse_ctx->k5ctx,
+                                        &gse_ctx->keytab);
+       if (ret) {
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
        }
 
+#ifdef HAVE_GSS_KRB5_IMPORT_CRED
+       /* This creates a GSSAPI cred_id_t with the principal and keytab set */
+       gss_maj = gss_krb5_import_cred(&gss_min, NULL, NULL, gse_ctx->keytab, 
+                                       &gse_ctx->creds);
+       if (gss_maj) {
+               DEBUG(0, ("gss_krb5_import_cred failed with [%s]\n",
+                         gse_errstr(gse_ctx, gss_maj, gss_min)));
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+#else
        /* FIXME!!!
         * This call sets the default keytab for the whole server, not
         * just for this context. Need to find a way that does not alter
         * the state of the whole server ... */
+
+       ret = smb_krb5_keytab_name(gse_ctx, gse_ctx->k5ctx,
+                                  gse_ctx->keytab, &ktname);
+       if (ret) {
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+
        ret = gsskrb5_register_acceptor_identity(ktname);
        if (ret) {
                status = NT_STATUS_INTERNAL_ERROR;
@@ -387,7 +395,7 @@ NTSTATUS gse_init_server(TALLOC_CTX *mem_ctx,
 
        mech_set.count = 1;
        mech_set.elements = &gse_ctx->gss_mech;
-
+       
        gss_maj = gss_acquire_cred(&gss_min,
                                   GSS_C_NO_NAME,
                                   GSS_C_INDEFINITE,
@@ -395,13 +403,14 @@ NTSTATUS gse_init_server(TALLOC_CTX *mem_ctx,
                                   GSS_C_ACCEPT,
                                   &gse_ctx->creds,
                                   NULL, NULL);
+
        if (gss_maj) {
                DEBUG(0, ("gss_acquire_creds failed with [%s]\n",
                          gse_errstr(gse_ctx, gss_maj, gss_min)));
                status = NT_STATUS_INTERNAL_ERROR;
                goto done;
        }
-
+#endif
        status = NT_STATUS_OK;
 
 done:
@@ -932,7 +941,6 @@ NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx,
 NTSTATUS gse_init_server(TALLOC_CTX *mem_ctx,
                         bool do_sign, bool do_seal,
                         uint32_t add_gss_c_flags,
-                        const char *keytab,
                         struct gse_context **_gse_ctx)
 {
        return NT_STATUS_NOT_IMPLEMENTED;
index a6d9a35a7ffdaf0c913e10625f78d0eedda4e931..fbcf5b6e10d0846bb83a029a188a1ae7cf3e0595 100644 (file)
@@ -42,7 +42,6 @@ NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx,
 NTSTATUS gse_init_server(TALLOC_CTX *mem_ctx,
                         bool do_sign, bool do_seal,
                         uint32_t add_gss_c_flags,
-                        const char *keytab,
                         struct gse_context **_gse_ctx);
 NTSTATUS gse_get_server_auth_token(TALLOC_CTX *mem_ctx,
                                   struct gse_context *gse_ctx,
index c8a015e066c38b70e1c4e1ccdae37d3df5d9e9d3..ec024596332316ef14ef8d45e2cbc0c5aaeb90c3 100644 (file)
@@ -47,7 +47,7 @@ NTSTATUS gssapi_server_auth_start(TALLOC_CTX *mem_ctx,
        /* by passing NULL, the code will attempt to set a default
         * keytab based on configuration options */
        status = gse_init_server(mem_ctx, do_sign, do_seal,
-                                add_flags, NULL, &gse_ctx);
+                                add_flags, &gse_ctx);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("Failed to init dcerpc gssapi server (%s)\n",
                          nt_errstr(status)));
index 2d454c57fa79d66e45da7205e535dfa4dc8785af..673fdf30b90cae94c536001c752e2321cabeea30 100644 (file)
@@ -630,7 +630,7 @@ msg.msg_acctrightslen = sizeof(fd);
         if conf.CHECK_FUNCS_IN('gss_display_status', 'gssapi') or \
            conf.CHECK_FUNCS_IN('gss_display_status', 'gssapi_krb5'):
             have_gssapi=True
-        conf.CHECK_FUNCS_IN('gss_wrap_iov', 'gssapi gssapi_krb5 krb5')
+        conf.CHECK_FUNCS_IN('gss_wrap_iov gss_krb5_import_cred', 'gssapi gssapi_krb5 krb5')
         conf.CHECK_FUNCS_IN('krb5_mk_req_extended krb5_kt_compare', 'krb5')
         conf.CHECK_FUNCS('''
 krb5_set_real_time krb5_set_default_in_tkt_etypes krb5_set_default_tgs_enctypes