Beispiel #1
0
/*
 * Solaris Kerberos:
 * krb5int_address_get_realm() given an address (either IPv4 or IPv6) tries to
 * find a realm based on the DNS name of that address. Assumes that its being
 * used as a callback for krb5int_foreach_localaddr().
 */
static int krb5int_address_get_realm(void *data, struct sockaddr *addr) {
	
	krb5_context context = data;
	struct hostent *he = NULL;

	switch (addr->sa_family) {
		case AF_INET:
			he = res_gethostbyaddr((char*)(&sa2sin(addr)->sin_addr),
			    sizeof(sa2sin(addr)->sin_addr), AF_INET);
			break;
		case AF_INET6:
			he = res_gethostbyaddr(
			    (char*)(&sa2sin6(addr)->sin6_addr),
			    sizeof(sa2sin6(addr)->sin6_addr), AF_INET6);
			break;
	}

	if (he) {
		/* Try to find realm using returned DNS name */
		krb5int_fqdn_get_realm(context, he->h_name,
		    &context->default_realm);

		/* If a realm was found return 1 to immediately halt
		 * krb5int_foreach_localaddr()
		 */ 
		if (context->default_realm != 0) {
			return (1);
		}
	}
	return (0);
}
Beispiel #2
0
static int
addr_eq (struct sockaddr *s1, struct sockaddr *s2)
{
    if (s1->sa_family != s2->sa_family)
        return 0;
    switch (s1->sa_family) {
    case AF_INET:
        return !memcmp(&sa2sin(s1)->sin_addr, &sa2sin(s2)->sin_addr,
                       sizeof(sa2sin(s1)->sin_addr));
    case AF_INET6:
        return !memcmp(&sa2sin6(s1)->sin6_addr, &sa2sin6(s2)->sin6_addr,
                       sizeof(sa2sin6(s1)->sin6_addr));
    default:
        /* Err on side of duplicate listings.  */
        return 0;
    }
}
Beispiel #3
0
static int
getbroadcastnets(
	struct in_addr *addrs,
	int sock,  /* any valid socket will do */
	char *buf  /* why allocxate more when we can use existing... */
	)
{
	struct ifconf ifc;
        struct ifreq ifreq, *ifr;
        int n, i;

        ifc.ifc_len = GIFCONF_BUFSIZE;
        ifc.ifc_buf = buf;
	memset (buf, 0, GIFCONF_BUFSIZE);
        if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
                perror("broadcast: ioctl (get interface configuration)");
                return (0);
        }
        ifr = ifc.ifc_req;
        for (i = 0, n = ifc.ifc_len/sizeof (struct ifreq); n > 0; n--, ifr++) {
                ifreq = *ifr;
                if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
                        perror("broadcast: ioctl (get interface flags)");
                        continue;
                }
                if ((ifreq.ifr_flags & IFF_BROADCAST) &&
		    (ifreq.ifr_flags & IFF_UP) &&
		    ifr->ifr_addr.sa_family == AF_INET) {
#ifdef SIOCGIFBRDADDR   /* 4.3BSD */
			if (ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
				addrs[i++].s_addr = INADDR_ANY;
			} else {
				addrs[i++] = sa2sin(&ifreq.ifr_addr)->sin_addr;
			}
#else /* 4.2 BSD */
			struct sockaddr_in *sockin;
			sockin = sa2sin(&ifr->ifr_addr);
			addrs[i++] = inet_makeaddr(inet_netof
			  (sockin->sin_addr.s_addr), INADDR_ANY);
#endif
		}
	}
	return (i);
}
Beispiel #4
0
static int
is_loopback_address(struct sockaddr *sa)
{
    switch (sa->sa_family) {
    case AF_INET: {
        struct sockaddr_in *s4 = sa2sin(sa);
        return s4->sin_addr.s_addr == htonl(INADDR_LOOPBACK);
    }
    case AF_INET6: {
        struct sockaddr_in6 *s6 = sa2sin6(sa);
        return IN6_IS_ADDR_LOOPBACK(&s6->sin6_addr);
    }
    default:
        return 0;
    }
}
Beispiel #5
0
/* Misc utility routines.  */
static void
set_sa_port(struct sockaddr *addr, int port)
{
    switch (addr->sa_family) {
    case AF_INET:
	sa2sin(addr)->sin_port = port;
	break;
#ifdef KRB5_USE_INET6
    case AF_INET6:
	sa2sin6(addr)->sin6_port = port;
	break;
#endif
    default:
	break;
    }
}
Beispiel #6
0
krb5_error_code
k5_os_hostaddr(krb5_context context, const char *name,
               krb5_address ***ret_addrs)
{
    krb5_error_code     retval;
    krb5_address        **addrs;
    int                 i, j, r;
    struct addrinfo hints, *ai, *aip;

    if (!name)
        return KRB5_ERR_BAD_HOSTNAME;

    memset (&hints, 0, sizeof (hints));
    hints.ai_flags = AI_NUMERICHOST | AI_ADDRCONFIG;
    /* We don't care what kind at this point, really, but without
       this, we can get back multiple sockaddrs per address, for
       SOCK_DGRAM, SOCK_STREAM, and SOCK_RAW.  I haven't checked if
       that's what the spec indicates.  */
    hints.ai_socktype = SOCK_DGRAM;

    r = getaddrinfo (name, 0, &hints, &ai);
    if (r && AI_NUMERICHOST != 0) {
        hints.ai_flags &= ~AI_NUMERICHOST;
        r = getaddrinfo (name, 0, &hints, &ai);
    }
    if (r)
        return KRB5_ERR_BAD_HOSTNAME;

    for (i = 0, aip = ai; aip; aip = aip->ai_next) {
        switch (aip->ai_addr->sa_family) {
        case AF_INET:
        case AF_INET6:
            i++;
        default:
            /* Ignore addresses of unknown families.  */
            ;
        }
    }

    addrs = malloc ((i+1) * sizeof(*addrs));
    if (!addrs)
        return ENOMEM;

    for (j = 0; j < i + 1; j++)
        addrs[j] = 0;

    for (i = 0, aip = ai; aip; aip = aip->ai_next) {
        void *ptr;
        size_t addrlen;
        int atype;

        switch (aip->ai_addr->sa_family) {
        case AF_INET:
            addrlen = sizeof (struct in_addr);
            ptr = &sa2sin(aip->ai_addr)->sin_addr;
            atype = ADDRTYPE_INET;
            break;
        case AF_INET6:
            addrlen = sizeof (struct in6_addr);
            ptr = &sa2sin6(aip->ai_addr)->sin6_addr;
            atype = ADDRTYPE_INET6;
            break;
        default:
            continue;
        }
        addrs[i] = (krb5_address *) malloc(sizeof(krb5_address));
        if (!addrs[i]) {
            retval = ENOMEM;
            goto errout;
        }
        addrs[i]->magic = KV5M_ADDRESS;
        addrs[i]->addrtype = atype;
        addrs[i]->length = addrlen;
        addrs[i]->contents = k5memdup(ptr, addrlen, &retval);
        if (addrs[i]->contents == NULL)
            goto errout;
        i++;
    }

    *ret_addrs = addrs;
    if (ai)
        freeaddrinfo(ai);
    return 0;

errout:
    if (addrs) {
        for (i = 0; addrs[i]; i++) {
            free (addrs[i]->contents);
            free (addrs[i]);
        }
        krb5_free_addresses(context, addrs);
    }
    if (ai)
        freeaddrinfo(ai);
    return retval;

}