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:

4 comments:

booterror said...

Is there anything else that needs to be done special? I am trying this on a Debian based machine (NIS Server) and a fresh install of FreeBSD 7.2 RELEASE (NIS Client)

I added your script and Makefile modifications and the FreeBSD machine can see the maps if I ypcat them (master.passwd etc), But acts like it cant see the maps when i attempt to login/id/etc any NIS users. ( I have added the appropriate lines in /etc/master.passwd)

Anonymous said...

Got this to work. Just an FYI, on Redhat EL4 there is no MAXUID by default in the Makefile, so need to add that variable to get it to work correctly.

Thanks,
James Kohout

zbigg said...

Hint -> PAM on NIS server must be configured to use md5.

Example from my ubuntu:

$ cat /etc/pam.d/common-password

password [success=2 default=ignore] pam_unix.so obscure md5 # sha512

dylex said...

Here's a version that doesn't need python: just replace the awk command with:

$(AWK) 'BEGIN{FS=OFS=":"}/[^-+#:]/{ if ($$3 >= $(MINUID) && $$3 <= $(MAXUID) && $$3 != $(NFSNOBODYUID) ) print $$3"\t"$$1,$$2,$$3,$$4,"",0,0,$$5,$$6,$$7 }'