From 3a2afe4285fca8ab9e3e323ef7f5388f4090d669 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 16 Apr 2011 08:50:53 +1000 Subject: s3-gse: Allow the GSSAPI wrapper to load a keytab using gss_krb5_import_cred() 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 | 1 + source3/librpc/crypto/gse.c | 50 ++++++++++++++++++++++---------------- source3/librpc/crypto/gse.h | 1 - source3/rpc_server/dcesrv_gssapi.c | 2 +- source3/wscript | 2 +- 5 files changed, 32 insertions(+), 24 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index c9518280c7..b2c1856bec 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -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 ]) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index 6e3066a9d0..0d9eead082 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -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; diff --git a/source3/librpc/crypto/gse.h b/source3/librpc/crypto/gse.h index a6d9a35a7f..fbcf5b6e10 100644 --- a/source3/librpc/crypto/gse.h +++ b/source3/librpc/crypto/gse.h @@ -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, diff --git a/source3/rpc_server/dcesrv_gssapi.c b/source3/rpc_server/dcesrv_gssapi.c index c8a015e066..ec02459633 100644 --- a/source3/rpc_server/dcesrv_gssapi.c +++ b/source3/rpc_server/dcesrv_gssapi.c @@ -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))); diff --git a/source3/wscript b/source3/wscript index 2d454c57fa..673fdf30b9 100644 --- a/source3/wscript +++ b/source3/wscript @@ -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 -- cgit