diff options
-rw-r--r-- | source3/libads/kerberos_verify.c | 102 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_pam.c | 2 | ||||
-rw-r--r-- | source3/smbd/sesssetup.c | 4 | ||||
-rw-r--r-- | source3/utils/ntlm_auth.c | 2 |
4 files changed, 68 insertions, 42 deletions
diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index ca36e6e425..ecd0f0869c 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -214,7 +214,14 @@ static krb5_error_code ads_secrets_verify_ticket(krb5_context context, BOOL auth_ok = False; char *password_s = NULL; krb5_data password; - krb5_enctype enctypes[4] = { ENCTYPE_DES_CBC_CRC, ENCTYPE_DES_CBC_MD5, 0, 0 }; + krb5_enctype enctypes[] = { +#if defined(ENCTYPE_ARCFOUR_HMAC) + ENCTYPE_ARCFOUR_HMAC, +#endif + ENCTYPE_DES_CBC_CRC, + ENCTYPE_DES_CBC_MD5, + ENCTYPE_NULL + }; krb5_data packet; int i; @@ -222,9 +229,6 @@ static krb5_error_code ads_secrets_verify_ticket(krb5_context context, *keyblock = NULL; *perr = 0; -#if defined(ENCTYPE_ARCFOUR_HMAC) - enctypes[2] = ENCTYPE_ARCFOUR_HMAC; -#endif if (!secrets_init()) { DEBUG(1,("ads_secrets_verify_ticket: secrets_init failed\n")); @@ -307,7 +311,8 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, char **principal, PAC_DATA **pac_data, DATA_BLOB *ap_rep, - DATA_BLOB *session_key) + DATA_BLOB *session_key, + BOOL use_replay_cache) { NTSTATUS sret = NT_STATUS_LOGON_FAILURE; NTSTATUS pac_ret; @@ -320,7 +325,7 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, krb5_keyblock *keyblock = NULL; time_t authtime; krb5_error_code ret = 0; - + krb5_int32 flags = 0; krb5_principal host_princ = NULL; krb5_const_principal client_principal = NULL; char *host_princ_s = NULL; @@ -363,6 +368,13 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, goto out; } + krb5_auth_con_getflags( context, auth_context, &flags ); + if ( !use_replay_cache ) { + /* Disable default use of a replay cache */ + flags &= ~KRB5_AUTH_CONTEXT_DO_TIME; + krb5_auth_con_setflags( context, auth_context, flags ); + } + asprintf(&host_princ_s, "%s$", global_myname()); if (!host_princ_s) { goto out; @@ -377,50 +389,62 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, } - /* Lock a mutex surrounding the replay as there is no locking in the MIT krb5 - * code surrounding the replay cache... */ + if ( use_replay_cache ) { + + /* Lock a mutex surrounding the replay as there is no + locking in the MIT krb5 code surrounding the replay + cache... */ - if (!grab_server_mutex("replay cache mutex")) { - DEBUG(1,("ads_verify_ticket: unable to protect replay cache with mutex.\n")); - ret = KRB5_CC_IO; - goto out; - } + if (!grab_server_mutex("replay cache mutex")) { + DEBUG(1,("ads_verify_ticket: unable to protect " + "replay cache with mutex.\n")); + ret = KRB5_CC_IO; + goto out; + } - got_replay_mutex = True; + got_replay_mutex = True; - /* - * JRA. We must set the rcache here. This will prevent replay attacks. - */ + /* JRA. We must set the rcache here. This will prevent + replay attacks. */ + + ret = krb5_get_server_rcache(context, + krb5_princ_component(context, host_princ, 0), + &rcache); + if (ret) { + DEBUG(1,("ads_verify_ticket: krb5_get_server_rcache " + "failed (%s)\n", error_message(ret))); + goto out; + } - ret = krb5_get_server_rcache(context, krb5_princ_component(context, host_princ, 0), &rcache); - if (ret) { - DEBUG(1,("ads_verify_ticket: krb5_get_server_rcache failed (%s)\n", error_message(ret))); - goto out; + ret = krb5_auth_con_setrcache(context, auth_context, rcache); + if (ret) { + DEBUG(1,("ads_verify_ticket: krb5_auth_con_setrcache " + "failed (%s)\n", error_message(ret))); + goto out; + } } - ret = krb5_auth_con_setrcache(context, auth_context, rcache); - if (ret) { - DEBUG(1,("ads_verify_ticket: krb5_auth_con_setrcache failed (%s)\n", error_message(ret))); - goto out; - } + /* Try secrets.tdb first and fallback to the krb5.keytab if + necessary */ - if (lp_use_kerberos_keytab()) { - auth_ok = ads_keytab_verify_ticket(context, auth_context, ticket, &tkt, &keyblock, &ret); - } - if (!auth_ok) { - auth_ok = ads_secrets_verify_ticket(context, auth_context, host_princ, - ticket, &tkt, &keyblock, &ret); - } + auth_ok = ads_secrets_verify_ticket(context, auth_context, host_princ, + ticket, &tkt, &keyblock, &ret); - release_server_mutex(); - got_replay_mutex = False; + if (!auth_ok && lp_use_kerberos_keytab()) { + auth_ok = ads_keytab_verify_ticket(context, auth_context, + ticket, &tkt, &keyblock, &ret); + } + if ( use_replay_cache ) { + release_server_mutex(); + got_replay_mutex = False; #if 0 - /* Heimdal leaks here, if we fix the leak, MIT crashes */ - if (rcache) { - krb5_rc_close(context, rcache); - } + /* Heimdal leaks here, if we fix the leak, MIT crashes */ + if (rcache) { + krb5_rc_close(context, rcache); + } #endif + } if (!auth_ok) { DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index 9653e6c876..9c0b642b94 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -615,7 +615,7 @@ static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain, &client_princ_out, &pac_data, &ap_rep, - &session_key); + &session_key, False); if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("winbindd_raw_kerberos_login: ads_verify_ticket failed: %s\n", nt_errstr(result))); diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 42a71f8ad7..22c598a654 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -270,7 +270,9 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } - ret = ads_verify_ticket(mem_ctx, lp_realm(), 0, &ticket, &client, &pac_data, &ap_rep, &session_key); + ret = ads_verify_ticket(mem_ctx, lp_realm(), 0, &ticket, + &client, &pac_data, &ap_rep, + &session_key, True); data_blob_free(&ticket); diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 4a74db6b4a..a2b41660b5 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -1169,7 +1169,7 @@ static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode, status = ads_verify_ticket(mem_ctx, lp_realm(), 0, &request.negTokenInit.mechToken, &principal, NULL, &ap_rep, - &session_key); + &session_key, True); talloc_destroy(mem_ctx); |