Tuesday, 17 March 2009

FreeBSD as NIS client of Linux

For record: FreeBSD has a little different way of storing important login information - Linux stores it in /etc/passwd and /etc/shadow FreeBSD uses only /etc/master.passwd (/etc/passwd is generated from the former for reference).

/etc/master.passwd contains both traditional "passwd" data like name, uid, gid, home shell + password and some administrative values.

So, FreeBSD expects NIS server to provide master.passwd file but and OOB Linux NIS server installation doesn't have it. One must add it to YP database. It's not so hard.

At least on Debian/Ubuntu YP domain data are stored in /var/yp. There is one makefile that simply generates all YP server data files from your ... (choose passwd, group, shadow, hosts ...). Regarding passwords we must generate two databases master.passwd.byuid and master.passwd.byname very similarly as passwd.{byname,byuid} are created. So let's go: Here is python script that takes custom merger output (shadow+passwd) and makes "master.passwd" compatible file.

#!/usr/bin/python

shell_map = {
    "/bin/bash": "/usr/local/bin/bash"
}
def map_shell(shell):
    return shell_map.get(shell, shell)

import sys
for line in sys.stdin.readlines():
    line = line.strip();    
    name, passwd, uid, gid, desc, home, shell = line.split(':')
    desc_fields = desc.split(",")
    gecos = desc_fields[0]
    class_name = ""
    password_change_time = "0"
    account_expiration_time = "0"
    shell = map_shell(shell)
    all = ":".join([name, passwd, uid, gid, class_name, password_change_time, account_expiration_time, gecos, home, shell])
    print all

And here is Makefile snippet that can be inserted to main Makefile or included:

#
# Makefile part for /var/yp/Makefile
#
ALL += master.passwd

MASTER_PASSWD_CONVERTER=python /home/zbigg/projects/nis-linux-freebsd/master.passwd-converter.py ### this is the path to former python script

master.passwd: master.passwd.byname master.passwd.byuid

master.passwd.byuid: $(PASSWD) $(SHADOW) $(YPDIR)/Makefile
 @echo "Updating $@"
 @$(MERGER) -p $(PASSWD) $(SHADOW) | $(MASTER_PASSWD_CONVERTER) | \
 $(AWK) -F: '!/^[-+#]/ { if ($$1 != "" && $$3 >= $(MINUID) && $$3 <= $(MAXUID) && $$3 != $(NFSNOBODYUID) ) \
 print $$3"\t"$$0 }' | $(DBLOAD) -i $(GROUP) -o $(YPMAPDIR)/$@ - $@
 -@$(NOPUSH) || $(YPPUSH) -d $(DOMAIN) $@

master.passwd.byname: $(PASSWD) $(SHADOW) $(YPDIR)/Makefile
 @echo "Updating $@"
 @$(MERGER) -p $(PASSWD) $(SHADOW) | $(MASTER_PASSWD_CONVERTER) | \
 $(AWK) -F: '!/^[-+#]/ { if ($$1 != "" && $$3 >= $(MINUID) && $$3 <= $(MAXUID) && $$3 != $(NFSNOBODYUID) ) \
 print $$1"\t"$$0 }' | $(DBLOAD) -i $(GROUP) -o $(YPMAPDIR)/$@ - $@

 -@$(NOPUSH) || $(YPPUSH) -d $(DOMAIN) $@

Works for me :)

When configuring NIS on hosts i've followed these instructions: