diff options
-rw-r--r-- | source4/heimdal/kdc/kdc-private.h | 3 | ||||
-rw-r--r-- | source4/heimdal/kdc/kerberos5.c | 2 | ||||
-rw-r--r-- | source4/heimdal/kdc/windc.c | 5 | ||||
-rw-r--r-- | source4/heimdal/kdc/windc_plugin.h | 2 | ||||
-rw-r--r-- | source4/kdc/pac-glue.c | 67 |
5 files changed, 57 insertions, 22 deletions
diff --git a/source4/heimdal/kdc/kdc-private.h b/source4/heimdal/kdc/kdc-private.h index 030be9ae58..4052e9b509 100644 --- a/source4/heimdal/kdc/kdc-private.h +++ b/source4/heimdal/kdc/kdc-private.h @@ -281,6 +281,7 @@ krb5_error_code _kdc_windc_client_access ( krb5_context /*context*/, struct hdb_entry_ex */*client*/, - KDC_REQ */*req*/); + KDC_REQ */*req*/, + krb5_data */*e_data*/); #endif /* __kdc_private_h__ */ diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c index bc600a5319..f1dea6499d 100644 --- a/source4/heimdal/kdc/kerberos5.c +++ b/source4/heimdal/kdc/kerberos5.c @@ -1050,7 +1050,7 @@ _kdc_as_rep(krb5_context context, goto out; } - ret = _kdc_windc_client_access(context, client, req); + ret = _kdc_windc_client_access(context, client, req, &e_data); if(ret) goto out; diff --git a/source4/heimdal/kdc/windc.c b/source4/heimdal/kdc/windc.c index 395ab73432..85e4d7f725 100644 --- a/source4/heimdal/kdc/windc.c +++ b/source4/heimdal/kdc/windc.c @@ -101,9 +101,10 @@ _kdc_pac_verify(krb5_context context, krb5_error_code _kdc_windc_client_access(krb5_context context, struct hdb_entry_ex *client, - KDC_REQ *req) + KDC_REQ *req, + krb5_data *e_data) { if (windcft == NULL) return 0; - return (windcft->client_access)(windcctx, context, client, req); + return (windcft->client_access)(windcctx, context, client, req, e_data); } diff --git a/source4/heimdal/kdc/windc_plugin.h b/source4/heimdal/kdc/windc_plugin.h index ec480cf950..3ae0c94681 100644 --- a/source4/heimdal/kdc/windc_plugin.h +++ b/source4/heimdal/kdc/windc_plugin.h @@ -64,7 +64,7 @@ typedef krb5_error_code typedef krb5_error_code (*krb5plugin_windc_client_access)( - void *, krb5_context, struct hdb_entry_ex *, KDC_REQ *); + void *, krb5_context, struct hdb_entry_ex *, KDC_REQ *, krb5_data *); #define KRB5_WINDC_PLUGING_MINOR 2 diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c index 66f36af870..f65bd67ab1 100644 --- a/source4/kdc/pac-glue.c +++ b/source4/kdc/pac-glue.c @@ -220,13 +220,48 @@ krb5_error_code samba_kdc_reget_pac(void *priv, krb5_context context, return ret; } +static void samba_kdc_build_edata_reply(TALLOC_CTX *tmp_ctx, krb5_data *e_data, + NTSTATUS nt_status) +{ + PA_DATA pa; + unsigned char *buf; + size_t len; + krb5_error_code ret = 0; + uint32_t *tmp; + + if (!e_data) + return; + + pa.padata_type = KRB5_PADATA_PW_SALT; + pa.padata_value.length = 12; + pa.padata_value.data = malloc(pa.padata_value.length); + if (!pa.padata_value.data) { + e_data->length = 0; + e_data->data = NULL; + return; + } + + SIVAL(pa.padata_value.data, 0, NT_STATUS_V(nt_status)); + SIVAL(pa.padata_value.data, 4, 0); + SIVAL(pa.padata_value.data, 8, 1); + + ASN1_MALLOC_ENCODE(PA_DATA, buf, len, &pa, &len, ret); + free(pa.padata_value.data); + + e_data->data = buf; + e_data->length = len; + + return; +} + /* Given an hdb entry (and in particular it's private member), consult * the account_ok routine in auth/auth_sam.c for consistancy */ krb5_error_code samba_kdc_check_client_access(void *priv, krb5_context context, hdb_entry_ex *entry_ex, - KDC_REQ *req) + KDC_REQ *req, + krb5_data *e_data) { krb5_error_code ret; NTSTATUS nt_status; @@ -274,30 +309,28 @@ krb5_error_code samba_kdc_check_client_access(void *priv, name); free(name); - /* TODO: Need a more complete mapping of NTSTATUS to krb5kdc errors */ - - /* TODO: Also need to add the appropriate e-data struct of type - * PA-PW-SALT (3) that includes the NT_STATUS code, which gives Windows - * the information it needs to display the appropriate dialog. */ + if (NT_STATUS_IS_OK(nt_status)) + return 0; if (NT_STATUS_EQUAL(nt_status, NT_STATUS_PASSWORD_MUST_CHANGE)) - return KRB5KDC_ERR_KEY_EXPIRED; + ret = KRB5KDC_ERR_KEY_EXPIRED; else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_PASSWORD_EXPIRED)) - return KRB5KDC_ERR_KEY_EXPIRED; + ret = KRB5KDC_ERR_KEY_EXPIRED; else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCOUNT_EXPIRED)) - return KRB5KDC_ERR_CLIENT_REVOKED; + ret = KRB5KDC_ERR_CLIENT_REVOKED; else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCOUNT_DISABLED)) - return KRB5KDC_ERR_CLIENT_REVOKED; + ret = KRB5KDC_ERR_CLIENT_REVOKED; else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_LOGON_HOURS)) - return KRB5KDC_ERR_CLIENT_REVOKED; + ret = KRB5KDC_ERR_CLIENT_REVOKED; else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCOUNT_LOCKED_OUT)) - return KRB5KDC_ERR_CLIENT_REVOKED; + ret = KRB5KDC_ERR_CLIENT_REVOKED; else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_WORKSTATION)) - return KRB5KDC_ERR_POLICY; - else if (!NT_STATUS_IS_OK(nt_status)) { - return KRB5KDC_ERR_POLICY; - } + ret = KRB5KDC_ERR_POLICY; + else + ret = KRB5KDC_ERR_POLICY; - return 0; + samba_kdc_build_edata_reply(tmp_ctx, e_data, nt_status); + + return ret; } |