summaryrefslogtreecommitdiff
path: root/source4/heimdal
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2015-02-10 14:37:29 +0100
committerStefan Metzmacher <metze@samba.org>2015-07-08 18:38:20 +0200
commit2d98800219e1bc434cccc09322b4b509879d2a7d (patch)
tree2571c63cea743263ddaa012caede38b74a7d4b05 /source4/heimdal
parentc63f3607881154e1bf86bdd1009f9cdec4a47576 (diff)
downloadsamba-2d98800219e1bc434cccc09322b4b509879d2a7d.tar.gz
heimdal:kdc: add support for HDB_ERR_WRONG_REALM
A backend can return this if asked with HDB_F_GET_CLIENT|HDB_F_FOR_AS_REQ for a KRB5_NT_ENTERPRISE_PRINCIPAL record or for HDB_F_GET_SERVER | HDB_F_FOR_TGS_REQ. entry_ex->entry.principal->realm needs to return the real realm of the principal (or at least a the realm of the next cross-realm trust hop). This is needed to route enterprise principals between AD domain trusts. Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'source4/heimdal')
-rw-r--r--source4/heimdal/kdc/kerberos5.c26
-rw-r--r--source4/heimdal/kdc/krb5tgs.c26
-rw-r--r--source4/heimdal/kdc/misc.c7
-rw-r--r--source4/heimdal/lib/hdb/hdb_err.et1
4 files changed, 59 insertions, 1 deletions
diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c
index cb97390d3e3..7e7aefd21e5 100644
--- a/source4/heimdal/kdc/kerberos5.c
+++ b/source4/heimdal/kdc/kerberos5.c
@@ -1060,6 +1060,30 @@ _kdc_as_rep(krb5_context context,
if(ret == HDB_ERR_NOT_FOUND_HERE) {
kdc_log(context, config, 5, "client %s does not have secrets at this KDC, need to proxy", client_name);
goto out;
+ } else if (ret == HDB_ERR_WRONG_REALM) {
+ char *fixed_client_name = NULL;
+
+ ret = krb5_unparse_name(context, client->entry.principal,
+ &fixed_client_name);
+ if (ret) {
+ goto out;
+ }
+
+ kdc_log(context, config, 0, "WRONG_REALM - %s -> %s",
+ client_name, fixed_client_name);
+ free(fixed_client_name);
+
+ ret = krb5_mk_error_ext(context,
+ KRB5_KDC_ERR_WRONG_REALM,
+ NULL, /* e_text */
+ NULL, /* e_data */
+ server_princ,
+ NULL, /* client_name */
+ &client->entry.principal->realm,
+ NULL, /* client_time */
+ NULL, /* client_usec */
+ reply);
+ goto out;
} else if(ret){
const char *msg = krb5_get_error_message(context, ret);
kdc_log(context, config, 0, "UNKNOWN -- %s: %s", client_name, msg);
@@ -1779,7 +1803,7 @@ _kdc_as_rep(krb5_context context,
out:
free_AS_REP(&rep);
- if(ret != 0 && ret != HDB_ERR_NOT_FOUND_HERE){
+ if(ret != 0 && ret != HDB_ERR_NOT_FOUND_HERE && reply->length == 0) {
krb5_mk_error(context,
ret,
e_text,
diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c
index ca589e87fa0..1d0d1ddc3fa 100644
--- a/source4/heimdal/kdc/krb5tgs.c
+++ b/source4/heimdal/kdc/krb5tgs.c
@@ -1616,6 +1616,32 @@ server_lookup:
if(ret == HDB_ERR_NOT_FOUND_HERE) {
kdc_log(context, config, 5, "target %s does not have secrets at this KDC, need to proxy", sp);
goto out;
+ } else if (ret == HDB_ERR_WRONG_REALM) {
+ if (ref_realm)
+ free(ref_realm);
+ ref_realm = strdup(server->entry.principal->realm);
+ if (ref_realm == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ kdc_log(context, config, 5,
+ "Returning a referral to realm %s for "
+ "server %s.",
+ ref_realm, spn);
+ krb5_free_principal(context, sp);
+ sp = NULL;
+ free(spn);
+ spn = NULL;
+ ret = krb5_make_principal(context, &sp, r, KRB5_TGS_NAME,
+ ref_realm, NULL);
+ if (ret)
+ goto out;
+ ret = krb5_unparse_name(context, sp, &spn);
+ if (ret)
+ goto out;
+
+ goto server_lookup;
} else if(ret){
const char *new_rlm, *msg;
Realm req_rlm;
diff --git a/source4/heimdal/kdc/misc.c b/source4/heimdal/kdc/misc.c
index 4ef5439cf14..b0bc38a2b6f 100644
--- a/source4/heimdal/kdc/misc.c
+++ b/source4/heimdal/kdc/misc.c
@@ -99,6 +99,13 @@ _kdc_db_fetch(krb5_context context,
config->db[i]->hdb_close(context, config->db[i]);
switch (ret) {
+ case HDB_ERR_WRONG_REALM:
+ /*
+ * the ent->entry.principal just contains hints for the client
+ * to retry. This is important for enterprise principal routing
+ * between trusts.
+ */
+ /* fall through */
case 0:
if (db)
*db = config->db[i];
diff --git a/source4/heimdal/lib/hdb/hdb_err.et b/source4/heimdal/lib/hdb/hdb_err.et
index 0bdcb385f6b..135747b0564 100644
--- a/source4/heimdal/lib/hdb/hdb_err.et
+++ b/source4/heimdal/lib/hdb/hdb_err.et
@@ -27,5 +27,6 @@ error_code MANDATORY_OPTION, "Entry contains unknown mandatory extension"
error_code NO_WRITE_SUPPORT, "HDB backend doesn't contain write support"
error_code NOT_FOUND_HERE, "The secret for this entry is not replicated to this database"
error_code MISUSE, "Incorrect use of the API"
+error_code WRONG_REALM, "The principal exists in another realm."
end