summaryrefslogtreecommitdiff
path: root/nis/nis_call.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1997-07-11 01:19:07 +0000
committerUlrich Drepper <drepper@redhat.com>1997-07-11 01:19:07 +0000
commit2d7da676f38bc00f40d2b604036c0295c156529e (patch)
treeb07f60862c86c9a3cd03ec0e4bfbe600b99c0f55 /nis/nis_call.c
parent9c2322bc08c01e34c7488ef12c1d1bf26097190b (diff)
1997-07-11 03:00 Ulrich Drepper <drepper@cygnus.com> * inet/inet_ntoa.c: Prevent looking for thread data key if we found one. * signal/sigandset.c: Include stddef.h to get NULL defined. * signal/sigisempty.c: Likewise. * signal/sigorset.c: Likewise. * sysdeps/stub/if_index.h: Likewise. * wcsmbs/wcstod_l.c: Include locale.h to get __locale_t defined. * wcsmbs/wcstof_l.c: Likewise. * wcsmbs/wcstol_l.c: Likewise. * wcsmbs/wcstold_l.c: Likewise. * wcsmbs/wcstoll_l.c: Likewise. * wcsmbs/wcstoul_l.c: Likewise. * wcsmbs/wcstoull_l.c: Likewise. Reported by Marcus G. Daniels <marcus@cathcart.sysc.pdx.edu>. * stdio-common/snprintf.c: Use ISO C function definition form. * sysdeps/stub/libc-lock.h: Don't define __libc_key_create and __libc_setspecific as empty macros since they are used as function with return value. Reported by Andreas Jaeger. 1997-07-10 Marcus G. Daniels <marcus@cathcart.sysc.pdx.edu> * sysdeps/mach/hurd/select.c (__select): Need bit count for MACH_MSG_TYPE_INTEGER_T. 1997-07-08 10:12 Fila Kolodny <fila@ibi.com> * sysdeps/i370/Implies: New file for i370-ibm-mvs port. * sysdeps/mvs/Implies: Likewise. 1997-07-09 23:06 Thorsten Kukuk <kukuk@vt.uni-paderborn.de> * nis/Makefile: Add new source files. * nis/nis_intern.h: Add new internal functions. * nis/rpcsvc/nislib.h: Likewise. * nis/lckcache.c: New. * nis/nis_cache.c: New, dummy functions in the moment. * nis/nis_util.c: New. * nis/nisplus-parser.h: New. * nis/nss_nisplus/nisplus-parser.c: New. * nis/rpcsvc/nis_cache.h: New. * nis/rpcsvc/nis_cache.x: New. * nis/nss_compat/compat-grp.c: Matches Solaris behaviour now. * nis/nss_compat/compat-pwd.c: Likewise. * nis/nss_compat/compat-spwd.c: Likewise. * nis/nss_nisplus/nisplus-alias.c: Likewise. * nis/nss_nisplus/nisplus-ethers.c: Likewise. * nis/nss_nisplus/nisplus-grp.c: Likewise. * nis/nss_nisplus/nisplus-hosts.c: Likewise. * nis/nss_nisplus/nisplus-netgrp.c: Likewise. * nis/nss_nisplus/nisplus-network.c: Likewise. * nis/nss_nisplus/nisplus-proto.c: Likewise. * nis/nss_nisplus/nisplus-publickey.c: Likewise. * nis/nss_nisplus/nisplus-pwd.c: Likewise. * nis/nss_nisplus/nisplus-rpc.c: Likewise. * nis/nss_nisplus/nisplus-service.c: Likewise. * nis/nss_nisplus/nisplus-spwd.c: Likewise. * nis/nss_nis/nis-publickey.c: Remove libc-lock.h include. * nis/nis_intern.c: Removed. * nis/nis_call.c: Complete rewrite. * nis/nis_lookup.c: Likewise. * nis/nis_table.c: Likewise. * nis/libnsl.map: Add missing symbols. * nis/nis_print.c: Fix nis_print_link. * nis/nis_subr.c: Fix nis_getnames. 1997-07-09 07:19 H.J. Lu <hjl@gnu.ai.mit.edu> * posix/execvp.c (execvp): Handle ESTALE. 1997-07-10 13:54 Ulrich Drepper <drepper@cygnus.com> * posix/regex.c: Make CHAR_SET_SIZE definition always available, even if SYNTAX_TABLE is defined. Patch by Akim Demaille <demaille@inf.enst.fr>. 1997-07-09 08:16 H.J. Lu <hjl@gnu.ai.mit.edu> * libio/fileops.c (_IO_file_underflow): Adjust pointers before calling _IO_SYSREAD (). 1997-07-07 22:54 Zack Weinberg <zack@rabi.phys.columbia.edu> * sysdeps/sparc/divrem.m4: Eliminate use of "DEFS.h" (sysdep.h does the same job). * sysdeps/sparc/alloca.S: Likewise. * sysdeps/sparc/dotmul.S: Likewise. * sysdeps/sparc/udiv_qrnnd.S: Likewise. * sysdeps/sparc/rem.S: Regenerated. * sysdeps/sparc/sdiv.S: Regenerated. * sysdeps/sparc/udiv.S: Regenerated. * sysdeps/sparc/urem.S: Regenerated. * sysdeps/sparc/DEFS.h: Removed. * sysdeps/sparc/elf/DEFS.h: Removed. * sysdeps/sparc/Dist: Don't distribute DEFS.h. * sysdeps/unix/sparc/sysdep.h: Use 4 byte alignment. Add .type directive #ifdef HAVE_ELF. Minor format changes. * sysdeps/alpha/DEFS.h: Removed. * sysdeps/alpha/Dist: Don't distribute DEFS.h. 1997-07-07 19:03 H.J. Lu <hjl@gnu.ai.mit.edu> * math/test-fenv.c (feenv_nomask_test): Move fesetenv (FE_NOMASK_ENV) after fork () to work with SMP. * sysdeps/i386/fpu_control.h (_FPU_IEEE): Fix comment. 1997-07-08 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * libc.map: Add _IO_peekc_locked. 1997-07-07 15:45 Fila Kolodny <fila@ibi.com> * Makeconfig: Add dbobjdir to rpath-link analogous to nssobjdir. 1997-07-08 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/m68k/fpu/feholdexcpt.c: Shift the exception mask in the right position. * sysdeps/m68k/fpu/fesetenv.c (fesetenv): Likewise. 1997-07-08 13:59 Ulrich Drepper <drepper@cygnus.com> * time/strftime.c (spaces, zeroes): Handle broken SGI compiler. Patch by Richard Stallman <rms@gnu.ai.mit.edu>.
Diffstat (limited to 'nis/nis_call.c')
-rw-r--r--nis/nis_call.c546
1 files changed, 349 insertions, 197 deletions
diff --git a/nis/nis_call.c b/nis/nis_call.c
index 08a20acd73..f25b8017a5 100644
--- a/nis/nis_call.c
+++ b/nis/nis_call.c
@@ -17,6 +17,7 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#include <fcntl.h>
#include <string.h>
#include <rpc/rpc.h>
#include <rpc/auth.h>
@@ -26,8 +27,30 @@
#include <arpa/inet.h>
#include "nis_intern.h"
-static struct timeval TIMEOUT = {25, 0};
-static int const MAXTRIES = 3;
+static struct timeval TIMEOUT = {10, 0};
+
+struct dir_binding
+{
+ CLIENT *clnt; /* RPC CLIENT handle */
+ nis_server *server_val; /* List of servers */
+ u_int server_len; /* # of servers */
+ u_int server_used; /* Which server we are bind in the moment ? */
+ u_int trys; /* How many server have we tried ? */
+ bool_t master_only; /* Is only binded to the master */
+ bool_t use_auth; /* Do we use AUTH ? */
+ bool_t use_udp; /* Do we use UDP ? */
+ time_t create; /* Binding creation time */
+ struct sockaddr_in addr; /* Server's IP address */
+ int socket; /* Server's local socket */
+ unsigned short port; /* Local port */
+};
+typedef struct dir_binding dir_binding;
+
+static inline u_int
+__nis_ping (const nis_server *serv, u_int serv_len)
+{
+ return 0;
+}
static unsigned long
inetstr2int (const char *str)
@@ -53,110 +76,217 @@ inetstr2int (const char *str)
return inet_addr (buffer);
}
-static CLIENT *
-__nis_dobind (const nis_server *server, u_long flags)
+static void
+__bind_destroy (dir_binding *bind)
{
- struct sockaddr_in clnt_saddr;
- int clnt_sock;
- size_t i;
- CLIENT *client = NULL;
-
- memset (&clnt_saddr, '\0', sizeof clnt_saddr);
- clnt_saddr.sin_family = AF_INET;
- for (i = 0; i < server->ep.ep_len; i++)
+ if (bind->clnt != NULL)
{
- if (strcmp (server->ep.ep_val[i].family, "loopback") == 0)
+ if (bind->use_auth)
+ auth_destroy (bind->clnt->cl_auth);
+ clnt_destroy (bind->clnt);
+ }
+ free (bind->server_val);
+ free (bind);
+}
+
+static nis_error
+__bind_next (dir_binding *bind)
+{
+ if (bind->trys >= bind->server_len)
+ return NIS_FAIL;
+
+ bind->server_used++;
+ if (bind->server_used >= bind->server_len)
+ bind->server_used = 0;
+
+ if (bind->clnt != NULL)
+ {
+ if (bind->use_auth)
+ auth_destroy (bind->clnt->cl_auth);
+ clnt_destroy (bind->clnt);
+ bind->clnt = NULL;
+ }
+
+ return NIS_SUCCESS;
+}
+
+static nis_error
+__bind_connect (dir_binding *dbp)
+{
+ struct sockaddr_in check;
+ nis_server *serv;
+ int checklen;
+ u_int i;
+
+ if (dbp == NULL)
+ return NIS_FAIL;
+
+ serv = &dbp->server_val[dbp->server_used];
+
+ memset (&dbp->addr, '\0', sizeof (dbp->addr));
+ dbp->addr.sin_family = AF_INET;
+ for (i = 0; i < serv->ep.ep_len; ++i)
+ {
+ if (strcmp (serv->ep.ep_val[i].family, "inet") == 0)
{
- if (server->ep.ep_val[i].uaddr[i] == '-')
- clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ if (dbp->use_udp)
+ {
+ if (strcmp (serv->ep.ep_val[i].proto, "udp") == 0)
+ dbp->addr.sin_addr.s_addr =
+ inetstr2int (serv->ep.ep_val[i].uaddr);
+ else
+ continue;
+ }
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);
- }
+ if (strcmp (serv->ep.ep_val[i].proto, "tcp") == 0)
+ dbp->addr.sin_addr.s_addr =
+ inetstr2int (serv->ep.ep_val[i].uaddr);
}
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 (clnt_call (client, 0, (xdrproc_t) xdr_void, NULL,
- (xdrproc_t) xdr_void, NULL, TIMEOUT) != RPC_SUCCESS)
+ }
+ if (dbp->addr.sin_addr.s_addr == 0)
+ return NIS_FAIL;
+
+ dbp->socket = RPC_ANYSOCK;
+ if (dbp->use_udp)
+ dbp->clnt = clntudp_create (&dbp->addr, NIS_PROG, NIS_VERSION,
+ TIMEOUT, &dbp->socket);
+ else
+ dbp->clnt = clnttcp_create (&dbp->addr, NIS_PROG, NIS_VERSION,
+ &dbp->socket, 0, 0);
+
+ if (dbp->clnt == NULL)
+ return NIS_RPCERROR;
+
+ clnt_control (dbp->clnt, CLSET_TIMEOUT, (caddr_t)&TIMEOUT);
+ /* If the program exists, close the socket */
+ if (fcntl (dbp->socket, F_SETFD, 1) == -1)
+ perror (_("fcntl: F_SETFD"));
+
+ if (dbp->use_auth)
+ {
+#if defined(HAVE_SECURE_RPC)
+ if (serv->key_type == NIS_PK_DH)
{
- clnt_destroy (client);
- continue;
+ char netname[MAXNETNAMELEN+1];
+ char *p;
+
+ p = stpcpy (netname, "unix.");
+ strncpy (p, serv->name,MAXNETNAMELEN-5);
+ netname[MAXNETNAMELEN] = '\0';
+ p = strchr (netname, '.');
+ *p = '@';
+ dbp->clnt->cl_auth =
+ authdes_pk_create (netname, &serv->pkey, 300, NULL, NULL);
+ if (!dbp->clnt->cl_auth)
+ dbp->clnt->cl_auth = authunix_create_default ();
}
+ else
+#endif
+ dbp->clnt->cl_auth = authunix_create_default ();
+ dbp->use_auth = TRUE;
+ }
+
+ /* Get port for sanity checks later */
+ checklen = sizeof (struct sockaddr_in);
+ memset (&check, 0, checklen);
+ if (dbp->use_udp)
+ bind (dbp->socket, (struct sockaddr *)&check, checklen);
+ check.sin_family = AF_INET;
+ if (!getsockname (dbp->socket, (struct sockaddr *)&check, &checklen))
+ dbp->port = check.sin_port;
+
+ dbp->create = time (NULL);
+
+ return NIS_SUCCESS;
+}
- if ((flags & NO_AUTHINFO) != NO_AUTHINFO)
+static dir_binding *
+__bind_create (const nis_server *serv_val, u_int serv_len, u_long flags)
+{
+ dir_binding *dbp;
+ u_int i;
+
+ dbp = calloc (1, sizeof (dir_binding));
+ if (dbp == NULL)
+ return NULL;
+
+ dbp->server_len = serv_len;
+ dbp->server_val = calloc (1, sizeof (nis_server) * serv_len);
+ if (dbp->server_val == NULL)
+ {
+ free (dbp);
+ return NULL;
+ }
+
+ for (i = 0; i < serv_len; ++i)
+ {
+ if (serv_val[i].name != NULL)
+ dbp->server_val[i].name = strdup (serv_val[i].name);
+
+ dbp->server_val[i].ep.ep_len = serv_val[i].ep.ep_len;
+ if (dbp->server_val[i].ep.ep_len > 0)
{
-#if defined(HAVE_SECURE_RPC)
- if (server->key_type == NIS_PK_DH && getenv ("NO_SECURE_RPC") == NULL)
+ unsigned long j;
+
+ dbp->server_val[i].ep.ep_val =
+ malloc (serv_val[i].ep.ep_len * sizeof (endpoint));
+ for (j = 0; j < dbp->server_val[i].ep.ep_len; ++j)
{
- char netname[MAXNETNAMELEN+1];
- char *p;
-
- p = stpcpy (netname, "unix.");
- strncpy (p, server->name,MAXNETNAMELEN-5);
- netname[MAXNETNAMELEN] = '\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 ();
+ if (serv_val[i].ep.ep_val[j].uaddr)
+ dbp->server_val[i].ep.ep_val[j].uaddr =
+ strdup (serv_val[i].ep.ep_val[j].uaddr);
+ else
+ dbp->server_val[i].ep.ep_val[j].uaddr = NULL;
+ if (serv_val[i].ep.ep_val[j].family)
+ dbp->server_val[i].ep.ep_val[j].family =
+ strdup (serv_val[i].ep.ep_val[j].family);
+ else
+ dbp->server_val[i].ep.ep_val[j].family = NULL;
+ if (serv_val[i].ep.ep_val[j].proto)
+ dbp->server_val[i].ep.ep_val[j].proto =
+ strdup (serv_val[i].ep.ep_val[j].proto);
+ else
+ dbp->server_val[i].ep.ep_val[j].proto = NULL;
}
- else
-#endif
- client->cl_auth = authunix_create_default ();
}
- return client;
+ else
+ dbp->server_val[i].ep.ep_val = NULL;
+ dbp->server_val[i].key_type = serv_val[i].key_type;
+ dbp->server_val[i].pkey.n_len = serv_val[i].pkey.n_len;
+ if (serv_val[i].pkey.n_len > 0)
+ {
+ dbp->server_val[i].pkey.n_bytes =
+ malloc (serv_val[i].pkey.n_len);
+ if (dbp->server_val[i].pkey.n_bytes == NULL)
+ return NULL;
+ memcpy (dbp->server_val[i].pkey.n_bytes, serv_val[i].pkey.n_bytes,
+ serv_val[i].pkey.n_len);
+ }
+ else
+ dbp->server_val[i].pkey.n_bytes = NULL;
}
+
+ dbp->server_used = __nis_ping (dbp->server_val, dbp->server_len);
+ if (flags & USE_DGRAM)
+ dbp->use_udp = TRUE;
+ else
+ dbp->use_udp = FALSE;
- return NULL;
+ if (flags & NO_AUTHINFO)
+ dbp->use_auth = FALSE;
+ else
+ dbp->use_auth = TRUE;
+
+ if (flags & MASTER_ONLY)
+ dbp->master_only = TRUE;
+ else
+ dbp->master_only = FALSE;
+
+ dbp->trys = 1;
+
+ return dbp;
}
nis_error
@@ -164,89 +294,84 @@ __do_niscall2 (const nis_server *server, u_int server_len, u_long prog,
xdrproc_t xargs, caddr_t req, xdrproc_t xres, caddr_t resp,
u_long flags)
{
- CLIENT *clnt;
- int try, result;
-
- try = 0;
- result = NIS_NAMEUNREACHABLE;
-
- if (((flags & MASTER_ONLY) == MASTER_ONLY) && server_len > 1)
- server_len = 1; /* The first entry is the master */
-
- while (try < MAXTRIES && result != RPC_SUCCESS)
+ enum clnt_stat result;
+ nis_error retcode;
+ dir_binding *dbp;
+
+ if (flags & MASTER_ONLY)
+ server_len = 1;
+
+ dbp = __bind_create (server, server_len, flags);
+ while (__bind_connect (dbp) != NIS_SUCCESS)
{
- unsigned int i;
-
- if ((flags & HARD_LOOKUP) == 0)
- ++try;
-
- for (i = 0; i < server_len; i++)
+ if (__bind_next (dbp) != NIS_SUCCESS)
{
- if ((clnt = __nis_dobind (&server[i], flags)) == NULL)
- continue;
-
- result = clnt_call (clnt, prog, xargs, req, xres, resp, TIMEOUT);
-
- if (result != RPC_SUCCESS)
- {
- clnt_perror (clnt, "do_niscall: clnt_call");
- clnt_destroy (clnt);
- result = NIS_RPCERROR;
- }
- else
- clnt_destroy (clnt);
+ __bind_destroy (dbp);
+ return NIS_NAMEUNREACHABLE;
}
}
- return result;
-}
-
-static directory_obj *
-dir_lookup (const_nis_name name, nis_server *serv, u_long flags)
-{
- CLIENT *clnt;
- int try, result;
- nis_result *res;
- struct ns_request req;
- directory_obj *dir;
-
- res = calloc (1, sizeof (nis_result));
- req.ns_name = (char *)name;
- req.ns_object.ns_object_len = 0;
- req.ns_object.ns_object_val = NULL;
- try = 0;
- result = NIS_NAMEUNREACHABLE;
-
- while (try < MAXTRIES && result != RPC_SUCCESS)
+ do
{
- if ((clnt = __nis_dobind (serv, flags)) == NULL)
- continue;
-
- result = clnt_call (clnt, NIS_LOOKUP, (xdrproc_t) xdr_ns_request,
- (caddr_t) &req, (xdrproc_t) xdr_nis_result,
- (caddr_t) res, TIMEOUT);
-
+ again:
+ result = clnt_call (dbp->clnt, prog, xargs, req, xres, resp, TIMEOUT);
+
if (result != RPC_SUCCESS)
{
- clnt_perror (clnt, "do_niscall: clnt_call");
- clnt_destroy (clnt);
- result = NIS_RPCERROR;
+ clnt_perror (dbp->clnt, "__do_niscall2: clnt_call");
+ __bind_destroy (dbp);
+ retcode = NIS_RPCERROR;
}
else
- clnt_destroy (clnt);
+ {
+ switch (prog)
+ {
+ case NIS_LOOKUP:
+ case NIS_ADD:
+ case NIS_MODIFY:
+ case NIS_REMOVE:
+ case NIS_IBLIST:
+ case NIS_IBADD:
+ case NIS_IBMODIFY:
+ case NIS_IBREMOVE:
+ case NIS_IBFIRST:
+ case NIS_IBNEXT:
+ if ((((nis_result *)xres)->status != NIS_SUCCESS) &&
+ (((nis_result *)xres)->status != NIS_S_SUCCESS))
+ if (__bind_next (dbp) == NIS_SUCCESS)
+ goto again;
+ case NIS_FINDDIRECTORY:
+ if (((fd_result *)xres)->status != NIS_SUCCESS)
+ if (__bind_next (dbp) == NIS_SUCCESS)
+ goto again;
+ break;
+#if 0
+ case NIS_STATUS: /* nis_taglist */
+ case NIS_SERVSTATE:
+ break;
+ case NIS_DUMPLOG: /* log_result */
+ case NIS_DUMP:
+ break;
+ case NIS_CHECKPOINT: /* cp_result */
+ break;
+#endif
+ default:
+ break;
+ }
+ __bind_destroy (dbp);
+ retcode = NIS_SUCCESS;
+ }
}
- if (result != RPC_SUCCESS || res->status != NIS_SUCCESS)
- return NULL;
-
- dir = nis_clone_directory (&res->objects.objects_val->DI_data, NULL);
- nis_freeresult (res);
-
- return dir;
+ while ((flags & HARD_LOOKUP) && retcode == NIS_RPCERROR);
+
+ return retcode;
}
static directory_obj *
rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags)
{
+ fd_result *fd_res;
+ XDR xdrs;
char domain [strlen (name) + 3];
nis_domain_of_r (name, domain, sizeof (domain));
@@ -287,8 +412,20 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags)
/* The root server of our domain is a replica of the parent
domain ! (Now I understand why a root server must be a
replica of the parent domain) */
- obj = dir_lookup (ndomain, dir->do_servers.do_servers_val,
- flags);
+ fd_res = __nis_finddirectory (dir, ndomain);
+ if (fd_res->status != NIS_SUCCESS)
+ {
+ nis_free_directory (dir);
+ xdr_free((xdrproc_t)xdr_fd_result, (caddr_t)fd_res);
+ return NULL;
+ }
+ __cache_add (fd_res);
+ obj = calloc(1, sizeof(directory_obj));
+ xdrmem_create(&xdrs, fd_res->dir_data.dir_data_val,
+ fd_res->dir_data.dir_data_len, XDR_DECODE);
+ xdr_directory_obj(&xdrs, obj);
+ xdr_destroy(&xdrs);
+ xdr_free((xdrproc_t)xdr_fd_result, (caddr_t)fd_res);
if (obj != NULL)
{
/* We have found a NIS+ server serving ndomain, now
@@ -303,15 +440,14 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags)
return NULL;
}
}
- break;
+ break;
case LOWER_NAME:
{
directory_obj *obj;
char leaf [strlen (name) + 3];
char ndomain [strlen (name) + 3];
- u_int i;
char *cp;
-
+
do
{
if (strlen (domain) == 0)
@@ -327,21 +463,30 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags)
cp = strchr (leaf, '\0');
*cp++ = '.';
strcpy (cp, domain);
-
- for (i = 0; i < dir->do_servers.do_servers_len; ++i)
+
+ fd_res = __nis_finddirectory (dir, leaf);
+ if (fd_res->status != NIS_SUCCESS)
{
- obj = dir_lookup (leaf, &dir->do_servers.do_servers_val[i],
- flags);
- if (obj != NULL)
- {
- /* We have found a NIS+ server serving ndomain, now
- let us search for "name" */
- nis_free_directory (dir);
- return rec_dirsearch (name, obj, flags);
- }
+ nis_free_directory (dir);
+ xdr_free((xdrproc_t)xdr_fd_result, (caddr_t)fd_res);
+ return NULL;
+ }
+ __cache_add (fd_res);
+ obj = calloc(1, sizeof(directory_obj));
+ xdrmem_create(&xdrs, fd_res->dir_data.dir_data_val,
+ fd_res->dir_data.dir_data_len, XDR_DECODE);
+ xdr_directory_obj(&xdrs, obj);
+ xdr_destroy(&xdrs);
+ xdr_free((xdrproc_t)xdr_fd_result, (caddr_t)fd_res);
+ if (obj != NULL)
+ {
+ /* We have found a NIS+ server serving ndomain, now
+ let us search for "name" */
+ nis_free_directory (dir);
+ return rec_dirsearch (name, obj, flags);
}
}
- break;
+ break;
case BAD_NAME:
nis_free_directory (dir);
return NULL;
@@ -354,37 +499,44 @@ nis_error
__do_niscall (const_nis_name name, u_long prog, xdrproc_t xargs,
caddr_t req, xdrproc_t xres, caddr_t resp, u_long flags)
{
- nis_error result;
+ nis_error retcode;
directory_obj *dir = NULL;
- const nis_server *server;
+ nis_server *server;
u_int server_len;
+ if (name == NULL)
+ return NIS_BADNAME;
- dir = readColdStartFile ();
- if (dir == NULL) /* No /var/nis/NIS_COLD_START -> no NIS+ installed */
- return NIS_UNAVAIL;
-
- if (name != NULL)
+ if ((flags & NO_CACHE) != NO_CACHE)
+ dir = __cache_search (name);
+
+ if (dir == NULL)
{
+ dir = readColdStartFile ();
+ if (dir == NULL) /* No /var/nis/NIS_COLD_START->no NIS+ installed */
+ return NIS_UNAVAIL;
+
dir = rec_dirsearch (name, dir, flags);
if (dir == NULL)
- {
- if (nis_dir_cmp (nis_local_directory(), name) == NOT_SEQUENTIAL)
- return NIS_NAMEUNREACHABLE;
- else
- return NIS_NOTFOUND;
- }
+ return NIS_NOTFOUND;
}
- server = dir->do_servers.do_servers_val;
- server_len = dir->do_servers.do_servers_len;
- if (((flags & MASTER_ONLY) == MASTER_ONLY) && server_len > 1)
- server_len = 1; /* The first entry is the master */
-
- result = __do_niscall2 (server, server_len, prog, xargs, req, xres,
- resp, flags);
- if (dir != NULL)
- nis_free_directory (dir);
+ if (flags & MASTER_ONLY)
+ {
+ server = dir->do_servers.do_servers_val;
+ server_len = 1;
+ }
+ else
+ {
+ server = dir->do_servers.do_servers_val;
+ server_len = dir->do_servers.do_servers_len;
+ }
+
+
+ retcode = __do_niscall2 (server, server_len, prog, xargs, req, xres, resp,
+ flags);
+
+ nis_free_directory (dir);
- return result;
+ return retcode;
}