diff options
Diffstat (limited to 'usr.sbin')
24 files changed, 1407 insertions, 58 deletions
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index 90c23dc26cc5..dcfe2037f8ce 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -174,6 +174,7 @@ SUBDIR.${MK_NETGRAPH}+= flowctl SUBDIR.${MK_NETGRAPH}+= ngctl SUBDIR.${MK_NETGRAPH}+= nghook SUBDIR.${MK_NIS}+= rpc.yppasswdd +SUBDIR.${MK_NIS}+= rpc.ypupdated SUBDIR.${MK_NIS}+= rpc.ypxfrd SUBDIR.${MK_NIS}+= ypbind SUBDIR.${MK_NIS}+= ypldap diff --git a/usr.sbin/certctl/certctl.8 b/usr.sbin/certctl/certctl.8 index 97bdc840c359..edf993e1361a 100644 --- a/usr.sbin/certctl/certctl.8 +++ b/usr.sbin/certctl/certctl.8 @@ -24,7 +24,7 @@ .\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd August 11, 2025 +.Dd August 18, 2025 .Dt CERTCTL 8 .Os .Sh NAME @@ -63,6 +63,8 @@ This option is only valid in conjunction with the command. .It Fl D Ar destdir Specify the DESTDIR (overriding values from the environment). +.It Fl d Ar distbase +Specify the DISTBASE (overriding values from the environment). .It Fl l When listing installed (trusted or untrusted) certificates, show the full path and distinguished name for each certificate. @@ -117,7 +119,13 @@ Remove the specified file from the untrusted list. .Sh ENVIRONMENT .Bl -tag -width UNTRUSTDESTDIR .It Ev DESTDIR -Alternate destination directory to operate on. +Absolute path to an alternate destination directory to operate on +instead of the file system root, e.g. +.Dq Li /tmp/install . +.It Ev DISTBASE +Additional path component to include when operating on certificate directories. +This must start with a slash, e.g. +.Dq Li /base . .It Ev LOCALBASE Location for local programs. Defaults to the value of the user.localbase sysctl which is usually @@ -125,22 +133,22 @@ Defaults to the value of the user.localbase sysctl which is usually .It Ev TRUSTPATH List of paths to search for trusted certificates. Default: -.Pa ${DESTDIR}/usr/share/certs/trusted +.Pa ${DESTDIR}${DISTBASE}/usr/share/certs/trusted .Pa ${DESTDIR}${LOCALBASE}/share/certs/trusted .Pa ${DESTDIR}${LOCALBASE}/share/certs .It Ev UNTRUSTPATH List of paths to search for untrusted certificates. Default: -.Pa ${DESTDIR}/usr/share/certs/untrusted +.Pa ${DESTDIR}${DISTBASE}/usr/share/certs/untrusted .Pa ${DESTDIR}${LOCALBASE}/share/certs/untrusted .It Ev TRUSTDESTDIR Destination directory for symbolic links to trusted certificates. Default: -.Pa ${DESTDIR}/etc/ssl/certs +.Pa ${DESTDIR}${DISTBASE}/etc/ssl/certs .It Ev UNTRUSTDESTDIR Destination directory for symbolic links to untrusted certificates. Default: -.Pa ${DESTDIR}/etc/ssl/untrusted +.Pa ${DESTDIR}${DISTBASE}/etc/ssl/untrusted .It Ev BUNDLE File name of bundle to produce. .El diff --git a/usr.sbin/certctl/certctl.c b/usr.sbin/certctl/certctl.c index 365870167aeb..ed7f05126ca7 100644 --- a/usr.sbin/certctl/certctl.c +++ b/usr.sbin/certctl/certctl.c @@ -63,6 +63,7 @@ static bool verbose; static const char *localbase; static const char *destdir; +static const char *distbase; static const char *metalog; static const char *uname = "root"; @@ -100,6 +101,28 @@ static char *bundle_dest; static FILE *mlf; /* + * Remove duplicate and trailing slashes from a path. + */ +static char * +normalize_path(const char *str) +{ + char *buf, *dst; + + if ((buf = malloc(strlen(str) + 1)) == NULL) + err(1, NULL); + for (dst = buf; *str != '\0'; dst++) { + if ((*dst = *str++) == '/') { + while (*str == '/') + str++; + if (*str == '\0') + break; + } + } + *dst = '\0'; + return (buf); +} + +/* * Split a colon-separated list into a NULL-terminated array. */ static char ** @@ -124,14 +147,14 @@ split_paths(const char *str) } /* - * Expand %L into LOCALBASE and prefix DESTDIR. + * Expand %L into LOCALBASE and prefix DESTDIR and DISTBASE as needed. */ static char * expand_path(const char *template) { if (template[0] == '%' && template[1] == 'L') return (xasprintf("%s%s%s", destdir, localbase, template + 2)); - return (xasprintf("%s%s", destdir, template)); + return (xasprintf("%s%s%s", destdir, distbase, template)); } /* @@ -155,6 +178,9 @@ expand_paths(const char *const *templates) /* * If destdir is a prefix of path, returns a pointer to the rest of path, * otherwise returns path. + * + * Note that this intentionally does not strip distbase from the path! + * Unlike destdir, distbase is expected to be included in the metalog. */ static const char * unexpand_path(const char *path) @@ -268,7 +294,7 @@ read_cert(const char *path, struct cert_tree *tree, struct cert_tree *exclude) X509_NAME *name; struct cert *cert; unsigned long hash; - int ni, no; + int len, ni, no; if ((f = fopen(path, "r")) == NULL) { warn("%s", path); @@ -293,11 +319,21 @@ read_cert(const char *path, struct cert_tree *tree, struct cert_tree *exclude) cert->x509 = x509; name = X509_get_subject_name(x509); cert->hash = X509_NAME_hash_ex(name, NULL, NULL, NULL); - cert->name = X509_NAME_oneline(name, NULL, 0); + len = X509_NAME_get_text_by_NID(name, NID_commonName, + NULL, 0); + if (len > 0) { + if ((cert->name = malloc(len + 1)) == NULL) + err(1, NULL); + X509_NAME_get_text_by_NID(name, NID_commonName, + cert->name, len + 1); + } else { + /* fallback for certificates without CN */ + cert->name = X509_NAME_oneline(name, NULL, 0); + } cert->path = xstrdup(unexpand_path(path)); if (RB_INSERT(cert_tree, tree, cert) != NULL) errx(1, "unexpected duplicate"); - info("%08lx: %s", cert->hash, strrchr(cert->name, '=') + 1); + info("%08lx: %s", cert->hash, cert->name); no++; } /* @@ -488,9 +524,10 @@ write_certs(const char *dir, struct cert_tree *tree) free(tmppath); tmppath = NULL; } + fflush(f); /* emit metalog */ if (mlf != NULL) { - fprintf(mlf, "%s/%s type=file " + fprintf(mlf, ".%s/%s type=file " "uname=%s gname=%s mode=%#o size=%ld\n", unexpand_path(dir), path, uname, gname, mode, ftell(f)); @@ -561,7 +598,7 @@ write_bundle(const char *dir, const char *file, struct cert_tree *tree) } if (ret == 0 && mlf != NULL) { fprintf(mlf, - "%s/%s type=file uname=%s gname=%s mode=%#o size=%ld\n", + ".%s/%s type=file uname=%s gname=%s mode=%#o size=%ld\n", unexpand_path(dir), file, uname, gname, mode, ftell(f)); } fclose(f); @@ -925,6 +962,14 @@ set_defaults(void) if (destdir == NULL && (destdir = getenv("DESTDIR")) == NULL) destdir = ""; + destdir = normalize_path(destdir); + + if (distbase == NULL && + (distbase = getenv("DISTBASE")) == NULL) + distbase = ""; + if (*distbase != '\0' && *distbase != '/') + errx(1, "DISTBASE=%s does not begin with a slash", distbase); + distbase = normalize_path(distbase); if (unprivileged && metalog == NULL && (metalog = getenv("METALOG")) == NULL) @@ -966,6 +1011,7 @@ set_defaults(void) info("localbase:\t%s", localbase); info("destdir:\t%s", destdir); + info("distbase:\t%s", distbase); info("unprivileged:\t%s", unprivileged ? "true" : "false"); info("verbose:\t%s", verbose ? "true" : "false"); } @@ -987,11 +1033,11 @@ static struct { static void usage(void) { - fprintf(stderr, "usage: certctl [-lv] [-D destdir] list\n" - " certctl [-lv] [-D destdir] untrusted\n" - " certctl [-BnUv] [-D destdir] [-M metalog] rehash\n" - " certctl [-nv] [-D destdir] untrust <file>\n" - " certctl [-nv] [-D destdir] trust <file>\n"); + fprintf(stderr, "usage: certctl [-lv] [-D destdir] [-d distbase] list\n" + " certctl [-lv] [-D destdir] [-d distbase] untrusted\n" + " certctl [-BnUv] [-D destdir] [-d distbase] [-M metalog] rehash\n" + " certctl [-nv] [-D destdir] [-d distbase] untrust <file>\n" + " certctl [-nv] [-D destdir] [-d distbase] trust <file>\n"); exit(1); } @@ -1001,7 +1047,7 @@ main(int argc, char *argv[]) const char *command; int opt; - while ((opt = getopt(argc, argv, "BcD:g:lL:M:no:Uv")) != -1) + while ((opt = getopt(argc, argv, "BcD:d:g:lL:M:no:Uv")) != -1) switch (opt) { case 'B': nobundle = true; @@ -1012,6 +1058,9 @@ main(int argc, char *argv[]) case 'D': destdir = optarg; break; + case 'd': + distbase = optarg; + break; case 'g': gname = optarg; break; diff --git a/usr.sbin/certctl/tests/certctl_test.sh b/usr.sbin/certctl/tests/certctl_test.sh index 4e236d5bfae8..f60bac6ffbb3 100644 --- a/usr.sbin/certctl/tests/certctl_test.sh +++ b/usr.sbin/certctl/tests/certctl_test.sh @@ -60,41 +60,77 @@ ZWUPHYWKKTVEFBJOLLPDAIKGRDFVXZID $collhash EOF } +sortfile() { + for filename; do + sort "${filename}" >"${filename}"- + mv "${filename}"- "${filename}" + done +} + certctl_setup() { export DESTDIR="$PWD" # Create input directories - mkdir -p usr/share/certs/trusted - mkdir -p usr/share/certs/untrusted - mkdir -p usr/local/share/certs + mkdir -p ${DESTDIR}${DISTBASE}/usr/share/certs/trusted + mkdir -p ${DESTDIR}${DISTBASE}/usr/share/certs/untrusted + mkdir -p ${DESTDIR}/usr/local/share/certs # Create output directories - mkdir -p etc/ssl/certs - mkdir -p etc/ssl/untrusted + mkdir -p ${DESTDIR}${DISTBASE}/etc/ssl/certs + mkdir -p ${DESTDIR}${DISTBASE}/etc/ssl/untrusted # Generate a random key keyname="testkey" gen_key ${keyname} # Generate certificates + :>metalog.expect + :>trusted.expect + :>untrusted.expect + metalog() { + echo ".${DISTBASE}$@ type=file" >>metalog.expect + } + trusted() { + local crtname=$1 + local filename=$2 + printf "%s\t%s\n" "${filename}" "${crtname}" >>trusted.expect + metalog "/etc/ssl/certs/${filename}" + } + untrusted() { + local crtname=$1 + local filename=$2 + printf "%s\t%s\n" "${filename}" "${crtname}" >>untrusted.expect + metalog "/etc/ssl/untrusted/${filename}" + } set1 | while read crtname hash ; do gen_crt ${crtname} ${keyname} - mv ${crtname}.crt usr/share/certs/trusted + mv ${crtname}.crt ${DESTDIR}${DISTBASE}/usr/share/certs/trusted + trusted "${crtname}" "${hash}.0" done + local c=0 coll | while read crtname hash ; do gen_crt ${crtname} ${keyname} - mv ${crtname}.crt usr/share/certs/trusted + mv ${crtname}.crt ${DESTDIR}${DISTBASE}/usr/share/certs/trusted + trusted "${crtname}" "${hash}.${c}" + c=$((c+1)) done set2 | while read crtname hash ; do gen_crt ${crtname} ${keyname} openssl x509 -in ${crtname}.crt rm ${crtname}.crt + trusted "${crtname}" "${hash}.0" done >usr/local/share/certs/bundle.crt set3 | while read crtname hash ; do gen_crt ${crtname} ${keyname} - mv ${crtname}.crt usr/share/certs/untrusted + mv ${crtname}.crt ${DESTDIR}${DISTBASE}/usr/share/certs/untrusted + untrusted "${crtname}" "${hash}.0" done + metalog "/etc/ssl/cert.pem" + unset -f untrusted + unset -f trusted + unset -f metalog + sortfile *.expect } check_trusted() { @@ -102,12 +138,12 @@ check_trusted() { local subject="$(subject ${crtname})" local c=${2:-1} - atf_check -o match:"found: ${c}\$" \ + atf_check -e ignore -o match:"found: ${c}\$" \ openssl storeutl -noout -subject "${subject}" \ - etc/ssl/certs - atf_check -o match:"found: 0\$" \ + ${DESTDIR}${DISTBASE}/etc/ssl/certs + atf_check -e ignore -o not-match:"found: [1-9]" \ openssl storeutl -noout -subject "${subject}" \ - etc/ssl/untrusted + ${DESTDIR}${DISTBASE}/etc/ssl/untrusted } check_untrusted() { @@ -115,23 +151,25 @@ check_untrusted() { local subject="$(subject ${crtname})" local c=${2:-1} - atf_check -o match:"found: 0\$" \ + atf_check -e ignore -o not-match:"found: [1-9]" \ openssl storeutl -noout -subject "${subject}" \ - etc/ssl/certs - atf_check -o match:"found: ${c}\$" \ + ${DESTDIR}/${DISTBASE}/etc/ssl/certs + atf_check -e ignore -o match:"found: ${c}\$" \ openssl storeutl -noout -subject "${subject}" \ - etc/ssl/untrusted + ${DESTDIR}/${DISTBASE}/etc/ssl/untrusted } check_in_bundle() { + local b=${DISTBASE}${DISTBASE+/} local crtfile=$1 local line line=$(tail +5 "${crtfile}" | head -1) - atf_check grep -q "${line}" etc/ssl/cert.pem + atf_check grep -q "${line}" ${DESTDIR}${DISTBASE}/etc/ssl/cert.pem } check_not_in_bundle() { + local b=${DISTBASE}${DISTBASE+/} local crtfile=$1 local line @@ -150,7 +188,7 @@ rehash_body() atf_check certctl rehash # Verify non-colliding trusted certificates - (set1 ; set2) > trusted + (set1; set2) >trusted while read crtname hash ; do check_trusted "${crtname}" done <trusted @@ -167,7 +205,7 @@ rehash_body() check_untrusted "${crtname}" done <untrusted - # Verify bundle; storeutl is no help here + # Verify bundle for f in etc/ssl/certs/*.? ; do check_in_bundle "${f}" done @@ -176,6 +214,31 @@ rehash_body() done } +atf_test_case list +list_head() +{ + atf_set "descr" "Test the list and untrusted commands" +} +list_body() +{ + certctl_setup + atf_check certctl rehash + + atf_check -o save:trusted.out certctl list + sortfile trusted.out + # the ordering of the colliding certificates is partly + # determined by fields that change every time we regenerate + # them, so ignore them in the diff + atf_check diff -u \ + --ignore-matching-lines $collhash \ + trusted.expect trusted.out + + atf_check -o save:untrusted.out certctl untrusted + sortfile untrusted.out + atf_check diff -u \ + untrusted.expect untrusted.out +} + atf_test_case trust trust_head() { @@ -185,7 +248,7 @@ trust_body() { certctl_setup atf_check certctl rehash - crtname=NJWIRLPWAIICVJBKXXHFHLCPAERZATRL + crtname=$(set3 | (read crtname hash ; echo ${crtname})) crtfile=usr/share/certs/untrusted/${crtname}.crt check_untrusted ${crtname} check_not_in_bundle ${crtfile} @@ -204,7 +267,7 @@ untrust_body() { certctl_setup atf_check certctl rehash - crtname=AVOYKJHSLFHWPVQMKBHENUAHJTEGMCCB + crtname=$(set1 | (read crtname hash ; echo ${crtname})) crtfile=usr/share/certs/trusted/${crtname}.crt check_trusted "${crtname}" check_in_bundle ${crtfile} @@ -213,9 +276,57 @@ untrust_body() check_not_in_bundle ${crtfile} } +atf_test_case metalog +metalog_head() +{ + atf_set "descr" "Verify the metalog" +} +metalog_body() +{ + export DISTBASE=/base + certctl_setup + + # certctl gets DESTDIR and DISTBASE from environment + rm -f metalog.orig + atf_check certctl -U -M metalog.orig rehash + sed -E 's/(type=file) .*/\1/' metalog.orig | sort >metalog.short + atf_check diff -u metalog.expect metalog.short + + # certctl gets DESTDIR and DISTBASE from command line + rm -f metalog.orig + atf_check env -uDESTDIR -uDISTBASE \ + certctl -D ${DESTDIR} -d ${DISTBASE} -U -M metalog.orig rehash + sed -E 's/(type=file) .*/\1/' metalog.orig | sort >metalog.short + atf_check diff -u metalog.expect metalog.short + + # as above, but intentionally add trailing slashes + rm -f metalog.orig + atf_check env -uDESTDIR -uDISTBASE \ + certctl -D ${DESTDIR}// -d ${DISTBASE}/ -U -M metalog.orig rehash + sed -E 's/(type=file) .*/\1/' metalog.orig | sort >metalog.short + atf_check diff -u metalog.expect metalog.short +} + +atf_test_case misc +misc_head() +{ + atf_set "descr" "Test miscellaneous edge cases" +} +misc_body() +{ + # certctl rejects DISTBASE that does not begin with a slash + atf_check -s exit:1 -e match:"begin with a slash" \ + certctl -d base -n rehash + atf_check -s exit:1 -e match:"begin with a slash" \ + env DISTBASE=base certctl -n rehash +} + atf_init_test_cases() { atf_add_test_case rehash + atf_add_test_case list atf_add_test_case trust atf_add_test_case untrust + atf_add_test_case metalog + atf_add_test_case misc } diff --git a/usr.sbin/chroot/chroot.c b/usr.sbin/chroot/chroot.c index 7ec5a00b50f0..e1af0a4131d3 100644 --- a/usr.sbin/chroot/chroot.c +++ b/usr.sbin/chroot/chroot.c @@ -147,15 +147,10 @@ main(int argc, char *argv[]) gid = resolve_group(group); if (grouplist != NULL) { - ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1; + ngroups_max = sysconf(_SC_NGROUPS_MAX); if ((gidlist = malloc(sizeof(gid_t) * ngroups_max)) == NULL) err(1, "malloc"); - /* Populate the egid slot in our groups to avoid accidents. */ - if (gid == 0) - gidlist[0] = getegid(); - else - gidlist[0] = gid; - for (gids = 1; (p = strsep(&grouplist, ",")) != NULL && + for (gids = 0; (p = strsep(&grouplist, ",")) != NULL && gids < ngroups_max; ) { if (*p == '\0') continue; diff --git a/usr.sbin/freebsd-update/freebsd-update.sh b/usr.sbin/freebsd-update/freebsd-update.sh index c388e76644dc..81040431ea79 100644 --- a/usr.sbin/freebsd-update/freebsd-update.sh +++ b/usr.sbin/freebsd-update/freebsd-update.sh @@ -3000,7 +3000,7 @@ install_from_index () { if [ -z "${LINK}" ]; then # Create a file, without setting flags. gunzip < files/${HASH}.gz > ${HASH} - install -S -o ${OWNER} -g ${GROUP} \ + install -o ${OWNER} -g ${GROUP} \ -m ${PERM} ${HASH} ${BASEDIR}/${FPATH} rm ${HASH} else diff --git a/usr.sbin/jail/config.c b/usr.sbin/jail/config.c index 70de82e662e7..1bad04ccde68 100644 --- a/usr.sbin/jail/config.c +++ b/usr.sbin/jail/config.c @@ -189,7 +189,7 @@ load_config(const char *cfname) * jail is created or found. */ if (j->intparams[KP_NAME] == NULL) - add_param(j, j->intparams[KP_JID], KP_NAME, NULL); + add_param(j, NULL, KP_NAME, j->name); /* Resolve any variable substitutions. */ pgen = 0; diff --git a/usr.sbin/jail/tests/jail_basic_test.sh b/usr.sbin/jail/tests/jail_basic_test.sh index 509900e8569c..6802da7b049a 100755 --- a/usr.sbin/jail/tests/jail_basic_test.sh +++ b/usr.sbin/jail/tests/jail_basic_test.sh @@ -198,7 +198,7 @@ clean_jails() fi while read jail; do - if jls -e -j "$jail"; then + if jls -c -j "$jail"; then jail -r "$jail" fi done < jails.lst @@ -211,10 +211,23 @@ jid_name_set_body() echo "basejail" >> jails.lst echo "$jid { name = basejail; persist; }" > jail.conf atf_check -o match:"$jid: created" jail -f jail.conf -c "$jid" + # Confirm that we didn't override the explicitly-set name with the jid + # as the name. + atf_check -o match:"basejail" jls -j "$jid" name + atf_check -o match:"$jid: removed" jail -f jail.conf -r "$jid" + + echo "$jid { host.hostname = \"\${name}\"; persist; }" > jail.conf + atf_check -o match:"$jid: created" jail -f jail.conf -c "$jid" + # Confirm that ${name} expanded and expanded correctly to the + # jid-implied name. + atf_check -o match:"$jid" jls -j "$jid" host.hostname atf_check -o match:"$jid: removed" jail -f jail.conf -r "$jid" echo "basejail { jid = $jid; persist; }" > jail.conf atf_check -o match:"basejail: created" jail -f jail.conf -c basejail + # Confirm that our jid assigment in the definition worked out and we + # did in-fact create the jail there. + atf_check -o match:"$jid" jls -j "basejail" jid atf_check -o match:"basejail: removed" jail -f jail.conf -r basejail } diff --git a/usr.sbin/lpr/lpc/lpc.c b/usr.sbin/lpr/lpc/lpc.c index a3da852de46e..b4db5bb2e29f 100644 --- a/usr.sbin/lpr/lpc/lpc.c +++ b/usr.sbin/lpr/lpc/lpc.c @@ -358,6 +358,8 @@ ingroup(const char *grname) err(1, "getgroups"); } gid = gptr->gr_gid; + if (gid == getegid()) + return(1); for (i = 0; i < ngroups; i++) if (gid == groups[i]) return(1); diff --git a/usr.sbin/makefs/zfs.c b/usr.sbin/makefs/zfs.c index 8d50c450541b..e33a182e5c8f 100644 --- a/usr.sbin/makefs/zfs.c +++ b/usr.sbin/makefs/zfs.c @@ -596,7 +596,7 @@ pool_labels_write(zfs_opt_t *zfs) * checksum is calculated in vdev_label_write(). */ for (size_t uoff = 0; uoff < sizeof(label->vl_uberblock); - uoff += (1 << zfs->ashift)) { + uoff += ASHIFT_UBERBLOCK_SIZE(zfs->ashift)) { ub = (uberblock_t *)(&label->vl_uberblock[0] + uoff); ub->ub_magic = UBERBLOCK_MAGIC; ub->ub_version = SPA_VERSION; diff --git a/usr.sbin/makefs/zfs/vdev.c b/usr.sbin/makefs/zfs/vdev.c index afcce402cb13..a2423e180ca3 100644 --- a/usr.sbin/makefs/zfs/vdev.c +++ b/usr.sbin/makefs/zfs/vdev.c @@ -200,7 +200,7 @@ vdev_label_write(zfs_opt_t *zfs, int ind, const vdev_label_t *labelp) * per sector; for example, with an ashift of 12 we end up with * 128KB/4KB=32 copies of the uberblock in the ring. */ - blksz = 1 << zfs->ashift; + blksz = ASHIFT_UBERBLOCK_SIZE(zfs->ashift); assert(sizeof(label->vl_uberblock) % blksz == 0); for (size_t roff = 0; roff < sizeof(label->vl_uberblock); roff += blksz) { diff --git a/usr.sbin/rpc.ypupdated/Makefile b/usr.sbin/rpc.ypupdated/Makefile new file mode 100644 index 000000000000..78ee19fc7a6d --- /dev/null +++ b/usr.sbin/rpc.ypupdated/Makefile @@ -0,0 +1,32 @@ +.PATH: ${SRCTOP}/usr.sbin/ypserv ${SRCTOP}/libexec/ypxfr + +PACKAGE=yp +PROG= rpc.ypupdated +MAN= +SRCS= ypupdate_prot_svc.c ypupdate_prot.h ypupdated_main.c \ + yp_error.c update.c ypupdated_server.c \ + yp_dblookup.c yp_dbwrite.c yp_dbdelete.c yp_dbupdate.c + +#CFLAGS+= -DYP +CFLAGS+= -I${SRCTOP}/usr.sbin/ypserv -I. -I${SRCTOP}/libexec/ypxfr + +WARNS?= 1 + +LIBADD= rpcsvc + +CLEANFILES= ypupdate_prot_svc.c ypupdate_prot.h + +RPCDIR= ${SYSROOT:U${DESTDIR}}/usr/include/rpcsvc +RPCGEN= RPCGEN_CPP=${CPP:Q} rpcgen -I -C + +# We need to remove the 'static' keyword from _rpcsvcstate so that +# ypupdated_main.c can see it. +ypupdate_prot_svc.c: ${RPCDIR}/ypupdate_prot.x + rm -f ${.TARGET} + ${RPCGEN} -m ${.ALLSRC} | \ + sed s/"static int _rpcsvcstate"/"int _rpcsvcstate"/g > ${.TARGET} + +ypupdate_prot.h: ${RPCDIR}/ypupdate_prot.x + ${RPCGEN} -h -o ${.TARGET} ${.ALLSRC} + +.include <bsd.prog.mk> diff --git a/usr.sbin/rpc.ypupdated/Makefile.depend b/usr.sbin/rpc.ypupdated/Makefile.depend new file mode 100644 index 000000000000..352a225b19c6 --- /dev/null +++ b/usr.sbin/rpc.ypupdated/Makefile.depend @@ -0,0 +1,18 @@ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + include \ + include/rpc \ + include/rpcsvc \ + include/xlocale \ + lib/${CSU_DIR} \ + lib/libc \ + lib/libcompiler_rt \ + lib/librpcsvc \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.sbin/rpc.ypupdated/update.c b/usr.sbin/rpc.ypupdated/update.c new file mode 100644 index 000000000000..332ed752acc4 --- /dev/null +++ b/usr.sbin/rpc.ypupdated/update.c @@ -0,0 +1,328 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Copyright (C) 1986, 1989, Sun Microsystems, Inc. + */ + +/* + * Administrative tool to add a new user to the publickey database + */ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <rpc/rpc.h> +#include <rpc/key_prot.h> +#ifdef YP +#include <rpcsvc/yp_prot.h> +#include <rpcsvc/ypclnt.h> +#include <sys/wait.h> +#include <netdb.h> +#endif /* YP */ +#include <pwd.h> +#include <string.h> +#include <sys/resource.h> +#include "ypupdated_extern.h" + +#ifdef YP +#define MAXMAPNAMELEN 256 +#else +#define YPOP_CHANGE 1 /* change, do not add */ +#define YPOP_INSERT 2 /* add, do not change */ +#define YPOP_DELETE 3 /* delete this entry */ +#define YPOP_STORE 4 /* add, or change */ +#endif + +#ifdef YP +static char SHELL[] = "/bin/sh"; +static char YPDBPATH[]="/var/yp"; /* This is defined but not used! */ +static char PKMAP[] = "publickey.byname"; +static char UPDATEFILE[] = "updaters"; +static char PKFILE[] = "/etc/publickey"; +#endif /* YP */ + +#ifdef YP +static int _openchild(char *, FILE **, FILE **); + +/* + * Determine if requester is allowed to update the given map, + * and update it if so. Returns the yp status, which is zero + * if there is no access violation. + */ +int +mapupdate(char *requester, char *mapname, u_int op, u_int keylen, char *key, + u_int datalen, char *data) +{ + char updater[MAXMAPNAMELEN + 40]; + FILE *childargs; + FILE *childrslt; +#ifdef WEXITSTATUS + int status; +#else + union wait status; +#endif + pid_t pid; + u_int yperrno; + + +#ifdef DEBUG + printf("%s %s\n", key, data); +#endif + (void)sprintf(updater, "make -s -f %s/%s %s", YPDBPATH, /* !!! */ + UPDATEFILE, mapname); + pid = _openchild(updater, &childargs, &childrslt); + if (pid < 0) { + return (YPERR_YPERR); + } + + /* + * Write to child + */ + (void)fprintf(childargs, "%s\n", requester); + (void)fprintf(childargs, "%u\n", op); + (void)fprintf(childargs, "%u\n", keylen); + (void)fwrite(key, (int)keylen, 1, childargs); + (void)fprintf(childargs, "\n"); + (void)fprintf(childargs, "%u\n", datalen); + (void)fwrite(data, (int)datalen, 1, childargs); + (void)fprintf(childargs, "\n"); + (void)fclose(childargs); + + /* + * Read from child + */ + (void)fscanf(childrslt, "%d", &yperrno); + (void)fclose(childrslt); + + (void)wait(&status); +#ifdef WEXITSTATUS + if (WEXITSTATUS(status) != 0) +#else + if (status.w_retcode != 0) +#endif + return (YPERR_YPERR); + return (yperrno); +} + +/* + * returns pid, or -1 for failure + */ +static int +_openchild(char *command, FILE **fto, FILE **ffrom) +{ + int i; + pid_t pid; + int pdto[2]; + int pdfrom[2]; + char *com; + struct rlimit rl; + + if (pipe(pdto) < 0) { + goto error1; + } + if (pipe(pdfrom) < 0) { + goto error2; + } + switch (pid = fork()) { + case -1: + goto error3; + + case 0: + /* + * child: read from pdto[0], write into pdfrom[1] + */ + (void)close(0); + (void)dup(pdto[0]); + (void)close(1); + (void)dup(pdfrom[1]); + getrlimit(RLIMIT_NOFILE, &rl); + for (i = rl.rlim_max - 1; i >= 3; i--) { + (void) close(i); + } + com = malloc((unsigned) strlen(command) + 6); + if (com == NULL) { + _exit(~0); + } + (void)sprintf(com, "exec %s", command); + execl(SHELL, basename(SHELL), "-c", com, (char *)NULL); + _exit(~0); + + default: + /* + * parent: write into pdto[1], read from pdfrom[0] + */ + *fto = fdopen(pdto[1], "w"); + (void)close(pdto[0]); + *ffrom = fdopen(pdfrom[0], "r"); + (void)close(pdfrom[1]); + break; + } + return (pid); + + /* + * error cleanup and return + */ +error3: + (void)close(pdfrom[0]); + (void)close(pdfrom[1]); +error2: + (void)close(pdto[0]); + (void)close(pdto[1]); +error1: + return (-1); +} + +static char * +basename(char *path) +{ + char *p; + + p = strrchr(path, '/'); + if (p == NULL) { + return (path); + } else { + return (p + 1); + } +} + +#else /* YP */ + +static int match(char *, char *); + +/* + * Determine if requester is allowed to update the given map, + * and update it if so. Returns the status, which is zero + * if there is no access violation. This function updates + * the local file and then shuts up. + */ +int +localupdate(char *name, char *filename, u_int op, u_int keylen __unused, + char *key, u_int datalen __unused, char *data) +{ + char line[256]; + FILE *rf; + FILE *wf; + char *tmpname; + int err; + + /* + * Check permission + */ + if (strcmp(name, key) != 0) { + return (ERR_ACCESS); + } + if (strcmp(name, "nobody") == 0) { + /* + * Can't change "nobody"s key. + */ + return (ERR_ACCESS); + } + + /* + * Open files + */ + tmpname = malloc(strlen(filename) + 4); + if (tmpname == NULL) { + return (ERR_MALLOC); + } + sprintf(tmpname, "%s.tmp", filename); + rf = fopen(filename, "r"); + if (rf == NULL) { + err = ERR_READ; + goto cleanup; + } + wf = fopen(tmpname, "w"); + if (wf == NULL) { + fclose(rf); + err = ERR_WRITE; + goto cleanup; + } + err = -1; + while (fgets(line, sizeof (line), rf)) { + if (err < 0 && match(line, name)) { + switch (op) { + case YPOP_INSERT: + err = ERR_KEY; + break; + case YPOP_STORE: + case YPOP_CHANGE: + fprintf(wf, "%s %s\n", key, data); + err = 0; + break; + case YPOP_DELETE: + /* do nothing */ + err = 0; + break; + } + } else { + fputs(line, wf); + } + } + if (err < 0) { + switch (op) { + case YPOP_CHANGE: + case YPOP_DELETE: + err = ERR_KEY; + break; + case YPOP_INSERT: + case YPOP_STORE: + err = 0; + fprintf(wf, "%s %s\n", key, data); + break; + } + } + fclose(wf); + fclose(rf); + if (err == 0) { + if (rename(tmpname, filename) < 0) { + err = ERR_DBASE; + goto cleanup; + } + } else { + if (unlink(tmpname) < 0) { + err = ERR_DBASE; + goto cleanup; + } + } +cleanup: + free(tmpname); + return (err); +} + +static int +match(char *line, char *name) +{ + int len; + + len = strlen(name); + return (strncmp(line, name, len) == 0 && + (line[len] == ' ' || line[len] == '\t')); +} +#endif /* !YP */ diff --git a/usr.sbin/rpc.ypupdated/yp_dbdelete.c b/usr.sbin/rpc.ypupdated/yp_dbdelete.c new file mode 100644 index 000000000000..d07a8fcd2ff9 --- /dev/null +++ b/usr.sbin/rpc.ypupdated/yp_dbdelete.c @@ -0,0 +1,68 @@ +/*- + * SPDX-License-Identifier: BSD-4-Clause + * + * Copyright (c) 1995, 1996 + * 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 <sys/cdefs.h> +#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 <rpcsvc/yp.h> +#include "ypxfr_extern.h" + +int +yp_del_record(DB *dbp, DBT *key) +{ + int rval; + + if ((rval = (dbp->del)(dbp,key,0))) { + switch (rval) { + case 1: + return(YP_FALSE); + break; + case -1: + default: + (void)(dbp->close)(dbp); + return(YP_BADDB); + break; + } + } + + return(YP_TRUE); +} diff --git a/usr.sbin/rpc.ypupdated/yp_dbupdate.c b/usr.sbin/rpc.ypupdated/yp_dbupdate.c new file mode 100644 index 000000000000..af17bf5244ef --- /dev/null +++ b/usr.sbin/rpc.ypupdated/yp_dbupdate.c @@ -0,0 +1,147 @@ +/*- + * SPDX-License-Identifier: BSD-4-Clause + * + * Copyright (c) 1996 + * 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 <sys/cdefs.h> +#include <sys/fcntl.h> + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <limits.h> +#include <db.h> +#include <unistd.h> +#include <rpcsvc/ypclnt.h> +#include <rpcsvc/ypupdate_prot.h> +#include "ypxfr_extern.h" +#include "ypupdated_extern.h" + +static int +yp_domake(char *map, char *domain) +{ + int pid; + + switch ((pid = fork())) { + case 0: + execlp(MAP_UPDATE_PATH, MAP_UPDATE, map, domain, (char *)NULL); + yp_error("couldn't exec map update process: %s", + strerror(errno)); + exit(1); + break; + case -1: + yp_error("fork() failed: %s", strerror(errno)); + return(YPERR_YPERR); + break; + default: + children++; + break; + } + + return(0); +} + +int +ypmap_update(char *netname, char *map, unsigned int op, unsigned int keylen, + char *keyval, unsigned int datlen, char *datval) +{ + DB *dbp; + DBT key = { NULL, 0 }, data = { NULL, 0 }; + char *yp_last = "YP_LAST_MODIFIED"; + char yplastbuf[32]; + char *domptr; + int rval = 0; + + if ((domptr = strchr(netname, '@')) == NULL) + return(ERR_ACCESS); + domptr++; + + + dbp = yp_open_db_rw(domptr, map, O_RDWR); + if (dbp == NULL) + return(ERR_DBASE); + + key.data = keyval; + key.size = keylen; + data.data = datval; + data.size = datlen; + + switch (op) { + case YPOP_DELETE: /* delete this entry */ + rval = yp_del_record(dbp, &key); + if (rval == YP_TRUE) + rval = 0; + break; + case YPOP_INSERT: /* add, do not change */ + rval = yp_put_record(dbp, &key, &data, 0); + if (rval == YP_TRUE) + rval = 0; + break; + case YPOP_STORE: /* add, or change */ + rval = yp_put_record(dbp, &key, &data, 1); + if (rval == YP_TRUE) + rval = 0; + break; + case YPOP_CHANGE: /* change, do not add */ + if (yp_get_record(domptr, map, &key, &data, 0) != YP_TRUE) { + rval = ERR_KEY; + break; + } + rval = yp_put_record(dbp, &key, &data, 1); + if (rval == YP_TRUE) + rval = 0; + break; + default: + yp_error("unknown update command: (%d)", op); + } + + if (rval) { + (void)(dbp->close)(dbp); + return(rval); + } + + snprintf(yplastbuf, sizeof(yplastbuf), "%jd", (intmax_t)time(NULL)); + key.data = yp_last; + key.size = strlen(yp_last); + data.data = (char *)&yplastbuf; + data.size = strlen(yplastbuf); + if (yp_put_record(dbp, &key, &data, 1) != YP_TRUE) { + yp_error("failed to update timestamp in %s/%s", domptr, map); + (void)(dbp->close)(dbp); + return(ERR_DBASE); + } + + (void)(dbp->close)(dbp); + return(yp_domake(map, domptr)); +} diff --git a/usr.sbin/rpc.ypupdated/ypupdate b/usr.sbin/rpc.ypupdated/ypupdate new file mode 100755 index 000000000000..8795ef3baf80 --- /dev/null +++ b/usr.sbin/rpc.ypupdated/ypupdate @@ -0,0 +1,32 @@ +#!/bin/sh +# +# This script is invoked by rpc.ypupdatedd to propagate NIS maps +# after the master map databases have been modified. It expects +# to be passed two arguments: the name of the map that was updated +# and the name of the domain where the map resides. +# These are passed to /var/yp/Makefile. +# +# Comment out the LOG=yes line to disable logging. +# +# + +LOG=yes +LOGFILE=/var/yp/ypupdate.log + +umask 077 + +if [ ! -f $LOGFILE ]; +then + /usr/bin/touch $LOGFILE + echo "# Edit /usr/libexec/yppwupdate to disable" >> $LOGFILE + echo "# logging to this file from yppasswdd." >> $LOGFILE + echo -n "# Log started on: " >> $LOGFILE + /bin/date >> $LOGFILE +fi + +if [ ! $LOG ]; +then + cd /var/yp/$2; /usr/bin/make -f ../Makefile $1 2>&1 +else + cd /var/yp/$2; /usr/bin/make -f ../Makefile $1 >> $LOGFILE +fi diff --git a/usr.sbin/rpc.ypupdated/ypupdated_extern.h b/usr.sbin/rpc.ypupdated/ypupdated_extern.h new file mode 100644 index 000000000000..90968df36748 --- /dev/null +++ b/usr.sbin/rpc.ypupdated/ypupdated_extern.h @@ -0,0 +1,32 @@ +/* + */ + +#include <db.h> + +#define YPOP_CHANGE 1 /* change, do not add */ +#define YPOP_INSERT 2 /* add, do not change */ +#define YPOP_DELETE 3 /* delete this entry */ +#define YPOP_STORE 4 /* add, or change */ + +#define ERR_ACCESS 1 +#define ERR_MALLOC 2 +#define ERR_READ 3 +#define ERR_WRITE 4 +#define ERR_DBASE 5 +#define ERR_KEY 6 + +#ifndef YPLIBDIR +#define YPLIBDIR "/usr/libexec/" +#endif + +#ifndef MAP_UPPATE +#define MAP_UPDATE "ypupdate" +#endif + +#define MAP_UPDATE_PATH YPLIBDIR MAP_UPDATE + +extern int children; +extern void ypu_prog_1(struct svc_req *, register SVCXPRT *); +extern int localupdate(char *, char *, u_int, u_int, char *, u_int, char *); +extern int ypmap_update(char *, char *, u_int, u_int, char *, u_int, char *); +extern int yp_del_record(DB *, DBT *); diff --git a/usr.sbin/rpc.ypupdated/ypupdated_main.c b/usr.sbin/rpc.ypupdated/ypupdated_main.c new file mode 100644 index 000000000000..dae956594da0 --- /dev/null +++ b/usr.sbin/rpc.ypupdated/ypupdated_main.c @@ -0,0 +1,287 @@ +/*- + * SPDX-License-Identifier: BSD-4-Clause + * + * Copyright (c) 1995, 1996 + * 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 <sys/cdefs.h> +#include "ypupdate_prot.h" +#include <stdio.h> +#include <stdlib.h> /* getenv, exit */ +#include <rpc/pmap_clnt.h> /* for pmap_unset */ +#include <rpc/rpc_com.h> +#include <string.h> /* strcmp */ +#include <signal.h> +#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 <errno.h> +#include <err.h> +#include <unistd.h> +#include "ypupdated_extern.h" +#include "yp_extern.h" + +#ifndef SIG_PF +#define SIG_PF void(*)(int) +#endif + +#ifdef DEBUG +#define RPC_SVC_FG +#endif + +#define _RPCSVC_CLOSEDOWN 120 +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 int _rpcsvcstate; /* Set when a request is serviced */ + +int debug; + +char *progname = "rpc.ypupdated"; +char *yp_dir = "/var/yp/"; + +static void +_msgout(char* msg) +{ +#ifdef RPC_SVC_FG + if (_rpcpmstart) + syslog(LOG_ERR, "%s", msg); + else + warnx("%s", msg); +#else + syslog(LOG_ERR, "%s", msg); +#endif +} + +static void +closedown(int sig) +{ + if (_rpcsvcstate == _IDLE) { + extern fd_set svc_fdset; + static int size; + int i, openfd; + + if (_rpcfdtype == SOCK_DGRAM) + 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) + exit(0); + } + if (_rpcsvcstate == _SERVED) + _rpcsvcstate = _IDLE; + + (void) signal(SIGALRM, (SIG_PF) closedown); + (void) alarm(_RPCSVC_CLOSEDOWN/2); +} + +static void +ypupdated_svc_run(void) +{ +#ifdef FD_SETSIZE + fd_set readfds; +#else + int readfds; +#endif /* def FD_SETSIZE */ + extern int forked; + int pid; + int fd_setsize = _rpc_dtablesize(); + + /* Establish the identity of the parent ypupdated process. */ + pid = getpid(); + + for (;;) { +#ifdef FD_SETSIZE + readfds = svc_fdset; +#else + readfds = svc_fds; +#endif /* def FD_SETSIZE */ + switch (select(fd_setsize, &readfds, NULL, NULL, + (struct timeval *)0)) { + case -1: + if (errno == EINTR) { + continue; + } + warn("svc_run: - select failed"); + return; + case 0: + continue; + default: + svc_getreqset(&readfds); + if (forked && pid != getpid()) + exit(0); + } + } +} + +static void +reaper(int sig) +{ + int status; + + if (sig == SIGHUP) { +#ifdef foo + load_securenets(); +#endif + return; + } + + if (sig == SIGCHLD) { + while (wait3(&status, WNOHANG, NULL) > 0) + children--; + } else { + (void) pmap_unset(YPU_PROG, YPU_VERS); + exit(0); + } +} + +void +usage(void) +{ + fprintf(stderr, "rpc.ypupdatedd [-p path]\n"); + exit(0); +} + +int +main(int argc, char *argv[]) +{ + register SVCXPRT *transp = NULL; + int sock; + int proto = 0; + struct sockaddr_in saddr; + int asize = sizeof (saddr); + int ch; + + while ((ch = getopt(argc, argv, "p:h")) != -1) { + switch (ch) { + case 'p': + yp_dir = optarg; + break; + default: + usage(); + break; + } + } +#ifdef foo + load_securenets(); +#endif + + if (svc_auth_reg(AUTH_DES, _svcauth_des) == -1) { + yp_error("failed to register AUTH_DES flavor"); + exit(1); + } + + 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("rpc.ypupdatedd", LOG_PID, LOG_DAEMON); + } else { +#ifndef RPC_SVC_FG + if (daemon(0,0)) { + err(1, "cannot fork"); + } + openlog("rpc.ypupdated", LOG_PID, LOG_DAEMON); +#endif + sock = RPC_ANYSOCK; + (void) pmap_unset(YPU_PROG, YPU_VERS); + } + + 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, YPU_PROG, YPU_VERS, ypu_prog_1, proto)) { + _msgout("unable to register (YPU_PROG, YPU_VERS, 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, YPU_PROG, YPU_VERS, ypu_prog_1, proto)) { + _msgout("unable to register (YPU_PROG, YPU_VERS, 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); + } + + (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); + + ypupdated_svc_run(); + _msgout("svc_run returned"); + exit(1); + /* NOTREACHED */ +} diff --git a/usr.sbin/rpc.ypupdated/ypupdated_server.c b/usr.sbin/rpc.ypupdated/ypupdated_server.c new file mode 100644 index 000000000000..47e52401cd6e --- /dev/null +++ b/usr.sbin/rpc.ypupdated/ypupdated_server.c @@ -0,0 +1,227 @@ +/*- + * SPDX-License-Identifier: BSD-4-Clause + * + * Copyright (c) 1995, 1996 + * 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. + * + * ypupdate server implementation + * + * Written by Bill Paul <wpaul@ctr.columbia.edu> + * Center for Telecommunications Research + * Columbia University, New York City + */ + +#include <sys/cdefs.h> +#include <stdio.h> +#include <rpc/rpc.h> +#include <rpc/key_prot.h> +#include <sys/param.h> +#include <rpcsvc/yp.h> +#include "ypupdate_prot.h" +#include "ypupdated_extern.h" +#include "yp_extern.h" +#include "ypxfr_extern.h" + +int children = 0; +int forked = 0; + +/* + * Try to avoid spoofing: if a client chooses to use a very large + * window and then tries a bunch of randomly chosen encrypted timestamps, + * there's a chance he might stumble onto a valid combination. + * We therefore reject any RPCs with a window size larger than a preset + * value. + */ +#ifndef WINDOW +#define WINDOW (60*60) +#endif + +static enum auth_stat +yp_checkauth(struct svc_req *svcreq) +{ + struct authdes_cred *des_cred; + + switch (svcreq->rq_cred.oa_flavor) { + case AUTH_DES: + des_cred = (struct authdes_cred *) svcreq->rq_clntcred; + if (des_cred->adc_fullname.window > WINDOW) { + yp_error("warning: client-specified window size \ +was too large -- possible spoof attempt"); + return(AUTH_BADCRED); + } + return(AUTH_OK); + break; + case AUTH_UNIX: + case AUTH_NONE: + yp_error("warning: client didn't use DES authentication"); + return(AUTH_TOOWEAK); + break; + default: + yp_error("client used unknown auth flavor"); + return(AUTH_REJECTEDCRED); + break; + } +} + +unsigned int * +ypu_change_1_svc(struct ypupdate_args *args, struct svc_req *svcreq) +{ + struct authdes_cred *des_cred; + static int res; + char *netname; + enum auth_stat astat; + + res = 0; + + astat = yp_checkauth(svcreq); + + if (astat != AUTH_OK) { + svcerr_auth(svcreq->rq_xprt, astat); + return(&res); + } + + des_cred = (struct authdes_cred *) svcreq->rq_clntcred; + netname = des_cred->adc_fullname.name; + + res = localupdate(netname, "/etc/publickey", YPOP_CHANGE, + args->key.yp_buf_len, args->key.yp_buf_val, + args->datum.yp_buf_len, args->datum.yp_buf_val); + + if (res) + return (&res); + + res = ypmap_update(netname, args->mapname, YPOP_CHANGE, + args->key.yp_buf_len, args->key.yp_buf_val, + args->datum.yp_buf_len, args->datum.yp_buf_val); + + return (&res); +} + +unsigned int * +ypu_insert_1_svc(struct ypupdate_args *args, struct svc_req *svcreq) +{ + struct authdes_cred *des_cred; + static int res; + char *netname; + enum auth_stat astat; + + res = 0; + + astat = yp_checkauth(svcreq); + + if (astat != AUTH_OK) { + svcerr_auth(svcreq->rq_xprt, astat); + return(&res); + } + + des_cred = (struct authdes_cred *) svcreq->rq_clntcred; + netname = des_cred->adc_fullname.name; + + res = localupdate(netname, "/etc/publickey", YPOP_INSERT, + args->key.yp_buf_len, args->key.yp_buf_val, + args->datum.yp_buf_len, args->datum.yp_buf_val); + + if (res) + return (&res); + + res = ypmap_update(netname, args->mapname, YPOP_INSERT, + args->key.yp_buf_len, args->key.yp_buf_val, + args->datum.yp_buf_len, args->datum.yp_buf_val); + + return (&res); +} + +unsigned int * +ypu_delete_1_svc(struct ypdelete_args *args, struct svc_req *svcreq) +{ + struct authdes_cred *des_cred; + static int res; + char *netname; + enum auth_stat astat; + + res = 0; + + astat = yp_checkauth(svcreq); + + if (astat != AUTH_OK) { + svcerr_auth(svcreq->rq_xprt, astat); + return(&res); + } + + des_cred = (struct authdes_cred *) svcreq->rq_clntcred; + netname = des_cred->adc_fullname.name; + + res = localupdate(netname, "/etc/publickey", YPOP_DELETE, + args->key.yp_buf_len, args->key.yp_buf_val, + 0, NULL); + + if (res) + return (&res); + + res = ypmap_update(netname, args->mapname, YPOP_DELETE, + args->key.yp_buf_len, args->key.yp_buf_val, + 0, NULL); + + return (&res); +} + +unsigned int * +ypu_store_1_svc(struct ypupdate_args *args, struct svc_req *svcreq) +{ + struct authdes_cred *des_cred; + static int res; + char *netname; + enum auth_stat astat; + + res = 0; + + astat = yp_checkauth(svcreq); + + if (astat != AUTH_OK) { + svcerr_auth(svcreq->rq_xprt, astat); + return(&res); + } + + des_cred = (struct authdes_cred *) svcreq->rq_clntcred; + netname = des_cred->adc_fullname.name; + + res = localupdate(netname, "/etc/publickey", YPOP_STORE, + args->key.yp_buf_len, args->key.yp_buf_val, + args->datum.yp_buf_len, args->datum.yp_buf_val); + + if (res) + return (&res); + + res = ypmap_update(netname, args->mapname, YPOP_STORE, + args->key.yp_buf_len, args->key.yp_buf_val, + args->datum.yp_buf_len, args->datum.yp_buf_val); + + return (&res); +} diff --git a/usr.sbin/services_mkdb/services b/usr.sbin/services_mkdb/services index 4a5b6863d92d..c5f950831767 100644 --- a/usr.sbin/services_mkdb/services +++ b/usr.sbin/services_mkdb/services @@ -893,7 +893,7 @@ biff 512/udp comsat #used by mail system to notify users # processes on the same machine login 513/tcp #remote login a la telnet; # automatic authentication performed -# based on priviledged port numbers +# based on privileged port numbers # and distributed data bases which # identify "authentication domains" who 513/udp whod #maintains data bases showing who's diff --git a/usr.sbin/syslogd/syslogd.8 b/usr.sbin/syslogd/syslogd.8 index fa61e78eaf3e..d39d9fdc8f5a 100644 --- a/usr.sbin/syslogd/syslogd.8 +++ b/usr.sbin/syslogd/syslogd.8 @@ -403,7 +403,7 @@ The message can contain a priority code, which should be a preceding decimal number in angle braces, for example, -.Sq Aq 5 . +.Sq <5> . This priority code should map into the priorities defined in the include file .In sys/syslog.h . diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c index fe7427130b78..81bbbbe66be8 100644 --- a/usr.sbin/syslogd/syslogd.c +++ b/usr.sbin/syslogd/syslogd.c @@ -1830,15 +1830,14 @@ fprintlog_write(struct filed *f, struct iovlist *il, int flags) case EHOSTUNREACH: case EHOSTDOWN: case EADDRNOTAVAIL: + case EAGAIN: + case ECONNREFUSED: break; /* case EBADF: */ /* case EACCES: */ /* case ENOTSOCK: */ /* case EFAULT: */ /* case EMSGSIZE: */ - /* case EAGAIN: */ - /* case ENOBUFS: */ - /* case ECONNREFUSED: */ default: dprintf("removing entry: errno=%d\n", e); f->f_type = F_UNUSED; diff --git a/usr.sbin/unbound/setup/local-unbound-setup.sh b/usr.sbin/unbound/setup/local-unbound-setup.sh index d52534b46fa3..d57d74952fc7 100755 --- a/usr.sbin/unbound/setup/local-unbound-setup.sh +++ b/usr.sbin/unbound/setup/local-unbound-setup.sh @@ -259,7 +259,7 @@ gen_unbound_conf() { echo " pidfile: ${pidfile}" echo " auto-trust-anchor-file: ${anchor}" if [ "${use_tls}" = "yes" ] ; then - echo " tls-system-cert: yes" + echo " tls-cert-bundle: /etc/ssl/cert.pem" fi echo "" if [ -f "${forward_conf}" ] ; then |