diff options
Diffstat (limited to 'source3/libads')
-rw-r--r-- | source3/libads/kerberos_verify.c | 95 |
1 files changed, 58 insertions, 37 deletions
diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 4d7bb8d20b..c07259394b 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -307,8 +307,10 @@ static krb5_error_code ads_secrets_verify_ticket(krb5_context context, { krb5_error_code ret = 0; bool auth_ok = False; + bool cont = true; char *password_s = NULL; - krb5_data password; + /* Let's make some room for 2 password (old and new)*/ + krb5_data passwords[2]; krb5_enctype enctypes[] = { #if defined(ENCTYPE_ARCFOUR_HMAC) ENCTYPE_ARCFOUR_HMAC, @@ -318,12 +320,13 @@ static krb5_error_code ads_secrets_verify_ticket(krb5_context context, ENCTYPE_NULL }; krb5_data packet; - int i; + int i, j; *pp_tkt = NULL; *keyblock = NULL; *perr = 0; + ZERO_STRUCT(passwords); if (!secrets_init()) { DEBUG(1,("ads_secrets_verify_ticket: secrets_init failed\n")); @@ -338,8 +341,15 @@ static krb5_error_code ads_secrets_verify_ticket(krb5_context context, return False; } - password.data = password_s; - password.length = strlen(password_s); + passwords[0].data = password_s; + passwords[0].length = strlen(password_s); + + password_s = secrets_fetch_prev_machine_password(lp_workgroup()); + if (password_s) { + DEBUG(10,("ads_secrets_verify_ticket: found previous password\n")); + passwords[1].data = password_s; + passwords[1].length = strlen(password_s); + } /* CIFS doesn't use addresses in tickets. This would break NAT. JRA */ @@ -347,50 +357,61 @@ static krb5_error_code ads_secrets_verify_ticket(krb5_context context, packet.data = (char *)ticket->data; /* We need to setup a auth context with each possible encoding type in turn. */ - for (i=0;enctypes[i];i++) { - krb5_keyblock *key = NULL; + for (j=0; j<2 && passwords[j].length; j++) { - if (!(key = SMB_MALLOC_P(krb5_keyblock))) { - ret = ENOMEM; - goto out; - } - - if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i], false)) { - SAFE_FREE(key); - continue; - } + for (i=0;enctypes[i];i++) { + krb5_keyblock *key = NULL; - krb5_auth_con_setuseruserkey(context, auth_context, key); + if (!(key = SMB_MALLOC_P(krb5_keyblock))) { + ret = ENOMEM; + goto out; + } - if (!(ret = krb5_rd_req(context, &auth_context, &packet, - NULL, - NULL, NULL, pp_tkt))) { - DEBUG(10,("ads_secrets_verify_ticket: enc type [%u] decrypted message !\n", - (unsigned int)enctypes[i] )); - auth_ok = True; - krb5_copy_keyblock(context, key, keyblock); - krb5_free_keyblock(context, key); - break; - } + if (create_kerberos_key_from_string(context, host_princ, &passwords[j], key, enctypes[i], false)) { + SAFE_FREE(key); + continue; + } + + krb5_auth_con_setuseruserkey(context, auth_context, key); + + if (!(ret = krb5_rd_req(context, &auth_context, &packet, + NULL, + NULL, NULL, pp_tkt))) { + DEBUG(10,("ads_secrets_verify_ticket: enc type [%u] decrypted message !\n", + (unsigned int)enctypes[i] )); + auth_ok = True; + cont = false; + krb5_copy_keyblock(context, key, keyblock); + krb5_free_keyblock(context, key); + break; + } - DEBUG((ret != KRB5_BAD_ENCTYPE) ? 3 : 10, - ("ads_secrets_verify_ticket: enc type [%u] failed to decrypt with error %s\n", - (unsigned int)enctypes[i], error_message(ret))); + DEBUG((ret != KRB5_BAD_ENCTYPE) ? 3 : 10, + ("ads_secrets_verify_ticket: enc type [%u] failed to decrypt with error %s\n", + (unsigned int)enctypes[i], error_message(ret))); + + /* successfully decrypted but ticket is just not valid at the moment */ + if (ret == KRB5KRB_AP_ERR_TKT_NYV || + ret == KRB5KRB_AP_ERR_TKT_EXPIRED || + ret == KRB5KRB_AP_ERR_SKEW) { + krb5_free_keyblock(context, key); + cont = false; + break; + } - /* successfully decrypted but ticket is just not valid at the moment */ - if (ret == KRB5KRB_AP_ERR_TKT_NYV || - ret == KRB5KRB_AP_ERR_TKT_EXPIRED || - ret == KRB5KRB_AP_ERR_SKEW) { krb5_free_keyblock(context, key); + } + if (!cont) { + /* If we found a valid pass then no need to try + * the next one or we have invalid ticket so no need + * to try next password*/ break; } - - krb5_free_keyblock(context, key); - } out: - SAFE_FREE(password_s); + SAFE_FREE(passwords[0].data); + SAFE_FREE(passwords[1].data); *perr = ret; return auth_ok; } |