* nis/nis_lookup.c (nis_lookup): Use __prepare_niscall instead of

doing it all here.  When server does not know the answer do not
	fail immediate, try parent first.
This commit is contained in:
Ulrich Drepper 2006-05-24 06:01:25 +00:00
parent 2d571cd125
commit 062e719bed
3 changed files with 30 additions and 43 deletions

View File

@ -1,5 +1,9 @@
2006-05-23 Ulrich Drepper <drepper@redhat.com> 2006-05-23 Ulrich Drepper <drepper@redhat.com>
* nis/nis_lookup.c (nis_lookup): Use __prepare_niscall instead of
doing it all here. When server does not know the answer do not
fail immediate, try parent first.
* nis/nis_domain_of_r.c (nis_domain_of_r): Add missing buffer * nis/nis_domain_of_r.c (nis_domain_of_r): Add missing buffer
overflow test. overflow test.

View File

@ -405,7 +405,7 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, nis_error *status)
++run; ++run;
} }
while (nis_dir_cmp (domain, dir->do_name) != SAME_NAME); while (nis_dir_cmp (domain, dir->do_name) != SAME_NAME);
printf("%s: run=%u\n", __func__, run);
if (run == 1) if (run == 1)
{ {
/* We have found the directory above. Use it. */ /* We have found the directory above. Use it. */

View File

@ -21,6 +21,8 @@
#include <rpcsvc/nis.h> #include <rpcsvc/nis.h>
#include "nis_xdr.h" #include "nis_xdr.h"
#include "nis_intern.h" #include "nis_intern.h"
#include <libnsl.h>
nis_result * nis_result *
nis_lookup (const_nis_name name, const unsigned int flags) nis_lookup (const_nis_name name, const unsigned int flags)
@ -61,36 +63,18 @@ nis_lookup (const_nis_name name, const unsigned int flags)
req.ns_object.ns_object_len = 0; req.ns_object.ns_object_len = 0;
req.ns_object.ns_object_val = NULL; req.ns_object.ns_object_val = NULL;
status = __nisfind_server (req.ns_name, &dir); status = __prepare_niscall (req.ns_name, &dir, &bptr, flags);
if (status != NIS_SUCCESS) if (__builtin_expect (status != NIS_SUCCESS, 0))
{ {
NIS_RES_STATUS (res) = status; NIS_RES_STATUS (res) = status;
goto out; goto out;
} }
status = __nisbind_create (&bptr, dir->do_servers.do_servers_val,
dir->do_servers.do_servers_len, flags);
if (status != NIS_SUCCESS)
{
NIS_RES_STATUS (res) = status;
nis_free_directory (dir);
goto out;;
}
while (__nisbind_connect (&bptr) != NIS_SUCCESS)
{
if (__nisbind_next (&bptr) != NIS_SUCCESS)
{
nis_free_directory (dir);
NIS_RES_STATUS (res) = NIS_NAMEUNREACHABLE;
goto out;
}
}
do do
{ {
static const struct timeval RPCTIMEOUT = {10, 0}; static const struct timeval RPCTIMEOUT = {10, 0};
enum clnt_stat result; enum clnt_stat result;
char ndomain[strlen (req.ns_name) + 1];
again: again:
result = clnt_call (bptr.clnt, NIS_LOOKUP, result = clnt_call (bptr.clnt, NIS_LOOKUP,
@ -106,11 +90,9 @@ nis_lookup (const_nis_name name, const unsigned int flags)
if (NIS_RES_STATUS (res) == NIS_SUCCESS) if (NIS_RES_STATUS (res) == NIS_SUCCESS)
{ {
if (__type_of(NIS_RES_OBJECT (res)) == NIS_LINK_OBJ if (__type_of (NIS_RES_OBJECT (res)) == NIS_LINK_OBJ
&& (flags & FOLLOW_LINKS)) /* We are following links */ && (flags & FOLLOW_LINKS)) /* We are following links */
{ {
if (count_links)
free (req.ns_name);
/* if we hit the link limit, bail */ /* if we hit the link limit, bail */
if (count_links > NIS_MAXLINKS) if (count_links > NIS_MAXLINKS)
{ {
@ -119,31 +101,15 @@ nis_lookup (const_nis_name name, const unsigned int flags)
} }
++count_links; ++count_links;
req.ns_name = req.ns_name =
strdup (NIS_RES_OBJECT (res)->LI_data.li_name); strdupa (NIS_RES_OBJECT (res)->LI_data.li_name);
if (req.ns_name == NULL)
{
nis_free_directory (dir);
res = NULL;
goto out;
}
/* The following is a non-obvious optimization. A /* The following is a non-obvious optimization. A
nis_freeresult call would call xdr_free as the nis_freeresult call would call xdr_free as the
following code. But it also would unnecessarily following code. But it also would unnecessarily
free the result structure. We avoid this here free the result structure. We avoid this here
along with the necessary tests. */ along with the necessary tests. */
#if 1
xdr_free ((xdrproc_t) _xdr_nis_result, (char *) res); xdr_free ((xdrproc_t) _xdr_nis_result, (char *) res);
memset (res, '\0', sizeof (*res)); memset (res, '\0', sizeof (*res));
#else
nis_freeresult (res);
res = calloc (1, sizeof (nis_result));
if (res == NULL)
{
__nisbind_destroy (&bptr);
return NULL;
}
#endif
link_first_try = 1; /* Try at first the old binding */ link_first_try = 1; /* Try at first the old binding */
goto again; goto again;
@ -176,7 +142,24 @@ nis_lookup (const_nis_name name, const unsigned int flags)
} }
else else
if (__nisbind_next (&bptr) != NIS_SUCCESS) if (__nisbind_next (&bptr) != NIS_SUCCESS)
break; /* No more servers to search */ {
/* No more servers to search. Try parent. */
nis_domain_of_r (req.ns_name, ndomain,
sizeof (ndomain));
req.ns_name = strdupa (ndomain);
__nisbind_destroy (&bptr);
nis_free_directory (dir);
dir = NULL;
status = __prepare_niscall (req.ns_name, &dir,
&bptr, flags);
if (__builtin_expect (status != NIS_SUCCESS, 0))
{
NIS_RES_STATUS (res) = status;
goto out;
}
goto again;
}
while (__nisbind_connect (&bptr) != NIS_SUCCESS) while (__nisbind_connect (&bptr) != NIS_SUCCESS)
{ {