From: Simo Sorce Date: Wed, 25 Apr 2012 21:29:09 +0000 (-0400) Subject: Move kerberos_kinit_keyblock_cc to krb5samba lib X-Git-Url: http://git.samba.org/idra/samba.git/?p=idra%2Fsamba.git;a=commitdiff_plain;h=7ddeb293425789ce36468c2368454fd2c95c126c Move kerberos_kinit_keyblock_cc to krb5samba lib Make it also work with MIT where krb5_get_in_tkt_with_keyblock is not available. --- diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c index 10207b58bc4..dfe4302a488 100644 --- a/lib/krb5_wrap/krb5_samba.c +++ b/lib/krb5_wrap/krb5_samba.c @@ -1552,6 +1552,97 @@ krb5_error_code smb_krb5_get_creds(const char *server_s, return ret; } +/* + simulate a kinit, putting the tgt in the given credentials cache. + Orignally by remus@snapserver.com + + This version is built to use a keyblock, rather than needing the + original password. + + The impersonate_principal is the principal if NULL, or the principal + to impersonate + + The target_service defaults to the krbtgt if NULL, but could be + kpasswd/realm or the local service (if we are doing s4u2self) +*/ +krb5_error_code kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc, + krb5_principal principal, + krb5_keyblock *keyblock, + const char *target_service, + krb5_get_init_creds_opt *krb_options, + time_t *expire_time, + time_t *kdc_time) +{ + krb5_error_code code = 0; + krb5_creds my_creds; + +#if defined(HAVE_KRB5_GET_INIT_CREDS_KEYBLOCK) + code = krb5_get_init_creds_keyblock(ctx, &my_creds, principal, + keyblock, 0, target_service, + krb_options); +#elif defined(HAVE_KRB5_GET_INIT_CREDS_KEYTAB) +{ +#define SMB_CREDS_KEYTAB "MEMORY:tmp_smb_creds_XXXXXX" + char *tmp_name[sizeof(SMB_CREDS_KEYTAB)]; + krb5_keytab_entry entry; + krb5_keytab keytab; + + memset(entry, 0, sizeof(entry)); + entry.principal = principal; + entry.key = keyblock; + + memcpy(tmp_name, SMB_CREDS_KEYTAB, sizeof(SMB_CREDS_KEYTAB)) + mktemp(tmp_name); + if (tmp_name[0] == 0) { + return KRB5_KT_BADNAME; + } + code = krb5_kt_resolve(ctx, tmp_name, &keytab); + if (code) { + return code; + } + + code = krb5_kt_add_entry(ctx, keytab, &entry); + if (code) { + (void)krb5_kt_close(ctx, keytab); + goto done; + } + + code = krb5_get_init_creds_keytab(ctx, &my_creds, principal, + keytab, 0, target_service, + krb_options); + (void)krb5_kt_close(ctx, keytab); +} +#else +#error krb5_get_init_creds_keyblock not available! +#endif + if (code) { + return code; + } + + code = krb5_cc_initialize(ctx, cc, principal); + if (code) { + goto done; + } + + code = krb5_cc_store_cred(ctx, cc, &my_creds); + if (code) { + goto done; + } + + if (expire_time) { + *expire_time = (time_t) my_creds.times.endtime; + } + + if (kdc_time) { + *kdc_time = (time_t) my_creds.times.starttime; + } + + code = 0; +done: + krb5_free_cred_contents(ctx, &my_creds); + return code; +} + /* * smb_krb5_principal_get_realm * diff --git a/lib/krb5_wrap/krb5_samba.h b/lib/krb5_wrap/krb5_samba.h index 6a0f9dc2fdc..771c43de44b 100644 --- a/lib/krb5_wrap/krb5_samba.h +++ b/lib/krb5_wrap/krb5_samba.h @@ -198,6 +198,13 @@ krb5_error_code smb_krb5_get_creds(const char *server_s, const char *cc, const char *impersonate_princ_s, krb5_creds **creds_p); +krb5_error_code kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc, + krb5_principal principal, + krb5_keyblock *keyblock, + const char *target_service, + krb5_get_init_creds_opt *krb_options, + time_t *expire_time, + time_t *kdc_time); char *smb_krb5_principal_get_realm(krb5_context context, krb5_principal principal); diff --git a/source4/auth/kerberos/kerberos.c b/source4/auth/kerberos/kerberos.c index 0fc9d143abd..b4e989d2aea 100644 --- a/source4/auth/kerberos/kerberos.c +++ b/source4/auth/kerberos/kerberos.c @@ -27,54 +27,6 @@ #ifdef HAVE_KRB5 -/* - simulate a kinit, putting the tgt in the given credentials cache. - Orignally by remus@snapserver.com - - This version is built to use a keyblock, rather than needing the - original password. - - The impersonate_principal is the principal if NULL, or the principal to impersonate - - The target_service defaults to the krbtgt if NULL, but could be kpasswd/realm or the local service (if we are doing s4u2self) -*/ - krb5_error_code kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc, - krb5_principal principal, krb5_keyblock *keyblock, - const char *target_service, - krb5_get_init_creds_opt *krb_options, - time_t *expire_time, time_t *kdc_time) -{ - krb5_error_code code = 0; - krb5_creds my_creds; - - if ((code = krb5_get_init_creds_keyblock(ctx, &my_creds, principal, keyblock, - 0, target_service, krb_options))) { - return code; - } - - if ((code = krb5_cc_initialize(ctx, cc, principal))) { - krb5_free_cred_contents(ctx, &my_creds); - return code; - } - - if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) { - krb5_free_cred_contents(ctx, &my_creds); - return code; - } - - if (expire_time) { - *expire_time = (time_t) my_creds.times.endtime; - } - - if (kdc_time) { - *kdc_time = (time_t) my_creds.times.starttime; - } - - krb5_free_cred_contents(ctx, &my_creds); - - return 0; -} - /* simulate a kinit, putting the tgt in the given credentials cache. Orignally by remus@snapserver.com diff --git a/source4/auth/kerberos/kerberos.h b/source4/auth/kerberos/kerberos.h index cc02aee27f5..018f6b80b10 100644 --- a/source4/auth/kerberos/kerberos.h +++ b/source4/auth/kerberos/kerberos.h @@ -74,13 +74,6 @@ const krb5_data *krb5_princ_component(krb5_context context, krb5_principal princ #endif /* Samba wrapper function for krb5 functionality. */ -krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, - krb5_principal principal, const char *password, - krb5_principal impersonate_principal, - const char *self_service, - const char *target_service, - krb5_get_init_creds_opt *krb_options, - time_t *expire_time, time_t *kdc_time); krb5_error_code kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc, krb5_principal principal, krb5_keyblock *keyblock, const char *target_service, diff --git a/source4/heimdal_build/wscript_configure b/source4/heimdal_build/wscript_configure old mode 100644 new mode 100755 index 1c03b341069..63838802293 --- a/source4/heimdal_build/wscript_configure +++ b/source4/heimdal_build/wscript_configure @@ -114,6 +114,7 @@ conf.define('HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC', 1) conf.define('HAVE_KRB5_GET_INIT_CREDS_OPT_FREE', 1) conf.define('HAVE_KRB5_GET_INIT_CREDS_OPT_GET_ERROR', 1) conf.define('HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST', 1) +conf.define('HAVE_KRB5_GET_INIT_CREDS_KEYBLOCK', 1) conf.define('HAVE_KRB5_GET_PW_SALT', 1) conf.define('HAVE_KRB5_GET_RENEWED_CREDS', 1) conf.define('HAVE_KRB5_KEYBLOCK_KEYVALUE', 1) diff --git a/wscript_configure_krb5 b/wscript_configure_krb5 index 6147bf5c243..efeb6a15616 100644 --- a/wscript_configure_krb5 +++ b/wscript_configure_krb5 @@ -61,7 +61,8 @@ conf.CHECK_FUNCS(''' krb5_get_init_creds_opt_free krb5_get_init_creds_opt_get_error krb5_enctype_to_string krb5_fwd_tgt_creds krb5_auth_con_set_req_cksumtype krb5_get_creds_opt_alloc krb5_get_creds_opt_set_impersonate krb5_get_creds - krb5_get_credentials_for_user krb5_get_host_realm krb5_free_host_realm''', + krb5_get_credentials_for_user krb5_get_host_realm krb5_free_host_realm + krb5_get_init_creds_keyblock krb5_get_init_creds_keytab''', lib='krb5 k5crypto') conf.CHECK_DECLS('''krb5_get_credentials_for_user krb5_auth_con_set_req_cksumtype''',