* nis/nis_call.c (__prepare_niscall): New function. Split out

from __do_niscall.
	* nis/nis_table.c (__create_ib_request): Renamed from create_ib_request
	and exported.
	(__follow_path): New function.  Split out from nis_list.
	* nis/nis_xdr.h: Add libnsl_hidden_proto for _xdr_ib_request and
	_xdr_nis_result.
	* nis/nis_xdr.c: Add libnsl_hidden_def for _xdr_ib_request and
	_xdr_nis_result.
	* nis/libnsl.h: Declare __prepare_niscall, __create_ib_request,
	and __follow_path.
	* nis/Versions: Export __prepare_niscall, __create_ib_request,
	__follow_path, __do_niscall3, _xdr_ib_request, and _xdr_nis_result
	from libnsl for version GLIBC_PRIVATE.
	* nis/nisplus-parser.h: Remove _nss_nisplus_parse_pwent_chk.
	Remove entry parameter from _nss_nisplus_parse_pwent and
	_nss_nisplus_parse_grent.
	* nis/nss_nisplus/nisplus-parser.c: Likewise.
	* nis/nss_nisplus/nisplus-pwd.c: Remove support for SETENT_BATCH_READ
	again.  Rewrite getpwent handling to not use nis_first_entry and
	nis_next_entry.  Roll out own niscall handling.
	* nis/nss_nisplus/nisplus-grp.c: Likewise.

	* sunrpc/xdr_rec.c: Fix typo in comment.

2006-05-18  David Woodhouse  <dwmw2@redhat.com>
This commit is contained in:
Ulrich Drepper 2006-05-20 19:22:30 +00:00
parent 1d4f062ab8
commit a17fa6100d
12 changed files with 483 additions and 362 deletions

View File

@ -1,3 +1,30 @@
2006-05-20 Ulrich Drepper <drepper@redhat.com>
* nis/nis_call.c (__prepare_niscall): New function. Split out
from __do_niscall.
* nis/nis_table.c (__create_ib_request): Renamed from create_ib_request
and exported.
(__follow_path): New function. Split out from nis_list.
* nis/nis_xdr.h: Add libnsl_hidden_proto for _xdr_ib_request and
_xdr_nis_result.
* nis/nis_xdr.c: Add libnsl_hidden_def for _xdr_ib_request and
_xdr_nis_result.
* nis/libnsl.h: Declare __prepare_niscall, __create_ib_request,
and __follow_path.
* nis/Versions: Export __prepare_niscall, __create_ib_request,
__follow_path, __do_niscall3, _xdr_ib_request, and _xdr_nis_result
from libnsl for version GLIBC_PRIVATE.
* nis/nisplus-parser.h: Remove _nss_nisplus_parse_pwent_chk.
Remove entry parameter from _nss_nisplus_parse_pwent and
_nss_nisplus_parse_grent.
* nis/nss_nisplus/nisplus-parser.c: Likewise.
* nis/nss_nisplus/nisplus-pwd.c: Remove support for SETENT_BATCH_READ
again. Rewrite getpwent handling to not use nis_first_entry and
nis_next_entry. Roll out own niscall handling.
* nis/nss_nisplus/nisplus-grp.c: Likewise.
* sunrpc/xdr_rec.c: Fix typo in comment.
2006-05-19 Ulrich Drepper <drepper@redhat.com> 2006-05-19 Ulrich Drepper <drepper@redhat.com>
* nis/nis_call.c (__do_niscall3): Avoid code duplication in error * nis/nis_call.c (__do_niscall3): Avoid code duplication in error
@ -30,7 +57,7 @@
cb->serv together. Remove now obsolete free calls. cb->serv together. Remove now obsolete free calls.
(__nis_destroy_callback): Remove now obsolete free call. (__nis_destroy_callback): Remove now obsolete free call.
2006-05-18 David Woodhouse <dwmw2@infradead.org> 2006-05-18 David Woodhouse <dwmw2@redhat.com>
* sysdeps/posix/getaddrinfo.c: Add unique labels to the default * sysdeps/posix/getaddrinfo.c: Add unique labels to the default
RFC3484 precedence table for fec0::/10 and fc00::/7 (site-local RFC3484 precedence table for fec0::/10 and fc00::/7 (site-local

View File

@ -58,7 +58,8 @@ libnsl {
xdr_ypall; xdr_ypall;
} }
GLIBC_PRIVATE { GLIBC_PRIVATE {
_nsl_default_nss; _nsl_default_nss; __prepare_niscall; __follow_path; __do_niscall3;
__create_ib_request; _xdr_ib_request; _xdr_nis_result;
} }
} }

View File

@ -16,6 +16,8 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */ 02111-1307 USA. */
#include <rpcsvc/nis.h>
#define NSS_FLAG_NETID_AUTHORITATIVE 1 #define NSS_FLAG_NETID_AUTHORITATIVE 1
#define NSS_FLAG_SERVICES_AUTHORITATIVE 2 #define NSS_FLAG_SERVICES_AUTHORITATIVE 2
#define NSS_FLAG_SETENT_BATCH_READ 4 #define NSS_FLAG_SETENT_BATCH_READ 4
@ -23,3 +25,15 @@
/* Get current set of default flags. */ /* Get current set of default flags. */
extern int _nsl_default_nss (void); extern int _nsl_default_nss (void);
/* Set up everything for a call to __do_niscall3. */
extern nis_error __prepare_niscall (const_nis_name name, directory_obj **dirp,
dir_binding *bptrp, unsigned int flags);
extern struct ib_request *__create_ib_request (const_nis_name name,
unsigned int flags);
libnsl_hidden_proto (__create_ib_request)
extern nis_error __follow_path (char **tablepath, char **tableptr,
struct ib_request *ibreq, dir_binding *bptr);
libnsl_hidden_proto (__follow_path)

View File

@ -531,50 +531,68 @@ __nisfind_server (const_nis_name name, directory_obj **dir)
return result; return result;
} }
nis_error
__prepare_niscall (const_nis_name name, directory_obj **dirp,
dir_binding *bptrp, unsigned int flags)
{
nis_error retcode = __nisfind_server (name, dirp);
if (__builtin_expect (retcode != NIS_SUCCESS, 0))
return retcode;
nis_server *server;
u_int server_len;
if (flags & MASTER_ONLY)
{
server = (*dirp)->do_servers.do_servers_val;
server_len = 1;
}
else
{
server = (*dirp)->do_servers.do_servers_val;
server_len = (*dirp)->do_servers.do_servers_len;
}
retcode = __nisbind_create (bptrp, server, server_len, flags);
if (retcode == NIS_SUCCESS)
{
do
if (__nisbind_connect (bptrp) == NIS_SUCCESS)
return NIS_SUCCESS;
while (__nisbind_next (bptrp) == NIS_SUCCESS);
__nisbind_destroy (bptrp);
memset (bptrp, '\0', sizeof (*bptrp));
retcode = NIS_NAMEUNREACHABLE;
}
nis_free_directory (*dirp);
*dirp = NULL;
return retcode;
}
nis_error nis_error
__do_niscall (const_nis_name name, u_long prog, xdrproc_t xargs, __do_niscall (const_nis_name name, u_long prog, xdrproc_t xargs,
caddr_t req, xdrproc_t xres, caddr_t resp, unsigned int flags, caddr_t req, xdrproc_t xres, caddr_t resp, unsigned int flags,
nis_cb *cb) nis_cb *cb)
{ {
nis_error retcode;
dir_binding bptr; dir_binding bptr;
directory_obj *dir = NULL; directory_obj *dir = NULL;
nis_server *server;
u_int server_len;
int saved_errno = errno; int saved_errno = errno;
retcode = __nisfind_server (name, &dir); nis_error retcode = __prepare_niscall (name, &dir, &bptr, flags);
if (retcode != NIS_SUCCESS)
return retcode;
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 = __nisbind_create (&bptr, server, server_len, flags);
if (retcode == NIS_SUCCESS) if (retcode == NIS_SUCCESS)
{ {
while (__nisbind_connect (&bptr) != NIS_SUCCESS)
{
if (__nisbind_next (&bptr) != NIS_SUCCESS)
{
nis_free_directory (dir);
return NIS_NAMEUNREACHABLE;
}
}
retcode = __do_niscall3 (&bptr, prog, xargs, req, xres, resp, flags, cb); retcode = __do_niscall3 (&bptr, prog, xargs, req, xres, resp, flags, cb);
__nisbind_destroy (&bptr); __nisbind_destroy (&bptr);
}
nis_free_directory (dir); nis_free_directory (dir);
}
__set_errno (saved_errno); __set_errno (saved_errno);

View File

@ -17,15 +17,17 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */ 02111-1307 USA. */
#include <assert.h>
#include <string.h> #include <string.h>
#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"
static struct ib_request * struct ib_request *
create_ib_request (const_nis_name name, unsigned int flags) __create_ib_request (const_nis_name name, unsigned int flags)
{ {
struct ib_request *ibreq = calloc (1, sizeof (struct ib_request)); struct ib_request *ibreq = calloc (1, sizeof (struct ib_request));
nis_attr *search_val = NULL; nis_attr *search_val = NULL;
@ -125,6 +127,7 @@ create_ib_request (const_nis_name name, unsigned int flags)
return ibreq; return ibreq;
} }
libnsl_hidden_def (__create_ib_request)
static const struct timeval RPCTIMEOUT = {10, 0}; static const struct timeval RPCTIMEOUT = {10, 0};
@ -160,6 +163,38 @@ get_tablepath (char *name, dir_binding *bptr)
return str; return str;
} }
nis_error
__follow_path (char **tablepath, char **tableptr, struct ib_request *ibreq,
dir_binding *bptr)
{
if (*tablepath == NULL)
{
*tablepath = get_tablepath (ibreq->ibr_name, bptr);
if (*tablepath == NULL)
return NIS_NOMEMORY;
*tableptr = *tablepath;
}
if (*tableptr == NULL)
return NIS_NOTFOUND;
char *newname = strsep (tableptr, ":");
if (newname[0] == '\0')
return NIS_NOTFOUND;
newname = strdup (newname);
if (newname == NULL)
return NIS_NOMEMORY;
free (ibreq->ibr_name);
ibreq->ibr_name = newname;
return NIS_SUCCESS;
}
libnsl_hidden_def (__follow_path)
nis_result * nis_result *
nis_list (const_nis_name name, unsigned int flags, nis_list (const_nis_name name, unsigned int flags,
int (*callback) (const_nis_name name, int (*callback) (const_nis_name name,
@ -193,7 +228,7 @@ nis_list (const_nis_name name, unsigned int flags,
return res; return res;
} }
ibreq = create_ib_request (name, flags); ibreq = __create_ib_request (name, flags);
if (ibreq == NULL) if (ibreq == NULL)
{ {
status = NIS_BADNAME; status = NIS_BADNAME;
@ -260,6 +295,7 @@ nis_list (const_nis_name name, unsigned int flags,
if (callback != NULL) if (callback != NULL)
{ {
assert (cb == NULL);
cb = __nis_create_callback (callback, userdata, flags); cb = __nis_create_callback (callback, userdata, flags);
ibreq->ibr_cbhost.ibr_cbhost_len = 1; ibreq->ibr_cbhost.ibr_cbhost_len = 1;
ibreq->ibr_cbhost.ibr_cbhost_val = cb->serv; ibreq->ibr_cbhost.ibr_cbhost_val = cb->serv;
@ -327,69 +363,30 @@ nis_list (const_nis_name name, unsigned int flags,
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)
goto fail;
#endif
first_try = 1; /* Try at first the old binding */ first_try = 1; /* Try at first the old binding */
goto again; goto again;
} }
else if ((flags & FOLLOW_PATH) else if ((flags & FOLLOW_PATH)
&& NIS_RES_STATUS (res) == NIS_PARTIAL) && NIS_RES_STATUS (res) == NIS_PARTIAL)
{ {
if (tablepath == NULL) clnt_status = __follow_path (&tablepath, &tableptr, ibreq,
&bptr);
if (clnt_status != NIS_SUCCESS)
{ {
tablepath = get_tablepath (ibreq->ibr_name, &bptr); NIS_RES_STATUS (res) = clnt_status;
tableptr = tablepath;
}
if (tableptr == NULL)
{
++done;
break;
}
free (ibreq->ibr_name);
ibreq->ibr_name = strsep (&tableptr, ":");
if (ibreq->ibr_name == NULL || ibreq->ibr_name[0] == '\0')
{
ibreq->ibr_name = strdup ("");
if (ibreq->ibr_name == NULL)
{
NIS_RES_STATUS (res) = NIS_NOMEMORY;
goto fail;
}
++done; ++done;
} }
else else
{ {
ibreq->ibr_name = strdup (ibreq->ibr_name);
/* 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));
if (ibreq->ibr_name == NULL)
{
NIS_RES_STATUS (res) = NIS_NOMEMORY;
goto fail;
}
#else
nis_freeresult (res);
res = calloc (1, sizeof (nis_result));
if (res == NULL || ibreq->ibr_name == NULL)
{
free (res);
res = NULL;
goto fail;
}
#endif
first_try = 1; first_try = 1;
goto again; goto again;
} }
@ -407,30 +404,10 @@ nis_list (const_nis_name name, unsigned int flags,
++done; ++done;
else else
{ {
if (tablepath == NULL) NIS_RES_STATUS (res)
{ = __follow_path (&tablepath, &tableptr, ibreq, &bptr);
tablepath = get_tablepath (ibreq->ibr_name, &bptr); if (NIS_RES_STATUS (res) != NIS_SUCCESS)
tableptr = tablepath; ++done;
}
if (tableptr == NULL)
{
++done;
break;
}
free (ibreq->ibr_name);
ibreq->ibr_name = strsep (&tableptr, ":");
if (ibreq->ibr_name == NULL || ibreq->ibr_name[0] == '\0')
{
ibreq->ibr_name = strdup ("");
++done;
}
else
ibreq->ibr_name = strdup (ibreq->ibr_name);
if (ibreq->ibr_name == NULL)
{
NIS_RES_STATUS (res) = NIS_NOMEMORY;
goto fail;
}
} }
} }
break; break;
@ -524,7 +501,7 @@ nis_add_entry (const_nis_name name, const nis_object *obj2, unsigned int flags)
return res; return res;
} }
ib_request *ibreq = create_ib_request (name, flags); ib_request *ibreq = __create_ib_request (name, flags);
if (ibreq == NULL) if (ibreq == NULL)
{ {
NIS_RES_STATUS (res) = NIS_BADNAME; NIS_RES_STATUS (res) = NIS_BADNAME;
@ -587,7 +564,7 @@ nis_modify_entry (const_nis_name name, const nis_object *obj2,
if (res == NULL) if (res == NULL)
return NULL; return NULL;
ibreq = create_ib_request (name, flags); ibreq = __create_ib_request (name, flags);
if (ibreq == NULL) if (ibreq == NULL)
{ {
NIS_RES_STATUS (res) = NIS_BADNAME; NIS_RES_STATUS (res) = NIS_BADNAME;
@ -646,7 +623,7 @@ nis_remove_entry (const_nis_name name, const nis_object *obj,
return res; return res;
} }
ibreq = create_ib_request (name, flags); ibreq = __create_ib_request (name, flags);
if (ibreq == NULL) if (ibreq == NULL)
{ {
NIS_RES_STATUS (res) = NIS_BADNAME; NIS_RES_STATUS (res) = NIS_BADNAME;
@ -693,7 +670,7 @@ nis_first_entry (const_nis_name name)
return res; return res;
} }
ibreq = create_ib_request (name, 0); ibreq = __create_ib_request (name, 0);
if (ibreq == NULL) if (ibreq == NULL)
{ {
NIS_RES_STATUS (res) = NIS_BADNAME; NIS_RES_STATUS (res) = NIS_BADNAME;
@ -730,7 +707,7 @@ nis_next_entry (const_nis_name name, const netobj *cookie)
return res; return res;
} }
ibreq = create_ib_request (name, 0); ibreq = __create_ib_request (name, 0);
if (ibreq == NULL) if (ibreq == NULL)
{ {
NIS_RES_STATUS (res) = NIS_BADNAME; NIS_RES_STATUS (res) = NIS_BADNAME;

View File

@ -308,6 +308,7 @@ _xdr_nis_result (XDR *xdrs, nis_result *objp)
} }
return res; return res;
} }
libnsl_hidden_def (_xdr_nis_result)
bool_t bool_t
_xdr_ns_request (XDR *xdrs, ns_request *objp) _xdr_ns_request (XDR *xdrs, ns_request *objp)
@ -357,6 +358,7 @@ _xdr_ib_request (XDR *xdrs, ib_request *objp)
} }
return res; return res;
} }
libnsl_hidden_def (_xdr_ib_request)
bool_t bool_t
_xdr_ping_args (XDR *xdrs, ping_args *objp) _xdr_ping_args (XDR *xdrs, ping_args *objp)

View File

@ -28,9 +28,7 @@ extern bool_t _xdr_nis_server (XDR *, nis_server*) attribute_hidden;
extern bool_t _xdr_directory_obj (XDR *, directory_obj*) attribute_hidden; extern bool_t _xdr_directory_obj (XDR *, directory_obj*) attribute_hidden;
extern bool_t _xdr_nis_object (XDR *, nis_object*) attribute_hidden; extern bool_t _xdr_nis_object (XDR *, nis_object*) attribute_hidden;
extern bool_t _xdr_nis_error (XDR *, nis_error*) attribute_hidden; extern bool_t _xdr_nis_error (XDR *, nis_error*) attribute_hidden;
extern bool_t _xdr_nis_result (XDR *, nis_result*) attribute_hidden;
extern bool_t _xdr_ns_request (XDR *, ns_request*) attribute_hidden; extern bool_t _xdr_ns_request (XDR *, ns_request*) attribute_hidden;
extern bool_t _xdr_ib_request (XDR *, ib_request*) attribute_hidden;
extern bool_t _xdr_ping_args (XDR *, ping_args*) attribute_hidden; extern bool_t _xdr_ping_args (XDR *, ping_args*) attribute_hidden;
extern bool_t _xdr_cp_result (XDR *, cp_result*) attribute_hidden; extern bool_t _xdr_cp_result (XDR *, cp_result*) attribute_hidden;
extern bool_t _xdr_nis_tag (XDR *, nis_tag*) attribute_hidden; extern bool_t _xdr_nis_tag (XDR *, nis_tag*) attribute_hidden;
@ -38,4 +36,9 @@ extern bool_t _xdr_nis_taglist (XDR *, nis_taglist*) attribute_hidden;
extern bool_t _xdr_fd_args (XDR *, fd_args*) attribute_hidden; extern bool_t _xdr_fd_args (XDR *, fd_args*) attribute_hidden;
extern bool_t _xdr_fd_result (XDR *, fd_result*) attribute_hidden; extern bool_t _xdr_fd_result (XDR *, fd_result*) attribute_hidden;
extern bool_t _xdr_ib_request (XDR *, ib_request*);
libnsl_hidden_proto (_xdr_ib_request)
extern bool_t _xdr_nis_result (XDR *, nis_result*);
libnsl_hidden_proto (_xdr_nis_result)
#endif #endif

View File

@ -24,15 +24,12 @@
#include <grp.h> #include <grp.h>
#include <shadow.h> #include <shadow.h>
extern int _nss_nisplus_parse_pwent (nis_result *result, size_t entry, extern int _nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
struct passwd *pw, char *buffer, char *buffer, size_t buflen, int *errnop);
size_t buflen, int *errnop);
extern int _nss_nisplus_parse_pwent_chk (nis_result *result, struct passwd *pw, extern int _nss_nisplus_parse_grent (nis_result *result, struct group *gr,
char *buffer, size_t buflen, char *buffer, size_t buflen, int *errnop);
int *errnop);
extern int _nss_nisplus_parse_grent (nis_result *result, u_long entry,
struct group *gr, char *buffer,
size_t buflen, int *errnop);
extern int _nss_nisplus_parse_spent (nis_result *result, struct spwd *sp, extern int _nss_nisplus_parse_spent (nis_result *result, struct spwd *sp,
char *buffer, size_t buflen, int *errnop); char *buffer, size_t buflen, int *errnop);

View File

@ -29,12 +29,23 @@
#include "nss-nisplus.h" #include "nss-nisplus.h"
#include "nisplus-parser.h" #include "nisplus-parser.h"
#include <libnsl.h>
#include <nis_intern.h>
#include <nis_xdr.h>
__libc_lock_define_initialized (static, lock); __libc_lock_define_initialized (static, lock);
static nis_result *result; /* Connection information. */
static unsigned long next_entry; static ib_request *ibreq;
static directory_obj *dir;
static dir_binding bptr;
static char *tablepath;
static char *tableptr;
/* Cursor. */
static netobj cursor;
static nis_name tablename_val; static nis_name tablename_val;
static size_t tablename_len; static size_t tablename_len;
@ -66,43 +77,57 @@ _nss_create_tablename (int *errnop)
return NSS_STATUS_SUCCESS; return NSS_STATUS_SUCCESS;
} }
static enum nss_status
internal_setgrent (void)
{
enum nss_status status;
if (result != NULL) static void
{ internal_endgrent (void)
nis_freeresult (result); {
result = NULL; __nisbind_destroy (&bptr);
} memset (&bptr, '\0', sizeof (bptr));
next_entry = 0;
nis_free_directory (dir);
dir = NULL;
nis_free_request (ibreq);
ibreq = NULL;
xdr_free ((xdrproc_t) xdr_netobj, (char *) &cursor);
memset (&cursor, '\0', sizeof (cursor));
free (tablepath);
tableptr = tablepath = NULL;
}
static enum nss_status
internal_setgrent (int *errnop)
{
enum nss_status status = NSS_STATUS_SUCCESS;
if (tablename_val == NULL) if (tablename_val == NULL)
{ status = _nss_create_tablename (errnop);
int err;
if (_nss_create_tablename (&err) != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
}
result = nis_list (tablename_val, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL); if (status == NSS_STATUS_SUCCESS)
if (result == NULL)
{ {
status = NSS_STATUS_TRYAGAIN; ibreq = __create_ib_request (tablename_val, 0);
__set_errno (ENOMEM); if (ibreq == NULL)
}
else
{
status = niserr2nss (result->status);
if (status != NSS_STATUS_SUCCESS)
{ {
nis_freeresult (result); *errnop = errno;
result = NULL; return NSS_STATUS_TRYAGAIN;
}
nis_error retcode = __prepare_niscall (tablename_val, &dir, &bptr, 0);
if (retcode != NIS_SUCCESS)
{
nis_free_request (ibreq);
ibreq = NULL;
status = niserr2nss (retcode);
} }
} }
return status; return status;
} }
enum nss_status enum nss_status
_nss_nisplus_setgrent (int stayopen) _nss_nisplus_setgrent (int stayopen)
{ {
@ -110,60 +135,133 @@ _nss_nisplus_setgrent (int stayopen)
__libc_lock_lock (lock); __libc_lock_lock (lock);
status = internal_setgrent (); internal_endgrent ();
// XXX We need to be able to set errno. Pass in new parameter.
int err;
status = internal_setgrent (&err);
__libc_lock_unlock (lock); __libc_lock_unlock (lock);
return status; return status;
} }
enum nss_status enum nss_status
_nss_nisplus_endgrent (void) _nss_nisplus_endgrent (void)
{ {
__libc_lock_lock (lock); __libc_lock_lock (lock);
if (result != NULL) internal_endgrent ();
{
nis_freeresult (result);
result = NULL;
}
__libc_lock_unlock (lock); __libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS; return NSS_STATUS_SUCCESS;
} }
static enum nss_status static enum nss_status
internal_nisplus_getgrent_r (struct group *gr, char *buffer, size_t buflen, internal_nisplus_getgrent_r (struct group *gr, char *buffer, size_t buflen,
int *errnop) int *errnop)
{ {
int parse_res; int parse_res = -1;
enum nss_status retval = NSS_STATUS_SUCCESS;
if (result == NULL)
{
enum nss_status status;
status = internal_setgrent ();
if (result == NULL || status != NSS_STATUS_SUCCESS)
return status;
}
/* Get the next entry until we found a correct one. */ /* Get the next entry until we found a correct one. */
do do
{ {
if (next_entry >= result->objects.objects_len) nis_error status;
return NSS_STATUS_NOTFOUND; nis_result result;
memset (&result, '\0', sizeof (result));
parse_res = _nss_nisplus_parse_grent (result, next_entry, gr, if (cursor.n_bytes == NULL)
{
if (ibreq == NULL)
{
retval = internal_setgrent (errnop);
if (retval != NSS_STATUS_SUCCESS)
return retval;
}
status = __do_niscall3 (&bptr, NIS_IBFIRST,
(xdrproc_t) _xdr_ib_request,
(caddr_t) ibreq,
(xdrproc_t) _xdr_nis_result,
(caddr_t) &result,
0, NULL);
}
else
{
ibreq->ibr_cookie.n_bytes = cursor.n_bytes;
ibreq->ibr_cookie.n_len = cursor.n_len;
status = __do_niscall3 (&bptr, NIS_IBNEXT,
(xdrproc_t) _xdr_ib_request,
(caddr_t) ibreq,
(xdrproc_t) _xdr_nis_result,
(caddr_t) &result,
0, NULL);
ibreq->ibr_cookie.n_bytes = NULL;
ibreq->ibr_cookie.n_len = 0;
}
if (status != NIS_SUCCESS)
return niserr2nss (status);
if (NIS_RES_STATUS (&result) == NIS_NOTFOUND)
{
/* No more entries on this server. This means we have to go
to the next server on the path. */
status = __follow_path (&tablepath, &tableptr, ibreq, &bptr);
if (status != NIS_SUCCESS)
return niserr2nss (status);
directory_obj *newdir = NULL;
dir_binding newbptr;
status = __prepare_niscall (ibreq->ibr_name, &newdir, &newbptr, 0);
if (status != NIS_SUCCESS)
return niserr2nss (status);
nis_free_directory (dir);
dir = newdir;
__nisbind_destroy (&bptr);
bptr = newbptr;
xdr_free ((xdrproc_t) xdr_netobj, (char *) &result.cookie);
result.cookie.n_bytes = NULL;
result.cookie.n_len = 0;
parse_res = 0;
goto next;
}
else if (NIS_RES_STATUS (&result) != NIS_SUCCESS)
return niserr2nss (NIS_RES_STATUS (&result));
parse_res = _nss_nisplus_parse_grent (&result, gr,
buffer, buflen, errnop); buffer, buflen, errnop);
if (parse_res == -1) if (__builtin_expect (parse_res == -1, 0))
return NSS_STATUS_TRYAGAIN; {
*errnop = ERANGE;
retval = NSS_STATUS_TRYAGAIN;
goto freeres;
}
++next_entry; next:
/* Free the old cursor. */
xdr_free ((xdrproc_t) xdr_netobj, (char *) &cursor);
/* Remember the new one. */
cursor.n_bytes = result.cookie.n_bytes;
cursor.n_len = result.cookie.n_len;
/* Free the result structure. NB: we do not remove the cookie. */
result.cookie.n_bytes = NULL;
result.cookie.n_len = 0;
freeres:
xdr_free ((xdrproc_t) _xdr_nis_result, (char *) &result);
memset (&result, '\0', sizeof (result));
} }
while (!parse_res); while (!parse_res);
return NSS_STATUS_SUCCESS; return retval;
} }
enum nss_status enum nss_status
@ -227,7 +325,7 @@ _nss_nisplus_getgrnam_r (const char *name, struct group *gr,
return status; return status;
} }
parse_res = _nss_nisplus_parse_grent (result, 0, gr, buffer, buflen, errnop); parse_res = _nss_nisplus_parse_grent (result, gr, buffer, buflen, errnop);
nis_freeresult (result); nis_freeresult (result);
if (__builtin_expect (parse_res < 1, 0)) if (__builtin_expect (parse_res < 1, 0))
{ {
@ -288,7 +386,7 @@ _nss_nisplus_getgrgid_r (const gid_t gid, struct group *gr,
return status; return status;
} }
parse_res = _nss_nisplus_parse_grent (result, 0, gr, buffer, buflen, errnop); parse_res = _nss_nisplus_parse_grent (result, gr, buffer, buflen, errnop);
nis_freeresult (result); nis_freeresult (result);
if (__builtin_expect (parse_res < 1, 0)) if (__builtin_expect (parse_res < 1, 0))

View File

@ -31,10 +31,16 @@
#define NISENTRYLEN(idx, col, res) \ #define NISENTRYLEN(idx, col, res) \
(NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len) (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len)
#define NISOBJVAL(col, obj) \
((obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val)
#define NISOBJLEN(col, obj) \
((obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len)
int int
_nss_nisplus_parse_pwent_chk (nis_result *result, struct passwd *pw, _nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
char *buffer, size_t buflen, int *errnop) char *buffer, size_t buflen, int *errnop)
{ {
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
|| NIS_RES_NUMOBJ (result) != 1 || NIS_RES_NUMOBJ (result) != 1
@ -43,19 +49,12 @@ _nss_nisplus_parse_pwent_chk (nis_result *result, struct passwd *pw,
|| NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 7) || NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 7)
return 0; return 0;
return _nss_nisplus_parse_pwent (result, 0, pw, buffer, buflen, errnop); nis_object *obj = NIS_RES_OBJECT (result);
}
int
_nss_nisplus_parse_pwent (nis_result *result, size_t entry, struct passwd *pw,
char *buffer, size_t buflen, int *errnop)
{
char *first_unused = buffer; char *first_unused = buffer;
size_t room_left = buflen; size_t room_left = buflen;
size_t len; size_t len;
if (NISENTRYLEN (entry, 0, result) >= room_left) if (NISOBJLEN (0, obj) >= room_left)
{ {
/* The line is too long for our buffer. */ /* The line is too long for our buffer. */
no_more_room: no_more_room:
@ -63,9 +62,8 @@ _nss_nisplus_parse_pwent (nis_result *result, size_t entry, struct passwd *pw,
return -1; return -1;
} }
strncpy (first_unused, NISENTRYVAL (entry, 0, result), strncpy (first_unused, NISOBJVAL (0, obj), NISOBJLEN (0, obj));
NISENTRYLEN (entry, 0, result)); first_unused[NISOBJLEN (0, obj)] = '\0';
first_unused[NISENTRYLEN (entry, 0, result)] = '\0';
len = strlen (first_unused); len = strlen (first_unused);
if (len == 0) /* No name ? Should never happen, database is corrupt */ if (len == 0) /* No name ? Should never happen, database is corrupt */
return 0; return 0;
@ -73,19 +71,18 @@ _nss_nisplus_parse_pwent (nis_result *result, size_t entry, struct passwd *pw,
room_left -= len + 1; room_left -= len + 1;
first_unused += len + 1; first_unused += len + 1;
if (NISENTRYLEN (entry, 1, result) >= room_left) if (NISOBJLEN (1, obj) >= room_left)
goto no_more_room; goto no_more_room;
strncpy (first_unused, NISENTRYVAL (entry, 1, result), strncpy (first_unused, NISOBJVAL (1, obj), NISOBJLEN (1, obj));
NISENTRYLEN (entry, 1, result)); first_unused[NISOBJLEN (1, obj)] = '\0';
first_unused[NISENTRYLEN (entry, 1, result)] = '\0';
pw->pw_passwd = first_unused; pw->pw_passwd = first_unused;
len = strlen (first_unused); len = strlen (first_unused);
room_left -= len + 1; room_left -= len + 1;
first_unused += len + 1; first_unused += len + 1;
char *numstr = NISENTRYVAL (entry, 2, result); char *numstr = NISOBJVAL (2, obj);
len = NISENTRYLEN (entry, 2, result); len = NISOBJLEN (2, obj);
if (len == 0 && numstr[len - 1] != '\0') if (len == 0 && numstr[len - 1] != '\0')
{ {
if (len >= room_left) if (len >= room_left)
@ -100,8 +97,8 @@ _nss_nisplus_parse_pwent (nis_result *result, size_t entry, struct passwd *pw,
return 0; return 0;
pw->pw_uid = strtoul (numstr, NULL, 10); pw->pw_uid = strtoul (numstr, NULL, 10);
numstr = NISENTRYVAL (entry, 3, result); numstr = NISOBJVAL (3, obj);
len = NISENTRYLEN (entry, 3, result); len = NISOBJLEN (3, obj);
if (len == 0 && numstr[len - 1] != '\0') if (len == 0 && numstr[len - 1] != '\0')
{ {
if (len >= room_left) if (len >= room_left)
@ -116,34 +113,31 @@ _nss_nisplus_parse_pwent (nis_result *result, size_t entry, struct passwd *pw,
return 0; return 0;
pw->pw_gid = strtoul (numstr, NULL, 10); pw->pw_gid = strtoul (numstr, NULL, 10);
if (NISENTRYLEN(entry, 4, result) >= room_left) if (NISOBJLEN(4, obj) >= room_left)
goto no_more_room; goto no_more_room;
strncpy (first_unused, NISENTRYVAL (entry, 4, result), strncpy (first_unused, NISOBJVAL (4, obj), NISOBJLEN (4, obj));
NISENTRYLEN (entry, 4, result)); first_unused[NISOBJLEN (4, obj)] = '\0';
first_unused[NISENTRYLEN (entry, 4, result)] = '\0';
pw->pw_gecos = first_unused; pw->pw_gecos = first_unused;
len = strlen (first_unused); len = strlen (first_unused);
room_left -= len + 1; room_left -= len + 1;
first_unused += len + 1; first_unused += len + 1;
if (NISENTRYLEN (entry, 5, result) >= room_left) if (NISOBJLEN (5, obj) >= room_left)
goto no_more_room; goto no_more_room;
strncpy (first_unused, NISENTRYVAL (entry, 5, result), strncpy (first_unused, NISOBJVAL (5, obj), NISOBJLEN (5, obj));
NISENTRYLEN (entry, 5, result)); first_unused[NISOBJLEN (5, obj)] = '\0';
first_unused[NISENTRYLEN (entry, 5, result)] = '\0';
pw->pw_dir = first_unused; pw->pw_dir = first_unused;
len = strlen (first_unused); len = strlen (first_unused);
room_left -= len + 1; room_left -= len + 1;
first_unused += len + 1; first_unused += len + 1;
if (NISENTRYLEN (entry, 6, result) >= room_left) if (NISOBJLEN (6, obj) >= room_left)
goto no_more_room; goto no_more_room;
strncpy (first_unused, NISENTRYVAL (entry, 6, result), strncpy (first_unused, NISOBJVAL (6, obj), NISOBJLEN (6, obj));
NISENTRYLEN (entry, 6, result)); first_unused[NISOBJLEN (6, obj)] = '\0';
first_unused[NISENTRYLEN (entry, 6, result)] = '\0';
pw->pw_shell = first_unused; pw->pw_shell = first_unused;
len = strlen (first_unused); len = strlen (first_unused);
room_left -= len + 1; room_left -= len + 1;
@ -154,26 +148,23 @@ _nss_nisplus_parse_pwent (nis_result *result, size_t entry, struct passwd *pw,
int int
_nss_nisplus_parse_grent (nis_result *result, u_long entry, struct group *gr, _nss_nisplus_parse_grent (nis_result *result, struct group *gr,
char *buffer, size_t buflen, int *errnop) char *buffer, size_t buflen, int *errnop)
{ {
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
|| __type_of(NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ
|| strcmp (NIS_RES_OBJECT (result)[0].EN_data.en_type, "group_tbl") != 0
|| NIS_RES_OBJECT (result)[0].EN_data.en_cols.en_cols_len < 4)
return 0;
nis_object *obj = NIS_RES_OBJECT (result);
char *first_unused = buffer; char *first_unused = buffer;
size_t room_left = buflen; size_t room_left = buflen;
char *line; char *line;
int count; int count;
size_t len; size_t len;
if (result == NULL) if (NISOBJLEN (0, obj) >= room_left)
return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
|| __type_of(NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ
|| strcmp (NIS_RES_OBJECT (result)[entry].EN_data.en_type,
"group_tbl") != 0
|| NIS_RES_OBJECT (result)[entry].EN_data.en_cols.en_cols_len < 4)
return 0;
if (NISENTRYLEN (entry, 0, result) >= room_left)
{ {
/* The line is too long for our buffer. */ /* The line is too long for our buffer. */
no_more_room: no_more_room:
@ -181,9 +172,8 @@ _nss_nisplus_parse_grent (nis_result *result, u_long entry, struct group *gr,
return -1; return -1;
} }
strncpy (first_unused, NISENTRYVAL (entry, 0, result), strncpy (first_unused, NISOBJVAL (0, obj), NISOBJLEN (0, obj));
NISENTRYLEN (entry, 0, result)); first_unused[NISOBJLEN (0, obj)] = '\0';
first_unused[NISENTRYLEN (entry, 0, result)] = '\0';
len = strlen (first_unused); len = strlen (first_unused);
if (len == 0) /* group table is corrupt */ if (len == 0) /* group table is corrupt */
return 0; return 0;
@ -191,20 +181,19 @@ _nss_nisplus_parse_grent (nis_result *result, u_long entry, struct group *gr,
room_left -= len + 1; room_left -= len + 1;
first_unused += len + 1; first_unused += len + 1;
if (NISENTRYLEN (entry, 1, result) >= room_left) if (NISOBJLEN (1, obj) >= room_left)
goto no_more_room; goto no_more_room;
strncpy (first_unused, NISENTRYVAL (entry, 1, result), strncpy (first_unused, NISOBJVAL (1, obj), NISOBJLEN (1, obj));
NISENTRYLEN (entry, 1, result)); first_unused[NISOBJLEN (1, obj)] = '\0';
first_unused[NISENTRYLEN (entry, 1, result)] = '\0';
gr->gr_passwd = first_unused; gr->gr_passwd = first_unused;
len = strlen (first_unused); len = strlen (first_unused);
room_left -= len + 1; room_left -= len + 1;
first_unused += len + 1; first_unused += len + 1;
char *numstr = NISENTRYVAL (entry, 2, result); char *numstr = NISOBJVAL (2, obj);
len = NISENTRYLEN (entry, 2, result); len = NISOBJLEN (2, obj);
if (len == 0 && numstr[len - 1] != '\0') if (len == 0 || numstr[len - 1] != '\0')
{ {
if (len >= room_left) if (len >= room_left)
goto no_more_room; goto no_more_room;
@ -218,12 +207,11 @@ _nss_nisplus_parse_grent (nis_result *result, u_long entry, struct group *gr,
return 0; return 0;
gr->gr_gid = strtoul (numstr, NULL, 10); gr->gr_gid = strtoul (numstr, NULL, 10);
if (NISENTRYLEN (entry, 3, result) >= room_left) if (NISOBJLEN (3, obj) >= room_left)
goto no_more_room; goto no_more_room;
strncpy (first_unused, NISENTRYVAL (entry, 3, result), strncpy (first_unused, NISOBJVAL (3, obj), NISOBJLEN (3, obj));
NISENTRYLEN (entry, 3, result)); first_unused[NISOBJLEN (3, obj)] = '\0';
first_unused[NISENTRYLEN (entry, 3, result)] = '\0';
line = first_unused; line = first_unused;
len = strlen (line); len = strlen (line);
room_left -= len + 1; room_left -= len + 1;

View File

@ -29,16 +29,21 @@
#include "nss-nisplus.h" #include "nss-nisplus.h"
#include "nisplus-parser.h" #include "nisplus-parser.h"
#include <libnsl.h> #include <libnsl.h>
#include <nis_intern.h>
#include <nis_xdr.h>
__libc_lock_define_initialized (static, lock) __libc_lock_define_initialized (static, lock)
/* Previous result of iteration. */ /* Connection information. */
static nis_result *result; static ib_request *ibreq;
static directory_obj *dir;
static dir_binding bptr;
static char *tablepath;
static char *tableptr;
/* Cursor. */
static netobj cursor;
/* All results of batch table load. */
static nis_result *cached_results;
static size_t cached_results_iter;
nis_name pwd_tablename_val attribute_hidden; nis_name pwd_tablename_val attribute_hidden;
size_t pwd_tablename_len attribute_hidden; size_t pwd_tablename_len attribute_hidden;
@ -80,50 +85,48 @@ _nss_pwd_create_tablename (int *errnop)
static void static void
internal_nisplus_endpwent (void) internal_nisplus_endpwent (void)
{ {
if (cached_results != NULL) __nisbind_destroy (&bptr);
{ memset (&bptr, '\0', sizeof (bptr));
nis_freeresult (cached_results);
cached_results = NULL;
cached_results_iter = 0;
}
if (result != NULL) nis_free_directory (dir);
{ dir = NULL;
nis_freeresult (result);
result = NULL; nis_free_request (ibreq);
} ibreq = NULL;
xdr_free ((xdrproc_t) xdr_netobj, (char *) &cursor);
memset (&cursor, '\0', sizeof (cursor));
free (tablepath);
tableptr = tablepath = NULL;
} }
static enum nss_status static enum nss_status
internal_nisplus_setpwent (int *errnop) internal_nisplus_setpwent (int *errnop)
{ {
enum nss_status status; enum nss_status status = NSS_STATUS_SUCCESS;
cached_results = nis_list (pwd_tablename_val, FOLLOW_PATH | FOLLOW_LINKS, if (pwd_tablename_val == NULL)
NULL, NULL); status = _nss_pwd_create_tablename (errnop);
if (cached_results == NULL) if (status == NSS_STATUS_SUCCESS)
{ {
*errnop = errno; ibreq = __create_ib_request (pwd_tablename_val, 0);
status = NSS_STATUS_TRYAGAIN; if (ibreq == NULL)
} {
else if (__builtin_expect ((status = niserr2nss (cached_results->status)) *errnop = errno;
!= NSS_STATUS_SUCCESS, 0)) return NSS_STATUS_TRYAGAIN;
{ }
nis_freeresult (cached_results);
cached_results = NULL; nis_error retcode = __prepare_niscall (pwd_tablename_val, &dir,
} &bptr, 0);
else if (__builtin_expect (__type_of (NIS_RES_OBJECT (cached_results)) if (retcode != NIS_SUCCESS)
!= NIS_ENTRY_OBJ {
|| strcmp (NIS_RES_OBJECT (cached_results)->EN_data.en_type, nis_free_request (ibreq);
"passwd_tbl") != 0 ibreq = NULL;
|| NIS_RES_OBJECT (cached_results)->EN_data.en_cols.en_cols_len < 7, status = niserr2nss (retcode);
0)) }
{
nis_freeresult (cached_results);
cached_results = NULL;
status = NSS_STATUS_NOTFOUND;
} }
return status; return status;
@ -133,26 +136,15 @@ internal_nisplus_setpwent (int *errnop)
enum nss_status enum nss_status
_nss_nisplus_setpwent (int stayopen) _nss_nisplus_setpwent (int stayopen)
{ {
enum nss_status status = NSS_STATUS_SUCCESS; enum nss_status status;
__libc_lock_lock (lock); __libc_lock_lock (lock);
internal_nisplus_endpwent (); internal_nisplus_endpwent ();
if (pwd_tablename_val == NULL) // XXX We need to be able to set errno. Pass in new parameter.
{ int err;
// XXX We need to be able to set errno. Pass in new parameter. status = internal_nisplus_setpwent (&err);
int err;
status = _nss_pwd_create_tablename (&err);
}
if (status == NSS_STATUS_SUCCESS
&& (_nsl_default_nss () & NSS_FLAG_SETENT_BATCH_READ))
{
// XXX We need to be able to set errno. Pass in new parameter.
int err;
status = internal_nisplus_setpwent (&err);
}
__libc_lock_unlock (lock); __libc_lock_unlock (lock);
@ -178,98 +170,104 @@ internal_nisplus_getpwent_r (struct passwd *pw, char *buffer, size_t buflen,
int *errnop) int *errnop)
{ {
int parse_res = -1; int parse_res = -1;
nis_result *saved_res = NULL; enum nss_status retval = NSS_STATUS_SUCCESS;
/* Get the next entry until we found a correct one. */ /* Get the next entry until we found a correct one. */
do do
{ {
if (cached_results != NULL) nis_error status;
{ nis_result result;
handle_batch_read: memset (&result, '\0', sizeof (result));
/* See whether we reported the last problem. */
if (cached_results_iter >= NIS_RES_NUMOBJ (cached_results))
return NSS_STATUS_NOTFOUND;
parse_res = _nss_nisplus_parse_pwent (cached_results, if (cursor.n_bytes == NULL)
cached_results_iter, pw, {
buffer, buflen, errnop); if (ibreq == NULL)
{
retval = internal_nisplus_setpwent (errnop);
if (retval != NSS_STATUS_SUCCESS)
return retval;
}
status = __do_niscall3 (&bptr, NIS_IBFIRST,
(xdrproc_t) _xdr_ib_request,
(caddr_t) ibreq,
(xdrproc_t) _xdr_nis_result,
(caddr_t) &result,
0, NULL);
} }
else else
{ {
if (result == NULL) ibreq->ibr_cookie.n_bytes = cursor.n_bytes;
{ ibreq->ibr_cookie.n_len = cursor.n_len;
if (pwd_tablename_val == NULL)
{
enum nss_status status = _nss_pwd_create_tablename (errnop);
if (status != NSS_STATUS_SUCCESS) status = __do_niscall3 (&bptr, NIS_IBNEXT,
return status; (xdrproc_t) _xdr_ib_request,
} (caddr_t) ibreq,
(xdrproc_t) _xdr_nis_result,
(caddr_t) &result,
0, NULL);
/* Determine whether we should instead read all entries at ibreq->ibr_cookie.n_bytes = NULL;
once. */ ibreq->ibr_cookie.n_len = 0;
if (_nsl_default_nss () & NSS_FLAG_SETENT_BATCH_READ)
{
enum nss_status status = internal_nisplus_setpwent (errnop);
if (status == NSS_STATUS_SUCCESS && cached_results != NULL)
goto handle_batch_read;
}
saved_res = NULL;
result = nis_first_entry (pwd_tablename_val);
if (result == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
return niserr2nss (result->status);
}
else
{
saved_res = result;
result = nis_next_entry (pwd_tablename_val, &result->cookie);
if (result == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
nis_freeresult (saved_res);
return niserr2nss (result->status);
}
}
parse_res = _nss_nisplus_parse_pwent_chk (result, pw, buffer,
buflen, errnop);
} }
if (status != NIS_SUCCESS)
return niserr2nss (status);
if (NIS_RES_STATUS (&result) == NIS_NOTFOUND)
{
/* No more entries on this server. This means we have to go
to the next server on the path. */
status = __follow_path (&tablepath, &tableptr, ibreq, &bptr);
if (status != NIS_SUCCESS)
return niserr2nss (status);
directory_obj *newdir = NULL;
dir_binding newbptr;
status = __prepare_niscall (ibreq->ibr_name, &newdir, &newbptr, 0);
if (status != NIS_SUCCESS)
return niserr2nss (status);
nis_free_directory (dir);
dir = newdir;
__nisbind_destroy (&bptr);
bptr = newbptr;
xdr_free ((xdrproc_t) xdr_netobj, (char *) &result.cookie);
result.cookie.n_bytes = NULL;
result.cookie.n_len = 0;
parse_res = 0;
goto next;
}
else if (NIS_RES_STATUS (&result) != NIS_SUCCESS)
return niserr2nss (NIS_RES_STATUS (&result));
parse_res = _nss_nisplus_parse_pwent (&result, pw, buffer,
buflen, errnop);
if (__builtin_expect (parse_res == -1, 0)) if (__builtin_expect (parse_res == -1, 0))
{ {
if (cached_results == NULL)
{
nis_freeresult (result);
result = saved_res;
}
*errnop = ERANGE; *errnop = ERANGE;
return NSS_STATUS_TRYAGAIN; retval = NSS_STATUS_TRYAGAIN;
goto freeres;
} }
if (cached_results != NULL) next:
++cached_results_iter; /* Free the old cursor. */
else xdr_free ((xdrproc_t) xdr_netobj, (char *) &cursor);
if (saved_res) /* Remember the new one. */
{ cursor.n_bytes = result.cookie.n_bytes;
nis_freeresult (saved_res); cursor.n_len = result.cookie.n_len;
saved_res = NULL; /* Free the result structure. NB: we do not remove the cookie. */
} result.cookie.n_bytes = NULL;
result.cookie.n_len = 0;
freeres:
xdr_free ((xdrproc_t) _xdr_nis_result, (char *) &result);
memset (&result, '\0', sizeof (result));
} }
while (!parse_res); while (!parse_res);
return NSS_STATUS_SUCCESS; return retval;
} }
enum nss_status enum nss_status
@ -331,8 +329,7 @@ _nss_nisplus_getpwnam_r (const char *name, struct passwd *pw,
return status; return status;
} }
parse_res = _nss_nisplus_parse_pwent_chk (result, pw, buffer, buflen, parse_res = _nss_nisplus_parse_pwent (result, pw, buffer, buflen, errnop);
errnop);
nis_freeresult (result); nis_freeresult (result);
@ -391,8 +388,7 @@ _nss_nisplus_getpwuid_r (const uid_t uid, struct passwd *pw,
return status; return status;
} }
parse_res = _nss_nisplus_parse_pwent_chk (result, pw, buffer, buflen, parse_res = _nss_nisplus_parse_pwent (result, pw, buffer, buflen, errnop);
errnop);
nis_freeresult (result); nis_freeresult (result);

View File

@ -176,7 +176,7 @@ xdrrec_create (XDR *xdrs, u_int sendsize,
/* /*
* now the rest ... * now the rest ...
*/ */
/* We have to add the const since the `struct xdr_ops' in `struct XDR' /* We have to add the cast since the `struct xdr_ops' in `struct XDR'
is not `const'. */ is not `const'. */
xdrs->x_ops = (struct xdr_ops *) &xdrrec_ops; xdrs->x_ops = (struct xdr_ops *) &xdrrec_ops;
xdrs->x_private = (caddr_t) rstrm; xdrs->x_private = (caddr_t) rstrm;