A young colleague was unnecessarily ranting about LDAP recently, and more as joke I suggested he switch to Hesiod. His look told me he didn’t know what the heck I was talking about, so I tried to explain.
Hesiod is a name (or directory) service. It’s a bit special in that it is a network database built on top of the Domain Name System (DNS). Hesiod was part of MIT’s original Project Athena, and was a key-stone of the operation in the Athena project and provided directories for many different things such as users, printers and file systems.
The earliest reference of Hesiod I’ve been able to dig (pun not intended) out is in RFC 1034, which cites a paper published in April 1987 by Dyer et.al. As far as I can tell, the paper is The Hesiod Name Server which is dated 1988. Be that as it may, the Hesiod idea and/or implementation have been around for a while. :-)
While Hesiod can be useful as a directory service it would be foolish to use it for confidential data (such as passwords) because DNS data is generally public. Hesiod can (and was) used as a directory service in conjunction with a strong authentication system like Kerberos.
A separate DNS record class (HS
) was set aside for Hesiod, but many preferred
to use the ubiquitous Internet class (IN
). (I believe BIND is the only server which
actually still implements the HS class.) Furthermore, the DNS TXT resource record
was created for Hesiod. From the paper:
A new class, HS, signifying a Hesiod query or datum has been reserved, and a new query type, TXT, that allows the storage of arbitrary ASCII strings. Paul Mockapetris, the Internet Domain System designer, has recently specified the HS class and the TXT type in RFCs 1034 and 1035.
Each of the “tables” managed by Hesiod has a name like “passwd
” or “uid
”, just like
NIS does. Programs
which need to query the database use library functions that send out DNS requests and
process the replies. Hesiod uses the DNS infrastructure including its caching capabilities.
Configure Hesiod
The Hesiod library consults /etc/hesiod.conf
to determine how your tables are
configured in the DNS. My file contains this:
rhs=.ww.mens.de
lhs=.hes
classes=IN
lhs specifies the domain prefix for Hesiod queries, and rhs specifies the default
Hesiod domain. For example, when querying for a username in the passwd
table,
Hesiod will query for <username>.passwd.<lhs>.<rhs>
in the IN
class. In addition
to this configuration, the stub resolver needs to be able to find your DNS servers.
Hesiod data in DNS
Each of the tables you want Hesiod support for (cluster, filsys, gid,
group, grplist, passwd, pcap, pobox, prcluserlist, prcluster,
service, sloc, and uid) must have corresponding domains in the DNS. As
I’m interested in group and passwd only, I add these
entries to the zone hes.ww.mens.de
:
$ORIGIN passwd.hes.ww.mens.de.
jane TXT "jane:x:6009:69:Jane Guest:/home/jane:/bin/bash"
$ORIGIN uid.hes.ww.mens.de.
6009 TXT "jane:x:6009:69:Jane Guest:/home/jane:/bin/bash"
$ORIGIN group.hes.ww.mens.de.
guests TXT "guests:*:69:mongo,jane"
$ORIGIN gid.hes.ww.mens.de.
69 TXT "guests:x:69"
(As Hesiod’s back-end is DNS, the data can also be updated dynamically.)
I can test using the hesinfo
utility:
$ hesinfo jane passwd
jane:x:6009:69:Jane Guest:/home/jane:/bin/bash
A similar output is produced by my small test program:
#include <stdio.h>
#include <hesiod.h>
/* gcc -o hes hes.c -lhesiod */
int main()
{
char **hesinfo, **hip, *username = "jane";
if ((hesinfo = hes_resolve(username, "passwd")) == 0) {
fprintf(stderr, "Unknown user\n");
return (1);
}
for (hip = hesinfo; hip && *hip; hip++) {
printf("%s\n", *hip);
}
return (0);
}
That looks ok, so I can proceed to the configuration of NSS.
Configure NSS
I’ve configured Hesiod and have added some entries to the appropriate DNS zones,
so I can now configure the Name Service Switch (NSS) to use Hesiod, by modifying
/etc/nsswitch.conf
. At least I’ll want to obtain user data via Hesiod, so I
change passwd and group:
$ grep hesiod /etc/nsswitch.conf
passwd: files hesiod
group: files hesiod
Does it work? Yes, it does, though note that Hesiod doesn’t support object-enumeration
because the underlying database doesn’t: so, while getent passwd
on, say, an LDAP
directory would work (depending on the directory-imposed restrictions), it won’t with Hesiod.
$ getent passwd jane
jane:x:6009:69:Jane Guest:/home/jane:/bin/bash
$ id jane
uid=6009(jane) gid=69(guests) groups=(69)guests
Using this setup by itself wouldn’t allow users to login to a system because
the password is missing. (What does work though, is for a privileged user to su jane
.)
While it can be added to the passwd entries in the
DNS, I urge you not to do that: use Kerberos for authentication instead,
with Hesiod as the name service.
Hesiod may not be very popular any more, but even so, RedHat/Centos-based systems still provide authconfig with support configuring Hesiod automatically. If you feel like hacking, Perl’s Net::Hesiod and a couple of Python modules are readily available.
In 1988, Dyer writes:
A measure of how successful Hesiod has been in its deployment over the past six months is how infrequently problems have appeared. For the most part, applications make Hesiod queries and receive answers with millisecond delays. Today, the Hesiod database for Project Athena contains almost three megabytes of data: roughly 9500 /etc/passwd entries, 10000 /etc/group entries, 6500 file system entries and 8600 post office records. There are three primary Hesiod nameservers distributed across the campus network.
There: end of history lesson.