summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>1995-12-16 20:54:17 +0000
committerwpaul <wpaul@FreeBSD.org>1995-12-16 20:54:17 +0000
commit6c6bb5ba6adeb2ff4ad3daae731ae6fd78bdaa36 (patch)
treeb482c0df4aeed97dbf67034a03c60d54726b3959 /usr.sbin
parent5cb69655f98eb01c22037b87a84bb2bd50a7b0fb (diff)
parentf177e119995c5aae346675c30599d00d3286440c (diff)
downloadFreeBSD-src-6c6bb5ba6adeb2ff4ad3daae731ae6fd78bdaa36.zip
FreeBSD-src-6c6bb5ba6adeb2ff4ad3daae731ae6fd78bdaa36.tar.gz
This commit was generated by cvs2svn to compensate for changes in r12891,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/ypserv/Makefile35
-rw-r--r--usr.sbin/ypserv/Makefile.yp394
-rwxr-xr-xusr.sbin/ypserv/mknetid36
-rw-r--r--usr.sbin/ypserv/yp_access.c146
-rw-r--r--usr.sbin/ypserv/yp_dblookup.c217
-rw-r--r--usr.sbin/ypserv/yp_dnslookup.c111
-rw-r--r--usr.sbin/ypserv/yp_error.c86
-rw-r--r--usr.sbin/ypserv/yp_extern.h73
-rw-r--r--usr.sbin/ypserv/yp_main.c315
-rw-r--r--usr.sbin/ypserv/yp_server.c626
-rw-r--r--usr.sbin/ypserv/ypserv.8306
11 files changed, 2345 insertions, 0 deletions
diff --git a/usr.sbin/ypserv/Makefile b/usr.sbin/ypserv/Makefile
new file mode 100644
index 0000000..e3fe74a
--- /dev/null
+++ b/usr.sbin/ypserv/Makefile
@@ -0,0 +1,35 @@
+# $Id: Makefile,v 1.6 1995/12/16 04:03:02 wpaul Exp $
+
+PROG= ypserv
+SRCS= yp_svc.c yp_server.c yp_dblookup.c yp_dnslookup.c \
+ yp_main.c yp_error.c yp_access.c
+
+MAN8= ypserv.8
+
+CLEANFILES= yp_svc.c yp.h
+
+RPCSRC= ${.DESTDIR}/usr/include/rpcsvc/yp.x
+RPCGEN= rpcgen -I -C -DYPSERV_ONLY
+
+# We need to remove the 'static' keyword from _rpcsvcstate so that
+# yp_main.c can see it.
+yp_svc.c: ${RPCSRC} yp.h
+ rm -f ${.TARGET}
+ ${RPCGEN} -m ${RPCSRC} | \
+ sed s/"static int _rpcsvcstate"/"int _rpcsvcstate"/g > ${.TARGET}
+
+yp_xdr.c: ${RPCSRC} yp.h
+ ${RPCGEN} -c -o ${.TARGET} ${RPCSRC}
+
+yp.h: ${RPCSRC}
+ ${RPCGEN} -h -o ${.TARGET} ${RPCSRC}
+
+afterinstall:
+ ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${.CURDIR}/Makefile.yp \
+ ${DESTDIR}/var/yp/Makefile
+ ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
+ ${.CURDIR}/mknetid \
+ ${DESTDIR}/usr/libexec/mknetid
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/ypserv/Makefile.yp b/usr.sbin/ypserv/Makefile.yp
new file mode 100644
index 0000000..67da59ad
--- /dev/null
+++ b/usr.sbin/ypserv/Makefile.yp
@@ -0,0 +1,394 @@
+#
+# Makefile for the NIS databases
+#
+# $Id: Makefile.yp,v 1.1 1995/12/09 04:33:14 wpaul Exp $
+#
+# This Makefile should only be run on the NIS master server of a domain.
+# All updated maps will be pushed to all NIS slave servers listed in the
+# /var/yp/ypservers file. Please make sure that the hostnames of all
+# NIS servers in your domain are listed in /var/yp/ypservers.
+#
+# This Makefile can be modified to support more NIS maps if desired.
+#
+
+# If this machine is an NIS master, comment out this next line so
+# that changes to the NIS maps can be propagated to the slave servers.
+# (By default we assume that we are only serving a small domain with
+# only one server.)
+#
+NOPUSH = "True"
+
+# If you want to use a FreeBSD NIS server to serve non-FreeBSD clients
+# (i.e. clients who expect the password field in the passwd maps to be
+# valid) then uncomment this line. This will cause $YPDIR/passwd to
+# be generated with valid password fields. This is insecure: FreeBSD
+# normally only serves the master.passwd maps (which have real encrypted
+# passwords in them) to the superuser on other FreeBSD machines, but
+# non-FreeBSD clients (e.g. SunOS, Solaris (without NIS+), IRIX, HP-UX,
+# etc...) will only work properly in 'unsecure' mode.
+#
+#UNSECURE = "True"
+
+# These are commands which this Makefile needs to properly rebuild the
+# NIS databases. Don't change these unless you have a good reason. Also
+# be sure not to place an @ in front of /usr/bin/awk: it isn't necessary
+# and it'll break everything in sight.
+#
+AWK = /usr/bin/awk
+RM = @/bin/rm -f
+RCAT = /bin/cat
+CAT = @$(RCAT)
+
+DBLOAD = /usr/sbin/yp_mkdb -m `hostname`
+MKNETID = /usr/libexec/mknetid
+YPPUSH = /usr/bin/yppush
+DOMAIN = `/bin/domainname`
+REVNETGROUP = /usr/libexec/revnetgroup
+
+YPSRCDIR = /etc
+YPDIR = /var/yp
+YPMAPDIR = $(YPDIR)/$(DOMAIN)
+
+# These are the files from which the NIS databases are built. You may edit
+# these to taste in the event that you wish to keep your NIS source files
+# seperate from your NIS server's actual configuration files. Note that the
+# NIS passwd and master.passwd files are stored in /var/yp: the server's
+# real password database is not used by default. However, you may use
+# the real /etc/passwd and /etc/master.passwd files by:
+#
+#
+# - invoking yppasswdd without the -m option (yppasswdd will use
+# /etc/master.passwd if no alternate master.passwd file is specified
+# and do a 'pwd_mkdb' as needed).
+# - Specifying the location of the master.passwd file using the
+# MASTER_PASSWD variable, i.e.:
+#
+# # make MASTER_PASSWD=/path/to/some/other/master.passwd
+#
+# - (optionally): editing this Makefile to change the default location.
+#
+# To add a user, edit $(YPDIR)/master.passwd and type 'make'. The raw
+# passwd file will be generated from the master.passwd file automagically.
+#
+ETHERS = $(YPSRCDIR)/ethers # ethernet addresses (for rarpd)
+BOOTPARAMS= $(YPSRCDIR)/bootparams # for booting Sun boxes (bootparamd)
+HOSTS = $(YPSRCDIR)/hosts
+NETWORKS = $(YPSRCDIR)/networks
+PROTOCOLS = $(YPSRCDIR)/protocols
+RPC = $(YPSRCDIR)/rpc
+SERVICES = $(YPSRCDIR)/services
+GROUP = $(YPSRCDIR)/group
+NETGROUP = $(YPSRCDIR)/netgroup
+PASSWD = $(YPDIR)/passwd
+.if !defined(MASTER_PASSWD)
+MASTER = $(YPDIR)/master.passwd
+.else
+MASTER = $(MASTER_PASSWD)
+.endif
+YPSERVERS = $(YPDIR)/ypservers # List of all NIS servers for a domain
+PUBLICKEY = $(YPSRCDIR)/publickey
+
+target:
+ @if [ ! -d $(DOMAIN) ]; then mkdir $(DOMAIN); fi; \
+ cd $(DOMAIN) ; echo "NIS Map update started on `date`" ; \
+ make -f ../Makefile all; echo "NIS Map update completed."
+
+# If you don't want some of these maps built, feel free to comment
+# them out from this list.
+# Note that we don't build the ethers or boorparams maps by default
+# since /etc/ethers and /etc/bootparams are not likely to be present
+# on all systems.
+#
+
+all: master.passwd passwd hosts group networks protocols \
+ rpc services servers netid # publickey netgroup ethers bootparam
+
+ethers: ethers.byname ethers.byaddr
+bootparam: bootparams
+hosts: hosts.byname hosts.byaddr
+networks: networks.byaddr networks.byname
+protocols: protocols.bynumber protocols.byname
+rpc: rpc.byname rpc.bynumber
+services: services.byname
+passwd: passwd.byname passwd.byuid
+group: group.byname group.bygid
+netgrp: netgroup
+netid: netid.byname
+servers: ypservers
+publickey: publickey.byname
+
+master.passwd: master.passwd.byname master.passwd.byuid
+
+
+ypservers: $(YPSERVERS)
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(YPSERVERS) | \
+ $(AWK) '{ if ($$1 != "" && $$1 != "#") print $$0"\t"$$0 }' $^ \
+ | $(DBLOAD) -i $(YPSERVERS) -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+
+ethers.byname: $(ETHERS)
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(ETHERS) | \
+ $(AWK) '{ if ($$1 != "" && $$1 != "#" && $$1 != "+") \
+ print $$2"\t"$$0 }' $^ | $(DBLOAD) -i $(ETHERS) \
+ -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) -i $(ETHERS) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+
+
+ethers.byaddr: $(ETHERS)
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(ETHERS) | \
+ $(AWK) '{ if ($$1 != "" && $$1 != "#" && $$1 != "+") \
+ print $$1"\t"$$0 }' $^ | $(DBLOAD) -i $(ETHERS) \
+ -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+
+
+bootparams: $(BOOTPARAMS)
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(BOOTPARAMS) | \
+ $(AWK) '{ if ($$1 != "" && $$1 != "#" && $$1 != "+") \
+ print $$0 }' $^ | $(DBLOAD) -i $(BOOTPARAMS) \
+ -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+
+
+netgroup: $(NETGROUP) netgroup.byhost netgroup.byuser
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(NETGROUP) | \
+ $(AWK) '{ if ($$1 != "" && $$1 != "#" && $$1 != "+") \
+ print $$0 }' $^ | $(DBLOAD) -i $(NETGROUP) \
+ -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+ @$(MAKE) -f ../Makefile netid
+
+
+netgroup.byhost: $(NETGROUP)
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(NETGROUP) | $(REVNETGROUP) -h -f $(NETGROUP) | \
+ $(AWK) '{ if ($$1 != "" && $$1 != "#" && $$1 != "+") \
+ print $$0 }' $^ | $(DBLOAD) -i $(NETGROUP) \
+ -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+
+
+netgroup.byuser: $(NETGROUP)
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(NETGROUP) | $(REVNETGROUP) -u -f $(NETGROUP) | \
+ $(AWK) '{ if ($$1 != "" && $$1 != "#" && $$1 != "+") \
+ print $$0 }' $^ | $(DBLOAD) -i $(NETGROUP) \
+ -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+
+
+hosts.byname: $(HOSTS)
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(HOSTS) | \
+ $(AWK) '/^[0-9]/ { for (n=2; n<=NF && $$n !~ "#"; n++) \
+ print $$n"\t"$$0 }' $^ | $(DBLOAD) -i $(HOSTS) \
+ -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+ @$(MAKE) -f ../Makefile netid
+
+hosts.byaddr: $(HOSTS)
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(HOSTS) | \
+ $(AWK) '$$1 !~ "#" { print $$1"\t"$$0 }' $^ \
+ | $(DBLOAD) -i $(HOSTS) -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+ @$(MAKE) -f ../Makefile netid
+
+
+networks.byname: $(NETWORKS)
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(NETWORKS) | \
+ $(AWK) \
+ '$$1 !~ "#" { print $$1"\t"$$0; \
+ for (n=3; n<=NF && $$n !~ "#"; n++) \
+ print $$n"\t"$$0 \
+ }' $^ | $(DBLOAD) -i $(NETWORKS) -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+
+
+networks.byaddr: $(NETWORKS)
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(NETWORKS) | \
+ $(AWK) '$$1 !~ "#" { print $$2"\t"$$0 }' $^ \
+ | $(DBLOAD) -i $(NETWORKS) -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+
+
+protocols.byname: $(PROTOCOLS)
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(PROTOCOLS) | \
+ $(AWK) \
+ '$$1 !~ "#" { print $$1"\t"$$0; \
+ for (n=3; n<=NF && $$n !~ "#"; n++) \
+ print $$n"\t"$$0 \
+ }' $^ | $(DBLOAD) -i $(PROTOCOLS) \
+ -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+
+
+protocols.bynumber: $(PROTOCOLS)
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(PROTOCOLS) | \
+ $(AWK) '$$1 !~ "#" { print $$2"\t"$$0 }' $^ \
+ | $(DBLOAD) -i $(PROTOCOLS) -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+
+
+rpc.byname: $(RPC)
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(RPC) | \
+ $(AWK) \
+ '$$1 !~ "#" { print $$1"\t"$$0; \
+ for (n=3; n<=NF && $$n !~ "#"; n++) \
+ print $$n"\t"$$0 \
+ }' $^ | $(DBLOAD) -i $(RPC) -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+
+
+rpc.bynumber: $(RPC)
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(RPC) | \
+ $(AWK) '$$1 !~ "#" { print $$2"\t"$$0 }' $^ \
+ | $(DBLOAD) -i $(RPC) -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+
+
+services.byname: $(SERVICES)
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(SERVICES) | \
+ $(AWK) \
+ '$$1 !~ "#" { if (index($$2,"udp")) { printf("%s/udp",$$1) } \
+ else { printf("%s/tcp",$$1) }; print "\t"$$0 \
+ }' $^ | $(DBLOAD) -i $(SERVICES) -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+
+
+publickey.byname: $(PUBLICKEY)
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(PUBLICKEY) | \
+ $(AWK) '$$1 !~ "#" { print $$1"\t"$$2 }' $^ \
+ | $(DBLOAD) -i $(PUBLICKEY) -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+
+
+$(PASSWD): $(MASTER)
+ @echo "Creating new $@ file from $(MASTER)..."
+ $(RM) $@
+ @if [ ! $(UNSECURE) ]; then \
+ $(RCAT) $(MASTER) | \
+ $(AWK) -F: '{if ($$1 != "+") \
+ print $$1":*:"$$3":"$$4":"$$8":"$$9":"$$10}' $^ \
+ > $(PASSWD) ; \
+ else $(RCAT) $(MASTER) | \
+ $(AWK) -F: '{if ($$1 != "+") \
+ print $$1":"$$2":"$$3":"$$4":"$$8":"$$9":"$$10}' $^ \
+ > $(PASSWD) ; fi
+
+
+passwd.byname: $(PASSWD)
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(PASSWD) | \
+ $(AWK) -F: '{ if ($$1 != "+") print $$1"\t"$$0 }' $^ \
+ | $(DBLOAD) -i $(PASSWD) -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+
+passwd.byuid: $(PASSWD)
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(PASSWD) | \
+ $(AWK) -F: '{ if ($$1 != "+") print $$3"\t"$$0 }' $^ \
+ | $(DBLOAD) -i $(PASSWD) -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+ @$(MAKE) -f ../Makefile netid
+
+
+group.byname: $(GROUP)
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(GROUP) | \
+ $(AWK) -F: '{ if ($$1 != "+") print $$1"\t"$$0 }' $^ \
+ | $(DBLOAD) -i $(GROUP) -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+
+
+group.bygid: $(GROUP)
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(GROUP) | \
+ $(AWK) -F: '{ if ($$1 != "+") print $$3"\t"$$0 }' $^ \
+ | $(DBLOAD) -i $(GROUP) -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+ @$(MAKE) -f ../Makefile netid
+
+
+netid.byname: $(GROUP) $(PASSWD)
+ @echo "Updating $@..."
+ $(RM) $@
+ @$(MKNETID) $(PASSWD) $(GROUP) `basename \`pwd\`` \
+ | $(DBLOAD) -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+
+
+master.passwd.byname: $(MASTER)
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(MASTER) | \
+ $(AWK) -F: '{ if ($$1 != "+") print $$1"\t"$$0 }' $^ \
+ | $(DBLOAD) -i $(MASTER) -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
+
+
+master.passwd.byuid: $(MASTER)
+ @echo "Updating $@..."
+ $(RM) $@
+ $(CAT) $(MASTER) | \
+ $(AWK) -F: '{ if ($$1 != "+") print $$3"\t"$$0 }' $^ \
+ | $(DBLOAD) -i $(MASTER) -o $(YPMAPDIR)/$@ - $@
+ @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOMAIN) $@; fi
+ @if [ ! $(NOPUSH) ]; then echo "Pushed $@ map." ; fi
diff --git a/usr.sbin/ypserv/mknetid b/usr.sbin/ypserv/mknetid
new file mode 100755
index 0000000..6619b5d
--- /dev/null
+++ b/usr.sbin/ypserv/mknetid
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+# Produce netid.byname map file
+#
+# Written by O.Kirch, 1994.
+#
+PASSWD=$1
+GROUP=$2
+DOMAIN=$3
+
+tempsed=/tmp/pass.$$
+
+ # First, get all login/uid info from passwd file
+ grep -v '^+:' $PASSWD |
+ awk -F: '{ printf "s/^%s:/%s/\n", $1, $3; }' >$tempsed
+ # next one is a giant pipe:
+ grep -v '^+:' $GROUP |
+ grep -v ':[ ]*$' |
+ sed 's/^[^:]*:[^:]*:\([0-9]*\):\(.*\)/\1,\2/' |
+ awk -F, '{ for (n=2; n<=NF; n++)
+ if ($n != "") print $n":\t"$1;
+ }' |
+ sed -f $tempsed | sort | grep -v ':' |
+ awk 'BEGIN { uid=-1; }
+ { if (uid == $1) {
+ groups=groups","$2;
+ } else {
+ if (uid != -1)
+ print uid":"groups;
+ uid=$1; groups=$2;
+ }
+ }
+ END { if (uid != -1) printf("%s:%s\n", uid, groups); }' |
+ sed "s/\(.*\):/unix.\1@$DOMAIN &/"
+ rm -f $tempsed
+ exit 0
diff --git a/usr.sbin/ypserv/yp_access.c b/usr.sbin/ypserv/yp_access.c
new file mode 100644
index 0000000..d022d8e
--- /dev/null
+++ b/usr.sbin/ypserv/yp_access.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 1995
+ * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <rpc/rpc.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/stat.h>
+#include <paths.h>
+#include <sys/param.h>
+#include "yp_extern.h"
+#ifdef TCP_WRAPPER
+#include "tcpd.h"
+#endif
+
+extern int debug;
+
+char *yp_procs[] = { "ypproc_null" ,
+ "ypproc_domain",
+ "ypproc_domain_nonack",
+ "ypproc_match",
+ "ypproc_first",
+ "ypproc_next",
+ "ypproc_xfr",
+ "ypproc_clear",
+ "ypproc_all",
+ "ypproc_master",
+ "ypproc_order",
+ "ypproc_maplist"
+ };
+
+/*
+ * Access control functions.
+ *
+ * yp_access() checks the mapname and client host address and watches for
+ * the following things:
+ *
+ * - If the client is referencing one of the master.passwd.* maps, it must
+ * be using a privileged port to make its RPC to us. If it is, then we can
+ * assume that the caller is root and allow the RPC to succeed. If it
+ * isn't access is denied.
+ *
+ * - If we are compiled with the tcpwrapper package, we also check to see
+ * if the host makes it past the libwrap checks and deny access if it
+ * doesn't. Host address checks are disabled if not compiled with the
+ * tcp_wrapper package.
+ *
+ * The yp_validdomain() functions checks the domain specified by the caller
+ * to make sure it's actually served by this server. This is more a sanity
+ * check than an a security check, but this seems to be the best place for
+ * it.
+ */
+
+int yp_access(map, rqstp)
+ const char *map;
+ const struct svc_req *rqstp;
+{
+ struct sockaddr_in *rqhost;
+#ifdef TCP_WRAPPER
+ int status = 0;
+ unsigned long oldaddr;
+#endif
+
+ rqhost = svc_getcaller(rqstp->rq_xprt);
+
+ if (debug) {
+ yp_error("Procedure %s called from %s:%d",
+ yp_procs[rqstp->rq_proc], inet_ntoa(rqhost->sin_addr),
+ ntohs(rqhost->sin_port));
+ if (map != NULL)
+ yp_error("Client is referencing map \"%s\".", map);
+ }
+
+ /* Check the map name if one was supplied. */
+ if (map != NULL) {
+ if (strstr(map, "master.passwd.") && ntohs(rqhost->sin_port) > 1023) {
+ yp_error("Access to %s denied -- client not privileged", map);
+ return(1);
+ }
+ }
+
+#ifdef TCP_WRAPPER
+ /* Check client address if TCP_WRAPPER is enalbled. */
+ status = hosts_ctl(progname, STRING_UNKNOWN,
+ inet_ntoa(rqhost->sin_addr, "");
+
+ if (!status && rqhost->sin_addr.s_addr != oldaddr) {
+ yp_error("connect from %s:%d refused",
+ inet_ntoa(rqhost->sin_addr, ntohs(rqhost->sin_port));
+ oldaddr = rqhost->sin_addr.s_addr;
+ return(1);
+ }
+#endif
+ return(0);
+
+}
+
+int yp_validdomain(domain)
+ const char *domain;
+{
+ struct stat statbuf;
+ char dompath[MAXPATHLEN + 2];
+
+ if (domain == NULL || strstr(domain, "binding") ||
+ !strcmp(domain, ".") || !strcmp(domain, "..") ||
+ strchr(domain, '/'))
+ return(1);
+
+ snprintf(dompath, sizeof(dompath), "%s/%s", yp_dir, domain);
+
+ if (stat(dompath, &statbuf) < 0 || !S_ISDIR(statbuf.st_mode))
+ return(1);
+
+ return(0);
+}
diff --git a/usr.sbin/ypserv/yp_dblookup.c b/usr.sbin/ypserv/yp_dblookup.c
new file mode 100644
index 0000000..79df52e
--- /dev/null
+++ b/usr.sbin/ypserv/yp_dblookup.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 1995
+ * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: yp_dblookup.c,v 1.13 1995/12/16 04:46:10 wpaul Exp $
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+#include <limits.h>
+#include <unistd.h>
+#include <db.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <paths.h>
+#include "yp.h"
+#include "yp_extern.h"
+
+extern int debug_flag;
+int yp_errno = YP_TRUE;
+
+#define PERM_SECURE (S_IRUSR|S_IWUSR)
+HASHINFO openinfo = {
+ 4096, /* bsize */
+ 32, /* ffactor */
+ 256, /* nelem */
+ 2048 * 1024, /* cachesize */
+ NULL, /* hash */
+ 0, /* lorder */
+};
+
+/*
+ * Open a DB database
+ */
+DB *yp_open_db(domain, map)
+ const char *domain;
+ const char *map;
+{
+ DB *dbp;
+ char buf[1025];
+
+
+ yp_errno = YP_TRUE;
+
+ if (map[0] == '.' || strchr(map, '/')) {
+ yp_errno = YP_BADARGS;
+ return (NULL);
+ }
+
+ snprintf(buf, sizeof(buf), "%s/%s/%s", yp_dir, domain, map);
+
+ dbp = dbopen(buf,O_RDONLY|O_EXCL, PERM_SECURE, DB_HASH, &openinfo);
+
+ if (dbp == NULL) {
+ switch(errno) {
+ case ENOENT:
+ yp_errno = YP_NOMAP;
+ break;
+ case EFTYPE:
+ yp_errno = YP_BADDB;
+ break;
+ default:
+ yp_errno = YP_YPERR;
+ break;
+ }
+ }
+
+ return (dbp);
+}
+
+/*
+ * Database access routines.
+ *
+ * - yp_get_record(): retrieve an arbitrary key/data pair given one key
+ * to match against.
+ *
+ * - yp_first_record(): retrieve first key/data base in a database.
+ *
+ * - yp_next_record(): retrieve key/data pair that sequentially follows
+ * the supplied key value in the database.
+ */
+
+int yp_get_record(domain,map,key,data,allow)
+ const char *domain;
+ const char *map;
+ const DBT *key;
+ DBT *data;
+ int allow;
+{
+ DB *dbp;
+
+ if (debug)
+ yp_error("Looking up key [%.*s] in map [%s]",
+ key->size, key->data, map);
+
+ /*
+ * Avoid passing back magic "YP_*" entries unless
+ * the caller specifically requested them by setting
+ * the 'allow' flag.
+ */
+ if (!allow && !strncmp(key->data, "YP_", 3))
+ return(YP_NOKEY);
+
+ if ((dbp = yp_open_db(domain, map)) == NULL) {
+ return(yp_errno);
+ }
+
+ if ((dbp->get)(dbp,key,data,0)) {
+ (void)(dbp->close)(dbp);
+ return(YP_NOKEY);
+ }
+
+ (void)(dbp->close)(dbp);
+
+ if (debug)
+ yp_error("Result of lookup: key: [%.*s] data: [%.*s]",
+ key->size, key->data, data->size, data->data);
+
+ return(YP_TRUE);
+}
+
+int yp_first_record(dbp,key,data)
+ const DB *dbp;
+ DBT *key;
+ DBT *data;
+{
+
+ if (debug)
+ yp_error("Retrieving first key in map.");
+
+ if ((dbp->seq)(dbp,key,data,R_FIRST))
+ return(YP_BADDB);
+
+ /* Avoid passing back magic "YP_*" records. */
+ while (!strncmp(key->data, "YP_", 3)) {
+ if ((dbp->seq)(dbp,key,data,R_NEXT))
+ return(YP_BADDB);
+ }
+
+ if (debug)
+ yp_error("Result of lookup: key: [%.*s] data: [%.*s]",
+ key->size, key->data, data->size, data->data);
+
+ return(YP_TRUE);
+}
+
+int yp_next_record(dbp,key,data,all)
+ const DB *dbp;
+ DBT *key;
+ DBT *data;
+ int all;
+{
+ DBT lkey, ldata;
+
+ if (key == NULL || key->data == NULL)
+ return(yp_first_record(dbp,key,data));
+
+ if (debug)
+ yp_error("Retreiving next key, previous was: [%.*s]",
+ key->size, key->data);
+
+ if (!all) {
+ (dbp->seq)(dbp,&lkey,&ldata,R_FIRST);
+ while(strncmp((char *)key->data,lkey.data,(int)key->size) ||
+ key->size != lkey.size)
+ (dbp->seq)(dbp,&lkey,&ldata,R_NEXT);
+ }
+
+ if ((dbp->seq)(dbp,&lkey,&ldata,R_NEXT))
+ return(YP_NOMORE);
+
+ /* Avoid passing back magic "YP_*" records. */
+ while (!strncmp(lkey.data, "YP_", 3))
+ if ((dbp->seq)(dbp,&lkey,&ldata,R_NEXT))
+ return(YP_NOMORE);
+
+ if ((dbp->get)(dbp,&lkey,&ldata,0))
+ return(YP_FALSE);
+
+ *key = lkey;
+ *data = ldata;
+
+ if (debug)
+ yp_error("Result of lookup: key: [%.*s] data: [%.*s]",
+ key->size, key->data, data->size, data->data);
+
+ return(YP_TRUE);
+}
diff --git a/usr.sbin/ypserv/yp_dnslookup.c b/usr.sbin/ypserv/yp_dnslookup.c
new file mode 100644
index 0000000..a3d4b7a
--- /dev/null
+++ b/usr.sbin/ypserv/yp_dnslookup.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1995
+ * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: yp_dnslookup.c,v 1.4 1995/12/07 05:01:34 wpaul Exp $
+ */
+
+/*
+ * Do standard and reverse DNS lookups using the resolver library.
+ * Take care of all the dirty work here so the main program only has to
+ * pass us a pointer to an array of characters.
+ *
+ * We have to use direct resolver calls here otherwise the YP server
+ * could end up looping by calling itself over and over again until
+ * it disappeared up its own belly button.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/param.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include "yp_extern.h"
+
+extern struct hostent *_gethostbydnsname __P(( char * ));
+extern struct hostent *_gethostbydnsaddr __P(( const char *, int, int ));
+
+static char *parse(hp)
+ struct hostent *hp;
+{
+ static char result[MAXHOSTNAMELEN * 2];
+ int len,i;
+ struct in_addr addr;
+
+ len = 16 + strlen(hp->h_name);
+ for (i = 0; hp->h_aliases[i]; i++)
+ len += strlen(hp->h_aliases[i]) + 1;
+
+ bzero(result, sizeof(result));
+
+ bcopy(hp->h_addr, &addr, sizeof(struct in_addr));
+ snprintf(result, sizeof(result), "%s %s", inet_ntoa(addr), hp->h_name);
+
+ for (i = 0; hp->h_aliases[i]; i++) {
+ strcat(result, " ");
+ strcat(result, hp->h_aliases[i]);
+ }
+
+ return ((char *)&result);
+}
+
+char *yp_dnsname(address)
+ char *address;
+{
+ struct hostent *hp;
+
+ if (strchr(address, '@'))
+ return (NULL);
+ if ((hp = (struct hostent *)_gethostbydnsname(address)) == NULL)
+ return (NULL);
+
+ return(parse(hp));
+}
+
+char *yp_dnsaddr(address)
+ const char *address;
+{
+ struct hostent *hp;
+ struct in_addr addr;
+
+ if (strchr(address, '@'))
+ return (NULL);
+ if (!inet_aton(address, &addr))
+ return (NULL);
+ if ((hp = (struct hostent *)_gethostbydnsaddr((const char *)&addr,
+ sizeof(unsigned long), AF_INET)) == NULL)
+ return (NULL);
+
+ return(parse(hp));
+}
diff --git a/usr.sbin/ypserv/yp_error.c b/usr.sbin/ypserv/yp_error.c
new file mode 100644
index 0000000..bb5e632
--- /dev/null
+++ b/usr.sbin/ypserv/yp_error.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1995
+ * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+/*
+ * error logging/reporting facilities
+ * stolen from /usr/libexec/mail.local via ypserv
+ *
+ * $Id: yp_error.c,v 1.2 1995/12/06 16:02:56 wpaul Exp $
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <syslog.h>
+
+int debug;
+extern int _rpcpmstart;
+
+extern char *progname;
+
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+void verr(fmt, ap)
+ const char *fmt;
+ _BSD_VA_LIST_ ap;
+
+{
+ if (debug && !_rpcpmstart) {
+ fprintf(stderr,"%s: ",progname);
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ } else {
+ vsyslog(LOG_NOTICE, fmt, ap);
+ }
+}
+
+void
+#ifdef __STDC__
+yp_error(const char *fmt, ...)
+#else
+yp_error(fmt, va_list)
+ const char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+#ifdef __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ verr(fmt,ap);
+ va_end(ap);
+}
diff --git a/usr.sbin/ypserv/yp_extern.h b/usr.sbin/ypserv/yp_extern.h
new file mode 100644
index 0000000..f16ba20
--- /dev/null
+++ b/usr.sbin/ypserv/yp_extern.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1995
+ * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: yp_extern.h,v 1.9 1995/12/16 04:01:55 wpaul Exp $
+ */
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <limits.h>
+#include <db.h>
+#include <rpc/rpc.h>
+
+#ifndef _PATH_YP
+#define _PATH_YP "/var/yp/"
+#endif
+
+#ifndef _PATH_LIBEXEC
+#define _PATH_LIBEXEC "/usr/libexec/"
+#endif
+
+#ifndef MAX_CHILDREN
+#define MAX_CHILDREN 20
+#endif
+
+/*
+ * External functions and variables.
+ */
+
+extern int debug;
+extern int do_dns;
+extern int children;
+extern char *progname;
+extern char *yp_dir;
+extern int yp_errno;
+extern void yp_error __P((const char *, ...));
+extern int yp_get_record __P(( const char *, const char *, const DBT *, DBT *, int));
+extern int yp_first_record __P((const DB *, DBT *, DBT *));
+extern int yp_next_record __P((const DB *, DBT *, DBT *, int));
+extern char *yp_dnsname __P(( char * ));
+extern char *yp_dnsaddr __P(( const char * ));
+extern int yp_access __P((const char *, const struct svc_req * ));
+extern int yp_validdomain __P((const char * ));
+extern DB *yp_open_db __P(( const char *, const char *));
diff --git a/usr.sbin/ypserv/yp_main.c b/usr.sbin/ypserv/yp_main.c
new file mode 100644
index 0000000..21748cf
--- /dev/null
+++ b/usr.sbin/ypserv/yp_main.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 1995
+ * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: yp_main.c,v 1.12 1995/12/11 22:38:19 wpaul Exp $
+ */
+
+/*
+ * ypserv startup function.
+ * We need out own main() since we have to do some additional work
+ * that rpcgen won't do for us. Most of this file was generated using
+ * rpcgen.new, and later modified.
+ */
+
+#include "yp.h"
+#include <stdio.h>
+#include <stdlib.h> /* getenv, exit */
+#include <rpc/pmap_clnt.h> /* for pmap_unset */
+#include <string.h> /* strcmp */
+#include <signal.h>
+#include <sys/ttycom.h> /* TIOCNOTTY */
+#ifdef __cplusplus
+#include <sysent.h> /* getdtablesize, open */
+#endif /* __cplusplus */
+#include <memory.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <syslog.h>
+#include <sys/wait.h>
+#include "yp_extern.h"
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <errno.h>
+
+#ifndef SIG_PF
+#define SIG_PF void(*)(int)
+#endif
+
+#define _RPCSVC_CLOSEDOWN 120
+#ifndef lint
+static char rcsid[] = "$Id: yp_main.c,v 1.12 1995/12/11 22:38:19 wpaul Exp $";
+#endif /* not lint */
+int _rpcpmstart; /* Started by a port monitor ? */
+static int _rpcfdtype;
+ /* Whether Stream or Datagram ? */
+ /* States a server can be in wrt request */
+
+#define _IDLE 0
+#define _SERVED 1
+#define _SERVING 2
+
+extern void ypprog_2 __P((struct svc_req, register SVCXPRT));
+extern int _rpc_dtablesize __P((void));
+extern int _rpcsvcstate; /* Set when a request is serviced */
+char *progname = "ypserv";
+char *yp_dir = _PATH_YP;
+int debug = 0;
+int do_dns = 0;
+int sunos_4_kludge = 0;
+
+static
+void _msgout(char* msg)
+{
+ if (debug) {
+ if (_rpcpmstart)
+ syslog(LOG_ERR, msg);
+ else
+ (void) fprintf(stderr, "%s\n", msg);
+ } else
+ syslog(LOG_ERR, msg);
+}
+
+static void
+yp_svc_run()
+{
+#ifdef FD_SETSIZE
+ fd_set readfds;
+#else
+ int readfds;
+#endif /* def FD_SETSIZE */
+ extern int forked;
+ int pid;
+
+ /* Establish the identity of the parent ypserv process. */
+ pid = getpid();
+
+ for (;;) {
+#ifdef FD_SETSIZE
+ readfds = svc_fdset;
+#else
+ readfds = svc_fds;
+#endif /* def FD_SETSIZE */
+ switch (select(_rpc_dtablesize(), &readfds, NULL, NULL,
+ (struct timeval *)0)) {
+ case -1:
+ if (errno == EINTR) {
+ continue;
+ }
+ perror("svc_run: - select failed");
+ return;
+ case 0:
+ continue;
+ default:
+ svc_getreqset(&readfds);
+ if (forked && pid != getpid())
+ exit(0);
+ }
+ }
+}
+
+static void unregister()
+{
+ (void) pmap_unset(YPPROG, YPVERS);
+ if (sunos_4_kludge)
+ (void) pmap_unset(YPPROG, 1);
+}
+
+static void reaper(sig)
+ int sig;
+{
+ int status;
+
+ if (sig == SIGCHLD) {
+ while (wait3(&status, WNOHANG, NULL) > 0)
+ children--;
+ } else {
+ unregister();
+ exit(0);
+ }
+}
+
+static void usage()
+{
+ fprintf(stderr, "Usage: %s [-h] [-d] [-n] [-k] [-p path]\n", progname);
+ exit(1);
+}
+
+static void
+closedown(int sig)
+{
+ if (_rpcsvcstate == _IDLE) {
+ extern fd_set svc_fdset;
+ static int size;
+ int i, openfd;
+
+ if (_rpcfdtype == SOCK_DGRAM) {
+ unregister();
+ exit(0);
+ }
+ if (size == 0) {
+ size = getdtablesize();
+ }
+ for (i = 0, openfd = 0; i < size && openfd < 2; i++)
+ if (FD_ISSET(i, &svc_fdset))
+ openfd++;
+ if (openfd <= 1) {
+ unregister();
+ exit(0);
+ }
+ }
+ if (_rpcsvcstate == _SERVED)
+ _rpcsvcstate = _IDLE;
+
+ (void) signal(SIGALRM, (SIG_PF) closedown);
+ (void) alarm(_RPCSVC_CLOSEDOWN/2);
+}
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ register SVCXPRT *transp;
+ int sock;
+ int proto;
+ struct sockaddr_in saddr;
+ int asize = sizeof (saddr);
+ int ch;
+
+ while ((ch = getopt(argc, argv, "hdnkp:")) != EOF) {
+ switch(ch) {
+ case 'd':
+ debug = 1;
+ break;
+ case 'n':
+ do_dns = 1;
+ break;
+ case 'k':
+ sunos_4_kludge = 1;
+ break;
+ case 'p':
+ yp_dir = optarg;
+ break;
+ case 'h':
+ default:
+ usage();
+ }
+ }
+
+ if (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {
+ int ssize = sizeof (int);
+
+ if (saddr.sin_family != AF_INET)
+ exit(1);
+ if (getsockopt(0, SOL_SOCKET, SO_TYPE,
+ (char *)&_rpcfdtype, &ssize) == -1)
+ exit(1);
+ sock = 0;
+ _rpcpmstart = 1;
+ proto = 0;
+ openlog(progname, LOG_PID, LOG_DAEMON);
+ } else {
+ if (!debug) {
+ if (daemon(0,0)) {
+ perror("cannot fork");
+ exit(1);
+ }
+ openlog(progname, LOG_PID, LOG_DAEMON);
+ }
+ sock = RPC_ANYSOCK;
+ (void) pmap_unset(YPPROG, YPVERS);
+ if (sunos_4_kludge)
+ (void) pmap_unset(YPPROG, 1);
+ }
+
+ if (sunos_4_kludge && ((_rpcfdtype == 0)||(_rpcfdtype == SOCK_DGRAM))) {
+ transp = svcudp_create(sock);
+ if (transp == NULL) {
+ _msgout("cannot create udp service.");
+ exit(1);
+ }
+ if (!_rpcpmstart)
+ proto = IPPROTO_UDP;
+ if (!svc_register(transp, YPPROG, 1, ypprog_2, proto)) {
+ _msgout("unable to register (YPPROG, OLDYPVERS, udp).");
+ exit(1);
+ }
+ }
+
+ if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_DGRAM)) {
+ transp = svcudp_create(sock);
+ if (transp == NULL) {
+ _msgout("cannot create udp service.");
+ exit(1);
+ }
+ if (!_rpcpmstart)
+ proto = IPPROTO_UDP;
+ if (!svc_register(transp, YPPROG, YPVERS, ypprog_2, proto)) {
+ _msgout("unable to register (YPPROG, YPVERS, udp).");
+ exit(1);
+ }
+ }
+
+ if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_STREAM)) {
+ transp = svctcp_create(sock, 0, 0);
+ if (transp == NULL) {
+ _msgout("cannot create tcp service.");
+ exit(1);
+ }
+ if (!_rpcpmstart)
+ proto = IPPROTO_TCP;
+ if (!svc_register(transp, YPPROG, YPVERS, ypprog_2, proto)) {
+ _msgout("unable to register (YPPROG, YPVERS, tcp).");
+ exit(1);
+ }
+ }
+
+ if (transp == (SVCXPRT *)NULL) {
+ _msgout("could not create a handle");
+ exit(1);
+ }
+ if (_rpcpmstart) {
+ (void) signal(SIGALRM, (SIG_PF) closedown);
+ (void) alarm(_RPCSVC_CLOSEDOWN/2);
+ }
+/*
+ * Make sure SIGPIPE doesn't blow us away while servicing TCP
+ * connections.
+ */
+ (void) signal(SIGPIPE, SIG_IGN);
+ (void) signal(SIGCHLD, (SIG_PF) reaper);
+ (void) signal(SIGTERM, (SIG_PF) reaper);
+ (void) signal(SIGINT, (SIG_PF) reaper);
+ (void) signal(SIGHUP, (SIG_PF) reaper);
+ yp_svc_run();
+ _msgout("svc_run returned");
+ exit(1);
+ /* NOTREACHED */
+}
diff --git a/usr.sbin/ypserv/yp_server.c b/usr.sbin/ypserv/yp_server.c
new file mode 100644
index 0000000..fcc8bbd
--- /dev/null
+++ b/usr.sbin/ypserv/yp_server.c
@@ -0,0 +1,626 @@
+/*
+ * Copyright (c) 1995
+ * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include "yp_extern.h"
+#include "yp.h"
+#include <stdlib.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#ifndef lint
+static char rcsid[] = "$Id: yp_server.c,v 1.18 1995/12/16 04:01:55 wpaul Exp $";
+#endif /* not lint */
+
+int forked = 0;
+int children = 0;
+DB *spec_dbp = NULL; /* Special global DB handle for ypproc_all. */
+
+void *
+ypproc_null_2_svc(void *argp, struct svc_req *rqstp)
+{
+ static char * result;
+ static char rval = 0;
+
+ if (yp_access(NULL, (struct svc_req *)rqstp))
+ return(NULL);
+
+ result = &rval;
+
+ return((void *) &result);
+}
+
+bool_t *
+ypproc_domain_2_svc(domainname *argp, struct svc_req *rqstp)
+{
+ static bool_t result;
+
+ if (yp_access(NULL, (struct svc_req *)rqstp)) {
+ result = FALSE;
+ return (&result);
+ }
+
+ if (argp == NULL || yp_validdomain(*argp))
+ result = FALSE;
+ else
+ result = TRUE;
+
+ return (&result);
+}
+
+bool_t *
+ypproc_domain_nonack_2_svc(domainname *argp, struct svc_req *rqstp)
+{
+ static bool_t result;
+
+ if (yp_access(NULL, (struct svc_req *)rqstp))
+ return (NULL);
+
+ if (argp == NULL || yp_validdomain(*argp))
+ return (NULL);
+ else
+ result = TRUE;
+
+ return (&result);
+}
+
+ypresp_val *
+ypproc_match_2_svc(ypreq_key *argp, struct svc_req *rqstp)
+{
+ static ypresp_val result;
+ DBT key, data;
+
+ if (yp_access(argp->map, (struct svc_req *)rqstp)) {
+ result.stat = YP_YPERR;
+ return (&result);
+ }
+
+ if (argp->domain == NULL || argp->map == NULL) {
+ result.stat = YP_BADARGS;
+ return (&result);
+ }
+
+ if (yp_validdomain(argp->domain)) {
+ result.stat = YP_NODOM;
+ return(&result);
+ }
+
+ key.size = argp->key.keydat_len;
+ key.data = argp->key.keydat_val;
+
+ result.stat = yp_get_record(argp->domain, argp->map, &key, &data, 0);
+
+ if (result.stat == YP_TRUE) {
+ result.val.valdat_len = data.size;
+ result.val.valdat_val = data.data;
+ }
+
+ /*
+ * Do DNS lookups for hosts maps if database lookup failed.
+ */
+
+ if (do_dns && result.stat != YP_TRUE && strstr(argp->map, "hosts")) {
+ char *rval;
+
+ /* DNS lookups can take time -- do them in a subprocess */
+
+ if (!debug && children < MAX_CHILDREN && fork()) {
+ children++;
+ forked = 0;
+ /*
+ * Returning NULL here prevents svc_sendreply()
+ * from being called by the parent. This is vital
+ * since having both the parent and the child process
+ * call it would confuse the client.
+ */
+ return (NULL);
+ } else {
+ forked++;
+ }
+
+ if (debug)
+ yp_error("Doing DNS lookup of %.*s",
+ argp->key.keydat_len,
+ argp->key.keydat_val);
+
+ /* NUL terminate! NUL terminate!! NUL TERMINATE!!! */
+ argp->key.keydat_val[argp->key.keydat_len] = '\0';
+
+ if (!strcmp(argp->map, "hosts.byname"))
+ rval = yp_dnsname((char *)argp->key.keydat_val);
+ else if (!strcmp(argp->map, "hosts.byaddr"))
+ rval = yp_dnsaddr((const char *)argp->key.keydat_val);
+
+
+ if (rval) {
+ if (debug)
+ yp_error("DNS lookup successful. Result: %s", rval);
+ result.val.valdat_len = strlen(rval);
+ result.val.valdat_val = rval;
+ result.stat = YP_TRUE;
+ } else {
+ if (debug)
+ yp_error("DNS lookup failed.");
+ result.stat = YP_NOKEY;
+ }
+ }
+
+ return (&result);
+}
+
+ypresp_key_val *
+ypproc_first_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
+{
+ static ypresp_key_val result;
+ DBT key, data;
+ DB *dbp;
+
+ if (yp_access(argp->map, (struct svc_req *)rqstp)) {
+ result.stat = YP_YPERR;
+ return (&result);
+ }
+
+ if (argp->domain == NULL) {
+ result.stat = YP_BADARGS;
+ return (&result);
+ }
+
+ if (yp_validdomain(argp->domain)) {
+ result.stat = YP_NODOM;
+ return(&result);
+ }
+
+ if ((dbp = yp_open_db(argp->domain, argp->map)) == NULL) {
+ result.stat = yp_errno;
+ return(&result);
+ }
+
+ key.data = NULL;
+ key.size = 0;
+ result.stat = yp_first_record(dbp, &key, &data);
+ (void)(dbp->close)(dbp);
+
+ if (result.stat == YP_TRUE) {
+ result.key.keydat_len = key.size;
+ result.key.keydat_val = key.data;
+ result.val.valdat_len = data.size;
+ result.val.valdat_val = data.data;
+ }
+
+ return (&result);
+}
+
+ypresp_key_val *
+ypproc_next_2_svc(ypreq_key *argp, struct svc_req *rqstp)
+{
+ static ypresp_key_val result;
+ DBT key, data;
+ DB *dbp;
+
+ if (yp_access(argp->map, (struct svc_req *)rqstp)) {
+ result.stat = YP_YPERR;
+ return (&result);
+ }
+
+ if (argp->domain == NULL || argp->map == NULL) {
+ result.stat = YP_BADARGS;
+ return (&result);
+ }
+
+ if (yp_validdomain(argp->domain)) {
+ result.stat = YP_NODOM;
+ return(&result);
+ }
+
+ if ((dbp = yp_open_db(argp->domain, argp->map)) == NULL) {
+ result.stat = yp_errno;
+ return(&result);
+ }
+
+ key.size = argp->key.keydat_len;
+ key.data = argp->key.keydat_val;
+
+ result.stat = yp_next_record(dbp, &key, &data, 0);
+ (void)(dbp->close)(dbp);
+
+ if (result.stat == YP_TRUE) {
+ result.key.keydat_len = key.size;
+ result.key.keydat_val = key.data;
+ result.val.valdat_len = data.size;
+ result.val.valdat_val = data.data;
+ }
+
+ return (&result);
+}
+
+ypresp_xfr *
+ypproc_xfr_2_svc(ypreq_xfr *argp, struct svc_req *rqstp)
+{
+ static ypresp_xfr result;
+
+ if (yp_access(argp->map_parms.map, (struct svc_req *)rqstp)) {
+ result.xfrstat = YPXFR_REFUSED;
+ return(&result);
+ }
+
+ if (argp->map_parms.domain == NULL) {
+ result.xfrstat = YPXFR_BADARGS;
+ return (&result);
+ }
+
+ if (yp_validdomain(argp->map_parms.domain)) {
+ result.xfrstat = YPXFR_NODOM;
+ return(&result);
+ }
+
+ switch(fork()) {
+ case 0:
+ {
+ char g[11], t[11], p[11];
+ struct sockaddr_in *rqhost;
+ char ypxfr_command[MAXPATHLEN + 2];
+
+ rqhost = svc_getcaller(rqstp->rq_xprt);
+ sprintf (ypxfr_command, "%sypxfr", _PATH_LIBEXEC);
+ sprintf (t, "%u", argp->transid);
+ sprintf (g, "%u", argp->prog);
+ sprintf (p, "%u", argp->port);
+ children++;
+ forked = 0;
+ execl(ypxfr_command, "ypxfr", "-d", argp->map_parms.domain,
+ "-h", argp->map_parms.peer, "-f", "-C", t, g,
+ inet_ntoa(rqhost->sin_addr), p, argp->map_parms.map,
+ NULL);
+ yp_error("ypxfr execl(): %s", strerror(errno));
+ return(NULL);
+ }
+ case -1:
+ yp_error("ypxfr fork(): %s", strerror(errno));
+ result.xfrstat = YPXFR_XFRERR;
+ break;
+ default:
+ result.xfrstat = YPXFR_SUCC;
+ forked++;
+ break;
+ }
+
+ result.transid = argp->transid;
+ return (&result);
+}
+
+void *
+ypproc_clear_2_svc(void *argp, struct svc_req *rqstp)
+{
+ static char * result;
+ static char rval = 0;
+
+ /*
+ * We don't have to do anything for ypproc_clear. Unlike
+ * the SunOS ypserv, we don't hold out database descriptors
+ * open forever.
+ */
+ if (yp_access(NULL, (struct svc_req *)rqstp))
+ return (NULL);
+
+ result = &rval;
+ return((void *) &result);
+}
+
+/*
+ * For ypproc_all, we have to send a stream of ypresp_all structures
+ * via TCP, but the XDR filter generated from the yp.x protocol
+ * definition file only serializes one such structure. This means that
+ * to send the whole stream, you need a wrapper which feeds all the
+ * records into the underlying XDR routine until it hits an 'EOF.'
+ * But to use the wrapper, you have to violate the boundaries between
+ * RPC layers by calling svc_sendreply() directly from the ypproc_all
+ * service routine instead of letting the RPC dispatcher do it.
+ *
+ * Bleah.
+ */
+
+/*
+ * Custom XDR routine for serialzing results of ypproc_all: keep
+ * reading from the database and spew until we run out of records
+ * or encounter an error.
+ */
+static bool_t
+xdr_my_ypresp_all(register XDR *xdrs, ypresp_all *objp)
+{
+ DBT key, data;
+
+ while (1) {
+ /* Get a record. */
+ key.size = objp->ypresp_all_u.val.key.keydat_len;
+ key.data = objp->ypresp_all_u.val.key.keydat_val;
+
+ if ((objp->ypresp_all_u.val.stat =
+ yp_next_record(spec_dbp,&key,&data,1)) == YP_TRUE) {
+ objp->ypresp_all_u.val.val.valdat_len = data.size;
+ objp->ypresp_all_u.val.val.valdat_val = data.data;
+ objp->ypresp_all_u.val.key.keydat_len = key.size;
+ objp->ypresp_all_u.val.key.keydat_val = key.data;
+ objp->more = TRUE;
+ } else {
+ objp->more = FALSE;
+ }
+
+ /* Serialize. */
+ if (!xdr_ypresp_all(xdrs, objp))
+ return(FALSE);
+ if (objp->more == FALSE)
+ return(TRUE);
+ }
+}
+
+ypresp_all *
+ypproc_all_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
+{
+ static ypresp_all result;
+
+ /*
+ * Set this here so that the client will be forced to make
+ * at least one attempt to read from us even if all we're
+ * doing is returning an error.
+ */
+ result.more = TRUE;
+
+ if (yp_access(argp->map, (struct svc_req *)rqstp)) {
+ result.ypresp_all_u.val.stat = YP_YPERR;
+ return (&result);
+ }
+
+ if (argp->domain == NULL || argp->map == NULL) {
+ result.ypresp_all_u.val.stat = YP_BADARGS;
+ return (&result);
+ }
+
+ if (yp_validdomain(argp->domain)) {
+ result.ypresp_all_u.val.stat = YP_NODOM;
+ return(&result);
+ }
+
+ /*
+ * The ypproc_all procedure can take a while to complete.
+ * Best to handle it in a subprocess so the parent doesn't
+ * block. We fork() here so we don't end up sharing a
+ * DB file handle with the parent.
+ */
+
+ if (!debug && children < MAX_CHILDREN && fork()) {
+ children++;
+ forked = 0;
+ return (NULL);
+ } else {
+ forked++;
+ }
+
+ if ((spec_dbp = yp_open_db(argp->domain, argp->map)) == NULL) {
+ result.ypresp_all_u.val.stat = yp_errno;
+ return(&result);
+ }
+
+ /* Kick off the actual data transfer. */
+ svc_sendreply(rqstp->rq_xprt, xdr_my_ypresp_all, (char *)&result);
+
+ /* Close database when done. */
+ (void)(spec_dbp->close)(spec_dbp);
+
+ /*
+ * Returning NULL prevents the dispatcher from calling
+ * svc_sendreply() since we already did it.
+ */
+ return (NULL);
+}
+
+ypresp_master *
+ypproc_master_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
+{
+ static ypresp_master result;
+ DBT key,data;
+
+ if (yp_access(NULL, (struct svc_req *)rqstp)) {
+ result.stat = YP_YPERR;
+ return(&result);
+ }
+
+ if (argp->domain == NULL) {
+ result.stat = YP_BADARGS;
+ return (&result);
+ }
+
+ if (yp_validdomain(argp->domain)) {
+ result.stat = YP_NODOM;
+ return (&result);
+ }
+
+ key.data = "YP_MASTER_NAME";
+ key.size = sizeof("YP_MASTER_NAME") - 1;
+
+ result.stat = yp_get_record(argp->domain, argp->map, &key, &data, 1);
+
+ if (result.stat == YP_TRUE) {
+ result.peer = (char *)data.data;
+ result.peer[data.size] = '\0';
+ } else
+ result.peer = "";
+
+ return (&result);
+}
+
+ypresp_order *
+ypproc_order_2_svc(ypreq_nokey *argp, struct svc_req *rqstp)
+{
+ static ypresp_order result;
+ DBT key,data;
+
+ if (yp_access(NULL, (struct svc_req *)rqstp)) {
+ result.stat = YP_YPERR;
+ return(&result);
+ }
+
+ if (argp->domain == NULL) {
+ result.stat = YP_BADARGS;
+ return (&result);
+ }
+
+ if (yp_validdomain(argp->domain)) {
+ result.stat = YP_NODOM;
+ return (&result);
+ }
+
+ /*
+ * We could just check the timestamp on the map file,
+ * but that's a hack: we'll only know the last time the file
+ * was touched, not the last time the database contents were
+ * updated.
+ */
+ key.data = "YP_LAST_MODIFIED";
+ key.size = sizeof("YP_LAST_MODIFIED") - 1;
+
+ result.stat = yp_get_record(argp->domain, argp->map, &key, &data, 1);
+
+ if (result.stat == YP_TRUE)
+ result.ordernum = atoi((char *)data.data);
+ else
+ result.ordernum = 0;
+
+ return (&result);
+}
+
+static void yp_maplist_free(yp_maplist)
+ struct ypmaplist *yp_maplist;
+{
+ register struct ypmaplist *next;
+
+ while(yp_maplist) {
+ next = yp_maplist->next;
+ free(yp_maplist->map);
+ free(yp_maplist);
+ yp_maplist = next;
+ }
+ return;
+}
+
+static struct ypmaplist *yp_maplist_create(domain)
+ const char *domain;
+{
+ char yp_mapdir[MAXPATHLEN + 2];
+ char yp_mapname[MAXPATHLEN + 2];
+ struct ypmaplist *cur = NULL;
+ struct ypmaplist *yp_maplist = NULL;
+ DIR *dird;
+ struct dirent *dirp;
+ struct stat statbuf;
+
+ snprintf(yp_mapdir, sizeof(yp_mapdir), "%s/%s", yp_dir, domain);
+
+ if ((dird = opendir(yp_mapdir)) == NULL) {
+ yp_error("opendir(%s) failed: %s", strerror(errno));
+ return(NULL);
+ }
+
+ while ((dirp = readdir(dird)) != NULL) {
+ if (strcmp(dirp->d_name, ".") && strcmp(dirp->d_name, "..")) {
+ snprintf(yp_mapname, sizeof(yp_mapname), "%s/%s",yp_mapdir,dirp->d_name);
+ if (stat(yp_mapname, &statbuf) < 0 || !S_ISREG(statbuf.st_mode))
+ continue;
+ if ((cur = (struct ypmaplist *)malloc(sizeof(struct ypmaplist))) < 0) {
+ yp_error("malloc() failed: %s", strerror(errno));
+ closedir(dird);
+ yp_maplist_free(yp_maplist);
+ return(NULL);
+ }
+ if ((cur->map = (char *)strdup(dirp->d_name)) == NULL) {
+ yp_error("strdup() failed: %s", strerror(errno));
+ closedir(dird);
+ yp_maplist_free(yp_maplist);
+ return(NULL);
+ }
+ cur->next = yp_maplist;
+ yp_maplist = cur;
+ if (debug)
+ yp_error("map: %s", yp_maplist->map);
+ }
+
+ }
+ closedir(dird);
+ return(yp_maplist);
+}
+
+ypresp_maplist *
+ypproc_maplist_2_svc(domainname *argp, struct svc_req *rqstp)
+{
+ static ypresp_maplist result;
+
+ if (yp_access(NULL, (struct svc_req *)rqstp)) {
+ result.stat = YP_YPERR;
+ return(&result);
+ }
+
+ if (argp == NULL) {
+ result.stat = YP_BADARGS;
+ return (&result);
+ }
+
+ if (yp_validdomain(*argp)) {
+ result.stat = YP_NODOM;
+ return (&result);
+ }
+
+ /*
+ * We have to construct a linked list for the ypproc_maplist
+ * procedure using dynamically allocated memory. Since the XDR
+ * layer won't free this list for us, we have to deal with it
+ * ourselves. We call yp_maplist_free() first to free any
+ * previously allocated data we may have accumulated to insure
+ * that we have only one linked list in memory at any given
+ * time.
+ */
+
+ yp_maplist_free(result.maps);
+
+ if ((result.maps = yp_maplist_create(*argp)) == NULL) {
+ yp_error("yp_maplist_create failed");
+ result.stat = YP_YPERR;
+ return(&result);
+ } else
+ result.stat = YP_TRUE;
+
+ return (&result);
+}
diff --git a/usr.sbin/ypserv/ypserv.8 b/usr.sbin/ypserv/ypserv.8
new file mode 100644
index 0000000..7a584b7
--- /dev/null
+++ b/usr.sbin/ypserv/ypserv.8
@@ -0,0 +1,306 @@
+.\" Copyright (c) 1995
+.\" Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by Bill Paul.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: ypserv.8,v 1.4 1995/12/10 04:46:38 wpaul Exp $
+.\"
+.Dd February 4, 1995
+.Dt YPSERV 8
+.Os
+.Sh NAME
+.Nm ypserv
+.Nd "NIS database server"
+.Sh SYNOPSIS
+.Nm ypserv
+.Op Fl n
+.Op Fl d
+.Op Fl k
+.Op Fl p Ar path
+.Sh DESCRIPTION
+.Nm NIS
+is an RPC-based service designed to allow a number of UNIX-based
+machines to share a common set of configuration files. Rather than
+requiring a system administrator to update several copies of files
+such as
+.Pa /etc/hosts ,
+.Pa /etc/passwd
+and
+.Pa /etc/group ,
+which tend to require frequent changes in most environments, NIS
+allows groups of computers to share one set of data which can be
+updated from a single location.
+.Pp
+.Nm ypserv
+is the server that distributes NIS databases
+to client systems within an NIS
+.Nm domain.
+Each client in an NIS domain must have its domainname set to
+one of the domains served by
+.Nm ypserv
+using the
+.Xr domainname 1
+command. The clients must also run
+.Xr ypbind 8
+in order to attach to a particular server, since it is possible to
+have serveral servers within a single NIS domain.
+.Pp
+The databases distributed by
+.Nm ypserv
+are stored in
+.Pa /var/yp/[domainname]
+where
+.Pa domainname
+is the name of the domain being served. There can be several
+such directories with different domainnames, and you need only one
+.Nm ypserv
+daemon to handle them all.
+.Pp
+The databases, or
+.Pa maps
+as they are often called,
+are created by
+.Nm /var/yp/Makefile
+using several system files as source. The database files are in
+.Xr db 3
+format to help speed retrieval when there are many records involved.
+In FreeBSD, the
+maps are always readable and writable only by root for security
+reasons. Technically this is only necessary for the password
+maps, but since the data in the other maps can be found in
+other world-readable files anyway, it doesn't hurt and it's considered
+good general practice.
+.Pp
+.Nm ypserv
+is started by
+.Nm /etc/rc
+if it has been enabled in
+.Nm /etc/sysconfig.
+.Sh SPECIAL FEATURES
+There are some problems associated with distributing FreeBSD's password
+database via NIS: FreeBSD normally only stores encrypted passwords
+in
+.Pa /etc/master.passwd ,
+which is readable and writable only by root. By turning this file
+into an NIS map, this security feature would be completely defeated.
+.Pp
+To make up for this, the FreeBSD version of
+.Nm ypserv
+handles the
+.Pa master.passwd.byname
+and
+.Pa master.basswd.byuid
+maps in a special way. When the server receives a request to access
+either of these two maps, it will check the TCP port from which the
+request originated and return an error if the port number is greater
+than 1023. Since only the superuser is allowed to bind to TCP ports
+with values less than 1024, the server can use this test to determine
+whether or not the access request came from a privileged user.
+Any requests made by non-privileged users are therefore rejected.
+.Pp
+Furthermore, the
+.Xr getpwent 3
+routines in FreeBSD's standard C libarary will only attempt to retrieve
+data from the
+.Pa master.passwd.byname
+and
+.Pa master.passwd.byuid
+maps for the superuser: if a normal user calls any of these functions,
+the standard
+.Pa passwd.byname
+and
+.Pa passwd.byuid
+maps will be accessed instead. The latter two maps are constructed by
+.Nm /var/yp/Makefile
+by parsing the
+.Pa master.passwd
+file and stripping out the password fields, and are therefore
+safe to pass on to unprivileged users. In this way, the shadow password
+aspect of the protected
+.Pa master.passwd
+database is maintained through NIS.
+.Pp
+.Sh NOTES
+.Ss Limitations
+There are two problems inherent with password shadowing in NIS
+that users should
+be aware of:
+.Bl -enum -offset indent
+.It
+The 'TCP port less than 1024' test is trivial to defeat for users with
+unrestricted access to machines on your network (even those machines
+which do not run UNIX-based operating systems).
+.It
+If you plan to use a FreeBSD system to serve non-FreeBSD clients that
+have no support for password shadowing (which is most of them), you
+will have to disable the password shadowing entirely by uncommenting the
+.Nm UNSECURE=True
+entry in
+.Nm /var/yp/Makefile .
+This will cause the standard
+.Pa passwd.byname
+and
+.Pa passwd.byuid
+maps to be generated with valid encrypted password fields, which is
+neccesary in order for non-FreeBSD clients to perform user
+authentication through NIS.
+.El
+.Pp
+.Ss Security
+.Nm ypserv
+has support for Wietse Venema's
+.Pa tcpwrapper
+package built in, though it is not compiled in by default since
+the
+.Pa tcpwrapper
+package is not distributed with FreeBSD. However, if you have
+.Nm libwrap.a
+and
+.Nm tcpd.h ,
+you can easily recompile
+.Nm ypserv
+with them, thereby enabling its 'securenets' features: you can
+configure
+.Nm ypserv
+to only handle resquests from machines listed
+in the
+.Pa tcpwrapper
+configuration files, which would help limit vulnerability to the
+first limitation listed above.
+.Pp
+.Ss NIS servers that are also NIS clients
+Care must be taken when running
+.Nm ypserv
+in a multi-server domain where the server machines are also
+NIS clients. It is generally a good idea to force the servers to
+bind to themselves rather than allowing them to broadcast bind
+requests and possibly become bound to each other: strange failure
+modes can result if one server goes down and
+others are dependent upon on it. (Eventually all the clients will
+time out and attempt to bind to other servers, but the delay
+involved can be considerable and the failure mode is still present
+since the servers might bind to each other all over again).
+.Pp
+Refer to the
+.Xr ypbind 8
+man page for details on how to force it to bind to a particular
+server.
+.Sh OPTIONS
+The following options are supported by
+.Nm ypserv :
+.Bl -tag -width flag
+.It Fl n
+This option affects the way
+.Nm ypserv
+handles yp_match requests for the
+.Pa hosts.byname
+and
+.Pa hosts.byaddress
+maps. By default, if
+.Nm ypserv
+can't find an entry for a given host in its hosts maps, it will
+return an error and perform no further processing. With the
+.Fl n
+flag,
+.Nm ypserv
+will go one step further: rather than giving up immediately, it
+will try to resolve the hostname or address using a DNS nameserver
+query. If the query is successful,
+.Nm ypserv
+will construct a fake database record and return it to the client,
+thereby making it seem as though the client's yp_match request
+succeeded.
+.Pp
+This feature is provided for compatiblity with SunOS 4.1.x,
+which has brain-damaged resolver functions in its standard C
+library that depend on NIS for hostname and address resolution.
+FreeBSD's resolver can be configured to do DNS
+queries directly, therefore it is not necessary to enable this
+option when serving only FreeBSD NIS clients.
+.It Fl d
+Causes the server to run in debugging mode. Normally,
+.Nm ypserv
+reports only unusual errors (access violations, file access failures)
+using the
+.Xr syslog 3
+facility. In debug mode, the server does not background
+itself and prints extra status messages to stderr for each
+request that it revceives. Also, while running in debug mode,
+.Nm ypserv
+will not spawn any additional subprocesses as it normally does
+when handling yp_all requests or doing DNS lookups. (These actions
+often take a fair amount of time to complete and are therefore handled
+in subprocesses, allowing the parent server process to go on handling
+other requests.) This makes it easier to trace the server with
+a debugging tool.
+.It Fl k
+This flag is provided for compatibility with SunOS 4. The
+.Xr ypbind 8
+command in SunOS 4 apparently expects to obtain a response from an
+NIS v1 server. Starting
+.Xr ypserv 8
+with the
+.Fl k
+flag causes it to register itself as an NIS v1 server and
+respond to YPPROC_DOMAIN_NONACK requests. Note carefully: this is
+merely a kludge (hence the 'k') to pacify SunOS 4's
+.Xr ypbind 8
+command: attempts to make the server actually handle NIS v1 queries
+will undoubtedly fail quite miserably.
+.It Fl p Ar path
+Normally,
+.Nm ypserv
+assumes that all NIS maps are stored under
+.Pa /var/yp .
+The
+.Fl p
+flag may be used to specify an alternate NIS root path, allowing
+the system administrator to move the map files to a different place
+within the filesystem.
+.El
+.Sh FILES
+.Bl -tag -width Pa -compact
+.It Pa /var/yp/[domainname]/[maps]
+The NIS maps.
+.It Pa /etc/host.conf
+Resolver configuration file.
+.El
+.Sh SEE ALSO
+.Xr ypbind 8 ,
+.Xr yppasswdd 8 ,
+.Xr yppush 8 ,
+.Xr ypxfr 8 ,
+.Xr ypcat 1 ,
+.Xr yp 8 ,
+.Xr db 3
+.Sh AUTHOR
+Bill Paul <wpaul@ctr.columbia.edu>
+.Sh HISTORY
+This version of
+.Nm ypserv
+first appeared in FreeBSD 2.1.
OpenPOWER on IntegriCloud