diff --git a/doc/admin.texinfo b/doc/admin.texinfo index 1ec4685183..fbdc5922eb 100644 --- a/doc/admin.texinfo +++ b/doc/admin.texinfo @@ -680,12 +680,14 @@ tags may be specified in the realm's subsection: @table @b @itemx kdc -The name of a host running a KDC for that realm. An optional port -number (separated from the hostname by a colon) may be included. For -your computer to be able to communicate with the KDC for each realm, -this tag must be given a value in each realm subsection in the -configuration file, or there must be DNS SRV records specifying the -KDCs (see @ref{Using DNS}). +The name or address of a host running a KDC for that realm. An optional +port number, separated from the hostname by a colon, may be included. +If the name or address contains colons (for example, if it is an IPv6 +address), enclose it in square brackets to distinguish the colon from a +port separator. For your computer to be able to communicate with the +KDC for each realm, this tag must be given a value in each realm +subsection in the configuration file, or there must be DNS SRV records +specifying the KDCs (see @ref{Using DNS}). @itemx master_kdc Identifies the master KDC(s). Currently, this tag is used in only one diff --git a/src/lib/kadm5/alt_prof.c b/src/lib/kadm5/alt_prof.c index 5b967a0ce0..7d28738869 100644 --- a/src/lib/kadm5/alt_prof.c +++ b/src/lib/kadm5/alt_prof.c @@ -481,6 +481,36 @@ get_deltat_param(krb5_deltat *param_out, krb5_deltat param_in, } } +/* + * Parse out the port number from an admin_server setting. Modify server to + * contain just the hostname or address. If a port is given, set *port, and + * set the appropriate bit in *mask. + */ +static void +parse_admin_server_port(char *server, int *port, long *mask) +{ + char *end, *portstr; + + /* Allow the name or addr to be enclosed in brackets, for IPv6 addrs. */ + if (*server == '[' && (end = strchr(server + 1, ']')) != NULL) { + portstr = (*(end + 1) == ':') ? end + 2 : NULL; + /* Shift the bracketed name or address back into server. */ + memmove(server, server + 1, end - (server + 1)); + *(end - 1) = '\0'; + } else { + /* Terminate the name at the colon, if any. */ + end = server + strcspn(server, ":"); + portstr = (*end == ':') ? end + 1 : NULL; + *end = '\0'; + } + + /* If we found a port string, parse it and set the appropriate bit. */ + if (portstr) { + *port = atoi(portstr); + *mask |= KADM5_CONFIG_KADMIND_PORT; + } +} + /* * Function: kadm5_get_config_params * @@ -581,13 +611,8 @@ krb5_error_code kadm5_get_config_params(context, use_kdc_config, NULL); if (params.mask & KADM5_CONFIG_ADMIN_SERVER) { - char *p; - p = strchr(params.admin_server, ':'); - if (p) { - params.kadmind_port = atoi(p+1); - params.mask |= KADM5_CONFIG_KADMIND_PORT; - *p = '\0'; - } + parse_admin_server_port(params.admin_server, ¶ms.kadmind_port, + ¶ms.mask); } /* Get the value for the database */ diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c index 0ecb2d9068..d0134c16f4 100644 --- a/src/lib/krb5/os/locate_kdc.c +++ b/src/lib/krb5/os/locate_kdc.c @@ -374,19 +374,11 @@ krb5_locate_srv_conf_1(krb5_context context, const krb5_data *realm, if (code == 0) { for (i=0; masterlist[i]; i++) { host = masterlist[i]; - - /* - * Strip off excess whitespace - */ - cp = strchr(host, ' '); - if (cp) - *cp = 0; - cp = strchr(host, '\t'); - if (cp) - *cp = 0; - cp = strchr(host, ':'); - if (cp) - *cp = 0; + /* Strip off excess characters. */ + if (*host == '[' && (cp = strchr(host, ']'))) + *(cp + 1) = '\0'; + else + *(host + strcspn(host, " \t:")) = '\0'; } } } else { @@ -407,20 +399,13 @@ krb5_locate_srv_conf_1(krb5_context context, const krb5_data *realm, host = hostlist[i]; Tprintf ("entry %d is '%s'\n", i, host); - /* - * Strip off excess whitespace - */ - cp = strchr(host, ' '); - if (cp) - *cp = 0; - cp = strchr(host, '\t'); - if (cp) - *cp = 0; - port = strchr(host, ':'); - if (port) { - *port = 0; - port++; - } + /* Find port number, and strip off any excess characters. */ + if (*host == '[' && (cp = strchr(host, ']'))) + cp = cp + 1; + else + cp = host + strcspn(host, " \t:"); + port = (*cp == ':') ? cp + 1 : NULL; + *cp = '\0'; ismaster = 0; if (masterlist) { @@ -454,15 +439,20 @@ krb5_locate_srv_conf_1(krb5_context context, const krb5_data *realm, p2 = sec_udpport; } + /* If the hostname was in brackets, strip those off now. */ + if (*host == '[' && (cp = strchr(host, ']'))) { + host++; + *cp = '\0'; + } + if (socktype != 0) - code = add_host_to_list (addrlist, hostlist[i], p1, p2, - socktype, family); + code = add_host_to_list(addrlist, host, p1, p2, socktype, family); else { - code = add_host_to_list (addrlist, hostlist[i], p1, p2, - SOCK_DGRAM, family); + code = add_host_to_list(addrlist, host, p1, p2, SOCK_DGRAM, + family); if (code == 0) - code = add_host_to_list (addrlist, hostlist[i], p1, p2, - SOCK_STREAM, family); + code = add_host_to_list(addrlist, host, p1, p2, SOCK_STREAM, + family); } if (code) { Tprintf ("error %d (%s) returned from add_host_to_list\n", code,