summaryrefslogtreecommitdiff
path: root/nis
diff options
context:
space:
mode:
Diffstat (limited to 'nis')
-rw-r--r--nis/Banner2
-rw-r--r--nis/Makefile40
-rw-r--r--nis/TODO40
-rw-r--r--nis/nis_call.c220
-rw-r--r--nis/nis_clone.c551
-rw-r--r--nis/nis_error.c124
-rw-r--r--nis/nis_file.c108
-rw-r--r--nis/nis_free.c334
-rw-r--r--nis/nis_intern.c169
-rw-r--r--nis/nis_intern.h39
-rw-r--r--nis/nis_local_names.c184
-rw-r--r--nis/nis_names.c238
-rw-r--r--nis/nis_print.c308
-rw-r--r--nis/nis_server.c143
-rw-r--r--nis/nis_subr.c310
-rw-r--r--nis/nis_table.c417
-rw-r--r--nis/nis_xdr.c572
-rw-r--r--nis/nss-nisplus.h90
-rw-r--r--nis/nss_nis/nis-service.c4
-rw-r--r--nis/nss_nisplus/nisplus-alias.c251
-rw-r--r--nis/nss_nisplus/nisplus-ethers.c278
-rw-r--r--nis/nss_nisplus/nisplus-grp.c387
-rw-r--r--nis/nss_nisplus/nisplus-hosts.c412
-rw-r--r--nis/nss_nisplus/nisplus-netgrp.c141
-rw-r--r--nis/nss_nisplus/nisplus-network.c340
-rw-r--r--nis/nss_nisplus/nisplus-proto.c284
-rw-r--r--nis/nss_nisplus/nisplus-publickey.c347
-rw-r--r--nis/nss_nisplus/nisplus-pwd.c293
-rw-r--r--nis/nss_nisplus/nisplus-rpc.c284
-rw-r--r--nis/nss_nisplus/nisplus-service.c308
-rw-r--r--nis/nss_nisplus/nisplus-spwd.c262
-rw-r--r--nis/rpcsvc/nis.h1008
-rw-r--r--nis/rpcsvc/nis.x446
-rw-r--r--nis/rpcsvc/nis_object.x287
-rw-r--r--nis/rpcsvc/nis_tags.h95
-rw-r--r--nis/rpcsvc/nislib.h165
36 files changed, 9474 insertions, 7 deletions
diff --git a/nis/Banner b/nis/Banner
index 9ef1ded2d2..f03f4ea3f5 100644
--- a/nis/Banner
+++ b/nis/Banner
@@ -1 +1 @@
-NIS(YP) NSS modules 0.9 by Thorsten Kukuk
+NIS(YP)/NIS+ NSS modules 0.10 by Thorsten Kukuk
diff --git a/nis/Makefile b/nis/Makefile
index 98ef4090a2..31fda25a45 100644
--- a/nis/Makefile
+++ b/nis/Makefile
@@ -22,15 +22,15 @@
subdir := nis
headers := $(wildcard rpcsvc/*.[hx])
-distribute := nss-nis.h
+distribute := nss-nis.h nss-nisplus.h
# These are the databases available for the nis (and perhaps later nisplus)
# service. This must be a superset of the services in nss.
databases = proto service hosts network grp pwd rpc ethers \
spwd netgrp alias
-# Specify rules for the nss_* modules. Later we may have nisplus as well.
-services := nis compat
+# Specify rules for the nss_* modules.
+services := nis compat nisplus
extra-libs = libnsl $(services:%=libnss_%)
# These libraries will be built in the `others' pass rather than
@@ -41,7 +41,10 @@ extra-libs-others = $(extra-libs)
subdir-dirs = $(services:%=nss_%)
vpath %.c $(subdir-dirs)
-libnsl-routines = yp_xdr ypclnt ypupdate_xdr
+libnsl-routines = yp_xdr ypclnt ypupdate_xdr \
+ nis_subr nis_local_names nis_free nis_file \
+ nis_print nis_error nis_call nis_names nis_clone\
+ nis_table nis_xdr nis_intern nis_server
libnss_compat-routines := $(addprefix compat-,grp pwd spwd)
libnss_compat-inhibit-o = $(filter-out .so,$(object-suffixes))
@@ -49,6 +52,8 @@ libnss_compat-inhibit-o = $(filter-out .so,$(object-suffixes))
libnss_nis-routines := $(addprefix nis-,$(databases))
libnss_nis-inhibit-o = $(filter-out .so,$(object-suffixes))
+libnss_nisplus-routines := $(addprefix nisplus-,$(databases))
+libnss_nisplus-inhibit-o = $(filter-out .so,$(object-suffixes))
# Sun's header files are not too clean.
CFLAGS-compat-pwd.c = -Wno-strict-prototypes
@@ -69,6 +74,32 @@ CFLAGS-nis-spwd.c = -Wno-strict-prototypes
CFLAGS-ypclnt.c = -Wno-strict-prototypes -Wno-write-strings -Irpcsvc
CFLAGS-yp_xdr.c = -Wno-strict-prototypes -Irpcsvc
CFLAGS-ypupdate_xdr.c = -Wno-strict-prototypes -Irpcsvc
+# For the NIS+ Code
+CFLAGS-nis_call.c = -DNO_DES_RPC -Wno-strict-prototypes
+CFLAGS-nis_subr.c = -Wno-strict-prototypes
+CFLAGS-nis_local_names.c = -Wno-strict-prototypes
+CFLAGS-nis_free.c = -Wno-strict-prototypes
+CFLAGS-nis_file.c = -Wno-strict-prototypes
+CFLAGS-nis_print.c = -Wno-strict-prototypes
+CFLAGS-nis_error.c = -Wno-strict-prototypes
+CFLAGS-nis_names.c = -Wno-strict-prototypes
+CFLAGS-nis_clone.c = -Wno-strict-prototypes
+CFLAGS-nis_table.c = -Wno-strict-prototypes
+CFLAGS-nis_server.c = -Wno-strict-prototypes
+CFLAGS-nis_xdr.c = -Wno-strict-prototypes
+CFLAGS-nis_intern.c = -Wno-strict-prototypes
+CFLAGS-nisplus-alias.c = -Wno-strict-prototypes
+CFLAGS-nisplus-ethers.c = -Wno-strict-prototypes
+CFLAGS-nisplus-grp.c = -Wno-strict-prototypes
+CFLAGS-nisplus-hosts.c = -Wno-strict-prototypes
+CFLAGS-nisplus-netgrp.c = -Wno-strict-prototypes
+CFLAGS-nisplus-network.c = -Wno-strict-prototypes
+CFLAGS-nisplus-proto.c = -Wno-strict-prototypes
+CFLAGS-nisplus-publickey.c = -Wno-strict-prototypes
+CFLAGS-nisplus-pwd.c = -Wno-strict-prototypes
+CFLAGS-nisplus-rpc.c = -Wno-strict-prototypes
+CFLAGS-nisplus-service.c = -Wno-strict-prototypes
+CFLAGS-nisplus-spwd.c = -Wno-strict-prototypes
include ../Rules
@@ -77,6 +108,7 @@ $(objpfx)libnss_compat.so: $(objpfx)libnsl.so$(libnsl.so-version) \
$(common-objpfx)nss/libnss_files.so
$(objpfx)libnss_nis.so: $(objpfx)libnsl.so$(libnsl.so-version) \
$(common-objpfx)nss/libnss_files.so
+$(objpfx)libnss_nisplus.so: $(objpfx)libnsl.so$(libnsl.so-version)
# Depend on libc.so so a DT_NEEDED is generated in the shared objects.
# This ensures they will load libc.so for needed symbols if loaded by
diff --git a/nis/TODO b/nis/TODO
new file mode 100644
index 0000000000..9b675dfbc6
--- /dev/null
+++ b/nis/TODO
@@ -0,0 +1,40 @@
+
+ * nss_nisplus: When using parser form nss_files, rewrite parser
+
+ * compat could use data from nisplus, too. Implement this
+
+ * nis_server: implement nis_getservlist, nis_stats, nis_servstate
+
+ * nis_groups: implement it
+
+ * nis_ping: implement it
+
+ * __start_clock(), __stop_clock(): Test the interface and
+ implement it
+
+ * What does nis_list give back, if rpc.nisd is not running or
+ if /var/nis/NIS_START_FILE does not exist ?
+
+ * nis_table.c: nis_list():
+ Missing flags: FOLLOW_PATH, ALL_RESULTS
+ callback: Don't simulate it, use server callback thread
+
+ * Possible flags:
+ - FOLLOW_LINKS (nis_list, nis_lookup)
+ - FOLLOW_PATH (nis_list, not supported)
+ - HARD_LOOKUP (__do_niscall, not supported)
+ - ALL_RESULTS (nis_list, not supported, needs server callback)
+ - NO_CACHE (__do_niscall, cache not supported yet)
+ - MASTER_ONLY (__do_niscall, not supported)
+ - EXPAND_NAME (nis_lookup, nis_list)
+ - RETURN_RESULT (nis_table.c)
+ - ADD_OVERWRITE (nis_table.c)
+ - REM_MULTIPLE (nis_table.c)
+ - MOD_SAMEOBJ (nis_table.c)
+ - ADD_RESERVED (nis_table.c)
+ - REM_RESERVED (nis_table.c)
+ - MOD_EXCLUSIVE (nis_table.c)
+ - USE_DGRAM (__do_niscall)
+ - NO_AUTHINFO (__do_niscall)
+
+
diff --git a/nis/nis_call.c b/nis/nis_call.c
new file mode 100644
index 0000000000..cd1b6170d4
--- /dev/null
+++ b/nis/nis_call.c
@@ -0,0 +1,220 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <string.h>
+#include <rpc/rpc.h>
+#include <rpc/auth.h>
+#include <rpcsvc/nis.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include "nis_intern.h"
+
+static struct timeval TIMEOUT = {25, 0};
+static int const MAXTRIES = 3;
+
+static unsigned long
+inetstr2int (const char *str)
+{
+ char buffer[strlen (str) + 3];
+ size_t buflen;
+ size_t i, j;
+
+ buflen = stpcpy (buffer, str) - buffer;
+
+ j = 0;
+ for (i = 0; i < buflen; ++i)
+ if (buffer[i] == '.')
+ {
+ ++j;
+ if (j == 4)
+ {
+ buffer[i] = '\0';
+ break;
+ }
+ }
+
+ return inet_addr (buffer);
+}
+
+static CLIENT *
+__nis_dobind (const nis_server *server, u_long flags)
+{
+ struct sockaddr_in clnt_saddr;
+ int clnt_sock;
+ size_t i;
+ CLIENT *client = NULL;
+ /* XXX What is this variable for? */
+ void *out = NULL;
+
+ for (i = 0; i < server->ep.ep_len; i++)
+ {
+ memset (&clnt_saddr, '\0', sizeof clnt_saddr);
+ clnt_saddr.sin_family = AF_INET;
+ if (strcmp (server->ep.ep_val[i].family,"loopback") == 0)
+ {
+ if (server->ep.ep_val[i].uaddr[i] == '-')
+ clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ else
+ if (strcmp (server->ep.ep_val[i].proto,"udp") == 0)
+ {
+ if ((flags & USE_DGRAM) == USE_DGRAM)
+ clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ else
+ continue;
+ }
+ else
+ if (strcmp (server->ep.ep_val[i].proto,"tcp") == 0)
+ {
+ if ((flags & USE_DGRAM) == USE_DGRAM)
+ continue;
+ else
+ clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ }
+ }
+ else
+ if (strcmp (server->ep.ep_val[i].family,"inet") == 0)
+ {
+ if (server->ep.ep_val[i].uaddr[i] == '-')
+ clnt_saddr.sin_addr.s_addr =
+ inetstr2int (server->ep.ep_val[i].uaddr);
+ else
+ if (strcmp (server->ep.ep_val[i].proto,"udp") == 0)
+ {
+ if ((flags & USE_DGRAM) == USE_DGRAM)
+ clnt_saddr.sin_addr.s_addr =
+ inetstr2int (server->ep.ep_val[i].uaddr);
+ else
+ continue;
+ }
+ else
+ if (strcmp (server->ep.ep_val[i].proto,"tcp") == 0)
+ {
+ if ((flags & USE_DGRAM) == USE_DGRAM)
+ continue;
+ else
+ clnt_saddr.sin_addr.s_addr =
+ inetstr2int (server->ep.ep_val[i].uaddr);
+ }
+ }
+ else
+ continue;
+
+ clnt_sock = RPC_ANYSOCK;
+ if ((flags & USE_DGRAM) == USE_DGRAM)
+ client = clntudp_create (&clnt_saddr, NIS_PROG, NIS_VERSION,
+ TIMEOUT, &clnt_sock);
+ else
+ client = clnttcp_create (&clnt_saddr, NIS_PROG, NIS_VERSION,
+ &clnt_sock, 0, 0);
+
+ if (client == NULL)
+ continue;
+#if 1
+ if (clnt_call (client, 0, (xdrproc_t) xdr_void, NULL,
+ (xdrproc_t) xdr_void, out, TIMEOUT) != RPC_SUCCESS)
+ {
+ clnt_destroy (client);
+ continue;
+ }
+#endif
+ if ((flags & NO_AUTHINFO) != NO_AUTHINFO)
+ {
+#if !defined(NO_DES_RPC)
+ if (server->key_type == NIS_PK_DH)
+ {
+ char netname[MAXNETNAMELEN+1];
+ char *p;
+
+ strcpy (netname, "unix.");
+ strncat (netname, server->name,MAXNETNAMELEN-5);
+ netname[MAXNETNAMELEN-5] = '\0';
+ p = strchr (netname, '.');
+ *p = '@';
+ client->cl_auth =
+ authdes_pk_create (netname, &server->pkey, 300, NULL, NULL);
+ if (!client->cl_auth)
+ client->cl_auth = authunix_create_default ();
+ }
+ else
+#endif
+ client->cl_auth = authunix_create_default ();
+ }
+ return client;
+ }
+
+ return NULL;
+}
+
+nis_error
+__do_niscall (const nis_server *serv, int serv_len, u_long prog,
+ xdrproc_t xargs, caddr_t req, xdrproc_t xres, caddr_t resp,
+ u_long flags)
+{
+ CLIENT *clnt;
+ directory_obj *dir = NULL;
+ const nis_server *server;
+ int try, result, server_len;
+
+ if (serv == NULL || serv_len == 0)
+ {
+ dir = readColdStartFile ();
+ if (dir == NULL)
+ return NIS_UNAVAIL;
+ server = dir->do_servers.do_servers_val;
+ server_len = dir->do_servers.do_servers_len;
+ }
+ else
+ {
+ server = serv;
+ server_len = serv_len;
+ }
+
+ try = 0;
+ result = NIS_NAMEUNREACHABLE;
+
+ while (try < MAXTRIES && result != RPC_SUCCESS)
+ {
+ unsigned int i;
+
+ ++try;
+ for (i = 0; i < server_len; i++)
+ {
+ if ((clnt = __nis_dobind (&server[i], flags)) == NULL)
+ continue;
+
+ result = clnt_call (clnt, prog, xargs, req, xres, resp, TIMEOUT);
+
+ if (result != RPC_SUCCESS)
+ {
+ /* XXX Grrr. The cast is needed for now since Sun code does
+ note know about `const'. */
+ clnt_perror (clnt, (char *) "do_niscall: clnt_call");
+ clnt_destroy (clnt);
+ result = NIS_RPCERROR;
+ }
+ else
+ clnt_destroy (clnt);
+ }
+ }
+
+ if (dir != NULL)
+ nis_free_directory (dir);
+ return result;
+}
diff --git a/nis/nis_clone.c b/nis/nis_clone.c
new file mode 100644
index 0000000000..860abb386c
--- /dev/null
+++ b/nis/nis_clone.c
@@ -0,0 +1,551 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <string.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+directory_obj *
+nis_clone_directory (const directory_obj *src, directory_obj *dest)
+{
+ directory_obj *res;
+
+ if (src == NULL)
+ return NULL;
+
+ if (dest == NULL)
+ {
+ res = calloc (1, sizeof (directory_obj));
+ if (res == NULL)
+ return NULL;
+ }
+ else
+ res = dest;
+
+ if (src->do_name)
+ res->do_name = strdup (src->do_name);
+ else
+ res->do_name = NULL;
+ res->do_type = src->do_type;
+ if (src->do_servers.do_servers_len > 0)
+ {
+ size_t i;
+
+ res->do_servers.do_servers_len = src->do_servers.do_servers_len;
+ if ((res->do_servers.do_servers_val =
+ malloc (src->do_servers.do_servers_len * sizeof (nis_server)))
+ == NULL)
+ return NULL;
+
+ for (i = 0; i < src->do_servers.do_servers_len; ++i)
+ {
+ if (src->do_servers.do_servers_val[i].name != NULL)
+ res->do_servers.do_servers_val[i].name =
+ strdup (src->do_servers.do_servers_val[i].name);
+ else
+ res->do_servers.do_servers_val[i].name = NULL;
+
+ res->do_servers.do_servers_val[i].ep.ep_len =
+ src->do_servers.do_servers_val[i].ep.ep_len;
+ if (res->do_servers.do_servers_val[i].ep.ep_len > 0)
+ {
+ size_t j;
+
+ res->do_servers.do_servers_val[i].ep.ep_val =
+ malloc (src->do_servers.do_servers_val[i].ep.ep_len *
+ sizeof (endpoint));
+ for (j = 0; j < res->do_servers.do_servers_val[i].ep.ep_len; ++j)
+ {
+ if (src->do_servers.do_servers_val[i].ep.ep_val[j].uaddr)
+ res->do_servers.do_servers_val[i].ep.ep_val[j].uaddr
+ = strdup (src->do_servers.do_servers_val[i].ep.ep_val[j].uaddr);
+ else
+ res->do_servers.do_servers_val[i].ep.ep_val[j].uaddr = NULL;
+
+ if (src->do_servers.do_servers_val[i].ep.ep_val[j].family)
+ res->do_servers.do_servers_val[i].ep.ep_val[j].family
+ = strdup (src->do_servers.do_servers_val[i].ep.ep_val[j].family);
+ else
+ res->do_servers.do_servers_val[i].ep.ep_val[j].family = NULL;
+
+ if (src->do_servers.do_servers_val[i].ep.ep_val[j].proto)
+ res->do_servers.do_servers_val[i].ep.ep_val[j].proto
+ = strdup (src->do_servers.do_servers_val[i].ep.ep_val[j].proto);
+ else
+ res->do_servers.do_servers_val[i].ep.ep_val[j].proto = NULL;
+ }
+ }
+ else
+ {
+ res->do_servers.do_servers_val[i].ep.ep_val = NULL;
+ }
+ res->do_servers.do_servers_val[i].key_type =
+ src->do_servers.do_servers_val[i].key_type;
+ res->do_servers.do_servers_val[i].pkey.n_len =
+ src->do_servers.do_servers_val[i].pkey.n_len;
+ if (res->do_servers.do_servers_val[i].pkey.n_len > 0)
+ {
+ res->do_servers.do_servers_val[i].pkey.n_bytes =
+ malloc (src->do_servers.do_servers_val[i].pkey.n_len);
+ if (res->do_servers.do_servers_val[i].pkey.n_bytes == NULL)
+ return NULL;
+ memcpy (res->do_servers.do_servers_val[i].pkey.n_bytes,
+ src->do_servers.do_servers_val[i].pkey.n_bytes,
+ src->do_servers.do_servers_val[i].pkey.n_len);
+ }
+ else
+ res->do_servers.do_servers_val[i].pkey.n_bytes = NULL;
+ }
+ }
+ else
+ {
+ res->do_servers.do_servers_len = 0;
+ res->do_servers.do_servers_val = NULL;
+ }
+ res->do_ttl = src->do_ttl;
+ res->do_armask.do_armask_len = src->do_armask.do_armask_len;
+ if (res->do_armask.do_armask_len > 0)
+ {
+ if ((res->do_armask.do_armask_val =
+ malloc (src->do_armask.do_armask_len * sizeof (oar_mask))) == NULL)
+ return NULL;
+ memcpy (res->do_armask.do_armask_val, src->do_armask.do_armask_val,
+ src->do_armask.do_armask_len * sizeof (oar_mask));
+ }
+ else
+ {
+ res->do_armask.do_armask_val = NULL;
+ }
+
+ return res;
+}
+
+group_obj *
+nis_clone_group (const group_obj *src, group_obj *dest)
+{
+ size_t i;
+ group_obj *res = NULL;
+
+ if (src == NULL)
+ return NULL;
+
+ if (dest == NULL)
+ {
+ res = calloc (1, sizeof (group_obj));
+ if (res == NULL)
+ return NULL;
+ }
+ else
+ res = dest;
+
+ res->gr_flags = src->gr_flags;
+
+ res->gr_members.gr_members_len = src->gr_members.gr_members_len;
+ if (res->gr_members.gr_members_len > 0)
+ {
+ if (res->gr_members.gr_members_val == NULL)
+ {
+ res->gr_members.gr_members_val =
+ malloc (res->gr_members.gr_members_len * sizeof (nis_name));
+ if (res->gr_members.gr_members_val == NULL)
+ return NULL;
+ }
+ for (i = 0; i < res->gr_members.gr_members_len; ++i)
+ if (src->gr_members.gr_members_val[i] != NULL)
+ res->gr_members.gr_members_val[i] =
+ strdup (src->gr_members.gr_members_val[i]);
+ else
+ res->gr_members.gr_members_val[i] = NULL;
+ }
+
+ return res;
+}
+
+table_obj *
+nis_clone_table (const table_obj *src, table_obj *dest)
+{
+ size_t i;
+ table_obj *res = NULL;
+
+ if (src == NULL)
+ return NULL;
+
+ if (dest == NULL)
+ {
+ res = calloc (1, sizeof (table_obj));
+ if (res == NULL)
+ return res;
+ }
+ else
+ res = dest;
+
+ if (src->ta_type != NULL)
+ {
+ if ((res->ta_type = strdup (src->ta_type)) == NULL)
+ return NULL;
+ }
+ else
+ res->ta_type = NULL;
+
+ res->ta_maxcol = src->ta_maxcol;
+ res->ta_sep = src->ta_sep;
+ res->ta_cols.ta_cols_len = src->ta_cols.ta_cols_len;
+ if (res->ta_cols.ta_cols_val == NULL)
+ {
+ res->ta_cols.ta_cols_val =
+ malloc (src->ta_cols.ta_cols_len * sizeof (table_col));
+ if (res->ta_cols.ta_cols_val == NULL)
+ return NULL;
+ }
+ for (i = 0; i < res->ta_cols.ta_cols_len; i++)
+ {
+ if (src->ta_cols.ta_cols_val[i].tc_name == NULL)
+ res->ta_cols.ta_cols_val[i].tc_name = NULL;
+ else
+ res->ta_cols.ta_cols_val[i].tc_name =
+ strdup (src->ta_cols.ta_cols_val[i].tc_name);
+ res->ta_cols.ta_cols_val[i].tc_flags =
+ src->ta_cols.ta_cols_val[i].tc_flags;
+ res->ta_cols.ta_cols_val[i].tc_rights =
+ src->ta_cols.ta_cols_val[i].tc_rights;
+ }
+
+ if (src->ta_path != NULL)
+ {
+ if ((res->ta_path = strdup (src->ta_path)) == NULL)
+ return NULL;
+ }
+ else
+ res->ta_path = NULL;
+
+ return res;
+}
+
+entry_obj *
+nis_clone_entry (const entry_obj *src, entry_obj *dest)
+{
+ size_t i;
+ entry_obj *res = NULL;
+
+ if (src == NULL)
+ return NULL;
+
+ if (dest == NULL)
+ {
+ res = calloc (1, sizeof (entry_obj));
+ if (res == NULL)
+ return NULL;
+ }
+ else
+ res = dest;
+
+ if (src->en_type)
+ res->en_type = strdup (src->en_type);
+ else
+ res->en_type = NULL;
+
+ res->en_cols.en_cols_len = src->en_cols.en_cols_len;
+ if (res->en_cols.en_cols_val == NULL && src->en_cols.en_cols_len > 0)
+ {
+ res->en_cols.en_cols_val =
+ malloc (src->en_cols.en_cols_len * sizeof (entry_col));
+ if (res->en_cols.en_cols_val == NULL)
+ return NULL;
+ }
+ for (i = 0; i < res->en_cols.en_cols_len; ++i)
+ {
+ res->en_cols.en_cols_val[i].ec_flags =
+ src->en_cols.en_cols_val[i].ec_flags;
+ res->en_cols.en_cols_val[i].ec_value.ec_value_len =
+ src->en_cols.en_cols_val[i].ec_value.ec_value_len;
+ if (res->en_cols.en_cols_val[i].ec_value.ec_value_val == NULL &&
+ src->en_cols.en_cols_val[i].ec_value.ec_value_len > 0)
+ res->en_cols.en_cols_val[i].ec_value.ec_value_val =
+ malloc (src->en_cols.en_cols_val[i].ec_value.ec_value_len);
+ memcpy (res->en_cols.en_cols_val[i].ec_value.ec_value_val,
+ src->en_cols.en_cols_val[i].ec_value.ec_value_val,
+ res->en_cols.en_cols_val[i].ec_value.ec_value_len);
+ }
+
+ return res;
+}
+
+nis_attr *
+nis_clone_nis_attr (const nis_attr *src, nis_attr *dest)
+{
+ nis_attr *res = NULL;
+
+ if (src == NULL)
+ return NULL;
+
+ if (dest == NULL)
+ {
+ res = calloc (1, sizeof (nis_attr));
+ if (res == NULL)
+ return NULL;
+ }
+ else
+ res = dest;
+
+ if (src->zattr_ndx != NULL)
+ {
+ if ((res->zattr_ndx = strdup (src->zattr_ndx)) == NULL)
+ return NULL;
+ }
+ else
+ res->zattr_ndx = NULL;
+
+ res->zattr_val.zattr_val_len = src->zattr_val.zattr_val_len;
+ if (res->zattr_val.zattr_val_val == NULL)
+ {
+ res->zattr_val.zattr_val_val =
+ malloc (src->zattr_val.zattr_val_len);
+ if (res->zattr_val.zattr_val_val == NULL)
+ return NULL;
+ }
+ memcpy (res->zattr_val.zattr_val_val, src->zattr_val.zattr_val_val,
+ src->zattr_val.zattr_val_len);
+
+ return res;
+}
+
+static nis_attr *
+__nis_clone_attrs (const nis_attr *src, nis_attr *dest, u_int len)
+{
+ unsigned int i;
+ nis_attr *res;
+
+ if (len == 0)
+ return dest;
+
+ if (dest == NULL)
+ {
+ res = calloc (len, sizeof (nis_attr));
+ if (res == NULL)
+ return NULL;
+ }
+ else
+ res = dest;
+
+ for (i = 0; i < len; i++)
+ nis_clone_nis_attr(&src[i], &res[i]);
+
+ return res;
+}
+
+link_obj *
+nis_clone_link (const link_obj *src, link_obj *dest)
+{
+ link_obj *res = NULL;
+
+ if (src == NULL)
+ return NULL;
+
+ if (dest == NULL)
+ {
+ res = calloc (1, sizeof (link_obj));
+ if (res == NULL)
+ return NULL;
+ }
+ else
+ res = dest;
+
+ res->li_rtype = src->li_rtype;
+
+ res->li_attrs.li_attrs_len = src->li_attrs.li_attrs_len;
+ res->li_attrs.li_attrs_val =
+ __nis_clone_attrs (src->li_attrs.li_attrs_val,
+ res->li_attrs.li_attrs_val,
+ src->li_attrs.li_attrs_len);
+
+ if ((res->li_name = strdup (src->li_name)) == NULL)
+ return NULL;
+
+ return res;
+}
+
+objdata *
+nis_clone_objdata (const objdata *src, objdata *dest)
+{
+ objdata *res = NULL;
+
+ if (src == NULL)
+ return NULL;
+
+ if (dest == NULL)
+ {
+ res = calloc (1, sizeof (objdata));
+ if (res == NULL)
+ return res;
+ }
+ else
+ res = dest;
+
+ res->zo_type = src->zo_type;
+
+ switch (src->zo_type)
+ {
+ case BOGUS_OBJ:
+ break;
+ case NO_OBJ:
+ break;
+ case DIRECTORY_OBJ:
+ if (nis_clone_directory (&src->objdata_u.di_data,
+ &res->objdata_u.di_data) == NULL)
+ return NULL;
+ break;
+ case GROUP_OBJ:
+ if (nis_clone_group (&src->objdata_u.gr_data,
+ &res->objdata_u.gr_data) == NULL)
+ return NULL;
+ break;
+ case TABLE_OBJ:
+ if (nis_clone_table (&src->objdata_u.ta_data,
+ &res->objdata_u.ta_data) == NULL)
+ return NULL;
+ break;
+ case ENTRY_OBJ:
+ if (nis_clone_entry (&src->objdata_u.en_data,
+ &res->objdata_u.en_data) == NULL)
+ return NULL;
+ break;
+ case LINK_OBJ:
+ if (nis_clone_link (&src->objdata_u.li_data,
+ &res->objdata_u.li_data) == NULL)
+ return NULL;
+ break;
+ case PRIVATE_OBJ:
+ res->objdata_u.po_data.po_data_len =
+ src->objdata_u.po_data.po_data_len;
+ if (src->objdata_u.po_data.po_data_val)
+ {
+ res->objdata_u.po_data.po_data_val =
+ malloc (res->objdata_u.po_data.po_data_len);
+ if (res->objdata_u.po_data.po_data_val == NULL)
+ return NULL;
+ memcpy (res->objdata_u.po_data.po_data_val,
+ src->objdata_u.po_data.po_data_val,
+ src->objdata_u.po_data.po_data_len);
+ if (res->objdata_u.po_data.po_data_val == NULL)
+ return NULL;
+ }
+ else
+ {
+ res->objdata_u.po_data.po_data_val = NULL;
+ res->objdata_u.po_data.po_data_len = 0;
+ }
+ break;
+ default:
+ return NULL;
+ }
+
+ return res;
+}
+
+nis_object *
+nis_clone_object (const nis_object *src, nis_object *dest)
+{
+ nis_object *res = NULL;
+
+ if (src == NULL)
+ return NULL;
+
+ if (dest == NULL)
+ {
+ res = calloc (1, sizeof (nis_object));
+ if (res == NULL)
+ return NULL;
+ }
+ else
+ res = dest;
+
+ res->zo_oid = src->zo_oid;
+
+ if ((res->zo_name = strdup (src->zo_name)) == NULL)
+ return NULL;
+ if ((res->zo_owner = strdup (src->zo_owner)) == NULL)
+ return NULL;
+ if ((res->zo_group = strdup (src->zo_group)) == NULL)
+ return NULL;
+ if ((res->zo_domain = strdup (src->zo_domain)) == NULL)
+ return NULL;
+
+ res->zo_access = src->zo_access;
+ res->zo_ttl = src->zo_ttl;
+
+ if (nis_clone_objdata (&src->zo_data, &res->zo_data) == NULL)
+ return NULL;
+
+ return res;
+}
+
+static nis_object *
+__nis_clone_objects (const nis_object *src, nis_object *dest, u_int len)
+{
+ unsigned int i;
+ nis_object *res;
+
+ if (len == 0)
+ return dest;
+
+ if (dest == NULL)
+ {
+ res = calloc (len, sizeof (nis_object));
+ if (res == NULL)
+ return NULL;
+ }
+ else
+ res = dest;
+
+ for (i = 0; i < len; ++i)
+ nis_clone_object(&src[i], &res[i]);
+
+ return res;
+}
+
+nis_result *
+nis_clone_result (const nis_result *src, nis_result *dest)
+{
+ nis_result *res = NULL;
+
+ if (src == NULL)
+ return NULL;
+
+ if (dest == NULL)
+ {
+ res = calloc (1, sizeof (nis_result));
+ if (res == NULL)
+ return NULL;
+ }
+ else
+ res = dest;
+
+ res->status = src->status;
+ res->objects.objects_len = src->objects.objects_len;
+ res->objects.objects_val =
+ __nis_clone_objects (src->objects.objects_val,
+ res->objects.objects_val,
+ src->objects.objects_len);
+ res->zticks = src->zticks;
+ res->dticks = src->dticks;
+ res->aticks = src->aticks;
+ res->cticks = src->cticks;
+
+ return res;
+}
diff --git a/nis/nis_error.c b/nis/nis_error.c
new file mode 100644
index 0000000000..760dc518ab
--- /dev/null
+++ b/nis/nis_error.c
@@ -0,0 +1,124 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <errno.h>
+#include <syslog.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+
+static const char *nis_errlist[] =
+{
+ N_("Success"),
+ N_("Probable success"),
+ N_("Not found"),
+ N_("Probably not found"),
+ N_("Cache expired"),
+ N_("NIS+ servers unreachable"),
+ N_("Unknown object"),
+ N_("Server busy, try again"),
+ N_("Generic system error"),
+ N_("First/Next chain broken"),
+ N_("Permission denied"),
+ N_("Not owner"),
+ N_("Name not served by this server"),
+ N_("Server out of memory"),
+ N_("Object with same name exists"),
+ N_("Not master server for this domain"),
+ N_("Invalid Object for operation"),
+ N_("Malformed Name, or illegal name"),
+ N_("Unable to create callback"),
+ N_("Results Sent to callback proc"),
+ N_("Not Found, no such name"),
+ N_("Name/entry isn't unique"),
+ N_("Modification failed"),
+ N_("Database for table does not exist"),
+ N_("Entry/Table type mismatch"),
+ N_("Link Points to illegal name"),
+ N_("Partial Success"),
+ N_("Too Many Attributes"),
+ N_("Error in RPC subsystem"),
+ N_("Missing or malformed attribute"),
+ N_("Named object is not searchable"),
+ N_("Error while talking to callback proc"),
+ N_("Non NIS+ namespace encountered"),
+ N_("Illegal object type for operation"),
+ N_("Passed object is not the same object on server"),
+ N_("Modify operation failed"),
+ N_("Query illegal for named table"),
+ N_("Attempt to remove a non-empty table"),
+ N_("Error in accessing NIS+ cold start file. Is NIS+ installed?"),
+ N_("Full resync required for directory"),
+ N_("NIS+ operation failed"),
+ N_("NIS+ service is unavailable or not installed"),
+ N_("Yes, 42 is the meaning of life"),
+ N_("Unable to authenticate NIS+ server"),
+ N_("Unable to authenticate NIS+ client"),
+ N_("No file space on server"),
+ N_("Unable to create process on server"),
+ N_("Master server busy, full dump rescheduled.")
+};
+
+const char *
+nis_sperrno (const nis_error status)
+{
+ if (status >= (sizeof (nis_errlist) / sizeof (nis_errlist[0])))
+ return "???";
+ else
+ return gettext (nis_errlist[status]);
+}
+
+void
+nis_perror (const nis_error status, const char *label)
+{
+ fprintf (stderr, "%s: %s\n", label, nis_sperrno (status));
+}
+
+void
+nis_lerror (const nis_error status, const char *label)
+{
+ syslog (LOG_ERR, "%s: %s", label, nis_sperrno (status));
+}
+
+char *
+nis_sperror_r (const nis_error status, const char *label,
+ char *buffer, size_t buflen)
+{
+ const char *cptr;
+
+ cptr = nis_sperrno (status);
+
+ if ((strlen (cptr) + strlen (label) + 3) > buflen)
+ {
+ errno = ERANGE;
+ return NULL;
+ }
+
+ sprintf (buffer, "%s: %s", label, cptr);
+
+ return buffer;
+}
+
+char *
+nis_sperror (const nis_error status, const char *label)
+{
+ static char buffer[NIS_MAXNAMELEN +1];
+
+ return nis_sperror_r (status, label, buffer, sizeof (buffer));
+}
diff --git a/nis/nis_file.c b/nis/nis_file.c
new file mode 100644
index 0000000000..002e72ed20
--- /dev/null
+++ b/nis/nis_file.c
@@ -0,0 +1,108 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+directory_obj *
+readColdStartFile (void)
+{
+ XDR xdrs;
+ FILE *in;
+ directory_obj obj;
+
+ in = fopen ("/var/nis/NIS_COLD_START", "rb");
+ if (in == NULL)
+ {
+ fputs (_("Error: Could not open /var/nis/NIS_COLD_START!\n"), stdout);
+ return NULL;
+ }
+ memset (&obj, '\0', sizeof (obj));
+ xdrstdio_create (&xdrs, in, XDR_DECODE);
+ if (!xdr_directory_obj (&xdrs, &obj))
+ {
+ fputs (("Error while reading /var/nis/NIS_COLD_START!\n"), stdout);
+ return NULL;
+ }
+
+ return nis_clone_directory (&obj, NULL);
+}
+
+bool_t
+writeColdStartFile (const directory_obj *obj)
+{
+ XDR xdrs;
+ FILE *out;
+
+ out = fopen ("/var/nis/NIS_COLD_START", "wb");
+ if (out == NULL)
+ return FALSE;
+
+ xdrstdio_create (&xdrs, out, XDR_ENCODE);
+ /* XXX The following cast is bad! Shouldn't the XDR functions take
+ pointers to const objects? */
+ if (!xdr_directory_obj (&xdrs, (directory_obj *) obj))
+ {
+ fputs (_("Error while reading /var/nis/NIS_COLD_START!\n"), stdout);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+nis_object *
+nis_read_obj (const char *name)
+{
+ XDR xdrs;
+ FILE *in;
+ nis_object obj;
+
+ in = fopen (name, "rb");
+ if (in == NULL)
+ return NULL;
+
+ memset (&obj, '\0', sizeof (obj));
+ xdrstdio_create (&xdrs, in, XDR_DECODE);
+ if (!xdr_nis_object (&xdrs, &obj))
+ return NULL;
+
+ return nis_clone_object (&obj, NULL);
+}
+
+bool_t
+nis_write_obj (const char *name, const nis_object *obj)
+{
+ XDR xdrs;
+ FILE *out;
+
+ out = fopen (name, "wb");
+ if (out == NULL)
+ return FALSE;
+
+ xdrstdio_create (&xdrs, out, XDR_ENCODE);
+ /* XXX The following cast is bad! Shouldn't the XDR functions take
+ pointers to const objects? */
+ if (!xdr_nis_object (&xdrs, (nis_object *) obj))
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/nis/nis_free.c b/nis/nis_free.c
new file mode 100644
index 0000000000..35b7331372
--- /dev/null
+++ b/nis/nis_free.c
@@ -0,0 +1,334 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+void
+nis_free_attr (nis_attr *obj)
+{
+ if (obj == NULL)
+ return;
+
+ if (obj->zattr_ndx)
+ {
+ free (obj->zattr_ndx);
+ obj->zattr_ndx = NULL;
+ }
+
+ if (obj->zattr_val.zattr_val_val)
+ {
+ free (obj->zattr_val.zattr_val_val);
+ obj->zattr_val.zattr_val_val = NULL;
+ obj->zattr_val.zattr_val_len = 0;
+ }
+}
+
+void
+nis_free_request (ib_request *ibreq)
+{
+ unsigned int i;
+
+ for (i = 0; i < ibreq->ibr_srch.ibr_srch_len; ++i)
+ {
+ nis_free_attr (&(ibreq->ibr_srch.ibr_srch_val)[i]);
+ ibreq->ibr_srch.ibr_srch_val = NULL;
+ ibreq->ibr_srch.ibr_srch_len = 0;
+ }
+
+ if (ibreq->ibr_name)
+ {
+ free (ibreq->ibr_name);
+ ibreq->ibr_name = NULL;
+ }
+
+ if (ibreq->ibr_cookie.n_bytes)
+ {
+ free (ibreq->ibr_cookie.n_bytes);
+ ibreq->ibr_cookie.n_bytes = NULL;
+ ibreq->ibr_cookie.n_len = 0;
+ }
+}
+
+void
+nis_free_endpoints (endpoint *ep, int len)
+{
+ int i;
+
+ if (ep == NULL)
+ return;
+
+ for (i = 0; i < len; ++i)
+ {
+ if (ep[i].uaddr)
+ {
+ free (ep[i].uaddr);
+ ep[i].uaddr = NULL;
+ }
+ if (ep[i].family)
+ {
+ free (ep[i].family);
+ ep[i].family = NULL;
+ }
+ if (ep[i].proto)
+ {
+ free (ep[i].proto);
+ ep[i].proto = NULL;
+ }
+ }
+}
+
+void
+nis_free_servers (nis_server *obj, int len)
+{
+ int i;
+
+ if (obj == NULL)
+ return;
+
+ for (i = 0; i < len; i++)
+ {
+ if (obj[i].name)
+ {
+ free (obj[i].name);
+ obj[i].name = NULL;
+ }
+ if (obj[i].ep.ep_len > 0)
+ {
+ nis_free_endpoints (obj[i].ep.ep_val, obj[i].ep.ep_len);
+ free (obj[i].ep.ep_val);
+ obj[i].ep.ep_val = NULL;
+ obj[i].ep.ep_len = 0;
+ }
+ if (obj[i].pkey.n_bytes && obj[i].pkey.n_len > 0)
+ {
+ free (obj[i].pkey.n_bytes);
+ obj[i].pkey.n_bytes = NULL;
+ obj[i].pkey.n_len = 0;
+ }
+ }
+}
+
+void
+nis_free_directory (directory_obj *obj)
+{
+ if (obj == NULL)
+ return;
+ if (obj->do_name)
+ {
+ free (obj->do_name);
+ obj->do_name = NULL;
+ }
+ if (obj->do_servers.do_servers_len > 0)
+ {
+ nis_free_servers (obj->do_servers.do_servers_val,
+ obj->do_servers.do_servers_len);
+ free (obj->do_servers.do_servers_val);
+ obj->do_servers.do_servers_val = NULL;
+ obj->do_servers.do_servers_len = 0;
+ }
+ if (obj->do_armask.do_armask_len > 0)
+ {
+ free (obj->do_armask.do_armask_val);
+ obj->do_armask.do_armask_val = NULL;
+ obj->do_armask.do_armask_len = 0;
+ }
+}
+
+void
+nis_free_group (group_obj *obj)
+{
+ unsigned int i;
+
+ if (obj->gr_members.gr_members_len > 0)
+ {
+ for (i = 0; i < obj->gr_members.gr_members_len; ++i)
+ if (obj->gr_members.gr_members_val[i])
+ free (obj->gr_members.gr_members_val[i]);
+ free (obj->gr_members.gr_members_val);
+ obj->gr_members.gr_members_val = NULL;
+ obj->gr_members.gr_members_len = 0;
+ }
+}
+
+void
+nis_free_table (table_obj *obj)
+{
+ if (obj == NULL)
+ return;
+
+ if (obj->ta_type)
+ {
+ free (obj->ta_type);
+ obj->ta_type = NULL;
+ }
+
+ if (obj->ta_cols.ta_cols_val)
+ {
+ unsigned int i;
+
+ for (i = 0; i < obj->ta_cols.ta_cols_len; ++i)
+ if (obj->ta_cols.ta_cols_val[i].tc_name)
+ free (obj->ta_cols.ta_cols_val[i].tc_name);
+ free (obj->ta_cols.ta_cols_val);
+ obj->ta_cols.ta_cols_val = NULL;
+ obj->ta_cols.ta_cols_len = 0;
+ }
+
+ if (obj->ta_path)
+ {
+ free (obj->ta_path);
+ obj->ta_path = NULL;
+ }
+}
+
+void
+nis_free_entry (entry_obj *obj)
+{
+ if (obj == NULL)
+ return;
+
+ if (obj->en_type)
+ {
+ free (obj->en_type);
+ obj->en_type = 0;
+ }
+
+ if (obj->en_cols.en_cols_val)
+ {
+ unsigned int i;
+
+ for (i = 0; i < obj->en_cols.en_cols_len; ++i)
+ if (obj->en_cols.en_cols_val[i].ec_value.ec_value_val)
+ free (obj->en_cols.en_cols_val[i].ec_value.ec_value_val);
+ free (obj->en_cols.en_cols_val);
+ obj->en_cols.en_cols_val = NULL;
+ obj->en_cols.en_cols_len = 0;
+ }
+}
+
+void
+nis_free_link (link_obj *obj)
+{
+ if (obj == NULL)
+ return;
+
+ if (obj->li_attrs.li_attrs_val)
+ {
+ unsigned int i;
+
+ for (i = 0; i < obj->li_attrs.li_attrs_len; ++i)
+ {
+ if (obj->li_attrs.li_attrs_val[i].zattr_ndx)
+ free (obj->li_attrs.li_attrs_val[i].zattr_ndx);
+ if (obj->li_attrs.li_attrs_val[i].zattr_val.zattr_val_val)
+ free (obj->li_attrs.li_attrs_val[i].zattr_val.zattr_val_val);
+ }
+ free (obj->li_attrs.li_attrs_val);
+ obj->li_attrs.li_attrs_val = NULL;
+ obj->li_attrs.li_attrs_len = 0;
+ }
+
+ if (obj->li_name)
+ {
+ free (obj->li_name);
+ obj->li_name = NULL;
+ }
+}
+
+void
+nis_free_object (nis_object *obj)
+{
+
+ if (obj == NULL)
+ return;
+
+ if (obj->zo_name)
+ {
+ free (obj->zo_name);
+ obj->zo_name = NULL;
+ }
+ if (obj->zo_owner)
+ {
+ free (obj->zo_owner);
+ obj->zo_owner = NULL;
+ }
+ if (obj->zo_group)
+ {
+ free (obj->zo_group);
+ obj->zo_group = NULL;
+ }
+ if (obj->zo_domain)
+ {
+ free (obj->zo_domain);
+ obj->zo_domain = NULL;
+ }
+ switch (obj->zo_data.zo_type)
+ {
+ case BOGUS_OBJ:
+ break;
+ case NO_OBJ:
+ break;
+ case DIRECTORY_OBJ:
+ nis_free_directory (&obj->zo_data.objdata_u.di_data);
+ break;
+ case GROUP_OBJ:
+ nis_free_group (&obj->zo_data.objdata_u.gr_data);
+ break;
+ case TABLE_OBJ:
+ nis_free_table (&obj->zo_data.objdata_u.ta_data);
+ break;
+ case ENTRY_OBJ:
+ nis_free_entry (&obj->zo_data.objdata_u.en_data);
+ break;
+ case LINK_OBJ:
+ nis_free_link (&obj->zo_data.objdata_u.li_data);
+ break;
+ case PRIVATE_OBJ:
+ if (obj->zo_data.objdata_u.po_data.po_data_val)
+ {
+ free (obj->zo_data.objdata_u.po_data.po_data_val);
+ obj->zo_data.objdata_u.po_data.po_data_val = NULL;
+ }
+ break;
+ default:
+ break;
+ }
+ obj->zo_data.zo_type = NO_OBJ;
+}
+
+void
+nis_freeresult (nis_result *res)
+{
+ unsigned int i;
+
+ if (res == NULL)
+ return;
+
+ for (i = 0; i < res->objects.objects_len; i++)
+ nis_free_object (&(res->objects.objects_val)[i]);
+
+ if (res->objects.objects_val != NULL)
+ free (res->objects.objects_val);
+
+ if (res->cookie.n_bytes != NULL && res->cookie.n_len > 0)
+ free (res->cookie.n_bytes);
+
+ free (res);
+}
diff --git a/nis/nis_intern.c b/nis/nis_intern.c
new file mode 100644
index 0000000000..57019b3cfa
--- /dev/null
+++ b/nis/nis_intern.c
@@ -0,0 +1,169 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <string.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+#include "nis_intern.h"
+
+/* Nearly the same as nis_getnames, but nis_getnames stopped
+ when 2 points left */
+nis_name *
+__nis_expandname (const nis_name name)
+{
+ nis_name *getnames = NULL;
+ char local_domain[NIS_MAXNAMELEN + 1];
+ char *path, *cp;
+ int count, pos;
+
+ strncpy (local_domain, nis_local_directory (), NIS_MAXNAMELEN);
+ local_domain[NIS_MAXNAMELEN] = '\0';
+
+ count = 1;
+ if ((getnames = malloc ((count + 1) * sizeof (char *))) == NULL)
+ return NULL;
+
+ /* Do we have a fully qualified NIS+ name ? If yes, give it back */
+ if (name[strlen (name) - 1] == '.')
+ {
+ if ((getnames[0] = strdup (name)) == NULL)
+ {
+ free (getnames);
+ return NULL;
+ }
+ getnames[1] = NULL;
+
+ return getnames;
+ }
+
+ /* Get the search path, where we have to search "name" */
+ path = getenv ("NIS_PATH");
+ if (path == NULL)
+ path = strdupa ("$");
+ else
+ path = strdupa (path);
+
+ pos = 0;
+
+ cp = strtok (path, ":");
+ while (cp)
+ {
+ if (strcmp (cp, "$") == 0)
+ {
+ char *cptr = local_domain;
+ char *tmp;
+
+ while (*cptr != '\0')
+ {
+ if (pos >= count)
+ {
+ count += 5;
+ getnames = realloc (getnames, (count + 1) * sizeof (char *));
+ }
+ tmp = malloc (strlen (cptr) + strlen (local_domain) +
+ strlen (name) + 2);
+ if (tmp == NULL)
+ return NULL;
+
+ getnames[pos] = tmp;
+ tmp = stpcpy (tmp, name);
+ if (*cptr != '.')
+ *tmp++ = '.';
+ stpcpy (tmp, cptr);
+
+ ++pos;
+
+ ++cptr;
+ while ((*cptr != '\0') && (*cptr != '.'))
+ ++cptr;
+
+ if ((*cptr == '.') && (cptr[1] != '\0'))
+ ++cptr;
+ }
+ }
+ else
+ {
+ char *tmp;
+
+ if (cp[strlen (cp) - 1] == '$')
+ {
+ tmp = malloc (strlen (cp) + strlen (local_domain) +
+ strlen (name) + 2);
+ if (tmp == NULL)
+ return NULL;
+
+ getnames[pos] = tmp;
+ tmp = stpcpy (tmp, name);
+ *tmp++ = '.';
+ tmp = stpcpy (tmp, cp);
+ --tmp;
+ if (tmp[- 1] != '.')
+ *tmp++ = '.';
+ stpcpy (tmp, local_domain);
+ }
+ else
+ {
+ tmp = malloc (strlen (cp) + strlen (name) + 2);
+ if (tmp == NULL)
+ return NULL;
+
+ tmp = stpcpy (tmp, name);
+ *tmp++ = '.';
+ stpcpy (tmp, cp);
+ }
+
+ if (pos > count)
+ {
+ count += 5;
+ getnames = realloc (getnames, (count + 1) * sizeof (char *));
+ }
+ getnames[pos] = tmp;
+ pos++;
+ }
+ cp = strtok (NULL, ":");
+ }
+
+ getnames[pos] = NULL;
+
+ return getnames;
+}
+
+fd_result *
+__nis_finddirectoy (nis_name dir_name)
+{
+ fd_args args;
+ nis_error status;
+ fd_result *res;
+
+ args.dir_name = dir_name;
+ args.requester = nis_local_principal ();
+
+ res = calloc (1, sizeof (fd_result));
+ if (res == NULL)
+ return NULL;
+
+ if ((status = __do_niscall (NULL, 0, NIS_FINDDIRECTORY,
+ (xdrproc_t) xdr_fd_args,
+ (caddr_t) & args,
+ (xdrproc_t) xdr_fd_result,
+ (caddr_t) res, 0)) != RPC_SUCCESS)
+ res->status = status;
+
+ return res;
+}
diff --git a/nis/nis_intern.h b/nis/nis_intern.h
new file mode 100644
index 0000000000..b5fb605506
--- /dev/null
+++ b/nis/nis_intern.h
@@ -0,0 +1,39 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef __NIS_INTERN_H
+
+#define __NIS_INTERN_H
+#include <features.h>
+
+__BEGIN_DECLS
+
+extern nis_error __do_niscall (__const nis_server *server, int server_len,
+ u_long prog, xdrproc_t xargs, caddr_t req,
+ xdrproc_t xres, caddr_t resp, u_long flags);
+#if !defined(NO_DES_RPC)
+extern AUTH *authdes_pk_create (char *, netobj *, u_int,
+ struct sockaddr *, des_block *);
+#endif
+
+extern nis_name *__nis_expandname (__const nis_name);
+
+__END_DECLS
+
+#endif
diff --git a/nis/nis_local_names.c b/nis/nis_local_names.c
new file mode 100644
index 0000000000..50120a6f73
--- /dev/null
+++ b/nis/nis_local_names.c
@@ -0,0 +1,184 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+nis_name
+nis_local_group (void)
+{
+ static char __nisgroup[NIS_MAXNAMELEN + 1];
+
+ if (__nisgroup[0] == '\0')
+ {
+ char *cptr;
+
+ if ((cptr = getenv ("NIS_GROUP")) == NULL)
+ return __nisgroup;
+
+ if (strlen (cptr) >= NIS_MAXNAMELEN)
+ return __nisgroup;
+
+ strcpy (__nisgroup, cptr);
+
+ if (__nisgroup[strlen (__nisgroup) - 1] != '.')
+ {
+ cptr = nis_local_directory ();
+ if (strlen (__nisgroup) + strlen (cptr) + 1 < NIS_MAXNAMELEN)
+ {
+ strcat (__nisgroup, ".");
+ strcat (__nisgroup, cptr);
+ }
+ else
+ {
+ __nisgroup[0] = '\0';
+ return __nisgroup;
+ }
+ }
+ }
+
+ return __nisgroup;
+}
+
+
+nis_name
+nis_local_directory (void)
+{
+ static char __nisdomainname[NIS_MAXNAMELEN + 1];
+ int len;
+
+ if (__nisdomainname[0] == '\0')
+ {
+ if (getdomainname (__nisdomainname, NIS_MAXNAMELEN) < 0)
+ strcpy (__nisdomainname, "\0");
+ else
+ {
+ len = strlen (__nisdomainname);
+
+ /* Missing trailing dot? */
+ if (__nisdomainname[len - 1] != '.')
+ {
+ __nisdomainname[len] = '.';
+ __nisdomainname[len + 1] = '\0';
+ }
+ }
+ }
+
+ return __nisdomainname;
+}
+
+nis_name
+nis_local_principal (void)
+{
+ static char __principal[NIS_MAXNAMELEN + 1];
+
+ if (__principal[0] == '\0')
+ {
+ char buf[NIS_MAXNAMELEN + 1];
+ nis_result *res;
+ uid_t uid = geteuid ();
+
+ if (uid != 0)
+ {
+ snprintf (buf, NIS_MAXNAMELEN - 1,
+ "[auth_name=%d,auth_type=LOCAL],cred.org_dir.%s",
+ uid, nis_local_directory ());
+
+ if (buf[strlen (buf) - 1] != '.')
+ strcat (buf, ".");
+
+ res = nis_list (buf, USE_DGRAM + NO_AUTHINFO + FOLLOW_LINKS +
+ FOLLOW_PATH, NULL, NULL);
+
+ if (res == NULL)
+ {
+ strcpy (__principal, "nobody");
+ return __principal;
+ }
+
+ if (res->status == NIS_SUCCESS)
+ {
+ if (res->objects.objects_len > 1)
+ {
+ /* More than one principal with same uid? something
+ wrong with cred table. Should be unique Warn user
+ and continue. */
+ printf (_("\
+LOCAL entry for UID %d in directory %s not unique\n"),
+ uid, nis_local_directory ());
+ }
+ strcpy (__principal, ENTRY_VAL (res->objects.objects_val, 0));
+ nis_freeresult (res);
+ return __principal;
+ }
+ else
+ {
+ nis_freeresult (res);
+ strcpy (__principal, "nobody");
+ return __principal;
+ }
+ }
+ else
+ {
+ strcpy (__principal, nis_local_host ());
+ return __principal;
+ }
+
+ /* Should be never reached */
+ strcpy (__principal, "nobody");
+ return __principal;
+ }
+ return __principal;
+}
+
+nis_name
+nis_local_host (void)
+{
+ static char __nishostname[NIS_MAXNAMELEN + 1];
+ int len;
+
+ if (__nishostname[0] == '\0')
+ {
+ char *cp = __nishostname;
+
+ if (gethostname (__nishostname, NIS_MAXNAMELEN) < 0)
+ cp = stpcpy (cp, "\0");
+
+ len = cp - __nishostname;
+
+ /* Hostname already fully qualified? */
+ if (__nishostname[len - 1] == '.')
+ return __nishostname;
+
+ if (strlen (__nishostname + strlen (nis_local_directory ()) + 1) >
+ NIS_MAXNAMELEN)
+ {
+ __nishostname[0] = '\0';
+ return __nishostname;
+ }
+
+ *cp++ = '.';
+ stpcpy (cp, nis_local_directory ());
+ }
+
+ return __nishostname;
+}
diff --git a/nis/nis_names.c b/nis/nis_names.c
new file mode 100644
index 0000000000..92f8040b3d
--- /dev/null
+++ b/nis/nis_names.c
@@ -0,0 +1,238 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <string.h>
+#include <rpc/rpc.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+#include "nis_intern.h"
+
+nis_result *
+nis_lookup (const nis_name name, const u_long flags)
+{
+ nis_result *res;
+ struct ns_request req;
+ nis_name *names;
+ nis_error status;
+ int is_link = 1; /* We should go at least once in the while loop */
+ int count_links = 0; /* We will follow only 16 links in the deep */
+ int i;
+
+ res = calloc (1, sizeof (nis_result));
+
+ if (flags & EXPAND_NAME)
+ {
+ names = __nis_expandname (name);
+ if (names == NULL)
+ {
+ res->status = NIS_NAMEUNREACHABLE;
+ return res;
+ }
+
+ i = 0;
+ while (names[i] != NULL && (i == 0 || res->status > 1))
+ {
+ req.ns_name = names[i];
+
+ while (is_link)
+ {
+ req.ns_object.ns_object_len = 0;
+ req.ns_object.ns_object_val = NULL;
+ memset (res, '\0', sizeof (nis_result));
+
+ if ((status = __do_niscall (NULL, 0, NIS_LOOKUP,
+ (xdrproc_t) xdr_ns_request,
+ (caddr_t) & req,
+ (xdrproc_t) xdr_nis_result,
+ (caddr_t) res, flags)) != RPC_SUCCESS)
+ {
+ res->status = status;
+ nis_freenames (names);
+ return res;
+ }
+
+ if ((res->status == NIS_SUCCESS || res->status == NIS_S_SUCCESS)
+ && (res->objects.objects_len > 0 &&
+ res->objects.objects_val->zo_data.zo_type == LINK_OBJ))
+ is_link = 1;
+ else
+ is_link = 0;
+
+ if (is_link)
+ {
+ if ((flags & FOLLOW_LINKS) == FOLLOW_LINKS)
+ {
+ if (count_links == 16)
+ {
+ res->status = NIS_LINKNAMEERROR;
+ return res;
+ }
+ else
+ ++count_links;
+
+ req.ns_name = res->objects.objects_val->LI_data.li_name;
+ }
+ else
+ {
+ res->status = NIS_NOTSEARCHABLE;
+ return res;
+ }
+ }
+ }
+
+ ++i;
+ if (res->status == NIS_NOT_ME)
+ res->status = NIS_NOSUCHNAME;
+ }
+
+ nis_freenames (names);
+ }
+ else
+ {
+ req.ns_name = name;
+
+ while (is_link)
+ {
+ req.ns_object.ns_object_len = 0;
+ req.ns_object.ns_object_val = NULL;
+ memset (res, '\0', sizeof (nis_result));
+
+ if ((status = __do_niscall (NULL, 0, NIS_LOOKUP,
+ (xdrproc_t) xdr_ns_request,
+ (caddr_t) & req,
+ (xdrproc_t) xdr_nis_result,
+ (caddr_t) res, flags)) != RPC_SUCCESS)
+ {
+ res->status = status;
+ return res;
+ }
+
+ if ((res->status == NIS_SUCCESS || res->status == NIS_S_SUCCESS) &&
+ (res->objects.objects_len > 0 &&
+ res->objects.objects_val->zo_data.zo_type == LINK_OBJ))
+ is_link = 1;
+ else
+ is_link = 0;
+
+ if (is_link)
+ {
+ if ((flags & FOLLOW_LINKS) == FOLLOW_LINKS)
+ {
+ if (count_links == 16)
+ {
+ res->status = NIS_LINKNAMEERROR;
+ return res;
+ }
+ else
+ ++count_links;
+
+ req.ns_name = res->objects.objects_val->LI_data.li_name;
+ }
+ else
+ {
+ res->status = NIS_NOTSEARCHABLE;
+ return res;
+ }
+ }
+ }
+ }
+
+ return res;
+}
+
+nis_result *
+nis_add (const nis_name name, const nis_object *obj)
+{
+ nis_result *res;
+ nis_error status;
+ struct ns_request req;
+
+ res = calloc (1, sizeof (nis_result));
+
+ req.ns_name = name;
+
+ req.ns_object.ns_object_len = 1;
+ req.ns_object.ns_object_val = nis_clone_object (obj, NULL);
+
+ if ((status = __do_niscall (NULL, 0, NIS_ADD, (xdrproc_t) xdr_ns_request,
+ (caddr_t) & req, (xdrproc_t) xdr_nis_result,
+ (caddr_t) res, 0)) != RPC_SUCCESS)
+ res->status = status;
+
+ nis_destroy_object (req.ns_object.ns_object_val);
+
+ return res;
+}
+
+nis_result *
+nis_remove (const nis_name name, const nis_object *obj)
+{
+ nis_result *res;
+ nis_error status;
+ struct ns_request req;
+
+ res = calloc (1, sizeof (nis_result));
+
+ req.ns_name = name;
+
+ if (obj != NULL)
+ {
+ req.ns_object.ns_object_len = 1;
+ req.ns_object.ns_object_val = nis_clone_object (obj, NULL);
+ }
+ else
+ {
+ req.ns_object.ns_object_len = 0;
+ req.ns_object.ns_object_val = NULL;
+ }
+
+ if ((status = __do_niscall (NULL, 0, NIS_REMOVE, (xdrproc_t) xdr_ns_request,
+ (caddr_t) & req, (xdrproc_t) xdr_nis_result,
+ (caddr_t) res, 0)) != RPC_SUCCESS)
+ res->status = status;
+
+ nis_destroy_object (req.ns_object.ns_object_val);
+
+ return res;
+}
+
+nis_result *
+nis_modify (const nis_name name, const nis_object *obj)
+{
+ nis_result *res;
+ nis_error status;
+ struct ns_request req;
+
+ res = calloc (1, sizeof (nis_result));
+
+ req.ns_name = name;
+
+ req.ns_object.ns_object_len = 1;
+ req.ns_object.ns_object_val = nis_clone_object (obj, NULL);
+
+ if ((status = __do_niscall (NULL, 0, NIS_REMOVE, (xdrproc_t) xdr_ns_request,
+ (caddr_t) & req, (xdrproc_t) xdr_nis_result,
+ (caddr_t) res, 0)) != RPC_SUCCESS)
+ res->status = status;
+
+ nis_destroy_object (req.ns_object.ns_object_val);
+
+ return res;
+}
diff --git a/nis/nis_print.c b/nis/nis_print.c
new file mode 100644
index 0000000000..e6eb264ae7
--- /dev/null
+++ b/nis/nis_print.c
@@ -0,0 +1,308 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <time.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+static const char *
+nis_nstype2str (const nstype type)
+{
+ switch (type)
+ {
+ case NIS:
+ return N_("NIS");
+ case SUNYP:
+ return N_("SUNYP");
+ case IVY:
+ return N_("IVY");
+ case DNS:
+ return N_("DNS");
+ case X500:
+ return N_("X500");
+ case DNANS:
+ return N_("DNANS");
+ case XCHS:
+ return N_("XCHS");
+ case CDS:
+ return N_("CDS");
+ default:
+ return N_("UNKNOWN");
+ }
+}
+
+static char *
+nis_ttl2str (const u_long ttl)
+{
+ static char buf[64];
+ unsigned long int time, s, m, h;
+
+ time = ttl;
+
+ h = time / (60 * 60);
+ time %= (60 * 60);
+ m = time / 60;
+ time %= 60;
+ s = time;
+ snprintf (buf, 63, "%lu:%02lu:%02lu", h, m, s);
+
+ return buf;
+}
+
+static char *
+nis_flags2str (const u_long flags)
+{
+ static char buf[1024];
+
+ snprintf (buf, 1023, "%lu", flags);
+
+ return buf;
+}
+
+void
+nis_print_rights (const u_long access)
+{
+ char result[17];
+ u_long acc;
+ int i;
+
+ acc = access; /* Parameter is const ! */
+ result[i = 16] = '\0';
+ while (i > 0)
+ {
+ i -= 4;
+ result[i + 0] = (acc & NIS_READ_ACC) ? 'r' : '-';
+ result[i + 1] = (acc & NIS_MODIFY_ACC) ? 'm' : '-';
+ result[i + 2] = (acc & NIS_CREATE_ACC) ? 'c' : '-';
+ result[i + 3] = (acc & NIS_DESTROY_ACC) ? 'd' : '-';
+
+ acc >>= 8;
+ }
+ printf ("%s", result);
+}
+
+void
+nis_print_directory (const directory_obj *dir)
+{
+ nis_server *sptr;
+ unsigned int i;
+
+ printf (_("Name : '%s'\n"), dir->do_name);
+ printf (_("Type : %s\n"), gettext (nis_nstype2str (dir->do_type)));
+ sptr = dir->do_servers.do_servers_val;
+ for (i = 0; i < dir->do_servers.do_servers_len; i++)
+ {
+ if (i == 0)
+ fputs (_("Master Server :\n"), stdout);
+ else
+ fputs (_("Replicate :\n"), stdout);
+ printf (_("\tName : %s\n"), sptr->name);
+ fputs (_("\tPublic Key : "), stdout);
+ switch (sptr->key_type)
+ {
+ case NIS_PK_NONE:
+ fputs (_("None.\n"), stdout);
+ break;
+ case NIS_PK_DH:
+ fputs (_("DH.\n"), stdout);
+ break;
+ case NIS_PK_RSA:
+ fputs (_("RSA.\n"), stdout);
+ break;
+ case NIS_PK_KERB:
+ fputs (_("Kerberous.\n"), stdout);
+ break;
+ default:
+ fputs (_("Unknown.\n"), stdout);
+ break;
+ }
+
+ if (sptr->ep.ep_len != 0)
+ {
+ unsigned int j;
+
+ endpoint *ptr;
+ ptr = sptr->ep.ep_val;
+ printf (_("\tUniversal addresses (%u)\n"), sptr->ep.ep_len);
+ for (j = 0; j < sptr->ep.ep_len; j++)
+ {
+ printf ("\t[%d] - ", j + 1);
+ if (ptr->proto != NULL && strlen (ptr->proto) > 0)
+ printf ("%s, ", ptr->proto);
+ else
+ printf ("-, ");
+ if (ptr->family != NULL && strlen (ptr->family) > 0)
+ printf ("%s, ", ptr->family);
+ else
+ printf ("-, ");
+ if (ptr->uaddr != NULL && strlen (ptr->uaddr) > 0)
+ printf ("%s\n", ptr->uaddr);
+ else
+ printf ("-\n");
+ ptr++;
+ }
+ }
+ sptr++;
+ }
+
+ printf (_("Time to live : %s\n"), nis_ttl2str (dir->do_ttl));
+ if (dir->do_armask.do_armask_len != 0)
+ {
+ oar_mask *ptr;
+
+ ptr = dir->do_armask.do_armask_val;
+ for (i = 0; i < dir->do_armask.do_armask_len; i++)
+ {
+ fputs (_("Default Access rights: "), stdout);
+ nis_print_rights (ptr->oa_rights);
+ printf (_("\nDirect Type : %d\n"), ptr->oa_otype);
+ ptr++;
+ }
+ }
+}
+
+void
+nis_print_group (const group_obj *obj)
+{
+ unsigned int i;
+
+ fputs (_("Group Flags :"), stdout);
+ if (obj->gr_flags)
+ printf ("0x%08lX", obj->gr_flags);
+ fputs (_("\nGroup Members :\n"), stdout);
+
+ for (i = 0; i < obj->gr_members.gr_members_len; i++)
+ printf ("\t%s\n", obj->gr_members.gr_members_val[i]);
+}
+
+void
+nis_print_table (const table_obj *obj)
+{
+ unsigned int i;
+
+ printf (_("Table Type : %s\n"), obj->ta_type);
+ printf (_("Number of Columns : %d\n"), obj->ta_maxcol);
+ printf (_("Character Separator : %c\n"), obj->ta_sep);
+ printf (_("Search Path : %s\n"), obj->ta_path);
+ fputs (_("Columns :\n"), stdout);
+ for (i = 0; i < obj->ta_cols.ta_cols_len; i++)
+ {
+ printf (_("\t[%d]\tName : %s\n"), i,
+ obj->ta_cols.ta_cols_val[i].tc_name);
+ printf (_("\t\tAttributes : %s\n"),
+ nis_flags2str (obj->ta_cols.ta_cols_val[i].tc_flags));
+ fputs (_("\t\tAccess Rights : "), stdout);
+ nis_print_rights (obj->ta_cols.ta_cols_val[i].tc_rights);
+ fputc ('\n', stdout);
+ }
+}
+
+void
+nis_print_link (const link_obj *obj)
+{
+ printf (_("Type : %d\n"), obj->li_rtype);
+ printf (_("Name : %s\n"), obj->li_name);
+ printf (_("Attributes : %d\n"), obj->li_attrs.li_attrs_len);
+}
+
+void
+nis_print_entry (const entry_obj *obj)
+{
+ unsigned int i;
+
+ printf (_("\tEntry data of type %s\n"), obj->en_type);
+ for (i = 0; i < obj->en_cols.en_cols_len; i++)
+ {
+ printf (_("\t[%u] - [%u bytes] "), i,
+ obj->en_cols.en_cols_val[i].ec_value.ec_value_len);
+ if ((obj->en_cols.en_cols_val[i].ec_flags & EN_CRYPT) == EN_CRYPT)
+ fputs (_("Encrypted data\n"), stdout);
+ else if ((obj->en_cols.en_cols_val[i].ec_flags & EN_BINARY) == EN_BINARY)
+ fputs (_("Binary data\n"), stdout);
+ else
+ printf ("%s\n", obj->en_cols.en_cols_val[i].ec_value.ec_value_val);
+ }
+}
+
+void
+nis_print_object (const nis_object * obj)
+{
+ printf (_("Object Name : %s\n"), obj->zo_name);
+ printf (_("Directory : %s\n"), obj->zo_domain);
+ printf (_("Owner : %s\n"), obj->zo_owner);
+ printf (_("Group : %s\n"), obj->zo_group);
+ fputs (_("Access Rights : "), stdout);
+ nis_print_rights (obj->zo_access);
+ printf (_("\nTime to Live : %lu (seconds)\n"), obj->zo_ttl);
+ printf (_("Creation Time : %s"), ctime (&obj->zo_oid.ctime));
+ printf (_("Mod. Time : %s"), ctime (&obj->zo_oid.mtime));
+ fputs (_("Object Type : "), stdout);
+ switch (obj->zo_data.zo_type)
+ {
+ case BOGUS_OBJ:
+ fputs (_("BOGUS OBJECT\n"), stdout);
+ break;
+ case NO_OBJ:
+ fputs (_("NO OBJECT\n"), stdout);
+ break;
+ case DIRECTORY_OBJ:
+ fputs (_("DIRECTORY\n"), stdout);
+ nis_print_directory (&obj->zo_data.objdata_u.di_data);
+ break;
+ case GROUP_OBJ:
+ fputs (_("GROUP\n"), stdout);
+ nis_print_group (&obj->zo_data.objdata_u.gr_data);
+ break;
+ case TABLE_OBJ:
+ fputs (_("TABLE\n"), stdout);
+ nis_print_table (&obj->zo_data.objdata_u.ta_data);
+ break;
+ case ENTRY_OBJ:
+ fputs (_("ENTRY\n"), stdout);
+ nis_print_entry (&obj->zo_data.objdata_u.en_data);
+ break;
+ case LINK_OBJ:
+ fputs (_("LINK\n"), stdout);
+ nis_print_link (&obj->zo_data.objdata_u.li_data);
+ break;
+ case PRIVATE_OBJ:
+ fputs (_("PRIVATE\n"), stdout);
+ printf (_(" Data Length = %u\n"),
+ obj->zo_data.objdata_u.po_data.po_data_len);
+ break;
+ default:
+ fputs (_("(Unknown object)\n"), stdout);
+ break;
+ }
+}
+
+void
+nis_print_result (const nis_result *res)
+{
+ unsigned int i;
+
+ printf (_("Status : %s\n"), nis_sperrno (res->status));
+ printf (_("Number of objects : %u\n"), res->objects.objects_len);
+
+ for (i = 0; i < res->objects.objects_len; i++)
+ {
+ printf (_("Object #%d:\n"), i);
+ nis_print_object (&res->objects.objects_val[i]);
+ }
+}
diff --git a/nis/nis_server.c b/nis/nis_server.c
new file mode 100644
index 0000000000..48d2144c78
--- /dev/null
+++ b/nis/nis_server.c
@@ -0,0 +1,143 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+#include "nis_intern.h"
+
+nis_error
+nis_mkdir (const nis_name dir, const nis_server *server)
+{
+ nis_error res;
+
+ if (server == NULL)
+ {
+ int result;
+ if ((result = __do_niscall (NULL, 0, NIS_MKDIR, (xdrproc_t) xdr_nis_name,
+ (caddr_t) dir, (xdrproc_t) xdr_nis_error,
+ (caddr_t) & res, 0)) != RPC_SUCCESS)
+ {
+ fprintf (stderr, _("__do_niscall: Error #%d\n"), result);
+ return NIS_RPCERROR;
+ }
+ }
+ else
+ {
+ int result;
+ if ((result = __do_niscall (server, 1, NIS_MKDIR,
+ (xdrproc_t) xdr_nis_name,
+ (caddr_t) dir, (xdrproc_t) xdr_nis_error,
+ (caddr_t) & res, 0)) != RPC_SUCCESS)
+ {
+ fprintf (stderr, _("__do_niscall: Error #%d\n"), result);
+ return NIS_RPCERROR;
+ }
+ }
+
+ return res;
+}
+
+nis_error
+nis_rmdir (const nis_name dir, const nis_server *server)
+{
+ nis_error res;
+
+ if (server == NULL)
+ {
+ int result;
+ if ((result = __do_niscall (NULL, 0, NIS_RMDIR, (xdrproc_t) xdr_nis_name,
+ (caddr_t) dir, (xdrproc_t) xdr_nis_error,
+ (caddr_t) & res, 0)) != RPC_SUCCESS)
+ {
+ fprintf (stderr, _("__do_niscall: Error #%d\n"), result);
+ return NIS_RPCERROR;
+ }
+ }
+ else
+ {
+ int result;
+ if ((result = __do_niscall (server, 1, NIS_RMDIR,
+ (xdrproc_t) xdr_nis_name,
+ (caddr_t) dir, (xdrproc_t) xdr_nis_error,
+ (caddr_t) & res, 0)) != RPC_SUCCESS)
+ {
+ fprintf (stderr, _("__do_niscall: Error #%d\n"), result);
+ return NIS_RPCERROR;
+ }
+ }
+
+ return res;
+}
+
+nis_error
+nis_servstate (const nis_server *serv, const nis_tag *tags,
+ const int numtags, nis_tag **result)
+{
+ *result = NULL;
+ return NIS_FAIL;
+}
+stub_warning (nis_servstate)
+
+nis_error
+nis_stats (const nis_server *serv, const nis_tag *tags,
+ const int numtags, nis_tag **result)
+{
+ result = malloc (sizeof (nis_tag *));
+ if (result != NULL)
+ result[0] = NULL;
+ return NIS_FAIL;
+}
+stub_warning (nis_stats);
+
+void
+nis_freetags (nis_tag *tags, const int numtags)
+{
+ int i;
+
+ for (i = 0; i < numtags; ++i)
+ free (tags->tag_val);
+ free (tags);
+}
+
+nis_server **
+nis_getservlist (const nis_name dir)
+{
+ nis_server **serv;
+
+ serv = malloc (sizeof (nis_server *));
+ if (serv != NULL)
+ serv[0] = NULL;
+
+ return serv;
+}
+stub_warning (nis_getservlist);
+
+void
+nis_freeservlist (nis_server **serv)
+{
+ int i;
+
+ if (serv == NULL)
+ return;
+
+ i = 0;
+ while (serv[i] != NULL)
+ nis_free_servers (serv[i], 1);
+ free (serv);
+}
diff --git a/nis/nis_subr.c b/nis/nis_subr.c
new file mode 100644
index 0000000000..74eb0b5c77
--- /dev/null
+++ b/nis/nis_subr.c
@@ -0,0 +1,310 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <errno.h>
+#include <string.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+nis_name
+nis_leaf_of (const nis_name name)
+{
+ static char result[NIS_MAXNAMELEN + 1];
+
+ return nis_leaf_of_r (name, result, NIS_MAXNAMELEN);
+}
+
+nis_name
+nis_leaf_of_r (const nis_name name, char *buffer, size_t buflen)
+{
+ size_t i = 0;
+
+ buffer[0] = '\0';
+
+ while (name[i] != '.' && name[i] != '\0')
+ i++;
+
+ if (i > buflen - 1)
+ {
+ errno = ERANGE;
+ return NULL;
+ }
+
+ if (i > 1)
+ strncpy (buffer, name, i - 1);
+
+ return buffer;
+}
+
+nis_name
+nis_name_of (const nis_name name)
+{
+ static char result[NIS_MAXNAMELEN + 1];
+
+ return nis_name_of_r (name, result, NIS_MAXNAMELEN);
+}
+
+nis_name
+nis_name_of_r (const nis_name name, char *buffer, size_t buflen)
+{
+ char *local_domain;
+ int diff;
+
+ local_domain = nis_local_directory ();
+
+ diff = strlen (name) - strlen (local_domain);
+ if (diff <= 0)
+ return NULL;
+
+ if (strcmp (&name[diff], local_domain) != 0)
+ return NULL;
+
+ if ((size_t) diff >= buflen)
+ {
+ errno = ERANGE;
+ return NULL;
+ }
+ memcpy (buffer, name, diff - 1);
+ buffer[diff - 1] = '\0';
+
+ if (diff - 1 == 0)
+ return NULL;
+
+ return buffer;
+}
+
+nis_name
+nis_domain_of (const nis_name name)
+{
+ static char result[NIS_MAXNAMELEN + 1];
+
+ return nis_domain_of_r (name, result, NIS_MAXNAMELEN);
+}
+
+nis_name
+nis_domain_of_r (const nis_name name, char *buffer, size_t buflen)
+{
+ char *cptr;
+ size_t cptr_len;
+
+ cptr = strchr (name, '.'); /* XXX What happens if the NIS name
+ does not contain a `.'? */
+ ++cptr;
+ cptr_len = strlen (cptr);
+
+ if (cptr_len == 0)
+ strcpy (buffer, ".");
+ else if (cptr_len >= buflen)
+ {
+ errno = ERANGE;
+ return NULL;
+ }
+ else
+ memcpy (buffer, cptr, cptr_len + 1);
+
+ return buffer;
+}
+
+static int
+count_dots (const nis_name str)
+{
+ int count = 0;
+ size_t i;
+
+ for (i = 0; i < strlen (str); ++i)
+ if (str[i] == '.')
+ ++count;
+
+ return count;
+}
+
+nis_name *
+nis_getnames (const nis_name name)
+{
+ nis_name *getnames = NULL;
+ char local_domain[NIS_MAXNAMELEN + 1];
+ char *path, *cp;
+ int count, pos;
+
+
+ strncpy (local_domain, nis_local_directory (), NIS_MAXNAMELEN);
+ local_domain[NIS_MAXNAMELEN] = '\0';
+
+ count = 1;
+ if ((getnames = malloc ((count + 1) * sizeof (char *))) == NULL)
+ return NULL;
+
+ /* Do we have a fully qualified NIS+ name ? If yes, give it back */
+ if (name[strlen (name) - 1] == '.')
+ {
+ if ((getnames[0] = strdup (name)) == NULL)
+ {
+ free (getnames);
+ return NULL;
+ }
+ getnames[1] = NULL;
+
+ return getnames;
+ }
+
+ /* Get the search path, where we have to search "name" */
+ path = getenv ("NIS_PATH");
+ if (path == NULL)
+ path = strdupa ("$");
+ else
+ path = strdupa (path);
+
+ pos = 0;
+
+ cp = strtok (path, ":");
+ while (cp)
+ {
+ if (strcmp (cp, "$") == 0)
+ {
+ char *cptr = local_domain;
+ char *tmp;
+
+ while (count_dots (cptr) >= 2)
+ {
+ if (pos >= count)
+ {
+ count += 5;
+ getnames = realloc (getnames, (count + 1) * sizeof (char *));
+ }
+ tmp = malloc (strlen (cptr) + strlen (local_domain) +
+ strlen (name) + 2);
+ if (tmp == NULL)
+ return NULL;
+
+ getnames[pos] = tmp;
+ tmp = stpcpy (tmp, name);
+ *tmp++ = '.';
+ stpcpy (tmp, cptr);
+
+ ++pos;
+
+ while (*cptr != '.')
+ ++cptr;
+ ++cptr;
+ }
+ }
+ else
+ {
+ char *tmp;
+
+ if (cp[strlen (cp) - 1] == '$')
+ {
+ tmp = malloc (strlen (cp) + strlen (local_domain) +
+ strlen (name) + 2);
+ if (tmp == NULL)
+ return NULL;
+
+ tmp = stpcpy (tmp, name);
+ *tmp++ = '.';
+ tmp = stpcpy (tmp, cp);
+ --tmp;
+ if (tmp[-1] != '.')
+ *tmp++ = '.';
+ stpcpy (tmp, local_domain);
+ }
+ else
+ {
+ tmp = malloc (strlen (cp) + strlen (name) + 2);
+ if (tmp == NULL)
+ return NULL;
+
+ tmp = stpcpy (tmp, name);
+ *tmp++ = '.';
+ stpcpy (tmp, cp);
+ }
+
+ if (pos > count)
+ {
+ count += 5;
+ getnames = realloc (getnames, (count + 1) * sizeof (char *));
+ if (getnames == NULL)
+ return NULL;
+ }
+ getnames[pos] = tmp;
+ ++pos;
+ }
+ cp = strtok (NULL, ":");
+ }
+
+ getnames[pos] = NULL;
+
+ return getnames;
+}
+
+void
+nis_freenames (nis_name *names)
+{
+ int i = 0;
+
+ while (names[i] != NULL)
+ {
+ free (names[i]);
+ ++i;
+ }
+
+ free (names);
+}
+
+name_pos
+nis_dir_cmp (const nis_name n1, const nis_name n2)
+{
+ int len1, len2;
+
+ len1 = strlen (n1);
+ len2 = strlen (n2);
+
+ if (len1 == len2)
+ {
+ if (strcmp (n1, n2) == 0)
+ return SAME_NAME;
+ else
+ return NOT_SEQUENTIAL;
+ }
+
+ if (len1 < len2)
+ {
+ if (n2[len2 - len1 - 1] != '.')
+ return NOT_SEQUENTIAL;
+ else if (strcmp (&n2[len2 - len1], n1) == 0)
+ return HIGHER_NAME;
+ else
+ return NOT_SEQUENTIAL;
+ }
+ else
+ {
+ if (n1[len1 - len2 - 1] != '.')
+ return NOT_SEQUENTIAL;
+ else if (strcmp (&n1[len1 - len2], n2) == 0)
+ return LOWER_NAME;
+ else
+ return NOT_SEQUENTIAL;
+
+ }
+}
+
+void
+nis_destroy_object (nis_object *obj)
+{
+ nis_free_object (obj);
+}
diff --git a/nis/nis_table.c b/nis/nis_table.c
new file mode 100644
index 0000000000..a3061e1d94
--- /dev/null
+++ b/nis/nis_table.c
@@ -0,0 +1,417 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <string.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+#include "nis_intern.h"
+
+static void
+splitname (const nis_name name, nis_name *ibr_name, int *srch_len,
+ nis_attr **srch_val)
+{
+ char *cptr, *key, *val, *next;
+ int size;
+
+ if (name == NULL)
+ return;
+
+ cptr = strdup (name);
+ if (srch_len)
+ *srch_len = 0;
+ if (srch_val)
+ *srch_val = NULL;
+ size = 0;
+
+ /* Not of "[key=value,key=value,...],foo.." format? */
+ if (cptr[0] != '[')
+ {
+ *ibr_name = cptr;
+ return;
+ }
+
+ *ibr_name = strchr (cptr, ']');
+ if (*ibr_name == NULL || (*ibr_name)[1] != ',')
+ {
+ free (cptr);
+ *ibr_name = NULL;
+ return;
+ }
+
+ *ibr_name[0] = '\0';
+ *ibr_name += 2;
+ *ibr_name = strdup (*ibr_name);
+
+ if (srch_len == NULL || srch_val == NULL)
+ {
+ free (cptr);
+ return;
+ }
+
+ key = (cptr) + 1;
+ do
+ {
+ next = strchr (key, ',');
+ if (next)
+ {
+ next[0] = '\0';
+ ++next;
+ }
+
+ val = strchr (key, '=');
+ if (!val)
+ {
+ free (cptr);
+ *srch_val = malloc (sizeof (char *));
+ if (*srch_val == NULL)
+ {
+ free (cptr);
+ free (*ibr_name);
+ *ibr_name = NULL;
+ return;
+ }
+ (*srch_val)[*srch_len].zattr_val.zattr_val_len = 0;
+ (*srch_val)[*srch_len].zattr_val.zattr_val_val = NULL;
+ return;
+ }
+
+ val[0] = '\0';
+ ++val;
+
+ if ((*srch_len) + 1 >= size)
+ {
+ size += 10;
+ if (size == 10)
+ *srch_val = malloc (size * sizeof (char *));
+ else
+ *srch_val = realloc (val, size * sizeof (char *));
+ if (*srch_val == NULL)
+ {
+ free (cptr);
+ free (*ibr_name);
+ *ibr_name = NULL;
+ return;
+ }
+ }
+
+ (*srch_val)[*srch_len].zattr_ndx = strdup (key);
+ if (((*srch_val)[*srch_len].zattr_ndx) == NULL)
+ {
+ free (cptr);
+ free (*ibr_name);
+ *ibr_name = NULL;
+ return;
+ }
+ (*srch_val)[*srch_len].zattr_val.zattr_val_len = strlen (val) + 1;
+ (*srch_val)[*srch_len].zattr_val.zattr_val_val = strdup (val);
+ if ((*srch_val)[*srch_len].zattr_val.zattr_val_val == NULL)
+ {
+ free (cptr);
+ free (*ibr_name);
+ *ibr_name = NULL;
+ return;
+ }
+ ++(*srch_len);
+
+ key = next;
+
+ }
+ while (next);
+
+ free (cptr);
+}
+
+static struct ib_request *
+__create_ib_request (const nis_name name, struct ib_request *ibreq,
+ u_long flags)
+{
+ splitname (name, &ibreq->ibr_name, &ibreq->ibr_srch.ibr_srch_len,
+ &ibreq->ibr_srch.ibr_srch_val);
+ if (ibreq->ibr_name == NULL)
+ return NULL;
+ if ((flags & EXPAND_NAME) == EXPAND_NAME)
+ {
+ nis_name *names;
+
+ names = __nis_expandname (ibreq->ibr_name);
+ free (ibreq->ibr_name);
+ ibreq->ibr_name = NULL;
+ if (names == NULL)
+ return NULL;
+ ibreq->ibr_name = strdup (names[0]);
+ nis_freenames (names);
+ }
+
+ ibreq->ibr_flags = (flags & (RETURN_RESULT | ADD_OVERWRITE | REM_MULTIPLE |
+ MOD_SAMEOBJ | ADD_RESERVED | REM_RESERVED |
+ MOD_EXCLUSIVE));
+ ibreq->ibr_obj.ibr_obj_len = 0;
+ ibreq->ibr_obj.ibr_obj_val = NULL;
+ ibreq->ibr_cbhost.ibr_cbhost_len = 0;
+ ibreq->ibr_cbhost.ibr_cbhost_val = NULL;
+ ibreq->ibr_bufsize = 0;
+ ibreq->ibr_cookie.n_len = 0;
+ ibreq->ibr_cookie.n_bytes = NULL;
+
+ return ibreq;
+}
+
+nis_result *
+nis_list (const nis_name name, const u_long flags,
+ int (*callback) (const nis_name name,
+ const nis_object *object,
+ const void *userdata),
+ const void *userdata)
+{
+ nis_result *res = NULL;
+ struct ib_request ibreq;
+ int result;
+ int count_links = 0; /* We will only follow 16 links! */
+ int is_link = 1; /* We should go at least once in the while loop */
+
+ res = calloc (1, sizeof (nis_result));
+
+ if (__create_ib_request (name, &ibreq, flags) == NULL)
+ {
+ res->status = NIS_BADNAME;
+ return res;
+ }
+
+ while (is_link)
+ {
+ memset (res, '\0', sizeof (nis_result));
+
+ if ((result = __do_niscall (NULL, 0, NIS_IBLIST,
+ (xdrproc_t) xdr_ib_request,
+ (caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
+ (caddr_t) res, flags)) != RPC_SUCCESS)
+ {
+ res->status = result;
+ nis_free_request (&ibreq);
+ return res;
+ }
+
+ nis_free_request (&ibreq);
+
+ if ((res->status == NIS_SUCCESS || res->status == NIS_S_SUCCESS) &&
+ (res->objects.objects_len > 0 &&
+ res->objects.objects_val->zo_data.zo_type == LINK_OBJ))
+ is_link = 1;
+ else
+ is_link = 0;
+
+ if (is_link)
+ {
+ if ((flags & FOLLOW_LINKS) == FOLLOW_LINKS)
+ {
+ if (count_links == 16)
+ {
+ res->status = NIS_LINKNAMEERROR;
+ return res;
+ }
+ else
+ ++count_links;
+
+ if (__create_ib_request (res->objects.objects_val->LI_data.li_name,
+ &ibreq, flags) == NULL)
+ {
+ res->status = NIS_BADNAME;
+ return res;
+ }
+ }
+ else
+ {
+ res->status = NIS_NOTSEARCHABLE;
+ return res;
+ }
+ }
+ }
+
+ if (callback != NULL &&
+ (res->status == NIS_SUCCESS || res->status == NIS_S_SUCCESS))
+ {
+ unsigned int i;
+
+ for (i = 0; i < res->objects.objects_len; ++i)
+ if ((*callback) (name, &(res->objects.objects_val)[i], userdata) != 0)
+ break;
+ }
+
+ return res;
+}
+
+nis_result *
+nis_add_entry (const nis_name name, const nis_object *obj,
+ const u_long flags)
+{
+ nis_result *res;
+ struct ib_request ibreq;
+ nis_error status;
+
+ res = calloc (1, sizeof (nis_result));
+
+ if (__create_ib_request (name, &ibreq, flags) == NULL)
+ {
+ res->status = NIS_BADNAME;
+ return res;
+ }
+
+ ibreq.ibr_flags = flags;
+ ibreq.ibr_obj.ibr_obj_val = nis_clone_object (obj, NULL);
+ ibreq.ibr_obj.ibr_obj_len = 1;
+
+ if ((status = __do_niscall (NULL, 0, NIS_IBADD,
+ (xdrproc_t) xdr_ib_request,
+ (caddr_t) & ibreq,
+ (xdrproc_t) xdr_nis_result,
+ (caddr_t) res, 0)) != RPC_SUCCESS)
+ res->status = status;
+
+ nis_free_request (&ibreq);
+
+ return res;
+}
+
+nis_result *
+nis_modify_entry (const nis_name name, const nis_object *obj,
+ const u_long flags)
+{
+ nis_result *res;
+ struct ib_request ibreq;
+ nis_error status;
+
+ res = calloc (1, sizeof (nis_result));
+
+ if (__create_ib_request (name, &ibreq, flags) == NULL)
+ {
+ res->status = NIS_BADNAME;
+ return res;
+ }
+
+ ibreq.ibr_flags = flags;
+ ibreq.ibr_obj.ibr_obj_val = nis_clone_object (obj, NULL);
+ ibreq.ibr_obj.ibr_obj_len = 1;
+
+ if ((status = __do_niscall (NULL, 0, NIS_IBMODIFY,
+ (xdrproc_t) xdr_ib_request,
+ (caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
+ (caddr_t) res, 0)) != RPC_SUCCESS)
+ res->status = status;
+
+ nis_free_request (&ibreq);
+
+ return res;
+}
+
+nis_result *
+nis_remove_entry (const nis_name name, const nis_object *obj,
+ const u_long flags)
+{
+ nis_result *res;
+ struct ib_request ibreq;
+ nis_error status;
+
+ res = calloc (1, sizeof (nis_result));
+
+ if (__create_ib_request (name, &ibreq, flags) == NULL)
+ {
+ res->status = NIS_BADNAME;
+ return res;
+ }
+
+ ibreq.ibr_flags = flags;
+ if (obj != NULL)
+ {
+ ibreq.ibr_obj.ibr_obj_val = nis_clone_object (obj, NULL);
+ ibreq.ibr_obj.ibr_obj_len = 1;
+ }
+
+ if ((status = __do_niscall (NULL, 0, NIS_IBREMOVE,
+ (xdrproc_t) xdr_ib_request,
+ (caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
+ (caddr_t) res, 0)) != RPC_SUCCESS)
+ res->status = status;
+
+ nis_free_request (&ibreq);
+
+ return res;
+}
+
+nis_result *
+nis_first_entry (const nis_name name)
+{
+ nis_result *res;
+ struct ib_request ibreq;
+ nis_error status;
+
+ res = calloc (1, sizeof (nis_result));
+
+ if (__create_ib_request (name, &ibreq, 0) == NULL)
+ {
+ res->status = NIS_BADNAME;
+ return res;
+ }
+
+ if ((status = __do_niscall (NULL, 0, NIS_IBFIRST, (xdrproc_t) xdr_ib_request,
+ (caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
+ (caddr_t) res, 0)) != RPC_SUCCESS)
+ res->status = status;
+
+ nis_free_request (&ibreq);
+
+ return res;
+}
+
+nis_result *
+nis_next_entry (const nis_name name, const netobj *cookie)
+{
+ nis_result *res;
+ struct ib_request ibreq;
+ nis_error status;
+
+ res = calloc (1, sizeof (nis_result));
+
+ if (__create_ib_request (name, &ibreq, 0) == NULL)
+ {
+ res->status = NIS_BADNAME;
+ return res;
+ }
+
+ if (cookie != NULL)
+ {
+ ibreq.ibr_cookie.n_bytes = malloc (cookie->n_len);
+ if (ibreq.ibr_cookie.n_bytes == NULL)
+ {
+ res->status = NIS_NOMEMORY;
+ free (res);
+ return NULL;
+ }
+ memcpy (ibreq.ibr_cookie.n_bytes, cookie->n_bytes, cookie->n_len);
+ ibreq.ibr_cookie.n_len = cookie->n_len;
+ }
+
+ if ((status = __do_niscall (NULL, 0, NIS_IBNEXT, (xdrproc_t) xdr_ib_request,
+ (caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
+ (caddr_t) res, 0)) != RPC_SUCCESS)
+ res->status = status;
+
+ nis_free_request (&ibreq);
+
+ return res;
+}
diff --git a/nis/nis_xdr.c b/nis/nis_xdr.c
new file mode 100644
index 0000000000..82df04e449
--- /dev/null
+++ b/nis/nis_xdr.c
@@ -0,0 +1,572 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <rpcsvc/nis.h>
+
+bool_t
+xdr_nis_attr (XDR *xdrs, nis_attr *objp)
+{
+ if (!xdr_string (xdrs, &objp->zattr_ndx, ~0))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **) &objp->zattr_val.zattr_val_val,
+ (u_int *) & objp->zattr_val.zattr_val_len, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nis_name (XDR *xdrs, nis_name *objp)
+{
+ if (!xdr_string (xdrs, objp, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_zotypes (XDR *xdrs, zotypes *objp)
+{
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nstype (XDR *xdrs, nstype *objp)
+{
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_oar_mask (XDR *xdrs, oar_mask *objp)
+{
+ if (!xdr_u_long (xdrs, &objp->oa_rights))
+ return FALSE;
+ if (!xdr_zotypes (xdrs, &objp->oa_otype))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_endpoint (XDR *xdrs, endpoint *objp)
+{
+ if (!xdr_string (xdrs, &objp->uaddr, ~0))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->family, ~0))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->proto, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nis_server (XDR *xdrs, nis_server *objp)
+{
+ if (!xdr_nis_name (xdrs, &objp->name))
+ return FALSE;
+ if (!xdr_array (xdrs, (char **) &objp->ep.ep_val, (u_int *) &objp->ep.ep_len,
+ ~0, sizeof (endpoint), (xdrproc_t) xdr_endpoint))
+ return FALSE;
+ if (!xdr_u_long (xdrs, &objp->key_type))
+ return FALSE;
+ if (!xdr_netobj (xdrs, &objp->pkey))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_directory_obj (XDR *xdrs, directory_obj *objp)
+{
+ if (!xdr_nis_name (xdrs, &objp->do_name))
+ return FALSE;
+ if (!xdr_nstype (xdrs, &objp->do_type))
+ return FALSE;
+ if (!xdr_array (xdrs, (char **) &objp->do_servers.do_servers_val,
+ (u_int *) & objp->do_servers.do_servers_len, ~0,
+ sizeof (nis_server), (xdrproc_t) xdr_nis_server))
+ return FALSE;
+
+ if (!xdr_u_long (xdrs, &objp->do_ttl))
+ return FALSE;
+ if (!xdr_array (xdrs, (char **) &objp->do_armask.do_armask_val,
+ (u_int *) & objp->do_armask.do_armask_len, ~0,
+ sizeof (oar_mask), (xdrproc_t) xdr_oar_mask))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_entry_col (XDR *xdrs, entry_col *objp)
+{
+ if (!xdr_u_long (xdrs, &objp->ec_flags))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **) &objp->ec_value.ec_value_val,
+ (u_int *) &objp->ec_value.ec_value_len, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_entry_obj (XDR *xdrs, entry_obj *objp)
+{
+ if (!xdr_string (xdrs, &objp->en_type, ~0))
+ return FALSE;
+ if (!xdr_array (xdrs, (char **) &objp->en_cols.en_cols_val,
+ (u_int *) &objp->en_cols.en_cols_len, ~0,
+ sizeof (entry_col), (xdrproc_t) xdr_entry_col))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_group_obj (XDR *xdrs, group_obj *objp)
+{
+ if (!xdr_u_long (xdrs, &objp->gr_flags))
+ return FALSE;
+ if (!xdr_array (xdrs, (char **) &objp->gr_members.gr_members_val,
+ (u_int *) &objp->gr_members.gr_members_len, ~0,
+ sizeof (nis_name), (xdrproc_t) xdr_nis_name))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_link_obj (XDR *xdrs, link_obj *objp)
+{
+ if (!xdr_zotypes (xdrs, &objp->li_rtype))
+ return FALSE;
+ if (!xdr_array (xdrs, (char **) &objp->li_attrs.li_attrs_val,
+ (u_int *) &objp->li_attrs.li_attrs_len, ~0,
+ sizeof (nis_attr), (xdrproc_t) xdr_nis_attr))
+ return FALSE;
+ if (!xdr_nis_name (xdrs, &objp->li_name))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_table_col (XDR *xdrs, table_col *objp)
+{
+ if (!xdr_string (xdrs, &objp->tc_name, 64))
+ return FALSE;
+ if (!xdr_u_long (xdrs, &objp->tc_flags))
+ return FALSE;
+ if (!xdr_u_long (xdrs, &objp->tc_rights))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_table_obj (XDR *xdrs, table_obj *objp)
+{
+ if (!xdr_string (xdrs, &objp->ta_type, 64))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->ta_maxcol))
+ return FALSE;
+ if (!xdr_u_char (xdrs, &objp->ta_sep))
+ return FALSE;
+ if (!xdr_array (xdrs, (char **) &objp->ta_cols.ta_cols_val,
+ (u_int *) &objp->ta_cols.ta_cols_len, ~0,
+ sizeof (table_col), (xdrproc_t) xdr_table_col))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->ta_path, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_objdata (XDR *xdrs, objdata *objp)
+{
+ if (!xdr_zotypes (xdrs, &objp->zo_type))
+ return FALSE;
+ switch (objp->zo_type)
+ {
+ case DIRECTORY_OBJ:
+ if (!xdr_directory_obj (xdrs, &objp->objdata_u.di_data))
+ return FALSE;
+ break;
+ case GROUP_OBJ:
+ if (!xdr_group_obj (xdrs, &objp->objdata_u.gr_data))
+ return FALSE;
+ break;
+ case TABLE_OBJ:
+ if (!xdr_table_obj (xdrs, &objp->objdata_u.ta_data))
+ return FALSE;
+ break;
+ case ENTRY_OBJ:
+ if (!xdr_entry_obj (xdrs, &objp->objdata_u.en_data))
+ return FALSE;
+ break;
+ case LINK_OBJ:
+ if (!xdr_link_obj (xdrs, &objp->objdata_u.li_data))
+ return FALSE;
+ break;
+ case PRIVATE_OBJ:
+ if (!xdr_bytes (xdrs, (char **) &objp->objdata_u.po_data.po_data_val,
+ (u_int *) & objp->objdata_u.po_data.po_data_len, ~0))
+ return FALSE;
+ break;
+ case NO_OBJ:
+ break;
+ case BOGUS_OBJ:
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_nis_oid (XDR *xdrs, nis_oid *objp)
+{
+ if (!xdr_u_long (xdrs, &objp->ctime))
+ return FALSE;
+ if (!xdr_u_long (xdrs, &objp->mtime))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nis_object (XDR *xdrs, nis_object *objp)
+{
+ if (!xdr_nis_oid (xdrs, &objp->zo_oid))
+ return FALSE;
+ if (!xdr_nis_name (xdrs, &objp->zo_name))
+ return FALSE;
+ if (!xdr_nis_name (xdrs, &objp->zo_owner))
+ return FALSE;
+ if (!xdr_nis_name (xdrs, &objp->zo_group))
+ return FALSE;
+ if (!xdr_nis_name (xdrs, &objp->zo_domain))
+ return FALSE;
+ if (!xdr_u_long (xdrs, &objp->zo_access))
+ return FALSE;
+ if (!xdr_u_long (xdrs, &objp->zo_ttl))
+ return FALSE;
+ if (!xdr_objdata (xdrs, &objp->zo_data))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nis_error (XDR *xdrs, nis_error *objp)
+{
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nis_result (XDR *xdrs, nis_result *objp)
+{
+ register long *buf;
+
+ if (xdrs->x_op == XDR_ENCODE)
+ {
+ if (!xdr_nis_error (xdrs, &objp->status))
+ return FALSE;
+ if (!xdr_array (xdrs, (char **) &objp->objects.objects_val,
+ (u_int *) &objp->objects.objects_len, ~0,
+ sizeof (nis_object), (xdrproc_t) xdr_nis_object))
+ return FALSE;
+ if (!xdr_netobj (xdrs, &objp->cookie))
+ return FALSE;
+ buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL)
+ {
+ if (!xdr_u_long (xdrs, &objp->zticks))
+ {
+ return FALSE;
+ }
+ if (!xdr_u_long (xdrs, &objp->dticks))
+ {
+ return FALSE;
+ }
+ if (!xdr_u_long (xdrs, &objp->aticks))
+ {
+ return FALSE;
+ }
+ if (!xdr_u_long (xdrs, &objp->cticks))
+ {
+ return FALSE;
+ }
+
+ }
+ else
+ {
+ IXDR_PUT_U_LONG (buf, objp->zticks);
+ IXDR_PUT_U_LONG (buf, objp->dticks);
+ IXDR_PUT_U_LONG (buf, objp->aticks);
+ IXDR_PUT_U_LONG (buf, objp->cticks);
+ }
+
+ return TRUE;
+ }
+ else if (xdrs->x_op == XDR_DECODE)
+ {
+ if (!xdr_nis_error (xdrs, &objp->status))
+ {
+ return FALSE;
+ }
+ if (!xdr_array (xdrs, (char **) &objp->objects.objects_val,
+ (u_int *) &objp->objects.objects_len, ~0,
+ sizeof (nis_object), (xdrproc_t) xdr_nis_object))
+ {
+ return FALSE;
+ }
+ if (!xdr_netobj (xdrs, &objp->cookie))
+ {
+ return FALSE;
+ }
+ buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL)
+ {
+ if (!xdr_u_long (xdrs, &objp->zticks))
+ {
+ return FALSE;
+ }
+ if (!xdr_u_long (xdrs, &objp->dticks))
+ {
+ return FALSE;
+ }
+ if (!xdr_u_long (xdrs, &objp->aticks))
+ {
+ return FALSE;
+ }
+ if (!xdr_u_long (xdrs, &objp->cticks))
+ {
+ return FALSE;
+ }
+
+ }
+ else
+ {
+ objp->zticks = IXDR_GET_U_LONG (buf);
+ objp->dticks = IXDR_GET_U_LONG (buf);
+ objp->aticks = IXDR_GET_U_LONG (buf);
+ objp->cticks = IXDR_GET_U_LONG (buf);
+ }
+ return TRUE;
+ }
+
+ if (!xdr_nis_error (xdrs, &objp->status))
+ {
+ return FALSE;
+ }
+ if (!xdr_array (xdrs, (char **) &objp->objects.objects_val,
+ (u_int *) &objp->objects.objects_len, ~0,
+ sizeof (nis_object), (xdrproc_t) xdr_nis_object))
+ {
+ return FALSE;
+ }
+ if (!xdr_netobj (xdrs, &objp->cookie))
+ {
+ return FALSE;
+ }
+ if (!xdr_u_long (xdrs, &objp->zticks))
+ {
+ return FALSE;
+ }
+ if (!xdr_u_long (xdrs, &objp->dticks))
+ {
+ return FALSE;
+ }
+ if (!xdr_u_long (xdrs, &objp->aticks))
+ {
+ return FALSE;
+ }
+ if (!xdr_u_long (xdrs, &objp->cticks))
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_ns_request (XDR *xdrs, ns_request *objp)
+{
+ if (!xdr_nis_name (xdrs, &objp->ns_name))
+ return FALSE;
+ if (!xdr_array (xdrs, (char **) &objp->ns_object.ns_object_val,
+ (u_int *) &objp->ns_object.ns_object_len, 1,
+ sizeof (nis_object), (xdrproc_t) xdr_nis_object))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_ib_request (XDR *xdrs, ib_request *objp)
+{
+ if (!xdr_nis_name (xdrs, &objp->ibr_name))
+ return FALSE;
+ if (!xdr_array (xdrs, (char **) &objp->ibr_srch.ibr_srch_val,
+ (u_int *) &objp->ibr_srch.ibr_srch_len, ~0,
+ sizeof (nis_attr), (xdrproc_t) xdr_nis_attr))
+ return FALSE;
+ if (!xdr_u_long (xdrs, &objp->ibr_flags))
+ return FALSE;
+ if (!xdr_array (xdrs, (char **) &objp->ibr_obj.ibr_obj_val,
+ (u_int *) &objp->ibr_obj.ibr_obj_len, 1,
+ sizeof (nis_object), (xdrproc_t) xdr_nis_object))
+ return FALSE;
+ if (!xdr_array (xdrs, (char **) &objp->ibr_cbhost.ibr_cbhost_val,
+ (u_int *) &objp->ibr_cbhost.ibr_cbhost_len, 1,
+ sizeof (nis_server), (xdrproc_t) xdr_nis_server))
+ return FALSE;
+ if (!xdr_u_long (xdrs, &objp->ibr_bufsize))
+ return FALSE;
+ if (!xdr_netobj (xdrs, &objp->ibr_cookie))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_ping_args (XDR *xdrs, ping_args *objp)
+{
+ if (!xdr_nis_name (xdrs, &objp->dir))
+ return FALSE;
+ if (!xdr_u_long (xdrs, &objp->stamp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_log_entry_t (XDR *xdrs, log_entry_t *objp)
+{
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_log_entry (XDR *xdrs, log_entry *objp)
+{
+ if (!xdr_u_long (xdrs, &objp->le_time))
+ return FALSE;
+ if (!xdr_log_entry_t (xdrs, &objp->le_type))
+ return FALSE;
+ if (!xdr_nis_name (xdrs, &objp->le_princp))
+ return FALSE;
+ if (!xdr_nis_name (xdrs, &objp->le_name))
+ return FALSE;
+ if (!xdr_array (xdrs, (char **) &objp->le_attrs.le_attrs_val,
+ (u_int *) &objp->le_attrs.le_attrs_len, ~0,
+ sizeof (nis_attr), (xdrproc_t) xdr_nis_attr))
+ return FALSE;
+ if (!xdr_nis_object (xdrs, &objp->le_object))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_log_result (XDR *xdrs, log_result *objp)
+{
+ if (!xdr_nis_error (xdrs, &objp->lr_status))
+ {
+ return FALSE;
+ }
+ if (!xdr_netobj (xdrs, &objp->lr_cookie))
+ {
+ return FALSE;
+ }
+ if (!xdr_array (xdrs, (char **) &objp->lr_entries.lr_entries_val,
+ (u_int *) &objp->lr_entries.lr_entries_len, ~0,
+ sizeof (log_entry), (xdrproc_t) xdr_log_entry))
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_cp_result (XDR *xdrs, cp_result *objp)
+{
+ if (!xdr_nis_error (xdrs, &objp->cp_status))
+ return FALSE;
+ if (!xdr_u_long (xdrs, &objp->cp_zticks))
+ return FALSE;
+ if (!xdr_u_long (xdrs, &objp->cp_dticks))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nis_tag (XDR *xdrs, nis_tag *objp)
+{
+ if (!xdr_u_long (xdrs, &objp->tag_type))
+ {
+ return FALSE;
+ }
+ if (!xdr_string (xdrs, &objp->tag_val, 1024))
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_nis_taglist (XDR *xdrs, nis_taglist *objp)
+{
+ if (!xdr_array (xdrs, (char **) &objp->tags.tags_val,
+ (u_int *) &objp->tags.tags_len, ~0, sizeof (nis_tag),
+ (xdrproc_t) xdr_nis_tag))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_dump_args (XDR *xdrs, dump_args *objp)
+{
+ if (!xdr_nis_name (xdrs, &objp->da_dir))
+ return FALSE;
+ if (!xdr_u_long (xdrs, &objp->da_time))
+ return FALSE;
+ if (!xdr_array (xdrs, (char **) &objp->da_cbhost.da_cbhost_val,
+ (u_int *) &objp->da_cbhost.da_cbhost_len, 1,
+ sizeof (nis_server), (xdrproc_t) xdr_nis_server))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_fd_args (XDR *xdrs, fd_args *objp)
+{
+ if (!xdr_nis_name (xdrs, &objp->dir_name))
+ return FALSE;
+ if (!xdr_nis_name (xdrs, &objp->requester))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_fd_result (XDR *xdrs, fd_result *objp)
+{
+ if (!xdr_nis_error (xdrs, &objp->status))
+ return FALSE;
+ if (!xdr_nis_name (xdrs, &objp->source))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **) &objp->dir_data.dir_data_val,
+ (u_int *) &objp->dir_data.dir_data_len, ~0))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **) &objp->signature.signature_val,
+ (u_int *) &objp->signature.signature_len, ~0))
+ return FALSE;
+ return TRUE;
+}
diff --git a/nis/nss-nisplus.h b/nis/nss-nisplus.h
new file mode 100644
index 0000000000..ff497f1ca4
--- /dev/null
+++ b/nis/nss-nisplus.h
@@ -0,0 +1,90 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef _NIS_NSS_NISPLUS_H
+#define _NIS_NSS_NISPLUS_H 1
+
+#include <rpcsvc/nis.h>
+
+#include "nsswitch.h"
+
+
+/* Convert NIS+ error number to NSS error number. */
+static enum nss_status niserr2nss_tab[] =
+{
+ [NIS_SUCCESS] = NSS_STATUS_SUCCESS,
+ [NIS_S_SUCCESS] = NSS_STATUS_SUCCESS,
+ [NIS_NOTFOUND] = NSS_STATUS_NOTFOUND,
+ [NIS_S_NOTFOUND] = NSS_STATUS_TRYAGAIN,
+ [NIS_CACHEEXPIRED] = NSS_STATUS_UNAVAIL,
+ [NIS_NAMEUNREACHABLE] = NSS_STATUS_TRYAGAIN,
+ [NIS_UNKNOWNOBJ] = NSS_STATUS_NOTFOUND,
+ [NIS_TRYAGAIN] = NSS_STATUS_TRYAGAIN,
+ [NIS_SYSTEMERROR] = NSS_STATUS_UNAVAIL, /* Maybe TRYAGAIN ? */
+ [NIS_CHAINBROKEN] = NSS_STATUS_UNAVAIL,
+ [NIS_PERMISSION] = NSS_STATUS_UNAVAIL,
+ [NIS_NOTOWNER] = NSS_STATUS_UNAVAIL,
+ [NIS_NOT_ME] = NSS_STATUS_UNAVAIL,
+ [NIS_NOMEMORY] = NSS_STATUS_TRYAGAIN,
+ [NIS_NAMEEXISTS] = NSS_STATUS_UNAVAIL,
+ [NIS_NOTMASTER] = NSS_STATUS_UNAVAIL,
+ [NIS_INVALIDOBJ] = NSS_STATUS_UNAVAIL,
+ [NIS_BADNAME] = NSS_STATUS_UNAVAIL,
+ [NIS_NOCALLBACK] = NSS_STATUS_UNAVAIL,
+ [NIS_CBRESULTS] = NSS_STATUS_UNAVAIL,
+ [NIS_NOSUCHNAME] = NSS_STATUS_NOTFOUND,
+ [NIS_NOTUNIQUE] = NSS_STATUS_UNAVAIL,
+ [NIS_IBMODERROR] = NSS_STATUS_UNAVAIL,
+ [NIS_NOSUCHTABLE] = NSS_STATUS_UNAVAIL,
+ [NIS_TYPEMISMATCH] = NSS_STATUS_UNAVAIL,
+ [NIS_LINKNAMEERROR] = NSS_STATUS_UNAVAIL,
+ [NIS_PARTIAL] = NSS_STATUS_NOTFOUND,
+ [NIS_TOOMANYATTRS] = NSS_STATUS_UNAVAIL,
+ [NIS_RPCERROR] = NSS_STATUS_UNAVAIL,
+ [NIS_BADATTRIBUTE] = NSS_STATUS_UNAVAIL,
+ [NIS_NOTSEARCHABLE] = NSS_STATUS_UNAVAIL,
+ [NIS_CBERROR] = NSS_STATUS_UNAVAIL,
+ [NIS_FOREIGNNS] = NSS_STATUS_UNAVAIL,
+ [NIS_BADOBJECT] = NSS_STATUS_UNAVAIL,
+ [NIS_NOTSAMEOBJ] = NSS_STATUS_UNAVAIL,
+ [NIS_MODFAIL] = NSS_STATUS_UNAVAIL,
+ [NIS_BADREQUEST] = NSS_STATUS_UNAVAIL,
+ [NIS_NOTEMPTY] = NSS_STATUS_UNAVAIL,
+ [NIS_COLDSTART_ERR] = NSS_STATUS_UNAVAIL,
+ [NIS_RESYNC] = NSS_STATUS_UNAVAIL,
+ [NIS_FAIL] = NSS_STATUS_UNAVAIL,
+ [NIS_UNAVAIL] = NSS_STATUS_UNAVAIL,
+ [NIS_RES2BIG] = NSS_STATUS_UNAVAIL,
+ [NIS_SRVAUTH] = NSS_STATUS_UNAVAIL,
+ [NIS_CLNTAUTH] = NSS_STATUS_UNAVAIL,
+ [NIS_NOFILESPACE] = NSS_STATUS_UNAVAIL,
+ [NIS_NOPROC] = NSS_STATUS_TRYAGAIN,
+ [NIS_DUMPLATER] = NSS_STATUS_UNAVAIL
+};
+#define NISERR_COUNT (sizeof (niserr2nss_tab) / sizeof (niserr2nss_tab[0]))
+
+static inline enum nss_status
+niserr2nss (int errval)
+{
+ if ((unsigned int) errval > NISERR_COUNT)
+ return NSS_STATUS_UNAVAIL;
+ return niserr2nss_tab[errval];
+}
+
+#endif /* nis/nss-nisplus.h */
diff --git a/nis/nss_nis/nis-service.c b/nis/nss_nis/nis-service.c
index fe189b161b..ae7667f231 100644
--- a/nis/nss_nis/nis-service.c
+++ b/nis/nss_nis/nis-service.c
@@ -204,7 +204,7 @@ _nss_nis_getservbyname_r (const char *name, char *protocol,
enum nss_status status;
int found;
- if (name == NULL || protocol == NULL)
+ if (name == NULL)
{
__set_errno (EINVAL);
return NSS_STATUS_UNAVAIL;
@@ -219,7 +219,7 @@ _nss_nis_getservbyname_r (const char *name, char *protocol,
((status = internal_nis_getservent_r (serv, buffer, buflen, &data))
== NSS_STATUS_SUCCESS))
{
- if (strcmp (serv->s_proto, protocol) == 0)
+ if (protocol == NULL || strcmp (serv->s_proto, protocol) == 0)
{
char **cp;
diff --git a/nis/nss_nisplus/nisplus-alias.c b/nis/nss_nisplus/nisplus-alias.c
new file mode 100644
index 0000000000..b0f035178e
--- /dev/null
+++ b/nis/nss_nisplus/nisplus-alias.c
@@ -0,0 +1,251 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <nss.h>
+#include <errno.h>
+#include <ctype.h>
+#include <string.h>
+#include <aliases.h>
+#include <libc-lock.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+#include "nss-nisplus.h"
+
+__libc_lock_define_initialized (static, lock)
+
+static nis_result *result = NULL;
+static nis_name *names = NULL;
+
+#define NISENTRYVAL(idx,col,res) \
+ ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
+
+#define NISENTRYLEN(idx,col,res) \
+ ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
+
+static int
+_nss_nisplus_parse_aliasent (nis_result *result, struct aliasent *alias,
+ char *buffer, size_t buflen)
+{
+ if (result == NULL)
+ return -1;
+
+ if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
+ result->objects.objects_len != 1 ||
+ result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
+ strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+ "mail_aliases") != 0 ||
+ result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 2)
+ return -1;
+ else
+ {
+ char *first_unused = buffer + NISENTRYLEN(0, 1, result) + 1;
+ size_t room_left =
+ buflen - (buflen % __alignof__ (char *)) -
+ NISENTRYLEN(0, 1, result) - 2;
+ char *line;
+ char *cp;
+
+ if (NISENTRYLEN(0, 1, result) >= buflen)
+ {
+ /* The line is too long for our buffer. */
+ no_more_room:
+ __set_errno (ERANGE);
+ return -1;
+ }
+ else
+ {
+ strncpy (buffer, NISENTRYVAL(0, 1, result), NISENTRYLEN(0, 1, result));
+ buffer[NISENTRYLEN(0, 1, result)] = '\0';
+ }
+
+ if (NISENTRYLEN(0, 0, result) >= room_left)
+ goto no_more_room;
+
+ alias->alias_local = 0;
+ alias->alias_members_len = 0;
+ *first_unused = '\0';
+ ++first_unused;
+ strcpy (first_unused, NISENTRYVAL(0, 0, result));
+ first_unused[NISENTRYLEN(0, 0, result)] = '\0';
+ alias->alias_name = first_unused;
+
+ /* Terminate the line for any case. */
+ cp = strpbrk (alias->alias_name, "#\n");
+ if (cp != NULL)
+ *cp = '\0';
+
+ first_unused += strlen (alias->alias_name) +1;
+ /* Adjust the pointer so it is aligned for
+ storing pointers. */
+ first_unused += __alignof__ (char *) - 1;
+ first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *));
+ alias->alias_members = (char **) first_unused;
+
+ line = buffer;
+
+ while (*line != '\0')
+ {
+ /* Skip leading blanks. */
+ while (isspace (*line))
+ line++;
+
+ if (*line == '\0')
+ break;
+
+ if (room_left < sizeof (char *))
+ goto no_more_room;
+ room_left -= sizeof (char *);
+ alias->alias_members[alias->alias_members_len] = line;
+
+ while (*line != '\0' && *line != ',')
+ line++;
+
+ if (line != alias->alias_members[alias->alias_members_len])
+ {
+ *line = '\0';
+ line++;
+ alias->alias_members_len++;
+ }
+ }
+
+ return alias->alias_members_len == 0 ? 0 : 1;
+ }
+}
+
+enum nss_status
+_nss_nisplus_setaliasent (void)
+{
+ __libc_lock_lock (lock);
+
+ if (result)
+ nis_freeresult (result);
+ result = NULL;
+ if (names)
+ {
+ nis_freenames (names);
+ names = NULL;
+ }
+
+ __libc_lock_unlock (lock);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_endaliasent (void)
+{
+ __libc_lock_lock (lock);
+
+ if (result)
+ nis_freeresult (result);
+ result = NULL;
+ if (names)
+ {
+ nis_freenames (names);
+ names = NULL;
+ }
+
+ __libc_lock_unlock (lock);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+static enum nss_status
+internal_nisplus_getaliasent_r (struct aliasent *alias,
+ char *buffer, size_t buflen)
+{
+ int parse_res;
+
+ /* Get the next entry until we found a correct one. */
+ do
+ {
+ if (result == NULL)
+ {
+ names = nis_getnames("mail_aliases.org_dir");
+ if (names == NULL || names[0] == NULL)
+ return NSS_STATUS_UNAVAIL;
+
+ result = nis_first_entry(names[0]);
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ return niserr2nss (result->status);
+ }
+ else
+ {
+ nis_result *res2;
+
+ res2 = nis_next_entry(names[0], &result->cookie);
+ nis_freeresult (result);
+ result = res2;
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ return niserr2nss (result->status);
+ }
+
+ parse_res = _nss_nisplus_parse_aliasent (result, alias, buffer, buflen);
+ } while (!parse_res);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_getaliasent_r (struct aliasent *result, char *buffer,
+ size_t buflen)
+{
+ int status;
+
+ __libc_lock_lock (lock);
+
+ status = internal_nisplus_getaliasent_r (result, buffer, buflen);
+
+ __libc_lock_unlock (lock);
+
+ return status;
+}
+
+enum nss_status
+_nss_nisplus_getaliasbyname_r (const char *name, struct aliasent *alias,
+ char *buffer, size_t buflen)
+{
+ int parse_res;
+
+ if (name == NULL || strlen(name) > 8)
+ return NSS_STATUS_NOTFOUND;
+ else
+ {
+ nis_result *result;
+ char buf[strlen (name) + 30];
+
+ sprintf(buf, "[name=%s],mail_aliases.org_dir", name);
+
+ result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ return niserr2nss (result->status);
+
+ parse_res = _nss_nisplus_parse_aliasent (result, alias, buffer, buflen);
+
+ if (parse_res)
+ return NSS_STATUS_SUCCESS;
+
+ if (!parse_res && errno == ERANGE)
+ return NSS_STATUS_TRYAGAIN;
+ else
+ return NSS_STATUS_NOTFOUND;
+ }
+}
diff --git a/nis/nss_nisplus/nisplus-ethers.c b/nis/nss_nisplus/nisplus-ethers.c
new file mode 100644
index 0000000000..ac3e06960a
--- /dev/null
+++ b/nis/nss_nisplus/nisplus-ethers.c
@@ -0,0 +1,278 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <nss.h>
+#include <errno.h>
+#include <ctype.h>
+#include <string.h>
+#include <libc-lock.h>
+#include <netdb.h>
+#include <netinet/ether.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+#include <netinet/if_ether.h>
+
+#include "nss-nisplus.h"
+
+__libc_lock_define_initialized (static, lock)
+
+static nis_result *result = NULL;
+static nis_name *names = NULL;
+
+/* Because the `ethers' lookup does not fit so well in the scheme so
+ we define a dummy struct here which helps us to use the available
+ functions. */
+struct etherent
+{
+ const char *e_name;
+ struct ether_addr e_addr;
+};
+struct etherent_data {};
+
+#define ENTNAME etherent
+#define DATABASE "ethers"
+#include "../../nss/nss_files/files-parse.c"
+LINE_PARSER
+("#",
+ /* Read the ethernet address: 6 x 8bit hexadecimal number. */
+ {
+ size_t cnt;
+
+ for (cnt = 0; cnt < 6; ++cnt)
+ {
+ unsigned int number;
+
+ if (cnt < 5)
+ INT_FIELD (number, ISCOLON , 0, 16, (unsigned int))
+ else
+ INT_FIELD (number, isspace, 0, 16, (unsigned int))
+
+ if (number > 0xff)
+ return 0;
+ result->e_addr.ether_addr_octet[cnt] = number;
+ }
+ };
+ STRING_FIELD (result->e_name, isspace, 1);
+ )
+
+#define NISENTRYVAL(idx,col,res) \
+ ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
+
+#define NISENTRYLEN(idx,col,res) \
+ ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
+
+static int
+_nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether,
+ char *buffer, size_t buflen)
+{
+ char *p = buffer;
+ size_t room_left = buflen;
+ struct parser_data *data = (void *) buffer;
+
+ if (result == NULL)
+ return -1;
+
+ if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
+ result->objects.objects_len != 1 ||
+ result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
+ strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+ "ethers_tbl") != 0 ||
+ result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 2)
+ return -1;
+
+ memset (p, '\0', room_left);
+
+ /* Generate the ether entry format and use the normal parser */
+ if (NISENTRYLEN (0, 0, result) +1 > room_left)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+ strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
+ room_left -= (NISENTRYLEN (0, 0, result) +1);
+
+ if (NISENTRYLEN (0, 1, result) +1 > room_left)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+ strcat (p, "\t");
+ strncat (p, NISENTRYVAL (0, 1, result), NISENTRYLEN (0, 1, result));
+ room_left -= (NISENTRYLEN (0, 1, result) + 1);
+
+ return _nss_files_parse_etherent (p,ether, data, buflen);
+}
+
+enum nss_status
+_nss_nisplus_setetherent (void)
+{
+ __libc_lock_lock (lock);
+
+ if (result)
+ nis_freeresult (result);
+ result = NULL;
+ if (names)
+ {
+ nis_freenames (names);
+ names = NULL;
+ }
+
+ __libc_lock_unlock (lock);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_endetherent (void)
+{
+ __libc_lock_lock (lock);
+
+ if (result)
+ nis_freeresult (result);
+ result = NULL;
+ if (names)
+ {
+ nis_freenames (names);
+ names = NULL;
+ }
+
+ __libc_lock_unlock (lock);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+static enum nss_status
+internal_nisplus_getetherent_r (struct etherent *ether, char *buffer,
+ size_t buflen)
+{
+ int parse_res;
+
+ /* Get the next entry until we found a correct one. */
+ do
+ {
+ if (result == NULL)
+ {
+ names = nis_getnames("ethers.org_dir");
+ if (names == NULL || names[0] == NULL)
+ return NSS_STATUS_UNAVAIL;
+
+ result = nis_first_entry(names[0]);
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ return niserr2nss (result->status);
+ }
+ else
+ {
+ nis_result *res2;
+
+ res2 = nis_next_entry(names[0], &result->cookie);
+ nis_freeresult (result);
+ result = res2;
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ return niserr2nss (result->status);
+ }
+
+ parse_res = _nss_nisplus_parse_etherent (result, ether, buffer, buflen);
+ } while (!parse_res);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_getetherent_r (struct etherent *result, char *buffer,
+ size_t buflen)
+{
+ int status;
+
+ __libc_lock_lock (lock);
+
+ status = internal_nisplus_getetherent_r (result, buffer, buflen);
+
+ __libc_lock_unlock (lock);
+
+ return status;
+}
+
+enum nss_status
+_nss_nisplus_gethostton_r (const char *name, struct etherent *eth,
+ char *buffer, size_t buflen)
+{
+ int parse_res;
+
+ if (name == NULL)
+ return NSS_STATUS_NOTFOUND;
+ else
+ {
+ nis_result *result;
+ char buf[strlen (name) + 255];
+
+ sprintf(buf, "[name=%s],ethers.org_dir", name);
+
+ result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ return niserr2nss (result->status);
+
+ parse_res = _nss_nisplus_parse_etherent (result, eth, buffer, buflen);
+
+ if (parse_res)
+ return NSS_STATUS_SUCCESS;
+
+ if (!parse_res && errno == ERANGE)
+ return NSS_STATUS_TRYAGAIN;
+ else
+ return NSS_STATUS_NOTFOUND;
+ }
+}
+
+enum nss_status
+_nss_nisplus_getntohost_r (const struct ether_addr *addr,
+ struct etherent *eth,
+ char *buffer, size_t buflen)
+{
+ int parse_res;
+ nis_result *result;
+ char buf[255];
+
+ if (addr == NULL)
+ {
+ __set_errno (EINVAL);
+ return NSS_STATUS_UNAVAIL;
+ }
+
+ memset (&buf, '\0', sizeof (buf));
+ snprintf(buf, sizeof (buf), "[addr=%x:%x:%x:%x:%x:%x],ethers.org_dir",
+ addr->ether_addr_octet[0], addr->ether_addr_octet[1],
+ addr->ether_addr_octet[2], addr->ether_addr_octet[3],
+ addr->ether_addr_octet[4], addr->ether_addr_octet[5]);
+
+ result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ return niserr2nss (result->status);
+
+ parse_res = _nss_nisplus_parse_etherent (result, eth, buffer, buflen);
+
+ if (parse_res)
+ return NSS_STATUS_SUCCESS;
+
+ if (!parse_res && errno == ERANGE)
+ return NSS_STATUS_TRYAGAIN;
+ else
+ return NSS_STATUS_NOTFOUND;
+}
diff --git a/nis/nss_nisplus/nisplus-grp.c b/nis/nss_nisplus/nisplus-grp.c
new file mode 100644
index 0000000000..2e56afa6fc
--- /dev/null
+++ b/nis/nss_nisplus/nisplus-grp.c
@@ -0,0 +1,387 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <nss.h>
+#include <grp.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <libc-lock.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+#include "nss-nisplus.h"
+
+__libc_lock_define_initialized (static, lock);
+
+static nis_result *result = NULL;
+static nis_name *names = NULL;
+
+#define NISENTRYVAL(idx,col,res) \
+((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
+
+#define NISENTRYLEN(idx,col,res) \
+ ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
+
+#define STRUCTURE group
+#define ENTNAME grent
+struct grent_data {};
+
+#define TRAILING_LIST_MEMBER gr_mem
+#define TRAILING_LIST_SEPARATOR_P(c) ((c) == ',')
+#include "../../nss/nss_files/files-parse.c"
+LINE_PARSER
+(,
+ STRING_FIELD (result->gr_name, ISCOLON, 0);
+ if (line[0] == '\0'
+ && (result->gr_name[0] == '+' || result->gr_name[0] == '-'))
+ {
+ result->gr_passwd = NULL;
+ result->gr_gid = 0;
+ }
+ else
+ {
+ STRING_FIELD (result->gr_passwd, ISCOLON, 0);
+ if (result->gr_name[0] == '+' || result->gr_name[0] == '-')
+ INT_FIELD_MAYBE_NULL (result->gr_gid, ISCOLON, 0, 10, , 0)
+ else
+ INT_FIELD (result->gr_gid, ISCOLON, 0, 10,)
+ }
+ )
+
+static int
+_nss_nisplus_parse_grent (nis_result * result, struct group *gr,
+ char *buffer, size_t buflen)
+{
+#if 0
+ /* XXX here is a bug, sometimes we get some special characters at the
+ end of a line */
+ char *first_unused = buffer;
+ size_t room_left = buflen;
+ char *line;
+ int count;
+
+ if (result == NULL)
+ return -1;
+
+ if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
+ result->objects.objects_len != 1 ||
+ result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
+ strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+ "group_tbl") != 0 ||
+ result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 4)
+ return -1;
+
+ if (NISENTRYLEN (0, 0, result) >= room_left)
+ {
+ /* The line is too long for our buffer. */
+ no_more_room:
+ __set_errno (ERANGE);
+ return -1;
+ }
+
+ strncpy (first_unused, NISENTRYVAL (0, 0, result),
+ NISENTRYLEN (0, 0, result));
+ first_unused[NISENTRYLEN (0, 0, result)] = '\0';
+ gr->gr_name = first_unused;
+ room_left -= (strlen (first_unused) + 1);
+ first_unused += strlen (first_unused) + 1;
+
+ if (NISENTRYLEN (0, 1, result) >= room_left)
+ goto no_more_room;
+
+ strncpy (first_unused, NISENTRYVAL (0, 1, result),
+ NISENTRYLEN (0, 1, result));
+ first_unused[NISENTRYLEN (0, 1, result)] = '\0';
+ gr->gr_passwd = first_unused;
+ room_left -= (strlen (first_unused) + 1);
+ first_unused += strlen (first_unused) + 1;
+
+ if (NISENTRYLEN (0, 2, result) >= room_left)
+ goto no_more_room;
+
+ strncpy (first_unused, NISENTRYVAL (0, 2, result),
+ NISENTRYLEN (0, 2, result));
+ first_unused[NISENTRYLEN (0, 2, result)] = '\0';
+ gr->gr_gid = atoi (first_unused);
+ room_left -= (strlen (first_unused) + 1);
+ first_unused += strlen (first_unused) + 1;
+
+ if (NISENTRYLEN (0, 3, result) >= room_left)
+ goto no_more_room;
+
+ strncpy (first_unused, NISENTRYVAL (0, 3, result),
+ NISENTRYLEN (0, 3, result));
+ first_unused[NISENTRYLEN (0, 3, result)] = '\0';
+ line = first_unused;
+ room_left -= (strlen (line) + 1);
+ first_unused += strlen (line) + 1;
+ /* Adjust the pointer so it is aligned for
+ storing pointers. */
+ first_unused += __alignof__ (char *) - 1;
+ first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *));
+ gr->gr_mem = (char **) first_unused;
+
+ count = 0;
+ while (*line != '\0')
+ {
+ /* Skip leading blanks. */
+ while (isspace (*line))
+ ++line;
+
+ if (*line == '\0')
+ break;
+
+ if (room_left < sizeof (char *))
+ goto no_more_room;
+ room_left -= sizeof (char *);
+ gr->gr_mem[count] = line;
+
+ while (*line != '\0' && *line != ',' && !isspace(*line))
+ ++line;
+
+ if (line != gr->gr_mem[count])
+ {
+ *line = '\0';
+ ++line;
+ ++count;
+ }
+ else
+ gr->gr_mem[count] = NULL;
+ }
+ if (room_left < sizeof (char *))
+ goto no_more_room;
+ room_left -= sizeof (char *);
+ gr->gr_mem[count] = NULL;
+
+ return 1;
+#else
+ char *p = buffer;
+ size_t room_left = buflen;
+ struct parser_data *data = (void *) buffer;
+
+ if (result == NULL)
+ return -1;
+
+ if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
+ result->objects.objects_len != 1 ||
+ result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
+ strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+ "group_tbl") != 0 ||
+ result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 4)
+ return -1;
+
+ memset (p, '\0', room_left);
+
+ if (NISENTRYLEN (0, 0, result) + 1 > room_left)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+ strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
+ room_left -= (NISENTRYLEN (0, 0, result) + 1);
+ strcat (p, ":");
+
+ if (NISENTRYLEN (0, 1, result) + 1 > room_left)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+ strncat (p, NISENTRYVAL (0, 1, result), NISENTRYLEN (0, 1, result));
+ room_left -= (NISENTRYLEN (0, 1, result) + 1);
+ strcat (p, ":");
+ if (NISENTRYLEN (0, 2, result) + 1 > room_left)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+ strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result));
+ room_left -= (NISENTRYLEN (0, 2, result) + 1);
+ strcat (p, ":");
+ if (NISENTRYLEN (0, 3, result) + 1 > room_left)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+ strncat (p, NISENTRYVAL (0, 3, result), NISENTRYLEN (0, 3, result));
+ room_left -= (NISENTRYLEN (0, 3, result) + 1);
+
+ return _nss_files_parse_grent (p, gr, data, buflen);
+#endif
+}
+
+enum nss_status
+_nss_nisplus_setgrent (void)
+{
+ __libc_lock_lock (lock);
+
+ if (result)
+ nis_freeresult (result);
+ result = NULL;
+ if (names)
+ {
+ nis_freenames (names);
+ names = NULL;
+ }
+
+ __libc_lock_unlock (lock);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_endgrent (void)
+{
+ __libc_lock_lock (lock);
+
+ if (result)
+ nis_freeresult (result);
+ result = NULL;
+ if (names)
+ {
+ nis_freenames (names);
+ names = NULL;
+ }
+
+ __libc_lock_unlock (lock);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+static enum nss_status
+internal_nisplus_getgrent_r (struct group *gr, char *buffer, size_t buflen)
+{
+ int parse_res;
+
+ /* Get the next entry until we found a correct one. */
+ do
+ {
+ if (result == NULL)
+ {
+ names = nis_getnames ("group.org_dir");
+ if (names == NULL || names[0] == NULL)
+ return NSS_STATUS_UNAVAIL;
+
+ result = nis_first_entry (names[0]);
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ return niserr2nss (result->status);
+ }
+ else
+ {
+ nis_result *res;
+
+ res = nis_next_entry (names[0], &result->cookie);
+ nis_freeresult (result);
+ result = res;
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ return niserr2nss (result->status);
+ }
+
+ parse_res = _nss_nisplus_parse_grent (result, gr, buffer, buflen);
+ }
+ while (!parse_res);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_getgrent_r (struct group *result, char *buffer, size_t buflen)
+{
+ int status;
+
+ __libc_lock_lock (lock);
+
+ status = internal_nisplus_getgrent_r (result, buffer, buflen);
+
+ __libc_lock_unlock (lock);
+
+ return status;
+}
+
+enum nss_status
+_nss_nisplus_getgrnam_r (const char *name, struct group *gr,
+ char *buffer, size_t buflen)
+{
+ int parse_res;
+
+ if (name == NULL || strlen (name) > 8)
+ return NSS_STATUS_NOTFOUND;
+ else
+ {
+ nis_result *result;
+ char buf[strlen (name) + 24];
+
+ sprintf (buf, "[name=%s],group.org_dir", name);
+
+ result = nis_list (buf, EXPAND_NAME, NULL, NULL);
+
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ {
+ enum nss_status status = niserr2nss (result->status);
+
+ nis_freeresult (result);
+ return status;
+ }
+
+ parse_res = _nss_nisplus_parse_grent (result, gr, buffer, buflen);
+
+ nis_freeresult (result);
+
+ if (parse_res)
+ return NSS_STATUS_SUCCESS;
+
+ if (!parse_res && errno == ERANGE)
+ return NSS_STATUS_TRYAGAIN;
+ else
+ return NSS_STATUS_NOTFOUND;
+ }
+}
+
+enum nss_status
+_nss_nisplus_getgrgid_r (const gid_t gid, struct group *gr,
+ char *buffer, size_t buflen)
+{
+ int parse_res;
+ nis_result *result;
+ char buf[36];
+
+ sprintf (buf, "[gid=%d],group.org_dir", gid);
+
+ result = nis_list (buf, EXPAND_NAME, NULL, NULL);
+
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ {
+ enum nss_status status = niserr2nss (result->status);
+
+ nis_freeresult (result);
+ return status;
+ }
+
+ parse_res = _nss_nisplus_parse_grent (result, gr, buffer, buflen);
+
+ nis_freeresult (result);
+
+ if (parse_res)
+ return NSS_STATUS_SUCCESS;
+
+ if (!parse_res && errno == ERANGE)
+ return NSS_STATUS_TRYAGAIN;
+ else
+ return NSS_STATUS_NOTFOUND;
+}
diff --git a/nis/nss_nisplus/nisplus-hosts.c b/nis/nss_nisplus/nisplus-hosts.c
new file mode 100644
index 0000000000..0a486411de
--- /dev/null
+++ b/nis/nss_nisplus/nisplus-hosts.c
@@ -0,0 +1,412 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <nss.h>
+#include <netdb.h>
+#include <errno.h>
+#include <ctype.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <libc-lock.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+#include "nss-nisplus.h"
+
+__libc_lock_define_initialized (static, lock)
+
+static nis_result *result = NULL;
+static nis_name *names = NULL;
+
+#define NISENTRYVAL(idx,col,res) \
+ ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
+
+#define NISENTRYLEN(idx,col,res) \
+ ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
+
+/* Get implementation for some internal functions. */
+#include "../../resolv/mapv4v6addr.h"
+#include "../../resolv/mapv4v6hostent.h"
+
+#define ENTNAME hostent
+#define DATABASE "hosts"
+#define NEED_H_ERRNO
+
+#define ENTDATA hostent_data
+struct hostent_data
+ {
+ unsigned char host_addr[16]; /* IPv4 or IPv6 address. */
+ char *h_addr_ptrs[2]; /* Points to that and null terminator. */
+ };
+
+#define TRAILING_LIST_MEMBER h_aliases
+#define TRAILING_LIST_SEPARATOR_P isspace
+#include "../../nss/nss_files/files-parse.c"
+LINE_PARSER
+("#",
+ {
+ char *addr;
+
+ STRING_FIELD (addr, isspace, 1);
+
+ /* Parse address. */
+ if ((_res.options & RES_USE_INET6)
+ && inet_pton (AF_INET6, addr, entdata->host_addr) > 0)
+ {
+ result->h_addrtype = AF_INET6;
+ result->h_length = IN6ADDRSZ;
+ }
+ else
+ if (inet_pton (AF_INET, addr, entdata->host_addr) > 0)
+ {
+ if (_res.options & RES_USE_INET6)
+ {
+ map_v4v6_address ((char *) entdata->host_addr,
+ (char *) entdata->host_addr);
+ result->h_addrtype = AF_INET6;
+ result->h_length = IN6ADDRSZ;
+ }
+ else
+ {
+ result->h_addrtype = AF_INET;
+ result->h_length = INADDRSZ;
+ }
+ }
+ else
+ /* Illegal address: ignore line. */
+ return 0;
+
+ /* Store a pointer to the address in the expected form. */
+ entdata->h_addr_ptrs[0] = entdata->host_addr;
+ entdata->h_addr_ptrs[1] = NULL;
+ result->h_addr_list = entdata->h_addr_ptrs;
+
+ /* If we need the host entry in IPv6 form change it now. */
+ if (_res.options & RES_USE_INET6)
+ {
+ char *bufptr = data->linebuffer;
+ size_t buflen = (char *) data + datalen - bufptr;
+ map_v4v6_hostent (result, &bufptr, &buflen);
+ }
+
+ STRING_FIELD (result->h_name, isspace, 1);
+ }
+)
+
+
+static int
+_nss_nisplus_parse_hostent (nis_result *result, struct hostent *host,
+ char *buffer, size_t buflen)
+{
+ char *p = buffer;
+ size_t room_left = buflen;
+ int parse_res, i;
+ struct parser_data *data = (void *) buffer;
+
+ if (result == NULL)
+ return -1;
+
+ if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
+ result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
+ strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+ "hosts_tbl") != 0 ||
+ result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 4)
+ return -1;
+
+ memset (p, '\0', room_left);
+
+ /* Generate the hosts entry format and use the normal parser */
+ if (NISENTRYLEN (0, 2, result) + 1 > room_left)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+ strncpy (p, NISENTRYVAL (0, 2, result),
+ NISENTRYLEN (0, 2, result));
+ room_left -= (NISENTRYLEN (0, 2, result) + 1);
+
+ if (NISENTRYLEN (0, 0, result) + 1 > room_left)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+ strcat (p, "\t");
+ strncat (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
+ room_left -= (NISENTRYLEN (0, 0, result) + 1);
+ /* + 1: We overwrite the last \0 */
+
+ for (i = 1; i < result->objects.objects_len; i++)
+ {
+ if (NISENTRYLEN (i, 1, result) + 1 > room_left)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+ strcat (p, " ");
+ strcat (p, NISENTRYVAL (i, 1, result));
+ room_left -= (NISENTRYLEN (i, 1, result) + 1);
+ }
+
+ parse_res = parse_line (p, host, data, buflen);
+
+ return parse_res;
+}
+
+enum nss_status
+_nss_nisplus_sethostent (void)
+{
+ __libc_lock_lock (lock);
+
+ if (result)
+ nis_freeresult (result);
+ result = NULL;
+ if (names)
+ {
+ nis_freenames (names);
+ names = NULL;
+ }
+
+ __libc_lock_unlock (lock);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_endhostent (void)
+{
+ __libc_lock_lock (lock);
+
+ if (result)
+ nis_freeresult (result);
+ result = NULL;
+ if (names)
+ {
+ nis_freenames (names);
+ names = NULL;
+ }
+
+ __libc_lock_unlock (lock);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+static enum nss_status
+internal_nisplus_gethostent_r (struct hostent *host, char *buffer,
+ size_t buflen, int *herrnop)
+{
+ int parse_res;
+
+ /* Get the next entry until we found a correct one. */
+ do
+ {
+ if (result == NULL)
+ {
+ names = nis_getnames("hosts.org_dir");
+ if (names == NULL || names[0] == NULL)
+ return NSS_STATUS_UNAVAIL;
+
+ result = nis_first_entry(names[0]);
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ {
+ int retval;
+
+ retval = niserr2nss (result->status);
+ if (retval == NSS_STATUS_TRYAGAIN)
+ {
+ *herrnop = NETDB_INTERNAL;
+ __set_errno (EAGAIN);
+ }
+ return retval;
+ }
+
+ }
+ else
+ {
+ nis_result *res2;
+
+ res2 = nis_next_entry(names[0], &result->cookie);
+ nis_freeresult (result);
+ result = res2;
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ {
+ int retval;
+
+ retval = niserr2nss (result->status);
+ if (retval == NSS_STATUS_TRYAGAIN)
+ {
+ *herrnop = NETDB_INTERNAL;
+ __set_errno (EAGAIN);
+ }
+ return retval;
+ }
+ }
+
+ parse_res = _nss_nisplus_parse_hostent (result, host, buffer, buflen);
+ if (!parse_res && errno == ERANGE)
+ {
+ *herrnop = NETDB_INTERNAL;
+ return NSS_STATUS_TRYAGAIN;
+ }
+
+ } while (!parse_res);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_gethostent_r (struct hostent *result, char *buffer,
+ size_t buflen, int *herrnop)
+{
+ int status;
+
+ __libc_lock_lock (lock);
+
+ status = internal_nisplus_gethostent_r (result, buffer, buflen, herrnop);
+
+ __libc_lock_unlock (lock);
+
+ return status;
+}
+
+enum nss_status
+_nss_nisplus_gethostbyname2_r (const char *name, int af, struct hostent *host,
+ char *buffer, size_t buflen, int *herrnop)
+{
+ int parse_res, retval;
+
+ if (name == NULL)
+ {
+ __set_errno (EINVAL);
+ *herrnop = NETDB_INTERNAL;
+ return NSS_STATUS_NOTFOUND;
+ }
+ else
+ {
+ nis_result *result;
+ char buf[strlen (name) + 255];
+
+ /* Search at first in the alias list, and use the correct name
+ for the next search */
+ sprintf(buf, "[name=%s],hosts.org_dir", name);
+ result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+
+ /* If we do not find it, try it as original name. But if the
+ database is correct, we should find it in the first case, too */
+ if ((result->status != NIS_SUCCESS &&
+ result->status != NIS_S_SUCCESS) ||
+ result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
+ strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+ "hosts_tbl") != 0 ||
+ result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len
+ < 3)
+ sprintf(buf, "[cname=%s],hosts.org_dir", name);
+ else
+ sprintf(buf, "[cname=%s],hosts.org_dir", NISENTRYVAL(0, 0, result));
+
+ nis_freeresult (result);
+ result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+
+ retval = niserr2nss (result->status);
+ if (retval != NSS_STATUS_SUCCESS)
+ {
+ if (retval == NSS_STATUS_TRYAGAIN)
+ {
+ __set_errno (EAGAIN);
+ *herrnop = NETDB_INTERNAL;
+ }
+ nis_freeresult (result);
+ return retval;
+ }
+
+ parse_res = _nss_nisplus_parse_hostent (result, host, buffer, buflen);
+
+ nis_freeresult (result);
+
+ if (parse_res)
+ return NSS_STATUS_SUCCESS;
+
+ *herrnop = NETDB_INTERNAL;
+ if (!parse_res && errno == ERANGE)
+ return NSS_STATUS_TRYAGAIN;
+ else
+ return NSS_STATUS_NOTFOUND;
+ }
+}
+
+enum nss_status
+_nss_nisplus_gethostbyname_r (const char *name, struct hostent *host,
+ char *buffer, size_t buflen, int *h_errnop)
+{
+ if (_res.options & RES_USE_INET6)
+ {
+ enum nss_status status;
+
+ status = _nss_nisplus_gethostbyname2_r (name, AF_INET6, host, buffer,
+ buflen, h_errnop);
+ if (status == NSS_STATUS_SUCCESS)
+ return status;
+ }
+
+ return _nss_nisplus_gethostbyname2_r (name, AF_INET, host, buffer,
+ buflen, h_errnop);
+}
+
+enum nss_status
+_nss_nisplus_gethostbyaddr_r (const char *addr, struct hostent *host,
+ char *buffer, size_t buflen, int *herrnop)
+{
+ if (addr == NULL)
+ return NSS_STATUS_NOTFOUND;
+ else
+ {
+ nis_result *result;
+ char buf[24 + strlen (addr)];
+ int retval, parse_res;
+
+ sprintf(buf, "[addr=%s],hosts.org_dir", addr);
+
+ result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+
+ retval = niserr2nss (result->status);
+ if (retval != NSS_STATUS_SUCCESS)
+ {
+ if (retval == NSS_STATUS_TRYAGAIN)
+ {
+ __set_errno (EAGAIN);
+ *herrnop = NETDB_INTERNAL;
+ }
+ nis_freeresult (result);
+ return retval;
+ }
+
+ parse_res = _nss_nisplus_parse_hostent (result, host, buffer, buflen);
+
+ nis_freeresult (result);
+
+ if (parse_res)
+ return NSS_STATUS_SUCCESS;
+
+ *herrnop = NETDB_INTERNAL;
+ if (!parse_res && errno == ERANGE)
+ return NSS_STATUS_TRYAGAIN;
+ else
+ return NSS_STATUS_NOTFOUND;
+ }
+}
diff --git a/nis/nss_nisplus/nisplus-netgrp.c b/nis/nss_nisplus/nisplus-netgrp.c
new file mode 100644
index 0000000000..766d2bc773
--- /dev/null
+++ b/nis/nss_nisplus/nisplus-netgrp.c
@@ -0,0 +1,141 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <nss.h>
+#include <errno.h>
+#include <ctype.h>
+#include <netdb.h>
+#include <string.h>
+#include <netgroup.h>
+#include <libc-lock.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+#include "nss-nisplus.h"
+
+__libc_lock_define_initialized (static, lock)
+
+static char *data = NULL;
+static size_t data_size = 0;
+static char *cursor = NULL;;
+
+extern enum nss_status
+_nss_netgroup_parseline (char **cursor, struct __netgrent *result,
+ char *buffer, size_t buflen);
+
+#define NISENTRYVAL(idx,col,res) \
+ ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
+
+#define NISENTRYLEN(idx,col,res) \
+ ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
+
+enum nss_status
+_nss_nisplus_setnetgrent (char *group)
+
+{
+ enum nss_status status;
+ nis_result *result;
+ char buf[strlen (group) + 30];
+ int i;
+ size_t len;
+
+ if (group == NULL || group[0] == '\0')
+ return NSS_STATUS_UNAVAIL;
+
+ status = NSS_STATUS_SUCCESS;
+
+ __libc_lock_lock (lock);
+
+ if (data != NULL)
+ {
+ free (data);
+ data = NULL;
+ data_size = 0;
+ cursor = NULL;
+ }
+
+ sprintf(buf, "[name=%s],netgroup.org_dir", group);
+
+ result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ status = niserr2nss (result->status);
+
+ len = 0;
+ for (i = 0; i < result->objects.objects_len; i++)
+ len += 1 + NISENTRYLEN (i, 1, result) + 1 + NISENTRYLEN(i,2,result)
+ + 1 + NISENTRYLEN(i,3,result) + 1 + NISENTRYLEN(i,4,result) + 2;
+
+ data = malloc (len+1);
+ memset (data, '\0', len+1);
+
+ for (i = 0; i < result->objects.objects_len; i++)
+ {
+ strncat (data, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));
+ strcat (data," (");
+ strncat (data, NISENTRYVAL(i,2,result), NISENTRYLEN (i, 2, result));
+ strcat (data, ",");
+ strncat (data, NISENTRYVAL(i,3,result), NISENTRYLEN (i, 3, result));
+ strcat (data, ",");
+ strncat (data, NISENTRYVAL(i,4,result), NISENTRYLEN (i, 4, result));
+ strcat (data, ") ");
+ }
+
+ nis_freeresult (result);
+
+ __libc_lock_unlock (lock);
+
+ return status;
+}
+
+enum nss_status
+_nss_nisplus_endnetgrent (void)
+{
+ __libc_lock_lock (lock);
+
+ if (data != NULL)
+ {
+ free (data);
+ data = NULL;
+ data_size = 0;
+ cursor = NULL;
+ }
+
+ __libc_lock_unlock (lock);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_getnetgrent_r (struct __netgrent *result,
+ char *buffer, size_t buflen)
+{
+ enum nss_status status;
+
+ if (cursor == NULL)
+ return NSS_STATUS_NOTFOUND;
+
+ __libc_lock_lock (lock);
+
+ status = _nss_netgroup_parseline (&cursor, result, buffer, buflen);
+
+ __libc_lock_unlock (lock);
+
+ return status;
+}
diff --git a/nis/nss_nisplus/nisplus-network.c b/nis/nss_nisplus/nisplus-network.c
new file mode 100644
index 0000000000..28580b6bc9
--- /dev/null
+++ b/nis/nss_nisplus/nisplus-network.c
@@ -0,0 +1,340 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <nss.h>
+#include <netdb.h>
+#include <errno.h>
+#include <ctype.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <libc-lock.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+#include "nss-nisplus.h"
+
+/* Get the declaration of the parser function. */
+#define ENTNAME netent
+#define DATABASE "networks"
+#define TRAILING_LIST_MEMBER n_aliases
+#define TRAILING_LIST_SEPARATOR_P isspace
+#include "../nss/nss_files/files-parse.c"
+LINE_PARSER
+("#",
+ {
+ char *addr;
+
+ STRING_FIELD (result->n_name, isspace, 1);
+
+ STRING_FIELD (addr, isspace, 1);
+ result->n_net = inet_network (addr);
+
+ })
+
+__libc_lock_define_initialized (static, lock)
+
+static nis_result *result = NULL;
+static nis_name *names = NULL;
+
+#define NISENTRYVAL(idx,col,res) \
+ ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
+
+#define NISENTRYLEN(idx,col,res) \
+ ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
+
+
+static int
+_nss_nisplus_parse_netent (nis_result *result, struct netent *network,
+ char *buffer, size_t buflen)
+{
+ char *p = buffer;
+ size_t room_left = buflen;
+ int i;
+ struct parser_data *data = (void *) buffer;
+
+ if (result == NULL)
+ return -1;
+
+ if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
+ result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
+ strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+ "networks_tbl") != 0 ||
+ result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3)
+ return -1;
+
+ /* Generate the network entry format and use the normal parser */
+ if (NISENTRYLEN (0, 0, result) +1 > room_left)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+
+ memset (p, '\0', room_left);
+
+ strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
+ room_left -= (NISENTRYLEN (0, 0, result) +1);
+
+ if (NISENTRYLEN (0, 2, result) +1 > room_left)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+ strcat (p, "\t");
+ strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result));
+ room_left -= (NISENTRYLEN (0, 2, result) + 1);
+ /* + 1: We overwrite the last \0 */
+
+ for (i = 1; i < result->objects.objects_len; i++)
+ /* XXX should we start with i = 0 or with i = 1 ? */
+ {
+ if (NISENTRYLEN (i, 1, result) +1 > room_left)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+ strcat (p, " ");
+ strncat (p, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));
+ room_left -= (NISENTRYLEN (i, 1, result) + 1);
+ }
+
+ return _nss_files_parse_netent (p, network, data, buflen);
+}
+
+enum nss_status
+_nss_nisplus_setnetent (void)
+{
+ __libc_lock_lock (lock);
+
+ if (result)
+ nis_freeresult (result);
+ result = NULL;
+ if (names)
+ {
+ nis_freenames (names);
+ names = NULL;
+ }
+
+ __libc_lock_unlock (lock);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_endnetent (void)
+{
+ __libc_lock_lock (lock);
+
+ if (result)
+ nis_freeresult (result);
+ result = NULL;
+ if (names)
+ {
+ nis_freenames (names);
+ names = NULL;
+ }
+
+ __libc_lock_unlock (lock);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+static enum nss_status
+internal_nisplus_getnetent_r (struct netent *network, char *buffer,
+ size_t buflen, int *herrnop)
+{
+ int parse_res;
+
+ /* Get the next entry until we found a correct one. */
+ do
+ {
+ if (result == NULL)
+ {
+ names = nis_getnames("networks.org_dir");
+ if (names == NULL || names[0] == NULL)
+ return NSS_STATUS_UNAVAIL;
+
+ result = nis_first_entry(names[0]);
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ {
+ int retval;
+
+ retval = niserr2nss (result->status);
+ if (retval == NSS_STATUS_TRYAGAIN)
+ {
+ *herrnop = NETDB_INTERNAL;
+ __set_errno (EAGAIN);
+ }
+ return retval;
+ }
+ }
+ else
+ {
+ nis_result *res;
+
+ res = nis_next_entry(names[0], &result->cookie);
+ nis_freeresult (result);
+ result = res;
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ {
+ int retval;
+
+ retval = niserr2nss (result->status);
+ if (retval == NSS_STATUS_TRYAGAIN)
+ {
+ *herrnop = NETDB_INTERNAL;
+ __set_errno (EAGAIN);
+ }
+ return retval;
+ }
+ }
+
+ parse_res = _nss_nisplus_parse_netent (result, network, buffer, buflen);
+ if (!parse_res && errno == ERANGE)
+ {
+ *herrnop = NETDB_INTERNAL;
+ return NSS_STATUS_TRYAGAIN;
+ }
+
+ } while (!parse_res);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_getnetent_r (struct netent *result, char *buffer,
+ size_t buflen, int *herrnop)
+{
+ int status;
+
+ __libc_lock_lock (lock);
+
+ status = internal_nisplus_getnetent_r (result, buffer, buflen, herrnop);
+
+ __libc_lock_unlock (lock);
+
+ return status;
+}
+
+enum nss_status
+_nss_nisplus_getnetbyname_r (const char *name, struct netent *network,
+ char *buffer, size_t buflen, int *herrnop)
+{
+ int parse_res, retval;
+
+ if (name == NULL)
+ {
+ __set_errno (EINVAL);
+ *herrnop = NETDB_INTERNAL;
+ return NSS_STATUS_UNAVAIL;
+ }
+ else
+ {
+ nis_result *result;
+ char buf[strlen (name) + 255];
+
+
+ /* Search at first in the alias list, and use the correct name
+ for the next search */
+ sprintf(buf, "[name=%s],networks.org_dir", name);
+ result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+
+ /* If we do not find it, try it as original name. But if the
+ database is correct, we should find it in the first case, too */
+ if ((result->status != NIS_SUCCESS &&
+ result->status != NIS_S_SUCCESS) ||
+ result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
+ strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+ "networks_tbl") != 0 ||
+ result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3)
+ sprintf(buf, "[cname=%s],networks.org_dir", name);
+ else
+ sprintf(buf, "[cname=%s],networks.org_dir", NISENTRYVAL(0, 0, result));
+
+ nis_freeresult (result);
+ result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+
+ retval = niserr2nss (result->status);
+ if (retval != NSS_STATUS_SUCCESS)
+ {
+ if (retval == NSS_STATUS_TRYAGAIN)
+ {
+ __set_errno (EAGAIN);
+ *herrnop = NETDB_INTERNAL;
+ }
+ nis_freeresult (result);
+ return retval;
+ }
+
+ parse_res = _nss_nisplus_parse_netent (result, network, buffer, buflen);
+
+ nis_freeresult (result);
+
+ if (parse_res)
+ return NSS_STATUS_SUCCESS;
+
+ *herrnop = NETDB_INTERNAL;
+ if (!parse_res && errno == ERANGE)
+ return NSS_STATUS_TRYAGAIN;
+ else
+ return NSS_STATUS_NOTFOUND;
+ }
+}
+
+/* XXX type is ignored, SUN's NIS+ table doesn't support it */
+enum nss_status
+_nss_nisplus_getnetbyaddr_r (const unsigned long addr, const int type,
+ struct netent *network,
+ char *buffer, size_t buflen, int *herrnop)
+{
+ int parse_res, retval;
+ nis_result *result;
+ char buf[1024];
+ struct in_addr in;
+
+ in = inet_makeaddr (addr, 0);
+ snprintf(buf, sizeof (buf) - 1, "[addr=%s],networks.org_dir",
+ inet_ntoa (in));
+
+ result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+
+ retval = niserr2nss (result->status);
+ if (retval != NSS_STATUS_SUCCESS)
+ {
+ if (retval == NSS_STATUS_TRYAGAIN)
+ {
+ __set_errno (EAGAIN);
+ *herrnop = NETDB_INTERNAL;
+ }
+ nis_freeresult (result);
+ return retval;
+ }
+
+ parse_res = _nss_nisplus_parse_netent (result, network, buffer, buflen);
+
+ nis_freeresult (result);
+
+ if (parse_res)
+ return NSS_STATUS_SUCCESS;
+
+ *herrnop = NETDB_INTERNAL;
+ if (!parse_res && errno == ERANGE)
+ return NSS_STATUS_TRYAGAIN;
+ else
+ return NSS_STATUS_NOTFOUND;
+}
diff --git a/nis/nss_nisplus/nisplus-proto.c b/nis/nss_nisplus/nisplus-proto.c
new file mode 100644
index 0000000000..b26cb8230e
--- /dev/null
+++ b/nis/nss_nisplus/nisplus-proto.c
@@ -0,0 +1,284 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <nss.h>
+#include <errno.h>
+#include <ctype.h>
+#include <netdb.h>
+#include <string.h>
+#include <libc-lock.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+#include "nss-nisplus.h"
+
+__libc_lock_define_initialized (static, lock)
+
+static nis_result *result = NULL;
+static nis_name *names = NULL;
+
+#define ENTNAME protoent
+#define DATABASE "protocols"
+#define TRAILING_LIST_MEMBER p_aliases
+#define TRAILING_LIST_SEPARATOR_P isspace
+#include "../../nss/nss_files/files-parse.c"
+LINE_PARSER
+("#",
+ STRING_FIELD (result->p_name, isspace, 1);
+ INT_FIELD (result->p_proto, isspace, 1, 10,);
+)
+
+#define NISENTRYVAL(idx,col,res) \
+ ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
+
+#define NISENTRYLEN(idx,col,res) \
+ ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
+
+static int
+_nss_nisplus_parse_protoent (nis_result * result, struct protoent *proto,
+ char *buffer, size_t buflen)
+{
+ char *p = buffer;
+ size_t room_left = buflen;
+ int i;
+ struct parser_data *data = (void *) buffer;
+
+ if (result == NULL)
+ return -1;
+
+ if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
+ result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
+ strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+ "protocols_tbl") != 0 ||
+ result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3)
+ return -1;
+
+ memset (p, '\0', room_left);
+
+ /* Generate the protocols entry format and use the normal parser */
+ if (NISENTRYLEN (0, 0, result) + 1 > room_left)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+ strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
+ room_left -= (NISENTRYLEN (0, 0, result) + 1);
+
+ if (NISENTRYLEN (0, 2, result) + 1 > room_left)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+ strcat (p, "\t");
+ strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result));
+ room_left -= (NISENTRYLEN (0, 2, result) + 1);
+ /* + 1: We overwrite the last \0 */
+
+ for (i = 1; i < result->objects.objects_len; i++)
+ {
+ if (NISENTRYLEN (i, 1, result) + 1 > room_left)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+ strcat (p, " ");
+ strncat (p, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));
+ room_left -= (NISENTRYLEN (i, 1, result) + 1);
+ }
+
+ return _nss_files_parse_protoent (p, proto, data, buflen);
+}
+
+enum nss_status
+_nss_nisplus_setprotoent (void)
+{
+ __libc_lock_lock (lock);
+
+ if (result)
+ nis_freeresult (result);
+ result = NULL;
+ if (names)
+ {
+ nis_freenames (names);
+ names = NULL;
+ }
+
+ __libc_lock_unlock (lock);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_endprotoent (void)
+{
+ __libc_lock_lock (lock);
+
+ if (result)
+ nis_freeresult (result);
+ result = NULL;
+ if (names)
+ {
+ nis_freenames (names);
+ names = NULL;
+ }
+
+ __libc_lock_unlock (lock);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+static enum nss_status
+internal_nisplus_getprotoent_r (struct protoent *proto, char *buffer,
+ size_t buflen)
+{
+ int parse_res;
+
+ /* Get the next entry until we found a correct one. */
+ do
+ {
+ if (result == NULL)
+ {
+ names = nis_getnames ("protocols.org_dir");
+ if (names == NULL || names[0] == NULL)
+ return NSS_STATUS_UNAVAIL;
+
+ result = nis_first_entry (names[0]);
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ return niserr2nss (result->status);
+ }
+ else
+ {
+ nis_result *res;
+
+ res = nis_next_entry (names[0], &result->cookie);
+ nis_freeresult (result);
+ result = res;
+
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ return niserr2nss (result->status);
+ }
+
+ parse_res = _nss_nisplus_parse_protoent (result, proto, buffer, buflen);
+ }
+ while (!parse_res);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_getprotoent_r (struct protoent *result, char *buffer,
+ size_t buflen)
+{
+ int status;
+
+ __libc_lock_lock (lock);
+
+ status = internal_nisplus_getprotoent_r (result, buffer, buflen);
+
+ __libc_lock_unlock (lock);
+
+ return status;
+}
+
+enum nss_status
+_nss_nisplus_getprotobyname_r (const char *name, struct protoent *proto,
+ char *buffer, size_t buflen)
+{
+ int parse_res;
+
+ if (name == NULL)
+ return NSS_STATUS_NOTFOUND;
+ else
+ {
+ nis_result *result;
+ char buf[strlen (name) + 255];
+
+ /* Search at first in the alias list, and use the correct name
+ for the next search */
+ sprintf (buf, "[name=%s],protocols.org_dir", name);
+ result = nis_list (buf, EXPAND_NAME, NULL, NULL);
+
+ /* If we do not find it, try it as original name. But if the
+ database is correct, we should find it in the first case, too */
+ if ((result->status != NIS_SUCCESS &&
+ result->status != NIS_S_SUCCESS) ||
+ result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
+ strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+ "protocols_tbl") != 0 ||
+ result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3)
+ sprintf (buf, "[cname=%s],protocols.org_dir", name);
+ else
+ sprintf (buf, "[cname=%s],protocols.org_dir", NISENTRYVAL (0, 0, result));
+
+ nis_freeresult (result);
+ result = nis_list (buf, EXPAND_NAME, NULL, NULL);
+
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ {
+ enum nss_status status = niserr2nss (result->status);
+
+ nis_freeresult (result);
+ return status;
+ }
+
+ parse_res = _nss_nisplus_parse_protoent (result, proto, buffer, buflen);
+
+ nis_freeresult (result);
+
+ if (parse_res)
+ return NSS_STATUS_SUCCESS;
+
+ if (!parse_res && errno == ERANGE)
+ return NSS_STATUS_TRYAGAIN;
+ else
+ return NSS_STATUS_NOTFOUND;
+ }
+}
+
+enum nss_status
+_nss_nisplus_getprotobynumber_r (const int number, struct protoent *proto,
+ char *buffer, size_t buflen)
+{
+ int parse_res;
+ nis_result *result;
+ char buf[46];
+
+ snprintf (buf, sizeof (buf), "[number=%d],protocols.org_dir", number);
+
+ result = nis_list (buf, EXPAND_NAME, NULL, NULL);
+
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ {
+ enum nss_status status = niserr2nss (result->status);
+
+ nis_freeresult (result);
+ return status;
+ }
+
+ parse_res = _nss_nisplus_parse_protoent (result, proto, buffer, buflen);
+
+ nis_freeresult (result);
+ if (parse_res)
+ return NSS_STATUS_SUCCESS;
+
+ if (!parse_res && errno == ERANGE)
+ return NSS_STATUS_TRYAGAIN;
+ else
+ return NSS_STATUS_NOTFOUND;
+}
diff --git a/nis/nss_nisplus/nisplus-publickey.c b/nis/nss_nisplus/nisplus-publickey.c
new file mode 100644
index 0000000000..7312c91229
--- /dev/null
+++ b/nis/nss_nisplus/nisplus-publickey.c
@@ -0,0 +1,347 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <nss.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+#include <rpc/key_prot.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+#include <nss-nisplus.h>
+
+extern int xdecrypt (char *, char *);
+
+/* If we found the entry, we give a SUCCESS and an empty key back. */
+enum nss_status
+_nss_nisplus_getpublickey (const char *netname, char *pkey)
+{
+ nis_result *res;
+ enum nss_status retval;
+ char buf[NIS_MAXNAMELEN+2];
+ char *domain, *cptr;
+ int len;
+
+ pkey[0] = 0;
+
+ if (netname == NULL)
+ {
+ __set_errno (EINVAL);
+ return NSS_STATUS_UNAVAIL;
+ }
+
+ domain = strchr (netname, '@');
+ if (!domain)
+ return NSS_STATUS_UNAVAIL;
+ domain++;
+
+ snprintf (buf, NIS_MAXNAMELEN,
+ "[auth_name=%s,auth_type=DES],cred.org_dir.%s",
+ netname, domain);
+
+ if (buf[strlen (buf)-1] != '.')
+ strcat(buf, ".");
+
+ res = nis_list(buf, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH,
+ NULL, NULL);
+
+ retval = niserr2nss (res->status);
+
+ if (retval != NSS_STATUS_SUCCESS)
+ {
+ if (retval == NSS_STATUS_TRYAGAIN)
+ __set_errno (EAGAIN);
+ nis_freeresult (res);
+ return retval;
+ }
+
+ if (res->objects.objects_len > 1)
+ {
+ /*
+ * More than one principal with same uid?
+ * something wrong with cred table. Should be unique
+ * Warn user and continue.
+ */
+ printf (_("DES entry for netname %s not unique\n"), netname);
+ nis_freeresult (res);
+ return NSS_STATUS_SUCCESS;
+ }
+
+ len = ENTRY_LEN (res->objects.objects_val, 3);
+ memcpy (pkey, ENTRY_VAL (res->objects.objects_val,3), len);
+ pkey[len] = 0;
+ cptr = strchr (pkey, ':');
+ if (cptr)
+ cptr[0] = '\0';
+ nis_freeresult (res);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd)
+{
+ nis_result *res;
+ enum nss_status retval;
+ char buf[NIS_MAXNAMELEN+2];
+ char *domain, *cptr;
+ int len;
+
+ skey[0] = 0;
+
+ if (netname == NULL)
+ {
+ __set_errno (EINVAL);
+ return NSS_STATUS_UNAVAIL;
+ }
+
+ domain = strchr (netname, '@');
+ if (!domain)
+ return NSS_STATUS_UNAVAIL;
+ domain++;
+
+ snprintf (buf, NIS_MAXNAMELEN,
+ "[auth_name=%s,auth_type=DES],cred.org_dir.%s",
+ netname, domain);
+
+ if (buf[strlen(buf)-1] != '.')
+ strcat(buf, ".");
+
+ res = nis_list (buf, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH,
+ NULL, NULL);
+
+ retval = niserr2nss (res->status);
+
+ if (retval != NSS_STATUS_SUCCESS)
+ {
+ if (retval == NSS_STATUS_TRYAGAIN)
+ __set_errno (EAGAIN);
+ nis_freeresult (res);
+ return retval;
+ }
+
+ if (res->objects.objects_len > 1)
+ {
+ /*
+ * More than one principal with same uid?
+ * something wrong with cred table. Should be unique
+ * Warn user and continue.
+ */
+ printf (_("DES entry for netname %s not unique\n"), netname);
+ nis_freeresult (res);
+ return NSS_STATUS_SUCCESS;
+ }
+
+ len = ENTRY_LEN (res->objects.objects_val, 4);
+ memcpy (buf, ENTRY_VAL (res->objects.objects_val,4), len);
+ skey[len] = 0;
+ cptr = strchr (skey, ':');
+ if (cptr)
+ cptr[0] = '\0';
+ nis_freeresult (res);
+
+ if (!xdecrypt (buf, passwd))
+ return NSS_STATUS_SUCCESS;
+
+ if (memcmp (buf, &(buf[HEXKEYBYTES]), KEYCHECKSUMSIZE) != 0)
+ return NSS_STATUS_SUCCESS;
+
+ buf[HEXKEYBYTES] = 0;
+ strcpy (skey, buf);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+/* Parse information from the passed string.
+ The format of the string passed is gid,grp,grp, ... */
+static enum nss_status
+parse_grp_str (const char *s, gid_t *gidp, int *gidlenp, gid_t *gidlist)
+{
+ int gidlen;
+
+ if (!s || (!isdigit (*s)))
+ {
+ syslog (LOG_ERR, "netname2user: missing group id list in '%s'.", s);
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ *gidp = (atoi (s));
+
+ gidlen = 0;
+
+ while ((s = strchr (s, ',')) != NULL)
+ {
+ s++;
+ gidlist[gidlen++] = atoi (s);
+ }
+ *gidlenp = gidlen;
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
+ gid_t *gidp, int *gidlenp, gid_t *gidlist)
+{
+ char *domain;
+ nis_result *res;
+ char sname[NIS_MAXNAMELEN+1]; /* search criteria + table name */
+ char principal[NIS_MAXNAMELEN+1];
+ int len;
+
+ /* 1. Get home domain of user. */
+ domain = strchr (netname, '@');
+ if (! domain)
+ return NSS_STATUS_UNAVAIL;
+
+ domain++; /* skip '@' */
+
+ /* 2. Get user's nisplus principal name. */
+ if ((strlen (netname) + strlen (domain)+45) >
+ (size_t) NIS_MAXNAMELEN)
+ return NSS_STATUS_UNAVAIL;
+
+ snprintf (sname, NIS_MAXNAMELEN,
+ "[auth_name=%s,auth_type=DES],cred.org_dir.%s",
+ netname, domain);
+ if (sname[strlen (sname) - 1] != '.')
+ strcat(sname, ".");
+
+ /* must use authenticated call here */
+ /* XXX but we cant, for now. XXX */
+ res = nis_list (sname, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH,
+ NULL, NULL);
+ switch(res->status)
+ {
+ case NIS_SUCCESS:
+ case NIS_S_SUCCESS:
+ break; /* go and do something useful */
+ case NIS_NOTFOUND:
+ case NIS_PARTIAL:
+ case NIS_NOSUCHNAME:
+ case NIS_NOSUCHTABLE:
+ nis_freeresult (res);
+ return NSS_STATUS_NOTFOUND;
+ case NIS_S_NOTFOUND:
+ case NIS_TRYAGAIN:
+ syslog (LOG_ERR, "netname2user: (nis+ lookup): %s\n",
+ nis_sperrno (res->status));
+ nis_freeresult (res);
+ return NSS_STATUS_TRYAGAIN;
+ default:
+ syslog (LOG_ERR, "netname2user: (nis+ lookup): %s\n",
+ nis_sperrno (res->status));
+ nis_freeresult (res);
+ return NSS_STATUS_UNAVAIL;
+ }
+
+ if (res->objects.objects_len > 1)
+ {
+ /*
+ * A netname belonging to more than one principal?
+ * Something wrong with cred table. should be unique.
+ * Warn user and continue.
+ */
+ syslog (LOG_ALERT,
+ _("netname2user: DES entry for %s in directory %s not unique"),
+ netname, domain);
+ }
+
+ len = ENTRY_LEN(res->objects.objects_val, 0);
+ strncpy(principal, ENTRY_VAL(res->objects.objects_val, 0), len);
+ principal[len] = '\0';
+ nis_freeresult(res);
+
+ if (principal[0] == '\0')
+ return NSS_STATUS_UNAVAIL;
+
+ /*
+ * 3. Use principal name to look up uid/gid information in
+ * LOCAL entry in **local** cred table.
+ */
+ domain = nis_local_directory ();
+ if ((strlen(principal)+strlen(domain)+45) >
+ (size_t) NIS_MAXNAMELEN)
+ {
+ syslog (LOG_ERR, _("netname2user: principal name '%s' too long"),
+ principal);
+ return NSS_STATUS_UNAVAIL;
+ }
+ sprintf(sname, "[cname=%s,auth_type=LOCAL],cred.org_dir.%s",
+ principal, domain);
+ if (sname[strlen(sname) - 1] != '.')
+ strcat(sname, ".");
+
+ /* must use authenticated call here */
+ /* XXX but we cant, for now. XXX */
+ res = nis_list(sname, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH,
+ NULL, NULL);
+ switch(res->status) {
+ case NIS_NOTFOUND:
+ case NIS_PARTIAL:
+ case NIS_NOSUCHNAME:
+ case NIS_NOSUCHTABLE:
+ nis_freeresult (res);
+ return NSS_STATUS_NOTFOUND;
+ case NIS_S_NOTFOUND:
+ case NIS_TRYAGAIN:
+ syslog (LOG_ERR,
+ "netname2user: (nis+ lookup): %s\n",
+ nis_sperrno (res->status));
+ nis_freeresult (res);
+ return NSS_STATUS_TRYAGAIN;
+ case NIS_SUCCESS:
+ case NIS_S_SUCCESS:
+ break; /* go and do something useful */
+ default:
+ syslog (LOG_ERR, "netname2user: (nis+ lookup): %s\n",
+ nis_sperrno (res->status));
+ nis_freeresult (res);
+ return NSS_STATUS_UNAVAIL;
+ }
+
+ if (res->objects.objects_len > 1)
+ {
+ /*
+ * A principal can have more than one LOCAL entry?
+ * Something wrong with cred table.
+ * Warn user and continue.
+ */
+ syslog(LOG_ALERT,
+ _("netname2user: LOCAL entry for %s in directory %s not unique"),
+ netname, domain);
+ }
+ /* Fetch the uid */
+ *uidp = (atoi (ENTRY_VAL (res->objects.objects_val, 2)));
+
+ if (*uidp == 0)
+ {
+ syslog (LOG_ERR, _("netname2user: should not have uid 0"));
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ parse_grp_str (ENTRY_VAL (res->objects.objects_val, 3),
+ gidp, gidlenp, gidlist);
+
+ nis_freeresult (res);
+ return NSS_STATUS_SUCCESS;
+}
diff --git a/nis/nss_nisplus/nisplus-pwd.c b/nis/nss_nisplus/nisplus-pwd.c
new file mode 100644
index 0000000000..3717d5e98a
--- /dev/null
+++ b/nis/nss_nisplus/nisplus-pwd.c
@@ -0,0 +1,293 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <nss.h>
+#include <errno.h>
+#include <pwd.h>
+#include <string.h>
+#include <libc-lock.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+#include "nss-nisplus.h"
+
+__libc_lock_define_initialized (static, lock)
+
+static nis_result *result = NULL;
+static nis_name *names = NULL;
+
+#define NISENTRYVAL(idx,col,res) \
+ ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
+
+#define NISENTRYLEN(idx,col,res) \
+ ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
+
+static int
+_nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
+ char *buffer, size_t buflen)
+{
+ char *first_unused = buffer;
+ size_t room_left = buflen;
+
+ if (result == NULL)
+ return -1;
+
+ if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
+ result->objects.objects_len != 1 ||
+ result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
+ strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+ "passwd_tbl") != 0 ||
+ result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 7)
+ return -1;
+
+ if (NISENTRYLEN(0, 0, result) >= room_left)
+ {
+ /* The line is too long for our buffer. */
+ no_more_room:
+ __set_errno (ERANGE);
+ return -1;
+ }
+
+ strncpy (first_unused, NISENTRYVAL(0, 0, result),
+ NISENTRYLEN (0, 0, result));
+ first_unused[NISENTRYLEN(0, 0, result)] = '\0';
+ pw->pw_name = first_unused;
+ room_left -= (strlen (first_unused) +1);
+ first_unused += strlen (first_unused) +1;
+
+ if (NISENTRYLEN(0, 1, result) >= room_left)
+ goto no_more_room;
+
+ strncpy (first_unused, NISENTRYVAL(0, 1, result),
+ NISENTRYLEN (0, 1, result));
+ first_unused[NISENTRYLEN(0, 1, result)] = '\0';
+ pw->pw_passwd = first_unused;
+ room_left -= (strlen (first_unused) +1);
+ first_unused += strlen (first_unused) +1;
+
+ if (NISENTRYLEN(0, 2, result) >= room_left)
+ goto no_more_room;
+
+ strncpy (first_unused, NISENTRYVAL (0, 2, result),
+ NISENTRYLEN (0, 2, result));
+ first_unused[NISENTRYLEN(0, 2, result)] = '\0';
+ pw->pw_uid = atoi (first_unused);
+ room_left -= (strlen (first_unused) +1);
+ first_unused += strlen (first_unused) +1;
+
+ if (NISENTRYLEN(0, 3, result) >= room_left)
+ goto no_more_room;
+
+ strncpy (first_unused, NISENTRYVAL(0, 3, result),
+ NISENTRYLEN (0, 3, result));
+ first_unused[NISENTRYLEN(0, 3, result)] = '\0';
+ pw->pw_gid = atoi (first_unused);
+ room_left -= (strlen (first_unused) +1);
+ first_unused += strlen (first_unused) +1;
+
+ if (NISENTRYLEN(0, 4, result) >= room_left)
+ goto no_more_room;
+
+ strncpy (first_unused, NISENTRYVAL(0, 4, result),
+ NISENTRYLEN (0, 4, result));
+ first_unused[NISENTRYLEN(0, 4, result)] = '\0';
+ pw->pw_gecos = first_unused;
+ room_left -= (strlen (first_unused) +1);
+ first_unused += strlen (first_unused) +1;
+
+ if (NISENTRYLEN(0, 5, result) >= room_left)
+ goto no_more_room;
+
+ strncpy (first_unused, NISENTRYVAL (0, 5, result),
+ NISENTRYLEN (0, 5, result));
+ first_unused[NISENTRYLEN(0, 5, result)] = '\0';
+ pw->pw_dir = first_unused;
+ room_left -= (strlen (first_unused) +1);
+ first_unused += strlen (first_unused) +1;
+
+ if (NISENTRYLEN(0, 6, result) >= room_left)
+ goto no_more_room;
+
+ strncpy (first_unused, NISENTRYVAL (0, 6, result),
+ NISENTRYLEN (0, 6, result));
+ first_unused[NISENTRYLEN (0, 6, result)] = '\0';
+ pw->pw_shell = first_unused;
+ room_left -= (strlen (first_unused) +1);
+ first_unused += strlen (first_unused) +1;
+
+ return 1;
+}
+
+enum nss_status
+_nss_nisplus_setpwent (void)
+{
+ __libc_lock_lock (lock);
+
+ if (result)
+ nis_freeresult (result);
+ result = NULL;
+ if (names)
+ {
+ nis_freenames (names);
+ names = NULL;
+ }
+
+ __libc_lock_unlock (lock);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_endpwent (void)
+{
+ __libc_lock_lock (lock);
+
+ if (result)
+ nis_freeresult (result);
+ result = NULL;
+ if (names)
+ {
+ nis_freenames (names);
+ names = NULL;
+ }
+
+ __libc_lock_unlock (lock);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+static enum nss_status
+internal_nisplus_getpwent_r (struct passwd *pw, char *buffer, size_t buflen)
+{
+ int parse_res;
+
+ /* Get the next entry until we found a correct one. */
+ do
+ {
+ if (result == NULL)
+ {
+ names = nis_getnames ("passwd.org_dir");
+ if (names == NULL || names[0] == NULL)
+ return NSS_STATUS_UNAVAIL;
+
+ result = nis_first_entry(names[0]);
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ return niserr2nss (result->status);
+ }
+ else
+ {
+ nis_result *res;
+
+ res = nis_next_entry(names[0], &result->cookie);
+ nis_freeresult (result);
+ result = res;
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ return niserr2nss (result->status);
+ }
+
+ parse_res = _nss_nisplus_parse_pwent (result, pw, buffer, buflen);
+ } while (!parse_res);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_getpwent_r (struct passwd *result, char *buffer, size_t buflen)
+{
+ int status;
+
+ __libc_lock_lock (lock);
+
+ status = internal_nisplus_getpwent_r (result, buffer, buflen);
+
+ __libc_lock_unlock (lock);
+
+ return status;
+}
+
+enum nss_status
+_nss_nisplus_getpwnam_r (const char *name, struct passwd *pw,
+ char *buffer, size_t buflen)
+{
+ int parse_res;
+
+ if (name == NULL || strlen (name) > 8)
+ return NSS_STATUS_NOTFOUND;
+ else
+ {
+ nis_result *result;
+ char buf[strlen (name) + 24];
+
+ sprintf(buf, "[name=%s],passwd.org_dir", name);
+
+ result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ {
+ enum nss_status status = niserr2nss (result->status);
+
+ nis_freeresult (result);
+ return status;
+ }
+
+ parse_res = _nss_nisplus_parse_pwent (result, pw, buffer, buflen);
+
+ nis_freeresult (result);
+
+ if (parse_res)
+ return NSS_STATUS_SUCCESS;
+
+ if (!parse_res && errno == ERANGE)
+ return NSS_STATUS_TRYAGAIN;
+ else
+ return NSS_STATUS_NOTFOUND;
+ }
+}
+
+enum nss_status
+_nss_nisplus_getpwuid_r (const uid_t uid, struct passwd *pw,
+ char *buffer, size_t buflen)
+{
+ int parse_res;
+ nis_result *result;
+ char buf[100];
+
+ sprintf(buf, "[uid=%d],passwd.org_dir", uid);
+
+ result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ {
+ enum nss_status status = niserr2nss (result->status);
+
+ nis_freeresult (result);
+ return status;
+ }
+
+ parse_res = _nss_nisplus_parse_pwent (result, pw, buffer, buflen);
+
+ nis_freeresult (result);
+ if (parse_res)
+ return NSS_STATUS_SUCCESS;
+
+ if (!parse_res && errno == ERANGE)
+ return NSS_STATUS_TRYAGAIN;
+ else
+ return NSS_STATUS_NOTFOUND;
+}
diff --git a/nis/nss_nisplus/nisplus-rpc.c b/nis/nss_nisplus/nisplus-rpc.c
new file mode 100644
index 0000000000..326f262749
--- /dev/null
+++ b/nis/nss_nisplus/nisplus-rpc.c
@@ -0,0 +1,284 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <nss.h>
+#include <errno.h>
+#include <ctype.h>
+#include <string.h>
+#include <libc-lock.h>
+#include <rpc/netdb.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+#include "nss-nisplus.h"
+
+__libc_lock_define_initialized (static, lock)
+
+static nis_result *result = NULL;
+static nis_name *names = NULL;
+
+#define ENTNAME rpcent
+#define DATABASE "rpc"
+#define TRAILING_LIST_MEMBER r_aliases
+#define TRAILING_LIST_SEPARATOR_P isspace
+#include "../../nss/nss_files/files-parse.c"
+LINE_PARSER
+("#",
+ STRING_FIELD (result->r_name, isspace, 1);
+ INT_FIELD (result->r_number, isspace, 1, 10,);
+ )
+
+#define NISENTRYVAL(idx,col,res) \
+ ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
+
+#define NISENTRYLEN(idx,col,res) \
+ ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
+
+static int
+_nss_nisplus_parse_rpcent (nis_result *result, struct rpcent *rpc,
+ char *buffer, size_t buflen)
+{
+ char *p = buffer;
+ size_t room_left = buflen;
+ int i;
+ struct parser_data *data = (void *) buffer;
+
+ if (result == NULL)
+ return -1;
+
+ if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
+ result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
+ strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+ "rpc_tbl") != 0 ||
+ result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3)
+ return -1;
+
+ memset (p, '\0', room_left);
+
+ /* Generate the rpc entry format and use the normal parser */
+ if (NISENTRYLEN (0, 0, result) +1 > room_left)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+ strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
+ room_left -= (NISENTRYLEN (0, 0, result) +1);
+
+ if (NISENTRYLEN (0, 2, result) +1 > room_left)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+ strcat (p, "\t");
+ strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result));
+ room_left -= (NISENTRYLEN (0, 2, result) + 1);
+ /* + 1: We overwrite the last \0 */
+
+ for (i = 0; i < result->objects.objects_len; i++)
+ /* XXX should we start with i = 0 or with i = 1 ? */
+ {
+ if (NISENTRYLEN (i, 1, result) +1 > room_left)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+ strcat (p, " ");
+ strncat (p, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));
+ room_left -= (NISENTRYLEN (i, 1, result) + 1);
+ }
+
+ return _nss_files_parse_rpcent (p, rpc, data, buflen);
+}
+
+enum nss_status
+_nss_nisplus_setrpcent (void)
+{
+ __libc_lock_lock (lock);
+
+ if (result)
+ nis_freeresult (result);
+ result = NULL;
+ if (names)
+ {
+ nis_freenames (names);
+ names = NULL;
+ }
+
+ __libc_lock_unlock (lock);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_endrpcent (void)
+{
+ __libc_lock_lock (lock);
+
+ if (result)
+ nis_freeresult (result);
+ result = NULL;
+ if (names)
+ {
+ nis_freenames (names);
+ names = NULL;
+ }
+
+ __libc_lock_unlock (lock);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+static enum nss_status
+internal_nisplus_getrpcent_r (struct rpcent *rpc, char *buffer,
+ size_t buflen)
+{
+ int parse_res;
+
+ /* Get the next entry until we found a correct one. */
+ do
+ {
+ if (result == NULL)
+ {
+ names = nis_getnames ("rpc.org_dir");
+ if (names == NULL || names[0] == NULL)
+ return NSS_STATUS_UNAVAIL;
+
+ result = nis_first_entry(names[0]);
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ return niserr2nss (result->status);
+ }
+ else
+ {
+ nis_result *res;
+
+ res = nis_next_entry (names[0], &result->cookie);
+ nis_freeresult (result);
+ result = res;
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ return niserr2nss (result->status);
+ }
+
+ parse_res = _nss_nisplus_parse_rpcent (result, rpc, buffer, buflen);
+ } while (!parse_res);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_getrpcent_r (struct rpcent *result, char *buffer,
+ size_t buflen)
+{
+ int status;
+
+ __libc_lock_lock (lock);
+
+ status = internal_nisplus_getrpcent_r (result, buffer, buflen);
+
+ __libc_lock_unlock (lock);
+
+ return status;
+}
+
+enum nss_status
+_nss_nisplus_getrpcbyname_r (const char *name, struct rpcent *rpc,
+ char *buffer, size_t buflen)
+{
+ int parse_res;
+
+ if (name == NULL)
+ return NSS_STATUS_NOTFOUND;
+ else
+ {
+ nis_result *result;
+ char buf[strlen (name) + 255];
+
+ /* Search at first in the alias list, and use the correct name
+ for the next search */
+ sprintf (buf, "[name=%s],rpc.org_dir", name);
+ result = nis_list (buf, EXPAND_NAME, NULL, NULL);
+
+ /* If we do not find it, try it as original name. But if the
+ database is correct, we should find it in the first case, too */
+ if ((result->status != NIS_SUCCESS &&
+ result->status != NIS_S_SUCCESS) ||
+ result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
+ strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+ "rpc_tbl") != 0 ||
+ result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3)
+ sprintf (buf, "[cname=%s],rpc.org_dir", name);
+ else
+ sprintf (buf, "[cname=%s],rpc.org_dir", NISENTRYVAL(0, 0, result));
+
+ nis_freeresult (result);
+ result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ {
+ enum nss_status status = niserr2nss (result->status);
+
+ nis_freeresult (result);
+ return status;
+ }
+
+ parse_res = _nss_nisplus_parse_rpcent (result, rpc, buffer, buflen);
+
+ nis_freeresult (result);
+
+ if (parse_res)
+ return NSS_STATUS_SUCCESS;
+
+ if (!parse_res && errno == ERANGE)
+ return NSS_STATUS_TRYAGAIN;
+ else
+ return NSS_STATUS_NOTFOUND;
+ }
+}
+
+enum nss_status
+_nss_nisplus_getrpcbynumber_r (const int number, struct rpcent *rpc,
+ char *buffer, size_t buflen)
+{
+ int parse_res;
+ nis_result *result;
+ char buf[100];
+
+ snprintf (buf, sizeof (buf), "[number=%d],rpc.org_dir", number);
+
+ result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ {
+ enum nss_status status = niserr2nss (result->status);
+
+ nis_freeresult (result);
+ return status;
+ }
+
+ parse_res = _nss_nisplus_parse_rpcent (result, rpc, buffer, buflen);
+
+ nis_freeresult (result);
+
+ if (parse_res)
+ return NSS_STATUS_SUCCESS;
+
+ if (!parse_res && errno == ERANGE)
+ return NSS_STATUS_TRYAGAIN;
+ else
+ return NSS_STATUS_NOTFOUND;
+}
diff --git a/nis/nss_nisplus/nisplus-service.c b/nis/nss_nisplus/nisplus-service.c
new file mode 100644
index 0000000000..54f4f876c7
--- /dev/null
+++ b/nis/nss_nisplus/nisplus-service.c
@@ -0,0 +1,308 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <nss.h>
+#include <errno.h>
+#include <ctype.h>
+#include <netdb.h>
+#include <string.h>
+#include <libc-lock.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+#include "nss-nisplus.h"
+
+__libc_lock_define_initialized (static, lock);
+
+static nis_result *result = NULL;
+static nis_name *names = NULL;
+
+#define ENTNAME servent
+#define DATABASE "services"
+#define TRAILING_LIST_MEMBER s_aliases
+#define TRAILING_LIST_SEPARATOR_P isspace
+#include "../../nss/nss_files/files-parse.c"
+#define ISSLASH(c) ((c) == '/')
+LINE_PARSER
+("#",
+ STRING_FIELD (result->s_name, isspace, 1);
+ INT_FIELD (result->s_port, ISSLASH, 10, 0, htons);
+ STRING_FIELD (result->s_proto, isspace, 1);
+ )
+
+
+#define NISENTRYVAL(idx,col,res) \
+ ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
+
+#define NISENTRYLEN(idx,col,res) \
+ ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
+
+static int
+_nss_nisplus_parse_servent (nis_result *result, struct servent *serv,
+ char *buffer, size_t buflen)
+{
+ char *p = buffer;
+ size_t room_left = buflen;
+ int i;
+ struct parser_data *data = (void *) buffer;
+
+ if (result == NULL)
+ return -1;
+
+ if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
+ result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
+ strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+ "services_tbl") != 0 ||
+ result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 4)
+ return -1;
+
+ memset (p, '\0', room_left);
+
+ /* Generate the services entry format and use the normal parser */
+ if (NISENTRYLEN (0, 0, result) + 1 > room_left)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+ strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
+ room_left -= (NISENTRYLEN (0, 0, result) + 1);
+
+ if (NISENTRYLEN (0, 3, result) + 1 > room_left)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+ strcat (p, "\t");
+ strncat (p, NISENTRYVAL (0, 3, result), NISENTRYLEN (0, 3, result));
+ room_left -= (NISENTRYLEN (0, 3, result) + 1);
+ if (NISENTRYLEN (0, 2, result) + 1 > room_left)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+ strcat (p, "/");
+ strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result));
+ room_left -= (NISENTRYLEN (0, 2, result) + 1);
+
+ for (i = 1; i < result->objects.objects_len; i++)
+ {
+ if (NISENTRYLEN (i, 1, result) + 1 > room_left)
+ {
+ __set_errno (ERANGE);
+ return -1;
+ }
+ strcat (p, " ");
+ strcat (p, NISENTRYVAL (i, 1, result));
+ room_left -= (NISENTRYLEN (i, 1, result) + 1);
+ }
+
+ return _nss_files_parse_servent (p, serv, data, buflen);
+}
+
+enum nss_status
+_nss_nisplus_setservent (void)
+{
+ __libc_lock_lock (lock);
+
+ if (result)
+ nis_freeresult (result);
+ result = NULL;
+ if (names)
+ {
+ nis_freenames (names);
+ names = NULL;
+ }
+
+ __libc_lock_unlock (lock);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_endservent (void)
+{
+ __libc_lock_lock (lock);
+
+ if (result)
+ nis_freeresult (result);
+ result = NULL;
+ if (names)
+ {
+ nis_freenames (names);
+ names = NULL;
+ }
+
+ __libc_lock_unlock (lock);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+static enum nss_status
+internal_nisplus_getservent_r (struct servent *serv, char *buffer,
+ size_t buflen)
+{
+ int parse_res;
+
+ /* Get the next entry until we found a correct one. */
+ do
+ {
+ if (result == NULL)
+ {
+ names = nis_getnames ("services.org_dir");
+ if (names == NULL || names[0] == NULL)
+ return NSS_STATUS_UNAVAIL;
+
+ result = nis_first_entry (names[0]);
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ return niserr2nss (result->status);
+ }
+ else
+ {
+ nis_result *res;
+
+ res = nis_next_entry (names[0], &result->cookie);
+ nis_freeresult (result);
+ result = res;
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ return niserr2nss (result->status);
+ }
+
+ parse_res = _nss_nisplus_parse_servent (result, serv, buffer, buflen);
+ }
+ while (!parse_res);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_getservent_r (struct servent *result, char *buffer,
+ size_t buflen)
+{
+ int status;
+
+ __libc_lock_lock (lock);
+
+ status = internal_nisplus_getservent_r (result, buffer, buflen);
+
+ __libc_lock_unlock (lock);
+
+ return status;
+}
+
+enum nss_status
+_nss_nisplus_getservbyname_r (const char *name, const char *protocol,
+ struct servent *serv,
+ char *buffer, size_t buflen)
+{
+ int parse_res;
+
+ if (name == NULL || protocol == NULL)
+ {
+ __set_errno (EINVAL);
+ return NSS_STATUS_NOTFOUND;
+ }
+ else
+ {
+ nis_result *result;
+ char buf[strlen (name) + 255];
+
+ /* Search at first in the alias list, and use the correct name
+ for the next search */
+ sprintf (buf, "[name=%s,proto=%s],services.org_dir", name,
+ protocol);
+ result = nis_list (buf, EXPAND_NAME, NULL, NULL);
+
+ /* If we do not find it, try it as original name. But if the
+ database is correct, we should find it in the first case, too */
+ if ((result->status != NIS_SUCCESS &&
+ result->status != NIS_S_SUCCESS) ||
+ result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
+ strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+ "services_tbl") != 0 ||
+ result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 4)
+ sprintf (buf, "[cname=%s,proto=%s],services.org_dir", name, protocol);
+ else
+ sprintf (buf, "[cname=%s,proto=%s],services.org_dir",
+ NISENTRYVAL (0, 0, result), protocol);
+
+ nis_freeresult (result);
+ result = nis_list (buf, EXPAND_NAME, NULL, NULL);
+
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ {
+ enum nss_status status = niserr2nss (result->status);
+
+ nis_freeresult (result);
+ return status;
+ }
+
+ parse_res = _nss_nisplus_parse_servent (result, serv, buffer, buflen);
+
+ nis_freeresult (result);
+
+ if (parse_res)
+ return NSS_STATUS_SUCCESS;
+
+ if (!parse_res && errno == ERANGE)
+ return NSS_STATUS_TRYAGAIN;
+ else
+ return NSS_STATUS_NOTFOUND;
+ }
+}
+
+enum nss_status
+_nss_nisplus_getservbynumber_r (const int number, const char *protocol,
+ struct servent *serv,
+ char *buffer, size_t buflen)
+{
+ int parse_res;
+ nis_result *result;
+ char buf[60 + strlen (protocol)];
+
+ if (protocol == NULL)
+ {
+ __set_errno (EINVAL);
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ snprintf (buf, sizeof (buf), "[number=%d,proto=%s],services.org_dir",
+ number, protocol);
+
+ result = nis_list (buf, EXPAND_NAME, NULL, NULL);
+
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ {
+ enum nss_status status = niserr2nss (result->status);
+
+ nis_freeresult (result);
+ return status;
+ }
+
+ parse_res = _nss_nisplus_parse_servent (result, serv, buffer, buflen);
+
+ nis_freeresult (result);
+
+ if (parse_res)
+ return NSS_STATUS_SUCCESS;
+
+ if (!parse_res && errno == ERANGE)
+ return NSS_STATUS_TRYAGAIN;
+ else
+ return NSS_STATUS_NOTFOUND;
+}
diff --git a/nis/nss_nisplus/nisplus-spwd.c b/nis/nss_nisplus/nisplus-spwd.c
new file mode 100644
index 0000000000..ec4b5b3340
--- /dev/null
+++ b/nis/nss_nisplus/nisplus-spwd.c
@@ -0,0 +1,262 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <nss.h>
+#include <errno.h>
+#include <shadow.h>
+#include <string.h>
+#include <libc-lock.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+#include "nss-nisplus.h"
+
+__libc_lock_define_initialized (static, lock)
+
+static nis_result *result = NULL;
+static nis_name *names = NULL;
+
+#define NISENTRYVAL(idx,col,res) \
+ ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
+
+#define NISENTRYLEN(idx,col,res) \
+ ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
+
+static int
+_nss_nisplus_parse_spent (nis_result *result, struct spwd *sp,
+ char *buffer, size_t buflen)
+{
+ char *first_unused = buffer;
+ size_t room_left = buflen;
+ char *line, *cp;
+
+ if (result == NULL)
+ return -1;
+
+ if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
+ result->objects.objects_len != 1 ||
+ result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
+ strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+ "passwd_tbl") != 0 ||
+ result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 8)
+ return -1;
+
+ if (NISENTRYLEN(0, 0, result) >= room_left)
+ {
+ /* The line is too long for our buffer. */
+ no_more_room:
+ __set_errno (ERANGE);
+ return -1;
+ }
+
+ strncpy (first_unused, NISENTRYVAL (0, 0, result),
+ NISENTRYLEN (0, 0, result));
+ first_unused[NISENTRYLEN(0, 0, result)] = '\0';
+ sp->sp_namp = first_unused;
+ room_left -= (strlen (first_unused) +1);
+ first_unused += strlen (first_unused) +1;
+
+ if (NISENTRYLEN(0, 1, result) >= room_left)
+ goto no_more_room;
+
+ strncpy (first_unused, NISENTRYVAL (0, 1, result),
+ NISENTRYLEN (0, 1, result));
+ first_unused[NISENTRYLEN(0, 1, result)] = '\0';
+ sp->sp_pwdp = first_unused;
+ room_left -= (strlen (first_unused) +1);
+ first_unused += strlen (first_unused) +1;
+
+ sp->sp_lstchg = sp->sp_min = sp->sp_max = sp->sp_warn = sp->sp_inact =
+ sp->sp_expire = sp->sp_flag = -1;
+
+ line = NISENTRYVAL (0, 7, result);
+ cp = strchr (line, ':');
+ if (cp == NULL)
+ return 0;
+ *cp++ = '\0';
+ sp->sp_lstchg = atoi (line);
+
+ line = cp;
+ cp = strchr (line, ':');
+ if (cp == NULL)
+ return 0;
+ *cp++ = '\0';
+ sp->sp_min = atoi(line);
+
+ line = cp;
+ cp = strchr (line, ':');
+ if (cp == NULL)
+ return 0;
+ *cp++ = '\0';
+ sp->sp_max = atoi(line);
+
+ line = cp;
+ cp = strchr (line, ':');
+ if (cp == NULL)
+ return 0;
+ *cp++ = '\0';
+ sp->sp_warn = atoi(line);
+
+ line = cp;
+ cp = strchr (line, ':');
+ if (cp == NULL)
+ return 0;
+ *cp++ = '\0';
+ sp->sp_inact = atoi(line);
+
+ line = cp;
+ cp = strchr (line, ':');
+ if (cp == NULL)
+ return 0;
+ *cp++ = '\0';
+ sp->sp_expire = atoi(line);
+
+ line = cp;
+ if (line == NULL)
+ return 0;
+ sp->sp_flag = atoi(line);
+
+ return 1;
+}
+
+enum nss_status
+_nss_nisplus_setspent (void)
+{
+ __libc_lock_lock (lock);
+
+ if (result)
+ nis_freeresult (result);
+ result = NULL;
+ if (names)
+ {
+ nis_freenames (names);
+ names = NULL;
+ }
+
+ __libc_lock_unlock (lock);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_endspent (void)
+{
+ __libc_lock_lock (lock);
+
+ if (result)
+ nis_freeresult (result);
+ result = NULL;
+ if (names)
+ {
+ nis_freenames (names);
+ names = NULL;
+ }
+
+ __libc_lock_unlock (lock);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+static enum nss_status
+internal_nisplus_getspent_r (struct spwd *sp, char *buffer, size_t buflen)
+{
+ int parse_res;
+
+ /* Get the next entry until we found a correct one. */
+ do
+ {
+ if (result == NULL)
+ {
+ names = nis_getnames ("passwd.org_dir");
+ if (names == NULL || names[0] == NULL)
+ return NSS_STATUS_UNAVAIL;
+
+ result = nis_first_entry (names[0]);
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ return niserr2nss (result->status);
+ }
+ else
+ {
+ nis_result *res;
+
+ res = nis_next_entry (names[0], &result->cookie);
+ nis_freeresult (result);
+ result = res;
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ return niserr2nss (result->status);
+ }
+
+ parse_res = _nss_nisplus_parse_spent (result, sp, buffer, buflen);
+ } while (!parse_res);
+
+ return NSS_STATUS_SUCCESS;
+}
+
+enum nss_status
+_nss_nisplus_getspent_r (struct spwd *result, char *buffer, size_t buflen)
+{
+ int status;
+
+ __libc_lock_lock (lock);
+
+ status = internal_nisplus_getspent_r (result, buffer, buflen);
+
+ __libc_lock_unlock (lock);
+
+ return status;
+}
+
+enum nss_status
+_nss_nisplus_getspnam_r (const char *name, struct spwd *sp,
+ char *buffer, size_t buflen)
+{
+ int parse_res;
+
+ if (name == NULL || strlen (name) > 8)
+ return NSS_STATUS_NOTFOUND;
+ else
+ {
+ nis_result *result;
+ char buf[strlen (name) + 24];
+
+ sprintf (buf, "[name=%s],passwd.org_dir", name);
+
+ result = nis_list (buf, EXPAND_NAME, NULL, NULL);
+
+ if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+ {
+ enum nss_status status = niserr2nss (result->status);
+
+ nis_freeresult (result);
+ return status;
+ }
+
+ parse_res = _nss_nisplus_parse_spent (result, sp, buffer, buflen);
+
+ nis_freeresult (result);
+
+ if (parse_res)
+ return NSS_STATUS_SUCCESS;
+
+ if (!parse_res && errno == ERANGE)
+ return NSS_STATUS_TRYAGAIN;
+ else
+ return NSS_STATUS_NOTFOUND;
+ }
+}
diff --git a/nis/rpcsvc/nis.h b/nis/rpcsvc/nis.h
new file mode 100644
index 0000000000..c2c5319abd
--- /dev/null
+++ b/nis/rpcsvc/nis.h
@@ -0,0 +1,1008 @@
+/*
+ * 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
+ */
+
+#ifndef _NIS_H_RPCGEN
+#define _NIS_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+/*
+ * nis.h
+ *
+ * This file is the main include file for NIS clients. It contains
+ * both the client library function defines and the various data
+ * structures used by the NIS service. It includes the file nis_tags.h
+ * which defines the tag values. This allows the tags to change without
+ * having to change the nis.x file.
+ *
+ * NOTE : DO NOT EDIT THIS FILE! It is automatically generated when
+ * rpcgen is run on the nis.x file. Note that there is a
+ * simple sed script to remove some unneeded lines. (See the
+ * Makefile target nis.h)
+ *
+ */
+#include <rpcsvc/nis_tags.h>
+#include <rpc/xdr.h>
+#pragma ident "@(#)nis_object.x 1.7 92/07/14 SMI"
+
+#ifndef __nis_object_h
+#define __nis_object_h
+
+#define NIS_MAXSTRINGLEN 255
+#define NIS_MAXNAMELEN 1024
+#define NIS_MAXATTRNAME 32
+#define NIS_MAXATTRVAL 2048
+#define NIS_MAXCOLUMNS 64
+#define NIS_MAXATTR 16
+#define NIS_MAXPATH 1024
+#define NIS_MAXREPLICAS 128
+#define NIS_MAXLINKS 16
+#define NIS_PK_NONE 0
+#define NIS_PK_DH 1
+#define NIS_PK_RSA 2
+#define NIS_PK_KERB 3
+
+struct nis_attr {
+ char *zattr_ndx;
+ struct {
+ u_int zattr_val_len;
+ char *zattr_val_val;
+ } zattr_val;
+};
+typedef struct nis_attr nis_attr;
+#ifdef __cplusplus
+extern "C" bool_t xdr_nis_attr(XDR *, nis_attr*);
+#elif __STDC__
+extern bool_t xdr_nis_attr(XDR *, nis_attr*);
+#else /* Old Style C */
+bool_t xdr_nis_attr();
+#endif /* Old Style C */
+
+
+typedef char *nis_name;
+#ifdef __cplusplus
+extern "C" bool_t xdr_nis_name(XDR *, nis_name*);
+#elif __STDC__
+extern bool_t xdr_nis_name(XDR *, nis_name*);
+#else /* Old Style C */
+bool_t xdr_nis_name();
+#endif /* Old Style C */
+
+
+enum zotypes {
+ BOGUS_OBJ = 0,
+ NO_OBJ = 1,
+ DIRECTORY_OBJ = 2,
+ GROUP_OBJ = 3,
+ TABLE_OBJ = 4,
+ ENTRY_OBJ = 5,
+ LINK_OBJ = 6,
+ PRIVATE_OBJ = 7,
+};
+typedef enum zotypes zotypes;
+#ifdef __cplusplus
+extern "C" bool_t xdr_zotypes(XDR *, zotypes*);
+#elif __STDC__
+extern bool_t xdr_zotypes(XDR *, zotypes*);
+#else /* Old Style C */
+bool_t xdr_zotypes();
+#endif /* Old Style C */
+
+
+enum nstype {
+ UNKNOWN = 0,
+ NIS = 1,
+ SUNYP = 2,
+ IVY = 3,
+ DNS = 4,
+ X500 = 5,
+ DNANS = 6,
+ XCHS = 7,
+ CDS = 8,
+};
+typedef enum nstype nstype;
+#ifdef __cplusplus
+extern "C" bool_t xdr_nstype(XDR *, nstype*);
+#elif __STDC__
+extern bool_t xdr_nstype(XDR *, nstype*);
+#else /* Old Style C */
+bool_t xdr_nstype();
+#endif /* Old Style C */
+
+
+struct oar_mask {
+ u_long oa_rights;
+ zotypes oa_otype;
+};
+typedef struct oar_mask oar_mask;
+#ifdef __cplusplus
+extern "C" bool_t xdr_oar_mask(XDR *, oar_mask*);
+#elif __STDC__
+extern bool_t xdr_oar_mask(XDR *, oar_mask*);
+#else /* Old Style C */
+bool_t xdr_oar_mask();
+#endif /* Old Style C */
+
+
+struct endpoint {
+ char *uaddr;
+ char *family;
+ char *proto;
+};
+typedef struct endpoint endpoint;
+#ifdef __cplusplus
+extern "C" bool_t xdr_endpoint(XDR *, endpoint*);
+#elif __STDC__
+extern bool_t xdr_endpoint(XDR *, endpoint*);
+#else /* Old Style C */
+bool_t xdr_endpoint();
+#endif /* Old Style C */
+
+
+struct nis_server {
+ nis_name name;
+ struct {
+ u_int ep_len;
+ endpoint *ep_val;
+ } ep;
+ u_long key_type;
+ netobj pkey;
+};
+typedef struct nis_server nis_server;
+#ifdef __cplusplus
+extern "C" bool_t xdr_nis_server(XDR *, nis_server*);
+#elif __STDC__
+extern bool_t xdr_nis_server(XDR *, nis_server*);
+#else /* Old Style C */
+bool_t xdr_nis_server();
+#endif /* Old Style C */
+
+
+struct directory_obj {
+ nis_name do_name;
+ nstype do_type;
+ struct {
+ u_int do_servers_len;
+ nis_server *do_servers_val;
+ } do_servers;
+ u_long do_ttl;
+ struct {
+ u_int do_armask_len;
+ oar_mask *do_armask_val;
+ } do_armask;
+};
+typedef struct directory_obj directory_obj;
+#ifdef __cplusplus
+extern "C" bool_t xdr_directory_obj(XDR *, directory_obj*);
+#elif __STDC__
+extern bool_t xdr_directory_obj(XDR *, directory_obj*);
+#else /* Old Style C */
+bool_t xdr_directory_obj();
+#endif /* Old Style C */
+
+#define EN_BINARY 1
+#define EN_CRYPT 2
+#define EN_XDR 4
+#define EN_MODIFIED 8
+#define EN_ASN1 64
+
+struct entry_col {
+ u_long ec_flags;
+ struct {
+ u_int ec_value_len;
+ char *ec_value_val;
+ } ec_value;
+};
+typedef struct entry_col entry_col;
+#ifdef __cplusplus
+extern "C" bool_t xdr_entry_col(XDR *, entry_col*);
+#elif __STDC__
+extern bool_t xdr_entry_col(XDR *, entry_col*);
+#else /* Old Style C */
+bool_t xdr_entry_col();
+#endif /* Old Style C */
+
+
+struct entry_obj {
+ char *en_type;
+ struct {
+ u_int en_cols_len;
+ entry_col *en_cols_val;
+ } en_cols;
+};
+typedef struct entry_obj entry_obj;
+#ifdef __cplusplus
+extern "C" bool_t xdr_entry_obj(XDR *, entry_obj*);
+#elif __STDC__
+extern bool_t xdr_entry_obj(XDR *, entry_obj*);
+#else /* Old Style C */
+bool_t xdr_entry_obj();
+#endif /* Old Style C */
+
+
+struct group_obj {
+ u_long gr_flags;
+ struct {
+ u_int gr_members_len;
+ nis_name *gr_members_val;
+ } gr_members;
+};
+typedef struct group_obj group_obj;
+#ifdef __cplusplus
+extern "C" bool_t xdr_group_obj(XDR *, group_obj*);
+#elif __STDC__
+extern bool_t xdr_group_obj(XDR *, group_obj*);
+#else /* Old Style C */
+bool_t xdr_group_obj();
+#endif /* Old Style C */
+
+
+struct link_obj {
+ zotypes li_rtype;
+ struct {
+ u_int li_attrs_len;
+ nis_attr *li_attrs_val;
+ } li_attrs;
+ nis_name li_name;
+};
+typedef struct link_obj link_obj;
+#ifdef __cplusplus
+extern "C" bool_t xdr_link_obj(XDR *, link_obj*);
+#elif __STDC__
+extern bool_t xdr_link_obj(XDR *, link_obj*);
+#else /* Old Style C */
+bool_t xdr_link_obj();
+#endif /* Old Style C */
+
+#define TA_BINARY 1
+#define TA_CRYPT 2
+#define TA_XDR 4
+#define TA_SEARCHABLE 8
+#define TA_CASE 16
+#define TA_MODIFIED 32
+#define TA_ASN1 64
+
+struct table_col {
+ char *tc_name;
+ u_long tc_flags;
+ u_long tc_rights;
+};
+typedef struct table_col table_col;
+#ifdef __cplusplus
+extern "C" bool_t xdr_table_col(XDR *, table_col*);
+#elif __STDC__
+extern bool_t xdr_table_col(XDR *, table_col*);
+#else /* Old Style C */
+bool_t xdr_table_col();
+#endif /* Old Style C */
+
+
+struct table_obj {
+ char *ta_type;
+ int ta_maxcol;
+ u_char ta_sep;
+ struct {
+ u_int ta_cols_len;
+ table_col *ta_cols_val;
+ } ta_cols;
+ char *ta_path;
+};
+typedef struct table_obj table_obj;
+#ifdef __cplusplus
+extern "C" bool_t xdr_table_obj(XDR *, table_obj*);
+#elif __STDC__
+extern bool_t xdr_table_obj(XDR *, table_obj*);
+#else /* Old Style C */
+bool_t xdr_table_obj();
+#endif /* Old Style C */
+
+
+struct objdata {
+ zotypes zo_type;
+ union {
+ struct directory_obj di_data;
+ struct group_obj gr_data;
+ struct table_obj ta_data;
+ struct entry_obj en_data;
+ struct link_obj li_data;
+ struct {
+ u_int po_data_len;
+ char *po_data_val;
+ } po_data;
+ } objdata_u;
+};
+typedef struct objdata objdata;
+#ifdef __cplusplus
+extern "C" bool_t xdr_objdata(XDR *, objdata*);
+#elif __STDC__
+extern bool_t xdr_objdata(XDR *, objdata*);
+#else /* Old Style C */
+bool_t xdr_objdata();
+#endif /* Old Style C */
+
+
+struct nis_oid {
+ u_long ctime;
+ u_long mtime;
+};
+typedef struct nis_oid nis_oid;
+#ifdef __cplusplus
+extern "C" bool_t xdr_nis_oid(XDR *, nis_oid*);
+#elif __STDC__
+extern bool_t xdr_nis_oid(XDR *, nis_oid*);
+#else /* Old Style C */
+bool_t xdr_nis_oid();
+#endif /* Old Style C */
+
+
+struct nis_object {
+ nis_oid zo_oid;
+ nis_name zo_name;
+ nis_name zo_owner;
+ nis_name zo_group;
+ nis_name zo_domain;
+ u_long zo_access;
+ u_long zo_ttl;
+ objdata zo_data;
+};
+typedef struct nis_object nis_object;
+#ifdef __cplusplus
+extern "C" bool_t xdr_nis_object(XDR *, nis_object*);
+#elif __STDC__
+extern bool_t xdr_nis_object(XDR *, nis_object*);
+#else /* Old Style C */
+bool_t xdr_nis_object();
+#endif /* Old Style C */
+
+
+#endif /* if __nis_object_h */
+
+
+enum nis_error {
+ NIS_SUCCESS = 0,
+ NIS_S_SUCCESS = 1,
+ NIS_NOTFOUND = 2,
+ NIS_S_NOTFOUND = 3,
+ NIS_CACHEEXPIRED = 4,
+ NIS_NAMEUNREACHABLE = 5,
+ NIS_UNKNOWNOBJ = 6,
+ NIS_TRYAGAIN = 7,
+ NIS_SYSTEMERROR = 8,
+ NIS_CHAINBROKEN = 9,
+ NIS_PERMISSION = 10,
+ NIS_NOTOWNER = 11,
+ NIS_NOT_ME = 12,
+ NIS_NOMEMORY = 13,
+ NIS_NAMEEXISTS = 14,
+ NIS_NOTMASTER = 15,
+ NIS_INVALIDOBJ = 16,
+ NIS_BADNAME = 17,
+ NIS_NOCALLBACK = 18,
+ NIS_CBRESULTS = 19,
+ NIS_NOSUCHNAME = 20,
+ NIS_NOTUNIQUE = 21,
+ NIS_IBMODERROR = 22,
+ NIS_NOSUCHTABLE = 23,
+ NIS_TYPEMISMATCH = 24,
+ NIS_LINKNAMEERROR = 25,
+ NIS_PARTIAL = 26,
+ NIS_TOOMANYATTRS = 27,
+ NIS_RPCERROR = 28,
+ NIS_BADATTRIBUTE = 29,
+ NIS_NOTSEARCHABLE = 30,
+ NIS_CBERROR = 31,
+ NIS_FOREIGNNS = 32,
+ NIS_BADOBJECT = 33,
+ NIS_NOTSAMEOBJ = 34,
+ NIS_MODFAIL = 35,
+ NIS_BADREQUEST = 36,
+ NIS_NOTEMPTY = 37,
+ NIS_COLDSTART_ERR = 38,
+ NIS_RESYNC = 39,
+ NIS_FAIL = 40,
+ NIS_UNAVAIL = 41,
+ NIS_RES2BIG = 42,
+ NIS_SRVAUTH = 43,
+ NIS_CLNTAUTH = 44,
+ NIS_NOFILESPACE = 45,
+ NIS_NOPROC = 46,
+ NIS_DUMPLATER = 47,
+};
+typedef enum nis_error nis_error;
+#ifdef __cplusplus
+extern "C" bool_t xdr_nis_error(XDR *, nis_error*);
+#elif __STDC__
+extern bool_t xdr_nis_error(XDR *, nis_error*);
+#else /* Old Style C */
+bool_t xdr_nis_error();
+#endif /* Old Style C */
+
+
+struct nis_result {
+ nis_error status;
+ struct {
+ u_int objects_len;
+ nis_object *objects_val;
+ } objects;
+ netobj cookie;
+ u_long zticks;
+ u_long dticks;
+ u_long aticks;
+ u_long cticks;
+};
+typedef struct nis_result nis_result;
+#ifdef __cplusplus
+extern "C" bool_t xdr_nis_result(XDR *, nis_result*);
+#elif __STDC__
+extern bool_t xdr_nis_result(XDR *, nis_result*);
+#else /* Old Style C */
+bool_t xdr_nis_result();
+#endif /* Old Style C */
+
+
+struct ns_request {
+ nis_name ns_name;
+ struct {
+ u_int ns_object_len;
+ nis_object *ns_object_val;
+ } ns_object;
+};
+typedef struct ns_request ns_request;
+#ifdef __cplusplus
+extern "C" bool_t xdr_ns_request(XDR *, ns_request*);
+#elif __STDC__
+extern bool_t xdr_ns_request(XDR *, ns_request*);
+#else /* Old Style C */
+bool_t xdr_ns_request();
+#endif /* Old Style C */
+
+
+struct ib_request {
+ nis_name ibr_name;
+ struct {
+ u_int ibr_srch_len;
+ nis_attr *ibr_srch_val;
+ } ibr_srch;
+ u_long ibr_flags;
+ struct {
+ u_int ibr_obj_len;
+ nis_object *ibr_obj_val;
+ } ibr_obj;
+ struct {
+ u_int ibr_cbhost_len;
+ nis_server *ibr_cbhost_val;
+ } ibr_cbhost;
+ u_long ibr_bufsize;
+ netobj ibr_cookie;
+};
+typedef struct ib_request ib_request;
+#ifdef __cplusplus
+extern "C" bool_t xdr_ib_request(XDR *, ib_request*);
+#elif __STDC__
+extern bool_t xdr_ib_request(XDR *, ib_request*);
+#else /* Old Style C */
+bool_t xdr_ib_request();
+#endif /* Old Style C */
+
+
+struct ping_args {
+ nis_name dir;
+ u_long stamp;
+};
+typedef struct ping_args ping_args;
+#ifdef __cplusplus
+extern "C" bool_t xdr_ping_args(XDR *, ping_args*);
+#elif __STDC__
+extern bool_t xdr_ping_args(XDR *, ping_args*);
+#else /* Old Style C */
+bool_t xdr_ping_args();
+#endif /* Old Style C */
+
+
+enum log_entry_t {
+ LOG_NOP = 0,
+ ADD_NAME = 1,
+ REM_NAME = 2,
+ MOD_NAME_OLD = 3,
+ MOD_NAME_NEW = 4,
+ ADD_IBASE = 5,
+ REM_IBASE = 6,
+ MOD_IBASE = 7,
+ UPD_STAMP = 8,
+};
+typedef enum log_entry_t log_entry_t;
+#ifdef __cplusplus
+extern "C" bool_t xdr_log_entry_t(XDR *, log_entry_t*);
+#elif __STDC__
+extern bool_t xdr_log_entry_t(XDR *, log_entry_t*);
+#else /* Old Style C */
+bool_t xdr_log_entry_t();
+#endif /* Old Style C */
+
+
+struct log_entry {
+ u_long le_time;
+ log_entry_t le_type;
+ nis_name le_princp;
+ nis_name le_name;
+ struct {
+ u_int le_attrs_len;
+ nis_attr *le_attrs_val;
+ } le_attrs;
+ nis_object le_object;
+};
+typedef struct log_entry log_entry;
+#ifdef __cplusplus
+extern "C" bool_t xdr_log_entry(XDR *, log_entry*);
+#elif __STDC__
+extern bool_t xdr_log_entry(XDR *, log_entry*);
+#else /* Old Style C */
+bool_t xdr_log_entry();
+#endif /* Old Style C */
+
+
+struct log_result {
+ nis_error lr_status;
+ netobj lr_cookie;
+ struct {
+ u_int lr_entries_len;
+ log_entry *lr_entries_val;
+ } lr_entries;
+};
+typedef struct log_result log_result;
+#ifdef __cplusplus
+extern "C" bool_t xdr_log_result(XDR *, log_result*);
+#elif __STDC__
+extern bool_t xdr_log_result(XDR *, log_result*);
+#else /* Old Style C */
+bool_t xdr_log_result();
+#endif /* Old Style C */
+
+
+struct cp_result {
+ nis_error cp_status;
+ u_long cp_zticks;
+ u_long cp_dticks;
+};
+typedef struct cp_result cp_result;
+#ifdef __cplusplus
+extern "C" bool_t xdr_cp_result(XDR *, cp_result*);
+#elif __STDC__
+extern bool_t xdr_cp_result(XDR *, cp_result*);
+#else /* Old Style C */
+bool_t xdr_cp_result();
+#endif /* Old Style C */
+
+
+struct nis_tag {
+ u_long tag_type;
+ char *tag_val;
+};
+typedef struct nis_tag nis_tag;
+#ifdef __cplusplus
+extern "C" bool_t xdr_nis_tag(XDR *, nis_tag*);
+#elif __STDC__
+extern bool_t xdr_nis_tag(XDR *, nis_tag*);
+#else /* Old Style C */
+bool_t xdr_nis_tag();
+#endif /* Old Style C */
+
+
+struct nis_taglist {
+ struct {
+ u_int tags_len;
+ nis_tag *tags_val;
+ } tags;
+};
+typedef struct nis_taglist nis_taglist;
+#ifdef __cplusplus
+extern "C" bool_t xdr_nis_taglist(XDR *, nis_taglist*);
+#elif __STDC__
+extern bool_t xdr_nis_taglist(XDR *, nis_taglist*);
+#else /* Old Style C */
+bool_t xdr_nis_taglist();
+#endif /* Old Style C */
+
+
+struct dump_args {
+ nis_name da_dir;
+ u_long da_time;
+ struct {
+ u_int da_cbhost_len;
+ nis_server *da_cbhost_val;
+ } da_cbhost;
+};
+typedef struct dump_args dump_args;
+#ifdef __cplusplus
+extern "C" bool_t xdr_dump_args(XDR *, dump_args*);
+#elif __STDC__
+extern bool_t xdr_dump_args(XDR *, dump_args*);
+#else /* Old Style C */
+bool_t xdr_dump_args();
+#endif /* Old Style C */
+
+
+struct fd_args {
+ nis_name dir_name;
+ nis_name requester;
+};
+typedef struct fd_args fd_args;
+#ifdef __cplusplus
+extern "C" bool_t xdr_fd_args(XDR *, fd_args*);
+#elif __STDC__
+extern bool_t xdr_fd_args(XDR *, fd_args*);
+#else /* Old Style C */
+bool_t xdr_fd_args();
+#endif /* Old Style C */
+
+
+struct fd_result {
+ nis_error status;
+ nis_name source;
+ struct {
+ u_int dir_data_len;
+ char *dir_data_val;
+ } dir_data;
+ struct {
+ u_int signature_len;
+ char *signature_val;
+ } signature;
+};
+typedef struct fd_result fd_result;
+#ifdef __cplusplus
+extern "C" bool_t xdr_fd_result(XDR *, fd_result*);
+#elif __STDC__
+extern bool_t xdr_fd_result(XDR *, fd_result*);
+#else /* Old Style C */
+bool_t xdr_fd_result();
+#endif /* Old Style C */
+
+/*
+ * Generic "hash" datastructures, used by all types of hashed data.
+ */
+struct nis_hash_data {
+ nis_name name; /* NIS name of hashed item */
+ int keychain; /* It's hash key (for pop) */
+ struct nis_hash_data *next; /* Hash collision pointer */
+ struct nis_hash_data *prv_item; /* A serial, doubly linked list */
+ struct nis_hash_data *nxt_item; /* of items in the hash table */
+};
+typedef struct nis_hash_data NIS_HASH_ITEM;
+
+struct nis_hash_table {
+ NIS_HASH_ITEM *keys[64]; /* A hash table of items */
+ NIS_HASH_ITEM *first; /* The first "item" in serial list */
+};
+typedef struct nis_hash_table NIS_HASH_TABLE;
+
+/* Structure for storing dynamically allocated static data */
+struct nis_sdata {
+ void *buf; /* Memory allocation pointer */
+ u_long size; /* Buffer size */
+};
+
+/* Generic client creating flags */
+#define ZMH_VC 1
+#define ZMH_DG 2
+#define ZMH_AUTH 4
+
+/* Testing Access rights for objects */
+
+#define NIS_READ_ACC 1
+#define NIS_MODIFY_ACC 2
+#define NIS_CREATE_ACC 4
+#define NIS_DESTROY_ACC 8
+/* Test macros. a == access rights, m == desired rights. */
+#define WORLD(a, m) (((a) & (m)) != 0)
+#define GROUP(a, m) (((a) & ((m) << 8)) != 0)
+#define OWNER(a, m) (((a) & ((m) << 16)) != 0)
+#define NOBODY(a, m) (((a) & ((m) << 24)) != 0)
+
+#define OATYPE(d, n) (((d)->do_armask.do_armask_val+n)->oa_otype)
+#define OARIGHTS(d, n) (((d)->do_armask.do_armask_val+n)->oa_rights)
+#define WORLD_DEFAULT (NIS_READ_ACC)
+#define GROUP_DEFAULT (NIS_READ_ACC << 8)
+#define OWNER_DEFAULT ((NIS_READ_ACC + NIS_MODIFY_ACC + NIS_CREATE_ACC +\
+ NIS_DESTROY_ACC) << 16)
+#define DEFAULT_RIGHTS (WORLD_DEFAULT | GROUP_DEFAULT | OWNER_DEFAULT)
+
+/* Result manipulation defines ... */
+#define NIS_RES_NUMOBJ(x) ((x)->objects.objects_len)
+#define NIS_RES_OBJECT(x) ((x)->objects.objects_val)
+#define NIS_RES_COOKIE(x) ((x)->cookie)
+#define NIS_RES_STATUS(x) ((x)->status)
+
+/* These defines make getting at the variant part of the object easier. */
+#define TA_data zo_data.objdata_u.ta_data
+#define EN_data zo_data.objdata_u.en_data
+#define DI_data zo_data.objdata_u.di_data
+#define LI_data zo_data.objdata_u.li_data
+#define GR_data zo_data.objdata_u.gr_data
+
+#define __type_of(o) ((o)->zo_data.zo_type)
+
+/* Declarations for the internal subroutines in nislib.c */
+enum name_pos {SAME_NAME, HIGHER_NAME, LOWER_NAME, NOT_SEQUENTIAL, BAD_NAME};
+typedef enum name_pos name_pos;
+
+/*
+ * Defines for getting at column data in entry objects. Because RPCGEN
+ * generates some rather wordy structures, we create some defines that
+ * collapse the needed keystrokes to access a particular value using
+ * these definitions they take an nis_object *, and an int and return
+ * a u_char * for Value, and an int for length.
+ */
+#define ENTRY_VAL(obj, col) (obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val
+#define ENTRY_LEN(obj, col) (obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Prototypes, and extern declarations for the NIS library functions. */
+#include <rpcsvc/nislib.h>
+#endif /* __NIS_RPCGEN_H */
+/* EDIT_START */
+
+/*
+ * nis_3.h
+ *
+ * This file contains definitions that are only of interest to the actual
+ * service daemon and client stubs. Normal users of NIS will not include
+ * this file.
+ *
+ * NOTE : This include file is automatically created by a combination
+ * of rpcgen and sed. DO NOT EDIT IT, change the nis.x file instead
+ * and then remake this file.
+ */
+#ifndef __nis_3_h
+#define __nis_3_h
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NIS_PROG ((u_long)100300)
+extern struct rpcgen_table nis_prog_3_table[];
+extern int nis_prog_3_nproc;
+#define NIS_VERSION ((u_long)3)
+
+#ifdef __cplusplus
+#define NIS_LOOKUP ((u_long)1)
+extern "C" nis_result * nis_lookup_3(ns_request *, CLIENT *);
+extern "C" nis_result * nis_lookup_3_svc(ns_request *, struct svc_req *);
+#define NIS_ADD ((u_long)2)
+extern "C" nis_result * nis_add_3(ns_request *, CLIENT *);
+extern "C" nis_result * nis_add_3_svc(ns_request *, struct svc_req *);
+#define NIS_MODIFY ((u_long)3)
+extern "C" nis_result * nis_modify_3(ns_request *, CLIENT *);
+extern "C" nis_result * nis_modify_3_svc(ns_request *, struct svc_req *);
+#define NIS_REMOVE ((u_long)4)
+extern "C" nis_result * nis_remove_3(ns_request *, CLIENT *);
+extern "C" nis_result * nis_remove_3_svc(ns_request *, struct svc_req *);
+#define NIS_IBLIST ((u_long)5)
+extern "C" nis_result * nis_iblist_3(ib_request *, CLIENT *);
+extern "C" nis_result * nis_iblist_3_svc(ib_request *, struct svc_req *);
+#define NIS_IBADD ((u_long)6)
+extern "C" nis_result * nis_ibadd_3(ib_request *, CLIENT *);
+extern "C" nis_result * nis_ibadd_3_svc(ib_request *, struct svc_req *);
+#define NIS_IBMODIFY ((u_long)7)
+extern "C" nis_result * nis_ibmodify_3(ib_request *, CLIENT *);
+extern "C" nis_result * nis_ibmodify_3_svc(ib_request *, struct svc_req *);
+#define NIS_IBREMOVE ((u_long)8)
+extern "C" nis_result * nis_ibremove_3(ib_request *, CLIENT *);
+extern "C" nis_result * nis_ibremove_3_svc(ib_request *, struct svc_req *);
+#define NIS_IBFIRST ((u_long)9)
+extern "C" nis_result * nis_ibfirst_3(ib_request *, CLIENT *);
+extern "C" nis_result * nis_ibfirst_3_svc(ib_request *, struct svc_req *);
+#define NIS_IBNEXT ((u_long)10)
+extern "C" nis_result * nis_ibnext_3(ib_request *, CLIENT *);
+extern "C" nis_result * nis_ibnext_3_svc(ib_request *, struct svc_req *);
+#define NIS_FINDDIRECTORY ((u_long)12)
+extern "C" fd_result * nis_finddirectory_3(fd_args *, CLIENT *);
+extern "C" fd_result * nis_finddirectory_3_svc(fd_args *, struct svc_req *);
+#define NIS_STATUS ((u_long)14)
+extern "C" nis_taglist * nis_status_3(nis_taglist *, CLIENT *);
+extern "C" nis_taglist * nis_status_3_svc(nis_taglist *, struct svc_req *);
+#define NIS_DUMPLOG ((u_long)15)
+extern "C" log_result * nis_dumplog_3(dump_args *, CLIENT *);
+extern "C" log_result * nis_dumplog_3_svc(dump_args *, struct svc_req *);
+#define NIS_DUMP ((u_long)16)
+extern "C" log_result * nis_dump_3(dump_args *, CLIENT *);
+extern "C" log_result * nis_dump_3_svc(dump_args *, struct svc_req *);
+#define NIS_CALLBACK ((u_long)17)
+extern "C" bool_t * nis_callback_3(netobj *, CLIENT *);
+extern "C" bool_t * nis_callback_3_svc(netobj *, struct svc_req *);
+#define NIS_CPTIME ((u_long)18)
+extern "C" u_long * nis_cptime_3(nis_name *, CLIENT *);
+extern "C" u_long * nis_cptime_3_svc(nis_name *, struct svc_req *);
+#define NIS_CHECKPOINT ((u_long)19)
+extern "C" cp_result * nis_checkpoint_3(nis_name *, CLIENT *);
+extern "C" cp_result * nis_checkpoint_3_svc(nis_name *, struct svc_req *);
+#define NIS_PING ((u_long)20)
+extern "C" void * nis_ping_3(ping_args *, CLIENT *);
+extern "C" void * nis_ping_3_svc(ping_args *, struct svc_req *);
+#define NIS_SERVSTATE ((u_long)21)
+extern "C" nis_taglist * nis_servstate_3(nis_taglist *, CLIENT *);
+extern "C" nis_taglist * nis_servstate_3_svc(nis_taglist *, struct svc_req *);
+#define NIS_MKDIR ((u_long)22)
+extern "C" nis_error * nis_mkdir_3(nis_name *, CLIENT *);
+extern "C" nis_error * nis_mkdir_3_svc(nis_name *, struct svc_req *);
+#define NIS_RMDIR ((u_long)23)
+extern "C" nis_error * nis_rmdir_3(nis_name *, CLIENT *);
+extern "C" nis_error * nis_rmdir_3_svc(nis_name *, struct svc_req *);
+#define NIS_UPDKEYS ((u_long)24)
+extern "C" nis_error * nis_updkeys_3(nis_name *, CLIENT *);
+extern "C" nis_error * nis_updkeys_3_svc(nis_name *, struct svc_req *);
+
+#elif __STDC__
+#define NIS_LOOKUP ((u_long)1)
+extern nis_result * nis_lookup_3(ns_request *, CLIENT *);
+extern nis_result * nis_lookup_3_svc(ns_request *, struct svc_req *);
+#define NIS_ADD ((u_long)2)
+extern nis_result * nis_add_3(ns_request *, CLIENT *);
+extern nis_result * nis_add_3_svc(ns_request *, struct svc_req *);
+#define NIS_MODIFY ((u_long)3)
+extern nis_result * nis_modify_3(ns_request *, CLIENT *);
+extern nis_result * nis_modify_3_svc(ns_request *, struct svc_req *);
+#define NIS_REMOVE ((u_long)4)
+extern nis_result * nis_remove_3(ns_request *, CLIENT *);
+extern nis_result * nis_remove_3_svc(ns_request *, struct svc_req *);
+#define NIS_IBLIST ((u_long)5)
+extern nis_result * nis_iblist_3(ib_request *, CLIENT *);
+extern nis_result * nis_iblist_3_svc(ib_request *, struct svc_req *);
+#define NIS_IBADD ((u_long)6)
+extern nis_result * nis_ibadd_3(ib_request *, CLIENT *);
+extern nis_result * nis_ibadd_3_svc(ib_request *, struct svc_req *);
+#define NIS_IBMODIFY ((u_long)7)
+extern nis_result * nis_ibmodify_3(ib_request *, CLIENT *);
+extern nis_result * nis_ibmodify_3_svc(ib_request *, struct svc_req *);
+#define NIS_IBREMOVE ((u_long)8)
+extern nis_result * nis_ibremove_3(ib_request *, CLIENT *);
+extern nis_result * nis_ibremove_3_svc(ib_request *, struct svc_req *);
+#define NIS_IBFIRST ((u_long)9)
+extern nis_result * nis_ibfirst_3(ib_request *, CLIENT *);
+extern nis_result * nis_ibfirst_3_svc(ib_request *, struct svc_req *);
+#define NIS_IBNEXT ((u_long)10)
+extern nis_result * nis_ibnext_3(ib_request *, CLIENT *);
+extern nis_result * nis_ibnext_3_svc(ib_request *, struct svc_req *);
+#define NIS_FINDDIRECTORY ((u_long)12)
+extern fd_result * nis_finddirectory_3(fd_args *, CLIENT *);
+extern fd_result * nis_finddirectory_3_svc(fd_args *, struct svc_req *);
+#define NIS_STATUS ((u_long)14)
+extern nis_taglist * nis_status_3(nis_taglist *, CLIENT *);
+extern nis_taglist * nis_status_3_svc(nis_taglist *, struct svc_req *);
+#define NIS_DUMPLOG ((u_long)15)
+extern log_result * nis_dumplog_3(dump_args *, CLIENT *);
+extern log_result * nis_dumplog_3_svc(dump_args *, struct svc_req *);
+#define NIS_DUMP ((u_long)16)
+extern log_result * nis_dump_3(dump_args *, CLIENT *);
+extern log_result * nis_dump_3_svc(dump_args *, struct svc_req *);
+#define NIS_CALLBACK ((u_long)17)
+extern bool_t * nis_callback_3(netobj *, CLIENT *);
+extern bool_t * nis_callback_3_svc(netobj *, struct svc_req *);
+#define NIS_CPTIME ((u_long)18)
+extern u_long * nis_cptime_3(nis_name *, CLIENT *);
+extern u_long * nis_cptime_3_svc(nis_name *, struct svc_req *);
+#define NIS_CHECKPOINT ((u_long)19)
+extern cp_result * nis_checkpoint_3(nis_name *, CLIENT *);
+extern cp_result * nis_checkpoint_3_svc(nis_name *, struct svc_req *);
+#define NIS_PING ((u_long)20)
+extern void * nis_ping_3(ping_args *, CLIENT *);
+extern void * nis_ping_3_svc(ping_args *, struct svc_req *);
+#define NIS_SERVSTATE ((u_long)21)
+extern nis_taglist * nis_servstate_3(nis_taglist *, CLIENT *);
+extern nis_taglist * nis_servstate_3_svc(nis_taglist *, struct svc_req *);
+#define NIS_MKDIR ((u_long)22)
+extern nis_error * nis_mkdir_3(nis_name *, CLIENT *);
+extern nis_error * nis_mkdir_3_svc(nis_name *, struct svc_req *);
+#define NIS_RMDIR ((u_long)23)
+extern nis_error * nis_rmdir_3(nis_name *, CLIENT *);
+extern nis_error * nis_rmdir_3_svc(nis_name *, struct svc_req *);
+#define NIS_UPDKEYS ((u_long)24)
+extern nis_error * nis_updkeys_3(nis_name *, CLIENT *);
+extern nis_error * nis_updkeys_3_svc(nis_name *, struct svc_req *);
+
+#else /* Old Style C */
+#define NIS_LOOKUP ((u_long)1)
+extern nis_result * nis_lookup_3();
+extern nis_result * nis_lookup_3_svc();
+#define NIS_ADD ((u_long)2)
+extern nis_result * nis_add_3();
+extern nis_result * nis_add_3_svc();
+#define NIS_MODIFY ((u_long)3)
+extern nis_result * nis_modify_3();
+extern nis_result * nis_modify_3_svc();
+#define NIS_REMOVE ((u_long)4)
+extern nis_result * nis_remove_3();
+extern nis_result * nis_remove_3_svc();
+#define NIS_IBLIST ((u_long)5)
+extern nis_result * nis_iblist_3();
+extern nis_result * nis_iblist_3_svc();
+#define NIS_IBADD ((u_long)6)
+extern nis_result * nis_ibadd_3();
+extern nis_result * nis_ibadd_3_svc();
+#define NIS_IBMODIFY ((u_long)7)
+extern nis_result * nis_ibmodify_3();
+extern nis_result * nis_ibmodify_3_svc();
+#define NIS_IBREMOVE ((u_long)8)
+extern nis_result * nis_ibremove_3();
+extern nis_result * nis_ibremove_3_svc();
+#define NIS_IBFIRST ((u_long)9)
+extern nis_result * nis_ibfirst_3();
+extern nis_result * nis_ibfirst_3_svc();
+#define NIS_IBNEXT ((u_long)10)
+extern nis_result * nis_ibnext_3();
+extern nis_result * nis_ibnext_3_svc();
+#define NIS_FINDDIRECTORY ((u_long)12)
+extern fd_result * nis_finddirectory_3();
+extern fd_result * nis_finddirectory_3_svc();
+#define NIS_STATUS ((u_long)14)
+extern nis_taglist * nis_status_3();
+extern nis_taglist * nis_status_3_svc();
+#define NIS_DUMPLOG ((u_long)15)
+extern log_result * nis_dumplog_3();
+extern log_result * nis_dumplog_3_svc();
+#define NIS_DUMP ((u_long)16)
+extern log_result * nis_dump_3();
+extern log_result * nis_dump_3_svc();
+#define NIS_CALLBACK ((u_long)17)
+extern bool_t * nis_callback_3();
+extern bool_t * nis_callback_3_svc();
+#define NIS_CPTIME ((u_long)18)
+extern u_long * nis_cptime_3();
+extern u_long * nis_cptime_3_svc();
+#define NIS_CHECKPOINT ((u_long)19)
+extern cp_result * nis_checkpoint_3();
+extern cp_result * nis_checkpoint_3_svc();
+#define NIS_PING ((u_long)20)
+extern void * nis_ping_3();
+extern void * nis_ping_3_svc();
+#define NIS_SERVSTATE ((u_long)21)
+extern nis_taglist * nis_servstate_3();
+extern nis_taglist * nis_servstate_3_svc();
+#define NIS_MKDIR ((u_long)22)
+extern nis_error * nis_mkdir_3();
+extern nis_error * nis_mkdir_3_svc();
+#define NIS_RMDIR ((u_long)23)
+extern nis_error * nis_rmdir_3();
+extern nis_error * nis_rmdir_3_svc();
+#define NIS_UPDKEYS ((u_long)24)
+extern nis_error * nis_updkeys_3();
+extern nis_error * nis_updkeys_3_svc();
+#endif /* Old Style C */
+struct rpcgen_table {
+ char *(*proc)();
+ xdrproc_t xdr_arg;
+ unsigned len_arg;
+ xdrproc_t xdr_res;
+ unsigned len_res;
+};
+
+#endif /* !_NIS_H_RPCGEN */
diff --git a/nis/rpcsvc/nis.x b/nis/rpcsvc/nis.x
new file mode 100644
index 0000000000..625ed57f10
--- /dev/null
+++ b/nis/rpcsvc/nis.x
@@ -0,0 +1,446 @@
+%/*
+% * 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
+% */
+
+/*
+ * From 4.1 : @(#)nis.x 1.61 Copyright 1989 Sun Microsystems
+ *
+ * RPC Language Protocol description file for NIS Plus
+ * This version : 1.61
+ * Last Modified : 3/19/91
+ */
+#ifdef RPC_HDR
+%/*
+% * nis.h
+% *
+% * This file is the main include file for NIS clients. It contains
+% * both the client library function defines and the various data
+% * structures used by the NIS service. It includes the file nis_tags.h
+% * which defines the tag values. This allows the tags to change without
+% * having to change the nis.x file.
+% *
+% * NOTE : DO NOT EDIT THIS FILE! It is automatically generated when
+% * rpcgen is run on the nis.x file. Note that there is a
+% * simple sed script to remove some unneeded lines. (See the
+% * Makefile target nis.h)
+% *
+% */
+%#include <rpcsvc/nis_tags.h>
+#endif
+
+/* This gets stuffed into the source files. */
+#if RPC_HDR
+%#include <rpc/xdr.h>
+#endif
+#if RPC_SVC
+%#include "nis_svc.h"
+#endif
+
+/* Include the RPC Language description of NIS objects */
+#include "nis_object.x"
+
+/* Errors that can be returned by the service */
+enum nis_error {
+ NIS_SUCCESS = 0, /* A-ok, let's rock n roll */
+ NIS_S_SUCCESS = 1, /* Name found (maybe) */
+ NIS_NOTFOUND = 2, /* Name definitely not found */
+ NIS_S_NOTFOUND = 3, /* Name maybe not found */
+ NIS_CACHEEXPIRED = 4, /* Name exists but cache out of date */
+ NIS_NAMEUNREACHABLE = 5, /* Can't get there from here */
+ NIS_UNKNOWNOBJ = 6, /* Object type is bogus */
+ NIS_TRYAGAIN = 7, /* I'm busy, call back */
+ NIS_SYSTEMERROR = 8, /* Out of band failure */
+ NIS_CHAINBROKEN = 9, /* First/Next warning */
+ NIS_PERMISSION = 10, /* Not enough permission to access */
+ NIS_NOTOWNER = 11, /* You don't own it, sorry */
+ NIS_NOT_ME = 12, /* I don't serve this name */
+ NIS_NOMEMORY = 13, /* Outta VM! Help! */
+ NIS_NAMEEXISTS = 14, /* Can't create over another name */
+ NIS_NOTMASTER = 15, /* I'm justa secondaray, don't ask me */
+ NIS_INVALIDOBJ = 16, /* Object is broken somehow */
+ NIS_BADNAME = 17, /* Unparsable name */
+ NIS_NOCALLBACK = 18, /* Couldn't talk to call back proc */
+ NIS_CBRESULTS = 19, /* Results being called back to you */
+ NIS_NOSUCHNAME = 20, /* Name unknown */
+ NIS_NOTUNIQUE = 21, /* Value is not uniques (entry) */
+ NIS_IBMODERROR = 22, /* Inf. Base. Modify error. */
+ NIS_NOSUCHTABLE = 23, /* Name for table was wrong */
+ NIS_TYPEMISMATCH = 24, /* Entry and table type mismatch */
+ NIS_LINKNAMEERROR = 25, /* Link points to bogus name */
+ NIS_PARTIAL = 26, /* Partial success, found table */
+ NIS_TOOMANYATTRS = 27, /* Too many attributes */
+ NIS_RPCERROR = 28, /* RPC error encountered */
+ NIS_BADATTRIBUTE = 29, /* Bad or invalid attribute */
+ NIS_NOTSEARCHABLE = 30, /* Non-searchable object searched */
+ NIS_CBERROR = 31, /* Error during callback (svc crash) */
+ NIS_FOREIGNNS = 32, /* Foreign Namespace */
+ NIS_BADOBJECT = 33, /* Malformed object structure */
+ NIS_NOTSAMEOBJ = 34, /* Object swapped during deletion */
+ NIS_MODFAIL = 35, /* Failure during a Modify. */
+ NIS_BADREQUEST = 36, /* Illegal query for table */
+ NIS_NOTEMPTY = 37, /* Attempt to remove a non-empty tbl */
+ NIS_COLDSTART_ERR = 38, /* Error accesing the cold start file */
+ NIS_RESYNC = 39, /* Transaction log too far out of date */
+ NIS_FAIL = 40, /* NIS operation failed. */
+ NIS_UNAVAIL = 41, /* NIS+ service is unavailable (client) */
+ NIS_RES2BIG = 42, /* NIS+ result too big for datagram */
+ NIS_SRVAUTH = 43, /* NIS+ server wasn't authenticated. */
+ NIS_CLNTAUTH = 44, /* NIS+ Client wasn't authenticated. */
+ NIS_NOFILESPACE = 45, /* NIS+ server ran out of disk space */
+ NIS_NOPROC = 46, /* NIS+ server couldn't create new proc */
+ NIS_DUMPLATER = 47 /* NIS+ server already has dump child */
+};
+
+
+/*
+ * Structure definitions for the parameters and results of the actual
+ * NIS RPC calls.
+ *
+ * This is the standard result (in the protocol) of most of the nis
+ * requests.
+ */
+
+struct nis_result {
+ nis_error status; /* Status of the response */
+ nis_object objects<>; /* objects found */
+ netobj cookie; /* Cookie Data */
+ u_long zticks; /* server ticks */
+ u_long dticks; /* DBM ticks. */
+ u_long aticks; /* Cache (accel) ticks */
+ u_long cticks; /* Client ticks */
+};
+
+/*
+ * A Name Service request
+ * This request is used to access the name space, ns_name is the name
+ * of the object within the namespace and the object is it's value, for
+ * add/modify, a copy of the original for remove.
+ */
+
+struct ns_request {
+ nis_name ns_name; /* Name in the NIS name space */
+ nis_object ns_object<1>; /* Optional Object (add/remove) */
+};
+
+/*
+ * An information base request
+ * This request includes the NIS name of the table we wish to search, the
+ * search criteria in the form of attribute/value pairs and an optional
+ * callback program number. If the callback program number is provided
+ * the server will send back objects one at a time, otherwise it will
+ * return them all in the response.
+ */
+
+struct ib_request {
+ nis_name ibr_name; /* The name of the Table */
+ nis_attr ibr_srch<>; /* The search critereia */
+ u_long ibr_flags; /* Optional flags */
+ nis_object ibr_obj<1>; /* optional object (add/modify) */
+ nis_server ibr_cbhost<1>; /* Optional callback info */
+ u_long ibr_bufsize; /* Optional first/next bufsize */
+ netobj ibr_cookie; /* The first/next cookie */
+};
+
+/*
+ * This argument to the PING call notifies the replicas that something in
+ * a directory has changed and this is it's timestamp. The replica will use
+ * the timestamp to determine if its resync operation was successful.
+ */
+struct ping_args {
+ nis_name dir; /* Directory that had the change */
+ u_long stamp; /* timestamp of the transaction */
+};
+
+/*
+ * These are the type of entries that are stored in the transaction log,
+ * note that modifications will appear as two entries, for names, they have
+ * a "OLD" entry followed by a "NEW" entry. For entries in tables, there
+ * is a remove followed by an add. It is done this way so that we can read
+ * the log backwards to back out transactions and forwards to propogate
+ * updated.
+ */
+enum log_entry_t {
+ LOG_NOP = 0,
+ ADD_NAME = 1, /* Name Added to name space */
+ REM_NAME = 2, /* Name removed from name space */
+ MOD_NAME_OLD = 3, /* Name was modified in the name space */
+ MOD_NAME_NEW = 4, /* Name was modified in the name space */
+ ADD_IBASE = 5, /* Entry added to information base */
+ REM_IBASE = 6, /* Entry removed from information base */
+ MOD_IBASE = 7, /* Entry was modified in information base */
+ UPD_STAMP = 8 /* Update timestamp (used as fenceposts) */
+};
+
+/*
+ * This result is returned from the name service when it is requested to
+ * dump logged entries from its transaction log. Information base updates
+ * will have the name of the information base in the le_name field and
+ * a canonical set of attribute/value pairs to fully specify the entry's
+ * 'name'.
+ */
+struct log_entry {
+ u_long le_time; /* Time in seconds */
+ log_entry_t le_type; /* Type of log entry */
+ nis_name le_princp; /* Principal making the change */
+ nis_name le_name; /* Name of table/dir involved */
+ nis_attr le_attrs<>; /* List of AV pairs. */
+ nis_object le_object; /* Actual object value */
+};
+
+struct log_result {
+ nis_error lr_status; /* The status itself */
+ netobj lr_cookie; /* Used by the dump callback */
+ log_entry lr_entries<>; /* zero or more entries */
+};
+
+struct cp_result {
+ nis_error cp_status; /* Status of the checkpoint */
+ u_long cp_zticks; /* Service 'ticks' */
+ u_long cp_dticks; /* Database 'ticks' */
+};
+
+/*
+ * This structure defines a generic NIS tag list. The taglist contains
+ * zero or tags, each of which is a type and a value. (u_long).
+ * These are used to report statistics (see tag definitions below)
+ * and to set or reset state variables.
+ */
+struct nis_tag {
+ u_long tag_type; /* Statistic tag (may vary) */
+ string tag_val<1024>; /* Statistic value may also vary */
+};
+
+struct nis_taglist {
+ nis_tag tags<>; /* List of tags */
+};
+
+struct dump_args {
+ nis_name da_dir; /* Directory to dump */
+ u_long da_time; /* From this timestamp */
+ nis_server da_cbhost<1>; /* Callback to use. */
+};
+
+struct fd_args {
+ nis_name dir_name; /* The directory we're looking for */
+ nis_name requester; /* Host principal name for signature */
+};
+
+struct fd_result {
+ nis_error status; /* Status returned by function */
+ nis_name source; /* Source of this answer */
+ opaque dir_data<>; /* Directory Data (XDR'ed) */
+ opaque signature<>; /* Signature of the source */
+};
+
+
+/*
+ * What's going on here? Well, it's like this. When the service
+ * is being compiled it wants to have the service definition specific
+ * info included, and when the client is being compiled it wants that
+ * info. This includes the appropriate file which was generated by
+ * make in the protocols directory (probably /usr/include/rpcsvc).
+ */
+#ifdef RPC_SVC
+%#include "nis_svc.h"
+#endif
+#ifdef RPC_CLNT
+%#include "nis_clnt.h"
+#endif
+
+program NIS_PROG {
+
+ /* RPC Language description of the NIS+ protocol */
+ version NIS_VERSION {
+ /* The name service functions */
+ nis_result NIS_LOOKUP(ns_request) = 1;
+ nis_result NIS_ADD(ns_request) = 2;
+ nis_result NIS_MODIFY(ns_request) = 3;
+ nis_result NIS_REMOVE(ns_request) = 4;
+
+ /* The information base functions */
+ nis_result NIS_IBLIST(ib_request) = 5;
+ nis_result NIS_IBADD(ib_request) = 6;
+ nis_result NIS_IBMODIFY(ib_request) = 7;
+ nis_result NIS_IBREMOVE(ib_request) = 8;
+ nis_result NIS_IBFIRST(ib_request) = 9;
+ nis_result NIS_IBNEXT(ib_request) = 10;
+
+ /* NIS Administrative functions */
+ fd_result NIS_FINDDIRECTORY(fd_args) = 12;
+
+ /* If fetch and optionally reset statistics */
+ nis_taglist NIS_STATUS(nis_taglist) = 14;
+
+ /* Dump changes to directory since time in da_time */
+ log_result NIS_DUMPLOG(dump_args) = 15;
+
+ /* Dump contents of directory named */
+ log_result NIS_DUMP(dump_args) = 16;
+
+ /* Check status of callback thread */
+ bool NIS_CALLBACK(netobj) = 17;
+
+ /* Return last update time for named dir */
+ u_long NIS_CPTIME(nis_name) = 18;
+
+ /* Checkpoint directory or table named */
+ cp_result NIS_CHECKPOINT(nis_name) = 19;
+
+ /* Send 'status changed' ping to replicates */
+ void NIS_PING(ping_args) = 20;
+
+ /* Modify server behaviour (such as debugging) */
+ nis_taglist NIS_SERVSTATE(nis_taglist) = 21;
+
+ /* Create a Directory */
+ nis_error NIS_MKDIR(nis_name) = 22;
+
+ /* Remove a Directory */
+ nis_error NIS_RMDIR(nis_name) = 23;
+
+ /* Update public keys of a directory object */
+ nis_error NIS_UPDKEYS(nis_name) = 24;
+ } = 3;
+} = 100300;
+
+/*
+ * Included below are the defines that become part of nis.h,
+ * they are technically not part of the protocol, but do define
+ * key aspects of the implementation and are therefore useful
+ * in building a conforming server or client.
+ */
+#if RPC_HDR
+%/*
+% * Generic "hash" datastructures, used by all types of hashed data.
+% */
+%struct nis_hash_data {
+% nis_name name; /* NIS name of hashed item */
+% int keychain; /* It's hash key (for pop) */
+% struct nis_hash_data *next; /* Hash collision pointer */
+% struct nis_hash_data *prv_item; /* A serial, doubly linked list */
+% struct nis_hash_data *nxt_item; /* of items in the hash table */
+%};
+%typedef struct nis_hash_data NIS_HASH_ITEM;
+%
+%struct nis_hash_table {
+% NIS_HASH_ITEM *keys[64]; /* A hash table of items */
+% NIS_HASH_ITEM *first; /* The first "item" in serial list */
+%};
+%typedef struct nis_hash_table NIS_HASH_TABLE;
+%
+%/* Structure for storing dynamically allocated static data */
+%struct nis_sdata {
+% void *buf; /* Memory allocation pointer */
+% u_long size; /* Buffer size */
+%};
+%
+%/* Generic client creating flags */
+%#define ZMH_VC 1
+%#define ZMH_DG 2
+%#define ZMH_AUTH 4
+%
+%/* Testing Access rights for objects */
+%
+%#define NIS_READ_ACC 1
+%#define NIS_MODIFY_ACC 2
+%#define NIS_CREATE_ACC 4
+%#define NIS_DESTROY_ACC 8
+%/* Test macros. a == access rights, m == desired rights. */
+%#define WORLD(a, m) (((a) & (m)) != 0)
+%#define GROUP(a, m) (((a) & ((m) << 8)) != 0)
+%#define OWNER(a, m) (((a) & ((m) << 16)) != 0)
+%#define NOBODY(a, m) (((a) & ((m) << 24)) != 0)
+%
+%#define OATYPE(d, n) (((d)->do_armask.do_armask_val+n)->oa_otype)
+%#define OARIGHTS(d, n) (((d)->do_armask.do_armask_val+n)->oa_rights)
+%#define WORLD_DEFAULT (NIS_READ_ACC)
+%#define GROUP_DEFAULT (NIS_READ_ACC << 8)
+%#define OWNER_DEFAULT ((NIS_READ_ACC +\
+ NIS_MODIFY_ACC +\
+ NIS_CREATE_ACC +\
+ NIS_DESTROY_ACC) << 16)
+%#define DEFAULT_RIGHTS (WORLD_DEFAULT | GROUP_DEFAULT | OWNER_DEFAULT)
+%
+%/* Result manipulation defines ... */
+%#define NIS_RES_NUMOBJ(x) ((x)->objects.objects_len)
+%#define NIS_RES_OBJECT(x) ((x)->objects.objects_val)
+%#define NIS_RES_COOKIE(x) ((x)->cookie)
+%#define NIS_RES_STATUS(x) ((x)->status)
+%
+%/* These defines make getting at the variant part of the object easier. */
+%#define TA_data zo_data.objdata_u.ta_data
+%#define EN_data zo_data.objdata_u.en_data
+%#define DI_data zo_data.objdata_u.di_data
+%#define LI_data zo_data.objdata_u.li_data
+%#define GR_data zo_data.objdata_u.gr_data
+%
+%#define __type_of(o) ((o)->zo_data.zo_type)
+%
+%/* Declarations for the internal subroutines in nislib.c */
+%enum name_pos {SAME_NAME, HIGHER_NAME, LOWER_NAME, NOT_SEQUENTIAL, BAD_NAME};
+%typedef enum name_pos name_pos;
+%
+%/*
+% * Defines for getting at column data in entry objects. Because RPCGEN
+% * generates some rather wordy structures, we create some defines that
+% * collapse the needed keystrokes to access a particular value using
+% * these definitions they take an nis_object *, and an int and return
+% * a u_char * for Value, and an int for length.
+% */
+%#define ENTRY_VAL(obj, col) \
+% (obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val
+%#define ENTRY_LEN(obj, col) \
+% (obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len
+%
+%#ifdef __cplusplus
+%}
+%#endif
+%
+%/* Prototypes, and extern declarations for the NIS library functions. */
+%#include <rpcsvc/nislib.h>
+%#endif /* __NIS_RPCGEN_H */
+%/* EDIT_START */
+%
+%/*
+% * nis_3.h
+% *
+% * This file contains definitions that are only of interest to the actual
+% * service daemon and client stubs. Normal users of NIS will not include
+% * this file.
+% *
+% * NOTE : This include file is automatically created by a combination
+% * of rpcgen and sed. DO NOT EDIT IT, change the nis.x file instead
+% * and then remake this file.
+% */
+%#ifndef __nis_3_h
+%#define __nis_3_h
+%#ifdef __cplusplus
+%extern "C" {
+%#endif
+#endif
diff --git a/nis/rpcsvc/nis_object.x b/nis/rpcsvc/nis_object.x
new file mode 100644
index 0000000000..e13ae47b70
--- /dev/null
+++ b/nis/rpcsvc/nis_object.x
@@ -0,0 +1,287 @@
+/*
+ * nis_object.x
+ *
+ * Copyright (c) 1988-1992 Sun Microsystems Inc
+ * All Rights Reserved.
+ */
+
+%#pragma ident "@(#)nis_object.x 1.7 92/07/14 SMI"
+
+#if RPC_HDR
+%
+%#ifndef __nis_object_h
+%#define __nis_object_h
+%
+#endif
+/*
+ * This file defines the format for a NIS object in RPC language.
+ * It is included by the main .x file and the database access protocol
+ * file. It is common because both of them need to deal with the same
+ * type of object. Generating the actual code though is a bit messy because
+ * the nis.x file and the nis_dba.x file will generate xdr routines to
+ * encode/decode objects when only one set is needed. Such is life when
+ * one is using rpcgen.
+ *
+ * Note, the protocol doesn't specify any limits on such things as
+ * maximum name length, number of attributes, etc. These are enforced
+ * by the database backend. When you hit them you will no. Also see
+ * the db_getlimits() function for fetching the limit values.
+ *
+ */
+
+/* Some manifest constants, chosen to maximize flexibility without
+ * plugging the wire full of data.
+ */
+const NIS_MAXSTRINGLEN = 255;
+const NIS_MAXNAMELEN = 1024;
+const NIS_MAXATTRNAME = 32;
+const NIS_MAXATTRVAL = 2048;
+const NIS_MAXCOLUMNS = 64;
+const NIS_MAXATTR = 16;
+const NIS_MAXPATH = 1024;
+const NIS_MAXREPLICAS = 128;
+const NIS_MAXLINKS = 16;
+
+const NIS_PK_NONE = 0; /* no public key (unix/sys auth) */
+const NIS_PK_DH = 1; /* Public key is Diffie-Hellman type */
+const NIS_PK_RSA = 2; /* Public key if RSA type */
+const NIS_PK_KERB = 3; /* Use kerberos style authentication */
+
+/*
+ * The fundamental name type of NIS. The name may consist of two parts,
+ * the first being the fully qualified name, and the second being an
+ * optional set of attribute/value pairs.
+ */
+struct nis_attr {
+ string zattr_ndx<>; /* name of the index */
+ opaque zattr_val<>; /* Value for the attribute. */
+};
+
+typedef string nis_name<>; /* The NIS name itself. */
+
+/* NIS object types are defined by the following enumeration. The numbers
+ * they use are based on the following scheme :
+ * 0 - 1023 are reserved for Sun,
+ * 1024 - 2047 are defined to be private to a particular tree.
+ * 2048 - 4095 are defined to be user defined.
+ * 4096 - ... are reserved for future use.
+ */
+
+enum zotypes {
+ BOGUS_OBJ = 0, /* Uninitialized object structure */
+ NO_OBJ = 1, /* NULL object (no data) */
+ DIRECTORY_OBJ = 2, /* Directory object describing domain */
+ GROUP_OBJ = 3, /* Group object (a list of names) */
+ TABLE_OBJ = 4, /* Table object (a database schema) */
+ ENTRY_OBJ = 5, /* Entry object (a database record) */
+ LINK_OBJ = 6, /* A name link. */
+ PRIVATE_OBJ = 7 /* Private object (all opaque data) */
+};
+
+/*
+ * The types of Name services NIS knows about. They are enumerated
+ * here. The Binder code will use this type to determine if it has
+ * a set of library routines that will access the indicated name service.
+ */
+enum nstype {
+ UNKNOWN = 0,
+ NIS = 1, /* Nis Plus Service */
+ SUNYP = 2, /* Old NIS Service */
+ IVY = 3, /* Nis Plus Plus Service */
+ DNS = 4, /* Domain Name Service */
+ X500 = 5, /* ISO/CCCIT X.500 Service */
+ DNANS = 6, /* Digital DECNet Name Service */
+ XCHS = 7, /* Xerox ClearingHouse Service */
+ CDS= 8
+};
+
+/*
+ * DIRECTORY - The name service object. These objects identify other name
+ * servers that are serving some portion of the name space. Each has a
+ * type associated with it. The resolver library will note whether or not
+ * is has the needed routines to access that type of service.
+ * The oarmask structure defines an access rights mask on a per object
+ * type basis for the name spaces. The only bits currently used are
+ * create and destroy. By enabling or disabling these access rights for
+ * a specific object type for a one of the accessor entities (owner,
+ * group, world) the administrator can control what types of objects
+ * may be freely added to the name space and which require the
+ * administrator's approval.
+ */
+struct oar_mask {
+ u_long oa_rights; /* Access rights mask */
+ zotypes oa_otype; /* Object type */
+};
+
+struct endpoint {
+ string uaddr<>;
+ string family<>; /* Transport family (INET, OSI, etc) */
+ string proto<>; /* Protocol (TCP, UDP, CLNP, etc) */
+};
+
+/*
+ * Note: pkey is a netobj which is limited to 1024 bytes which limits the
+ * keysize to 8192 bits. This is consider to be a reasonable limit for
+ * the expected lifetime of this service.
+ */
+struct nis_server {
+ nis_name name; /* Principal name of the server */
+ endpoint ep<>; /* Universal addr(s) for server */
+ u_long key_type; /* Public key type */
+ netobj pkey; /* server's public key */
+};
+
+struct directory_obj {
+ nis_name do_name; /* Name of the directory being served */
+ nstype do_type; /* one of NIS, DNS, IVY, YP, or X.500 */
+ nis_server do_servers<>; /* <0> == Primary name server */
+ u_long do_ttl; /* Time To Live (for caches) */
+ oar_mask do_armask<>; /* Create/Destroy rights by object type */
+};
+
+/*
+ * ENTRY - This is one row of data from an information base.
+ * The type value is used by the client library to convert the entry to
+ * it's internal structure representation. The Table name is a back pointer
+ * to the table where the entry is stored. This allows the client library
+ * to determine where to send a request if the client wishes to change this
+ * entry but got to it through a LINK rather than directly.
+ * If the entry is a "standalone" entry then this field is void.
+ */
+const EN_BINARY = 1; /* Indicates value is binary data */
+const EN_CRYPT = 2; /* Indicates the value is encrypted */
+const EN_XDR = 4; /* Indicates the value is XDR encoded */
+const EN_MODIFIED = 8; /* Indicates entry is modified. */
+const EN_ASN1 = 64; /* Means contents use ASN.1 encoding */
+
+struct entry_col {
+ u_long ec_flags; /* Flags for this value */
+ opaque ec_value<>; /* It's textual value */
+};
+
+struct entry_obj {
+ string en_type<>; /* Type of entry such as "passwd" */
+ entry_col en_cols<>; /* Value for the entry */
+};
+
+/*
+ * GROUP - The group object contains a list of NIS principal names. Groups
+ * are used to authorize principals. Each object has a set of access rights
+ * for members of its group. Principal names in groups are in the form
+ * name.directory and recursive groups are expressed as @groupname.directory
+ */
+struct group_obj {
+ u_long gr_flags; /* Flags controlling group */
+ nis_name gr_members<>; /* List of names in group */
+};
+
+/*
+ * LINK - This is the LINK object. It is quite similar to a symbolic link
+ * in the UNIX filesystem. The attributes in the main object structure are
+ * relative to the LINK data and not what it points to (like the file system)
+ * "modify" privleges here indicate the right to modify what the link points
+ * at and not to modify that actual object pointed to by the link.
+ */
+struct link_obj {
+ zotypes li_rtype; /* Real type of the object */
+ nis_attr li_attrs<>; /* Attribute/Values for tables */
+ nis_name li_name; /* The object's real NIS name */
+};
+
+/*
+ * TABLE - This is the table object. It implements a simple
+ * data base that applications and use for configuration or
+ * administration purposes. The role of the table is to group together
+ * a set of related entries. Tables are the simple database component
+ * of NIS. Like many databases, tables are logically divided into columns
+ * and rows. The columns are labeled with indexes and each ENTRY makes
+ * up a row. Rows may be addressed within the table by selecting one
+ * or more indexes, and values for those indexes. Each row which has
+ * a value for the given index that matches the desired value is returned.
+ * Within the definition of each column there is a flags variable, this
+ * variable contains flags which determine whether or not the column is
+ * searchable, contains binary data, and access rights for the entry objects
+ * column value.
+ */
+
+const TA_BINARY = 1; /* Means table data is binary */
+const TA_CRYPT = 2; /* Means value should be encrypted */
+const TA_XDR = 4; /* Means value is XDR encoded */
+const TA_SEARCHABLE = 8; /* Means this column is searchable */
+const TA_CASE = 16; /* Means this column is Case Sensitive */
+const TA_MODIFIED = 32; /* Means this columns attrs are modified*/
+const TA_ASN1 = 64; /* Means contents use ASN.1 encoding */
+
+struct table_col {
+ string tc_name<64>; /* Column Name */
+ u_long tc_flags; /* control flags */
+ u_long tc_rights; /* Access rights mask */
+};
+
+struct table_obj {
+ string ta_type<64>; /* Table type such as "passwd" */
+ int ta_maxcol; /* Total number of columns */
+ u_char ta_sep; /* Separator character */
+ table_col ta_cols<>; /* The number of table indexes */
+ string ta_path<>; /* A search path for this table */
+};
+
+/*
+ * This union joins together all of the currently known objects.
+ */
+union objdata switch (zotypes zo_type) {
+ case DIRECTORY_OBJ :
+ struct directory_obj di_data;
+ case GROUP_OBJ :
+ struct group_obj gr_data;
+ case TABLE_OBJ :
+ struct table_obj ta_data;
+ case ENTRY_OBJ:
+ struct entry_obj en_data;
+ case LINK_OBJ :
+ struct link_obj li_data;
+ case PRIVATE_OBJ :
+ opaque po_data<>;
+ case NO_OBJ :
+ void;
+ case BOGUS_OBJ :
+ void;
+ default :
+ void;
+};
+
+/*
+ * This is the basic NIS object data type. It consists of a generic part
+ * which all objects contain, and a specialized part which varies depending
+ * on the type of the object. All of the specialized sections have been
+ * described above. You might have wondered why they all start with an
+ * integer size, followed by the useful data. The answer is, when the
+ * server doesn't recognize the type returned it treats it as opaque data.
+ * And the definition for opaque data is {int size; char *data;}. In this
+ * way, servers and utility routines that do not understand a given type
+ * may still pass it around. One has to be careful in setting
+ * this variable accurately, it must take into account such things as
+ * XDR padding of structures etc. The best way to set it is to note one's
+ * position in the XDR encoding stream, encode the structure, look at the
+ * new position and calculate the size.
+ */
+struct nis_oid {
+ u_long ctime; /* Time of objects creation */
+ u_long mtime; /* Time of objects modification */
+};
+
+struct nis_object {
+ nis_oid zo_oid; /* object identity verifier. */
+ nis_name zo_name; /* The NIS name for this object */
+ nis_name zo_owner; /* NIS name of object owner. */
+ nis_name zo_group; /* NIS name of access group. */
+ nis_name zo_domain; /* The administrator for the object */
+ u_long zo_access; /* Access rights (owner, group, world) */
+ u_long zo_ttl; /* Object's time to live in seconds. */
+ objdata zo_data; /* Data structure for this type */
+};
+#if RPC_HDR
+%
+%#endif /* if __nis_object_h */
+%
+#endif
diff --git a/nis/rpcsvc/nis_tags.h b/nis/rpcsvc/nis_tags.h
new file mode 100644
index 0000000000..30bdff6d1a
--- /dev/null
+++ b/nis/rpcsvc/nis_tags.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 1991, Sun Microsystems Inc.
+ */
+
+/*
+ * nis_tags.h
+ *
+ * This file contains the tags and statistics definitions. It is
+ * automatically included by nis.h
+ */
+
+#ifndef _RPCSVC_NIS_TAGS_H
+#define _RPCSVC_NIS_TAGS_H
+
+#pragma ident "@(#)nis_tags.h 1.13 95/02/17 SMI"
+/* from file: zns_tags.h 1.7 Copyright (c) 1990 Sun Microsystems */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define NIS_DIR "data"
+
+/* Lookup and List function flags */
+#define FOLLOW_LINKS (1<<0) /* Follow link objects */
+#define FOLLOW_PATH (1<<1) /* Follow the path in a table */
+#define HARD_LOOKUP (1<<2) /* Block until successful */
+#define ALL_RESULTS (1<<3) /* Retrieve all results */
+#define NO_CACHE (1<<4) /* Do not return 'cached' results */
+#define MASTER_ONLY (1<<5) /* Get value only from master server */
+#define EXPAND_NAME (1<<6) /* Expand partitially qualified names */
+
+/* Semantic modification for table operations flags */
+#define RETURN_RESULT (1<<7) /* Return resulting object to client */
+#define ADD_OVERWRITE (1<<8) /* Allow overwrites on ADD */
+#define REM_MULTIPLE (1<<9) /* Allow wildcard deletes */
+#define MOD_SAMEOBJ (1<<10) /* Check modified object before write */
+#define ADD_RESERVED (1<<11) /* Spare ADD semantic */
+#define REM_RESERVED (1<<12) /* Spare REM semantic */
+#define MOD_EXCLUSIVE (1<<13) /* Modify no overwrite on modified keys */
+
+/* Transport specific modifications to the operation */
+#define USE_DGRAM (1<<16) /* Use a datagram transport */
+#define NO_AUTHINFO (1<<17) /* Don't bother attaching auth info */
+
+/*
+ * Declarations for "standard" NIS+ tags
+ * State variable tags have values 0 - 2047
+ * Statistic tags have values 2048 - 65535
+ * User Tags have values >2^16
+ */
+#define TAG_DEBUG 1 /* set debug level */
+#define TAG_STATS 2 /* Enable/disable statistics */
+#define TAG_GCACHE 3 /* Flush the Group Cache */
+#define TAG_GCACHE_ALL TAG_GCACHE
+#define TAG_DCACHE 4 /* Flush the directory cache */
+#define TAG_DCACHE_ONE TAG_DCACHE
+#define TAG_OCACHE 5 /* Flush the Object Cache */
+#define TAG_SECURE 6 /* Set the security level */
+#define TAG_TCACHE_ONE 7 /* Flush the table cache */
+#define TAG_DCACHE_ALL 8 /* Flush entire directory cache */
+#define TAG_TCACHE_ALL 9 /* Flush entire table cache */
+#define TAG_GCACHE_ONE 10 /* Flush one group object */
+#define TAG_DCACHE_ONE_REFRESH 11 /* Flush and refresh one DO */
+
+#define TAG_OPSTATS 2048 /* NIS+ operations statistics */
+#define TAG_THREADS 2049 /* Child process/thread status */
+#define TAG_HEAP 2050 /* Heap usage statistics */
+#define TAG_UPDATES 2051 /* Updates to this service */
+#define TAG_VISIBLE 2052 /* First update that isn't replicated */
+#define TAG_S_DCACHE 2053 /* Directory cache statistics */
+#define TAG_S_OCACHE 2054 /* Object cache statistics */
+#define TAG_S_GCACHE 2055 /* Group cache statistics */
+#define TAG_S_STORAGE 2056 /* Group cache statistics */
+#define TAG_UPTIME 2057 /* Time that server has been up */
+#define TAG_DIRLIST 2058 /* Dir served by this server */
+#define TAG_NISCOMPAT 2059 /* Whether supports NIS compat mode */
+#define TAG_DNSFORWARDING 2060 /* Whether DNS forwarding supported */
+#define TAG_SECURITY_LEVEL 2061 /* Security level of the server */
+#define TAG_ROOTSERVER 2062 /* Whether root server */
+
+/*
+ * Declarations for the Group object flags. Currently
+ * there are only 3.
+ */
+#define IMPMEM_GROUPS 1 /* Implicit Membership allowed */
+#define RECURS_GROUPS 2 /* Recursive Groups allowed */
+#define NEGMEM_GROUPS 4 /* Negative Groups allowed */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RPCSVC_NIS_TAGS_H */
diff --git a/nis/rpcsvc/nislib.h b/nis/rpcsvc/nislib.h
new file mode 100644
index 0000000000..2ad38ef9c8
--- /dev/null
+++ b/nis/rpcsvc/nislib.h
@@ -0,0 +1,165 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef __RPCSVC_NISLIB_H__
+#define __RPCSVC_NISLIB_H__
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/*
+** nis_names
+*/
+extern nis_result *nis_lookup __P ((__const nis_name, const u_long));
+extern nis_result *nis_add __P ((__const nis_name, const nis_object *));
+extern nis_result *nis_remove __P ((__const nis_name, const nis_object *));
+extern nis_result *nis_modify __P ((__const nis_name, const nis_object *));
+/*
+** nis_table
+*/
+extern nis_result *nis_list __P ((__const nis_name, const u_long,
+ int (*)(__const nis_name,
+ __const nis_object *,
+ __const void *), __const void *));
+extern nis_result *nis_add_entry __P ((__const nis_name, __const nis_object *,
+ __const u_long));
+extern nis_result *nis_modify_entry __P ((__const nis_name,
+ __const nis_object *,
+ __const u_long));
+extern nis_result *nis_remove_entry __P ((__const nis_name,
+ __const nis_object *,
+ __const u_long));
+extern nis_result *nis_first_entry __P ((__const nis_name));
+extern nis_result *nis_next_entry __P ((__const nis_name, __const netobj *));
+/*
+** nis_server
+*/
+extern nis_error nis_mkdir __P ((__const nis_name, __const nis_server *));
+extern nis_error nis_rmdir __P ((__const nis_name, __const nis_server *));
+extern nis_error nis_servstate __P ((__const nis_server *, __const nis_tag *,
+ __const int, nis_tag **));
+extern nis_error nis_stats __P ((__const nis_server *, __const nis_tag *,
+ __const int, nis_tag **));
+extern void nis_freetags __P ((nis_tag *, __const int));
+extern nis_server **nis_getservlist __P ((__const nis_name));
+extern void nis_freeservlist __P ((nis_server **));
+/*
+** nis_subr
+*/
+extern nis_name nis_leaf_of __P ((__const nis_name));
+extern nis_name nis_leaf_of_r __P ((__const nis_name, char *, size_t));
+extern nis_name nis_name_of __P ((__const nis_name));
+extern nis_name nis_name_of_r __P ((__const nis_name, char *, size_t));
+extern nis_name nis_domain_of __P ((__const nis_name));
+extern nis_name nis_domain_of_r __P ((__const nis_name, char *, size_t));
+extern nis_name *nis_getnames __P ((__const nis_name));
+extern void nis_freenames __P ((nis_name *));
+extern name_pos nis_dir_cmp __P ((nis_name, nis_name));
+extern nis_object *nis_clone_object __P ((__const nis_object *, nis_object *));
+extern void nis_destroy_object __P ((nis_object *));
+extern void nis_print_object __P ((__const nis_object *));
+/*
+** nis_local_names
+*/
+extern nis_name nis_local_group __P ((void));
+extern nis_name nis_local_directory __P ((void));
+extern nis_name nis_local_principal __P ((void));
+extern nis_name nis_local_host __P ((void));
+/*
+** nis_error
+*/
+extern const char *nis_sperrno __P ((__const nis_error));
+extern void nis_perror __P ((__const nis_error, __const char *));
+extern void nis_lerror __P ((__const nis_error, __const char *));
+extern char *nis_sperror __P ((__const nis_error, __const char *));
+extern char *nis_sperror_r __P ((__const nis_error, __const char *,
+ char *, size_t));
+/*
+** nis_groups
+*/
+extern bool_t nis_ismember __P ((__const nis_name, __const nis_name));
+extern nis_error nis_addmember __P ((__const nis_name, __const nis_name));
+extern nis_error nis_removemember __P ((__const nis_name, __const nis_name));
+extern nis_error nis_creategroup __P ((__const nis_name, __const u_long));
+extern nis_error nis_destroygroup __P ((__const nis_name));
+extern void nis_print_group_entry __P ((__const nis_name));
+extern nis_error nis_verifygroup __P ((__const nis_name));
+/*
+** nis_ping
+*/
+extern void nis_ping __P ((__const nis_name, __const u_long,
+ __const nis_object *));
+extern nis_result *nis_checkpoint __P ((__const nis_name));
+
+/*
+** nis_print (XXX INTERNAL FUNCTIONS, SHOULD NOT BE USED !!)
+*/
+extern void nis_print_result __P ((__const nis_result *));
+extern void nis_print_rights __P ((__const u_long));
+extern void nis_print_directory __P ((__const directory_obj *));
+extern void nis_print_group __P ((__const group_obj *));
+extern void nis_print_table __P ((__const table_obj *));
+extern void nis_print_link __P ((__const link_obj *));
+extern void nis_print_entry __P ((__const entry_obj *));
+/*
+** nis_file (XXX INTERNAL FUNCTIONS, SHOULD NOT BE USED !!)
+*/
+extern directory_obj *readColdStartFile __P ((void));
+extern bool_t writeColdStartFile __P ((__const directory_obj *));
+extern nis_object *nis_read_obj __P ((__const char *));
+extern bool_t nis_write_obj __P ((__const char *, __const nis_object *));
+/*
+** nis_clone - (XXX INTERNAL FUNCTIONS, SHOULD NOT BE USED !!)
+*/
+
+extern directory_obj *nis_clone_directory __P ((__const directory_obj *,
+ directory_obj *));
+extern group_obj *nis_clone_group __P ((__const group_obj *, group_obj *));
+extern table_obj *nis_clone_table __P ((__const table_obj *, table_obj *));
+extern entry_obj *nis_clone_entry __P ((__const entry_obj *, entry_obj *));
+extern link_obj *nis_clone_link __P ((__const link_obj *, link_obj *));
+extern objdata *nis_clone_objdata __P ((__const objdata *, objdata *));
+extern nis_result *nis_clone_result __P ((__const nis_result *, nis_result *));
+/*
+** nis_free - nis_freeresult
+*/
+extern void nis_freeresult __P ((nis_result *));
+/* (XXX INTERNAL FUNCTIONS, SHOULD NOT BE USED !!) */
+extern void nis_free_attr __P ((nis_attr *));
+extern void nis_free_request __P ((ib_request *));
+extern void nis_free_endpoints __P ((endpoint *, int));
+extern void nis_free_servers __P ((nis_server *, int));
+extern void nis_free_directory __P ((directory_obj *));
+extern void nis_free_group __P ((group_obj *));
+extern void nis_free_table __P ((table_obj *));
+extern void nis_free_entry __P ((entry_obj *));
+extern void nis_free_link __P ((link_obj *));
+extern void nis_free_object __P ((nis_object *));
+
+/* This is the SUN definition, but I don't know for what we need
+ the directory_obj parameter */
+/* extern fd_result *nis_finddirectory __P ((directory_obj *, nis_name)); */
+extern fd_result *__nis_finddirectory __P ((nis_name));
+extern int __start_clock(int);
+extern u_long __stop_clock(int);
+
+__END_DECLS
+
+#endif /* __RPCSVC_NISLIB_H__ */