Beispiel #1
0
/*
 * Collect a list of servers from DNS URI records, for the requested service
 * and transport type.  Problematic entries are skipped.
 */
static krb5_error_code
locate_uri(krb5_context context, const krb5_data *realm,
           const char *req_service, struct serverlist *serverlist,
           k5_transport req_transport, int default_port,
           krb5_boolean master_only)
{
    krb5_error_code ret;
    k5_transport transport, host_trans;
    struct srv_dns_entry *answers, *entry;
    char *host;
    const char *host_field, *path;
    int port, def_port, master;

    ret = k5_make_uri_query(context, realm, req_service, &answers);
    if (ret || answers == NULL)
        return ret;

    for (entry = answers; entry != NULL; entry = entry->next) {
        def_port = default_port;
        path = NULL;

        parse_uri_fields(entry->host, &transport, &host_field, &master);
        if (host_field == NULL)
            continue;

        /* TCP_OR_UDP allows entries of any transport type; otherwise
         * we're asking for a match. */
        if (req_transport != TCP_OR_UDP && req_transport != transport)
            continue;

        /* Process a MS-KKDCP target. */
        if (transport == HTTPS) {
            host_trans = 0;
            def_port = 443;
            parse_uri_if_https(host_field, &host_trans, &host_field, &path);
            if (host_trans != HTTPS)
                continue;
        }

        ret = k5_parse_host_string(host_field, def_port, &host, &port);
        if (ret == ENOMEM)
            break;

        if (ret || host == NULL) {
            ret = 0;
            continue;
        }

        ret = add_host_to_list(serverlist, host, port, transport, AF_UNSPEC,
                               path, master);
        free(host);
        if (ret)
            break;
    }

    krb5int_free_srv_dns_data(answers);
    return ret;
}
Beispiel #2
0
static krb5_error_code
locate_srv_conf_1(krb5_context context, const krb5_data *realm,
                  const char * name, struct serverlist *serverlist,
                  k5_transport transport, int udpport)
{
    const char *realm_srv_names[4];
    char **hostlist = NULL, *realmstr = NULL, *host = NULL;
    const char *hostspec;
    krb5_error_code code;
    int i, default_port;

    Tprintf("looking in krb5.conf for realm %s entry %s; ports %d,%d\n",
            realm->data, name, udpport);

    realmstr = k5memdup0(realm->data, realm->length, &code);
    if (realmstr == NULL)
        goto cleanup;

    realm_srv_names[0] = KRB5_CONF_REALMS;
    realm_srv_names[1] = realmstr;
    realm_srv_names[2] = name;
    realm_srv_names[3] = 0;
    code = profile_get_values(context->profile, realm_srv_names, &hostlist);
    if (code) {
        Tprintf("config file lookup failed: %s\n", error_message(code));
        if (code == PROF_NO_SECTION || code == PROF_NO_RELATION)
            code = 0;
        goto cleanup;
    }

    for (i = 0; hostlist[i]; i++) {
        int port_num;
        k5_transport this_transport = transport;
        const char *uri_path = NULL;

        hostspec = hostlist[i];
        Tprintf("entry %d is '%s'\n", i, hostspec);

        parse_uri_if_https(hostspec, &this_transport, &hostspec, &uri_path);

        default_port = (this_transport == HTTPS) ? 443 : udpport;
        code = k5_parse_host_string(hostspec, default_port, &host, &port_num);
        if (code == 0 && host == NULL)
            code = EINVAL;
        if (code)
            goto cleanup;

        code = add_host_to_list(serverlist, host, port_num, this_transport,
                                AF_UNSPEC, uri_path, -1);
        if (code)
            goto cleanup;

        free(host);
        host = NULL;
    }

cleanup:
    free(realmstr);
    free(host);
    profile_free_list(hostlist);
    return code;
}
Beispiel #3
0
static krb5_error_code
locate_srv_conf_1(krb5_context context, const krb5_data *realm,
                  const char * name, struct serverlist *serverlist,
                  k5_transport transport, int udpport, int sec_udpport)
{
    const char  *realm_srv_names[4];
    char **hostlist, *host, *port, *cp;
    krb5_error_code code;
    int i;

    Tprintf ("looking in krb5.conf for realm %s entry %s; ports %d,%d\n",
             realm->data, name, ntohs (udpport), ntohs (sec_udpport));

    if ((host = malloc(realm->length + 1)) == NULL)
        return ENOMEM;

    strncpy(host, realm->data, realm->length);
    host[realm->length] = '\0';
    hostlist = 0;

    realm_srv_names[0] = KRB5_CONF_REALMS;
    realm_srv_names[1] = host;
    realm_srv_names[2] = name;
    realm_srv_names[3] = 0;

    code = profile_get_values(context->profile, realm_srv_names, &hostlist);
    free(host);

    if (code) {
        Tprintf ("config file lookup failed: %s\n",
                 error_message(code));
        if (code == PROF_NO_SECTION || code == PROF_NO_RELATION)
            code = 0;
        return code;
    }

    for (i=0; hostlist[i]; i++) {
        int p1, p2;
        k5_transport this_transport = transport;
        char *uri_path = NULL;

        host = hostlist[i];
        Tprintf ("entry %d is '%s'\n", i, host);

        parse_uri_if_https(host, &this_transport, &host, &uri_path);

        /* 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';

        if (port) {
            unsigned long l;
            char *endptr;
            l = strtoul (port, &endptr, 10);
            if (endptr == NULL || *endptr != 0)
                return EINVAL;
            /* L is unsigned, don't need to check <0.  */
            if (l > 65535)
                return EINVAL;
            p1 = htons (l);
            p2 = 0;
        } else if (this_transport == HTTPS) {
            p1 = htons(443);
            p2 = 0;
        } else {
            p1 = udpport;
            p2 = sec_udpport;
        }

        /* If the hostname was in brackets, strip those off now. */
        if (*host == '[' && (cp = strchr(host, ']'))) {
            host++;
            *cp = '\0';
        }

        code = add_host_to_list(serverlist, host, p1, this_transport,
                                AF_UNSPEC, uri_path);
        /* Second port is for IPv4 UDP only, and should possibly go away as
         * it was originally a krb4 compatibility measure. */
        if (code == 0 && p2 != 0 &&
            (this_transport == TCP_OR_UDP || this_transport == UDP)) {
            code = add_host_to_list(serverlist, host, p2, UDP, AF_INET,
                                    uri_path);
        }
        if (code)
            goto cleanup;
    }

cleanup:
    profile_free_list(hostlist);
    return code;
}