示例#1
0
/*
 * krb5int_dns_nextans() - get next answer record
 *
 * Sets pp to NULL if no more records.
 */
int
krb5int_dns_nextans(struct krb5int_dns_state *ds,
		    const unsigned char **pp, int *lenp)
{
    int len;
    unsigned char *p;
    unsigned short ntype, nclass, rdlen;
#if !HAVE_DN_SKIPNAME
    char host[MAXDNAME];
#endif

    *pp = NULL;
    *lenp = 0;
    p = ds->ptr;

    while (ds->nanswers--) {
#if HAVE_DN_SKIPNAME
	len = dn_skipname(p, (unsigned char *)ds->ansp + ds->anslen);
#else
	len = dn_expand(ds->ansp, (unsigned char *)ds->ansp + ds->anslen,
			p, host, sizeof(host));
#endif
	if (len < 0 || !INCR_OK(ds->ansp, ds->anslen, p, len))
	    return -1;
	p += len;
	SAFE_GETUINT16(ds->ansp, ds->anslen, p, 2, ntype, out);
	/* Also skip 4 bytes of TTL */
	SAFE_GETUINT16(ds->ansp, ds->anslen, p, 6, nclass, out);
	SAFE_GETUINT16(ds->ansp, ds->anslen, p, 2, rdlen, out);

	if (!INCR_OK(ds->ansp, ds->anslen, p, rdlen))
	    return -1;
/* Solaris Kerberos - resync */
#if 0
	if (rdlen > INT_MAX)
	    return -1;
#endif
	if (nclass == ds->nclass && ntype == ds->ntype) {
	    *pp = p;
	    *lenp = rdlen;
	    ds->ptr = p + rdlen;
	    return 0;
	}
	p += rdlen;
    }
    return 0;
out:
    return -1;
}
示例#2
0
文件: dnsglue.c 项目: Baalmart/krb5
/*
 * initparse
 *
 * Skip header and question section of reply.  Set a pointer to the
 * beginning of the answer section, and prepare to iterate over
 * answer records.
 */
static int
initparse(struct krb5int_dns_state *ds)
{
    HEADER *hdr;
    unsigned char *p;
    unsigned short nqueries, nanswers;
    int len;
#if !HAVE_DN_SKIPNAME
    char host[MAXDNAME];
#endif

    if ((size_t) ds->anslen < sizeof(HEADER))
        return -1;

    hdr = (HEADER *)ds->ansp;
    p = ds->ansp;
    nqueries = ntohs((unsigned short)hdr->qdcount);
    nanswers = ntohs((unsigned short)hdr->ancount);
    p += sizeof(HEADER);

    /*
     * Skip query records.
     */
    while (nqueries--) {
#if HAVE_DN_SKIPNAME
        len = dn_skipname(p, (unsigned char *)ds->ansp + ds->anslen);
#else
        len = dn_expand(ds->ansp, (unsigned char *)ds->ansp + ds->anslen,
                        p, host, sizeof(host));
#endif
        if (len < 0 || !INCR_OK(ds->ansp, ds->anslen, p, len + 4))
            return -1;
        p += len + 4;
    }
    ds->ptr = p;
    ds->nanswers = nanswers;
    return 0;
}
示例#3
0
krb5_error_code
krb5_try_realm_txt_rr(const char *prefix, const char *name, char **realm)
{
    krb5_error_code retval = KRB5_ERR_HOST_REALM_UNKNOWN;
    const unsigned char *p, *base;
    char host[MAXDNAME];
    int ret, rdlen, len;
    struct krb5int_dns_state *ds = NULL;
    struct k5buf buf;

    /*
     * Form our query, and send it via DNS
     */

    krb5int_buf_init_fixed(&buf, host, sizeof(host));
    if (name == NULL || name[0] == '\0') {
	krb5int_buf_add(&buf, prefix);
    } else {
	krb5int_buf_add_fmt(&buf, "%s.%s", prefix, name);

        /* Realm names don't (normally) end with ".", but if the query
           doesn't end with "." and doesn't get an answer as is, the
           resolv code will try appending the local domain.  Since the
           realm names are absolutes, let's stop that.  

           But only if a name has been specified.  If we are performing
           a search on the prefix alone then the intention is to allow
           the local domain or domain search lists to be expanded.
        */

	len = krb5int_buf_len(&buf);
	if (len > 0 && host[len - 1] != '.')
	    krb5int_buf_add(&buf, ".");
    }
    if (krb5int_buf_data(&buf) == NULL)
	return KRB5_ERR_HOST_REALM_UNKNOWN;
    ret = krb5int_dns_init(&ds, host, C_IN, T_TXT);
    if (ret < 0)
	goto errout;

    ret = krb5int_dns_nextans(ds, &base, &rdlen);
    if (ret < 0 || base == NULL)
	goto errout;

    p = base;
    if (!INCR_OK(base, rdlen, p, 1))
	goto errout;
    len = *p++;
    *realm = malloc((size_t)len + 1);
    if (*realm == NULL) {
	retval = ENOMEM;
	goto errout;
    }
    strncpy(*realm, (const char *)p, (size_t)len);
    (*realm)[len] = '\0';
    /* Avoid a common error. */
    if ( (*realm)[len-1] == '.' )
	(*realm)[len-1] = '\0';
    retval = 0;

errout:
    if (ds != NULL) {
	krb5int_dns_fini(ds);
	ds = NULL;
    }
    return retval;
}