heimdal: Match windows and return KRB5KDC_ERR_CLIENT_REVOKED when the account is...
[metze/heimdal/wip.git] / kdc / kerberos5.c
index 7f780da3a0659eb34bef57e0260966c4ecce24dc..027f8dff2933cc8d30d757b140ad4c108b9bc3ba 100644 (file)
@@ -433,6 +433,7 @@ pa_pkinit_validate(astgs_request_t r, const PA_DATA *pa)
        _kdc_set_e_text(r, "Failed to build PK-INIT reply");
        goto out;
     }
+    r->reply_kvno = 0;
 #if 0
     ret = _kdc_add_initial_verified_cas(r->context, r->config,
                                        pkp, &r->et);
@@ -518,6 +519,14 @@ pa_enc_chal_validate(astgs_request_t r, const PA_DATA *pa)
        return ret;
     }
 
+    if (r->client->entry.flags.locked_out) {
+       ret = KRB5KDC_ERR_CLIENT_REVOKED;
+       kdc_log(r->context, r->config, 0,
+               "Client (%s) is locked out", r->client_name);
+       return ret;
+    }
+
+
     ret = decode_EncryptedData(pa->padata_value.data,
                               pa->padata_value.length,
                               &enc_data,
@@ -628,6 +637,8 @@ pa_enc_chal_validate(astgs_request_t r, const PA_DATA *pa)
        if (ret)
            goto out;
 
+       r->reply_kvno = 0;
+
        /*
         * Success
         */
@@ -659,7 +670,14 @@ pa_enc_ts_validate(astgs_request_t r, const PA_DATA *pa)
     size_t len;
     Key *pa_key;
     char *str;
-       
+
+    if (r->client->entry.flags.locked_out) {
+       ret = KRB5KDC_ERR_CLIENT_REVOKED;
+       kdc_log(r->context, r->config, 0,
+               "Client (%s) is locked out", r->client_name);
+       return ret;
+    }
+
     ret = decode_EncryptedData(pa->padata_value.data,
                               pa->padata_value.length,
                               &enc_data,
@@ -783,6 +801,12 @@ pa_enc_ts_validate(astgs_request_t r, const PA_DATA *pa)
     if (ret)
        return ret;
 
+    if (pa_key->mkvno != NULL) {
+       r->reply_kvno = *pa_key->mkvno;
+    } else {
+       r->reply_kvno = r->client->entry.kvno;
+    }
+
     ret = krb5_enctype_to_string(r->context, pa_key->key.keytype, &str);
     if (ret)
        str = NULL;
@@ -1463,7 +1487,7 @@ kdc_check_flags(astgs_request_t r, krb5_boolean is_as_req)
        /* check client */
        if (client->flags.locked_out) {
            _kdc_audit_addreason((kdc_request_t)r, "Client is locked out");
-           return KRB5KDC_ERR_POLICY;
+           return KRB5KDC_ERR_CLIENT_REVOKED;
        }
 
        if (client->flags.invalid) {
@@ -1667,10 +1691,19 @@ static krb5_error_code
 generate_pac(astgs_request_t r, Key *skey)
 {
     krb5_error_code ret;
+    const krb5_keyblock *pk_reply_key = NULL;
     krb5_pac p = NULL;
     krb5_data data;
 
-    ret = _kdc_pac_generate(r->context, r->client, &p);
+    switch (r->validated_pa_type) {
+    case KRB5_PADATA_PK_AS_REQ:
+    case KRB5_PADATA_PK_AS_REQ_WIN:
+       pk_reply_key = &r->reply_key;
+       break;
+    }
+
+    ret = _kdc_pac_generate(r->context, r->client,
+                           pk_reply_key, &p);
     if (ret) {
        _kdc_r_log(r, 4, "PAC generation failed for -- %s",
                   r->cname);
@@ -1977,6 +2010,7 @@ _kdc_as_rep(astgs_request_t r)
                        pat[n].name, r->cname);
                found_pa = 1;
                r->et.flags.pre_authent = 1;
+               r->validated_pa_type = pat[n].type;
            }
        }
     }
@@ -2027,6 +2061,8 @@ _kdc_as_rep(astgs_request_t r)
        ret = krb5_copy_keyblock_contents(r->context, &ckey->key, &r->reply_key);
        if (ret)
            goto out;
+
+       r->reply_kvno = 0;
     }
 
     if (r->clientdb->hdb_auth_status) {
@@ -2374,7 +2410,7 @@ _kdc_as_rep(astgs_request_t r)
                            r->armor_crypto, req->req_body.nonce,
                            &rep, &r->et, &r->ek, setype,
                            r->server->entry.kvno, &skey->key,
-                           r->client->entry.kvno,
+                           r->reply_kvno,
                            &r->reply_key, 0, &r->e_text, r->reply);
     if (ret)
        goto out;