Import FreeBSD's libypclnt.
authorPeter Avalos <pavalos@theshell.com>
Sun, 14 Dec 2008 18:17:36 +0000 (13:17 -0500)
committerPeter Avalos <pavalos@theshell.com>
Sun, 28 Dec 2008 04:17:04 +0000 (23:17 -0500)
This centralizes NIS client code that is duplicated throughout the tree.

lib/Makefile
lib/libypclnt/Makefile [new file with mode: 0644]
lib/libypclnt/ypclnt.h [new file with mode: 0644]
lib/libypclnt/ypclnt_connect.c [new file with mode: 0644]
lib/libypclnt/ypclnt_error.c [new file with mode: 0644]
lib/libypclnt/ypclnt_free.c [new file with mode: 0644]
lib/libypclnt/ypclnt_get.c [new file with mode: 0644]
lib/libypclnt/ypclnt_new.c [new file with mode: 0644]
lib/libypclnt/ypclnt_passwd.c [new file with mode: 0644]

index eacd8e1..08d66bf 100644 (file)
@@ -28,7 +28,7 @@ SUBDIR=       libarchive libbluetooth libcom_err libcrypt libm libmd \
        ${_libmilter} ${_libncp} libnetgraph libopie libpam \
        libpcap libposix1e libsdp libthread_xu libpthread librpcsvc ${_libsm} \
        ${_libsmb} ${_libsmdb} ${_libsmutil} libstand libtelnet libusbhid \
-       ${_libvgl} libwrap libxpg4 liby libz i18n_module pam_module \
+       ${_libvgl} libwrap libxpg4 liby libypclnt libz i18n_module pam_module \
        libc_rtld libsctp
 
 .if exists(${.CURDIR}/compat/${MACHINE_ARCH}/Makefile)
diff --git a/lib/libypclnt/Makefile b/lib/libypclnt/Makefile
new file mode 100644 (file)
index 0000000..1445b63
--- /dev/null
@@ -0,0 +1,54 @@
+# $FreeBSD: src/lib/libypclnt/Makefile,v 1.16 2007/05/21 02:49:08 deischen Exp $
+
+LIB=   ypclnt
+SRCS=  ypclnt_connect.c \
+       ypclnt_error.c \
+       ypclnt_free.c \
+       ypclnt_new.c \
+       ypclnt_passwd.c \
+       ${GENSRCS}
+CLEANFILES+= ${GENSRCS}
+INCS= ypclnt.h
+
+CFLAGS+= -I.
+WARNS?=        6
+
+GENSRCS=yp.h \
+       yp_clnt.c \
+       yppasswd.h \
+       yppasswd_xdr.c \
+       yppasswd_clnt.c \
+       yppasswd_private.h \
+       yppasswd_private_clnt.c \
+       yppasswd_private_xdr.c
+
+RPCGEN=        rpcgen -C
+RPCSRC=        ${.CURDIR}/../../include/rpcsvc/yp.x
+RPCSRC_PW=     ${.CURDIR}/../../include/rpcsvc/yppasswd.x
+RPCSRC_PRIV=   ${.CURDIR}/../../usr.sbin/rpc.yppasswdd/yppasswd_private.x
+
+yp.h: ${RPCSRC}
+       ${RPCGEN} -h -o ${.TARGET} ${RPCSRC}
+
+yp_clnt.c: ${RPCSRC}
+       ${RPCGEN} -l -o ${.TARGET} ${RPCSRC}
+
+yppasswd.h: ${RPCSRC_PW}
+       ${RPCGEN} -h -o ${.TARGET} ${RPCSRC_PW}
+
+yppasswd_xdr.c: ${RPCSRC_PW}
+       ${RPCGEN} -c -o ${.TARGET} ${RPCSRC_PW}
+
+yppasswd_clnt.c: ${RPCSRC_PW}
+       ${RPCGEN} -l -o ${.TARGET} ${RPCSRC_PW}
+
+yppasswd_private.h: ${RPCSRC_PRIV}
+       ${RPCGEN} -h -o ${.TARGET} ${RPCSRC_PRIV}
+
+yppasswd_private_xdr.c: ${RPCSRC_PRIV}
+       ${RPCGEN} -c -o ${.TARGET} ${RPCSRC_PRIV}
+
+yppasswd_private_clnt.c: ${RPCSRC_PRIV}
+       ${RPCGEN} -l -o ${.TARGET} ${RPCSRC_PRIV}
+
+.include <bsd.lib.mk>
diff --git a/lib/libypclnt/ypclnt.h b/lib/libypclnt/ypclnt.h
new file mode 100644 (file)
index 0000000..f380bb0
--- /dev/null
@@ -0,0 +1,56 @@
+/*-
+ * Copyright (c) 2002 Networks Associates Technology, Inc.
+ * All rights reserved.
+ *
+ * This software was developed for the FreeBSD Project by ThinkSec AS and
+ * NAI Labs, the Security Research Division of Network Associates, Inc.
+ * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
+ * DARPA CHATS research program.
+ *
+ * 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. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 THE AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libypclnt/ypclnt.h,v 1.4 2006/07/28 21:34:37 stefanf Exp $
+ */
+
+#ifndef _YPCLNT_H_INCLUDED
+
+typedef struct ypclnt ypclnt_t;
+struct ypclnt {
+       char    *domain;        /* Domain name */
+       char    *map;           /* Map name */
+       char    *server;        /* Server name */
+       char    *error;         /* Error message */
+};
+
+struct passwd;
+
+ypclnt_t       *ypclnt_new(const char *, const char *, const char *);
+void            ypclnt_free(ypclnt_t *);
+void            ypclnt_error(ypclnt_t *, const char *, const char *, ...);
+int             ypclnt_connect(ypclnt_t *);
+int             ypclnt_havepasswdd(ypclnt_t *);
+int             ypclnt_passwd(ypclnt_t *, const struct passwd *, const char *);
+
+#endif
diff --git a/lib/libypclnt/ypclnt_connect.c b/lib/libypclnt/ypclnt_connect.c
new file mode 100644 (file)
index 0000000..5dfedcb
--- /dev/null
@@ -0,0 +1,87 @@
+/*-
+ * Copyright (c) 2002 Networks Associates Technology, Inc.
+ * All rights reserved.
+ *
+ * This software was developed for the FreeBSD Project by ThinkSec AS and
+ * NAI Labs, the Security Research Division of Network Associates, Inc.
+ * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
+ * DARPA CHATS research program.
+ *
+ * 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. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 THE AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libypclnt/ypclnt_connect.c,v 1.2 2006/07/28 21:34:37 stefanf Exp $
+ */
+
+#include <sys/param.h>
+
+#include <err.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <rpcsvc/ypclnt.h>
+
+#include "ypclnt.h"
+
+int
+ypclnt_connect(ypclnt_t *ypclnt)
+{
+       int r;
+
+       /* get default domain name unless specified */
+       if (ypclnt->domain == NULL) {
+               if ((ypclnt->domain = malloc(MAXHOSTNAMELEN)) == NULL) {
+                       ypclnt_error(ypclnt, __func__,
+                           "%s", strerror(errno));
+                       return (-1);
+               }
+               if (getdomainname(ypclnt->domain, MAXHOSTNAMELEN) != 0) {
+                       ypclnt_error(ypclnt, __func__,
+                           "can't get NIS domain name");
+                       return (-1);
+               }
+       }
+
+       /* map must be specified */
+       if (ypclnt->map == NULL) {
+               ypclnt_error(ypclnt, __func__,
+                   "caller must specify map name");
+               return (-1);
+       }
+
+       /* get master server for requested map unless specified */
+       if (ypclnt->server == NULL) {
+               r = yp_master(ypclnt->domain, ypclnt->map, &ypclnt->server);
+               if (r != 0) {
+                       ypclnt_error(ypclnt, __func__,
+                           "can't get NIS server name: %s", yperr_string(r));
+                       return (-1);
+               }
+       }
+
+       ypclnt_error(ypclnt, NULL, NULL);
+       return (0);
+}
diff --git a/lib/libypclnt/ypclnt_error.c b/lib/libypclnt/ypclnt_error.c
new file mode 100644 (file)
index 0000000..40075b5
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 2002 Networks Associates Technology, Inc.
+ * All rights reserved.
+ *
+ * This software was developed for the FreeBSD Project by ThinkSec AS and
+ * NAI Labs, the Security Research Division of Network Associates, Inc.
+ * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
+ * DARPA CHATS research program.
+ *
+ * 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. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 THE AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libypclnt/ypclnt_error.c,v 1.1 2002/04/13 06:20:02 des Exp $
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "ypclnt.h"
+
+void
+ypclnt_error(ypclnt_t *ypclnt, const char *func, const char *fmt, ...)
+{
+       char *errmsg;
+       va_list ap;
+
+       free(ypclnt->error);
+       ypclnt->error = NULL;
+       if (fmt == NULL)
+               return;
+
+       va_start(ap, fmt);
+       vasprintf(&errmsg, fmt, ap);
+       va_end(ap);
+       asprintf(&ypclnt->error, "%s(): %s", func, errmsg);
+       free(errmsg);
+}
diff --git a/lib/libypclnt/ypclnt_free.c b/lib/libypclnt/ypclnt_free.c
new file mode 100644 (file)
index 0000000..975083b
--- /dev/null
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2002 Networks Associates Technology, Inc.
+ * All rights reserved.
+ *
+ * This software was developed for the FreeBSD Project by ThinkSec AS and
+ * NAI Labs, the Security Research Division of Network Associates, Inc.
+ * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
+ * DARPA CHATS research program.
+ *
+ * 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. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 THE AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libypclnt/ypclnt_free.c,v 1.1 2002/04/13 06:20:02 des Exp $
+ */
+
+#include <stdlib.h>
+
+#include "ypclnt.h"
+
+void
+ypclnt_free(ypclnt_t *ypclnt)
+{
+       if (ypclnt != NULL) {
+               free(ypclnt->domain);
+               free(ypclnt->map);
+               free(ypclnt->server);
+               free(ypclnt->error);
+               free(ypclnt);
+       }
+}
diff --git a/lib/libypclnt/ypclnt_get.c b/lib/libypclnt/ypclnt_get.c
new file mode 100644 (file)
index 0000000..e242a13
--- /dev/null
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 2002 Networks Associates Technology, Inc.
+ * All rights reserved.
+ *
+ * This software was developed for the FreeBSD Project by ThinkSec AS and
+ * NAI Labs, the Security Research Division of Network Associates, Inc.
+ * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
+ * DARPA CHATS research program.
+ *
+ * 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. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 THE AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libypclnt/ypclnt_get.c,v 1.1 2002/04/13 06:20:02 des Exp $
+ */
+
+#include "ypclnt.h"
+
+char *
+ypclnt_get(ypclnt_t *ypc, const char *key)
+{
+       char *value;
+       int len, r;
+
+       r = yp_match(ypc->domain, ypc->map,
+           key, (int)strlen(key), &value, &len);
+       if (r != 0) {
+               ypclnt_error(ypc, __func__, "%s", yperr_string(r));
+               return (NULL);
+       }
+       return (value);
+}
diff --git a/lib/libypclnt/ypclnt_new.c b/lib/libypclnt/ypclnt_new.c
new file mode 100644 (file)
index 0000000..a6cb21f
--- /dev/null
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 2002 Networks Associates Technology, Inc.
+ * All rights reserved.
+ *
+ * This software was developed for the FreeBSD Project by ThinkSec AS and
+ * NAI Labs, the Security Research Division of Network Associates, Inc.
+ * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
+ * DARPA CHATS research program.
+ *
+ * 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. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 THE AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libypclnt/ypclnt_new.c,v 1.1 2002/04/13 06:20:02 des Exp $
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "ypclnt.h"
+
+ypclnt_t *
+ypclnt_new(const char *domain, const char *map, const char *server)
+{
+       ypclnt_t *ypclnt;
+
+       if ((ypclnt = calloc(1, sizeof *ypclnt)) == NULL)
+               return (NULL);
+       if (domain != NULL && (ypclnt->domain = strdup(domain)) == NULL)
+               goto fail;
+       if (map != NULL && (ypclnt->map = strdup(map)) == NULL)
+               goto fail;
+       if (server != NULL && (ypclnt->server = strdup(server)) == NULL)
+               goto fail;
+       return (ypclnt);
+ fail:
+       free(ypclnt->domain);
+       free(ypclnt->map);
+       free(ypclnt->server);
+       free(ypclnt);
+       return (NULL);
+}
diff --git a/lib/libypclnt/ypclnt_passwd.c b/lib/libypclnt/ypclnt_passwd.c
new file mode 100644 (file)
index 0000000..c95ed38
--- /dev/null
@@ -0,0 +1,313 @@
+/*-
+ * Copyright (c) 2002 Networks Associates Technology, Inc.
+ * All rights reserved.
+ *
+ * This software was developed for the FreeBSD Project by ThinkSec AS and
+ * NAI Labs, the Security Research Division of Network Associates, Inc.
+ * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
+ * DARPA CHATS research program.
+ *
+ * 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. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 THE AUTHOR 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.
+ *
+ * $FreeBSD: src/lib/libypclnt/ypclnt_passwd.c,v 1.7 2006/07/28 21:34:37 stefanf Exp $
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <err.h>
+#include <errno.h>
+#include <netconfig.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <rpcsvc/ypclnt.h>
+#include <rpcsvc/yppasswd.h>
+
+#include "ypclnt.h"
+#include "yppasswd_private.h"
+
+static int yppasswd_remote(ypclnt_t *, const struct passwd *, const char *);
+static int yppasswd_local(ypclnt_t *, const struct passwd *);
+
+/*
+ * Determines the availability of rpc.yppasswdd.  Returns -1 for not
+ * available (or unable to determine), 0 for available, 1 for available in
+ * master mode.
+ */
+int
+ypclnt_havepasswdd(ypclnt_t *ypclnt)
+{
+       struct netconfig *nc = NULL;
+       void *localhandle = 0;
+       CLIENT *clnt = NULL;
+       int ret;
+
+       /* check if rpc.yppasswdd is running */
+       if (getrpcport(ypclnt->server, YPPASSWDPROG,
+               YPPASSWDPROC_UPDATE, IPPROTO_UDP) == 0) {
+               ypclnt_error(ypclnt, __func__, "no rpc.yppasswdd on server");
+               return (-1);
+       }
+
+       /* if we're not root, use remote method */
+       if (getuid() != 0)
+               return (0);
+
+       /* try to connect to rpc.yppasswdd */
+       localhandle = setnetconfig();
+       while ((nc = getnetconfig(localhandle)) != NULL) {
+               if (nc->nc_protofmly != NULL &&
+                       strcmp(nc->nc_protofmly, NC_LOOPBACK) == 0)
+                               break;
+       }
+       if (nc == NULL) {
+               ypclnt_error(ypclnt, __func__,
+                   "getnetconfig: %s", nc_sperror());
+               ret = 0;
+               goto done;
+       }
+       if ((clnt = clnt_tp_create(NULL, MASTER_YPPASSWDPROG,
+           MASTER_YPPASSWDVERS, nc)) == NULL) {
+               ypclnt_error(ypclnt, __func__,
+                   "failed to connect to rpc.yppasswdd: %s",
+                   clnt_spcreateerror(ypclnt->server));
+               ret = 0;
+               goto done;
+       } else
+               ret = 1;
+
+done:
+       if (clnt != NULL) {
+               clnt_destroy(clnt);
+       }
+       endnetconfig(localhandle);
+       return (ret);
+}
+
+/*
+ * Updates the NIS user information for the specified user.
+ */
+int
+ypclnt_passwd(ypclnt_t *ypclnt, const struct passwd *pwd, const char *passwd)
+{
+       switch (ypclnt_havepasswdd(ypclnt)) {
+       case 0:
+               return (yppasswd_remote(ypclnt, pwd, passwd));
+       case 1:
+               return (yppasswd_local(ypclnt, pwd));
+       default:
+               return (-1);
+       }
+}
+
+/*
+ * yppasswd_remote and yppasswd_local are quite similar but still
+ * sufficiently different that merging them into one makes the code
+ * significantly less readable, IMHO, so we keep them separate.
+ */
+
+static int
+yppasswd_local(ypclnt_t *ypclnt, const struct passwd *pwd)
+{
+       struct master_yppasswd yppwd;
+       struct rpc_err rpcerr;
+       struct netconfig *nc = NULL;
+       void *localhandle = 0;
+       CLIENT *clnt = NULL;
+       int ret, *result;
+
+       /* fill the master_yppasswd structure */
+       memset(&yppwd, 0, sizeof yppwd);
+       yppwd.newpw.pw_uid = pwd->pw_uid;
+       yppwd.newpw.pw_gid = pwd->pw_gid;
+       yppwd.newpw.pw_change = pwd->pw_change;
+       yppwd.newpw.pw_expire = pwd->pw_expire;
+       yppwd.newpw.pw_fields = pwd->pw_fields;
+       yppwd.oldpass = strdup("");
+       yppwd.domain = strdup(ypclnt->domain);
+       if ((yppwd.newpw.pw_name = strdup(pwd->pw_name)) == NULL ||
+           (yppwd.newpw.pw_passwd = strdup(pwd->pw_passwd)) == NULL ||
+           (yppwd.newpw.pw_class = strdup(pwd->pw_class)) == NULL ||
+           (yppwd.newpw.pw_gecos = strdup(pwd->pw_gecos)) == NULL ||
+           (yppwd.newpw.pw_dir = strdup(pwd->pw_dir)) == NULL ||
+           (yppwd.newpw.pw_shell = strdup(pwd->pw_shell)) == NULL) {
+               ypclnt_error(ypclnt, __func__, strerror(errno));
+               ret = -1;
+               goto done;
+       }
+
+       /* connect to rpc.yppasswdd */
+       localhandle = setnetconfig();
+       while ((nc = getnetconfig(localhandle)) != NULL) {
+               if (nc->nc_protofmly != NULL &&
+                   strcmp(nc->nc_protofmly, NC_LOOPBACK) == 0)
+                       break;
+       }
+       if (nc == NULL) {
+               ypclnt_error(ypclnt, __func__,
+                   "getnetconfig: %s", nc_sperror());
+               ret = -1;
+               goto done;
+       }
+       if ((clnt = clnt_tp_create(NULL, MASTER_YPPASSWDPROG,
+           MASTER_YPPASSWDVERS, nc)) == NULL) {
+               ypclnt_error(ypclnt, __func__,
+                   "failed to connect to rpc.yppasswdd: %s",
+                   clnt_spcreateerror(ypclnt->server));
+               ret = -1;
+               goto done;
+       }
+       clnt->cl_auth = authunix_create_default();
+
+       /* request the update */
+       result = yppasswdproc_update_master_1(&yppwd, clnt);
+
+       /* check for RPC errors */
+       clnt_geterr(clnt, &rpcerr);
+       if (rpcerr.re_status != RPC_SUCCESS) {
+               ypclnt_error(ypclnt, __func__,
+                   "NIS password update failed: %s",
+                   clnt_sperror(clnt, ypclnt->server));
+               ret = -1;
+               goto done;
+       }
+
+       /* check the result of the update */
+       if (result == NULL || *result != 0) {
+               ypclnt_error(ypclnt, __func__,
+                   "NIS password update failed");
+               /* XXX how do we get more details? */
+               ret = -1;
+               goto done;
+       }
+
+       ypclnt_error(ypclnt, NULL, NULL);
+       ret = 0;
+
+ done:
+       if (clnt != NULL) {
+               auth_destroy(clnt->cl_auth);
+               clnt_destroy(clnt);
+       }
+       endnetconfig(localhandle);
+       free(yppwd.newpw.pw_name);
+       if (yppwd.newpw.pw_passwd != NULL) {
+               memset(yppwd.newpw.pw_passwd, 0, strlen(yppwd.newpw.pw_passwd));
+               free(yppwd.newpw.pw_passwd);
+       }
+       free(yppwd.newpw.pw_class);
+       free(yppwd.newpw.pw_gecos);
+       free(yppwd.newpw.pw_dir);
+       free(yppwd.newpw.pw_shell);
+       if (yppwd.oldpass != NULL) {
+               memset(yppwd.oldpass, 0, strlen(yppwd.oldpass));
+               free(yppwd.oldpass);
+       }
+       return (ret);
+}
+
+static int
+yppasswd_remote(ypclnt_t *ypclnt, const struct passwd *pwd, const char *passwd)
+{
+       struct yppasswd yppwd;
+       struct rpc_err rpcerr;
+       CLIENT *clnt = NULL;
+       int ret, *result;
+
+       /* fill the yppasswd structure */
+       memset(&yppwd, 0, sizeof yppwd);
+       yppwd.newpw.pw_uid = pwd->pw_uid;
+       yppwd.newpw.pw_gid = pwd->pw_gid;
+       if ((yppwd.newpw.pw_name = strdup(pwd->pw_name)) == NULL ||
+           (yppwd.newpw.pw_passwd = strdup(pwd->pw_passwd)) == NULL ||
+           (yppwd.newpw.pw_gecos = strdup(pwd->pw_gecos)) == NULL ||
+           (yppwd.newpw.pw_dir = strdup(pwd->pw_dir)) == NULL ||
+           (yppwd.newpw.pw_shell = strdup(pwd->pw_shell)) == NULL ||
+           (yppwd.oldpass = strdup(passwd ? passwd : "")) == NULL) {
+               ypclnt_error(ypclnt, __func__, strerror(errno));
+               ret = -1;
+               goto done;
+       }
+
+       /* connect to rpc.yppasswdd */
+       clnt = clnt_create(ypclnt->server, YPPASSWDPROG, YPPASSWDVERS, "udp");
+       if (clnt == NULL) {
+               ypclnt_error(ypclnt, __func__,
+                   "failed to connect to rpc.yppasswdd: %s",
+                   clnt_spcreateerror(ypclnt->server));
+               ret = -1;
+               goto done;
+       }
+       clnt->cl_auth = authunix_create_default();
+
+       /* request the update */
+       result = yppasswdproc_update_1(&yppwd, clnt);
+
+       /* check for RPC errors */
+       clnt_geterr(clnt, &rpcerr);
+       if (rpcerr.re_status != RPC_SUCCESS) {
+               ypclnt_error(ypclnt, __func__,
+                   "NIS password update failed: %s",
+                   clnt_sperror(clnt, ypclnt->server));
+               ret = -1;
+               goto done;
+       }
+
+       /* check the result of the update */
+       if (result == NULL || *result != 0) {
+               ypclnt_error(ypclnt, __func__,
+                   "NIS password update failed");
+               /* XXX how do we get more details? */
+               ret = -1;
+               goto done;
+       }
+
+       ypclnt_error(ypclnt, NULL, NULL);
+       ret = 0;
+
+ done:
+       if (clnt != NULL) {
+               auth_destroy(clnt->cl_auth);
+               clnt_destroy(clnt);
+       }
+       free(yppwd.newpw.pw_name);
+       if (yppwd.newpw.pw_passwd != NULL) {
+               memset(yppwd.newpw.pw_passwd, 0, strlen(yppwd.newpw.pw_passwd));
+               free(yppwd.newpw.pw_passwd);
+       }
+       free(yppwd.newpw.pw_gecos);
+       free(yppwd.newpw.pw_dir);
+       free(yppwd.newpw.pw_shell);
+       if (yppwd.oldpass != NULL) {
+               memset(yppwd.oldpass, 0, strlen(yppwd.oldpass));
+               free(yppwd.oldpass);
+       }
+       return (ret);
+}