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>.
This commit is contained in:
Ulrich Drepper 1997-07-11 01:19:07 +00:00
parent 9c2322bc08
commit 2d7da676f3
78 changed files with 2844 additions and 1891 deletions

144
ChangeLog
View File

@ -1,3 +1,147 @@
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>.
1997-07-08 02:18 Ulrich Drepper <drepper@cygnus.com>
* io/lockf.c (lockf): Clear fl before using.

View File

@ -372,10 +372,11 @@ else
default-rpath = $(libdir)
endif
# This is how to find at build-time things that will be installed there.
rpath-link = $(common-objdir):$(mathobjdir):$(elfobjdir):$(nssobjdir)
rpath-link = $(common-objdir):$(mathobjdir):$(elfobjdir):$(nssobjdir):$(dbobjdir)
mathobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)math)
elfobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)elf)
nssobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)nss)
dbobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)db)
else
link-libc = $(common-objpfx)libc.a $(gnulib) $(common-objpfx)libc.a
endif

View File

@ -57,6 +57,9 @@ inet_ntoa (struct in_addr in)
really went wrong. In any case use a static buffer
which is better than nothing. */
buffer = static_buf;
else
/* We have a key. */
initialized = 1;
}
__libc_lock_unlock (lock);

View File

@ -80,6 +80,7 @@ GLIBC_2.0 {
_IO_seekmark; _IO_unsave_markers; _IO_str_overflow;
_IO_str_underflow; _IO_str_init_static; _IO_str_init_readonly;
_IO_str_seekoff; _IO_str_pbackfail; _IO_list_all; _IO_file_jumps;
_IO_peekc_locked;
_rpc_dtablesize;
# all functions and variables in the normal name space

View File

@ -291,6 +291,15 @@ DEFUN(_IO_file_underflow, (fp),
_IO_switch_to_get_mode(fp);
/* This is very tricky. We have to adjust those
pointers before we call _IO_SYSREAD () since
we may longjump () out while waiting for
input. Those pointers may be screwed up. H.J. */
fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base;
fp->_IO_read_end = fp->_IO_buf_base;
fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
= fp->_IO_buf_base;
count = _IO_SYSREAD (fp, fp->_IO_buf_base,
fp->_IO_buf_end - fp->_IO_buf_base);
if (count <= 0)
@ -300,10 +309,7 @@ DEFUN(_IO_file_underflow, (fp),
else
fp->_flags |= _IO_ERR_SEEN, count = 0;
}
fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base;
fp->_IO_read_end = fp->_IO_buf_base + count;
fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
= fp->_IO_buf_base;
fp->_IO_read_end += count;
if (count == 0)
return EOF;
if (fp->_offset != _IO_pos_BAD)

View File

@ -1,5 +1,5 @@
%% TeX macros to handle Texinfo files.
%% $Id: texinfo.tex,v 2.207 1997/07/07 13:08:20 drepper Exp $
%% $Id: texinfo.tex,v 2.208 1997/07/11 01:01:45 drepper Exp $
% Copyright (C) 1985, 86, 88, 90, 91, 92, 93,
% 94, 95, 96, 97 Free Software Foundation, Inc.
@ -36,7 +36,7 @@
% This automatically updates the version number based on RCS.
\def\deftexinfoversion$#1: #2 ${\def\texinfoversion{#2}}
\deftexinfoversion$Revision: 2.207 $
\deftexinfoversion$Revision: 2.208 $
\message{Loading texinfo package [Version \texinfoversion]:}
% If in a .fmt file, print the version number
@ -101,6 +101,7 @@
\hyphenation{ap-pen-dix}
\hyphenation{mini-buf-fer mini-buf-fers}
\hyphenation{eshell}
\hyphenation{white-space}
% Margin to add to right of even pages, to left of odd pages.
\newdimen \bindingoffset
@ -1235,6 +1236,7 @@ where each line of input produces a line of output.}
\let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy
\let\tenttsl=\titlettsl
\resetmathfonts \setleading{25pt}}
\def\titlefont#1{{\titlefonts #1}}
\def\chapfonts{%
\let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
\let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
@ -3298,7 +3300,9 @@ width0pt\relax} \fi
\unnumbchapmacro{#1}\def\thischapter{}%
\begingroup % Set up to handle contents files properly.
\catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11
\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi
% We can't do this, because then an actual ^ in a section
% title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97.
%\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi
\raggedbottom % Worry more about breakpoints than the bottom.
\advance\hsize by -\contentsrightmargin % Don't use the full line length.
}

View File

@ -227,10 +227,10 @@ feenv_nomask_test (const char *flag_name, int fe_exc)
printf ("Test: after fesetenv (FE_NOMASK_ENV) processes will abort\n");
printf (" when feraiseexcept (%s) is called.\n", flag_name);
fesetenv (FE_NOMASK_ENV);
pid = fork ();
if (pid == 0)
{
fesetenv (FE_NOMASK_ENV);
feraiseexcept (fe_exc);
exit (2);
}
@ -270,10 +270,10 @@ feenv_mask_test (const char *flag_name, int fe_exc)
printf ("Test: after fesetenv (FE_DFL_ENV) processes will not abort\n");
printf (" when feraiseexcept (%s) is called.\n", flag_name);
fesetenv (FE_DFL_ENV);
pid = fork ();
if (pid == 0)
{
fesetenv (FE_DFL_ENV);
feraiseexcept (fe_exc);
exit (2);
}

View File

@ -1 +1 @@
NIS(YP)/NIS+ NSS modules 0.11 by Thorsten Kukuk
NIS(YP)/NIS+ NSS modules 0.12 by Thorsten Kukuk

View File

@ -17,12 +17,13 @@
# Boston, MA 02111-1307, USA.
#
# Makefile for NIS part.
# Makefile for NIS/NIS+ part.
#
subdir := nis
headers := $(wildcard rpcsvc/*.[hx])
distribute := nss-nis.h nss-nisplus.h nis_intern.h Banner
distribute := nss-nis.h nss-nisplus.h nis_intern.h Banner \
nisplus-parser.h
# These are the databases available for the nis (and perhaps later nisplus)
# service. This must be a superset of the services in nss.
@ -44,15 +45,15 @@ vpath %.c $(subdir-dirs)
libnsl-routines = yp_xdr ypclnt ypupdate_xdr \
nis_subr nis_local_names nis_free nis_file \
nis_print nis_error nis_call nis_lookup nis_clone\
nis_table nis_xdr nis_intern nis_server nis_ping\
nis_cache nis_table nis_xdr nis_server nis_ping\
nis_checkpoint nis_mkdir nis_rmdir nis_getservlist\
nis_verifygroup nis_ismember nis_addmember \
nis_verifygroup nis_ismember nis_addmember nis_util\
nis_removemember nis_creategroup nis_destroygroup\
nis_print_group_entry nis_domain_of nis_domain_of_r\
nis_modify nis_remove nis_add nis_defaults
nis_modify nis_remove nis_add nis_defaults lckcache
libnsl-map = libnsl.map
libnss_compat-routines := $(addprefix compat-,grp pwd spwd)
libnss_compat-routines := $(addprefix compat-,grp pwd spwd) nisplus-parser
libnss_compat-inhibit-o = $(filter-out .so,$(object-suffixes))
libnss_compat-map := libnss_compat.map
@ -60,16 +61,14 @@ libnss_nis-routines := $(addprefix nis-,$(databases))
libnss_nis-inhibit-o = $(filter-out .so,$(object-suffixes))
libnss_nis-map := libnss_nis.map
libnss_nisplus-routines := $(addprefix nisplus-,$(databases))
libnss_nisplus-routines := $(addprefix nisplus-,$(databases)) nisplus-parser
libnss_nisplus-inhibit-o = $(filter-out .so,$(object-suffixes))
libnss_nisplus-map := libnss_nisplus.map
include ../Rules
$(objpfx)libnss_compat.so: $(objpfx)libnsl.so$(libnsl.so-version) \
$(common-objpfx)nss/libnss_files.so \
$(common-objpfx)nis/libnss_nisplus.so
$(objpfx)libnss_compat.so: $(objpfx)libnsl.so$(libnsl.so-version)
$(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)

View File

@ -2,8 +2,6 @@
* nis_addmember: Where checks for duplicate group members ? nisgrpadm or
nis_addmember ?
* nss_nisplus: When using parser form nss_files, rewrite parser
* nis_table.c: nis_list():
Missing flags: FOLLOW_PATH, ALL_RESULTS
callback: Don't simulate it, use server callback thread

181
nis/lckcache.c Normal file
View File

@ -0,0 +1,181 @@
/* Handle locking of NIS+ cache file.
Copyright (C) 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library.
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 <fcntl.h>
#include <bits/libc-lock.h>
#include <shadow.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <sys/file.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
#include <rpcsvc/nis_cache.h>
/* How long to wait for getting the lock before returning with an
error. */
#define TIMEOUT 15 /* sec */
/* File descriptor for lock file. */
static int lock_fd = -1;
/* Prevent problems in multithreaded program by using mutex. */
__libc_lock_define_initialized (static, lock)
/* Prototypes for local functions. */
static void noop_handler __P ((int __sig));
/* We cannot simply return in error cases. We have to close the file
and perhaps restore the signal handler. */
#define RETURN_CLOSE_FD(code) \
do { \
if ((code) < 0 && lock_fd >= 0) \
{ \
close (lock_fd); \
lock_fd = -1; \
} \
__libc_lock_unlock (lock); \
return (code); \
} while (0)
#define RETURN_RESTORE_HANDLER(code) \
do { \
/* Restore old action handler for alarm. We don't need to know \
about the current one. */ \
sigaction (SIGALRM, &saved_act, NULL); \
RETURN_CLOSE_FD (code); \
} while (0)
#define RETURN_CLEAR_ALARM(code) \
do { \
/* Clear alarm. */ \
alarm (0); \
/* Restore old set of handled signals. We don't need to know \
about the current one.*/ \
sigprocmask (SIG_SETMASK, &saved_set, NULL); \
RETURN_RESTORE_HANDLER (code); \
} while (0)
int
__nis_lock_cache (void)
{
int flags;
sigset_t saved_set; /* Saved set of caught signals. */
struct sigaction saved_act; /* Saved signal action. */
sigset_t new_set; /* New set of caught signals. */
struct sigaction new_act; /* New signal action. */
struct flock fl; /* Information struct for locking. */
int result;
if (lock_fd != -1)
/* Still locked by own process. */
return -1;
/* Prevent problems caused by multiple threads. */
__libc_lock_lock (lock);
lock_fd = open (CACHELOCK, O_RDONLY|O_CREAT, 0666);
if (lock_fd == -1)
/* Cannot create lock file. */
RETURN_CLOSE_FD (-1);
/* Make sure file gets correctly closed when process finished. */
flags = fcntl (lock_fd, F_GETFD, 0);
if (flags == -1)
/* Cannot get file flags. */
RETURN_CLOSE_FD (-1);
flags |= FD_CLOEXEC; /* Close on exit. */
if (fcntl (lock_fd, F_SETFD, flags) < 0)
/* Cannot set new flags. */
RETURN_CLOSE_FD (-1);
/* Now we have to get exclusive write access. Since multiple
process could try this we won't stop when it first fails.
Instead we set a timeout for the system call. Once the timer
expires it is likely that there are some problems which cannot be
resolved by waiting.
It is important that we don't change the signal state. We must
restore the old signal behaviour. */
memset (&new_act, '\0', sizeof (struct sigaction));
new_act.sa_handler = noop_handler;
sigfillset (&new_act.sa_mask);
new_act.sa_flags = 0ul;
/* Install new action handler for alarm and save old. */
if (sigaction (SIGALRM, &new_act, &saved_act) < 0)
/* Cannot install signal handler. */
RETURN_CLOSE_FD (-1);
/* Now make sure the alarm signal is not blocked. */
sigemptyset (&new_set);
sigaddset (&new_set, SIGALRM);
if (sigprocmask (SIG_UNBLOCK, &new_set, &saved_set) < 0)
RETURN_RESTORE_HANDLER (-1);
/* Start timer. If we cannot get the lock in the specified time we
get a signal. */
alarm (TIMEOUT);
/* Try to get the lock. */
memset (&fl, '\0', sizeof (struct flock));
fl.l_type = F_RDLCK;
fl.l_whence = SEEK_SET;
result = fcntl (lock_fd, F_SETLK, &fl);
RETURN_CLEAR_ALARM (result);
}
int
__nis_unlock_cache ()
{
int result;
if (lock_fd == -1)
/* There is no lock set. */
result = -1;
else
{
/* Prevent problems caused by multiple threads. */
__libc_lock_lock (lock);
result = close (lock_fd);
/* Mark descriptor as unused. */
lock_fd = -1;
/* Clear mutex. */
__libc_lock_unlock (lock);
}
return result;
}
static void
noop_handler (sig)
int sig;
{
/* We simply return which makes the `fcntl' call return with an error. */
}

View File

@ -1,7 +1,10 @@
GLIBC_2.0 {
global:
__nis_default_access; __nis_default_group; __nis_default_owner;
__nis_default_ttl; __yp_check; nis_add;
__nis_default_ttl; __nis_finddirectory; __nis_lock_cache;
__nis_unlock_cache; __nis_hash;
nis_add;
nis_add_entry; nis_addmember; nis_checkpoint;
nis_clone_directory; nis_clone_entry; nis_clone_group;
nis_clone_link; nis_clone_nis_attr; nis_clone_objdata;
@ -51,6 +54,7 @@ GLIBC_2.0 {
xdr_ypresp_xfr; xdr_ypstat; xdr_ypupdate_args;
xdr_ypxfrstat; xdr_zotypes;
__yp_check;
yp_all; yp_bind; yp_first;
yp_get_default_domain; yp_maplist; yp_master;
yp_match; yp_next; yp_order;

44
nis/nis_cache.c Normal file
View File

@ -0,0 +1,44 @@
/* 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 <fcntl.h>
#include <unistd.h>
#include <syslog.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
#include <rpcsvc/nis_cache.h>
#include <bits/libc-lock.h>
#include "nis_intern.h"
/* XXX Only dummy functions in the moment. The real implementation
will follow, if we have a working nis_cachemgr */
directory_obj *
__cache_search (const_nis_name name)
{
return NULL;
}
nis_error
__cache_add (fd_result *fd)
{
return NIS_FAIL;
}

View File

@ -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 (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;
if (bind->use_auth)
auth_destroy (bind->clnt->cl_auth);
clnt_destroy (bind->clnt);
}
free (bind->server_val);
free (bind);
}
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);
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 (client == NULL)
continue;
if (clnt_call (client, 0, (xdrproc_t) xdr_void, NULL,
(xdrproc_t) xdr_void, NULL, TIMEOUT) != RPC_SUCCESS)
{
clnt_destroy (client);
continue;
}
if (bind->clnt != NULL)
{
if (bind->use_auth)
auth_destroy (bind->clnt->cl_auth);
clnt_destroy (bind->clnt);
bind->clnt = NULL;
}
return NIS_SUCCESS;
}
if ((flags & NO_AUTHINFO) != NO_AUTHINFO)
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 defined(HAVE_SECURE_RPC)
if (server->key_type == NIS_PK_DH && getenv ("NO_SECURE_RPC") == NULL)
if (dbp->use_udp)
{
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 (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
#endif
client->cl_auth = authunix_create_default ();
if (strcmp (serv->ep.ep_val[i].proto, "tcp") == 0)
dbp->addr.sin_addr.s_addr =
inetstr2int (serv->ep.ep_val[i].uaddr);
}
return client;
else
continue;
}
if (dbp->addr.sin_addr.s_addr == 0)
return NIS_FAIL;
return NULL;
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)
{
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;
}
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)
{
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)
{
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
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;
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;
enum clnt_stat result;
nis_error retcode;
dir_binding *dbp;
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)
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 */
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);
result = __do_niscall2 (server, server_len, prog, xargs, req, xres,
resp, flags);
if (dir != NULL)
nis_free_directory (dir);
return result;
return retcode;
}

View File

@ -1,145 +0,0 @@
/* 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 char *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;
}

View File

@ -24,17 +24,22 @@
__BEGIN_DECLS
extern nis_error __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);
extern 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);
extern nis_error __do_niscall2 __P ((const nis_server *serv, u_int serv_len,
u_long prog, xdrproc_t xargs, caddr_t req,
xdrproc_t xres, caddr_t resp,
u_long flags));
extern nis_error __do_niscall __P ((const_nis_name name, u_long prog,
xdrproc_t xargs, caddr_t req,
xdrproc_t xres, caddr_t resp,
u_long flags));
#if defined (HAVE_SECURE_RPC)
extern AUTH *authdes_pk_create (const char *, const netobj *, u_int,
struct sockaddr *, des_block *);
extern AUTH *authdes_pk_create __P ((const char *, const netobj *, u_int,
struct sockaddr *, des_block *));
#endif
extern nis_name *__nis_expandname (const char *);
/* NIS+ cache */
extern directory_obj *__cache_search __P ((const_nis_name name));
extern nis_error __cache_add __P ((fd_result *));
__END_DECLS

View File

@ -30,128 +30,94 @@ nis_lookup (const_nis_name name, const u_long flags)
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;
int done = 0;
int name_nr = 0;
nis_name namebuf[2] = {NULL, NULL};
res = calloc (1, sizeof (nis_result));
if (flags & EXPAND_NAME)
{
names = __nis_expandname (name);
names = nis_getnames (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 (req.ns_name, 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 = (char *)name;
names = namebuf;
names[0] = (nis_name) name;
}
while (is_link)
req.ns_name = names[0];
while (!done)
{
req.ns_object.ns_object_len = 0;
req.ns_object.ns_object_val = NULL;
memset (res, '\0', sizeof (nis_result));
status = __do_niscall (req.ns_name, NIS_LOOKUP,
(xdrproc_t) xdr_ns_request,
(caddr_t) & req,
(xdrproc_t) xdr_nis_result,
(caddr_t) res, flags);
if (status != NIS_SUCCESS)
res->status = status;
switch (res->status)
{
req.ns_object.ns_object_len = 0;
req.ns_object.ns_object_val = NULL;
memset (res, '\0', sizeof (nis_result));
if ((status = __do_niscall (req.ns_name, NIS_LOOKUP,
(xdrproc_t) xdr_ns_request,
(caddr_t) &req,
(xdrproc_t) xdr_nis_result,
(caddr_t) res, flags)) != RPC_SUCCESS)
case NIS_PARTIAL:
case NIS_SUCCESS:
case NIS_S_SUCCESS:
if (__type_of(NIS_RES_OBJECT (res)) == LINK_OBJ &&
flags & FOLLOW_LINKS) /* We are following links */
{
res->status = status;
return res;
/* if we hit the link limit, bail */
if (count_links > NIS_MAXLINKS)
{
res->status = NIS_LINKNAMEERROR;
++done;
break;
}
if (count_links)
free (req.ns_name);
++count_links;
req.ns_name = strdup (NIS_RES_OBJECT (res)->LI_data.li_name);
nis_freeresult (res);
res = calloc (1, sizeof (nis_result));
}
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)
++done;
break;
case NIS_CBRESULTS:
/* XXX Implement CALLBACK here ! */
++done;
break;
default:
/* Try the next domainname if we don't follow a link */
if (count_links)
{
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;
}
free (req.ns_name);
res->status = NIS_LINKNAMEERROR;
++done;
break;
}
++name_nr;
if (names[name_nr] == NULL)
{
++done;
break;
}
req.ns_name = names[name_nr];
break;
}
}
if (names != namebuf)
nis_freenames (names);
return res;
}

View File

@ -77,6 +77,41 @@ nis_flags2str (const u_long flags)
return buf;
}
static void
nis_print_objtype (enum zotypes type)
{
switch (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);
break;
case GROUP_OBJ:
fputs (_("GROUP\n"), stdout);
break;
case TABLE_OBJ:
fputs (_("TABLE\n"), stdout);
break;
case ENTRY_OBJ:
fputs (_("ENTRY\n"), stdout);
break;
case LINK_OBJ:
fputs (_("LINK\n"), stdout);
break;
case PRIVATE_OBJ:
fputs (_("PRIVATE\n"), stdout);
break;
default:
fputs (_("(Unknown object)\n"), stdout);
break;
}
}
void
nis_print_rights (const u_long access)
{
@ -218,9 +253,10 @@ nis_print_table (const table_obj *obj)
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);
fputs (_("Linked Object Type : "), stdout);
nis_print_objtype (obj->li_rtype);
printf (_("Linked to : %s\n"), obj->li_name);
/* XXX Print the attributs here, if they exists */
}
void
@ -255,41 +291,29 @@ nis_print_object (const nis_object * obj)
printf (_("Creation Time : %s"), ctime (&obj->zo_oid.ctime));
printf (_("Mod. Time : %s"), ctime (&obj->zo_oid.mtime));
fputs (_("Object Type : "), stdout);
nis_print_objtype (obj->zo_data.zo_type);
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;
}
}

View File

@ -116,8 +116,7 @@ nis_getnames (const_nis_name name)
nis_name *getnames = NULL;
char local_domain[NIS_MAXNAMELEN + 1];
char *path, *cp;
int count, pos;
int count, pos, have_point;
strncpy (local_domain, nis_local_directory (), NIS_MAXNAMELEN);
local_domain[NIS_MAXNAMELEN] = '\0';
@ -146,6 +145,8 @@ nis_getnames (const_nis_name name)
else
path = strdupa (path);
have_point = (strchr (name, '.') != NULL);
pos = 0;
cp = strtok (path, ":");
@ -156,7 +157,7 @@ nis_getnames (const_nis_name name)
char *cptr = local_domain;
char *tmp;
while (count_dots (cptr) >= 2)
while ((have_point && *cptr != '\0') || (count_dots (cptr) >= 2))
{
if (pos >= count)
{
@ -171,13 +172,18 @@ nis_getnames (const_nis_name name)
getnames[pos] = tmp;
tmp = stpcpy (tmp, name);
*tmp++ = '.';
stpcpy (tmp, cptr);
if (cptr[1] != '\0')
stpcpy (tmp, cptr);
else
++cptr;
++pos;
while (*cptr != '.')
while (*cptr != '.' && *cptr != '\0')
++cptr;
if (cptr[0] != '\0' && cptr[1] != '\0')
/* If we have only ".", don't remove the "." */
++cptr;
++cptr;
}
}
else
@ -186,31 +192,35 @@ nis_getnames (const_nis_name name)
if (cp[strlen (cp) - 1] == '$')
{
char *p;
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);
p = stpcpy (tmp, name);
*p++ = '.';
p = stpcpy (p, cp);
--p;
if (p[-1] != '.')
*p++ = '.';
stpcpy (p, local_domain);
}
else
{
char *p;
tmp = malloc (strlen (cp) + strlen (name) + 2);
if (tmp == NULL)
return NULL;
tmp = stpcpy (tmp, name);
*tmp++ = '.';
stpcpy (tmp, cp);
p = stpcpy (tmp, name);
*p++ = '.';
stpcpy (p, cp);
}
if (pos > count)
if (pos >= count)
{
count += 5;
getnames = realloc (getnames, (count + 1) * sizeof (char *));

View File

@ -145,18 +145,6 @@ __create_ib_request (const_nis_name name, struct ib_request *ibreq,
&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 |
@ -181,9 +169,12 @@ nis_list (const_nis_name name, u_long flags,
{
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 */
int status;
int count_links = 0; /* We will only follow 16 links! */
int done = 0;
nis_name *names;
nis_name namebuf[2] = {NULL, NULL};
int name_nr = 0;
res = calloc (1, sizeof (nis_result));
@ -193,56 +184,95 @@ nis_list (const_nis_name name, u_long flags,
return res;
}
while (is_link)
if (flags & EXPAND_NAME)
{
names = nis_getnames (ibreq.ibr_name);
free (ibreq.ibr_name);
ibreq.ibr_name = NULL;
if (names == NULL)
{
res->status = NIS_BADNAME;
return res;
}
ibreq.ibr_name = strdup (names[name_nr]);
}
else
names = namebuf;
while (!done)
{
memset (res, '\0', sizeof (nis_result));
if ((result = __do_niscall (ibreq.ibr_name, NIS_IBLIST,
(xdrproc_t) xdr_ib_request,
(caddr_t) &ibreq, (xdrproc_t) xdr_nis_result,
(caddr_t) res, flags)) != RPC_SUCCESS)
status = __do_niscall (ibreq.ibr_name, NIS_IBLIST,
(xdrproc_t) xdr_ib_request,
(caddr_t) &ibreq, (xdrproc_t) xdr_nis_result,
(caddr_t) res, flags);
if (status != NIS_SUCCESS)
res->status = status;
switch (res->status)
{
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)
case NIS_PARTIAL:
case NIS_SUCCESS:
case NIS_S_SUCCESS:
if (__type_of(NIS_RES_OBJECT (res)) == LINK_OBJ &&
flags & FOLLOW_LINKS) /* We are following links */
{
if (count_links == 16)
/* if we hit the link limit, bail */
if (count_links > NIS_MAXLINKS)
{
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;
++done;
break;
}
if (count_links)
free (ibreq.ibr_name);
++count_links;
free (ibreq.ibr_name);
ibreq.ibr_name = strdup (NIS_RES_OBJECT (res)->LI_data.li_name);
if (NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_len)
if (ibreq.ibr_srch.ibr_srch_len == 0)
{
ibreq.ibr_srch.ibr_srch_len =
NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_len;
ibreq.ibr_srch.ibr_srch_val =
NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_val;
}
nis_freeresult (res);
res = calloc (1, sizeof (nis_result));
}
else
++done;
break;
case NIS_CBRESULTS:
/* XXX Implement CALLBACK here ! */
++done;
break;
default:
/* Try the next domainname if we don't follow a link */
if (count_links)
{
res->status = NIS_NOTSEARCHABLE;
return res;
free (ibreq.ibr_name);
res->status = NIS_LINKNAMEERROR;
++done;
break;
}
++name_nr;
if (names[name_nr] == NULL)
{
++done;
break;
}
ibreq.ibr_name = names[name_nr];
break;
}
}
if (names != namebuf)
nis_freenames (names);
nis_free_request (&ibreq);
if (callback != NULL &&
(res->status == NIS_SUCCESS || res->status == NIS_S_SUCCESS))
{
@ -279,34 +309,34 @@ nis_add_entry (const_nis_name name, const nis_object *obj,
ibreq.ibr_obj.ibr_obj_val = nis_clone_object (obj, NULL);
ibreq.ibr_obj.ibr_obj_len = 1;
p1 = ibreq.ibr_obj.ibr_obj_val[0].zo_name;
p1 = ibreq.ibr_obj.ibr_obj_val->zo_name;
if (p1 == NULL || strlen (p1) == 0)
ibreq.ibr_obj.ibr_obj_val[0].zo_name =
ibreq.ibr_obj.ibr_obj_val->zo_name =
nis_leaf_of_r (name, buf1, sizeof (buf1));
p2 = ibreq.ibr_obj.ibr_obj_val[0].zo_owner;
p2 = ibreq.ibr_obj.ibr_obj_val->zo_owner;
if (p2 == NULL || strlen (p2) == 0)
ibreq.ibr_obj.ibr_obj_val[0].zo_owner = nis_local_principal ();
ibreq.ibr_obj.ibr_obj_val->zo_owner = nis_local_principal ();
p3 = ibreq.ibr_obj.ibr_obj_val[0].zo_group;
p3 = ibreq.ibr_obj.ibr_obj_val->zo_group;
if (p3 == NULL || strlen (p3) == 0)
ibreq.ibr_obj.ibr_obj_val[0].zo_group = nis_local_group ();
ibreq.ibr_obj.ibr_obj_val->zo_group = nis_local_group ();
p4 = ibreq.ibr_obj.ibr_obj_val[0].zo_domain;
ibreq.ibr_obj.ibr_obj_val[0].zo_domain =
p4 = ibreq.ibr_obj.ibr_obj_val->zo_domain;
ibreq.ibr_obj.ibr_obj_val->zo_domain =
nis_domain_of_r (name, buf4, sizeof (buf4));
if ((status = __do_niscall (ibreq.ibr_name, NIS_IBADD,
(xdrproc_t) xdr_ib_request,
(caddr_t) &ibreq,
(xdrproc_t) xdr_nis_result,
(caddr_t) res, 0)) != RPC_SUCCESS)
(caddr_t) res, 0)) != NIS_SUCCESS)
res->status = status;
ibreq.ibr_obj.ibr_obj_val[0].zo_name = p1;
ibreq.ibr_obj.ibr_obj_val[0].zo_owner = p2;
ibreq.ibr_obj.ibr_obj_val[0].zo_group = p3;
ibreq.ibr_obj.ibr_obj_val[0].zo_domain = p4;
ibreq.ibr_obj.ibr_obj_val->zo_name = p1;
ibreq.ibr_obj.ibr_obj_val->zo_owner = p2;
ibreq.ibr_obj.ibr_obj_val->zo_group = p3;
ibreq.ibr_obj.ibr_obj_val->zo_domain = p4;
nis_free_request (&ibreq);
@ -336,33 +366,33 @@ nis_modify_entry (const_nis_name name, const nis_object *obj,
ibreq.ibr_obj.ibr_obj_val = nis_clone_object (obj, NULL);
ibreq.ibr_obj.ibr_obj_len = 1;
p1 = ibreq.ibr_obj.ibr_obj_val[0].zo_name;
p1 = ibreq.ibr_obj.ibr_obj_val->zo_name;
if (p1 == NULL || strlen (p1) == 0)
ibreq.ibr_obj.ibr_obj_val[0].zo_name =
ibreq.ibr_obj.ibr_obj_val->zo_name =
nis_leaf_of_r (name, buf1, sizeof (buf1));
p2 = ibreq.ibr_obj.ibr_obj_val[0].zo_owner;
p2 = ibreq.ibr_obj.ibr_obj_val->zo_owner;
if (p2 == NULL || strlen (p2) == 0)
ibreq.ibr_obj.ibr_obj_val[0].zo_owner = nis_local_principal ();
ibreq.ibr_obj.ibr_obj_val->zo_owner = nis_local_principal ();
p3 = ibreq.ibr_obj.ibr_obj_val[0].zo_group;
p3 = ibreq.ibr_obj.ibr_obj_val->zo_group;
if (p3 == NULL || strlen (p3) == 0)
ibreq.ibr_obj.ibr_obj_val[0].zo_group = nis_local_group ();
ibreq.ibr_obj.ibr_obj_val->zo_group = nis_local_group ();
p4 = ibreq.ibr_obj.ibr_obj_val[0].zo_domain;
ibreq.ibr_obj.ibr_obj_val[0].zo_domain =
p4 = ibreq.ibr_obj.ibr_obj_val->zo_domain;
ibreq.ibr_obj.ibr_obj_val->zo_domain =
nis_domain_of_r (name, buf4, sizeof (buf4));
if ((status = __do_niscall (ibreq.ibr_name, NIS_IBMODIFY,
(xdrproc_t) xdr_ib_request,
(caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
(caddr_t) res, 0)) != RPC_SUCCESS)
(caddr_t) res, 0)) != NIS_SUCCESS)
res->status = status;
ibreq.ibr_obj.ibr_obj_val[0].zo_name = p1;
ibreq.ibr_obj.ibr_obj_val[0].zo_owner = p2;
ibreq.ibr_obj.ibr_obj_val[0].zo_group = p3;
ibreq.ibr_obj.ibr_obj_val[0].zo_domain = p4;
ibreq.ibr_obj.ibr_obj_val->zo_name = p1;
ibreq.ibr_obj.ibr_obj_val->zo_owner = p2;
ibreq.ibr_obj.ibr_obj_val->zo_group = p3;
ibreq.ibr_obj.ibr_obj_val->zo_domain = p4;
nis_free_request (&ibreq);
@ -395,7 +425,7 @@ nis_remove_entry (const_nis_name name, const nis_object *obj,
if ((status = __do_niscall (ibreq.ibr_name, NIS_IBREMOVE,
(xdrproc_t) xdr_ib_request,
(caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
(caddr_t) res, 0)) != RPC_SUCCESS)
(caddr_t) res, 0)) != NIS_SUCCESS)
res->status = status;
nis_free_request (&ibreq);
@ -421,7 +451,7 @@ nis_first_entry (const_nis_name name)
if ((status = __do_niscall (ibreq.ibr_name, NIS_IBFIRST,
(xdrproc_t) xdr_ib_request,
(caddr_t) &ibreq, (xdrproc_t) xdr_nis_result,
(caddr_t) res, 0)) != RPC_SUCCESS)
(caddr_t) res, 0)) != NIS_SUCCESS)
res->status = status;
nis_free_request (&ibreq);
@ -460,7 +490,7 @@ nis_next_entry (const_nis_name name, const netobj *cookie)
if ((status = __do_niscall (ibreq.ibr_name, NIS_IBNEXT,
(xdrproc_t) xdr_ib_request,
(caddr_t) &ibreq, (xdrproc_t) xdr_nis_result,
(caddr_t) res, 0)) != RPC_SUCCESS)
(caddr_t) res, 0)) != NIS_SUCCESS)
res->status = status;
nis_free_request (&ibreq);

99
nis/nis_util.c Normal file
View File

@ -0,0 +1,99 @@
/* 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 "nis_intern.h"
fd_result *
__nis_finddirectory (directory_obj *dir, const_nis_name name)
{
fd_args fd_args;
fd_result *fd_res;
fd_args.dir_name = strdup (name);
fd_args.requester = nis_local_host();
fd_res = calloc (1, sizeof (fd_result));
if (__do_niscall2 (dir->do_servers.do_servers_val,
dir->do_servers.do_servers_len, NIS_FINDDIRECTORY,
(xdrproc_t) xdr_fd_args,
(caddr_t) &fd_args, (xdrproc_t) xdr_fd_result,
(caddr_t) fd_res, NO_AUTHINFO|USE_DGRAM) != NIS_SUCCESS)
fd_res->status = NIS_RPCERROR;
return fd_res;
}
/* This is from libc/db/hash/hash_func.c, hash3 is static there */
/*
* This is INCREDIBLY ugly, but fast. We break the string up into 8 byte
* units. On the first time through the loop we get the "leftover bytes"
* (strlen % 8). On every other iteration, we perform 8 HASHC's so we handle
* all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. If
* this routine is heavily used enough, it's worth the ugly coding.
*
* OZ's original sdbm hash
*/
unsigned long
__nis_hash (const void *keyarg, register size_t len)
{
register const u_char *key;
register size_t loop;
register u_int32_t h;
#define HASHC h = *key++ + 65599 * h
h = 0;
key = keyarg;
if (len > 0)
{
loop = (len + 8 - 1) >> 3;
switch (len & (8 - 1))
{
case 0:
do {
HASHC;
/* FALLTHROUGH */
case 7:
HASHC;
/* FALLTHROUGH */
case 6:
HASHC;
/* FALLTHROUGH */
case 5:
HASHC;
/* FALLTHROUGH */
case 4:
HASHC;
/* FALLTHROUGH */
case 3:
HASHC;
/* FALLTHROUGH */
case 2:
HASHC;
/* FALLTHROUGH */
case 1:
HASHC;
} while (--loop);
}
}
return (h);
}

34
nis/nisplus-parser.h Normal file
View File

@ -0,0 +1,34 @@
/* 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 __NISPLUS_PARSER_H_
#define __NISPLUS_PARSER_H_ 1
#include <pwd.h>
#include <grp.h>
#include <shadow.h>
extern int _nss_nisplus_parse_pwent (nis_result *, struct passwd *,
char *, size_t);
extern int _nss_nisplus_parse_grent (nis_result *, u_long, struct group *,
char *, size_t);
extern int _nss_nisplus_parse_spent (nis_result *, struct spwd *,
char *, size_t);
#endif

View File

@ -30,9 +30,12 @@
#include <nsswitch.h>
#include "nss-nisplus.h"
#include "nisplus-parser.h"
static service_user *ni = NULL;
static bool_t use_nisplus = FALSE; /* default: group_compat: nis */
static nis_name grptable = NULL; /* Name of the group table */
static size_t grptablelen = 0;
/* Get the declaration of the parser function. */
#define ENTNAME grent
@ -57,14 +60,12 @@ struct ent_t
char *oldkey;
int oldkeylen;
nis_result *result;
nis_name *names;
u_long names_nr;
FILE *stream;
struct blacklist_t blacklist;
};
typedef struct ent_t ent_t;
static ent_t ext_ent = {0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0}};
static ent_t ext_ent = {0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0}};
/* Protect global state against multiple changers. */
__libc_lock_define_initialized (static, lock)
@ -72,8 +73,31 @@ __libc_lock_define_initialized (static, lock)
/* Prototypes for local functions. */
static void blacklist_store_name (const char *, ent_t *);
static int in_blacklist (const char *, int, ent_t *);
extern int _nss_nisplus_parse_grent (nis_result *, struct group *,
char *, size_t);
static enum nss_status
_nss_first_init (void)
{
if (ni == NULL)
{
__nss_database_lookup ("group_compat", NULL, "nis", &ni);
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
}
if (grptable == NULL)
{
char buf [20 + strlen (nis_local_directory ())];
char *p;
p = stpcpy (buf, "group.org_dir.");
p = stpcpy (p, nis_local_directory ());
grptable = strdup (buf);
if (grptable == NULL)
return NSS_STATUS_TRYAGAIN;
grptablelen = strlen (grptable);
}
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_setgrent (ent_t *ent)
@ -82,6 +106,9 @@ internal_setgrent (ent_t *ent)
ent->nis = ent->nis_first = 0;
if (_nss_first_init () != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
if (ent->oldkey != NULL)
{
free (ent->oldkey);
@ -95,12 +122,6 @@ internal_setgrent (ent_t *ent)
ent->result = NULL;
}
if (ent->names != NULL)
{
nis_freenames (ent->names);
ent->names = NULL;
}
ent->names_nr = 0;
ent->blacklist.current = 0;
if (ent->blacklist.data != NULL)
ent->blacklist.data[0] = '\0';
@ -126,12 +147,6 @@ _nss_compat_setgrent (void)
__libc_lock_lock (lock);
if (ni == NULL)
{
__nss_database_lookup ("group_compat", NULL, "nis", &ni);
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
}
result = internal_setgrent (&ext_ent);
__libc_lock_unlock (lock);
@ -164,12 +179,6 @@ internal_endgrent (ent_t *ent)
ent->result = NULL;
}
if (ent->names != NULL)
{
nis_freenames (ent->names);
ent->names = NULL;
}
ent->names_nr = 0;
ent->blacklist.current = 0;
if (ent->blacklist.data != NULL)
ent->blacklist.data[0] = '\0';
@ -263,22 +272,11 @@ getgrent_next_nisplus (struct group *result, ent_t *ent, char *buffer,
{
int parse_res;
if (ent->names == NULL)
{
ent->names = nis_getnames ("group.org_dir");
if (ent->names == NULL || ent->names[0] == NULL)
{
ent->nis = 0;
return NSS_STATUS_UNAVAIL;
}
}
do
{
if (ent->nis_first)
{
next_name:
ent->result = nis_first_entry(ent->names[ent->names_nr]);
ent->result = nis_first_entry(grptable);
if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
{
ent->nis = 0;
@ -290,27 +288,16 @@ getgrent_next_nisplus (struct group *result, ent_t *ent, char *buffer,
{
nis_result *res;
res = nis_next_entry(ent->names[ent->names_nr],
&ent->result->cookie);
res = nis_next_entry(grptable, &ent->result->cookie);
nis_freeresult (ent->result);
ent->result = res;
if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
{
if ((ent->result->status == NIS_NOTFOUND) &&
ent->names[ent->names_nr + 1] != NULL)
{
nis_freeresult (ent->result);
ent->names_nr += 1;
goto next_name;
}
else
{
ent->nis = 0;
return niserr2nss (ent->result->status);
}
ent->nis = 0;
return niserr2nss (ent->result->status);
}
}
parse_res = _nss_nisplus_parse_grent (ent->result, result, buffer,
parse_res = _nss_nisplus_parse_grent (ent->result, 0, result, buffer,
buflen);
if (parse_res &&
in_blacklist (result->gr_name, strlen (result->gr_name), ent))
@ -332,11 +319,10 @@ getgrent_next_file_plusgroup (struct group *result, char *buffer,
if (use_nisplus) /* Do the NIS+ query here */
{
nis_result *res;
char buf[strlen (result->gr_name) + 24];
char buf[strlen (result->gr_name) + 24 + grptablelen];
sprintf(buf, "[name=%s],group.org_dir",
&result->gr_name[1]);
res = nis_list(buf, EXPAND_NAME, NULL, NULL);
sprintf(buf, "[name=%s],%s", &result->gr_name[1], grptable);
res = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
if (niserr2nss (res->status) != NSS_STATUS_SUCCESS)
{
enum nss_status status = niserr2nss (res->status);
@ -344,7 +330,7 @@ getgrent_next_file_plusgroup (struct group *result, char *buffer,
nis_freeresult (res);
return status;
}
parse_res = _nss_nisplus_parse_grent (res, result, buffer, buflen);
parse_res = _nss_nisplus_parse_grent (res, 0, result, buffer, buflen);
nis_freeresult (res);
}
else /* Use NIS */
@ -470,12 +456,6 @@ _nss_compat_getgrent_r (struct group *grp, char *buffer, size_t buflen)
__libc_lock_lock (lock);
if (ni == NULL)
{
__nss_database_lookup ("group_compat", NULL, "nis", &ni);
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
}
/* Be prepared that the setgrent function was not called before. */
if (ext_ent.stream == NULL)
status = internal_setgrent (&ext_ent);
@ -493,7 +473,7 @@ enum nss_status
_nss_compat_getgrnam_r (const char *name, struct group *grp,
char *buffer, size_t buflen)
{
ent_t ent = {0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0}};
ent_t ent = {0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0}};
enum nss_status status;
if (name[0] == '-' || name[0] == '+')
@ -501,15 +481,10 @@ _nss_compat_getgrnam_r (const char *name, struct group *grp,
__libc_lock_lock (lock);
if (ni == NULL)
{
__nss_database_lookup ("group_compat", NULL, "nis", &ni);
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
}
status = internal_setgrent (&ent);
__libc_lock_unlock (lock);
status = internal_setgrent (&ent);
if (status != NSS_STATUS_SUCCESS)
return status;
@ -527,20 +502,15 @@ enum nss_status
_nss_compat_getgrgid_r (gid_t gid, struct group *grp,
char *buffer, size_t buflen)
{
ent_t ent = {0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0}};
ent_t ent = {0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0}};
enum nss_status status;
__libc_lock_lock (lock);
if (ni == NULL)
{
__nss_database_lookup ("group_compat", NULL, "nis", &ni);
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
}
status = internal_setgrent (&ent);
__libc_lock_unlock (lock);
status = internal_setgrent (&ent);
if (status != NSS_STATUS_SUCCESS)
return status;

View File

@ -32,9 +32,12 @@
#include "netgroup.h"
#include "nss-nisplus.h"
#include "nisplus-parser.h"
static service_user *ni = NULL;
static bool_t use_nisplus = FALSE; /* default: passwd_compat: nis */
static nis_name pwdtable = NULL; /* Name of the pwd table */
static size_t pwdtablelen = 0;
/* Get the declaration of the parser function. */
#define ENTNAME pwent
@ -60,8 +63,6 @@ struct ent_t
char *oldkey;
int oldkeylen;
nis_result *result;
nis_name *names;
u_long names_nr;
FILE *stream;
struct blacklist_t blacklist;
struct passwd pwd;
@ -69,7 +70,7 @@ struct ent_t
};
typedef struct ent_t ent_t;
static ent_t ext_ent = {0, 0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0},
static ent_t ext_ent = {0, 0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0},
{NULL, NULL, 0, 0, NULL, NULL, NULL}};
/* Protect global state against multiple changers. */
@ -78,8 +79,7 @@ __libc_lock_define_initialized (static, lock)
/* Prototypes for local functions. */
static void blacklist_store_name (const char *, ent_t *);
static int in_blacklist (const char *, int, ent_t *);
extern int _nss_nisplus_parse_pwent (nis_result *, struct passwd *,
char *, size_t);
static void
give_pwd_free (struct passwd *pwd)
{
@ -209,12 +209,19 @@ internal_setpwent (ent_t *ent)
ent->result = NULL;
}
if (ent->names != NULL)
if (pwdtable == NULL)
{
nis_freenames (ent->names);
ent->names = NULL;
char buf [20 + strlen (nis_local_directory ())];
char *p;
p = stpcpy (buf, "passwd.org_dir.");
p = stpcpy (p, nis_local_directory ());
pwdtable = strdup (buf);
if (pwdtable == NULL)
return NSS_STATUS_TRYAGAIN;
pwdtablelen = strlen (pwdtable);
}
ent->names_nr = 0;
ent->blacklist.current = 0;
if (ent->blacklist.data != NULL)
ent->blacklist.data[0] = '\0';
@ -280,13 +287,6 @@ internal_endpwent (ent_t *ent)
ent->result = NULL;
}
if (ent->names != NULL)
{
nis_freenames (ent->names);
ent->names = NULL;
}
ent->names_nr = 0;
ent->blacklist.current = 0;
if (ent->blacklist.data != NULL)
ent->blacklist.data[0] = '\0';
@ -435,9 +435,9 @@ getpwent_next_nisplus_netgr (struct passwd *result, ent_t *ent, char *group,
p2 = buffer + (buflen - p2len);
buflen -= p2len;
{
char buf[strlen (user) + 30];
sprintf(buf, "[name=%s],passwd.org_dir", user);
nisres = nis_list(buf, EXPAND_NAME, NULL, NULL);
char buf[strlen (user) + 30 + pwdtablelen];
sprintf(buf, "[name=%s],%s", user, pwdtable);
nisres = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
}
if (niserr2nss (nisres->status) != NSS_STATUS_SUCCESS)
{
@ -475,16 +475,6 @@ getpwent_next_nisplus (struct passwd *result, ent_t *ent, char *buffer,
size_t p2len;
char *p2;
if (ent->names == NULL)
{
ent->names = nis_getnames ("passwd.org_dir");
if (ent->names == NULL || ent->names[0] == NULL)
{
ent->nis = 0;
return NSS_STATUS_UNAVAIL;
}
}
p2len = pwd_need_buflen (&ent->pwd);
if (p2len > buflen)
{
@ -497,8 +487,7 @@ getpwent_next_nisplus (struct passwd *result, ent_t *ent, char *buffer,
{
if (ent->first)
{
next_name:
ent->result = nis_first_entry(ent->names[ent->names_nr]);
ent->result = nis_first_entry(pwdtable);
if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
{
ent->nis = 0;
@ -511,25 +500,14 @@ getpwent_next_nisplus (struct passwd *result, ent_t *ent, char *buffer,
{
nis_result *res;
res = nis_next_entry(ent->names[ent->names_nr],
&ent->result->cookie);
res = nis_next_entry(pwdtable, &ent->result->cookie);
nis_freeresult (ent->result);
ent->result = res;
if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
{
if ((ent->result->status == NIS_NOTFOUND) &&
ent->names[ent->names_nr + 1] != NULL)
{
nis_freeresult (ent->result);
ent->names_nr += 1;
goto next_name;
}
else
{
ent->nis = 0;
give_pwd_free (&ent->pwd);
return niserr2nss (ent->result->status);
}
ent->nis = 0;
give_pwd_free (&ent->pwd);
return niserr2nss (ent->result->status);
}
}
parse_res = _nss_nisplus_parse_pwent (ent->result, result, buffer,
@ -648,11 +626,10 @@ getpwent_next_file_plususer (struct passwd *result, char *buffer,
if (use_nisplus) /* Do the NIS+ query here */
{
nis_result *res;
char buf[strlen (result->pw_name) + 24];
char buf[strlen (result->pw_name) + 24 + pwdtablelen];
sprintf(buf, "[name=%s],passwd.org_dir",
&result->pw_name[1]);
res = nis_list(buf, EXPAND_NAME, NULL, NULL);
sprintf(buf, "[name=%s],%s", &result->pw_name[1], pwdtable);
res = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
if (niserr2nss (res->status) != NSS_STATUS_SUCCESS)
{
enum nss_status status = niserr2nss (res->status);
@ -869,7 +846,7 @@ enum nss_status
_nss_compat_getpwnam_r (const char *name, struct passwd *pwd,
char *buffer, size_t buflen)
{
ent_t ent = {0, 0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0},
ent_t ent = {0, 0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0},
{NULL, NULL, 0, 0, NULL, NULL, NULL}};
enum nss_status status;
@ -904,7 +881,7 @@ enum nss_status
_nss_compat_getpwuid_r (uid_t uid, struct passwd *pwd,
char *buffer, size_t buflen)
{
ent_t ent = {0, 0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0},
ent_t ent = {0, 0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0},
{NULL, NULL, 0, 0, NULL, NULL, NULL}};
enum nss_status status;

View File

@ -32,9 +32,12 @@
#include "netgroup.h"
#include "nss-nisplus.h"
#include "nisplus-parser.h"
static service_user *ni = NULL;
static bool_t use_nisplus = FALSE; /* default: passwd_compat: nis */
static nis_name pwdtable = NULL; /* Name of the password table */
static size_t pwdtablelen = 0;
/* Get the declaration of the parser function. */
#define ENTNAME spent
@ -60,8 +63,6 @@ struct ent_t
char *oldkey;
int oldkeylen;
nis_result *result;
nis_name *names;
u_long names_nr;
FILE *stream;
struct blacklist_t blacklist;
struct spwd pwd;
@ -69,7 +70,7 @@ struct ent_t
};
typedef struct ent_t ent_t;
static ent_t ext_ent = {0, 0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0},
static ent_t ext_ent = {0, 0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0},
{NULL, NULL, 0, 0, 0, 0, 0, 0, 0}};
/* Protect global state against multiple changers. */
@ -78,8 +79,7 @@ __libc_lock_define_initialized (static, lock)
/* Prototypes for local functions. */
static void blacklist_store_name (const char *, ent_t *);
static int in_blacklist (const char *, int, ent_t *);
extern int _nss_nisplus_parse_spent (nis_result *, struct spwd *,
char *, size_t);
static void
give_spwd_free (struct spwd *pwd)
{
@ -160,12 +160,19 @@ internal_setspent (ent_t *ent)
nis_freeresult (ent->result);
ent->result = NULL;
}
if (ent->names != NULL)
if (pwdtable == NULL)
{
nis_freenames (ent->names);
ent->names = NULL;
char buf [20 + strlen (nis_local_directory ())];
char *p;
p = stpcpy (buf, "passwd.org_dir.");
p = stpcpy (p, nis_local_directory ());
pwdtable = strdup (buf);
if (pwdtable == NULL)
return NSS_STATUS_TRYAGAIN;
pwdtablelen = strlen (pwdtable);
}
ent->names_nr = 0;
ent->blacklist.current = 0;
if (ent->blacklist.data != NULL)
@ -234,12 +241,6 @@ internal_endspent (ent_t *ent)
nis_freeresult (ent->result);
ent->result = NULL;
}
if (ent->names != NULL)
{
nis_freenames (ent->names);
ent->names = NULL;
}
ent->names_nr = 0;
ent->blacklist.current = 0;
if (ent->blacklist.data != NULL)
@ -387,9 +388,9 @@ getspent_next_nisplus_netgr (struct spwd *result, ent_t *ent, char *group,
p2 = buffer + (buflen - p2len);
buflen -= p2len;
{
char buf[strlen (user) + 30];
sprintf(buf, "[name=%s],passwd.org_dir", user);
nisres = nis_list(buf, EXPAND_NAME, NULL, NULL);
char buf[strlen (user) + 30 + pwdtablelen];
sprintf(buf, "[name=%s],%s", user, pwdtable);
nisres = nis_list(buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
}
if (niserr2nss (nisres->status) != NSS_STATUS_SUCCESS)
{
@ -427,16 +428,6 @@ getspent_next_nisplus (struct spwd *result, ent_t *ent, char *buffer,
size_t p2len;
char *p2;
if (ent->names == NULL)
{
ent->names = nis_getnames ("passwd.org_dir");
if (ent->names == NULL || ent->names[0] == NULL)
{
ent->nis = 0;
return NSS_STATUS_UNAVAIL;
}
}
p2len = spwd_need_buflen (&ent->pwd);
if (p2len > buflen)
{
@ -449,8 +440,7 @@ getspent_next_nisplus (struct spwd *result, ent_t *ent, char *buffer,
{
if (ent->first)
{
next_name:
ent->result = nis_first_entry(ent->names[ent->names_nr]);
ent->result = nis_first_entry(pwdtable);
if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
{
ent->nis = 0;
@ -463,25 +453,14 @@ getspent_next_nisplus (struct spwd *result, ent_t *ent, char *buffer,
{
nis_result *res;
res = nis_next_entry(ent->names[ent->names_nr],
&ent->result->cookie);
res = nis_next_entry(pwdtable, &ent->result->cookie);
nis_freeresult (ent->result);
ent->result = res;
if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
{
if ((ent->result->status == NIS_NOTFOUND) &&
ent->names[ent->names_nr + 1] != NULL)
{
nis_freeresult (ent->result);
ent->names_nr += 1;
goto next_name;
}
else
{
ent->nis = 0;
give_spwd_free (&ent->pwd);
return niserr2nss (ent->result->status);
}
ent->nis = 0;
give_spwd_free (&ent->pwd);
return niserr2nss (ent->result->status);
}
}
parse_res = _nss_nisplus_parse_spent (ent->result, result, buffer,
@ -601,11 +580,10 @@ getspent_next_file_plususer (struct spwd *result, char *buffer,
if (use_nisplus) /* Do the NIS+ query here */
{
nis_result *res;
char buf[strlen (result->sp_namp) + 24];
char buf[strlen (result->sp_namp) + 24 + pwdtablelen];
sprintf(buf, "[name=%s],passwd.org_dir",
&result->sp_namp[1]);
res = nis_list(buf, EXPAND_NAME, NULL, NULL);
sprintf(buf, "[name=%s],%s", &result->sp_namp[1], pwdtable);
res = nis_list(buf, 0, NULL, NULL);
if (niserr2nss (res->status) != NSS_STATUS_SUCCESS)
{
enum nss_status status = niserr2nss (res->status);
@ -821,7 +799,7 @@ enum nss_status
_nss_compat_getspnam_r (const char *name, struct spwd *pwd,
char *buffer, size_t buflen)
{
ent_t ent = {0, 0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0},
ent_t ent = {0, 0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0},
{NULL, NULL, 0, 0, 0, 0, 0, 0, 0}};
enum nss_status status;

View File

@ -22,7 +22,6 @@
#include <errno.h>
#include <string.h>
#include <syslog.h>
#include <bits/libc-lock.h>
#include <rpc/rpc.h>
#include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h>
@ -40,7 +39,7 @@ _nss_nis_getpublickey (const char *netname, char *pkey)
enum nss_status retval;
char *domain, *result;
int len;
pkey[0] = 0;
if (netname == NULL)

View File

@ -31,27 +31,47 @@
__libc_lock_define_initialized (static, lock)
static nis_result *result = NULL;
static nis_name *names = NULL;
static u_long next_entry = 0;
static nis_name tablename_val = NULL;
static u_long tablename_len = 0;
#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)
((res)->objects.objects_val[(idx)].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)
((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
static enum nss_status
_nss_create_tablename (void)
{
if (tablename_val == NULL)
{
char buf [40 + strlen (nis_local_directory ())];
char *p;
p = stpcpy (buf, "mail_aliases.org_dir.");
p = stpcpy (p, nis_local_directory ());
tablename_val = strdup (buf);
if (tablename_val == NULL)
return NSS_STATUS_TRYAGAIN;
tablename_len = strlen (tablename_val);
}
return NSS_STATUS_SUCCESS;
}
static int
_nss_nisplus_parse_aliasent (nis_result *result, struct aliasent *alias,
char *buffer, size_t buflen)
_nss_nisplus_parse_aliasent (nis_result *result, unsigned long entry,
struct aliasent *alias, char *buffer,
size_t buflen)
{
if (result == NULL)
return 0;
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,
__type_of (&result->objects.objects_val[entry]) != ENTRY_OBJ ||
strcmp(result->objects.objects_val[entry].EN_data.en_type,
"mail_aliases") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 2)
result->objects.objects_val[entry].EN_data.en_cols.en_cols_len < 2)
return 0;
else
{
@ -62,7 +82,7 @@ _nss_nisplus_parse_aliasent (nis_result *result, struct aliasent *alias,
char *line;
char *cp;
if (NISENTRYLEN(0, 1, result) >= buflen)
if (NISENTRYLEN(entry, 1, result) >= buflen)
{
/* The line is too long for our buffer. */
no_more_room:
@ -71,19 +91,20 @@ _nss_nisplus_parse_aliasent (nis_result *result, struct aliasent *alias,
}
else
{
strncpy (buffer, NISENTRYVAL(0, 1, result), NISENTRYLEN(0, 1, result));
buffer[NISENTRYLEN(0, 1, result)] = '\0';
strncpy (buffer, NISENTRYVAL(entry, 1, result),
NISENTRYLEN(entry, 1, result));
buffer[NISENTRYLEN(entry, 1, result)] = '\0';
}
if (NISENTRYLEN(0, 0, result) >= room_left)
if (NISENTRYLEN(entry, 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';
strcpy (first_unused, NISENTRYVAL(entry, 0, result));
first_unused[NISENTRYLEN(entry, 0, result)] = '\0';
alias->alias_name = first_unused;
/* Terminate the line for any case. */
@ -129,23 +150,38 @@ _nss_nisplus_parse_aliasent (nis_result *result, struct aliasent *alias,
}
}
enum nss_status
_nss_nisplus_setaliasent (void)
static enum nss_status
internal_setaliasent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
next_entry = 0;
result = nis_list(tablename_val, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
nis_freenames (names);
names = NULL;
nis_freeresult (result);
result = NULL;
}
return niserr2nss (result->status);
}
enum nss_status
_nss_nisplus_setaliasent (void)
{
enum nss_status status;
__libc_lock_lock (lock);
status = internal_setaliasent ();
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
return status;
}
enum nss_status
@ -156,11 +192,7 @@ _nss_nisplus_endaliasent (void)
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
next_entry = 0;
__libc_lock_unlock (lock);
@ -173,31 +205,18 @@ internal_nisplus_getaliasent_r (struct aliasent *alias,
{
int parse_res;
if (result == NULL)
internal_setaliasent ();
/* 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;
if (next_entry >= result->objects.objects_len)
return NSS_STATUS_NOTFOUND;
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);
parse_res = _nss_nisplus_parse_aliasent (result, next_entry, alias,
buffer, buflen);
++next_entry;
} while (!parse_res);
return NSS_STATUS_SUCCESS;
@ -224,21 +243,26 @@ _nss_nisplus_getaliasbyname_r (const char *name, struct aliasent *alias,
{
int parse_res;
if (tablename_val == NULL)
if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
if (name == NULL || strlen(name) > 8)
return NSS_STATUS_NOTFOUND;
else
{
nis_result *result;
char buf[strlen (name) + 30];
char buf[strlen (name) + 30 + tablename_len];
sprintf(buf, "[name=%s],mail_aliases.org_dir", name);
sprintf(buf, "[name=%s],%s", name, tablename_val);
result = nis_list(buf, EXPAND_NAME, NULL, NULL);
result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
return niserr2nss (result->status);
parse_res = _nss_nisplus_parse_aliasent (result, alias, buffer, buflen);
parse_res = _nss_nisplus_parse_aliasent (result, 0, alias,
buffer, buflen);
if (parse_res)
return NSS_STATUS_SUCCESS;

View File

@ -33,7 +33,8 @@
__libc_lock_define_initialized (static, lock)
static nis_result *result = NULL;
static nis_name *names = NULL;
static nis_name tablename_val = NULL;
static u_long tablename_len = 0;
/* 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
@ -45,32 +46,6 @@ struct etherent
};
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)
@ -83,21 +58,18 @@ _nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether,
{
char *p = buffer;
size_t room_left = buflen;
struct parser_data *data = (void *) buffer;
if (result == NULL)
return 0;
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,
__type_of (NIS_RES_OBJECT (result)) != ENTRY_OBJ ||
strcmp(NIS_RES_OBJECT (result)->EN_data.en_type,
"ethers_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 2)
NIS_RES_OBJECT(result)->EN_data.en_cols.en_cols_len < 2)
return 0;
memset (p, '\0', room_left);
/* Generate the ether entry format and use the normal parser */
if (NISENTRYLEN (0, 0, result) +1 > room_left)
{
@ -106,32 +78,47 @@ _nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether,
}
strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
room_left -= (NISENTRYLEN (0, 0, result) +1);
ether->e_name = p;
if (NISENTRYLEN (0, 1, result) +1 > room_left)
{
__set_errno (ERANGE);
return 0;
}
strcat (p, "\t");
strncat (p, NISENTRYVAL (0, 1, result), NISENTRYLEN (0, 1, result));
room_left -= (NISENTRYLEN (0, 1, result) + 1);
ether->e_addr = *ether_aton (NISENTRYVAL (0, 1, result));
return _nss_files_parse_etherent (p,ether, data, buflen);
return 1;
}
static enum nss_status
_nss_create_tablename (void)
{
if (tablename_val == NULL)
{
char buf [40 + strlen (nis_local_directory ())];
char *p;
p = stpcpy (buf, "ethers.org_dir.");
p = stpcpy (p, nis_local_directory ());
tablename_val = strdup (buf);
if (tablename_val == NULL)
return NSS_STATUS_TRYAGAIN;
tablename_len = strlen (tablename_val);
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_setetherent (void)
{
enum nss_status status;
status = NSS_STATUS_SUCCESS;
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
status = NSS_STATUS_UNAVAIL;
__libc_lock_unlock (lock);
@ -146,11 +133,6 @@ _nss_nisplus_endetherent (void)
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
@ -163,16 +145,16 @@ internal_nisplus_getetherent_r (struct etherent *ether, char *buffer,
{
int parse_res;
if (tablename_val == NULL)
if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
/* 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]);
result = nis_first_entry(tablename_val);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
return niserr2nss (result->status);
}
@ -180,7 +162,7 @@ internal_nisplus_getetherent_r (struct etherent *ether, char *buffer,
{
nis_result *res2;
res2 = nis_next_entry(names[0], &result->cookie);
res2 = nis_next_entry(tablename_val, &result->cookie);
nis_freeresult (result);
result = res2;
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
@ -214,16 +196,20 @@ _nss_nisplus_gethostton_r (const char *name, struct etherent *eth,
{
int parse_res;
if (tablename_val == NULL)
if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
if (name == NULL)
return NSS_STATUS_NOTFOUND;
else
{
nis_result *result;
char buf[strlen (name) + 255];
char buf[strlen (name) + 40 + tablename_len];
sprintf(buf, "[name=%s],ethers.org_dir", name);
sprintf(buf, "[name=%s],%s", name, tablename_val);
result = nis_list(buf, EXPAND_NAME, NULL, NULL);
result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
return niserr2nss (result->status);
@ -245,34 +231,40 @@ _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 (tablename_val == NULL)
if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
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;
{
int parse_res;
nis_result *result;
char buf[255 + tablename_len];
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, FOLLOW_PATH | FOLLOW_LINKS, 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;
}
}

View File

@ -27,143 +27,66 @@
#include <rpcsvc/nislib.h>
#include "nss-nisplus.h"
#include "nisplus-parser.h"
__libc_lock_define_initialized (static, lock);
static nis_result *result = NULL;
static nis_name *names = NULL;
static unsigned long next_entry = 0;
static nis_name tablename_val = NULL;
static u_long tablename_len = 0;
#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)
int
_nss_nisplus_parse_grent (nis_result * result, struct group *gr,
char *buffer, size_t buflen)
static enum nss_status
_nss_create_tablename (void)
{
char *first_unused = buffer;
size_t room_left = buflen;
char *line;
int count;
if (result == NULL)
return 0;
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 0;
if (NISENTRYLEN (0, 0, result) >= room_left)
if (tablename_val == NULL)
{
/* The line is too long for our buffer. */
no_more_room:
__set_errno (ERANGE);
return 0;
char buf [40 + strlen (nis_local_directory ())];
char *p;
p = stpcpy (buf, "group.org_dir.");
p = stpcpy (p, nis_local_directory ());
tablename_val = strdup (buf);
if (tablename_val == NULL)
return NSS_STATUS_TRYAGAIN;
tablename_len = strlen (tablename_val);
}
return NSS_STATUS_SUCCESS;
}
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;
static enum nss_status
internal_setgrent (void)
{
if (result)
nis_freeresult (result);
result = NULL;
next_entry = 0;
if (NISENTRYLEN (0, 1, result) >= room_left)
goto no_more_room;
if (tablename_val == NULL)
if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
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')
result = nis_list (tablename_val, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
/* 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])
{
if (*line != '\0')
{
*line = '\0';
++line;
}
++count;
}
else
gr->gr_mem[count] = NULL;
nis_freeresult (result);
result = NULL;
}
if (room_left < sizeof (char *))
goto no_more_room;
room_left -= sizeof (char *);
gr->gr_mem[count] = NULL;
return 1;
return niserr2nss (result->status);
}
enum nss_status
_nss_nisplus_setgrent (void)
{
enum nss_status status;
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
status = internal_setgrent ();
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
return status;
}
enum nss_status
@ -174,11 +97,6 @@ _nss_nisplus_endgrent (void)
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
@ -190,31 +108,18 @@ internal_nisplus_getgrent_r (struct group *gr, char *buffer, size_t buflen)
{
int parse_res;
if (result == NULL)
internal_setgrent ();
/* 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;
if (next_entry >= result->objects.objects_len)
return NSS_STATUS_NOTFOUND;
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);
parse_res = _nss_nisplus_parse_grent (result, next_entry, gr,
buffer, buflen);
++next_entry;
}
while (!parse_res);
@ -241,16 +146,20 @@ _nss_nisplus_getgrnam_r (const char *name, struct group *gr,
{
int parse_res;
if (tablename_val == NULL)
if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
if (name == NULL || strlen (name) > 8)
return NSS_STATUS_NOTFOUND;
else
{
nis_result *result;
char buf[strlen (name) + 24];
char buf[strlen (name) + 24 + tablename_len];
sprintf (buf, "[name=%s],group.org_dir", name);
sprintf (buf, "[name=%s],%s", name, tablename_val);
result = nis_list (buf, EXPAND_NAME, NULL, NULL);
result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
@ -260,7 +169,7 @@ _nss_nisplus_getgrnam_r (const char *name, struct group *gr,
return status;
}
parse_res = _nss_nisplus_parse_grent (result, gr, buffer, buflen);
parse_res = _nss_nisplus_parse_grent (result, 0, gr, buffer, buflen);
nis_freeresult (result);
@ -278,31 +187,37 @@ 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];
if (tablename_val == NULL)
if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
sprintf (buf, "[gid=%d],group.org_dir", gid);
{
int parse_res;
nis_result *result;
char buf[36 + tablename_len];
result = nis_list (buf, EXPAND_NAME, NULL, NULL);
sprintf (buf, "[gid=%d],%s", gid, tablename_val);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
enum nss_status status = niserr2nss (result->status);
result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
nis_freeresult (result);
return status;
}
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
enum nss_status status = niserr2nss (result->status);
parse_res = _nss_nisplus_parse_grent (result, gr, buffer, buflen);
nis_freeresult (result);
return status;
}
nis_freeresult (result);
parse_res = _nss_nisplus_parse_grent (result, 0, gr, buffer, buflen);
if (parse_res)
return NSS_STATUS_SUCCESS;
nis_freeresult (result);
if (!parse_res && errno == ERANGE)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
if (parse_res)
return NSS_STATUS_SUCCESS;
if (!parse_res && errno == ERANGE)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
}

View File

@ -33,13 +33,14 @@
__libc_lock_define_initialized (static, lock)
static nis_result *result = NULL;
static nis_name *names = NULL;
static nis_name tablename_val = NULL;
static u_long tablename_len = 0;
#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)
((res)->objects.objects_val[(idx)].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)
((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
/* Get implementation for some internal functions. */
#include "../../resolv/mapv4v6addr.h"
@ -57,10 +58,10 @@ _nss_nisplus_parse_hostent (nis_result *result, int af, struct hostent *host,
return 0;
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)
__type_of (result->objects.objects_val) != ENTRY_OBJ ||
strcmp(result->objects.objects_val[0].EN_data.en_type,
"hosts_tbl") != 0 ||
result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 4)
return 0;
if (room_left < NISENTRYLEN (0, 2, result) + 1)
@ -162,37 +163,58 @@ _nss_nisplus_parse_hostent (nis_result *result, int af, struct hostent *host,
host->h_aliases[i] = line;
while (*line != '\0' && *line != ' ')
line++;
++line;
if (line != host->h_aliases[i])
{
*line = '\0';
line++;
i++;
}
if (*line == ' ')
{
*line = '\0';
++line;
++i;
}
else
host->h_aliases[i+1] = NULL;
}
return 1;
}
static enum nss_status
_nss_create_tablename (void)
{
if (tablename_val == NULL)
{
char buf [40 + strlen (nis_local_directory ())];
char *p;
p = stpcpy (buf, "hosts.org_dir.");
p = stpcpy (p, nis_local_directory ());
tablename_val = strdup (buf);
if (tablename_val == NULL)
return NSS_STATUS_TRYAGAIN;
tablename_len = strlen (tablename_val);
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_sethostent (void)
{
enum nss_status status = NSS_STATUS_SUCCESS;
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
if (tablename_val == NULL)
if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
status = NSS_STATUS_UNAVAIL;
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
return status;
}
enum nss_status
@ -203,11 +225,6 @@ _nss_nisplus_endhostent (void)
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
@ -225,11 +242,11 @@ internal_nisplus_gethostent_r (struct hostent *host, char *buffer,
{
if (result == NULL)
{
names = nis_getnames("hosts.org_dir");
if (names == NULL || names[0] == NULL)
return NSS_STATUS_UNAVAIL;
if (tablename_val == NULL)
if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
result = nis_first_entry(names[0]);
result = nis_first_entry(tablename_val);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
int retval;
@ -248,7 +265,7 @@ internal_nisplus_gethostent_r (struct hostent *host, char *buffer,
{
nis_result *res2;
res2 = nis_next_entry(names[0], &result->cookie);
res2 = nis_next_entry(tablename_val, &result->cookie);
nis_freeresult (result);
result = res2;
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
@ -302,6 +319,13 @@ _nss_nisplus_gethostbyname2_r (const char *name, int af, struct hostent *host,
{
int parse_res, retval;
if (tablename_val == NULL)
if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
{
*herrnop = NETDB_INTERNAL;
return NSS_STATUS_UNAVAIL;
}
if (name == NULL)
{
__set_errno (EINVAL);
@ -311,28 +335,27 @@ _nss_nisplus_gethostbyname2_r (const char *name, int af, struct hostent *host,
else
{
nis_result *result;
char buf[strlen (name) + 255];
char buf[strlen (name) + 255 + tablename_len];
/* 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);
sprintf(buf, "[name=%s],%s", name, tablename_val);
result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, 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,
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
__type_of (result->objects.objects_val) != ENTRY_OBJ ||
strcmp(result->objects.objects_val->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);
result->objects.objects_val->EN_data.en_cols.en_cols_len < 3)
sprintf(buf, "[cname=%s],%s", name, tablename_val);
else
sprintf(buf, "[cname=%s],hosts.org_dir", NISENTRYVAL(0, 0, result));
sprintf(buf, "[cname=%s],%s", NISENTRYVAL(0, 0, result),
tablename_val);
nis_freeresult (result);
result = nis_list(buf, EXPAND_NAME, NULL, NULL);
result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
retval = niserr2nss (result->status);
if (retval != NSS_STATUS_SUCCESS)
@ -385,17 +408,21 @@ _nss_nisplus_gethostbyaddr_r (const char *addr, int addrlen, int type,
struct hostent *host, char *buffer,
size_t buflen, int *herrnop)
{
if (tablename_val == NULL)
if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
if (addr == NULL)
return NSS_STATUS_NOTFOUND;
else
{
nis_result *result;
char buf[1025];
char buf[255 + tablename_len];
int retval, parse_res;
snprintf(buf, sizeof (buf) -1, "[addr=%s],hosts.org_dir",
inet_ntoa (*(struct in_addr *)addr));
result = nis_list(buf, EXPAND_NAME, NULL, NULL);
snprintf(buf, sizeof (buf) -1, "[addr=%s],%s",
inet_ntoa (*(struct in_addr *)addr), tablename_val);
result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
retval = niserr2nss (result->status);
if (retval != NSS_STATUS_SUCCESS)

View File

@ -36,10 +36,10 @@ static unsigned long data_size = 0;
static unsigned long position = 0;
#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)
((res)->objects.objects_val[(idx)].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)
((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
static enum nss_status
_nss_nisplus_parse_netgroup (struct __netgrent *result, char *buffer,
@ -49,8 +49,7 @@ _nss_nisplus_parse_netgroup (struct __netgrent *result, char *buffer,
/* Some sanity checks. */
if (data == NULL || data_size == 0)
/* User bug. setnetgrent() wasn't called before. */
abort ();
return NSS_STATUS_NOTFOUND;
if (position == data_size)
return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
@ -154,9 +153,9 @@ _nss_nisplus_setnetgrent (char *group)
position = 0;
}
sprintf(buf, "[name=%s],netgroup.org_dir", group);
sprintf (buf, "[name=%s],netgroup.org_dir", group);
data = nis_list(buf, EXPAND_NAME, NULL, NULL);
data = nis_list (buf, EXPAND_NAME, NULL, NULL);
if (niserr2nss (data->status) != NSS_STATUS_SUCCESS)
{

View File

@ -29,109 +29,160 @@
#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;
static nis_name tablename_val = NULL;
static u_long tablename_len = 0;
#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)
((res)->objects.objects_val[(idx)].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)
((res)->objects.objects_val[(idx)].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;
char *first_unused = buffer;
size_t room_left = buflen;
unsigned int i;
struct parser_data *data = (void *) buffer;
char *p, *line;
if (result == NULL)
return 0;
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,
__type_of (result->objects.objects_val) != ENTRY_OBJ ||
strcmp(result->objects.objects_val[0].EN_data.en_type,
"networks_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3)
result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 3)
return 0;
/* Generate the network entry format and use the normal parser */
if (NISENTRYLEN (0, 0, result) +1 > room_left)
if (NISENTRYLEN(0, 0, result) >= room_left)
{
/* The line is too long for our buffer. */
no_more_room:
__set_errno (ERANGE);
return 0;
}
memset (p, '\0', room_left);
strncpy (first_unused, NISENTRYVAL(0, 0, result),
NISENTRYLEN (0, 0, result));
first_unused[NISENTRYLEN(0, 0, result)] = '\0';
network->n_name = first_unused;
room_left -= (strlen (first_unused) +1);
first_unused += strlen (first_unused) +1;
network->n_addrtype = 0;
network->n_net = inet_network (NISENTRYVAL (0, 2, result));
p = first_unused;
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)
line = p;
for (i = 0; i < result->objects.objects_len; i++)
{
__set_errno (ERANGE);
return 0;
if (strcmp (NISENTRYVAL (i, 1, result), network->n_name) != 0)
{
if (NISENTRYLEN (i, 1, result) + 2 > room_left)
{
__set_errno (ERANGE);
return 0;
}
p = stpcpy(p, " ");
p = stpncpy (p, NISENTRYVAL (i, 1, result),
NISENTRYLEN (i, 1, result));
*p = '\0';
room_left -= (NISENTRYLEN (i, 1, result) + 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 */
++p;
first_unused = p;
for (i = 1; i < result->objects.objects_len; i++)
/* Adjust the pointer so it is aligned for
storing pointers. */
first_unused += __alignof__ (char *) - 1;
first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *));
network->n_aliases = (char **) first_unused;
if (room_left < 2 * sizeof (char *))
goto no_more_room;
room_left -= (2 * sizeof (char *));
network->n_aliases[0] = NULL;
i = 0;
while (*line != '\0')
{
if (NISENTRYLEN (i, 1, result) +1 > room_left)
{
__set_errno (ERANGE);
return 0;
}
strcat (p, " ");
strncat (p, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));
room_left -= (NISENTRYLEN (i, 1, result) + 1);
/* Skip leading blanks. */
while (isspace (*line))
line++;
if (*line == '\0')
break;
if (room_left < sizeof (char *))
{
__set_errno (ERANGE);
return 0;
}
room_left -= sizeof (char *);
network->n_aliases[i] = line;
while (*line != '\0' && *line != ' ')
++line;
if (line != network->n_aliases[i])
{
if (*line != '\0')
{
*line = '\0';
++line;
}
++i;
}
else
network->n_aliases[i] = NULL;
}
return _nss_files_parse_netent (p, network, data, buflen);
return 1;
}
static enum nss_status
_nss_create_tablename (void)
{
if (tablename_val == NULL)
{
char buf [40 + strlen (nis_local_directory ())];
char *p;
p = stpcpy (buf, "networks.org_dir.");
p = stpcpy (p, nis_local_directory ());
tablename_val = strdup (buf);
if (tablename_val == NULL)
return NSS_STATUS_TRYAGAIN;
tablename_len = strlen (tablename_val);
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_setnetent (void)
{
enum nss_status status = NSS_STATUS_SUCCESS;
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
if (tablename_val == NULL)
if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
status = NSS_STATUS_UNAVAIL;
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
return status;
}
enum nss_status
@ -142,11 +193,6 @@ _nss_nisplus_endnetent (void)
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
@ -164,11 +210,11 @@ internal_nisplus_getnetent_r (struct netent *network, char *buffer,
{
if (result == NULL)
{
names = nis_getnames("networks.org_dir");
if (names == NULL || names[0] == NULL)
return NSS_STATUS_UNAVAIL;
if (tablename_val == NULL)
if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
result = nis_first_entry(names[0]);
result = nis_first_entry(tablename_val);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
int retval;
@ -178,15 +224,17 @@ internal_nisplus_getnetent_r (struct netent *network, char *buffer,
{
*herrnop = NETDB_INTERNAL;
__set_errno (EAGAIN);
return retval;
}
return retval;
else
return retval;
}
}
else
{
nis_result *res;
res = nis_next_entry(names[0], &result->cookie);
res = nis_next_entry(tablename_val, &result->cookie);
nis_freeresult (result);
result = res;
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
@ -236,6 +284,10 @@ _nss_nisplus_getnetbyname_r (const char *name, struct netent *network,
{
int parse_res, retval;
if (tablename_val == NULL)
if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
if (name == NULL)
{
__set_errno (EINVAL);
@ -245,28 +297,28 @@ _nss_nisplus_getnetbyname_r (const char *name, struct netent *network,
else
{
nis_result *result;
char buf[strlen (name) + 255];
char buf[strlen (name) + 255 + tablename_len];
/* 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);
sprintf(buf, "[name=%s],%s", name, tablename_val);
result = nis_list(buf, FOLLOW_LINKS | FOLLOW_PATH, 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,
__type_of (result->objects.objects_val) != ENTRY_OBJ ||
strcmp(result->objects.objects_val[0].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);
result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 3)
sprintf(buf, "[cname=%s],%s", name, tablename_val);
else
sprintf(buf, "[cname=%s],networks.org_dir", NISENTRYVAL(0, 0, result));
sprintf(buf, "[cname=%s],%s", NISENTRYVAL(0, 0, result),
tablename_val);
nis_freeresult (result);
result = nis_list(buf, EXPAND_NAME, NULL, NULL);
result = nis_list(buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
retval = niserr2nss (result->status);
if (retval != NSS_STATUS_SUCCESS)
@ -301,39 +353,45 @@ _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;
if (tablename_val == NULL)
if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
in = inet_makeaddr (addr, 0);
snprintf(buf, sizeof (buf) - 1, "[addr=%s],networks.org_dir",
inet_ntoa (in));
{
int parse_res, retval;
nis_result *result;
char buf[1024 + tablename_len];
struct in_addr in;
result = nis_list(buf, EXPAND_NAME, NULL, NULL);
in = inet_makeaddr (addr, 0);
snprintf(buf, sizeof (buf) - 1, "[addr=%s],%s",
inet_ntoa (in), tablename_len);
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;
}
result = nis_list(buf, EXPAND_NAME, NULL, NULL);
parse_res = _nss_nisplus_parse_netent (result, network, buffer, buflen);
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;
}
nis_freeresult (result);
parse_res = _nss_nisplus_parse_netent (result, network, buffer, buflen);
if (parse_res)
return NSS_STATUS_SUCCESS;
nis_freeresult (result);
*herrnop = NETDB_INTERNAL;
if (!parse_res && errno == ERANGE)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
if (parse_res)
return NSS_STATUS_SUCCESS;
*herrnop = NETDB_INTERNAL;
if (!parse_res && errno == ERANGE)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
}

View File

@ -0,0 +1,337 @@
/* 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 <pwd.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <rpcsvc/nis.h>
#include "nisplus-parser.h"
#define NISENTRYVAL(idx,col,res) \
((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
#define NISENTRYLEN(idx,col,res) \
((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
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 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
result->objects.objects_len != 1 ||
__type_of (result->objects.objects_val) != ENTRY_OBJ ||
strcmp(result->objects.objects_val->EN_data.en_type,
"passwd_tbl") != 0 ||
result->objects.objects_val->EN_data.en_cols.en_cols_len < 7)
return 0;
if (NISENTRYLEN (0, 0, result) >= room_left)
{
/* The line is too long for our buffer. */
no_more_room:
__set_errno (ERANGE);
return 0;
}
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;
}
int
_nss_nisplus_parse_grent (nis_result *result, u_long entry,
struct group *gr, char *buffer, size_t buflen)
{
char *first_unused = buffer;
size_t room_left = buflen;
char *line;
int count;
if (result == NULL)
return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
__type_of(result->objects.objects_val) != ENTRY_OBJ ||
strcmp (result->objects.objects_val[entry].EN_data.en_type,
"group_tbl") != 0 ||
result->objects.objects_val[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. */
no_more_room:
__set_errno (ERANGE);
return 0;
}
strncpy (first_unused, NISENTRYVAL (entry, 0, result),
NISENTRYLEN (entry, 0, result));
first_unused[NISENTRYLEN (entry, 0, result)] = '\0';
gr->gr_name = first_unused;
room_left -= (strlen (first_unused) + 1);
first_unused += strlen (first_unused) + 1;
if (NISENTRYLEN (entry, 1, result) >= room_left)
goto no_more_room;
strncpy (first_unused, NISENTRYVAL (entry, 1, result),
NISENTRYLEN (entry, 1, result));
first_unused[NISENTRYLEN (entry, 1, result)] = '\0';
gr->gr_passwd = first_unused;
room_left -= (strlen (first_unused) + 1);
first_unused += strlen (first_unused) + 1;
if (NISENTRYLEN (entry, 2, result) >= room_left)
goto no_more_room;
strncpy (first_unused, NISENTRYVAL (entry, 2, result),
NISENTRYLEN (entry, 2, result));
first_unused[NISENTRYLEN (entry, 2, result)] = '\0';
gr->gr_gid = atoi (first_unused);
room_left -= (strlen (first_unused) + 1);
first_unused += strlen (first_unused) + 1;
if (NISENTRYLEN (entry, 3, result) >= room_left)
goto no_more_room;
strncpy (first_unused, NISENTRYVAL (entry, 3, result),
NISENTRYLEN (entry, 3, result));
first_unused[NISENTRYLEN (entry, 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])
{
if (*line != '\0')
{
*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;
}
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;
if (result == NULL)
return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
result->objects.objects_len != 1 ||
__type_of(result->objects.objects_val) != ENTRY_OBJ ||
strcmp (result->objects.objects_val->EN_data.en_type,
"passwd_tbl") != 0 ||
result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 8)
return 0;
if (NISENTRYLEN(0, 0, result) >= room_left)
{
/* The line is too long for our buffer. */
no_more_room:
__set_errno (ERANGE);
return 0;
}
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;
if (NISENTRYLEN (0, 7, result) > 0)
{
char *line, *cp;
line = NISENTRYVAL (0, 7, result);
cp = strchr (line, ':');
if (cp == NULL)
return 0;
*cp++ = '\0';
sp->sp_lstchg = atol (line);
line = cp;
cp = strchr (line, ':');
if (cp == NULL)
return 0;
*cp++ = '\0';
sp->sp_min = atol(line);
line = cp;
cp = strchr (line, ':');
if (cp == NULL)
return 0;
*cp++ = '\0';
sp->sp_max = atol(line);
line = cp;
cp = strchr (line, ':');
if (cp == NULL)
return 0;
*cp++ = '\0';
sp->sp_warn = atol(line);
line = cp;
cp = strchr (line, ':');
if (cp == NULL)
return 0;
*cp++ = '\0';
sp->sp_inact = atol(line);
line = cp;
cp = strchr (line, ':');
if (cp == NULL)
return 0;
*cp++ = '\0';
sp->sp_expire = atol(line);
line = cp;
if (line == NULL)
return 0;
sp->sp_flag = atol(line);
}
return 1;
}

View File

@ -31,97 +31,146 @@
__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,);
)
static nis_name tablename_val = NULL;
static u_long tablename_len = 0;
#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)
((res)->objects.objects_val[(idx)].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)
((res)->objects.objects_val[(idx)].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;
char *first_unused = buffer;
size_t room_left = buflen;
unsigned int i;
struct parser_data *data = (void *) buffer;
char *p, *line;
if (result == NULL)
return 0;
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)
__type_of (NIS_RES_OBJECT (result)) != ENTRY_OBJ ||
strcmp (NIS_RES_OBJECT (result)->EN_data.en_type, "protocols_tbl") != 0
|| NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 3)
return 0;
memset (p, '\0', room_left);
/* Generate the protocols entry format and use the normal parser */
if (NISENTRYLEN (0, 0, result) + 1 > room_left)
{
no_more_room:
__set_errno (ERANGE);
return 0;
}
strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
room_left -= (NISENTRYLEN (0, 0, result) + 1);
strncpy (first_unused, NISENTRYVAL (0, 0, result),
NISENTRYLEN (0, 0, result));
first_unused[NISENTRYLEN (0, 0, result)] = '\0';
proto->p_name = first_unused;
room_left -= (strlen (first_unused) +1);
first_unused += strlen (first_unused) +1;
if (NISENTRYLEN (0, 2, result) + 1 > room_left)
{
__set_errno (ERANGE);
return 0;
}
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 */
goto no_more_room;
proto->p_proto = atoi (NISENTRYVAL (0, 2, result));
p = first_unused;
for (i = 1; i < result->objects.objects_len; i++)
line = p;
for (i = 0; i < result->objects.objects_len; i++)
{
if (NISENTRYLEN (i, 1, result) + 1 > room_left)
{
__set_errno (ERANGE);
return 0;
}
strcat (p, " ");
strncat (p, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));
room_left -= (NISENTRYLEN (i, 1, result) + 1);
if (strcmp (NISENTRYVAL (i, 1, result), proto->p_name) != 0)
{
if (NISENTRYLEN (i, 1, result) + 2 > room_left)
goto no_more_room;
p = stpcpy(p, " ");
p = stpncpy (p, NISENTRYVAL (i, 1, result),
NISENTRYLEN (i, 1, result));
*p = '\0';
room_left -= (NISENTRYLEN (i, 1, result) + 1);
}
}
++p;
first_unused = p;
/* Adjust the pointer so it is aligned for
storing pointers. */
first_unused += __alignof__ (char *) - 1;
first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *));
proto->p_aliases = (char **) first_unused;
if (room_left < sizeof (char *))
goto no_more_room;
room_left -= (sizeof (char *));
proto->p_aliases[0] = NULL;
i = 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 *);
proto->p_aliases[i] = line;
while (*line != '\0' && *line != ' ')
++line;
if (*line == ' ')
{
*line = '\0';
++line;
++i;
}
else
proto->p_aliases[i+1] = NULL;
}
return _nss_files_parse_protoent (p, proto, data, buflen);
return 1;
}
static enum nss_status
_nss_create_tablename (void)
{
if (tablename_val == NULL)
{
char buf [40 + strlen (nis_local_directory ())];
char *p;
p = stpcpy (buf, "protocols.org_dir.");
p = stpcpy (p, nis_local_directory ());
tablename_val = strdup (buf);
if (tablename_val == NULL)
return NSS_STATUS_TRYAGAIN;
tablename_len = strlen (tablename_val);
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_setprotoent (void)
{
enum nss_status status = NSS_STATUS_SUCCESS;
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
if (tablename_val == NULL)
status = _nss_create_tablename ();
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
return status;
}
enum nss_status
@ -132,11 +181,6 @@ _nss_nisplus_endprotoent (void)
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
@ -154,11 +198,11 @@ internal_nisplus_getprotoent_r (struct protoent *proto, char *buffer,
{
if (result == NULL)
{
names = nis_getnames ("protocols.org_dir");
if (names == NULL || names[0] == NULL)
return NSS_STATUS_UNAVAIL;
if (tablename_val == NULL)
if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
result = nis_first_entry (names[0]);
result = nis_first_entry (tablename_val);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
return niserr2nss (result->status);
}
@ -166,7 +210,7 @@ internal_nisplus_getprotoent_r (struct protoent *proto, char *buffer,
{
nis_result *res;
res = nis_next_entry (names[0], &result->cookie);
res = nis_next_entry (tablename_val, &result->cookie);
nis_freeresult (result);
result = res;
@ -202,32 +246,37 @@ _nss_nisplus_getprotobyname_r (const char *name, struct protoent *proto,
{
int parse_res;
if (tablename_val == NULL)
if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
if (name == NULL)
return NSS_STATUS_NOTFOUND;
else
{
nis_result *result;
char buf[strlen (name) + 255];
char buf[strlen (name) + 255 + tablename_len];
/* 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);
sprintf (buf, "[name=%s],%s", name, tablename_val);
result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, 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,
__type_of (result->objects.objects_val) != ENTRY_OBJ ||
strcmp (result->objects.objects_val->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);
result->objects.objects_val->EN_data.en_cols.en_cols_len < 3)
sprintf (buf, "[cname=%s],%s", name, tablename_val);
else
sprintf (buf, "[cname=%s],protocols.org_dir", NISENTRYVAL (0, 0, result));
sprintf (buf, "[cname=%s],%s", NISENTRYVAL (0, 0, result),
tablename_val);
nis_freeresult (result);
result = nis_list (buf, EXPAND_NAME, NULL, NULL);
result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
@ -255,30 +304,35 @@ 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];
if (tablename_val == NULL)
if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
{
int parse_res;
nis_result *result;
char buf[46 + tablename_len];
snprintf (buf, sizeof (buf), "[number=%d],protocols.org_dir", number);
snprintf (buf, sizeof (buf), "[number=%d],%s", number, tablename_val);
result = nis_list (buf, EXPAND_NAME, NULL, NULL);
result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
enum nss_status status = niserr2nss (result->status);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
enum nss_status status = niserr2nss (result->status);
nis_freeresult (result);
return status;
}
nis_freeresult (result);
return status;
}
parse_res = _nss_nisplus_parse_protoent (result, proto, buffer, buflen);
parse_res = _nss_nisplus_parse_protoent (result, proto, buffer, buflen);
nis_freeresult (result);
if (parse_res)
return NSS_STATUS_SUCCESS;
nis_freeresult (result);
if (parse_res)
return NSS_STATUS_SUCCESS;
if (!parse_res && errno == ERANGE)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
if (!parse_res && errno == ERANGE)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
}

View File

@ -61,10 +61,10 @@ _nss_nisplus_getpublickey (const char *netname, char *pkey)
netname, domain);
if (buf[strlen (buf)-1] != '.')
strcat(buf, ".");
strcat (buf, ".");
res = nis_list(buf, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH,
NULL, NULL);
res = nis_list (buf, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH,
NULL, NULL);
retval = niserr2nss (res->status);
@ -192,7 +192,7 @@ parse_grp_str (const char *s, gid_t *gidp, int *gidlenp, gid_t *gidlist)
return NSS_STATUS_NOTFOUND;
}
*gidp = (atoi (s));
*gidp = atoi (s);
gidlen = 0;
@ -238,7 +238,7 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
/* XXX but we cant, for now. XXX */
res = nis_list (sname, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH,
NULL, NULL);
switch(res->status)
switch (res->status)
{
case NIS_SUCCESS:
case NIS_S_SUCCESS:
@ -274,10 +274,10 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
netname, domain);
}
len = ENTRY_LEN(res->objects.objects_val, 0);
strncpy(principal, ENTRY_VAL(res->objects.objects_val, 0), len);
len = ENTRY_LEN (res->objects.objects_val, 0);
strncpy (principal, ENTRY_VAL (res->objects.objects_val, 0), len);
principal[len] = '\0';
nis_freeresult(res);
nis_freeresult (res);
if (principal[0] == '\0')
return NSS_STATUS_UNAVAIL;
@ -287,45 +287,45 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
* LOCAL entry in **local** cred table.
*/
domain = nis_local_directory ();
if ((strlen(principal)+strlen(domain)+45) >
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",
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;
}
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)
{
@ -339,7 +339,7 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
netname, domain);
}
/* Fetch the uid */
*uidp = (atoi (ENTRY_VAL (res->objects.objects_val, 2)));
*uidp = atoi (ENTRY_VAL (res->objects.objects_val, 2));
if (*uidp == 0)
{

View File

@ -30,127 +30,48 @@
__libc_lock_define_initialized (static, lock)
static nis_result *result = NULL;
static nis_name *names = NULL;
static nis_name tablename_val = NULL;
static u_long tablename_len = 0;
#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)
extern int _nss_nisplus_parse_pwent (nis_result *res, struct passwd *pw,
char *buffer, size_t buflen);
#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)
int
_nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
char *buffer, size_t buflen)
static enum nss_status
_nss_create_tablename (void)
{
char *first_unused = buffer;
size_t room_left = buflen;
if (result == NULL)
return 0;
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 0;
if (NISENTRYLEN(0, 0, result) >= room_left)
if (tablename_val == NULL)
{
/* The line is too long for our buffer. */
no_more_room:
__set_errno (ERANGE);
return 0;
char buf [40 + strlen (nis_local_directory ())];
char *p;
p = stpcpy (buf, "passwd.org_dir.");
p = stpcpy (p, nis_local_directory ());
tablename_val = strdup (buf);
if (tablename_val == NULL)
return NSS_STATUS_TRYAGAIN;
tablename_len = strlen (tablename_val);
}
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;
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_setpwent (void)
{
enum nss_status status = NSS_STATUS_SUCCESS;
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
if (tablename_val == NULL)
status = _nss_create_tablename ();
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
return status;
}
enum nss_status
@ -161,11 +82,6 @@ _nss_nisplus_endpwent (void)
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
@ -182,11 +98,11 @@ internal_nisplus_getpwent_r (struct passwd *pw, char *buffer, size_t buflen)
{
if (result == NULL)
{
names = nis_getnames ("passwd.org_dir");
if (names == NULL || names[0] == NULL)
return NSS_STATUS_UNAVAIL;
if (tablename_val == NULL)
if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
result = nis_first_entry(names[0]);
result = nis_first_entry(tablename_val);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
return niserr2nss (result->status);
}
@ -194,7 +110,7 @@ internal_nisplus_getpwent_r (struct passwd *pw, char *buffer, size_t buflen)
{
nis_result *res;
res = nis_next_entry(names[0], &result->cookie);
res = nis_next_entry(tablename_val, &result->cookie);
nis_freeresult (result);
result = res;
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
@ -227,16 +143,20 @@ _nss_nisplus_getpwnam_r (const char *name, struct passwd *pw,
{
int parse_res;
if (tablename_val == NULL)
if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
if (name == NULL || strlen (name) > 8)
return NSS_STATUS_NOTFOUND;
else
{
nis_result *result;
char buf[strlen (name) + 24];
char buf[strlen (name) + 24 + tablename_len];
sprintf(buf, "[name=%s],passwd.org_dir", name);
sprintf(buf, "[name=%s],%s", name, tablename_val);
result = nis_list(buf, EXPAND_NAME, NULL, NULL);
result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
@ -264,30 +184,35 @@ 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];
if (tablename_val == NULL)
if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
{
int parse_res;
nis_result *result;
char buf[100 + tablename_len];
sprintf(buf, "[uid=%d],passwd.org_dir", uid);
sprintf(buf, "[uid=%d],%s", uid, tablename_val);
result = nis_list(buf, EXPAND_NAME, NULL, NULL);
result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
enum nss_status status = niserr2nss (result->status);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
enum nss_status status = niserr2nss (result->status);
nis_freeresult (result);
return status;
}
nis_freeresult (result);
return status;
}
parse_res = _nss_nisplus_parse_pwent (result, pw, buffer, buflen);
parse_res = _nss_nisplus_parse_pwent (result, pw, buffer, buflen);
nis_freeresult (result);
if (parse_res)
return NSS_STATUS_SUCCESS;
nis_freeresult (result);
if (parse_res)
return NSS_STATUS_SUCCESS;
if (!parse_res && errno == ERANGE)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
if (!parse_res && errno == ERANGE)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
}

View File

@ -31,98 +31,148 @@
__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,);
)
static nis_name tablename_val = NULL;
static u_long tablename_len = 0;
#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)
((res)->objects.objects_val[(idx)].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)
((res)->objects.objects_val[(idx)].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;
char *first_unused = buffer;
size_t room_left = buflen;
unsigned int i;
struct parser_data *data = (void *) buffer;
char *p, *line;
if (result == NULL)
return 0;
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,
__type_of (result->objects.objects_val) != ENTRY_OBJ ||
strcmp(result->objects.objects_val[0].EN_data.en_type,
"rpc_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3)
result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 3)
return 0;
memset (p, '\0', room_left);
/* Generate the rpc entry format and use the normal parser */
if (NISENTRYLEN (0, 0, result) +1 > room_left)
if (NISENTRYLEN (0, 0, result) >= room_left)
{
no_more_room:
__set_errno (ERANGE);
return 0;
}
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 0;
}
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 */
strncpy (first_unused, NISENTRYVAL (0, 0, result),
NISENTRYLEN (0, 0, result));
first_unused[NISENTRYLEN (0, 0, result)] = '\0';
rpc->r_name = first_unused;
room_left -= (strlen (first_unused) +1);
first_unused += strlen (first_unused) +1;
rpc->r_number = atoi (NISENTRYVAL (0, 2, result));
p = first_unused;
line = p;
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)
if (strcmp (NISENTRYVAL (i, 1, result), rpc->r_name) != 0)
{
__set_errno (ERANGE);
return 0;
if (NISENTRYLEN (i, 1, result) + 2 > room_left)
goto no_more_room;
p = stpcpy(p, " ");
p = stpncpy (p, NISENTRYVAL (i, 1, result),
NISENTRYLEN (i, 1, result));
*p = '\0';
room_left -= (NISENTRYLEN (i, 1, result) + 1);
}
strcat (p, " ");
strncat (p, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));
room_left -= (NISENTRYLEN (i, 1, result) + 1);
}
++p;
first_unused = p;
/* Adjust the pointer so it is aligned for
storing pointers. */
first_unused += __alignof__ (char *) - 1;
first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *));
rpc->r_aliases = (char **) first_unused;
if (room_left < sizeof (char *))
goto no_more_room;
room_left -= (sizeof (char *));
rpc->r_aliases[0] = NULL;
i = 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 *);
rpc->r_aliases[i] = line;
while (*line != '\0' && *line != ' ')
++line;
if (line != rpc->r_aliases[i])
{
if (*line != '\0')
{
*line = '\0';
++line;
}
++i;
}
else
rpc->r_aliases[i] = NULL;
}
return _nss_files_parse_rpcent (p, rpc, data, buflen);
return 1;
}
static enum nss_status
_nss_create_tablename (void)
{
if (tablename_val == NULL)
{
char buf [40 + strlen (nis_local_directory ())];
char *p;
p = stpcpy (buf, "rpc.org_dir.");
p = stpcpy (p, nis_local_directory ());
tablename_val = strdup (buf);
if (tablename_val == NULL)
return NSS_STATUS_TRYAGAIN;
tablename_len = strlen (tablename_val);
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_setrpcent (void)
{
enum nss_status status = NSS_STATUS_SUCCESS;
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
if (tablename_val == NULL)
status = _nss_create_tablename ();
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
return status;
}
enum nss_status
@ -133,11 +183,6 @@ _nss_nisplus_endrpcent (void)
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
@ -155,11 +200,11 @@ internal_nisplus_getrpcent_r (struct rpcent *rpc, char *buffer,
{
if (result == NULL)
{
names = nis_getnames ("rpc.org_dir");
if (names == NULL || names[0] == NULL)
return NSS_STATUS_UNAVAIL;
if (tablename_val == NULL)
if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
result = nis_first_entry(names[0]);
result = nis_first_entry(tablename_val);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
return niserr2nss (result->status);
}
@ -167,7 +212,7 @@ internal_nisplus_getrpcent_r (struct rpcent *rpc, char *buffer,
{
nis_result *res;
res = nis_next_entry (names[0], &result->cookie);
res = nis_next_entry (tablename_val, &result->cookie);
nis_freeresult (result);
result = res;
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
@ -201,32 +246,37 @@ _nss_nisplus_getrpcbyname_r (const char *name, struct rpcent *rpc,
{
int parse_res;
if (tablename_val == NULL)
if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
if (name == NULL)
return NSS_STATUS_NOTFOUND;
else
{
nis_result *result;
char buf[strlen (name) + 255];
char buf[strlen (name) + 255 + tablename_len];
/* 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);
sprintf (buf, "[name=%s],%s", name, tablename_val);
result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, 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,
__type_of (result->objects.objects_val) != ENTRY_OBJ ||
strcmp (result->objects.objects_val->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);
result->objects.objects_val->EN_data.en_cols.en_cols_len < 3)
sprintf (buf, "[cname=%s],%s", name, tablename_val);
else
sprintf (buf, "[cname=%s],rpc.org_dir", NISENTRYVAL(0, 0, result));
sprintf (buf, "[cname=%s],%s", NISENTRYVAL(0, 0, result),
tablename_val);
nis_freeresult (result);
result = nis_list(buf, EXPAND_NAME, NULL, NULL);
result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS , NULL, NULL);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
@ -254,31 +304,37 @@ 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];
if (tablename_val == NULL)
if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
snprintf (buf, sizeof (buf), "[number=%d],rpc.org_dir", number);
{
int parse_res;
nis_result *result;
char buf[100 + tablename_len];
result = nis_list(buf, EXPAND_NAME, NULL, NULL);
snprintf (buf, sizeof (buf), "[number=%d],%s", number, tablename_val);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
enum nss_status status = niserr2nss (result->status);
result = nis_list(buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
nis_freeresult (result);
return status;
}
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
enum nss_status status = niserr2nss (result->status);
parse_res = _nss_nisplus_parse_rpcent (result, rpc, buffer, buflen);
nis_freeresult (result);
return status;
}
nis_freeresult (result);
parse_res = _nss_nisplus_parse_rpcent (result, rpc, buffer, buflen);
if (parse_res)
return NSS_STATUS_SUCCESS;
nis_freeresult (result);
if (!parse_res && errno == ERANGE)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
if (parse_res)
return NSS_STATUS_SUCCESS;
if (!parse_res && errno == ERANGE)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
}

View File

@ -31,107 +31,154 @@
__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);
)
static nis_name tablename_val = NULL;
static u_long tablename_len = 0;
#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)
((res)->objects.objects_val[(idx)].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)
((res)->objects.objects_val[(idx)].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;
char *first_unused = buffer;
size_t room_left = buflen;
unsigned int i;
struct parser_data *data = (void *) buffer;
char *p, *line;
if (result == NULL)
return 0;
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)
__type_of (result->objects.objects_val) != ENTRY_OBJ ||
strcmp (result->objects.objects_val->EN_data.en_type,
"services_tbl") != 0 ||
result->objects.objects_val->EN_data.en_cols.en_cols_len < 4)
return 0;
memset (p, '\0', room_left);
/* Generate the services entry format and use the normal parser */
if (NISENTRYLEN (0, 0, result) + 1 > room_left)
if (NISENTRYLEN (0, 0, result) >= room_left)
{
no_more_room:
__set_errno (ERANGE);
return 0;
}
strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
room_left -= (NISENTRYLEN (0, 0, result) + 1);
strncpy (first_unused, NISENTRYVAL (0, 0, result),
NISENTRYLEN (0, 0, result));
first_unused[NISENTRYLEN (0, 0, result)] = '\0';
serv->s_name = first_unused;
room_left -= (strlen (first_unused) +1);
first_unused += strlen (first_unused) +1;
if (NISENTRYLEN (0, 3, result) + 1 > room_left)
{
__set_errno (ERANGE);
return 0;
}
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 0;
}
strcat (p, "/");
strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result));
room_left -= (NISENTRYLEN (0, 2, result) + 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';
serv->s_proto = first_unused;
room_left -= (strlen (first_unused) +1);
first_unused += strlen (first_unused) +1;
for (i = 1; i < result->objects.objects_len; i++)
serv->s_port = atoi (NISENTRYVAL (0, 3, result));
p = first_unused;
line = p;
for (i = 0; i < result->objects.objects_len; i++)
{
if (NISENTRYLEN (i, 1, result) + 1 > room_left)
{
__set_errno (ERANGE);
return 0;
if (strcmp (NISENTRYVAL (i, 1, result), serv->s_name) != 0)
{
if (NISENTRYLEN (i, 1, result) + 2 > room_left)
goto no_more_room;
p = stpcpy(p, " ");
p = stpncpy (p, NISENTRYVAL (i, 1, result),
NISENTRYLEN (i, 1, result));
*p = '\0';
room_left -= (NISENTRYLEN (i, 1, result) + 1);
}
}
++p;
first_unused = p;
/* Adjust the pointer so it is aligned for
storing pointers. */
first_unused += __alignof__ (char *) - 1;
first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *));
serv->s_aliases = (char **) first_unused;
if (room_left < sizeof (char *))
goto no_more_room;
room_left -= (sizeof (char *));
serv->s_aliases[0] = NULL;
i = 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 *);
serv->s_aliases[i] = line;
while (*line != '\0' && *line != ' ')
++line;
if (*line == ' ')
{
*line = '\0';
++line;
++i;
}
strcat (p, " ");
strcat (p, NISENTRYVAL (i, 1, result));
room_left -= (NISENTRYLEN (i, 1, result) + 1);
else
serv->s_aliases[i+1] = NULL;
}
return _nss_files_parse_servent (p, serv, data, buflen);
return 1;
}
static enum nss_status
_nss_create_tablename (void)
{
if (tablename_val == NULL)
{
char buf [40 + strlen (nis_local_directory ())];
char *p;
p = stpcpy (buf, "services.org_dir.");
p = stpcpy (p, nis_local_directory ());
tablename_val = strdup (buf);
if (tablename_val == NULL)
return NSS_STATUS_TRYAGAIN;
tablename_len = strlen (tablename_val);
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_setservent (void)
{
enum nss_status status = NSS_STATUS_SUCCESS;
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
if (tablename_val == NULL)
status = _nss_create_tablename ();
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
return status;
}
enum nss_status
@ -142,11 +189,6 @@ _nss_nisplus_endservent (void)
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
@ -164,11 +206,11 @@ internal_nisplus_getservent_r (struct servent *serv, char *buffer,
{
if (result == NULL)
{
names = nis_getnames ("services.org_dir");
if (names == NULL || names[0] == NULL)
return NSS_STATUS_UNAVAIL;
if (tablename_val == NULL)
if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
result = nis_first_entry (names[0]);
result = nis_first_entry (tablename_val);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
return niserr2nss (result->status);
}
@ -176,7 +218,7 @@ internal_nisplus_getservent_r (struct servent *serv, char *buffer,
{
nis_result *res;
res = nis_next_entry (names[0], &result->cookie);
res = nis_next_entry (tablename_val, &result->cookie);
nis_freeresult (result);
result = res;
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
@ -212,6 +254,10 @@ _nss_nisplus_getservbyname_r (const char *name, const char *protocol,
{
int parse_res;
if (tablename_val == NULL)
if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
if (name == NULL || protocol == NULL)
{
__set_errno (EINVAL);
@ -220,29 +266,30 @@ _nss_nisplus_getservbyname_r (const char *name, const char *protocol,
else
{
nis_result *result;
char buf[strlen (name) + 255];
char buf[strlen (name) + 255 + tablename_len];
/* 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);
sprintf (buf, "[name=%s,proto=%s],%s", name, protocol,
tablename_val);
result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, 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,
__type_of (result->objects.objects_val) != ENTRY_OBJ ||
strcmp (result->objects.objects_val->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);
result->objects.objects_val->EN_data.en_cols.en_cols_len < 4)
sprintf (buf, "[cname=%s,proto=%s],%s", name, protocol,
tablename_val);
else
sprintf (buf, "[cname=%s,proto=%s],services.org_dir",
NISENTRYVAL (0, 0, result), protocol);
sprintf (buf, "[cname=%s,proto=%s],%s",
NISENTRYVAL (0, 0, result), protocol, tablename_val);
nis_freeresult (result);
result = nis_list (buf, EXPAND_NAME, NULL, NULL);
result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
@ -271,38 +318,44 @@ _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 (tablename_val == NULL)
if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
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)
else
{
enum nss_status status = niserr2nss (result->status);
int parse_res;
nis_result *result;
char buf[60 + strlen (protocol) + tablename_len];
snprintf (buf, sizeof (buf), "[number=%d,proto=%s],%s",
number, protocol, tablename_val);
result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, 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);
return status;
if (parse_res)
return NSS_STATUS_SUCCESS;
if (!parse_res && errno == ERANGE)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
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;
}

View File

@ -26,132 +26,45 @@
#include <rpcsvc/nislib.h>
#include "nss-nisplus.h"
#include "nisplus-parser.h"
__libc_lock_define_initialized (static, lock)
static nis_result *result = NULL;
static nis_name *names = NULL;
static nis_name tablename_val = NULL;
static u_long tablename_len = 0;
#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)
int
_nss_nisplus_parse_spent (nis_result *result, struct spwd *sp,
char *buffer, size_t buflen)
static enum nss_status
_nss_create_tablename (void)
{
char *first_unused = buffer;
size_t room_left = buflen;
if (result == NULL)
return 0;
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 0;
if (NISENTRYLEN(0, 0, result) >= room_left)
if (tablename_val == NULL)
{
/* The line is too long for our buffer. */
no_more_room:
__set_errno (ERANGE);
return 0;
char buf [40 + strlen (nis_local_directory ())];
char *p;
p = stpcpy (buf, "passwd.org_dir.");
p = stpcpy (p, nis_local_directory ());
tablename_val = strdup (buf);
if (tablename_val == NULL)
return NSS_STATUS_TRYAGAIN;
tablename_len = strlen (tablename_val);
}
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;
if (NISENTRYVAL (0, 7, result) != NULL)
{
char *line, *cp;
line = NISENTRYVAL (0, 7, result);
cp = strchr (line, ':');
if (cp == NULL)
return 0;
*cp++ = '\0';
sp->sp_lstchg = atol (line);
line = cp;
cp = strchr (line, ':');
if (cp == NULL)
return 0;
*cp++ = '\0';
sp->sp_min = atol(line);
line = cp;
cp = strchr (line, ':');
if (cp == NULL)
return 0;
*cp++ = '\0';
sp->sp_max = atol(line);
line = cp;
cp = strchr (line, ':');
if (cp == NULL)
return 0;
*cp++ = '\0';
sp->sp_warn = atol(line);
line = cp;
cp = strchr (line, ':');
if (cp == NULL)
return 0;
*cp++ = '\0';
sp->sp_inact = atol(line);
line = cp;
cp = strchr (line, ':');
if (cp == NULL)
return 0;
*cp++ = '\0';
sp->sp_expire = atol(line);
line = cp;
if (line == NULL)
return 0;
sp->sp_flag = atol(line);
}
return 1;
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_setspent (void)
{
enum nss_status status = NSS_STATUS_SUCCESS;
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
if (tablename_val == NULL)
status = _nss_create_tablename ();
__libc_lock_unlock (lock);
@ -166,11 +79,6 @@ _nss_nisplus_endspent (void)
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
@ -187,11 +95,11 @@ internal_nisplus_getspent_r (struct spwd *sp, char *buffer, size_t buflen)
{
if (result == NULL)
{
names = nis_getnames ("passwd.org_dir");
if (names == NULL || names[0] == NULL)
return NSS_STATUS_UNAVAIL;
if (tablename_val == NULL)
if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
result = nis_first_entry (names[0]);
result = nis_first_entry (tablename_val);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
return niserr2nss (result->status);
}
@ -199,7 +107,7 @@ internal_nisplus_getspent_r (struct spwd *sp, char *buffer, size_t buflen)
{
nis_result *res;
res = nis_next_entry (names[0], &result->cookie);
res = nis_next_entry (tablename_val, &result->cookie);
nis_freeresult (result);
result = res;
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
@ -232,16 +140,20 @@ _nss_nisplus_getspnam_r (const char *name, struct spwd *sp,
{
int parse_res;
if (tablename_val == NULL)
if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
if (name == NULL || strlen (name) > 8)
return NSS_STATUS_NOTFOUND;
else
{
nis_result *result;
char buf[strlen (name) + 24];
char buf[strlen (name) + 24 + tablename_len];
sprintf (buf, "[name=%s],passwd.org_dir", name);
sprintf (buf, "[name=%s],%s", name, tablename_val);
result = nis_list (buf, EXPAND_NAME, NULL, NULL);
result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{

47
nis/rpcsvc/nis_cache.h Normal file
View File

@ -0,0 +1,47 @@
#ifndef __RPCSVC_NIS_CACHE_H_
#define __RPCSVC_NIS_CACHE_H_
#include <features.h>
#include <rpc/rpc.h>
#include <rpc/types.h>
#include <rpcsvc/nis.h>
__BEGIN_DECLS
/* default cache file */
#define CACHEFILE "/var/nis/NIS_SHARED_DIRCACHE"
/* clients have to read-lock the cache file, and SVR4 locking requires that */
/* the file be writable, but we don't want a world-writable cache file. */
/* So... everyone agrees to use a different, world-writable file for the */
/* locking operations, but the data is in CACHEFILE. */
#define CACHELOCK "/usr/tmp/.NIS_DIR_CACHELOCK"
/* the file containing one trusted XDR'ed directory object.
* This has to be present for the system to work.
*/
#define COLD_START_FILE "/var/nis/NIS_COLD_START"
enum pc_status {HIT, MISS, NEAR_MISS};
#define CACHEPROG ((u_long)100301)
#define CACHE_VER_1 ((u_long)1)
#define NIS_CACHE_ADD_ENTRY ((u_long)1)
#define NIS_CACHE_REMOVE_ENTRY ((u_long)2)
#define NIS_CACHE_READ_COLDSTART ((u_long)3)
#define NIS_CACHE_REFRESH_ENTRY ((u_long)4)
extern void *nis_cache_add_entry_1 __P ((fd_result *, CLIENT *));
extern void *nis_cache_add_entry_1_svc __P ((fd_result *, struct svc_req *));
extern void *nis_cache_remove_entry_1 __P ((directory_obj *, CLIENT *));
extern void *nis_cache_remove_entry_1_svc __P ((directory_obj *,
struct svc_req *));
extern void *nis_cache_read_coldstart_1 __P ((void *, CLIENT *));
extern void *nis_cache_read_coldstart_1_svc __P ((void *, struct svc_req *));
extern void *nis_cache_refresh_entry_1 __P ((char **, CLIENT *));
extern void *nis_cache_refresh_entry_1_svc __P ((char **, struct svc_req *));
__END_DECLS
#endif /* !_RPCSVC_NIS_CACHE_H_ */

47
nis/rpcsvc/nis_cache.x Normal file
View File

@ -0,0 +1,47 @@
/*
* nis_cache.x
*
* Copyright (c) 1988-1992 Sun Microsystems Inc
* All Rights Reserved.
*/
%#pragma ident "@(#)nis_cache.x 1.8 92/07/14 SMI"
#ifdef RPC_HDR
%#include <rpc/types.h>
%#include <rpcsvc/nis.h>
%
%/* default cache file */
%#define CACHEFILE "/var/nis/NIS_SHARED_DIRCACHE"
%
%/* clients have to read-lock the cache file, and SVR4 locking requires that */
%/* the file be writable, but we don't want a world-writable cache file. */
%/* So... everyone agrees to use a different, world-writable file for the */
%/* locking operations, but the data is in CACHEFILE. */
%#define CACHELOCK "/usr/tmp/.NIS_DIR_CACHELOCK"
%
%/* the file containing one trusted XDR'ed directory object.
% * This has to be present for the system to work.
% */
%#define COLD_START_FILE "/var/nis/NIS_COLD_START"
%
%enum pc_status {HIT, MISS, NEAR_MISS};
%
%extern int __nis_debuglevel;
%
%
#endif
#ifdef RPC_CLNT
%#include "../gen/nis_clnt.h"
#endif
program CACHEPROG {
version CACHE_VER_1 {
void NIS_CACHE_ADD_ENTRY(fd_result) = 1;
void NIS_CACHE_REMOVE_ENTRY(directory_obj) = 2;
void NIS_CACHE_READ_COLDSTART(void) = 3;
void NIS_CACHE_REFRESH_ENTRY(string<>) = 4;
} = 1;
} = 100301;

View File

@ -254,10 +254,14 @@ extern nis_name __nis_default_owner __P ((char *));
extern nis_name __nis_default_group __P ((char *));
extern u_long __nis_default_ttl __P ((char *));
extern u_long __nis_default_access __P ((char *, u_long));
extern fd_result *__nis_finddirectory __P ((directory_obj *, nis_name));
extern fd_result *__nis_finddirectory __P ((directory_obj *, const_nis_name));
extern u_long __nis_hash __P ((const void *keyarg, register size_t len));
extern log_result *__nis_dumplog __P ((nis_server *,nis_name, u_long));
extern log_result *__nis_dump __P ((nis_server *, nis_name,
int (*)(nis_name, nis_object *, void *)));
/* NIS+ cache locking */
extern int __nis_lock_cache __P ((void));
extern int __nis_unlock_cache __P ((void));
__END_DECLS

View File

@ -116,6 +116,7 @@ execvp (file, argv)
that we did find one but were denied access. */
got_eacces = 1;
case ENOENT:
case ESTALE:
/* Those errors indicate the file is missing or not executable
by us, in which case we want to just try the next path
directory. */

View File

@ -128,15 +128,15 @@ char *realloc ();
#define SWITCH_ENUM_CAST(x) (x)
#endif
/* How many characters in the character set. */
#define CHAR_SET_SIZE 256
#ifdef SYNTAX_TABLE
extern char *re_syntax_table;
#else /* not SYNTAX_TABLE */
/* How many characters in the character set. */
#define CHAR_SET_SIZE 256
static char re_syntax_table[CHAR_SET_SIZE];
static void

View File

@ -18,6 +18,8 @@
#include <errno.h>
#include <signal.h>
#define __need_NULL
#include <stddef.h>
/* Combine sets LEFT and RIGHT by logical AND and place result in DEST. */
int

View File

@ -18,6 +18,8 @@
#include <errno.h>
#include <signal.h>
#define __need_NULL
#include <stddef.h>
/* Test whether SET is empty. */
int

View File

@ -18,6 +18,8 @@
#include <errno.h>
#include <signal.h>
#define __need_NULL
#include <stddef.h>
/* Combine sets LEFT and RIGHT by logical OR and place result in DEST. */
int

View File

@ -23,10 +23,7 @@
string FORMAT, writing no more than MAXLEN characters. */
/* VARARGS3 */
int
__snprintf (s, maxlen, format)
char *s;
size_t maxlen;
const char *format;
__snprintf (char *s, size_t maxlen, const char *format, ...)
{
va_list arg;
int done;

View File

@ -1,27 +0,0 @@
#ifdef __STDC__
#define FUNC__(name) \
.align 3; \
.globl __##name; \
.ent __##name; \
__##name: \
lda sp, -16(sp); \
.frame sp, 16, t9, 0; \
.prologue 0
#else
#define FUNC__(name) \
.align 3; \
.globl __/**/name; \
.ent __/**/name,0; \
__/**/name: \
lda sp, -16(sp); \
.frame sp, 16, t9, 0; \
.prologue 0
#endif
#ifdef __STDC__
#define NAME__(name) \
__##name
#else
#define NAME__(name) \
__/**/name
#endif

View File

@ -1,5 +1,4 @@
setjmp_aux.c
DEFS.h
divrem.h
divl.S divq.S reml.S remq.S
_mcount.S

1
sysdeps/i370/Implies Normal file
View File

@ -0,0 +1 @@
wordsize-32

View File

@ -1,5 +1,5 @@
/* FPU control word bits. i387 version.
Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc.
Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Olaf Flebbe.
@ -82,7 +82,7 @@
#define _FPU_DEFAULT 0x137f
/* IEEE: same as above, but exceptions */
/* IEEE: same as above. */
#define _FPU_IEEE 0x137f
/* Type of the control word. */

View File

@ -32,7 +32,7 @@ feholdexcept (fenv_t *envp)
fpsr = envp->status_register & ~FE_ALL_EXCEPT;
__asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr));
/* And set all exceptions to non-stop. */
fpcr = envp->control_register & ~(FE_ALL_EXCEPT << 5);
fpcr = envp->control_register & ~(FE_ALL_EXCEPT << 6);
__asm__ __volatile__ ("fmove%.l %0,%!" : : "dm" (fpcr));
return 1;

View File

@ -32,15 +32,15 @@ fesetenv (const fenv_t *envp)
__asm__ ("fmovem%.l %/fpcr/%/fpsr,%0" : "=m" (*&temp));
temp.status_register &= ~FE_ALL_EXCEPT;
temp.control_register &= ~((FE_ALL_EXCEPT << 5) | FE_UPWARD);
temp.control_register &= ~((FE_ALL_EXCEPT << 6) | FE_UPWARD);
if (envp == FE_DFL_ENV)
;
else if (envp == FE_NOMASK_ENV)
temp.control_register |= FE_ALL_EXCEPT << 5;
temp.control_register |= FE_ALL_EXCEPT << 6;
else
{
temp.control_register |= (envp->control_register
& ((FE_ALL_EXCEPT << 5) | FE_UPWARD));
& ((FE_ALL_EXCEPT << 6) | FE_UPWARD));
temp.status_register |= envp->status_register & FE_ALL_EXCEPT;
}

View File

@ -223,7 +223,7 @@ __select (nfds, readfds, writefds, exceptfds, timeout)
/* We got a message. Decode it. */
#define IO_SELECT_REPLY_MSGID (21012 + 100) /* XXX */
const mach_msg_type_t inttype =
{ MACH_MSG_TYPE_INTEGER_T, sizeof (MACH_MSG_TYPE_INTEGER_T),
{ MACH_MSG_TYPE_INTEGER_T, sizeof (MACH_MSG_TYPE_INTEGER_T) * 8,
1, 1, 0, 0 };
if (msg.head.msgh_id == IO_SELECT_REPLY_MSGID &&
msg.head.msgh_size >= sizeof msg.error &&

1
sysdeps/mvs/Implies Normal file
View File

@ -0,0 +1 @@
posix

View File

@ -1,12 +0,0 @@
#ifdef HAVE_ELF
# define FUNC(name) \
.global name; \
.type name,@function; \
.align 4; \
name:
#else
# define FUNC(name) \
.global name; \
.align 4; \
name:
#endif

View File

@ -1,5 +1,3 @@
DEFS.h
elf/DEFS.h
dotmul.S umul.S
divrem.m4 sdiv.S udiv.S rem.S urem.S
alloca.S

View File

@ -16,7 +16,7 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "DEFS.h"
#include "sysdep.h"
/* Code produced by Sun's C compiler calls this function with two extra
arguments which it makes relocatable symbols but seem always to be
@ -26,7 +26,7 @@
#define __builtin_alloca ___builtin_alloca
#endif
FUNC (__builtin_alloca)
ENTRY (__builtin_alloca)
sub %sp, %o0, %sp /* Push some stack space. */
retl /* Return; the returned buffer leaves 96 */
add %sp, 96, %o0 /* bytes of register save area at the top. */

View File

@ -82,7 +82,7 @@ L.$1.eval(2**N+$2):
', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2-1)')')
ifelse($1, 1, `9:')')dnl
#include "DEFS.h"
#include "sysdep.h"
#ifdef __linux__
#include <asm/traps.h>
#else

View File

@ -10,8 +10,8 @@
* This code optimizes short (less than 13-bit) multiplies.
*/
#include "DEFS.h"
FUNC(.mul)
#include "sysdep.h"
ENTRY(.mul)
mov %o0, %y ! multiplier -> Y
andncc %o0, 0xfff, %g0 ! test bits 12..31
be Lmul_shortway ! if zero, can do it the short way

View File

@ -1,5 +0,0 @@
#define FUNC(name) \
.global name; \
.type name,@function; \
.align 4; \
name:

View File

@ -37,10 +37,18 @@
#include "DEFS.h"
#include "sysdep.h"
#ifdef __linux__
#include <asm/traps.h>
#else
#ifdef __svr4__
#include <sys/trap.h>
#else
#include <machine/trap.h>
#endif
#endif
FUNC(.rem)
ENTRY(.rem)
! compute sign of result; if neither is negative, no problem
orcc %o1, %o0, %g0 ! either negative?
bge 2f ! no, go do the divide

View File

@ -37,10 +37,18 @@
#include "DEFS.h"
#include "sysdep.h"
#ifdef __linux__
#include <asm/traps.h>
#else
#ifdef __svr4__
#include <sys/trap.h>
#else
#include <machine/trap.h>
#endif
#endif
FUNC(.div)
ENTRY(.div)
! compute sign of result; if neither is negative, no problem
orcc %o1, %o0, %g0 ! either negative?
bge 2f ! no, go do the divide

View File

@ -37,10 +37,18 @@
#include "DEFS.h"
#include "sysdep.h"
#ifdef __linux__
#include <asm/traps.h>
#else
#ifdef __svr4__
#include <sys/trap.h>
#else
#include <machine/trap.h>
#endif
#endif
FUNC(.udiv)
ENTRY(.udiv)
! Ready to divide. Compute size of quotient; scale comparand.
orcc %o1, %g0, %o5

View File

@ -26,7 +26,7 @@
! n1 i1
! n0 i2
! d i3
#include "DEFS.h"
#include "sysdep.h"
#undef ret /* Kludge for glibc */
@ -38,7 +38,7 @@ LC1: .double 0r2147483648
.align 4
.global __udiv_qrnnd
.type __udiv_qrnnd,@function
FUNC(__udiv_qrnnd)
ENTRY(__udiv_qrnnd)
!#PROLOGUE# 0
save %sp,-104,%sp
!#PROLOGUE# 1

View File

@ -37,10 +37,18 @@
#include "DEFS.h"
#include "sysdep.h"
#ifdef __linux__
#include <asm/traps.h>
#else
#ifdef __svr4__
#include <sys/trap.h>
#else
#include <machine/trap.h>
#endif
#endif
FUNC(.urem)
ENTRY(.urem)
! Ready to divide. Compute size of quotient; scale comparand.
orcc %o1, %g0, %o5

View File

@ -84,10 +84,10 @@
typedef int __libc_key_t;
/* Create key for thread specific data. */
#define __libc_key_create(KEY,DEST)
#define __libc_key_create(KEY,DEST) -1
/* Set thread-specific data associated with KEY to VAL. */
#define __libc_setspecific(KEY,VAL)
#define __libc_setspecific(KEY,VAL) -1
/* Get thread-specific data associated with KEY. */
#define __libc_getspecific(KEY) 0

View File

@ -16,21 +16,28 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
unsigned int if_nametoindex(const char *ifname)
#define __need_NULL
#include <stddef.h>
unsigned int
if_nametoindex (const char *ifname)
{
return 0;
}
char *if_indextoname(unsigned int ifindex, char *ifname)
char *
if_indextoname (unsigned int ifindex, char *ifname)
{
return NULL;
}
void if_freenameindex(struct if_nameindex *ifn)
void
if_freenameindex (struct if_nameindex *ifn)
{
}
struct if_nameindex *if_nameindex(void)
struct if_nameindex *
if_nameindex (void)
{
return NULL;
}

View File

@ -27,19 +27,29 @@
#define syscall_error C_SYMBOL_NAME(__syscall_error)
#endif
#define ENTRY(name) \
.global C_SYMBOL_NAME(name); \
.align 2; \
#ifdef HAVE_ELF
#define ENTRY(name) \
.global C_SYMBOL_NAME(name); \
.type name,@function; \
.align 4; \
C_LABEL(name)
#define PSEUDO(name, syscall_name, args) \
.global syscall_error; \
ENTRY (name) \
mov SYS_ify(syscall_name), %g1; \
ta 0; \
bcc 1f; \
sethi %hi(syscall_error), %g1; \
jmp %g1 + %lo(syscall_error); nop; \
#else
#define ENTRY(name) \
.global C_SYMBOL_NAME(name); \
.align 4; \
C_LABEL(name)
#endif /* HAVE_ELF */
#define PSEUDO(name, syscall_name, args) \
.global syscall_error; \
ENTRY (name) \
mov SYS_ify(syscall_name), %g1; \
ta 0; \
bcc 1f; \
sethi %hi(syscall_error), %g1; \
jmp %g1 + %lo(syscall_error); nop; \
1:
#define ret retl; nop

View File

@ -172,11 +172,15 @@ localtime_r (t, tp)
#endif /* ! defined (_LIBC) */
#if !defined (memset) && !defined (HAVE_MEMSET) && !defined (_LIBC)
#if !defined memset && !defined HAVE_MEMSET && !defined _LIBC
/* Some systems lack the `memset' function and we don't want to
introduce additional dependencies. */
static const char spaces[16] = " ";
static const char zeroes[16] = "0000000000000000";
/* The SGI compiler reportedly barfs on the trailing null
if we use a string constant as the initializer. 28 June 1997, rms. */
static const char spaces[16] = /* " " */
{ ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' };
static const char zeroes[16] = /* "0000000000000000" */
{ '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0' };
# define memset_space(P, Len) \
do { \

View File

@ -20,6 +20,7 @@
#define __need_wchar_t
#include <stddef.h>
#include <locale.h>
#define USE_IN_EXTENDED_LOCALE_MODEL 1

View File

@ -20,6 +20,7 @@
#define __need_wchar_t
#include <stddef.h>
#include <locale.h>
#define USE_IN_EXTENDED_LOCALE_MODEL 1

View File

@ -20,6 +20,7 @@
#define __need_wchar_t
#include <stddef.h>
#include <locale.h>
#define USE_IN_EXTENDED_LOCALE_MODEL 1

View File

@ -20,6 +20,7 @@
#define __need_wchar_t
#include <stddef.h>
#include <locale.h>
#define USE_IN_EXTENDED_LOCALE_MODEL 1

View File

@ -20,6 +20,7 @@
#define __need_wchar_t
#include <stddef.h>
#include <locale.h>
#define USE_IN_EXTENDED_LOCALE_MODEL 1

View File

@ -20,6 +20,7 @@
#define __need_wchar_t
#include <stddef.h>
#include <locale.h>
#define USE_IN_EXTENDED_LOCALE_MODEL 1

View File

@ -20,6 +20,7 @@
#define __need_wchar_t
#include <stddef.h>
#include <locale.h>
#define USE_IN_EXTENDED_LOCALE_MODEL 1