remember the real port number when falling back from kpasswd ->
kadmin, and krb524 -> kdc git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@10210 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -48,17 +48,23 @@ string_to_proto(const char *string)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set `res' and `count' to the result of looking up SRV RR in DNS for
|
||||||
|
* `proto', `proto', `realm' using `dns_type'.
|
||||||
|
* if `port' != 0, force that port number
|
||||||
|
*/
|
||||||
|
|
||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count,
|
srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count,
|
||||||
const char *realm, const char *dns_type,
|
const char *realm, const char *dns_type,
|
||||||
const char *proto, const char *service)
|
const char *proto, const char *service, int port)
|
||||||
{
|
{
|
||||||
char domain[1024];
|
char domain[1024];
|
||||||
struct dns_reply *r;
|
struct dns_reply *r;
|
||||||
struct resource_record *rr;
|
struct resource_record *rr;
|
||||||
int num_srv;
|
int num_srv;
|
||||||
int proto_num;
|
int proto_num;
|
||||||
short int port;
|
int def_port;
|
||||||
|
|
||||||
proto_num = string_to_proto(proto);
|
proto_num = string_to_proto(proto);
|
||||||
if(proto_num < 0) {
|
if(proto_num < 0) {
|
||||||
@@ -67,9 +73,11 @@ srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(proto_num == KRB5_KRBHST_HTTP)
|
if(proto_num == KRB5_KRBHST_HTTP)
|
||||||
port = krb5_getportbyname (context, "http", "tcp", 80);
|
def_port = krb5_getportbyname (context, "http", "tcp", 80);
|
||||||
else
|
else if(port == 0)
|
||||||
port = krb5_getportbyname (context, service, proto, 88);
|
def_port = krb5_getportbyname (context, service, proto, 88);
|
||||||
|
else
|
||||||
|
def_port = port;
|
||||||
|
|
||||||
snprintf(domain, sizeof(domain), "_%s._%s.%s.", service, proto, realm);
|
snprintf(domain, sizeof(domain), "_%s._%s.%s.", service, proto, realm);
|
||||||
|
|
||||||
@@ -108,8 +116,11 @@ srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count,
|
|||||||
|
|
||||||
hi->proto = proto_num;
|
hi->proto = proto_num;
|
||||||
|
|
||||||
hi->def_port = ntohs(port);
|
hi->def_port = ntohs(def_port);
|
||||||
hi->port = rr->u.srv->port;
|
if (port != 0)
|
||||||
|
hi->port = ntohs(port);
|
||||||
|
else
|
||||||
|
hi->port = rr->u.srv->port;
|
||||||
|
|
||||||
strcpy(hi->hostname, rr->u.srv->target);
|
strcpy(hi->hostname, rr->u.srv->target);
|
||||||
}
|
}
|
||||||
@@ -124,6 +135,8 @@ srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count,
|
|||||||
struct krb5_krbhst_data {
|
struct krb5_krbhst_data {
|
||||||
char *realm;
|
char *realm;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
|
int def_port;
|
||||||
|
int port; /* hardwired port number if != 0 */
|
||||||
#define KD_CONFIG 1
|
#define KD_CONFIG 1
|
||||||
#define KD_SRV_UDP 2
|
#define KD_SRV_UDP 2
|
||||||
#define KD_SRV_TCP 4
|
#define KD_SRV_TCP 4
|
||||||
@@ -145,8 +158,13 @@ krbhst_empty(const struct krb5_krbhst_data *kd)
|
|||||||
return kd->index == &kd->hosts;
|
return kd->index == &kd->hosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* parse `spec' into a krb5_krbhst_info, defaulting the port to `def_port'
|
||||||
|
* and forcing it to `port' if port != 0
|
||||||
|
*/
|
||||||
|
|
||||||
static struct krb5_krbhst_info*
|
static struct krb5_krbhst_info*
|
||||||
parse_hostspec(krb5_context context, const char *spec, int def_port)
|
parse_hostspec(krb5_context context, const char *spec, int def_port, int port)
|
||||||
{
|
{
|
||||||
const char *p = spec;
|
const char *p = spec;
|
||||||
struct krb5_krbhst_info *hi;
|
struct krb5_krbhst_info *hi;
|
||||||
@@ -188,9 +206,19 @@ parse_hostspec(krb5_context context, const char *spec, int def_port)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (port)
|
||||||
|
hi->port = port;
|
||||||
return hi;
|
return hi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_krbhst_info(krb5_krbhst_info *hi)
|
||||||
|
{
|
||||||
|
if (hi->ai != NULL)
|
||||||
|
freeaddrinfo(hi->ai);
|
||||||
|
free(hi);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
append_host_hostinfo(struct krb5_krbhst_data *kd, struct krb5_krbhst_info *host)
|
append_host_hostinfo(struct krb5_krbhst_data *kd, struct krb5_krbhst_info *host)
|
||||||
{
|
{
|
||||||
@@ -200,7 +228,7 @@ append_host_hostinfo(struct krb5_krbhst_data *kd, struct krb5_krbhst_info *host)
|
|||||||
if(h->proto == host->proto &&
|
if(h->proto == host->proto &&
|
||||||
h->port == host->port &&
|
h->port == host->port &&
|
||||||
strcmp(h->hostname, host->hostname) == 0) {
|
strcmp(h->hostname, host->hostname) == 0) {
|
||||||
free(host);
|
free_krbhst_info(host);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*kd->end = host;
|
*kd->end = host;
|
||||||
@@ -209,11 +237,11 @@ append_host_hostinfo(struct krb5_krbhst_data *kd, struct krb5_krbhst_info *host)
|
|||||||
|
|
||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
append_host_string(krb5_context context, struct krb5_krbhst_data *kd,
|
append_host_string(krb5_context context, struct krb5_krbhst_data *kd,
|
||||||
const char *host, int def_port)
|
const char *host, int def_port, int port)
|
||||||
{
|
{
|
||||||
struct krb5_krbhst_info *hi;
|
struct krb5_krbhst_info *hi;
|
||||||
|
|
||||||
hi = parse_hostspec(context, host, def_port);
|
hi = parse_hostspec(context, host, def_port, port);
|
||||||
if(hi == NULL)
|
if(hi == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
@@ -304,16 +332,21 @@ srv_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
|
|||||||
krb5_krbhst_info **res;
|
krb5_krbhst_info **res;
|
||||||
int count, i;
|
int count, i;
|
||||||
|
|
||||||
srv_find_realm(context, &res, &count, kd->realm, "SRV", proto, service);
|
srv_find_realm(context, &res, &count, kd->realm, "SRV", proto, service,
|
||||||
|
kd->port);
|
||||||
for(i = 0; i < count; i++)
|
for(i = 0; i < count; i++)
|
||||||
append_host_hostinfo(kd, res[i]);
|
append_host_hostinfo(kd, res[i]);
|
||||||
free(res);
|
free(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read the configuration for `conf_string', defaulting to kd->def_port and
|
||||||
|
* forcing it to `kd->port' if kd->port != 0
|
||||||
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
config_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
|
config_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
|
||||||
const char *conf_string, int def_port)
|
const char *conf_string)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -325,7 +358,7 @@ config_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
|
|||||||
return;
|
return;
|
||||||
kd->flags |= KD_CONFIG_EXISTS;
|
kd->flags |= KD_CONFIG_EXISTS;
|
||||||
for(i = 0; hostlist && hostlist[i] != NULL; i++)
|
for(i = 0; hostlist && hostlist[i] != NULL; i++)
|
||||||
append_host_string(context, kd, hostlist[i], def_port);
|
append_host_string(context, kd, hostlist[i], kd->def_port, kd->port);
|
||||||
|
|
||||||
krb5_config_free_strings(hostlist);
|
krb5_config_free_strings(hostlist);
|
||||||
}
|
}
|
||||||
@@ -333,13 +366,13 @@ config_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
|
|||||||
/*
|
/*
|
||||||
* as a fallback, look for `serv_string.kd->realm' (typically
|
* as a fallback, look for `serv_string.kd->realm' (typically
|
||||||
* kerberos.REALM, kerberos-1.REALM, ...
|
* kerberos.REALM, kerberos-1.REALM, ...
|
||||||
* `def_port' is the default port for the service, and `proto' the
|
* `port' is the default port for the service, and `proto' the
|
||||||
* protocol
|
* protocol
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
|
fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
|
||||||
const char *serv_string, int def_port, int proto)
|
const char *serv_string, int port, int proto)
|
||||||
{
|
{
|
||||||
char *host;
|
char *host;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -357,7 +390,7 @@ fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
|
|||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
make_hints(&hints, proto);
|
make_hints(&hints, proto);
|
||||||
snprintf(portstr, sizeof(portstr), "%d", def_port);
|
snprintf(portstr, sizeof(portstr), "%d", port);
|
||||||
ret = getaddrinfo(host, portstr, &hints, &ai);
|
ret = getaddrinfo(host, portstr, &hints, &ai);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
/* no more hosts, so we're done here */
|
/* no more hosts, so we're done here */
|
||||||
@@ -374,7 +407,7 @@ fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
hi->proto = proto;
|
hi->proto = proto;
|
||||||
hi->port = hi->def_port = def_port;
|
hi->port = hi->def_port = port;
|
||||||
hi->ai = ai;
|
hi->ai = ai;
|
||||||
memmove(hi->hostname, host, hostlen - 1);
|
memmove(hi->hostname, host, hostlen - 1);
|
||||||
hi->hostname[hostlen - 1] = '\0';
|
hi->hostname[hostlen - 1] = '\0';
|
||||||
@@ -391,10 +424,9 @@ kdc_get_next(krb5_context context,
|
|||||||
krb5_krbhst_info **host)
|
krb5_krbhst_info **host)
|
||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
int port = ntohs(krb5_getportbyname (context, "kerberos", "udp", 88));
|
|
||||||
|
|
||||||
if((kd->flags & KD_CONFIG) == 0) {
|
if((kd->flags & KD_CONFIG) == 0) {
|
||||||
config_get_hosts(context, kd, "kdc", port);
|
config_get_hosts(context, kd, "kdc");
|
||||||
kd->flags |= KD_CONFIG;
|
kd->flags |= KD_CONFIG;
|
||||||
if(get_next(kd, host))
|
if(get_next(kd, host))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -427,7 +459,7 @@ kdc_get_next(krb5_context context,
|
|||||||
|
|
||||||
while((kd->flags & KD_FALLBACK) == 0) {
|
while((kd->flags & KD_FALLBACK) == 0) {
|
||||||
ret = fallback_get_hosts(context, kd, "kerberos",
|
ret = fallback_get_hosts(context, kd, "kerberos",
|
||||||
port, KRB5_KRBHST_UDP);
|
kd->def_port, KRB5_KRBHST_UDP);
|
||||||
if(ret)
|
if(ret)
|
||||||
return ret;
|
return ret;
|
||||||
if(get_next(kd, host))
|
if(get_next(kd, host))
|
||||||
@@ -443,10 +475,9 @@ admin_get_next(krb5_context context,
|
|||||||
krb5_krbhst_info **host)
|
krb5_krbhst_info **host)
|
||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
int port = ntohs(krb5_getportbyname (context, "kerberos-adm", "tcp", 749));
|
|
||||||
|
|
||||||
if((kd->flags & KD_CONFIG) == 0) {
|
if((kd->flags & KD_CONFIG) == 0) {
|
||||||
config_get_hosts(context, kd, "admin_server", port);
|
config_get_hosts(context, kd, "admin_server");
|
||||||
kd->flags |= KD_CONFIG;
|
kd->flags |= KD_CONFIG;
|
||||||
if(get_next(kd, host))
|
if(get_next(kd, host))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -467,7 +498,7 @@ admin_get_next(krb5_context context,
|
|||||||
if (krbhst_empty(kd)
|
if (krbhst_empty(kd)
|
||||||
&& (kd->flags & KD_FALLBACK) == 0) {
|
&& (kd->flags & KD_FALLBACK) == 0) {
|
||||||
ret = fallback_get_hosts(context, kd, "kerberos",
|
ret = fallback_get_hosts(context, kd, "kerberos",
|
||||||
port, KRB5_KRBHST_UDP);
|
kd->def_port, KRB5_KRBHST_UDP);
|
||||||
if(ret)
|
if(ret)
|
||||||
return ret;
|
return ret;
|
||||||
kd->flags |= KD_FALLBACK;
|
kd->flags |= KD_FALLBACK;
|
||||||
@@ -483,11 +514,8 @@ kpasswd_get_next(krb5_context context,
|
|||||||
struct krb5_krbhst_data *kd,
|
struct krb5_krbhst_data *kd,
|
||||||
krb5_krbhst_info **host)
|
krb5_krbhst_info **host)
|
||||||
{
|
{
|
||||||
int port = ntohs(krb5_getportbyname (context, "kpasswd", "udp",
|
|
||||||
KPASSWD_PORT));
|
|
||||||
|
|
||||||
if((kd->flags & KD_CONFIG) == 0) {
|
if((kd->flags & KD_CONFIG) == 0) {
|
||||||
config_get_hosts(context, kd, "kpasswd_server", port);
|
config_get_hosts(context, kd, "kpasswd_server");
|
||||||
if(get_next(kd, host))
|
if(get_next(kd, host))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -508,6 +536,7 @@ kpasswd_get_next(krb5_context context,
|
|||||||
|
|
||||||
if (krbhst_empty(kd)) {
|
if (krbhst_empty(kd)) {
|
||||||
kd->flags = 0;
|
kd->flags = 0;
|
||||||
|
kd->port = kd->def_port;
|
||||||
kd->get_next = admin_get_next;
|
kd->get_next = admin_get_next;
|
||||||
return (*kd->get_next)(context, kd, host);
|
return (*kd->get_next)(context, kd, host);
|
||||||
}
|
}
|
||||||
@@ -520,10 +549,8 @@ krb524_get_next(krb5_context context,
|
|||||||
struct krb5_krbhst_data *kd,
|
struct krb5_krbhst_data *kd,
|
||||||
krb5_krbhst_info **host)
|
krb5_krbhst_info **host)
|
||||||
{
|
{
|
||||||
int port = ntohs(krb5_getportbyname (context, "krb524", "udp", 4444));
|
|
||||||
|
|
||||||
if((kd->flags & KD_CONFIG) == 0) {
|
if((kd->flags & KD_CONFIG) == 0) {
|
||||||
config_get_hosts(context, kd, "krb524_server", port);
|
config_get_hosts(context, kd, "krb524_server");
|
||||||
if(get_next(kd, host))
|
if(get_next(kd, host))
|
||||||
return 0;
|
return 0;
|
||||||
kd->flags |= KD_CONFIG;
|
kd->flags |= KD_CONFIG;
|
||||||
@@ -552,6 +579,7 @@ krb524_get_next(krb5_context context,
|
|||||||
|
|
||||||
if (krbhst_empty(kd)) {
|
if (krbhst_empty(kd)) {
|
||||||
kd->flags = 0;
|
kd->flags = 0;
|
||||||
|
kd->port = kd->def_port;
|
||||||
kd->get_next = kdc_get_next;
|
kd->get_next = kdc_get_next;
|
||||||
return (*kd->get_next)(context, kd, host);
|
return (*kd->get_next)(context, kd, host);
|
||||||
}
|
}
|
||||||
@@ -590,18 +618,26 @@ krb5_krbhst_init(krb5_context context,
|
|||||||
struct krb5_krbhst_data *kd;
|
struct krb5_krbhst_data *kd;
|
||||||
krb5_error_code (*get_next)(krb5_context, struct krb5_krbhst_data *,
|
krb5_error_code (*get_next)(krb5_context, struct krb5_krbhst_data *,
|
||||||
krb5_krbhst_info **);
|
krb5_krbhst_info **);
|
||||||
|
int def_port;
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case KRB5_KRBHST_KDC:
|
case KRB5_KRBHST_KDC:
|
||||||
get_next = kdc_get_next;
|
get_next = kdc_get_next;
|
||||||
|
def_port = ntohs(krb5_getportbyname (context, "kerberos", "udp", 88));
|
||||||
break;
|
break;
|
||||||
case KRB5_KRBHST_ADMIN:
|
case KRB5_KRBHST_ADMIN:
|
||||||
get_next = admin_get_next;
|
get_next = admin_get_next;
|
||||||
|
def_port = ntohs(krb5_getportbyname (context, "kerberos-adm",
|
||||||
|
"tcp", 749));
|
||||||
break;
|
break;
|
||||||
case KRB5_KRBHST_CHANGEPW:
|
case KRB5_KRBHST_CHANGEPW:
|
||||||
get_next = kpasswd_get_next;
|
get_next = kpasswd_get_next;
|
||||||
|
def_port = ntohs(krb5_getportbyname (context, "kpasswd", "udp",
|
||||||
|
KPASSWD_PORT));
|
||||||
break;
|
break;
|
||||||
case KRB5_KRBHST_KRB524:
|
case KRB5_KRBHST_KRB524:
|
||||||
get_next = krb524_get_next;
|
get_next = krb524_get_next;
|
||||||
|
def_port = ntohs(krb5_getportbyname (context, "krb524", "udp", 4444));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
krb5_set_error_string(context, "unknown krbhst type (%u)", type);
|
krb5_set_error_string(context, "unknown krbhst type (%u)", type);
|
||||||
@@ -610,6 +646,7 @@ krb5_krbhst_init(krb5_context context,
|
|||||||
if((kd = common_init(context, realm)) == NULL)
|
if((kd = common_init(context, realm)) == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
kd->get_next = get_next;
|
kd->get_next = get_next;
|
||||||
|
kd->def_port = def_port;
|
||||||
*handle = kd;
|
*handle = kd;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -655,14 +692,6 @@ krb5_krbhst_reset(krb5_context context, krb5_krbhst_handle handle)
|
|||||||
handle->index = &handle->hosts;
|
handle->index = &handle->hosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
free_krbhst_info(krb5_krbhst_info *hi)
|
|
||||||
{
|
|
||||||
if (hi->ai != NULL)
|
|
||||||
freeaddrinfo(hi->ai);
|
|
||||||
free(hi);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
krb5_krbhst_free(krb5_context context, krb5_krbhst_handle handle)
|
krb5_krbhst_free(krb5_context context, krb5_krbhst_handle handle)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user