summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/heimdal/kdc/kdc-private.h3
-rw-r--r--source4/heimdal/kdc/kerberos5.c2
-rw-r--r--source4/heimdal/kdc/windc.c5
-rw-r--r--source4/heimdal/kdc/windc_plugin.h2
-rw-r--r--source4/kdc/pac-glue.c67
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;
}