aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog16
-rw-r--r--nis/nis_call.c46
-rw-r--r--nis/nis_lookup.c7
-rw-r--r--nis/nis_table.c3
-rw-r--r--nis/rpcsvc/nislib.h5
5 files changed, 56 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index 34428caa54..98ecfa6d5e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2006-08-07 Ulrich Drepper <drepper@redhat.com>
+
+ * nis/nis_call.c: Minor cleanups throughout.
+ (rec_dirsearch) [HIGHER_NAME]: Correctly size ndomain array.
+ (first_shoot): Add search_parent_first parameter. Only if it is set
+ search parent server first.
+ If directory for table found through cold start cache is not the same
+ as referenced in the cache, don't use it.
+ (__nisfind_server): Take additional parameter. Pass it on to
+ first_shoot.
+ (__prepare_niscall): Adjust __nisfind_server call.
+ * nis/rpcsvc/nislib.h: Adjust __nisfind_server prototype.
+ * nis/nis_table.c: Adjust __nisfind_server call.
+ * nis/nis_lookup.c: Likewise.
+ (nis_lookup): Don't loop endlessly if name is reduced to ".".
+
2006-08-03 Ulrich Drepper <drepper@redhat.com>
[BZ #2182]
diff --git a/nis/nis_call.c b/nis/nis_call.c
index f8f00d8c82..bad1f776a1 100644
--- a/nis/nis_call.c
+++ b/nis/nis_call.c
@@ -38,12 +38,12 @@ static const struct timeval UDPTIMEOUT = {5, 0};
extern u_short __pmap_getnisport (struct sockaddr_in *address, u_long program,
u_long version, u_int protocol);
-unsigned long
+unsigned long int
inetstr2int (const char *str)
{
size_t j = 0;
for (size_t i = 0; str[i] != '\0'; ++i)
- if (str[i] == '.' && ++j == 4)
+ if (str[i] == '.' && __builtin_expect (++j == 4, 0))
{
char buffer[i + 1];
buffer[i] = '\0';
@@ -68,8 +68,6 @@ libnsl_hidden_def (__nisbind_destroy)
nis_error
__nisbind_next (dir_binding *bind)
{
- u_int j;
-
if (bind->clnt != NULL)
{
if (bind->use_auth)
@@ -81,7 +79,7 @@ __nisbind_next (dir_binding *bind)
if (bind->trys >= bind->server_len)
return NIS_FAIL;
- for (j = bind->current_ep + 1;
+ for (u_int j = bind->current_ep + 1;
j < bind->server_val[bind->server_used].ep.ep_len; ++j)
if (strcmp (bind->server_val[bind->server_used].ep.ep_val[j].family,
"inet") == 0)
@@ -96,7 +94,7 @@ __nisbind_next (dir_binding *bind)
if (bind->server_used >= bind->server_len)
bind->server_used = 0;
- for (j = 0; j < bind->server_val[bind->server_used].ep.ep_len; ++j)
+ for (u_int j = 0; j < bind->server_val[bind->server_used].ep.ep_len; ++j)
if (strcmp (bind->server_val[bind->server_used].ep.ep_val[j].family,
"inet") == 0)
if (bind->server_val[bind->server_used].ep.ep_val[j].proto[0] == '-')
@@ -125,7 +123,7 @@ __nisbind_connect (dir_binding *dbp)
dbp->addr.sin_addr.s_addr =
inetstr2int (serv->ep.ep_val[dbp->current_ep].uaddr);
- if (dbp->addr.sin_addr.s_addr == 0)
+ if (dbp->addr.sin_addr.s_addr == INADDR_NONE)
return NIS_FAIL;
/* Check, if the host is online and rpc.nisd is running. Much faster
@@ -340,7 +338,7 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, nis_error *status)
case HIGHER_NAME:
{ /* We need data from a parent domain */
directory_obj *obj;
- char ndomain [strlen (name) + 3];
+ char ndomain[strlen (dir->do_name) + 3];
nis_domain_of_r (dir->do_name, ndomain, sizeof (ndomain));
@@ -461,31 +459,44 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, nis_error *status)
/* We try to query the current server for the searched object,
maybe he know about it ? */
static directory_obj *
-first_shoot (const_nis_name name, directory_obj *dir)
+first_shoot (const_nis_name name, int search_parent_first, directory_obj *dir)
{
directory_obj *obj = NULL;
fd_result *fd_res;
XDR xdrs;
char domain[strlen (name) + 3];
+#if 0
if (nis_dir_cmp (name, dir->do_name) == SAME_NAME)
return dir;
+#endif
- nis_domain_of_r (name, domain, sizeof (domain));
+ const char *search_name = name;
+ if (search_parent_first)
+ {
+ nis_domain_of_r (name, domain, sizeof (domain));
+ search_name = domain;
+ }
- if (nis_dir_cmp (domain, dir->do_name) == SAME_NAME)
+ if (nis_dir_cmp (search_name, dir->do_name) == SAME_NAME)
return dir;
- fd_res = __nis_finddirectory (dir, domain);
+ fd_res = __nis_finddirectory (dir, search_name);
if (fd_res == NULL)
return NULL;
if (fd_res->status == NIS_SUCCESS
&& (obj = calloc (1, sizeof (directory_obj))) != NULL)
{
- xdrmem_create(&xdrs, fd_res->dir_data.dir_data_val,
- fd_res->dir_data.dir_data_len, XDR_DECODE);
+ 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);
+
+ if (strcmp (dir->do_name, obj->do_name) != 0)
+ {
+ nis_free_directory (obj);
+ obj = NULL;
+ }
}
__free_fdresult (fd_res);
@@ -497,7 +508,8 @@ first_shoot (const_nis_name name, directory_obj *dir)
}
nis_error
-__nisfind_server (const_nis_name name, directory_obj **dir)
+__nisfind_server (const_nis_name name, int search_parent_first,
+ directory_obj **dir)
{
if (name == NULL)
return NIS_BADNAME;
@@ -520,7 +532,7 @@ __nisfind_server (const_nis_name name, directory_obj **dir)
return NIS_UNAVAIL;
/* Try at first, if servers in "dir" know our object */
- obj = first_shoot (name, *dir);
+ obj = first_shoot (name, search_parent_first, *dir);
if (obj == NULL)
{
obj = rec_dirsearch (name, *dir, &status);
@@ -539,7 +551,7 @@ nis_error
__prepare_niscall (const_nis_name name, directory_obj **dirp,
dir_binding *bptrp, unsigned int flags)
{
- nis_error retcode = __nisfind_server (name, dirp);
+ nis_error retcode = __nisfind_server (name, 1, dirp);
if (__builtin_expect (retcode != NIS_SUCCESS, 0))
return retcode;
diff --git a/nis/nis_lookup.c b/nis/nis_lookup.c
index c198376464..839ee4ee42 100644
--- a/nis/nis_lookup.c
+++ b/nis/nis_lookup.c
@@ -127,7 +127,7 @@ nis_lookup (const_nis_name name, const unsigned int flags)
/* Otherwise __nisfind_server will not do anything. */
dir = NULL;
- if (__nisfind_server (req.ns_name, &dir)
+ if (__nisfind_server (req.ns_name, 1, &dir)
!= NIS_SUCCESS)
goto out;
@@ -147,6 +147,11 @@ nis_lookup (const_nis_name name, const unsigned int flags)
nis_domain_of_r (req.ns_name, ndomain,
sizeof (ndomain));
req.ns_name = strdupa (ndomain);
+ if (strcmp (ndomain, ".") == 0)
+ {
+ NIS_RES_STATUS (res) = NIS_NAMEUNREACHABLE;
+ goto out;
+ }
__nisbind_destroy (&bptr);
nis_free_directory (dir);
diff --git a/nis/nis_table.c b/nis/nis_table.c
index 3213035067..a92a4b64ce 100644
--- a/nis/nis_table.c
+++ b/nis/nis_table.c
@@ -271,7 +271,8 @@ nis_list (const_nis_name name, unsigned int flags,
memset (res, '\0', sizeof (nis_result));
- status = __nisfind_server (ibreq->ibr_name, &dir);
+ status = __nisfind_server (ibreq->ibr_name,
+ ibreq->ibr_srch.ibr_srch_val != NULL, &dir);
if (status != NIS_SUCCESS)
{
NIS_RES_STATUS (res) = status;
diff --git a/nis/rpcsvc/nislib.h b/nis/rpcsvc/nislib.h
index a55de61830..c993bac5e8 100644
--- a/nis/rpcsvc/nislib.h
+++ b/nis/rpcsvc/nislib.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 1999, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997.
@@ -276,7 +276,8 @@ extern nis_error __nisbind_create (dir_binding *, const nis_server *,
extern nis_error __nisbind_connect (dir_binding *) __THROW;
extern nis_error __nisbind_next (dir_binding *) __THROW;
extern void __nisbind_destroy (dir_binding *) __THROW;
-extern nis_error __nisfind_server (const_nis_name, directory_obj **) __THROW;
+extern nis_error __nisfind_server (const_nis_name, int, directory_obj **)
+ __THROW;
#endif