}
/* Construct a DNS label of the form "service.[protocol.]realm.". protocol may
- * be NULL. */
+ * and/or sitename be NULL. */
static char *
make_lookup_name(const krb5_data *realm, const char *service,
- const char *protocol)
+ const char *protocol, const char *sitename)
{
struct k5buf buf;
k5_buf_add_fmt(&buf, "%s.", service);
if (protocol != NULL)
k5_buf_add_fmt(&buf, "%s.", protocol);
+ if (sitename != NULL)
+ k5_buf_add_fmt(&buf, "%s._sites.", sitename);
k5_buf_add_len(&buf, realm->data, realm->length);
/*
krb5_error_code
krb5int_make_srv_query_realm(krb5_context context, const krb5_data *realm,
const char *service, const char *protocol,
+ const char *sitename,
struct srv_dns_entry **answers)
{
char *name = NULL;
*answers = NULL;
- name = make_lookup_name(realm, service, protocol);
+ name = make_lookup_name(realm, service, protocol, sitename);
if (name == NULL)
return 0;
st = DnsQuery_UTF8(name, DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &records,
NULL);
+ if (st != ERROR_SUCCESS && sitename != NULL) {
+ /* Try again without the site name. */
+ free(name);
+ return krb5int_make_srv_query_realm(context, realm, service, protocol,
+ NULL, answers);
+ }
if (st != ERROR_SUCCESS)
return 0;
/* Query the URI RR, collecting weight, priority, and target. */
krb5_error_code
k5_make_uri_query(krb5_context context, const krb5_data *realm,
- const char *service, struct srv_dns_entry **answers)
+ const char *service, const char *sitename,
+ struct srv_dns_entry **answers)
{
const unsigned char *p = NULL, *base = NULL;
char *name = NULL;
*answers = NULL;
/* Construct service.realm. */
- name = make_lookup_name(realm, service, NULL);
+ name = make_lookup_name(realm, service, NULL, sitename);
if (name == NULL)
return 0;
TRACE_DNS_URI_SEND(context, name);
size = krb5int_dns_init(&ds, name, C_IN, T_URI);
+ if (size < 0 && sitename != NULL) {
+ /* Try again without the site name. */
+ free(name);
+ return k5_make_uri_query(context, realm, service, NULL, answers);
+ }
if (size < 0)
goto out;
krb5_error_code
krb5int_make_srv_query_realm(krb5_context context, const krb5_data *realm,
const char *service, const char *protocol,
+ const char *sitename,
struct srv_dns_entry **answers)
{
const unsigned char *p = NULL, *base = NULL;
*
*/
- name = make_lookup_name(realm, service, protocol);
+ name = make_lookup_name(realm, service, protocol, sitename);
if (name == NULL)
return 0;
TRACE_DNS_SRV_SEND(context, name);
size = krb5int_dns_init(&ds, name, C_IN, T_SRV);
+ if (size < 0 && sitename) {
+ /* Try again without the site name. */
+ free(name);
+ return krb5int_make_srv_query_realm(context, realm, service, protocol,
+ NULL, answers);
+ }
if (size < 0)
goto out;
DEFAULT_LOOKUP_REALM);
}
+static krb5_error_code
+get_sitename(krb5_context context, const krb5_data *realm, char **out)
+{
+ krb5_error_code ret;
+ char *realmstr;
+
+ *out = NULL;
+ realmstr = k5memdup0(realm->data, realm->length, &ret);
+ if (realmstr == NULL)
+ return ret;
+ ret = profile_get_string(context->profile, KRB5_CONF_REALMS,
+ realmstr, KRB5_CONF_SITENAME, NULL, out);
+ free(realmstr);
+ return ret;
+}
+
#endif /* KRB5_DNS_LOOKUP */
/* Free up everything pointed to by the serverlist structure, but don't
struct srv_dns_entry *head = NULL, *entry = NULL;
krb5_error_code code = 0;
k5_transport transport;
+ char *sitename;
+ code = get_sitename(context, realm, &sitename);
+ if (code)
+ return code;
code = krb5int_make_srv_query_realm(context, realm, service, protocol,
- &head);
+ sitename, &head);
+ free(sitename);
if (code)
return 0;
krb5_error_code ret;
k5_transport transport, host_trans;
struct srv_dns_entry *answers, *entry;
- char *host;
+ char *host, *sitename;
const char *host_field, *path;
int port, def_port, primary;
- ret = k5_make_uri_query(context, realm, req_service, &answers);
+ ret = get_sitename(context, realm, &sitename);
+ if (ret)
+ return ret;
+ ret = k5_make_uri_query(context, realm, req_service, sitename, &answers);
+ free(sitename);
if (ret || answers == NULL)
return ret;
krb5_error_code
krb5int_make_srv_query_realm(krb5_context context, const krb5_data *realm,
const char *service, const char *protocol,
+ const char *sitename,
struct srv_dns_entry **answers);
void krb5int_free_srv_dns_data(struct srv_dns_entry *);
krb5_error_code
k5_make_uri_query(krb5_context context, const krb5_data *realm,
- const char *service, struct srv_dns_entry **answers);
+ const char *service, const char *sitename,
+ struct srv_dns_entry **answers);
krb5_error_code k5_try_realm_txt_rr(krb5_context context, const char *prefix,
const char *name, char **realm);