[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: A more robust krb5_get_host_realm?



On Fri, 23 Mar 2007 09:52:52 +0100
Gabor Gombas <gombasg@sztaki.hu> wrote:

> On Fri, Mar 23, 2007 at 01:56:56AM -0400, Michael B Allen wrote:
> 
> > I want krb5_get_host_realm to try harder to find the domain name. In
> > particular, some systems (Ubuntu Linux for example) easily end up with
> > a hostname that is not an FQDN. In this case, krb5_get_host_realm gives
> > up with KRB5_ERR_HOST_REALM_UNKNOWN.
> 
> Since the hostname has no relation to networking, it is perfectly normal
> if you can not resolve it in any way using DNS.
> 
> > Can someone recommend a superior method? Personally I'm partial to just
> > getting down to business and doing a PTR lookup. Portable too.
> 
> I see two possible methods:
> 
> - Enumerate all IP addresses on all network interfaces and look up the
>   associated FQDNs. On multi-homed machines different addresses may
>   resolve to completely different domains, so you must be able to return
>   a list.
> 
>   If you want a portable solution, use something like libdnet:
>   http://libdnet.sourceforge.net
> 
> - Just make it mandatory to specify the domain/realm in krb5.conf in
>   case the hostname is not resolvable. I think this is the case now,
>   maybe we just need better error messages to inform the user about the
>   situation.

That is what is done now but my user's are not kerberos savvy. I want
to be able to use an empty krb5.conf for as many people as possible and
right now default_realm on debian systems is the only thing throwing a
wrench in my plan.

I don't need a perfect solution. It just needs to try a little harder. As
it is it't just using gethostname and that's it. If gethostname doesn't
return an FQDN it gives up.

After looking at Linux's net-tools (package containing the hostname
command) I came up with the following code that emulates the logic of
hostname --fqdn but strips a trailing '.' if present.

I'll stick it into krb5_get_host_realm and see how it works. If it
doesn't blow up I'll post a patch.

Mike

int   
dns_get_default_domain(unsigned char *dst, size_t dn)
{
    unsigned char buf[HOST_NAME_MAX];
    unsigned char *name = buf, *dot, *dlim = dst + dn;

    if (gethostname(buf, sizeof(buf)) == -1) {
        return -1;
    }

    dot = strchr(name, '.');
    if (dot == NULL || dot[1] == '\0') { 
        struct hostent *he;

        he = gethostbyname(buf);
        if (he == NULL) { 
            return -1;
        }
        name = he->h_name;

        dot = strchr(name, '.');
        if (dot == NULL || dot[1] == '\0') { 
            int ai;

            name = NULL; 
            for (ai = 0; he->h_aliases[ai]; ai++) { 
                name = he->h_aliases[ai];

                dot = strchr(name, '.');
                if (dot && dot[1] != '\0') { 
                    break;
                }
                name = NULL; 
            }       
        }
    }

    if (name == NULL) { 
        errno = ENOENT; 
        return -1;
    }

    /* Copy everything after first '.' to dst (but
     * not a trailing '.' if present)
     */      
    dot = NULL; 
    while (*name) {
        if (dot) { 
            if (dst == dlim)
                break;  
            *dst++ = *name;
        }       
        if (*name == '.') 
            dot = dst - 1;
        name++;
    }
    if (name[-1] == '.') 
        dst = dot;

    if (dst >= dlim) { 
        errno = ENOBUFS;
        return -1;
    }

    *dst = '\0'; 

    return 0;
}

-- 
Michael B Allen
PHP Active Directory Kerberos SSO
http://www.ioplex.com/