*** include/krb5.h.orig Thu Jan 6 10:23:50 2000 --- include/krb5.h Thu Jan 6 10:02:33 2000 *************** *** 632,638 **** /* #define KDC_OPT_RESERVED 0x00008000 */ /* #define KDC_OPT_RESERVED 0x00004000 */ /* #define KDC_OPT_RESERVED 0x00002000 */ ! /* #define KDC_OPT_RESERVED 0x00001000 */ /* #define KDC_OPT_RESERVED 0x00000800 */ /* #define KDC_OPT_RESERVED 0x00000400 */ /* #define KDC_OPT_RESERVED 0x00000200 */ --- 632,638 ---- /* #define KDC_OPT_RESERVED 0x00008000 */ /* #define KDC_OPT_RESERVED 0x00004000 */ /* #define KDC_OPT_RESERVED 0x00002000 */ ! #define KDC_OPT_NAME_CANONICALIZE 0x00010000 /* #define KDC_OPT_RESERVED 0x00000800 */ /* #define KDC_OPT_RESERVED 0x00000400 */ /* #define KDC_OPT_RESERVED 0x00000200 */ *** kdc/kdc_util.c.orig Thu Jan 6 10:23:40 2000 --- kdc/kdc_util.c Thu Jan 6 10:04:05 2000 *************** *** 1069,1075 **** KDC_OPT_ALLOW_POSTDATE | KDC_OPT_POSTDATED | \ KDC_OPT_RENEWABLE | KDC_OPT_RENEWABLE_OK | \ KDC_OPT_ENC_TKT_IN_SKEY | KDC_OPT_RENEW | \ ! KDC_OPT_VALIDATE) #define NO_TGT_OPTION (KDC_OPT_FORWARDED | KDC_OPT_PROXY | KDC_OPT_RENEW | \ KDC_OPT_VALIDATE) --- 1069,1076 ---- KDC_OPT_ALLOW_POSTDATE | KDC_OPT_POSTDATED | \ KDC_OPT_RENEWABLE | KDC_OPT_RENEWABLE_OK | \ KDC_OPT_ENC_TKT_IN_SKEY | KDC_OPT_RENEW | \ ! KDC_OPT_VALIDATE | \ ! KDC_OPT_NAME_CANONICALIZE) #define NO_TGT_OPTION (KDC_OPT_FORWARDED | KDC_OPT_PROXY | KDC_OPT_RENEW | \ KDC_OPT_VALIDATE) *** kdc/do_tgs_req.c.orig Thu Jan 6 10:23:31 2000 --- kdc/do_tgs_req.c Thu Jan 6 12:15:17 2000 *************** *** 169,175 **** * might be a request for a TGT for some other realm; we * should do our best to find such a TGS in this db */ ! if (firstpass && krb5_is_tgs_principal(request->server) == TRUE) { if (krb5_princ_size(kdc_context, request->server) == 2) { krb5_data *server_1 = krb5_princ_component(kdc_context, request->server, 1); --- 169,176 ---- * might be a request for a TGT for some other realm; we * should do our best to find such a TGS in this db */ ! if (firstpass) { ! if (krb5_is_tgs_principal(request->server) == TRUE) { if (krb5_princ_size(kdc_context, request->server) == 2) { krb5_data *server_1 = krb5_princ_component(kdc_context, request->server, 1); *************** *** 183,188 **** --- 184,242 ---- firstpass = 0; goto tgt_again; } + } + } + else if (isflagset(request->kdc_options, KDC_OPT_NAME_CANONICALIZE)) { + /* See if there is a configured referral realm */ + const char *cap_names[4] = {"realms", 0, "referral_realm", 0}; + char *cap_realm; + char **cap_nodes; + krb5_error_code cap_code; + krb5_principal reftgt; + + cap_realm = (char *)malloc(krb5_princ_size(kdc_context, krb5_princ_realm(kdc_context, request->server)) + 1); + memset(cap_realm, 0, krb5_princ_size(kdc_context, krb5_princ_realm(kdc_context, request->server)) + 1); + strncpy(cap_realm, + krb5_princ_name(kdc_context, krb5_princ_realm(kdc_context, request->server)), + krb5_princ_size(kdc_context, krb5_princ_realm(kdc_context, request->server))); + cap_names[1] = cap_realm; + cap_code = profile_get_values(kdc_context->profile, cap_names, &cap_nodes); + if (cap_code == 0) { + /* see if we have a cross-realm ticket for this realm */ + errcode = krb5_build_principal(kdc_context, &reftgt, + strlen(cap_realm), + cap_realm, + KRB5_TGS_NAME, + cap_nodes[0], + 0); + krb5_xfree((char *)cap_nodes); + if (errcode == 0) { + krb5_db_free_principal(kdc_context, &server, nprincs); + errcode = krb5_db_get_principal(kdc_context, + reftgt, &server, + &nprincs, &more); + if (errcode == 0 && nprincs == 1) { + char *s0name; + if (krb5_unparse_name(kdc_context, request->server, &s0name)) { + s0name = ""; + } + if (krb5_unparse_name(kdc_context, reftgt, &sname)) { + sname = ""; + + } + limit_string(sname); + limit_string(s0name); + krb5_klog_syslog(LOG_INFO, + "TGS_REQ: issuing referral TGT %s for %s", sname, s0name); + free(s0name); + krb5_free_principal(kdc_context, request->server); + request->server = reftgt; + firstpass = 0; + goto tgt_again; + } + } + } + krb5_xfree((char *)cap_realm); } } krb5_db_free_principal(kdc_context, &server, nprincs);