1997-03-19 01:40  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/unix/sysv/sco3.2.4/Dist: New file.

	* sysdeps/unix/sysv/sysv4/Dist: Add __getpgid.c and __setpgid.c.

	* sysdeps/unix/bsd/Dist: Add bsdstat.h, setrgid.c, and setruid.c.

	* sysdeps/unix/sysv/Dist: Add direct.h.

	* sysdeps/unix/sysv/linux/Dist: Add netinet/tcp.h.

	* Make-dist ($(tardir).tar): Prefer writing temporary file to
	$TMPDIR is available.  The default is /tmp.

	* sysdeps/generic/ip.h: Move to...
	* sysdeps/generic/netinet/ip.h: ...here.

	* Makefile (tests): Quote $(CC) argument to isomac program.
	Patch by H.J. Lu <hjl@gnu.ai.mit.edu>.

	* sysdeps/i386/setjmp.S (__setjmp): Fix fatal bug where 0 argument
	is placed in wrong place on the stack.
	Reported by Marc Lehmann <mlehmann@hildesheim.sgh-net.de>.
	* sysdeps/tst-setjmp.c: Add new test for above problem.

	* sysdeps/libm-i387/e_pow.S: Compute PIC addres early.
	* sysdeps/libm-i387/e_powf.S: Likewise.
	* sysdeps/libm-i387/e_powl.S: Likewise.

1997-03-18 23:18  Ulrich Drepper  <drepper@cygnus.com>

	* time/offtime.c (__offtime): Change type of `yg' to long int.
	Reported by a sun <asun@zoology.washington.edu>.

1997-03-18 23:08  a sun  <asun@zoology.washington.edu>

	* sysdeps/unix/sysv/linux/net/if_ppp.h (PPP_VERSION): Define to
	2.2.0 to prevent version mismatch.

1997-03-17 19:26  Andreas Jaeger  <aj@arthur.pfalz.de>

	* stdio-common/printf_fphex.c (MIN): Only define MIN if not
	already defined.

1997-03-14 23:34  Geoff Keating  <geoffk@ozemail.com.au>

	* sysdeps/unix/sysv/linux/powerpc/termbits.h: Leave ioctl numbers
	in ioctls.h.

	* elf/rtld.c (_dl_start): Call elf_machine_runtime_setup when the
	loader first relocates itself.
	* sysdeps/powerpc/elf/start.c (__start1): Fix bug for static objects.
	* sysdeps/powerpc/dl-machine.h (elf_machine_rela): Fix bugs in
	jump slot relocation. Prefer relative branches (some PowerPC chips
	don't predict absolute branches).
	(elf_machine_runtime_setup): Simplify and correct expressions.
	(RTLD_START): Fix bug changing _dl_starting_up.
	* sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c: Added. Deal with
	strange Linux/PPC padding of initial stack.

1997-03-11 04:14  Geoff Keating  <geoffk@ozemail.com.au>

	* sysdeps/unix/sysv/linux/powerpc/termbits.h: Increase NCCS to 39,
	for future expansion.
	* sysdeps/unix/sysv/linux/powerpc/sys/kernel_termios.h: Added.
	* sysdeps/powerpc/dl-machine.h (elf_machine_rela): Explain why it
	can't have a switch statement.
	* sysdeps/powerpc/elf/start.c (__start1): Explain why it can't be
	static.

	* sysdeps/powerpc/elf/start.c (_start): Use .previous to avoid
	confusing gcc's idea of the current section.
	* sysdeps/powerpc/dl-machine.h (ELF_MACHINE_RUNTIME_TRAMPOLINE,
	RTLD_START): Likewise.

1997-03-08 09:10  Geoff Keating  <geoffk@ozemail.com.au>

	* sysdeps/powerpc/dl-machine.h (elf_machine_rela,
	elf_machine_runtime_setup): Flush data & instruction caches when
	necessary, for 603/604 support. Add better support for large PLTs.
	(elf_machine_rela): Remove relocations that wouldn't work if
	anyone ever used them. Use memcpy for copy reloc, it'll be safe.
	Never target branch relocations at a PLT entry.

	* sysdeps/powerpc/bsd-setjmp.S: Make jump to PLT entry if we are
	generating PIC.
	* sysdeps/powerpc/bsd-_setjmp.S: Likewise.
	* sysdeps/powerpc/setjmp.S: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/clone.S: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/socket.S: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/syscall.S: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/sysdep.h: Likewise.

	* sysdeps/powerpc/elf/start.c: Clean up.

	* sysdeps/powerpc/__longjmp.S: Return 'value' as result from
	setjmp call.

	* sysdeps/unix/sysv/linux/powerpc/statbuf.h: New file.

1997-03-09 12:36  H.J. Lu  <hjl@gnu.ai.mit.edu>

	* Make-dist (srcs): Add $(test-srcs).
	* MakeTAGS (all-sources): Likewise.
	* Makerules (depfiles, common-mostlyclean): Likewise.
	* Rules (tests): Likewise.

1997-03-18 05:28  Roland McGrath  <roland@frob.com>

	* elf/dl-reloc.c (RESOLVE): Don't try to resolve ocal symbols.

1997-03-17 21:39  Philip Blundell  <phil@london.uk.eu.org>

	* nis/nss_nis/nis-service.c (_nss_nis_getservbyname_r): Allow
	protocol=NULL to match any protocol rather than returning an
	error.

1997-03-17 19:00  Philip Blundell  <phil@london.uk.eu.org>

	* nss/nss_files/files-service.c (servbyname): Match any protocol
	if proto==NULL.

1997-03-18 05:17  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/unix/sysv/linux/alpha/fcntlbits.h: Don't define O_NORW.
	* sysdeps/unix/sysv/linux/fcntlbits.h: Likewise.
	Proposed by Thomas Bushnell, n/BSG.

1997-03-18 07:53  H.J. Lu  <hjl@gnu.ai.mit.edu>

	* sysdeps/generic/setenv.c (setenv): Don't copy name when we reuse
	the buffer for replacement.

1997-03-16 19:30  H.J. Lu  <hjl@gnu.ai.mit.edu>

	* sysdeps/unix/sysv/linux/syscalls.list: Add sys_fstat,
	sys_lstat and sys_stat.

1997-03-17 12:43  Thorsten Kukuk  <kukuk@vt.uni-paderborn.de>

	Add NIS+ functions
	* shlib-versions: Add libnss_nisplus.
	* nis/Makefile: Add NIS+ source files.
	* nis/nis_call.c: New file.
	* nis/nis_clone.c: New file.
	* nis/nis_error.c: New file.
	* nis/nis_file.c: New file.
	* nis/nis_free.c: New file.
	* nis/nis_intern.c: New file.
	* nis/nis_intern.h: New file.
	* nis/nis_local_names.c: New file.
	* nis/nis_names.c: New file.
	* nis/nis_print.c: New file.
	* nis/nis_server.c: New file.
	* nis/nis_subr.c: New file.
	* nis/nis_table.c: New file.
	* nis/nis_xdr.c: New file.
	* nis/nss-nisplus.h: New file.
	* nis/nss_nisplus/nisplus-alias.c: New file.
	* nis/nss_nisplus/nisplus-ethers.c: New file.
	* nis/nss_nisplus/nisplus-grp.c: New file.
	* nis/nss_nisplus/nisplus-hosts.c: New file.
	* nis/nss_nisplus/nisplus-netgrp.c: New file.
	* nis/nss_nisplus/nisplus-network.c: New file.
	* nis/nss_nisplus/nisplus-proto.c: New file.
	* nis/nss_nisplus/nisplus-publickey.c: New file.
	* nis/nss_nisplus/nisplus-pwd.c: New file.
	* nis/nss_nisplus/nisplus-rpc.c: New file.
	* nis/nss_nisplus/nisplus-service.c: New file.
	* nis/nss_nisplus/nisplus-spwd.c: New file.
	* nis/rpcsvc/nis.h: New file.
	* nis/rpcsvc/nis.x: New file.
	* nis/rpcsvc/nis_object.x: New file.
	* nis/rpcsvc/nis_tags.h: New file.
	* nis/rpcsvc/nislib.h: New file.

1997-03-17 12:52  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>

	* mach/devstream.c (output/write_some): Don't try and write more
	than IO_INBAND_MAX in a single call to device_write_inband.

	* sysdeps/libm-ieee754/w_atan2.c: Don't ignore exception if library
	* sysdeps/libm-ieee754/w_atan2f.c: Likewise.
	* sysdeps/libm-ieee754/w_atan2l.c: Likewise.
	* sysdeps/unix/sysv/linux/sys/mman.h (msync): Add description for
	* stdlib/atoll.c: Undefine atoll, not atol.
This commit is contained in:
Ulrich Drepper 1997-03-19 05:47:56 +00:00
parent 6465cfc9cf
commit e61abf8398
82 changed files with 10595 additions and 366 deletions

View File

@ -1,4 +1,4 @@
*.d *.o *.so *.po *.go stamp.* *.stamp *.ustamp *.udeps
*.d *.o *.so *.po *.go *.bo stamp.* *.stamp *.ustamp *.udeps
*.gz *.Z *.tar *.tgz
=*
TODO COPYING* AUTHORS copyr-* copying.*

192
ChangeLog
View File

@ -1,11 +1,193 @@
1997-03-19 01:40 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/unix/sysv/sco3.2.4/Dist: New file.
* sysdeps/unix/sysv/sysv4/Dist: Add __getpgid.c and __setpgid.c.
* sysdeps/unix/bsd/Dist: Add bsdstat.h, setrgid.c, and setruid.c.
* sysdeps/unix/sysv/Dist: Add direct.h.
* sysdeps/unix/sysv/linux/Dist: Add netinet/tcp.h.
* Make-dist ($(tardir).tar): Prefer writing temporary file to
$TMPDIR is available. The default is /tmp.
* sysdeps/generic/ip.h: Move to...
* sysdeps/generic/netinet/ip.h: ...here.
* Makefile (tests): Quote $(CC) argument to isomac program.
Patch by H.J. Lu <hjl@gnu.ai.mit.edu>.
* sysdeps/i386/setjmp.S (__setjmp): Fix fatal bug where 0 argument
is placed in wrong place on the stack.
Reported by Marc Lehmann <mlehmann@hildesheim.sgh-net.de>.
* sysdeps/tst-setjmp.c: Add new test for above problem.
* sysdeps/libm-i387/e_pow.S: Compute PIC addres early.
* sysdeps/libm-i387/e_powf.S: Likewise.
* sysdeps/libm-i387/e_powl.S: Likewise.
1997-03-18 23:18 Ulrich Drepper <drepper@cygnus.com>
* time/offtime.c (__offtime): Change type of `yg' to long int.
Reported by a sun <asun@zoology.washington.edu>.
1997-03-18 23:08 a sun <asun@zoology.washington.edu>
* sysdeps/unix/sysv/linux/net/if_ppp.h (PPP_VERSION): Define to
2.2.0 to prevent version mismatch.
1997-03-17 19:26 Andreas Jaeger <aj@arthur.pfalz.de>
* stdio-common/printf_fphex.c (MIN): Only define MIN if not
already defined.
1997-03-14 23:34 Geoff Keating <geoffk@ozemail.com.au>
* sysdeps/unix/sysv/linux/powerpc/termbits.h: Leave ioctl numbers
in ioctls.h.
* elf/rtld.c (_dl_start): Call elf_machine_runtime_setup when the
loader first relocates itself.
* sysdeps/powerpc/elf/start.c (__start1): Fix bug for static objects.
* sysdeps/powerpc/dl-machine.h (elf_machine_rela): Fix bugs in
jump slot relocation. Prefer relative branches (some PowerPC chips
don't predict absolute branches).
(elf_machine_runtime_setup): Simplify and correct expressions.
(RTLD_START): Fix bug changing _dl_starting_up.
* sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c: Added. Deal with
strange Linux/PPC padding of initial stack.
1997-03-11 04:14 Geoff Keating <geoffk@ozemail.com.au>
* sysdeps/unix/sysv/linux/powerpc/termbits.h: Increase NCCS to 39,
for future expansion.
* sysdeps/unix/sysv/linux/powerpc/sys/kernel_termios.h: Added.
* sysdeps/powerpc/dl-machine.h (elf_machine_rela): Explain why it
can't have a switch statement.
* sysdeps/powerpc/elf/start.c (__start1): Explain why it can't be
static.
* sysdeps/powerpc/elf/start.c (_start): Use .previous to avoid
confusing gcc's idea of the current section.
* sysdeps/powerpc/dl-machine.h (ELF_MACHINE_RUNTIME_TRAMPOLINE,
RTLD_START): Likewise.
1997-03-08 09:10 Geoff Keating <geoffk@ozemail.com.au>
* sysdeps/powerpc/dl-machine.h (elf_machine_rela,
elf_machine_runtime_setup): Flush data & instruction caches when
necessary, for 603/604 support. Add better support for large PLTs.
(elf_machine_rela): Remove relocations that wouldn't work if
anyone ever used them. Use memcpy for copy reloc, it'll be safe.
Never target branch relocations at a PLT entry.
* sysdeps/powerpc/bsd-setjmp.S: Make jump to PLT entry if we are
generating PIC.
* sysdeps/powerpc/bsd-_setjmp.S: Likewise.
* sysdeps/powerpc/setjmp.S: Likewise.
* sysdeps/unix/sysv/linux/powerpc/clone.S: Likewise.
* sysdeps/unix/sysv/linux/powerpc/socket.S: Likewise.
* sysdeps/unix/sysv/linux/powerpc/syscall.S: Likewise.
* sysdeps/unix/sysv/linux/powerpc/sysdep.h: Likewise.
* sysdeps/powerpc/elf/start.c: Clean up.
* sysdeps/powerpc/__longjmp.S: Return 'value' as result from
setjmp call.
* sysdeps/unix/sysv/linux/powerpc/statbuf.h: New file.
1997-03-09 12:36 H.J. Lu <hjl@gnu.ai.mit.edu>
* Make-dist (srcs): Add $(test-srcs).
* MakeTAGS (all-sources): Likewise.
* Makerules (depfiles, common-mostlyclean): Likewise.
* Rules (tests): Likewise.
1997-03-18 05:28 Roland McGrath <roland@frob.com>
* elf/dl-reloc.c (RESOLVE): Don't try to resolve ocal symbols.
1997-03-17 21:39 Philip Blundell <phil@london.uk.eu.org>
* nis/nss_nis/nis-service.c (_nss_nis_getservbyname_r): Allow
protocol=NULL to match any protocol rather than returning an
error.
1997-03-17 19:00 Philip Blundell <phil@london.uk.eu.org>
* nss/nss_files/files-service.c (servbyname): Match any protocol
if proto==NULL.
1997-03-18 05:17 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/unix/sysv/linux/alpha/fcntlbits.h: Don't define O_NORW.
* sysdeps/unix/sysv/linux/fcntlbits.h: Likewise.
Proposed by Thomas Bushnell, n/BSG.
1997-03-18 07:53 H.J. Lu <hjl@gnu.ai.mit.edu>
* sysdeps/generic/setenv.c (setenv): Don't copy name when we reuse
the buffer for replacement.
1997-03-16 19:30 H.J. Lu <hjl@gnu.ai.mit.edu>
* sysdeps/unix/sysv/linux/syscalls.list: Add sys_fstat,
sys_lstat and sys_stat.
1997-03-17 12:43 Thorsten Kukuk <kukuk@vt.uni-paderborn.de>
Add NIS+ functions
* shlib-versions: Add libnss_nisplus.
* nis/Makefile: Add NIS+ source files.
* nis/nis_call.c: New file.
* nis/nis_clone.c: New file.
* nis/nis_error.c: New file.
* nis/nis_file.c: New file.
* nis/nis_free.c: New file.
* nis/nis_intern.c: New file.
* nis/nis_intern.h: New file.
* nis/nis_local_names.c: New file.
* nis/nis_names.c: New file.
* nis/nis_print.c: New file.
* nis/nis_server.c: New file.
* nis/nis_subr.c: New file.
* nis/nis_table.c: New file.
* nis/nis_xdr.c: New file.
* nis/nss-nisplus.h: New file.
* nis/nss_nisplus/nisplus-alias.c: New file.
* nis/nss_nisplus/nisplus-ethers.c: New file.
* nis/nss_nisplus/nisplus-grp.c: New file.
* nis/nss_nisplus/nisplus-hosts.c: New file.
* nis/nss_nisplus/nisplus-netgrp.c: New file.
* nis/nss_nisplus/nisplus-network.c: New file.
* nis/nss_nisplus/nisplus-proto.c: New file.
* nis/nss_nisplus/nisplus-publickey.c: New file.
* nis/nss_nisplus/nisplus-pwd.c: New file.
* nis/nss_nisplus/nisplus-rpc.c: New file.
* nis/nss_nisplus/nisplus-service.c: New file.
* nis/nss_nisplus/nisplus-spwd.c: New file.
* nis/rpcsvc/nis.h: New file.
* nis/rpcsvc/nis.x: New file.
* nis/rpcsvc/nis_object.x: New file.
* nis/rpcsvc/nis_tags.h: New file.
* nis/rpcsvc/nislib.h: New file.
1997-03-17 12:52 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
* mach/devstream.c (output/write_some): Don't try and write more
than IO_INBAND_MAX in a single call to device_write_inband.
1997-03-17 04:00 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/libmieee754/w_atan2.c: Don't ignore exception if library
* sysdeps/libm-ieee754/w_atan2.c: Don't ignore exception if library
type is SVID.
* sysdeps/libmieee754/w_atan2f.c: Likewise.
* sysdeps/libmieee754/w_atan2l.c: Likewise.
* sysdeps/libm-ieee754/w_atan2f.c: Likewise.
* sysdeps/libm-ieee754/w_atan2l.c: Likewise.
* sysdeps/unix/sysv/linux/sys/mman.h (msync): Add descrption for
* sysdeps/unix/sysv/linux/sys/mman.h (msync): Add description for
FLAGS parameter.
1997-03-16 20:28 Philip Blundell <phil@london.uk.eu.org>
@ -2099,7 +2281,7 @@
1997-02-11 14:49 Andreas Jaeger <jaeger@informatik.uni-kl.de>
* stdlib/atoll.c: Undefined atoll, not atol.
* stdlib/atoll.c: Undefine atoll, not atol.
1997-02-08 09:36 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>

View File

@ -142,10 +142,10 @@ ifdef subdir
foo:=$(shell echo subdir foo >&2)
+tsrcs := Makefile $(+tsrcs) \
$(addsuffix .c,$(others) $(tests)) \
$(wildcard $(addsuffix .input,$(tests)) \
$(addsuffix .args,$(tests)))
+tsrcs := Makefile $(+tsrcs) \
$(addsuffix .c,$(others) $(tests) $(test-srcs)) \
$(wildcard $(addsuffix .input,$(tests) $(test-srcs)) \
$(addsuffix .args,$(tests) $(test-srcs)))
+tardeps := $(strip $(+tsrcs))
verbose = v

View File

@ -87,8 +87,8 @@ sources += $(foreach lib,$(extra-libs),$($(lib)-routines:=.c))
# Files that are found in the current directory cannot occur in
# sysdep directories, so don't bother searching them.
sysdep-sources := $(filter-out $(wildcard $(sources)), $(sources))
all-sources = $(wildcard $(sort $(sources) $(sources:.c=.S) $(sources:.c=.s) \
$(others:=.c) $(tests:=.c))) \
all-sources = $(wildcard $(sort $(sources) $(sources:.c=.S) $(sources:.c=.s) \
$(others:=.c) $(tests:=.c) $(test-srcs:=.c))) \
$(foreach dir,$(all-dirs),\
$(wildcard \
$(addprefix $(dir)/,\

View File

@ -282,7 +282,7 @@ parent_echo-distinfo:
# Run a test on the header files we use.
tests: $(objpfx)isomac
$(objpfx)./isomac $(CC) '$(+sysdep-includes)' \
$(objpfx)./isomac '$(CC)' '$(+sysdep-includes)' \
>$(common-objpfx)isomac.out
$(objpfx)isomac: isomac.c

View File

@ -857,9 +857,10 @@ mostlyclean: common-mostlyclean
# Remove the object files.
common-mostlyclean:
-rm -f $(addprefix $(objpfx),$(tests) $(others) \
$(addsuffix .o,$(tests) $(others)) \
$(addsuffix .out,$(tests)))
-rm -f $(addprefix $(objpfx),$(tests) $(test-srcs) $(others) \
$(addsuffix .o,$(tests) $(test-srcs) \
$(others)) \
$(addsuffix .out,$(tests) $(test-srcs)))
-rm -f $(addprefix $(objpfx),$(extra-objs) $(install-lib))
-rm -f core $(common-objpfx)stub-$(subdir)
$(rmobjs)

16
NEWS
View File

@ -1,4 +1,4 @@
GNU C Library NEWS -- history of user-visible changes. 1997-02-13
GNU C Library NEWS -- history of user-visible changes. 1997-03-18
Copyright (C) 1992, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
See the end for copying conditions.
@ -24,6 +24,18 @@ Version 2.1
numbers
* scanf recognizes the %A format for scanning floating point numbers
* the new header <inttypes.h> from ISO C 9X provides information and
interfaces for the available integer types
* the new header <complex.h> contains definitions of the complex math
functions from ISO C 9X
* Thorsten Kukuk provided an implementation for NIS+, securelevel 0 and 1.
The implementation for securelevel 2 will follow as soon as the Diffie-
Hellman patent expired.
* Andreas Jaeger provided a test suite for the math library
Version 2.0.2
@ -32,6 +44,8 @@ Version 2.0.2
* add atoll function
* fix complex problems in Berkeley DB code
* fix math functions
Version 2.0.1

8
Rules
View File

@ -83,19 +83,19 @@ common-generated := $(common-generated) dummy.o dummy.c empty.c empty.o
.PHONY: others tests
others: $(addprefix $(objpfx),$(others) $(extra-objs))
ifeq ($(cross-compiling),yes)
tests: $(addprefix $(objpfx),$(tests))
tests: $(addprefix $(objpfx),$(tests) $(test-srcs))
else
tests: $(tests:%=$(objpfx)%.out)
endif
ifneq "$(strip $(others) $(tests))" ""
$(addprefix $(objpfx),$(others) $(tests)): %: %.o \
ifneq "$(strip $(others) $(tests) $(test-srcs))" ""
$(addprefix $(objpfx),$(others) $(tests) $(test-srcs)): %: %.o \
$(sort $(filter $(common-objpfx)libc%,$(link-libc))) \
$(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit)
$(+link)
endif
ifneq "$(strip $(tests))" ""
ifneq "$(strip $(tests) $(test-srcs))" ""
# These are the implicit rules for making test outputs
# from the test programs and whatever input files are present.
$(objpfx)%.out: %.args $(objpfx)% %.input

View File

@ -4,3 +4,4 @@
TODO COPYING* AUTHORS copyr-* copying.*
glibc-*
distinfo
specs

View File

@ -58,7 +58,10 @@ _dl_relocate_object (struct link_map *l, struct link_map *scope[], int lazy)
/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */
#define RESOLVE(ref, version, flags) \
((version) != NULL && (version)->hash != 0 \
((*ref)->st_shndx != SHN_UNDEF && \
ELFW(ST_BIND) ((*ref)->st_info) == STB_LOCAL \
? l->l_addr : \
(version) != NULL && (version)->hash != 0 \
? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, (ref), scope, \
l->l_name, (version), (flags)) \
: _dl_lookup_symbol (strtab + (*ref)->st_name, (ref), scope, \

View File

@ -106,6 +106,7 @@ _dl_start (void *arg)
ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0);
elf_machine_runtime_setup (&bootstrap_map, 0);
/* Now life is sane; we can call functions and access global data.
Set up to use the operating system facilities, and find out from

View File

@ -147,10 +147,16 @@ output (FILE *f, int c)
{
kern_return_t err;
int wrote;
int thiswrite;
while (to_write > 0)
{
thiswrite = to_write;
if (thiswrite > IO_INBAND_MAX)
thiswrite = IO_INBAND_MAX;
if (err = device_write_inband ((device_t) f->__cookie, 0,
f->__target, p, to_write, &wrote))
f->__target, p, thiswrite, &wrote))
{
errno = err;
f->__error = 1;

View File

@ -1 +1 @@
NIS(YP) NSS modules 0.9 by Thorsten Kukuk
NIS(YP)/NIS+ NSS modules 0.10 by Thorsten Kukuk

View File

@ -22,15 +22,15 @@
subdir := nis
headers := $(wildcard rpcsvc/*.[hx])
distribute := nss-nis.h
distribute := nss-nis.h nss-nisplus.h
# These are the databases available for the nis (and perhaps later nisplus)
# service. This must be a superset of the services in nss.
databases = proto service hosts network grp pwd rpc ethers \
spwd netgrp alias
# Specify rules for the nss_* modules. Later we may have nisplus as well.
services := nis compat
# Specify rules for the nss_* modules.
services := nis compat nisplus
extra-libs = libnsl $(services:%=libnss_%)
# These libraries will be built in the `others' pass rather than
@ -41,7 +41,10 @@ extra-libs-others = $(extra-libs)
subdir-dirs = $(services:%=nss_%)
vpath %.c $(subdir-dirs)
libnsl-routines = yp_xdr ypclnt ypupdate_xdr
libnsl-routines = yp_xdr ypclnt ypupdate_xdr \
nis_subr nis_local_names nis_free nis_file \
nis_print nis_error nis_call nis_names nis_clone\
nis_table nis_xdr nis_intern nis_server
libnss_compat-routines := $(addprefix compat-,grp pwd spwd)
libnss_compat-inhibit-o = $(filter-out .so,$(object-suffixes))
@ -49,6 +52,8 @@ libnss_compat-inhibit-o = $(filter-out .so,$(object-suffixes))
libnss_nis-routines := $(addprefix nis-,$(databases))
libnss_nis-inhibit-o = $(filter-out .so,$(object-suffixes))
libnss_nisplus-routines := $(addprefix nisplus-,$(databases))
libnss_nisplus-inhibit-o = $(filter-out .so,$(object-suffixes))
# Sun's header files are not too clean.
CFLAGS-compat-pwd.c = -Wno-strict-prototypes
@ -69,6 +74,32 @@ CFLAGS-nis-spwd.c = -Wno-strict-prototypes
CFLAGS-ypclnt.c = -Wno-strict-prototypes -Wno-write-strings -Irpcsvc
CFLAGS-yp_xdr.c = -Wno-strict-prototypes -Irpcsvc
CFLAGS-ypupdate_xdr.c = -Wno-strict-prototypes -Irpcsvc
# For the NIS+ Code
CFLAGS-nis_call.c = -DNO_DES_RPC -Wno-strict-prototypes
CFLAGS-nis_subr.c = -Wno-strict-prototypes
CFLAGS-nis_local_names.c = -Wno-strict-prototypes
CFLAGS-nis_free.c = -Wno-strict-prototypes
CFLAGS-nis_file.c = -Wno-strict-prototypes
CFLAGS-nis_print.c = -Wno-strict-prototypes
CFLAGS-nis_error.c = -Wno-strict-prototypes
CFLAGS-nis_names.c = -Wno-strict-prototypes
CFLAGS-nis_clone.c = -Wno-strict-prototypes
CFLAGS-nis_table.c = -Wno-strict-prototypes
CFLAGS-nis_server.c = -Wno-strict-prototypes
CFLAGS-nis_xdr.c = -Wno-strict-prototypes
CFLAGS-nis_intern.c = -Wno-strict-prototypes
CFLAGS-nisplus-alias.c = -Wno-strict-prototypes
CFLAGS-nisplus-ethers.c = -Wno-strict-prototypes
CFLAGS-nisplus-grp.c = -Wno-strict-prototypes
CFLAGS-nisplus-hosts.c = -Wno-strict-prototypes
CFLAGS-nisplus-netgrp.c = -Wno-strict-prototypes
CFLAGS-nisplus-network.c = -Wno-strict-prototypes
CFLAGS-nisplus-proto.c = -Wno-strict-prototypes
CFLAGS-nisplus-publickey.c = -Wno-strict-prototypes
CFLAGS-nisplus-pwd.c = -Wno-strict-prototypes
CFLAGS-nisplus-rpc.c = -Wno-strict-prototypes
CFLAGS-nisplus-service.c = -Wno-strict-prototypes
CFLAGS-nisplus-spwd.c = -Wno-strict-prototypes
include ../Rules
@ -77,6 +108,7 @@ $(objpfx)libnss_compat.so: $(objpfx)libnsl.so$(libnsl.so-version) \
$(common-objpfx)nss/libnss_files.so
$(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)
# Depend on libc.so so a DT_NEEDED is generated in the shared objects.
# This ensures they will load libc.so for needed symbols if loaded by

40
nis/TODO Normal file
View File

@ -0,0 +1,40 @@
* nss_nisplus: When using parser form nss_files, rewrite parser
* compat could use data from nisplus, too. Implement this
* nis_server: implement nis_getservlist, nis_stats, nis_servstate
* nis_groups: implement it
* nis_ping: implement it
* __start_clock(), __stop_clock(): Test the interface and
implement it
* What does nis_list give back, if rpc.nisd is not running or
if /var/nis/NIS_START_FILE does not exist ?
* nis_table.c: nis_list():
Missing flags: FOLLOW_PATH, ALL_RESULTS
callback: Don't simulate it, use server callback thread
* Possible flags:
- FOLLOW_LINKS (nis_list, nis_lookup)
- FOLLOW_PATH (nis_list, not supported)
- HARD_LOOKUP (__do_niscall, not supported)
- ALL_RESULTS (nis_list, not supported, needs server callback)
- NO_CACHE (__do_niscall, cache not supported yet)
- MASTER_ONLY (__do_niscall, not supported)
- EXPAND_NAME (nis_lookup, nis_list)
- RETURN_RESULT (nis_table.c)
- ADD_OVERWRITE (nis_table.c)
- REM_MULTIPLE (nis_table.c)
- MOD_SAMEOBJ (nis_table.c)
- ADD_RESERVED (nis_table.c)
- REM_RESERVED (nis_table.c)
- MOD_EXCLUSIVE (nis_table.c)
- USE_DGRAM (__do_niscall)
- NO_AUTHINFO (__do_niscall)

220
nis/nis_call.c Normal file
View File

@ -0,0 +1,220 @@
/* 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 <rpc/rpc.h>
#include <rpc/auth.h>
#include <rpcsvc/nis.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "nis_intern.h"
static struct timeval TIMEOUT = {25, 0};
static int const MAXTRIES = 3;
static unsigned long
inetstr2int (const char *str)
{
char buffer[strlen (str) + 3];
size_t buflen;
size_t i, j;
buflen = stpcpy (buffer, str) - buffer;
j = 0;
for (i = 0; i < buflen; ++i)
if (buffer[i] == '.')
{
++j;
if (j == 4)
{
buffer[i] = '\0';
break;
}
}
return inet_addr (buffer);
}
static CLIENT *
__nis_dobind (const nis_server *server, u_long flags)
{
struct sockaddr_in clnt_saddr;
int clnt_sock;
size_t i;
CLIENT *client = NULL;
/* XXX What is this variable for? */
void *out = NULL;
for (i = 0; i < server->ep.ep_len; i++)
{
memset (&clnt_saddr, '\0', sizeof clnt_saddr);
clnt_saddr.sin_family = AF_INET;
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;
clnt_sock = RPC_ANYSOCK;
if ((flags & USE_DGRAM) == USE_DGRAM)
client = clntudp_create (&clnt_saddr, NIS_PROG, NIS_VERSION,
TIMEOUT, &clnt_sock);
else
client = clnttcp_create (&clnt_saddr, NIS_PROG, NIS_VERSION,
&clnt_sock, 0, 0);
if (client == NULL)
continue;
#if 1
if (clnt_call (client, 0, (xdrproc_t) xdr_void, NULL,
(xdrproc_t) xdr_void, out, TIMEOUT) != RPC_SUCCESS)
{
clnt_destroy (client);
continue;
}
#endif
if ((flags & NO_AUTHINFO) != NO_AUTHINFO)
{
#if !defined(NO_DES_RPC)
if (server->key_type == NIS_PK_DH)
{
char netname[MAXNETNAMELEN+1];
char *p;
strcpy (netname, "unix.");
strncat (netname, server->name,MAXNETNAMELEN-5);
netname[MAXNETNAMELEN-5] = '\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 ();
}
else
#endif
client->cl_auth = authunix_create_default ();
}
return client;
}
return NULL;
}
nis_error
__do_niscall (const nis_server *serv, int serv_len, u_long prog,
xdrproc_t xargs, caddr_t req, xdrproc_t xres, caddr_t resp,
u_long flags)
{
CLIENT *clnt;
directory_obj *dir = NULL;
const nis_server *server;
int try, result, server_len;
if (serv == NULL || serv_len == 0)
{
dir = readColdStartFile ();
if (dir == NULL)
return NIS_UNAVAIL;
server = dir->do_servers.do_servers_val;
server_len = dir->do_servers.do_servers_len;
}
else
{
server = serv;
server_len = serv_len;
}
try = 0;
result = NIS_NAMEUNREACHABLE;
while (try < MAXTRIES && result != RPC_SUCCESS)
{
unsigned int i;
++try;
for (i = 0; i < server_len; i++)
{
if ((clnt = __nis_dobind (&server[i], flags)) == NULL)
continue;
result = clnt_call (clnt, prog, xargs, req, xres, resp, TIMEOUT);
if (result != RPC_SUCCESS)
{
/* XXX Grrr. The cast is needed for now since Sun code does
note know about `const'. */
clnt_perror (clnt, (char *) "do_niscall: clnt_call");
clnt_destroy (clnt);
result = NIS_RPCERROR;
}
else
clnt_destroy (clnt);
}
}
if (dir != NULL)
nis_free_directory (dir);
return result;
}

551
nis/nis_clone.c Normal file
View File

@ -0,0 +1,551 @@
/* 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>
directory_obj *
nis_clone_directory (const directory_obj *src, directory_obj *dest)
{
directory_obj *res;
if (src == NULL)
return NULL;
if (dest == NULL)
{
res = calloc (1, sizeof (directory_obj));
if (res == NULL)
return NULL;
}
else
res = dest;
if (src->do_name)
res->do_name = strdup (src->do_name);
else
res->do_name = NULL;
res->do_type = src->do_type;
if (src->do_servers.do_servers_len > 0)
{
size_t i;
res->do_servers.do_servers_len = src->do_servers.do_servers_len;
if ((res->do_servers.do_servers_val =
malloc (src->do_servers.do_servers_len * sizeof (nis_server)))
== NULL)
return NULL;
for (i = 0; i < src->do_servers.do_servers_len; ++i)
{
if (src->do_servers.do_servers_val[i].name != NULL)
res->do_servers.do_servers_val[i].name =
strdup (src->do_servers.do_servers_val[i].name);
else
res->do_servers.do_servers_val[i].name = NULL;
res->do_servers.do_servers_val[i].ep.ep_len =
src->do_servers.do_servers_val[i].ep.ep_len;
if (res->do_servers.do_servers_val[i].ep.ep_len > 0)
{
size_t j;
res->do_servers.do_servers_val[i].ep.ep_val =
malloc (src->do_servers.do_servers_val[i].ep.ep_len *
sizeof (endpoint));
for (j = 0; j < res->do_servers.do_servers_val[i].ep.ep_len; ++j)
{
if (src->do_servers.do_servers_val[i].ep.ep_val[j].uaddr)
res->do_servers.do_servers_val[i].ep.ep_val[j].uaddr
= strdup (src->do_servers.do_servers_val[i].ep.ep_val[j].uaddr);
else
res->do_servers.do_servers_val[i].ep.ep_val[j].uaddr = NULL;
if (src->do_servers.do_servers_val[i].ep.ep_val[j].family)
res->do_servers.do_servers_val[i].ep.ep_val[j].family
= strdup (src->do_servers.do_servers_val[i].ep.ep_val[j].family);
else
res->do_servers.do_servers_val[i].ep.ep_val[j].family = NULL;
if (src->do_servers.do_servers_val[i].ep.ep_val[j].proto)
res->do_servers.do_servers_val[i].ep.ep_val[j].proto
= strdup (src->do_servers.do_servers_val[i].ep.ep_val[j].proto);
else
res->do_servers.do_servers_val[i].ep.ep_val[j].proto = NULL;
}
}
else
{
res->do_servers.do_servers_val[i].ep.ep_val = NULL;
}
res->do_servers.do_servers_val[i].key_type =
src->do_servers.do_servers_val[i].key_type;
res->do_servers.do_servers_val[i].pkey.n_len =
src->do_servers.do_servers_val[i].pkey.n_len;
if (res->do_servers.do_servers_val[i].pkey.n_len > 0)
{
res->do_servers.do_servers_val[i].pkey.n_bytes =
malloc (src->do_servers.do_servers_val[i].pkey.n_len);
if (res->do_servers.do_servers_val[i].pkey.n_bytes == NULL)
return NULL;
memcpy (res->do_servers.do_servers_val[i].pkey.n_bytes,
src->do_servers.do_servers_val[i].pkey.n_bytes,
src->do_servers.do_servers_val[i].pkey.n_len);
}
else
res->do_servers.do_servers_val[i].pkey.n_bytes = NULL;
}
}
else
{
res->do_servers.do_servers_len = 0;
res->do_servers.do_servers_val = NULL;
}
res->do_ttl = src->do_ttl;
res->do_armask.do_armask_len = src->do_armask.do_armask_len;
if (res->do_armask.do_armask_len > 0)
{
if ((res->do_armask.do_armask_val =
malloc (src->do_armask.do_armask_len * sizeof (oar_mask))) == NULL)
return NULL;
memcpy (res->do_armask.do_armask_val, src->do_armask.do_armask_val,
src->do_armask.do_armask_len * sizeof (oar_mask));
}
else
{
res->do_armask.do_armask_val = NULL;
}
return res;
}
group_obj *
nis_clone_group (const group_obj *src, group_obj *dest)
{
size_t i;
group_obj *res = NULL;
if (src == NULL)
return NULL;
if (dest == NULL)
{
res = calloc (1, sizeof (group_obj));
if (res == NULL)
return NULL;
}
else
res = dest;
res->gr_flags = src->gr_flags;
res->gr_members.gr_members_len = src->gr_members.gr_members_len;
if (res->gr_members.gr_members_len > 0)
{
if (res->gr_members.gr_members_val == NULL)
{
res->gr_members.gr_members_val =
malloc (res->gr_members.gr_members_len * sizeof (nis_name));
if (res->gr_members.gr_members_val == NULL)
return NULL;
}
for (i = 0; i < res->gr_members.gr_members_len; ++i)
if (src->gr_members.gr_members_val[i] != NULL)
res->gr_members.gr_members_val[i] =
strdup (src->gr_members.gr_members_val[i]);
else
res->gr_members.gr_members_val[i] = NULL;
}
return res;
}
table_obj *
nis_clone_table (const table_obj *src, table_obj *dest)
{
size_t i;
table_obj *res = NULL;
if (src == NULL)
return NULL;
if (dest == NULL)
{
res = calloc (1, sizeof (table_obj));
if (res == NULL)
return res;
}
else
res = dest;
if (src->ta_type != NULL)
{
if ((res->ta_type = strdup (src->ta_type)) == NULL)
return NULL;
}
else
res->ta_type = NULL;
res->ta_maxcol = src->ta_maxcol;
res->ta_sep = src->ta_sep;
res->ta_cols.ta_cols_len = src->ta_cols.ta_cols_len;
if (res->ta_cols.ta_cols_val == NULL)
{
res->ta_cols.ta_cols_val =
malloc (src->ta_cols.ta_cols_len * sizeof (table_col));
if (res->ta_cols.ta_cols_val == NULL)
return NULL;
}
for (i = 0; i < res->ta_cols.ta_cols_len; i++)
{
if (src->ta_cols.ta_cols_val[i].tc_name == NULL)
res->ta_cols.ta_cols_val[i].tc_name = NULL;
else
res->ta_cols.ta_cols_val[i].tc_name =
strdup (src->ta_cols.ta_cols_val[i].tc_name);
res->ta_cols.ta_cols_val[i].tc_flags =
src->ta_cols.ta_cols_val[i].tc_flags;
res->ta_cols.ta_cols_val[i].tc_rights =
src->ta_cols.ta_cols_val[i].tc_rights;
}
if (src->ta_path != NULL)
{
if ((res->ta_path = strdup (src->ta_path)) == NULL)
return NULL;
}
else
res->ta_path = NULL;
return res;
}
entry_obj *
nis_clone_entry (const entry_obj *src, entry_obj *dest)
{
size_t i;
entry_obj *res = NULL;
if (src == NULL)
return NULL;
if (dest == NULL)
{
res = calloc (1, sizeof (entry_obj));
if (res == NULL)
return NULL;
}
else
res = dest;
if (src->en_type)
res->en_type = strdup (src->en_type);
else
res->en_type = NULL;
res->en_cols.en_cols_len = src->en_cols.en_cols_len;
if (res->en_cols.en_cols_val == NULL && src->en_cols.en_cols_len > 0)
{
res->en_cols.en_cols_val =
malloc (src->en_cols.en_cols_len * sizeof (entry_col));
if (res->en_cols.en_cols_val == NULL)
return NULL;
}
for (i = 0; i < res->en_cols.en_cols_len; ++i)
{
res->en_cols.en_cols_val[i].ec_flags =
src->en_cols.en_cols_val[i].ec_flags;
res->en_cols.en_cols_val[i].ec_value.ec_value_len =
src->en_cols.en_cols_val[i].ec_value.ec_value_len;
if (res->en_cols.en_cols_val[i].ec_value.ec_value_val == NULL &&
src->en_cols.en_cols_val[i].ec_value.ec_value_len > 0)
res->en_cols.en_cols_val[i].ec_value.ec_value_val =
malloc (src->en_cols.en_cols_val[i].ec_value.ec_value_len);
memcpy (res->en_cols.en_cols_val[i].ec_value.ec_value_val,
src->en_cols.en_cols_val[i].ec_value.ec_value_val,
res->en_cols.en_cols_val[i].ec_value.ec_value_len);
}
return res;
}
nis_attr *
nis_clone_nis_attr (const nis_attr *src, nis_attr *dest)
{
nis_attr *res = NULL;
if (src == NULL)
return NULL;
if (dest == NULL)
{
res = calloc (1, sizeof (nis_attr));
if (res == NULL)
return NULL;
}
else
res = dest;
if (src->zattr_ndx != NULL)
{
if ((res->zattr_ndx = strdup (src->zattr_ndx)) == NULL)
return NULL;
}
else
res->zattr_ndx = NULL;
res->zattr_val.zattr_val_len = src->zattr_val.zattr_val_len;
if (res->zattr_val.zattr_val_val == NULL)
{
res->zattr_val.zattr_val_val =
malloc (src->zattr_val.zattr_val_len);
if (res->zattr_val.zattr_val_val == NULL)
return NULL;
}
memcpy (res->zattr_val.zattr_val_val, src->zattr_val.zattr_val_val,
src->zattr_val.zattr_val_len);
return res;
}
static nis_attr *
__nis_clone_attrs (const nis_attr *src, nis_attr *dest, u_int len)
{
unsigned int i;
nis_attr *res;
if (len == 0)
return dest;
if (dest == NULL)
{
res = calloc (len, sizeof (nis_attr));
if (res == NULL)
return NULL;
}
else
res = dest;
for (i = 0; i < len; i++)
nis_clone_nis_attr(&src[i], &res[i]);
return res;
}
link_obj *
nis_clone_link (const link_obj *src, link_obj *dest)
{
link_obj *res = NULL;
if (src == NULL)
return NULL;
if (dest == NULL)
{
res = calloc (1, sizeof (link_obj));
if (res == NULL)
return NULL;
}
else
res = dest;
res->li_rtype = src->li_rtype;
res->li_attrs.li_attrs_len = src->li_attrs.li_attrs_len;
res->li_attrs.li_attrs_val =
__nis_clone_attrs (src->li_attrs.li_attrs_val,
res->li_attrs.li_attrs_val,
src->li_attrs.li_attrs_len);
if ((res->li_name = strdup (src->li_name)) == NULL)
return NULL;
return res;
}
objdata *
nis_clone_objdata (const objdata *src, objdata *dest)
{
objdata *res = NULL;
if (src == NULL)
return NULL;
if (dest == NULL)
{
res = calloc (1, sizeof (objdata));
if (res == NULL)
return res;
}
else
res = dest;
res->zo_type = src->zo_type;
switch (src->zo_type)
{
case BOGUS_OBJ:
break;
case NO_OBJ:
break;
case DIRECTORY_OBJ:
if (nis_clone_directory (&src->objdata_u.di_data,
&res->objdata_u.di_data) == NULL)
return NULL;
break;
case GROUP_OBJ:
if (nis_clone_group (&src->objdata_u.gr_data,
&res->objdata_u.gr_data) == NULL)
return NULL;
break;
case TABLE_OBJ:
if (nis_clone_table (&src->objdata_u.ta_data,
&res->objdata_u.ta_data) == NULL)
return NULL;
break;
case ENTRY_OBJ:
if (nis_clone_entry (&src->objdata_u.en_data,
&res->objdata_u.en_data) == NULL)
return NULL;
break;
case LINK_OBJ:
if (nis_clone_link (&src->objdata_u.li_data,
&res->objdata_u.li_data) == NULL)
return NULL;
break;
case PRIVATE_OBJ:
res->objdata_u.po_data.po_data_len =
src->objdata_u.po_data.po_data_len;
if (src->objdata_u.po_data.po_data_val)
{
res->objdata_u.po_data.po_data_val =
malloc (res->objdata_u.po_data.po_data_len);
if (res->objdata_u.po_data.po_data_val == NULL)
return NULL;
memcpy (res->objdata_u.po_data.po_data_val,
src->objdata_u.po_data.po_data_val,
src->objdata_u.po_data.po_data_len);
if (res->objdata_u.po_data.po_data_val == NULL)
return NULL;
}
else
{
res->objdata_u.po_data.po_data_val = NULL;
res->objdata_u.po_data.po_data_len = 0;
}
break;
default:
return NULL;
}
return res;
}
nis_object *
nis_clone_object (const nis_object *src, nis_object *dest)
{
nis_object *res = NULL;
if (src == NULL)
return NULL;
if (dest == NULL)
{
res = calloc (1, sizeof (nis_object));
if (res == NULL)
return NULL;
}
else
res = dest;
res->zo_oid = src->zo_oid;
if ((res->zo_name = strdup (src->zo_name)) == NULL)
return NULL;
if ((res->zo_owner = strdup (src->zo_owner)) == NULL)
return NULL;
if ((res->zo_group = strdup (src->zo_group)) == NULL)
return NULL;
if ((res->zo_domain = strdup (src->zo_domain)) == NULL)
return NULL;
res->zo_access = src->zo_access;
res->zo_ttl = src->zo_ttl;
if (nis_clone_objdata (&src->zo_data, &res->zo_data) == NULL)
return NULL;
return res;
}
static nis_object *
__nis_clone_objects (const nis_object *src, nis_object *dest, u_int len)
{
unsigned int i;
nis_object *res;
if (len == 0)
return dest;
if (dest == NULL)
{
res = calloc (len, sizeof (nis_object));
if (res == NULL)
return NULL;
}
else
res = dest;
for (i = 0; i < len; ++i)
nis_clone_object(&src[i], &res[i]);
return res;
}
nis_result *
nis_clone_result (const nis_result *src, nis_result *dest)
{
nis_result *res = NULL;
if (src == NULL)
return NULL;
if (dest == NULL)
{
res = calloc (1, sizeof (nis_result));
if (res == NULL)
return NULL;
}
else
res = dest;
res->status = src->status;
res->objects.objects_len = src->objects.objects_len;
res->objects.objects_val =
__nis_clone_objects (src->objects.objects_val,
res->objects.objects_val,
src->objects.objects_len);
res->zticks = src->zticks;
res->dticks = src->dticks;
res->aticks = src->aticks;
res->cticks = src->cticks;
return res;
}

124
nis/nis_error.c Normal file
View File

@ -0,0 +1,124 @@
/* 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 <errno.h>
#include <syslog.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
static const char *nis_errlist[] =
{
N_("Success"),
N_("Probable success"),
N_("Not found"),
N_("Probably not found"),
N_("Cache expired"),
N_("NIS+ servers unreachable"),
N_("Unknown object"),
N_("Server busy, try again"),
N_("Generic system error"),
N_("First/Next chain broken"),
N_("Permission denied"),
N_("Not owner"),
N_("Name not served by this server"),
N_("Server out of memory"),
N_("Object with same name exists"),
N_("Not master server for this domain"),
N_("Invalid Object for operation"),
N_("Malformed Name, or illegal name"),
N_("Unable to create callback"),
N_("Results Sent to callback proc"),
N_("Not Found, no such name"),
N_("Name/entry isn't unique"),
N_("Modification failed"),
N_("Database for table does not exist"),
N_("Entry/Table type mismatch"),
N_("Link Points to illegal name"),
N_("Partial Success"),
N_("Too Many Attributes"),
N_("Error in RPC subsystem"),
N_("Missing or malformed attribute"),
N_("Named object is not searchable"),
N_("Error while talking to callback proc"),
N_("Non NIS+ namespace encountered"),
N_("Illegal object type for operation"),
N_("Passed object is not the same object on server"),
N_("Modify operation failed"),
N_("Query illegal for named table"),
N_("Attempt to remove a non-empty table"),
N_("Error in accessing NIS+ cold start file. Is NIS+ installed?"),
N_("Full resync required for directory"),
N_("NIS+ operation failed"),
N_("NIS+ service is unavailable or not installed"),
N_("Yes, 42 is the meaning of life"),
N_("Unable to authenticate NIS+ server"),
N_("Unable to authenticate NIS+ client"),
N_("No file space on server"),
N_("Unable to create process on server"),
N_("Master server busy, full dump rescheduled.")
};
const char *
nis_sperrno (const nis_error status)
{
if (status >= (sizeof (nis_errlist) / sizeof (nis_errlist[0])))
return "???";
else
return gettext (nis_errlist[status]);
}
void
nis_perror (const nis_error status, const char *label)
{
fprintf (stderr, "%s: %s\n", label, nis_sperrno (status));
}
void
nis_lerror (const nis_error status, const char *label)
{
syslog (LOG_ERR, "%s: %s", label, nis_sperrno (status));
}
char *
nis_sperror_r (const nis_error status, const char *label,
char *buffer, size_t buflen)
{
const char *cptr;
cptr = nis_sperrno (status);
if ((strlen (cptr) + strlen (label) + 3) > buflen)
{
errno = ERANGE;
return NULL;
}
sprintf (buffer, "%s: %s", label, cptr);
return buffer;
}
char *
nis_sperror (const nis_error status, const char *label)
{
static char buffer[NIS_MAXNAMELEN +1];
return nis_sperror_r (status, label, buffer, sizeof (buffer));
}

108
nis/nis_file.c Normal file
View File

@ -0,0 +1,108 @@
/* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
directory_obj *
readColdStartFile (void)
{
XDR xdrs;
FILE *in;
directory_obj obj;
in = fopen ("/var/nis/NIS_COLD_START", "rb");
if (in == NULL)
{
fputs (_("Error: Could not open /var/nis/NIS_COLD_START!\n"), stdout);
return NULL;
}
memset (&obj, '\0', sizeof (obj));
xdrstdio_create (&xdrs, in, XDR_DECODE);
if (!xdr_directory_obj (&xdrs, &obj))
{
fputs (("Error while reading /var/nis/NIS_COLD_START!\n"), stdout);
return NULL;
}
return nis_clone_directory (&obj, NULL);
}
bool_t
writeColdStartFile (const directory_obj *obj)
{
XDR xdrs;
FILE *out;
out = fopen ("/var/nis/NIS_COLD_START", "wb");
if (out == NULL)
return FALSE;
xdrstdio_create (&xdrs, out, XDR_ENCODE);
/* XXX The following cast is bad! Shouldn't the XDR functions take
pointers to const objects? */
if (!xdr_directory_obj (&xdrs, (directory_obj *) obj))
{
fputs (_("Error while reading /var/nis/NIS_COLD_START!\n"), stdout);
return FALSE;
}
return TRUE;
}
nis_object *
nis_read_obj (const char *name)
{
XDR xdrs;
FILE *in;
nis_object obj;
in = fopen (name, "rb");
if (in == NULL)
return NULL;
memset (&obj, '\0', sizeof (obj));
xdrstdio_create (&xdrs, in, XDR_DECODE);
if (!xdr_nis_object (&xdrs, &obj))
return NULL;
return nis_clone_object (&obj, NULL);
}
bool_t
nis_write_obj (const char *name, const nis_object *obj)
{
XDR xdrs;
FILE *out;
out = fopen (name, "wb");
if (out == NULL)
return FALSE;
xdrstdio_create (&xdrs, out, XDR_ENCODE);
/* XXX The following cast is bad! Shouldn't the XDR functions take
pointers to const objects? */
if (!xdr_nis_object (&xdrs, (nis_object *) obj))
return FALSE;
return TRUE;
}

334
nis/nis_free.c Normal file
View File

@ -0,0 +1,334 @@
/* 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 <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
void
nis_free_attr (nis_attr *obj)
{
if (obj == NULL)
return;
if (obj->zattr_ndx)
{
free (obj->zattr_ndx);
obj->zattr_ndx = NULL;
}
if (obj->zattr_val.zattr_val_val)
{
free (obj->zattr_val.zattr_val_val);
obj->zattr_val.zattr_val_val = NULL;
obj->zattr_val.zattr_val_len = 0;
}
}
void
nis_free_request (ib_request *ibreq)
{
unsigned int i;
for (i = 0; i < ibreq->ibr_srch.ibr_srch_len; ++i)
{
nis_free_attr (&(ibreq->ibr_srch.ibr_srch_val)[i]);
ibreq->ibr_srch.ibr_srch_val = NULL;
ibreq->ibr_srch.ibr_srch_len = 0;
}
if (ibreq->ibr_name)
{
free (ibreq->ibr_name);
ibreq->ibr_name = NULL;
}
if (ibreq->ibr_cookie.n_bytes)
{
free (ibreq->ibr_cookie.n_bytes);
ibreq->ibr_cookie.n_bytes = NULL;
ibreq->ibr_cookie.n_len = 0;
}
}
void
nis_free_endpoints (endpoint *ep, int len)
{
int i;
if (ep == NULL)
return;
for (i = 0; i < len; ++i)
{
if (ep[i].uaddr)
{
free (ep[i].uaddr);
ep[i].uaddr = NULL;
}
if (ep[i].family)
{
free (ep[i].family);
ep[i].family = NULL;
}
if (ep[i].proto)
{
free (ep[i].proto);
ep[i].proto = NULL;
}
}
}
void
nis_free_servers (nis_server *obj, int len)
{
int i;
if (obj == NULL)
return;
for (i = 0; i < len; i++)
{
if (obj[i].name)
{
free (obj[i].name);
obj[i].name = NULL;
}
if (obj[i].ep.ep_len > 0)
{
nis_free_endpoints (obj[i].ep.ep_val, obj[i].ep.ep_len);
free (obj[i].ep.ep_val);
obj[i].ep.ep_val = NULL;
obj[i].ep.ep_len = 0;
}
if (obj[i].pkey.n_bytes && obj[i].pkey.n_len > 0)
{
free (obj[i].pkey.n_bytes);
obj[i].pkey.n_bytes = NULL;
obj[i].pkey.n_len = 0;
}
}
}
void
nis_free_directory (directory_obj *obj)
{
if (obj == NULL)
return;
if (obj->do_name)
{
free (obj->do_name);
obj->do_name = NULL;
}
if (obj->do_servers.do_servers_len > 0)
{
nis_free_servers (obj->do_servers.do_servers_val,
obj->do_servers.do_servers_len);
free (obj->do_servers.do_servers_val);
obj->do_servers.do_servers_val = NULL;
obj->do_servers.do_servers_len = 0;
}
if (obj->do_armask.do_armask_len > 0)
{
free (obj->do_armask.do_armask_val);
obj->do_armask.do_armask_val = NULL;
obj->do_armask.do_armask_len = 0;
}
}
void
nis_free_group (group_obj *obj)
{
unsigned int i;
if (obj->gr_members.gr_members_len > 0)
{
for (i = 0; i < obj->gr_members.gr_members_len; ++i)
if (obj->gr_members.gr_members_val[i])
free (obj->gr_members.gr_members_val[i]);
free (obj->gr_members.gr_members_val);
obj->gr_members.gr_members_val = NULL;
obj->gr_members.gr_members_len = 0;
}
}
void
nis_free_table (table_obj *obj)
{
if (obj == NULL)
return;
if (obj->ta_type)
{
free (obj->ta_type);
obj->ta_type = NULL;
}
if (obj->ta_cols.ta_cols_val)
{
unsigned int i;
for (i = 0; i < obj->ta_cols.ta_cols_len; ++i)
if (obj->ta_cols.ta_cols_val[i].tc_name)
free (obj->ta_cols.ta_cols_val[i].tc_name);
free (obj->ta_cols.ta_cols_val);
obj->ta_cols.ta_cols_val = NULL;
obj->ta_cols.ta_cols_len = 0;
}
if (obj->ta_path)
{
free (obj->ta_path);
obj->ta_path = NULL;
}
}
void
nis_free_entry (entry_obj *obj)
{
if (obj == NULL)
return;
if (obj->en_type)
{
free (obj->en_type);
obj->en_type = 0;
}
if (obj->en_cols.en_cols_val)
{
unsigned int i;
for (i = 0; i < obj->en_cols.en_cols_len; ++i)
if (obj->en_cols.en_cols_val[i].ec_value.ec_value_val)
free (obj->en_cols.en_cols_val[i].ec_value.ec_value_val);
free (obj->en_cols.en_cols_val);
obj->en_cols.en_cols_val = NULL;
obj->en_cols.en_cols_len = 0;
}
}
void
nis_free_link (link_obj *obj)
{
if (obj == NULL)
return;
if (obj->li_attrs.li_attrs_val)
{
unsigned int i;
for (i = 0; i < obj->li_attrs.li_attrs_len; ++i)
{
if (obj->li_attrs.li_attrs_val[i].zattr_ndx)
free (obj->li_attrs.li_attrs_val[i].zattr_ndx);
if (obj->li_attrs.li_attrs_val[i].zattr_val.zattr_val_val)
free (obj->li_attrs.li_attrs_val[i].zattr_val.zattr_val_val);
}
free (obj->li_attrs.li_attrs_val);
obj->li_attrs.li_attrs_val = NULL;
obj->li_attrs.li_attrs_len = 0;
}
if (obj->li_name)
{
free (obj->li_name);
obj->li_name = NULL;
}
}
void
nis_free_object (nis_object *obj)
{
if (obj == NULL)
return;
if (obj->zo_name)
{
free (obj->zo_name);
obj->zo_name = NULL;
}
if (obj->zo_owner)
{
free (obj->zo_owner);
obj->zo_owner = NULL;
}
if (obj->zo_group)
{
free (obj->zo_group);
obj->zo_group = NULL;
}
if (obj->zo_domain)
{
free (obj->zo_domain);
obj->zo_domain = NULL;
}
switch (obj->zo_data.zo_type)
{
case BOGUS_OBJ:
break;
case NO_OBJ:
break;
case DIRECTORY_OBJ:
nis_free_directory (&obj->zo_data.objdata_u.di_data);
break;
case GROUP_OBJ:
nis_free_group (&obj->zo_data.objdata_u.gr_data);
break;
case TABLE_OBJ:
nis_free_table (&obj->zo_data.objdata_u.ta_data);
break;
case ENTRY_OBJ:
nis_free_entry (&obj->zo_data.objdata_u.en_data);
break;
case LINK_OBJ:
nis_free_link (&obj->zo_data.objdata_u.li_data);
break;
case PRIVATE_OBJ:
if (obj->zo_data.objdata_u.po_data.po_data_val)
{
free (obj->zo_data.objdata_u.po_data.po_data_val);
obj->zo_data.objdata_u.po_data.po_data_val = NULL;
}
break;
default:
break;
}
obj->zo_data.zo_type = NO_OBJ;
}
void
nis_freeresult (nis_result *res)
{
unsigned int i;
if (res == NULL)
return;
for (i = 0; i < res->objects.objects_len; i++)
nis_free_object (&(res->objects.objects_val)[i]);
if (res->objects.objects_val != NULL)
free (res->objects.objects_val);
if (res->cookie.n_bytes != NULL && res->cookie.n_len > 0)
free (res->cookie.n_bytes);
free (res);
}

169
nis/nis_intern.c Normal file
View File

@ -0,0 +1,169 @@
/* 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 nis_name 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;
}
fd_result *
__nis_finddirectoy (nis_name dir_name)
{
fd_args args;
nis_error status;
fd_result *res;
args.dir_name = dir_name;
args.requester = nis_local_principal ();
res = calloc (1, sizeof (fd_result));
if (res == NULL)
return NULL;
if ((status = __do_niscall (NULL, 0, NIS_FINDDIRECTORY,
(xdrproc_t) xdr_fd_args,
(caddr_t) & args,
(xdrproc_t) xdr_fd_result,
(caddr_t) res, 0)) != RPC_SUCCESS)
res->status = status;
return res;
}

39
nis/nis_intern.h Normal file
View File

@ -0,0 +1,39 @@
/* 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 __NIS_INTERN_H
#define __NIS_INTERN_H
#include <features.h>
__BEGIN_DECLS
extern nis_error __do_niscall (__const nis_server *server, int server_len,
u_long prog, xdrproc_t xargs, caddr_t req,
xdrproc_t xres, caddr_t resp, u_long flags);
#if !defined(NO_DES_RPC)
extern AUTH *authdes_pk_create (char *, netobj *, u_int,
struct sockaddr *, des_block *);
#endif
extern nis_name *__nis_expandname (__const nis_name);
__END_DECLS
#endif

184
nis/nis_local_names.c Normal file
View File

@ -0,0 +1,184 @@
/* 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 <errno.h>
#include <string.h>
#include <unistd.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
nis_name
nis_local_group (void)
{
static char __nisgroup[NIS_MAXNAMELEN + 1];
if (__nisgroup[0] == '\0')
{
char *cptr;
if ((cptr = getenv ("NIS_GROUP")) == NULL)
return __nisgroup;
if (strlen (cptr) >= NIS_MAXNAMELEN)
return __nisgroup;
strcpy (__nisgroup, cptr);
if (__nisgroup[strlen (__nisgroup) - 1] != '.')
{
cptr = nis_local_directory ();
if (strlen (__nisgroup) + strlen (cptr) + 1 < NIS_MAXNAMELEN)
{
strcat (__nisgroup, ".");
strcat (__nisgroup, cptr);
}
else
{
__nisgroup[0] = '\0';
return __nisgroup;
}
}
}
return __nisgroup;
}
nis_name
nis_local_directory (void)
{
static char __nisdomainname[NIS_MAXNAMELEN + 1];
int len;
if (__nisdomainname[0] == '\0')
{
if (getdomainname (__nisdomainname, NIS_MAXNAMELEN) < 0)
strcpy (__nisdomainname, "\0");
else
{
len = strlen (__nisdomainname);
/* Missing trailing dot? */
if (__nisdomainname[len - 1] != '.')
{
__nisdomainname[len] = '.';
__nisdomainname[len + 1] = '\0';
}
}
}
return __nisdomainname;
}
nis_name
nis_local_principal (void)
{
static char __principal[NIS_MAXNAMELEN + 1];
if (__principal[0] == '\0')
{
char buf[NIS_MAXNAMELEN + 1];
nis_result *res;
uid_t uid = geteuid ();
if (uid != 0)
{
snprintf (buf, NIS_MAXNAMELEN - 1,
"[auth_name=%d,auth_type=LOCAL],cred.org_dir.%s",
uid, nis_local_directory ());
if (buf[strlen (buf) - 1] != '.')
strcat (buf, ".");
res = nis_list (buf, USE_DGRAM + NO_AUTHINFO + FOLLOW_LINKS +
FOLLOW_PATH, NULL, NULL);
if (res == NULL)
{
strcpy (__principal, "nobody");
return __principal;
}
if (res->status == NIS_SUCCESS)
{
if (res->objects.objects_len > 1)
{
/* More than one principal with same uid? something
wrong with cred table. Should be unique Warn user
and continue. */
printf (_("\
LOCAL entry for UID %d in directory %s not unique\n"),
uid, nis_local_directory ());
}
strcpy (__principal, ENTRY_VAL (res->objects.objects_val, 0));
nis_freeresult (res);
return __principal;
}
else
{
nis_freeresult (res);
strcpy (__principal, "nobody");
return __principal;
}
}
else
{
strcpy (__principal, nis_local_host ());
return __principal;
}
/* Should be never reached */
strcpy (__principal, "nobody");
return __principal;
}
return __principal;
}
nis_name
nis_local_host (void)
{
static char __nishostname[NIS_MAXNAMELEN + 1];
int len;
if (__nishostname[0] == '\0')
{
char *cp = __nishostname;
if (gethostname (__nishostname, NIS_MAXNAMELEN) < 0)
cp = stpcpy (cp, "\0");
len = cp - __nishostname;
/* Hostname already fully qualified? */
if (__nishostname[len - 1] == '.')
return __nishostname;
if (strlen (__nishostname + strlen (nis_local_directory ()) + 1) >
NIS_MAXNAMELEN)
{
__nishostname[0] = '\0';
return __nishostname;
}
*cp++ = '.';
stpcpy (cp, nis_local_directory ());
}
return __nishostname;
}

238
nis/nis_names.c Normal file
View File

@ -0,0 +1,238 @@
/* Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@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 <rpc/rpc.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
#include "nis_intern.h"
nis_result *
nis_lookup (const nis_name name, const u_long flags)
{
nis_result *res;
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;
res = calloc (1, sizeof (nis_result));
if (flags & EXPAND_NAME)
{
names = __nis_expandname (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 (NULL, 0, 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 = name;
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 (NULL, 0, NIS_LOOKUP,
(xdrproc_t) xdr_ns_request,
(caddr_t) & req,
(xdrproc_t) xdr_nis_result,
(caddr_t) res, flags)) != RPC_SUCCESS)
{
res->status = status;
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;
}
}
}
}
return res;
}
nis_result *
nis_add (const nis_name name, const nis_object *obj)
{
nis_result *res;
nis_error status;
struct ns_request req;
res = calloc (1, sizeof (nis_result));
req.ns_name = name;
req.ns_object.ns_object_len = 1;
req.ns_object.ns_object_val = nis_clone_object (obj, NULL);
if ((status = __do_niscall (NULL, 0, NIS_ADD, (xdrproc_t) xdr_ns_request,
(caddr_t) & req, (xdrproc_t) xdr_nis_result,
(caddr_t) res, 0)) != RPC_SUCCESS)
res->status = status;
nis_destroy_object (req.ns_object.ns_object_val);
return res;
}
nis_result *
nis_remove (const nis_name name, const nis_object *obj)
{
nis_result *res;
nis_error status;
struct ns_request req;
res = calloc (1, sizeof (nis_result));
req.ns_name = name;
if (obj != NULL)
{
req.ns_object.ns_object_len = 1;
req.ns_object.ns_object_val = nis_clone_object (obj, NULL);
}
else
{
req.ns_object.ns_object_len = 0;
req.ns_object.ns_object_val = NULL;
}
if ((status = __do_niscall (NULL, 0, NIS_REMOVE, (xdrproc_t) xdr_ns_request,
(caddr_t) & req, (xdrproc_t) xdr_nis_result,
(caddr_t) res, 0)) != RPC_SUCCESS)
res->status = status;
nis_destroy_object (req.ns_object.ns_object_val);
return res;
}
nis_result *
nis_modify (const nis_name name, const nis_object *obj)
{
nis_result *res;
nis_error status;
struct ns_request req;
res = calloc (1, sizeof (nis_result));
req.ns_name = name;
req.ns_object.ns_object_len = 1;
req.ns_object.ns_object_val = nis_clone_object (obj, NULL);
if ((status = __do_niscall (NULL, 0, NIS_REMOVE, (xdrproc_t) xdr_ns_request,
(caddr_t) & req, (xdrproc_t) xdr_nis_result,
(caddr_t) res, 0)) != RPC_SUCCESS)
res->status = status;
nis_destroy_object (req.ns_object.ns_object_val);
return res;
}

308
nis/nis_print.c Normal file
View File

@ -0,0 +1,308 @@
/* 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 <time.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
static const char *
nis_nstype2str (const nstype type)
{
switch (type)
{
case NIS:
return N_("NIS");
case SUNYP:
return N_("SUNYP");
case IVY:
return N_("IVY");
case DNS:
return N_("DNS");
case X500:
return N_("X500");
case DNANS:
return N_("DNANS");
case XCHS:
return N_("XCHS");
case CDS:
return N_("CDS");
default:
return N_("UNKNOWN");
}
}
static char *
nis_ttl2str (const u_long ttl)
{
static char buf[64];
unsigned long int time, s, m, h;
time = ttl;
h = time / (60 * 60);
time %= (60 * 60);
m = time / 60;
time %= 60;
s = time;
snprintf (buf, 63, "%lu:%02lu:%02lu", h, m, s);
return buf;
}
static char *
nis_flags2str (const u_long flags)
{
static char buf[1024];
snprintf (buf, 1023, "%lu", flags);
return buf;
}
void
nis_print_rights (const u_long access)
{
char result[17];
u_long acc;
int i;
acc = access; /* Parameter is const ! */
result[i = 16] = '\0';
while (i > 0)
{
i -= 4;
result[i + 0] = (acc & NIS_READ_ACC) ? 'r' : '-';
result[i + 1] = (acc & NIS_MODIFY_ACC) ? 'm' : '-';
result[i + 2] = (acc & NIS_CREATE_ACC) ? 'c' : '-';
result[i + 3] = (acc & NIS_DESTROY_ACC) ? 'd' : '-';
acc >>= 8;
}
printf ("%s", result);
}
void
nis_print_directory (const directory_obj *dir)
{
nis_server *sptr;
unsigned int i;
printf (_("Name : '%s'\n"), dir->do_name);
printf (_("Type : %s\n"), gettext (nis_nstype2str (dir->do_type)));
sptr = dir->do_servers.do_servers_val;
for (i = 0; i < dir->do_servers.do_servers_len; i++)
{
if (i == 0)
fputs (_("Master Server :\n"), stdout);
else
fputs (_("Replicate :\n"), stdout);
printf (_("\tName : %s\n"), sptr->name);
fputs (_("\tPublic Key : "), stdout);
switch (sptr->key_type)
{
case NIS_PK_NONE:
fputs (_("None.\n"), stdout);
break;
case NIS_PK_DH:
fputs (_("DH.\n"), stdout);
break;
case NIS_PK_RSA:
fputs (_("RSA.\n"), stdout);
break;
case NIS_PK_KERB:
fputs (_("Kerberous.\n"), stdout);
break;
default:
fputs (_("Unknown.\n"), stdout);
break;
}
if (sptr->ep.ep_len != 0)
{
unsigned int j;
endpoint *ptr;
ptr = sptr->ep.ep_val;
printf (_("\tUniversal addresses (%u)\n"), sptr->ep.ep_len);
for (j = 0; j < sptr->ep.ep_len; j++)
{
printf ("\t[%d] - ", j + 1);
if (ptr->proto != NULL && strlen (ptr->proto) > 0)
printf ("%s, ", ptr->proto);
else
printf ("-, ");
if (ptr->family != NULL && strlen (ptr->family) > 0)
printf ("%s, ", ptr->family);
else
printf ("-, ");
if (ptr->uaddr != NULL && strlen (ptr->uaddr) > 0)
printf ("%s\n", ptr->uaddr);
else
printf ("-\n");
ptr++;
}
}
sptr++;
}
printf (_("Time to live : %s\n"), nis_ttl2str (dir->do_ttl));
if (dir->do_armask.do_armask_len != 0)
{
oar_mask *ptr;
ptr = dir->do_armask.do_armask_val;
for (i = 0; i < dir->do_armask.do_armask_len; i++)
{
fputs (_("Default Access rights: "), stdout);
nis_print_rights (ptr->oa_rights);
printf (_("\nDirect Type : %d\n"), ptr->oa_otype);
ptr++;
}
}
}
void
nis_print_group (const group_obj *obj)
{
unsigned int i;
fputs (_("Group Flags :"), stdout);
if (obj->gr_flags)
printf ("0x%08lX", obj->gr_flags);
fputs (_("\nGroup Members :\n"), stdout);
for (i = 0; i < obj->gr_members.gr_members_len; i++)
printf ("\t%s\n", obj->gr_members.gr_members_val[i]);
}
void
nis_print_table (const table_obj *obj)
{
unsigned int i;
printf (_("Table Type : %s\n"), obj->ta_type);
printf (_("Number of Columns : %d\n"), obj->ta_maxcol);
printf (_("Character Separator : %c\n"), obj->ta_sep);
printf (_("Search Path : %s\n"), obj->ta_path);
fputs (_("Columns :\n"), stdout);
for (i = 0; i < obj->ta_cols.ta_cols_len; i++)
{
printf (_("\t[%d]\tName : %s\n"), i,
obj->ta_cols.ta_cols_val[i].tc_name);
printf (_("\t\tAttributes : %s\n"),
nis_flags2str (obj->ta_cols.ta_cols_val[i].tc_flags));
fputs (_("\t\tAccess Rights : "), stdout);
nis_print_rights (obj->ta_cols.ta_cols_val[i].tc_rights);
fputc ('\n', stdout);
}
}
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);
}
void
nis_print_entry (const entry_obj *obj)
{
unsigned int i;
printf (_("\tEntry data of type %s\n"), obj->en_type);
for (i = 0; i < obj->en_cols.en_cols_len; i++)
{
printf (_("\t[%u] - [%u bytes] "), i,
obj->en_cols.en_cols_val[i].ec_value.ec_value_len);
if ((obj->en_cols.en_cols_val[i].ec_flags & EN_CRYPT) == EN_CRYPT)
fputs (_("Encrypted data\n"), stdout);
else if ((obj->en_cols.en_cols_val[i].ec_flags & EN_BINARY) == EN_BINARY)
fputs (_("Binary data\n"), stdout);
else
printf ("%s\n", obj->en_cols.en_cols_val[i].ec_value.ec_value_val);
}
}
void
nis_print_object (const nis_object * obj)
{
printf (_("Object Name : %s\n"), obj->zo_name);
printf (_("Directory : %s\n"), obj->zo_domain);
printf (_("Owner : %s\n"), obj->zo_owner);
printf (_("Group : %s\n"), obj->zo_group);
fputs (_("Access Rights : "), stdout);
nis_print_rights (obj->zo_access);
printf (_("\nTime to Live : %lu (seconds)\n"), obj->zo_ttl);
printf (_("Creation Time : %s"), ctime (&obj->zo_oid.ctime));
printf (_("Mod. Time : %s"), ctime (&obj->zo_oid.mtime));
fputs (_("Object Type : "), stdout);
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;
}
}
void
nis_print_result (const nis_result *res)
{
unsigned int i;
printf (_("Status : %s\n"), nis_sperrno (res->status));
printf (_("Number of objects : %u\n"), res->objects.objects_len);
for (i = 0; i < res->objects.objects_len; i++)
{
printf (_("Object #%d:\n"), i);
nis_print_object (&res->objects.objects_val[i]);
}
}

143
nis/nis_server.c Normal file
View File

@ -0,0 +1,143 @@
/* 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 <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
#include "nis_intern.h"
nis_error
nis_mkdir (const nis_name dir, const nis_server *server)
{
nis_error res;
if (server == NULL)
{
int result;
if ((result = __do_niscall (NULL, 0, NIS_MKDIR, (xdrproc_t) xdr_nis_name,
(caddr_t) dir, (xdrproc_t) xdr_nis_error,
(caddr_t) & res, 0)) != RPC_SUCCESS)
{
fprintf (stderr, _("__do_niscall: Error #%d\n"), result);
return NIS_RPCERROR;
}
}
else
{
int result;
if ((result = __do_niscall (server, 1, NIS_MKDIR,
(xdrproc_t) xdr_nis_name,
(caddr_t) dir, (xdrproc_t) xdr_nis_error,
(caddr_t) & res, 0)) != RPC_SUCCESS)
{
fprintf (stderr, _("__do_niscall: Error #%d\n"), result);
return NIS_RPCERROR;
}
}
return res;
}
nis_error
nis_rmdir (const nis_name dir, const nis_server *server)
{
nis_error res;
if (server == NULL)
{
int result;
if ((result = __do_niscall (NULL, 0, NIS_RMDIR, (xdrproc_t) xdr_nis_name,
(caddr_t) dir, (xdrproc_t) xdr_nis_error,
(caddr_t) & res, 0)) != RPC_SUCCESS)
{
fprintf (stderr, _("__do_niscall: Error #%d\n"), result);
return NIS_RPCERROR;
}
}
else
{
int result;
if ((result = __do_niscall (server, 1, NIS_RMDIR,
(xdrproc_t) xdr_nis_name,
(caddr_t) dir, (xdrproc_t) xdr_nis_error,
(caddr_t) & res, 0)) != RPC_SUCCESS)
{
fprintf (stderr, _("__do_niscall: Error #%d\n"), result);
return NIS_RPCERROR;
}
}
return res;
}
nis_error
nis_servstate (const nis_server *serv, const nis_tag *tags,
const int numtags, nis_tag **result)
{
*result = NULL;
return NIS_FAIL;
}
stub_warning (nis_servstate)
nis_error
nis_stats (const nis_server *serv, const nis_tag *tags,
const int numtags, nis_tag **result)
{
result = malloc (sizeof (nis_tag *));
if (result != NULL)
result[0] = NULL;
return NIS_FAIL;
}
stub_warning (nis_stats);
void
nis_freetags (nis_tag *tags, const int numtags)
{
int i;
for (i = 0; i < numtags; ++i)
free (tags->tag_val);
free (tags);
}
nis_server **
nis_getservlist (const nis_name dir)
{
nis_server **serv;
serv = malloc (sizeof (nis_server *));
if (serv != NULL)
serv[0] = NULL;
return serv;
}
stub_warning (nis_getservlist);
void
nis_freeservlist (nis_server **serv)
{
int i;
if (serv == NULL)
return;
i = 0;
while (serv[i] != NULL)
nis_free_servers (serv[i], 1);
free (serv);
}

310
nis/nis_subr.c Normal file
View File

@ -0,0 +1,310 @@
/* 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 <errno.h>
#include <string.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
nis_name
nis_leaf_of (const nis_name name)
{
static char result[NIS_MAXNAMELEN + 1];
return nis_leaf_of_r (name, result, NIS_MAXNAMELEN);
}
nis_name
nis_leaf_of_r (const nis_name name, char *buffer, size_t buflen)
{
size_t i = 0;
buffer[0] = '\0';
while (name[i] != '.' && name[i] != '\0')
i++;
if (i > buflen - 1)
{
errno = ERANGE;
return NULL;
}
if (i > 1)
strncpy (buffer, name, i - 1);
return buffer;
}
nis_name
nis_name_of (const nis_name name)
{
static char result[NIS_MAXNAMELEN + 1];
return nis_name_of_r (name, result, NIS_MAXNAMELEN);
}
nis_name
nis_name_of_r (const nis_name name, char *buffer, size_t buflen)
{
char *local_domain;
int diff;
local_domain = nis_local_directory ();
diff = strlen (name) - strlen (local_domain);
if (diff <= 0)
return NULL;
if (strcmp (&name[diff], local_domain) != 0)
return NULL;
if ((size_t) diff >= buflen)
{
errno = ERANGE;
return NULL;
}
memcpy (buffer, name, diff - 1);
buffer[diff - 1] = '\0';
if (diff - 1 == 0)
return NULL;
return buffer;
}
nis_name
nis_domain_of (const nis_name name)
{
static char result[NIS_MAXNAMELEN + 1];
return nis_domain_of_r (name, result, NIS_MAXNAMELEN);
}
nis_name
nis_domain_of_r (const nis_name name, char *buffer, size_t buflen)
{
char *cptr;
size_t cptr_len;
cptr = strchr (name, '.'); /* XXX What happens if the NIS name
does not contain a `.'? */
++cptr;
cptr_len = strlen (cptr);
if (cptr_len == 0)
strcpy (buffer, ".");
else if (cptr_len >= buflen)
{
errno = ERANGE;
return NULL;
}
else
memcpy (buffer, cptr, cptr_len + 1);
return buffer;
}
static int
count_dots (const nis_name str)
{
int count = 0;
size_t i;
for (i = 0; i < strlen (str); ++i)
if (str[i] == '.')
++count;
return count;
}
nis_name *
nis_getnames (const nis_name 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 (count_dots (cptr) >= 2)
{
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);
*tmp++ = '.';
stpcpy (tmp, cptr);
++pos;
while (*cptr != '.')
++cptr;
++cptr;
}
}
else
{
char *tmp;
if (cp[strlen (cp) - 1] == '$')
{
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);
}
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 *));
if (getnames == NULL)
return NULL;
}
getnames[pos] = tmp;
++pos;
}
cp = strtok (NULL, ":");
}
getnames[pos] = NULL;
return getnames;
}
void
nis_freenames (nis_name *names)
{
int i = 0;
while (names[i] != NULL)
{
free (names[i]);
++i;
}
free (names);
}
name_pos
nis_dir_cmp (const nis_name n1, const nis_name n2)
{
int len1, len2;
len1 = strlen (n1);
len2 = strlen (n2);
if (len1 == len2)
{
if (strcmp (n1, n2) == 0)
return SAME_NAME;
else
return NOT_SEQUENTIAL;
}
if (len1 < len2)
{
if (n2[len2 - len1 - 1] != '.')
return NOT_SEQUENTIAL;
else if (strcmp (&n2[len2 - len1], n1) == 0)
return HIGHER_NAME;
else
return NOT_SEQUENTIAL;
}
else
{
if (n1[len1 - len2 - 1] != '.')
return NOT_SEQUENTIAL;
else if (strcmp (&n1[len1 - len2], n2) == 0)
return LOWER_NAME;
else
return NOT_SEQUENTIAL;
}
}
void
nis_destroy_object (nis_object *obj)
{
nis_free_object (obj);
}

417
nis/nis_table.c Normal file
View File

@ -0,0 +1,417 @@
/* 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"
static void
splitname (const nis_name name, nis_name *ibr_name, int *srch_len,
nis_attr **srch_val)
{
char *cptr, *key, *val, *next;
int size;
if (name == NULL)
return;
cptr = strdup (name);
if (srch_len)
*srch_len = 0;
if (srch_val)
*srch_val = NULL;
size = 0;
/* Not of "[key=value,key=value,...],foo.." format? */
if (cptr[0] != '[')
{
*ibr_name = cptr;
return;
}
*ibr_name = strchr (cptr, ']');
if (*ibr_name == NULL || (*ibr_name)[1] != ',')
{
free (cptr);
*ibr_name = NULL;
return;
}
*ibr_name[0] = '\0';
*ibr_name += 2;
*ibr_name = strdup (*ibr_name);
if (srch_len == NULL || srch_val == NULL)
{
free (cptr);
return;
}
key = (cptr) + 1;
do
{
next = strchr (key, ',');
if (next)
{
next[0] = '\0';
++next;
}
val = strchr (key, '=');
if (!val)
{
free (cptr);
*srch_val = malloc (sizeof (char *));
if (*srch_val == NULL)
{
free (cptr);
free (*ibr_name);
*ibr_name = NULL;
return;
}
(*srch_val)[*srch_len].zattr_val.zattr_val_len = 0;
(*srch_val)[*srch_len].zattr_val.zattr_val_val = NULL;
return;
}
val[0] = '\0';
++val;
if ((*srch_len) + 1 >= size)
{
size += 10;
if (size == 10)
*srch_val = malloc (size * sizeof (char *));
else
*srch_val = realloc (val, size * sizeof (char *));
if (*srch_val == NULL)
{
free (cptr);
free (*ibr_name);
*ibr_name = NULL;
return;
}
}
(*srch_val)[*srch_len].zattr_ndx = strdup (key);
if (((*srch_val)[*srch_len].zattr_ndx) == NULL)
{
free (cptr);
free (*ibr_name);
*ibr_name = NULL;
return;
}
(*srch_val)[*srch_len].zattr_val.zattr_val_len = strlen (val) + 1;
(*srch_val)[*srch_len].zattr_val.zattr_val_val = strdup (val);
if ((*srch_val)[*srch_len].zattr_val.zattr_val_val == NULL)
{
free (cptr);
free (*ibr_name);
*ibr_name = NULL;
return;
}
++(*srch_len);
key = next;
}
while (next);
free (cptr);
}
static struct ib_request *
__create_ib_request (const nis_name name, struct ib_request *ibreq,
u_long flags)
{
splitname (name, &ibreq->ibr_name, &ibreq->ibr_srch.ibr_srch_len,
&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 |
MOD_EXCLUSIVE));
ibreq->ibr_obj.ibr_obj_len = 0;
ibreq->ibr_obj.ibr_obj_val = NULL;
ibreq->ibr_cbhost.ibr_cbhost_len = 0;
ibreq->ibr_cbhost.ibr_cbhost_val = NULL;
ibreq->ibr_bufsize = 0;
ibreq->ibr_cookie.n_len = 0;
ibreq->ibr_cookie.n_bytes = NULL;
return ibreq;
}
nis_result *
nis_list (const nis_name name, const u_long flags,
int (*callback) (const nis_name name,
const nis_object *object,
const void *userdata),
const void *userdata)
{
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 */
res = calloc (1, sizeof (nis_result));
if (__create_ib_request (name, &ibreq, flags) == NULL)
{
res->status = NIS_BADNAME;
return res;
}
while (is_link)
{
memset (res, '\0', sizeof (nis_result));
if ((result = __do_niscall (NULL, 0, NIS_IBLIST,
(xdrproc_t) xdr_ib_request,
(caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
(caddr_t) res, flags)) != RPC_SUCCESS)
{
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)
{
if (count_links == 16)
{
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;
}
}
else
{
res->status = NIS_NOTSEARCHABLE;
return res;
}
}
}
if (callback != NULL &&
(res->status == NIS_SUCCESS || res->status == NIS_S_SUCCESS))
{
unsigned int i;
for (i = 0; i < res->objects.objects_len; ++i)
if ((*callback) (name, &(res->objects.objects_val)[i], userdata) != 0)
break;
}
return res;
}
nis_result *
nis_add_entry (const nis_name name, const nis_object *obj,
const u_long flags)
{
nis_result *res;
struct ib_request ibreq;
nis_error status;
res = calloc (1, sizeof (nis_result));
if (__create_ib_request (name, &ibreq, flags) == NULL)
{
res->status = NIS_BADNAME;
return res;
}
ibreq.ibr_flags = flags;
ibreq.ibr_obj.ibr_obj_val = nis_clone_object (obj, NULL);
ibreq.ibr_obj.ibr_obj_len = 1;
if ((status = __do_niscall (NULL, 0, NIS_IBADD,
(xdrproc_t) xdr_ib_request,
(caddr_t) & ibreq,
(xdrproc_t) xdr_nis_result,
(caddr_t) res, 0)) != RPC_SUCCESS)
res->status = status;
nis_free_request (&ibreq);
return res;
}
nis_result *
nis_modify_entry (const nis_name name, const nis_object *obj,
const u_long flags)
{
nis_result *res;
struct ib_request ibreq;
nis_error status;
res = calloc (1, sizeof (nis_result));
if (__create_ib_request (name, &ibreq, flags) == NULL)
{
res->status = NIS_BADNAME;
return res;
}
ibreq.ibr_flags = flags;
ibreq.ibr_obj.ibr_obj_val = nis_clone_object (obj, NULL);
ibreq.ibr_obj.ibr_obj_len = 1;
if ((status = __do_niscall (NULL, 0, NIS_IBMODIFY,
(xdrproc_t) xdr_ib_request,
(caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
(caddr_t) res, 0)) != RPC_SUCCESS)
res->status = status;
nis_free_request (&ibreq);
return res;
}
nis_result *
nis_remove_entry (const nis_name name, const nis_object *obj,
const u_long flags)
{
nis_result *res;
struct ib_request ibreq;
nis_error status;
res = calloc (1, sizeof (nis_result));
if (__create_ib_request (name, &ibreq, flags) == NULL)
{
res->status = NIS_BADNAME;
return res;
}
ibreq.ibr_flags = flags;
if (obj != NULL)
{
ibreq.ibr_obj.ibr_obj_val = nis_clone_object (obj, NULL);
ibreq.ibr_obj.ibr_obj_len = 1;
}
if ((status = __do_niscall (NULL, 0, NIS_IBREMOVE,
(xdrproc_t) xdr_ib_request,
(caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
(caddr_t) res, 0)) != RPC_SUCCESS)
res->status = status;
nis_free_request (&ibreq);
return res;
}
nis_result *
nis_first_entry (const nis_name name)
{
nis_result *res;
struct ib_request ibreq;
nis_error status;
res = calloc (1, sizeof (nis_result));
if (__create_ib_request (name, &ibreq, 0) == NULL)
{
res->status = NIS_BADNAME;
return res;
}
if ((status = __do_niscall (NULL, 0, NIS_IBFIRST, (xdrproc_t) xdr_ib_request,
(caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
(caddr_t) res, 0)) != RPC_SUCCESS)
res->status = status;
nis_free_request (&ibreq);
return res;
}
nis_result *
nis_next_entry (const nis_name name, const netobj *cookie)
{
nis_result *res;
struct ib_request ibreq;
nis_error status;
res = calloc (1, sizeof (nis_result));
if (__create_ib_request (name, &ibreq, 0) == NULL)
{
res->status = NIS_BADNAME;
return res;
}
if (cookie != NULL)
{
ibreq.ibr_cookie.n_bytes = malloc (cookie->n_len);
if (ibreq.ibr_cookie.n_bytes == NULL)
{
res->status = NIS_NOMEMORY;
free (res);
return NULL;
}
memcpy (ibreq.ibr_cookie.n_bytes, cookie->n_bytes, cookie->n_len);
ibreq.ibr_cookie.n_len = cookie->n_len;
}
if ((status = __do_niscall (NULL, 0, NIS_IBNEXT, (xdrproc_t) xdr_ib_request,
(caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
(caddr_t) res, 0)) != RPC_SUCCESS)
res->status = status;
nis_free_request (&ibreq);
return res;
}

572
nis/nis_xdr.c Normal file
View File

@ -0,0 +1,572 @@
/* 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 <rpcsvc/nis.h>
bool_t
xdr_nis_attr (XDR *xdrs, nis_attr *objp)
{
if (!xdr_string (xdrs, &objp->zattr_ndx, ~0))
return FALSE;
if (!xdr_bytes (xdrs, (char **) &objp->zattr_val.zattr_val_val,
(u_int *) & objp->zattr_val.zattr_val_len, ~0))
return FALSE;
return TRUE;
}
bool_t
xdr_nis_name (XDR *xdrs, nis_name *objp)
{
if (!xdr_string (xdrs, objp, ~0))
return FALSE;
return TRUE;
}
bool_t
xdr_zotypes (XDR *xdrs, zotypes *objp)
{
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
return TRUE;
}
bool_t
xdr_nstype (XDR *xdrs, nstype *objp)
{
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
return TRUE;
}
bool_t
xdr_oar_mask (XDR *xdrs, oar_mask *objp)
{
if (!xdr_u_long (xdrs, &objp->oa_rights))
return FALSE;
if (!xdr_zotypes (xdrs, &objp->oa_otype))
return FALSE;
return TRUE;
}
bool_t
xdr_endpoint (XDR *xdrs, endpoint *objp)
{
if (!xdr_string (xdrs, &objp->uaddr, ~0))
return FALSE;
if (!xdr_string (xdrs, &objp->family, ~0))
return FALSE;
if (!xdr_string (xdrs, &objp->proto, ~0))
return FALSE;
return TRUE;
}
bool_t
xdr_nis_server (XDR *xdrs, nis_server *objp)
{
if (!xdr_nis_name (xdrs, &objp->name))
return FALSE;
if (!xdr_array (xdrs, (char **) &objp->ep.ep_val, (u_int *) &objp->ep.ep_len,
~0, sizeof (endpoint), (xdrproc_t) xdr_endpoint))
return FALSE;
if (!xdr_u_long (xdrs, &objp->key_type))
return FALSE;
if (!xdr_netobj (xdrs, &objp->pkey))
return FALSE;
return TRUE;
}
bool_t
xdr_directory_obj (XDR *xdrs, directory_obj *objp)
{
if (!xdr_nis_name (xdrs, &objp->do_name))
return FALSE;
if (!xdr_nstype (xdrs, &objp->do_type))
return FALSE;
if (!xdr_array (xdrs, (char **) &objp->do_servers.do_servers_val,
(u_int *) & objp->do_servers.do_servers_len, ~0,
sizeof (nis_server), (xdrproc_t) xdr_nis_server))
return FALSE;
if (!xdr_u_long (xdrs, &objp->do_ttl))
return FALSE;
if (!xdr_array (xdrs, (char **) &objp->do_armask.do_armask_val,
(u_int *) & objp->do_armask.do_armask_len, ~0,
sizeof (oar_mask), (xdrproc_t) xdr_oar_mask))
return FALSE;
return TRUE;
}
bool_t
xdr_entry_col (XDR *xdrs, entry_col *objp)
{
if (!xdr_u_long (xdrs, &objp->ec_flags))
return FALSE;
if (!xdr_bytes (xdrs, (char **) &objp->ec_value.ec_value_val,
(u_int *) &objp->ec_value.ec_value_len, ~0))
return FALSE;
return TRUE;
}
bool_t
xdr_entry_obj (XDR *xdrs, entry_obj *objp)
{
if (!xdr_string (xdrs, &objp->en_type, ~0))
return FALSE;
if (!xdr_array (xdrs, (char **) &objp->en_cols.en_cols_val,
(u_int *) &objp->en_cols.en_cols_len, ~0,
sizeof (entry_col), (xdrproc_t) xdr_entry_col))
return FALSE;
return TRUE;
}
bool_t
xdr_group_obj (XDR *xdrs, group_obj *objp)
{
if (!xdr_u_long (xdrs, &objp->gr_flags))
return FALSE;
if (!xdr_array (xdrs, (char **) &objp->gr_members.gr_members_val,
(u_int *) &objp->gr_members.gr_members_len, ~0,
sizeof (nis_name), (xdrproc_t) xdr_nis_name))
return FALSE;
return TRUE;
}
bool_t
xdr_link_obj (XDR *xdrs, link_obj *objp)
{
if (!xdr_zotypes (xdrs, &objp->li_rtype))
return FALSE;
if (!xdr_array (xdrs, (char **) &objp->li_attrs.li_attrs_val,
(u_int *) &objp->li_attrs.li_attrs_len, ~0,
sizeof (nis_attr), (xdrproc_t) xdr_nis_attr))
return FALSE;
if (!xdr_nis_name (xdrs, &objp->li_name))
return FALSE;
return TRUE;
}
bool_t
xdr_table_col (XDR *xdrs, table_col *objp)
{
if (!xdr_string (xdrs, &objp->tc_name, 64))
return FALSE;
if (!xdr_u_long (xdrs, &objp->tc_flags))
return FALSE;
if (!xdr_u_long (xdrs, &objp->tc_rights))
return FALSE;
return TRUE;
}
bool_t
xdr_table_obj (XDR *xdrs, table_obj *objp)
{
if (!xdr_string (xdrs, &objp->ta_type, 64))
return FALSE;
if (!xdr_int (xdrs, &objp->ta_maxcol))
return FALSE;
if (!xdr_u_char (xdrs, &objp->ta_sep))
return FALSE;
if (!xdr_array (xdrs, (char **) &objp->ta_cols.ta_cols_val,
(u_int *) &objp->ta_cols.ta_cols_len, ~0,
sizeof (table_col), (xdrproc_t) xdr_table_col))
return FALSE;
if (!xdr_string (xdrs, &objp->ta_path, ~0))
return FALSE;
return TRUE;
}
bool_t
xdr_objdata (XDR *xdrs, objdata *objp)
{
if (!xdr_zotypes (xdrs, &objp->zo_type))
return FALSE;
switch (objp->zo_type)
{
case DIRECTORY_OBJ:
if (!xdr_directory_obj (xdrs, &objp->objdata_u.di_data))
return FALSE;
break;
case GROUP_OBJ:
if (!xdr_group_obj (xdrs, &objp->objdata_u.gr_data))
return FALSE;
break;
case TABLE_OBJ:
if (!xdr_table_obj (xdrs, &objp->objdata_u.ta_data))
return FALSE;
break;
case ENTRY_OBJ:
if (!xdr_entry_obj (xdrs, &objp->objdata_u.en_data))
return FALSE;
break;
case LINK_OBJ:
if (!xdr_link_obj (xdrs, &objp->objdata_u.li_data))
return FALSE;
break;
case PRIVATE_OBJ:
if (!xdr_bytes (xdrs, (char **) &objp->objdata_u.po_data.po_data_val,
(u_int *) & objp->objdata_u.po_data.po_data_len, ~0))
return FALSE;
break;
case NO_OBJ:
break;
case BOGUS_OBJ:
break;
default:
break;
}
return TRUE;
}
bool_t
xdr_nis_oid (XDR *xdrs, nis_oid *objp)
{
if (!xdr_u_long (xdrs, &objp->ctime))
return FALSE;
if (!xdr_u_long (xdrs, &objp->mtime))
return FALSE;
return TRUE;
}
bool_t
xdr_nis_object (XDR *xdrs, nis_object *objp)
{
if (!xdr_nis_oid (xdrs, &objp->zo_oid))
return FALSE;
if (!xdr_nis_name (xdrs, &objp->zo_name))
return FALSE;
if (!xdr_nis_name (xdrs, &objp->zo_owner))
return FALSE;
if (!xdr_nis_name (xdrs, &objp->zo_group))
return FALSE;
if (!xdr_nis_name (xdrs, &objp->zo_domain))
return FALSE;
if (!xdr_u_long (xdrs, &objp->zo_access))
return FALSE;
if (!xdr_u_long (xdrs, &objp->zo_ttl))
return FALSE;
if (!xdr_objdata (xdrs, &objp->zo_data))
return FALSE;
return TRUE;
}
bool_t
xdr_nis_error (XDR *xdrs, nis_error *objp)
{
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
return TRUE;
}
bool_t
xdr_nis_result (XDR *xdrs, nis_result *objp)
{
register long *buf;
if (xdrs->x_op == XDR_ENCODE)
{
if (!xdr_nis_error (xdrs, &objp->status))
return FALSE;
if (!xdr_array (xdrs, (char **) &objp->objects.objects_val,
(u_int *) &objp->objects.objects_len, ~0,
sizeof (nis_object), (xdrproc_t) xdr_nis_object))
return FALSE;
if (!xdr_netobj (xdrs, &objp->cookie))
return FALSE;
buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
if (buf == NULL)
{
if (!xdr_u_long (xdrs, &objp->zticks))
{
return FALSE;
}
if (!xdr_u_long (xdrs, &objp->dticks))
{
return FALSE;
}
if (!xdr_u_long (xdrs, &objp->aticks))
{
return FALSE;
}
if (!xdr_u_long (xdrs, &objp->cticks))
{
return FALSE;
}
}
else
{
IXDR_PUT_U_LONG (buf, objp->zticks);
IXDR_PUT_U_LONG (buf, objp->dticks);
IXDR_PUT_U_LONG (buf, objp->aticks);
IXDR_PUT_U_LONG (buf, objp->cticks);
}
return TRUE;
}
else if (xdrs->x_op == XDR_DECODE)
{
if (!xdr_nis_error (xdrs, &objp->status))
{
return FALSE;
}
if (!xdr_array (xdrs, (char **) &objp->objects.objects_val,
(u_int *) &objp->objects.objects_len, ~0,
sizeof (nis_object), (xdrproc_t) xdr_nis_object))
{
return FALSE;
}
if (!xdr_netobj (xdrs, &objp->cookie))
{
return FALSE;
}
buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
if (buf == NULL)
{
if (!xdr_u_long (xdrs, &objp->zticks))
{
return FALSE;
}
if (!xdr_u_long (xdrs, &objp->dticks))
{
return FALSE;
}
if (!xdr_u_long (xdrs, &objp->aticks))
{
return FALSE;
}
if (!xdr_u_long (xdrs, &objp->cticks))
{
return FALSE;
}
}
else
{
objp->zticks = IXDR_GET_U_LONG (buf);
objp->dticks = IXDR_GET_U_LONG (buf);
objp->aticks = IXDR_GET_U_LONG (buf);
objp->cticks = IXDR_GET_U_LONG (buf);
}
return TRUE;
}
if (!xdr_nis_error (xdrs, &objp->status))
{
return FALSE;
}
if (!xdr_array (xdrs, (char **) &objp->objects.objects_val,
(u_int *) &objp->objects.objects_len, ~0,
sizeof (nis_object), (xdrproc_t) xdr_nis_object))
{
return FALSE;
}
if (!xdr_netobj (xdrs, &objp->cookie))
{
return FALSE;
}
if (!xdr_u_long (xdrs, &objp->zticks))
{
return FALSE;
}
if (!xdr_u_long (xdrs, &objp->dticks))
{
return FALSE;
}
if (!xdr_u_long (xdrs, &objp->aticks))
{
return FALSE;
}
if (!xdr_u_long (xdrs, &objp->cticks))
{
return FALSE;
}
return TRUE;
}
bool_t
xdr_ns_request (XDR *xdrs, ns_request *objp)
{
if (!xdr_nis_name (xdrs, &objp->ns_name))
return FALSE;
if (!xdr_array (xdrs, (char **) &objp->ns_object.ns_object_val,
(u_int *) &objp->ns_object.ns_object_len, 1,
sizeof (nis_object), (xdrproc_t) xdr_nis_object))
return FALSE;
return TRUE;
}
bool_t
xdr_ib_request (XDR *xdrs, ib_request *objp)
{
if (!xdr_nis_name (xdrs, &objp->ibr_name))
return FALSE;
if (!xdr_array (xdrs, (char **) &objp->ibr_srch.ibr_srch_val,
(u_int *) &objp->ibr_srch.ibr_srch_len, ~0,
sizeof (nis_attr), (xdrproc_t) xdr_nis_attr))
return FALSE;
if (!xdr_u_long (xdrs, &objp->ibr_flags))
return FALSE;
if (!xdr_array (xdrs, (char **) &objp->ibr_obj.ibr_obj_val,
(u_int *) &objp->ibr_obj.ibr_obj_len, 1,
sizeof (nis_object), (xdrproc_t) xdr_nis_object))
return FALSE;
if (!xdr_array (xdrs, (char **) &objp->ibr_cbhost.ibr_cbhost_val,
(u_int *) &objp->ibr_cbhost.ibr_cbhost_len, 1,
sizeof (nis_server), (xdrproc_t) xdr_nis_server))
return FALSE;
if (!xdr_u_long (xdrs, &objp->ibr_bufsize))
return FALSE;
if (!xdr_netobj (xdrs, &objp->ibr_cookie))
return FALSE;
return TRUE;
}
bool_t
xdr_ping_args (XDR *xdrs, ping_args *objp)
{
if (!xdr_nis_name (xdrs, &objp->dir))
return FALSE;
if (!xdr_u_long (xdrs, &objp->stamp))
return FALSE;
return TRUE;
}
bool_t
xdr_log_entry_t (XDR *xdrs, log_entry_t *objp)
{
if (!xdr_enum (xdrs, (enum_t *) objp))
return FALSE;
return TRUE;
}
bool_t
xdr_log_entry (XDR *xdrs, log_entry *objp)
{
if (!xdr_u_long (xdrs, &objp->le_time))
return FALSE;
if (!xdr_log_entry_t (xdrs, &objp->le_type))
return FALSE;
if (!xdr_nis_name (xdrs, &objp->le_princp))
return FALSE;
if (!xdr_nis_name (xdrs, &objp->le_name))
return FALSE;
if (!xdr_array (xdrs, (char **) &objp->le_attrs.le_attrs_val,
(u_int *) &objp->le_attrs.le_attrs_len, ~0,
sizeof (nis_attr), (xdrproc_t) xdr_nis_attr))
return FALSE;
if (!xdr_nis_object (xdrs, &objp->le_object))
return FALSE;
return TRUE;
}
bool_t
xdr_log_result (XDR *xdrs, log_result *objp)
{
if (!xdr_nis_error (xdrs, &objp->lr_status))
{
return FALSE;
}
if (!xdr_netobj (xdrs, &objp->lr_cookie))
{
return FALSE;
}
if (!xdr_array (xdrs, (char **) &objp->lr_entries.lr_entries_val,
(u_int *) &objp->lr_entries.lr_entries_len, ~0,
sizeof (log_entry), (xdrproc_t) xdr_log_entry))
{
return FALSE;
}
return TRUE;
}
bool_t
xdr_cp_result (XDR *xdrs, cp_result *objp)
{
if (!xdr_nis_error (xdrs, &objp->cp_status))
return FALSE;
if (!xdr_u_long (xdrs, &objp->cp_zticks))
return FALSE;
if (!xdr_u_long (xdrs, &objp->cp_dticks))
return FALSE;
return TRUE;
}
bool_t
xdr_nis_tag (XDR *xdrs, nis_tag *objp)
{
if (!xdr_u_long (xdrs, &objp->tag_type))
{
return FALSE;
}
if (!xdr_string (xdrs, &objp->tag_val, 1024))
{
return FALSE;
}
return TRUE;
}
bool_t
xdr_nis_taglist (XDR *xdrs, nis_taglist *objp)
{
if (!xdr_array (xdrs, (char **) &objp->tags.tags_val,
(u_int *) &objp->tags.tags_len, ~0, sizeof (nis_tag),
(xdrproc_t) xdr_nis_tag))
return FALSE;
return TRUE;
}
bool_t
xdr_dump_args (XDR *xdrs, dump_args *objp)
{
if (!xdr_nis_name (xdrs, &objp->da_dir))
return FALSE;
if (!xdr_u_long (xdrs, &objp->da_time))
return FALSE;
if (!xdr_array (xdrs, (char **) &objp->da_cbhost.da_cbhost_val,
(u_int *) &objp->da_cbhost.da_cbhost_len, 1,
sizeof (nis_server), (xdrproc_t) xdr_nis_server))
return FALSE;
return TRUE;
}
bool_t
xdr_fd_args (XDR *xdrs, fd_args *objp)
{
if (!xdr_nis_name (xdrs, &objp->dir_name))
return FALSE;
if (!xdr_nis_name (xdrs, &objp->requester))
return FALSE;
return TRUE;
}
bool_t
xdr_fd_result (XDR *xdrs, fd_result *objp)
{
if (!xdr_nis_error (xdrs, &objp->status))
return FALSE;
if (!xdr_nis_name (xdrs, &objp->source))
return FALSE;
if (!xdr_bytes (xdrs, (char **) &objp->dir_data.dir_data_val,
(u_int *) &objp->dir_data.dir_data_len, ~0))
return FALSE;
if (!xdr_bytes (xdrs, (char **) &objp->signature.signature_val,
(u_int *) &objp->signature.signature_len, ~0))
return FALSE;
return TRUE;
}

90
nis/nss-nisplus.h Normal file
View File

@ -0,0 +1,90 @@
/* Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@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 _NIS_NSS_NISPLUS_H
#define _NIS_NSS_NISPLUS_H 1
#include <rpcsvc/nis.h>
#include "nsswitch.h"
/* Convert NIS+ error number to NSS error number. */
static enum nss_status niserr2nss_tab[] =
{
[NIS_SUCCESS] = NSS_STATUS_SUCCESS,
[NIS_S_SUCCESS] = NSS_STATUS_SUCCESS,
[NIS_NOTFOUND] = NSS_STATUS_NOTFOUND,
[NIS_S_NOTFOUND] = NSS_STATUS_TRYAGAIN,
[NIS_CACHEEXPIRED] = NSS_STATUS_UNAVAIL,
[NIS_NAMEUNREACHABLE] = NSS_STATUS_TRYAGAIN,
[NIS_UNKNOWNOBJ] = NSS_STATUS_NOTFOUND,
[NIS_TRYAGAIN] = NSS_STATUS_TRYAGAIN,
[NIS_SYSTEMERROR] = NSS_STATUS_UNAVAIL, /* Maybe TRYAGAIN ? */
[NIS_CHAINBROKEN] = NSS_STATUS_UNAVAIL,
[NIS_PERMISSION] = NSS_STATUS_UNAVAIL,
[NIS_NOTOWNER] = NSS_STATUS_UNAVAIL,
[NIS_NOT_ME] = NSS_STATUS_UNAVAIL,
[NIS_NOMEMORY] = NSS_STATUS_TRYAGAIN,
[NIS_NAMEEXISTS] = NSS_STATUS_UNAVAIL,
[NIS_NOTMASTER] = NSS_STATUS_UNAVAIL,
[NIS_INVALIDOBJ] = NSS_STATUS_UNAVAIL,
[NIS_BADNAME] = NSS_STATUS_UNAVAIL,
[NIS_NOCALLBACK] = NSS_STATUS_UNAVAIL,
[NIS_CBRESULTS] = NSS_STATUS_UNAVAIL,
[NIS_NOSUCHNAME] = NSS_STATUS_NOTFOUND,
[NIS_NOTUNIQUE] = NSS_STATUS_UNAVAIL,
[NIS_IBMODERROR] = NSS_STATUS_UNAVAIL,
[NIS_NOSUCHTABLE] = NSS_STATUS_UNAVAIL,
[NIS_TYPEMISMATCH] = NSS_STATUS_UNAVAIL,
[NIS_LINKNAMEERROR] = NSS_STATUS_UNAVAIL,
[NIS_PARTIAL] = NSS_STATUS_NOTFOUND,
[NIS_TOOMANYATTRS] = NSS_STATUS_UNAVAIL,
[NIS_RPCERROR] = NSS_STATUS_UNAVAIL,
[NIS_BADATTRIBUTE] = NSS_STATUS_UNAVAIL,
[NIS_NOTSEARCHABLE] = NSS_STATUS_UNAVAIL,
[NIS_CBERROR] = NSS_STATUS_UNAVAIL,
[NIS_FOREIGNNS] = NSS_STATUS_UNAVAIL,
[NIS_BADOBJECT] = NSS_STATUS_UNAVAIL,
[NIS_NOTSAMEOBJ] = NSS_STATUS_UNAVAIL,
[NIS_MODFAIL] = NSS_STATUS_UNAVAIL,
[NIS_BADREQUEST] = NSS_STATUS_UNAVAIL,
[NIS_NOTEMPTY] = NSS_STATUS_UNAVAIL,
[NIS_COLDSTART_ERR] = NSS_STATUS_UNAVAIL,
[NIS_RESYNC] = NSS_STATUS_UNAVAIL,
[NIS_FAIL] = NSS_STATUS_UNAVAIL,
[NIS_UNAVAIL] = NSS_STATUS_UNAVAIL,
[NIS_RES2BIG] = NSS_STATUS_UNAVAIL,
[NIS_SRVAUTH] = NSS_STATUS_UNAVAIL,
[NIS_CLNTAUTH] = NSS_STATUS_UNAVAIL,
[NIS_NOFILESPACE] = NSS_STATUS_UNAVAIL,
[NIS_NOPROC] = NSS_STATUS_TRYAGAIN,
[NIS_DUMPLATER] = NSS_STATUS_UNAVAIL
};
#define NISERR_COUNT (sizeof (niserr2nss_tab) / sizeof (niserr2nss_tab[0]))
static inline enum nss_status
niserr2nss (int errval)
{
if ((unsigned int) errval > NISERR_COUNT)
return NSS_STATUS_UNAVAIL;
return niserr2nss_tab[errval];
}
#endif /* nis/nss-nisplus.h */

View File

@ -204,7 +204,7 @@ _nss_nis_getservbyname_r (const char *name, char *protocol,
enum nss_status status;
int found;
if (name == NULL || protocol == NULL)
if (name == NULL)
{
__set_errno (EINVAL);
return NSS_STATUS_UNAVAIL;
@ -219,7 +219,7 @@ _nss_nis_getservbyname_r (const char *name, char *protocol,
((status = internal_nis_getservent_r (serv, buffer, buflen, &data))
== NSS_STATUS_SUCCESS))
{
if (strcmp (serv->s_proto, protocol) == 0)
if (protocol == NULL || strcmp (serv->s_proto, protocol) == 0)
{
char **cp;

View File

@ -0,0 +1,251 @@
/* 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 <nss.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <aliases.h>
#include <libc-lock.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
#include "nss-nisplus.h"
__libc_lock_define_initialized (static, lock)
static nis_result *result = NULL;
static nis_name *names = NULL;
#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)
static int
_nss_nisplus_parse_aliasent (nis_result *result, struct aliasent *alias,
char *buffer, size_t buflen)
{
if (result == NULL)
return -1;
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,
"mail_aliases") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 2)
return -1;
else
{
char *first_unused = buffer + NISENTRYLEN(0, 1, result) + 1;
size_t room_left =
buflen - (buflen % __alignof__ (char *)) -
NISENTRYLEN(0, 1, result) - 2;
char *line;
char *cp;
if (NISENTRYLEN(0, 1, result) >= buflen)
{
/* The line is too long for our buffer. */
no_more_room:
__set_errno (ERANGE);
return -1;
}
else
{
strncpy (buffer, NISENTRYVAL(0, 1, result), NISENTRYLEN(0, 1, result));
buffer[NISENTRYLEN(0, 1, result)] = '\0';
}
if (NISENTRYLEN(0, 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';
alias->alias_name = first_unused;
/* Terminate the line for any case. */
cp = strpbrk (alias->alias_name, "#\n");
if (cp != NULL)
*cp = '\0';
first_unused += strlen (alias->alias_name) +1;
/* Adjust the pointer so it is aligned for
storing pointers. */
first_unused += __alignof__ (char *) - 1;
first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *));
alias->alias_members = (char **) first_unused;
line = buffer;
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 *);
alias->alias_members[alias->alias_members_len] = line;
while (*line != '\0' && *line != ',')
line++;
if (line != alias->alias_members[alias->alias_members_len])
{
*line = '\0';
line++;
alias->alias_members_len++;
}
}
return alias->alias_members_len == 0 ? 0 : 1;
}
}
enum nss_status
_nss_nisplus_setaliasent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_endaliasent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nisplus_getaliasent_r (struct aliasent *alias,
char *buffer, size_t buflen)
{
int parse_res;
/* 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;
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);
} while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getaliasent_r (struct aliasent *result, char *buffer,
size_t buflen)
{
int status;
__libc_lock_lock (lock);
status = internal_nisplus_getaliasent_r (result, buffer, buflen);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_getaliasbyname_r (const char *name, struct aliasent *alias,
char *buffer, size_t buflen)
{
int parse_res;
if (name == NULL || strlen(name) > 8)
return NSS_STATUS_NOTFOUND;
else
{
nis_result *result;
char buf[strlen (name) + 30];
sprintf(buf, "[name=%s],mail_aliases.org_dir", name);
result = nis_list(buf, EXPAND_NAME, NULL, NULL);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
return niserr2nss (result->status);
parse_res = _nss_nisplus_parse_aliasent (result, alias, 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

@ -0,0 +1,278 @@
/* 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 <nss.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <libc-lock.h>
#include <netdb.h>
#include <netinet/ether.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
#include <netinet/if_ether.h>
#include "nss-nisplus.h"
__libc_lock_define_initialized (static, lock)
static nis_result *result = NULL;
static nis_name *names = NULL;
/* 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
functions. */
struct etherent
{
const char *e_name;
struct ether_addr e_addr;
};
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)
#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)
static int
_nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether,
char *buffer, size_t buflen)
{
char *p = buffer;
size_t room_left = buflen;
struct parser_data *data = (void *) buffer;
if (result == NULL)
return -1;
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,
"ethers_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 2)
return -1;
memset (p, '\0', room_left);
/* Generate the ether entry format and use the normal parser */
if (NISENTRYLEN (0, 0, result) +1 > room_left)
{
__set_errno (ERANGE);
return -1;
}
strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
room_left -= (NISENTRYLEN (0, 0, result) +1);
if (NISENTRYLEN (0, 1, result) +1 > room_left)
{
__set_errno (ERANGE);
return -1;
}
strcat (p, "\t");
strncat (p, NISENTRYVAL (0, 1, result), NISENTRYLEN (0, 1, result));
room_left -= (NISENTRYLEN (0, 1, result) + 1);
return _nss_files_parse_etherent (p,ether, data, buflen);
}
enum nss_status
_nss_nisplus_setetherent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_endetherent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nisplus_getetherent_r (struct etherent *ether, char *buffer,
size_t buflen)
{
int parse_res;
/* 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]);
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_etherent (result, ether, buffer, buflen);
} while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getetherent_r (struct etherent *result, char *buffer,
size_t buflen)
{
int status;
__libc_lock_lock (lock);
status = internal_nisplus_getetherent_r (result, buffer, buflen);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_gethostton_r (const char *name, struct etherent *eth,
char *buffer, size_t buflen)
{
int parse_res;
if (name == NULL)
return NSS_STATUS_NOTFOUND;
else
{
nis_result *result;
char buf[strlen (name) + 255];
sprintf(buf, "[name=%s],ethers.org_dir", name);
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;
}
}
enum nss_status
_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 (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;
}

View File

@ -0,0 +1,387 @@
/* 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 <nss.h>
#include <grp.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <libc-lock.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
#include "nss-nisplus.h"
__libc_lock_define_initialized (static, lock);
static nis_result *result = NULL;
static nis_name *names = NULL;
#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)
#define STRUCTURE group
#define ENTNAME grent
struct grent_data {};
#define TRAILING_LIST_MEMBER gr_mem
#define TRAILING_LIST_SEPARATOR_P(c) ((c) == ',')
#include "../../nss/nss_files/files-parse.c"
LINE_PARSER
(,
STRING_FIELD (result->gr_name, ISCOLON, 0);
if (line[0] == '\0'
&& (result->gr_name[0] == '+' || result->gr_name[0] == '-'))
{
result->gr_passwd = NULL;
result->gr_gid = 0;
}
else
{
STRING_FIELD (result->gr_passwd, ISCOLON, 0);
if (result->gr_name[0] == '+' || result->gr_name[0] == '-')
INT_FIELD_MAYBE_NULL (result->gr_gid, ISCOLON, 0, 10, , 0)
else
INT_FIELD (result->gr_gid, ISCOLON, 0, 10,)
}
)
static int
_nss_nisplus_parse_grent (nis_result * result, struct group *gr,
char *buffer, size_t buflen)
{
#if 0
/* XXX here is a bug, sometimes we get some special characters at the
end of a line */
char *first_unused = buffer;
size_t room_left = buflen;
char *line;
int count;
if (result == NULL)
return -1;
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 -1;
if (NISENTRYLEN (0, 0, result) >= room_left)
{
/* The line is too long for our buffer. */
no_more_room:
__set_errno (ERANGE);
return -1;
}
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;
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';
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')
{
/* 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])
{
*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;
#else
char *p = buffer;
size_t room_left = buflen;
struct parser_data *data = (void *) buffer;
if (result == NULL)
return -1;
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 -1;
memset (p, '\0', room_left);
if (NISENTRYLEN (0, 0, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
}
strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
room_left -= (NISENTRYLEN (0, 0, result) + 1);
strcat (p, ":");
if (NISENTRYLEN (0, 1, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
}
strncat (p, NISENTRYVAL (0, 1, result), NISENTRYLEN (0, 1, result));
room_left -= (NISENTRYLEN (0, 1, result) + 1);
strcat (p, ":");
if (NISENTRYLEN (0, 2, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
}
strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result));
room_left -= (NISENTRYLEN (0, 2, result) + 1);
strcat (p, ":");
if (NISENTRYLEN (0, 3, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
}
strncat (p, NISENTRYVAL (0, 3, result), NISENTRYLEN (0, 3, result));
room_left -= (NISENTRYLEN (0, 3, result) + 1);
return _nss_files_parse_grent (p, gr, data, buflen);
#endif
}
enum nss_status
_nss_nisplus_setgrent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_endgrent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nisplus_getgrent_r (struct group *gr, char *buffer, size_t buflen)
{
int parse_res;
/* 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;
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);
}
while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getgrent_r (struct group *result, char *buffer, size_t buflen)
{
int status;
__libc_lock_lock (lock);
status = internal_nisplus_getgrent_r (result, buffer, buflen);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_getgrnam_r (const char *name, struct group *gr,
char *buffer, size_t buflen)
{
int parse_res;
if (name == NULL || strlen (name) > 8)
return NSS_STATUS_NOTFOUND;
else
{
nis_result *result;
char buf[strlen (name) + 24];
sprintf (buf, "[name=%s],group.org_dir", name);
result = nis_list (buf, EXPAND_NAME, 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_grent (result, gr, 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;
}
}
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];
sprintf (buf, "[gid=%d],group.org_dir", gid);
result = nis_list (buf, EXPAND_NAME, 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_grent (result, gr, 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

@ -0,0 +1,412 @@
/* 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 <nss.h>
#include <netdb.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <libc-lock.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
#include "nss-nisplus.h"
__libc_lock_define_initialized (static, lock)
static nis_result *result = NULL;
static nis_name *names = NULL;
#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)
/* Get implementation for some internal functions. */
#include "../../resolv/mapv4v6addr.h"
#include "../../resolv/mapv4v6hostent.h"
#define ENTNAME hostent
#define DATABASE "hosts"
#define NEED_H_ERRNO
#define ENTDATA hostent_data
struct hostent_data
{
unsigned char host_addr[16]; /* IPv4 or IPv6 address. */
char *h_addr_ptrs[2]; /* Points to that and null terminator. */
};
#define TRAILING_LIST_MEMBER h_aliases
#define TRAILING_LIST_SEPARATOR_P isspace
#include "../../nss/nss_files/files-parse.c"
LINE_PARSER
("#",
{
char *addr;
STRING_FIELD (addr, isspace, 1);
/* Parse address. */
if ((_res.options & RES_USE_INET6)
&& inet_pton (AF_INET6, addr, entdata->host_addr) > 0)
{
result->h_addrtype = AF_INET6;
result->h_length = IN6ADDRSZ;
}
else
if (inet_pton (AF_INET, addr, entdata->host_addr) > 0)
{
if (_res.options & RES_USE_INET6)
{
map_v4v6_address ((char *) entdata->host_addr,
(char *) entdata->host_addr);
result->h_addrtype = AF_INET6;
result->h_length = IN6ADDRSZ;
}
else
{
result->h_addrtype = AF_INET;
result->h_length = INADDRSZ;
}
}
else
/* Illegal address: ignore line. */
return 0;
/* Store a pointer to the address in the expected form. */
entdata->h_addr_ptrs[0] = entdata->host_addr;
entdata->h_addr_ptrs[1] = NULL;
result->h_addr_list = entdata->h_addr_ptrs;
/* If we need the host entry in IPv6 form change it now. */
if (_res.options & RES_USE_INET6)
{
char *bufptr = data->linebuffer;
size_t buflen = (char *) data + datalen - bufptr;
map_v4v6_hostent (result, &bufptr, &buflen);
}
STRING_FIELD (result->h_name, isspace, 1);
}
)
static int
_nss_nisplus_parse_hostent (nis_result *result, struct hostent *host,
char *buffer, size_t buflen)
{
char *p = buffer;
size_t room_left = buflen;
int parse_res, i;
struct parser_data *data = (void *) buffer;
if (result == NULL)
return -1;
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)
return -1;
memset (p, '\0', room_left);
/* Generate the hosts entry format and use the normal parser */
if (NISENTRYLEN (0, 2, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
}
strncpy (p, NISENTRYVAL (0, 2, result),
NISENTRYLEN (0, 2, result));
room_left -= (NISENTRYLEN (0, 2, result) + 1);
if (NISENTRYLEN (0, 0, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
}
strcat (p, "\t");
strncat (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
room_left -= (NISENTRYLEN (0, 0, result) + 1);
/* + 1: We overwrite the last \0 */
for (i = 1; i < result->objects.objects_len; i++)
{
if (NISENTRYLEN (i, 1, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
}
strcat (p, " ");
strcat (p, NISENTRYVAL (i, 1, result));
room_left -= (NISENTRYLEN (i, 1, result) + 1);
}
parse_res = parse_line (p, host, data, buflen);
return parse_res;
}
enum nss_status
_nss_nisplus_sethostent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_endhostent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nisplus_gethostent_r (struct hostent *host, char *buffer,
size_t buflen, int *herrnop)
{
int parse_res;
/* Get the next entry until we found a correct one. */
do
{
if (result == NULL)
{
names = nis_getnames("hosts.org_dir");
if (names == NULL || names[0] == NULL)
return NSS_STATUS_UNAVAIL;
result = nis_first_entry(names[0]);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
int retval;
retval = niserr2nss (result->status);
if (retval == NSS_STATUS_TRYAGAIN)
{
*herrnop = NETDB_INTERNAL;
__set_errno (EAGAIN);
}
return retval;
}
}
else
{
nis_result *res2;
res2 = nis_next_entry(names[0], &result->cookie);
nis_freeresult (result);
result = res2;
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
int retval;
retval = niserr2nss (result->status);
if (retval == NSS_STATUS_TRYAGAIN)
{
*herrnop = NETDB_INTERNAL;
__set_errno (EAGAIN);
}
return retval;
}
}
parse_res = _nss_nisplus_parse_hostent (result, host, buffer, buflen);
if (!parse_res && errno == ERANGE)
{
*herrnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
} while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_gethostent_r (struct hostent *result, char *buffer,
size_t buflen, int *herrnop)
{
int status;
__libc_lock_lock (lock);
status = internal_nisplus_gethostent_r (result, buffer, buflen, herrnop);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_gethostbyname2_r (const char *name, int af, struct hostent *host,
char *buffer, size_t buflen, int *herrnop)
{
int parse_res, retval;
if (name == NULL)
{
__set_errno (EINVAL);
*herrnop = NETDB_INTERNAL;
return NSS_STATUS_NOTFOUND;
}
else
{
nis_result *result;
char buf[strlen (name) + 255];
/* 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);
/* 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,
"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);
else
sprintf(buf, "[cname=%s],hosts.org_dir", NISENTRYVAL(0, 0, result));
nis_freeresult (result);
result = nis_list(buf, EXPAND_NAME, NULL, NULL);
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;
}
parse_res = _nss_nisplus_parse_hostent (result, host, buffer, buflen);
nis_freeresult (result);
if (parse_res)
return NSS_STATUS_SUCCESS;
*herrnop = NETDB_INTERNAL;
if (!parse_res && errno == ERANGE)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
}
enum nss_status
_nss_nisplus_gethostbyname_r (const char *name, struct hostent *host,
char *buffer, size_t buflen, int *h_errnop)
{
if (_res.options & RES_USE_INET6)
{
enum nss_status status;
status = _nss_nisplus_gethostbyname2_r (name, AF_INET6, host, buffer,
buflen, h_errnop);
if (status == NSS_STATUS_SUCCESS)
return status;
}
return _nss_nisplus_gethostbyname2_r (name, AF_INET, host, buffer,
buflen, h_errnop);
}
enum nss_status
_nss_nisplus_gethostbyaddr_r (const char *addr, struct hostent *host,
char *buffer, size_t buflen, int *herrnop)
{
if (addr == NULL)
return NSS_STATUS_NOTFOUND;
else
{
nis_result *result;
char buf[24 + strlen (addr)];
int retval, parse_res;
sprintf(buf, "[addr=%s],hosts.org_dir", addr);
result = nis_list(buf, EXPAND_NAME, NULL, NULL);
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;
}
parse_res = _nss_nisplus_parse_hostent (result, host, buffer, buflen);
nis_freeresult (result);
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,141 @@
/* 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 <nss.h>
#include <errno.h>
#include <ctype.h>
#include <netdb.h>
#include <string.h>
#include <netgroup.h>
#include <libc-lock.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
#include "nss-nisplus.h"
__libc_lock_define_initialized (static, lock)
static char *data = NULL;
static size_t data_size = 0;
static char *cursor = NULL;;
extern enum nss_status
_nss_netgroup_parseline (char **cursor, struct __netgrent *result,
char *buffer, size_t buflen);
#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)
enum nss_status
_nss_nisplus_setnetgrent (char *group)
{
enum nss_status status;
nis_result *result;
char buf[strlen (group) + 30];
int i;
size_t len;
if (group == NULL || group[0] == '\0')
return NSS_STATUS_UNAVAIL;
status = NSS_STATUS_SUCCESS;
__libc_lock_lock (lock);
if (data != NULL)
{
free (data);
data = NULL;
data_size = 0;
cursor = NULL;
}
sprintf(buf, "[name=%s],netgroup.org_dir", group);
result = nis_list(buf, EXPAND_NAME, NULL, NULL);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
status = niserr2nss (result->status);
len = 0;
for (i = 0; i < result->objects.objects_len; i++)
len += 1 + NISENTRYLEN (i, 1, result) + 1 + NISENTRYLEN(i,2,result)
+ 1 + NISENTRYLEN(i,3,result) + 1 + NISENTRYLEN(i,4,result) + 2;
data = malloc (len+1);
memset (data, '\0', len+1);
for (i = 0; i < result->objects.objects_len; i++)
{
strncat (data, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));
strcat (data," (");
strncat (data, NISENTRYVAL(i,2,result), NISENTRYLEN (i, 2, result));
strcat (data, ",");
strncat (data, NISENTRYVAL(i,3,result), NISENTRYLEN (i, 3, result));
strcat (data, ",");
strncat (data, NISENTRYVAL(i,4,result), NISENTRYLEN (i, 4, result));
strcat (data, ") ");
}
nis_freeresult (result);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_endnetgrent (void)
{
__libc_lock_lock (lock);
if (data != NULL)
{
free (data);
data = NULL;
data_size = 0;
cursor = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getnetgrent_r (struct __netgrent *result,
char *buffer, size_t buflen)
{
enum nss_status status;
if (cursor == NULL)
return NSS_STATUS_NOTFOUND;
__libc_lock_lock (lock);
status = _nss_netgroup_parseline (&cursor, result, buffer, buflen);
__libc_lock_unlock (lock);
return status;
}

View File

@ -0,0 +1,340 @@
/* 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 <nss.h>
#include <netdb.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <arpa/inet.h>
#include <libc-lock.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
#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;
#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)
static int
_nss_nisplus_parse_netent (nis_result *result, struct netent *network,
char *buffer, size_t buflen)
{
char *p = buffer;
size_t room_left = buflen;
int i;
struct parser_data *data = (void *) buffer;
if (result == NULL)
return -1;
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,
"networks_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3)
return -1;
/* Generate the network entry format and use the normal parser */
if (NISENTRYLEN (0, 0, result) +1 > room_left)
{
__set_errno (ERANGE);
return -1;
}
memset (p, '\0', room_left);
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 -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 */
for (i = 1; 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)
{
__set_errno (ERANGE);
return -1;
}
strcat (p, " ");
strncat (p, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));
room_left -= (NISENTRYLEN (i, 1, result) + 1);
}
return _nss_files_parse_netent (p, network, data, buflen);
}
enum nss_status
_nss_nisplus_setnetent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_endnetent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nisplus_getnetent_r (struct netent *network, char *buffer,
size_t buflen, int *herrnop)
{
int parse_res;
/* Get the next entry until we found a correct one. */
do
{
if (result == NULL)
{
names = nis_getnames("networks.org_dir");
if (names == NULL || names[0] == NULL)
return NSS_STATUS_UNAVAIL;
result = nis_first_entry(names[0]);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
int retval;
retval = niserr2nss (result->status);
if (retval == NSS_STATUS_TRYAGAIN)
{
*herrnop = NETDB_INTERNAL;
__set_errno (EAGAIN);
}
return retval;
}
}
else
{
nis_result *res;
res = nis_next_entry(names[0], &result->cookie);
nis_freeresult (result);
result = res;
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
int retval;
retval = niserr2nss (result->status);
if (retval == NSS_STATUS_TRYAGAIN)
{
*herrnop = NETDB_INTERNAL;
__set_errno (EAGAIN);
}
return retval;
}
}
parse_res = _nss_nisplus_parse_netent (result, network, buffer, buflen);
if (!parse_res && errno == ERANGE)
{
*herrnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
} while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getnetent_r (struct netent *result, char *buffer,
size_t buflen, int *herrnop)
{
int status;
__libc_lock_lock (lock);
status = internal_nisplus_getnetent_r (result, buffer, buflen, herrnop);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_getnetbyname_r (const char *name, struct netent *network,
char *buffer, size_t buflen, int *herrnop)
{
int parse_res, retval;
if (name == NULL)
{
__set_errno (EINVAL);
*herrnop = NETDB_INTERNAL;
return NSS_STATUS_UNAVAIL;
}
else
{
nis_result *result;
char buf[strlen (name) + 255];
/* 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);
/* 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,
"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);
else
sprintf(buf, "[cname=%s],networks.org_dir", NISENTRYVAL(0, 0, result));
nis_freeresult (result);
result = nis_list(buf, EXPAND_NAME, NULL, NULL);
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;
}
parse_res = _nss_nisplus_parse_netent (result, network, buffer, buflen);
nis_freeresult (result);
if (parse_res)
return NSS_STATUS_SUCCESS;
*herrnop = NETDB_INTERNAL;
if (!parse_res && errno == ERANGE)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
}
/* XXX type is ignored, SUN's NIS+ table doesn't support it */
enum nss_status
_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;
in = inet_makeaddr (addr, 0);
snprintf(buf, sizeof (buf) - 1, "[addr=%s],networks.org_dir",
inet_ntoa (in));
result = nis_list(buf, EXPAND_NAME, NULL, NULL);
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;
}
parse_res = _nss_nisplus_parse_netent (result, network, buffer, buflen);
nis_freeresult (result);
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,284 @@
/* 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 <nss.h>
#include <errno.h>
#include <ctype.h>
#include <netdb.h>
#include <string.h>
#include <libc-lock.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
#include "nss-nisplus.h"
__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,);
)
#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)
static int
_nss_nisplus_parse_protoent (nis_result * result, struct protoent *proto,
char *buffer, size_t buflen)
{
char *p = buffer;
size_t room_left = buflen;
int i;
struct parser_data *data = (void *) buffer;
if (result == NULL)
return -1;
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)
return -1;
memset (p, '\0', room_left);
/* Generate the protocols entry format and use the normal parser */
if (NISENTRYLEN (0, 0, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
}
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 -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 */
for (i = 1; i < result->objects.objects_len; i++)
{
if (NISENTRYLEN (i, 1, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
}
strcat (p, " ");
strncat (p, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));
room_left -= (NISENTRYLEN (i, 1, result) + 1);
}
return _nss_files_parse_protoent (p, proto, data, buflen);
}
enum nss_status
_nss_nisplus_setprotoent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_endprotoent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nisplus_getprotoent_r (struct protoent *proto, char *buffer,
size_t buflen)
{
int parse_res;
/* Get the next entry until we found a correct one. */
do
{
if (result == NULL)
{
names = nis_getnames ("protocols.org_dir");
if (names == NULL || names[0] == NULL)
return NSS_STATUS_UNAVAIL;
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_protoent (result, proto, buffer, buflen);
}
while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getprotoent_r (struct protoent *result, char *buffer,
size_t buflen)
{
int status;
__libc_lock_lock (lock);
status = internal_nisplus_getprotoent_r (result, buffer, buflen);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_getprotobyname_r (const char *name, struct protoent *proto,
char *buffer, size_t buflen)
{
int parse_res;
if (name == NULL)
return NSS_STATUS_NOTFOUND;
else
{
nis_result *result;
char buf[strlen (name) + 255];
/* 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);
/* 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,
"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);
else
sprintf (buf, "[cname=%s],protocols.org_dir", NISENTRYVAL (0, 0, result));
nis_freeresult (result);
result = nis_list (buf, EXPAND_NAME, 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_protoent (result, proto, 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;
}
}
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];
snprintf (buf, sizeof (buf), "[number=%d],protocols.org_dir", number);
result = nis_list (buf, EXPAND_NAME, 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_protoent (result, proto, 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

@ -0,0 +1,347 @@
/* 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 <nss.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <rpc/key_prot.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
#include <nss-nisplus.h>
extern int xdecrypt (char *, char *);
/* If we found the entry, we give a SUCCESS and an empty key back. */
enum nss_status
_nss_nisplus_getpublickey (const char *netname, char *pkey)
{
nis_result *res;
enum nss_status retval;
char buf[NIS_MAXNAMELEN+2];
char *domain, *cptr;
int len;
pkey[0] = 0;
if (netname == NULL)
{
__set_errno (EINVAL);
return NSS_STATUS_UNAVAIL;
}
domain = strchr (netname, '@');
if (!domain)
return NSS_STATUS_UNAVAIL;
domain++;
snprintf (buf, NIS_MAXNAMELEN,
"[auth_name=%s,auth_type=DES],cred.org_dir.%s",
netname, domain);
if (buf[strlen (buf)-1] != '.')
strcat(buf, ".");
res = nis_list(buf, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH,
NULL, NULL);
retval = niserr2nss (res->status);
if (retval != NSS_STATUS_SUCCESS)
{
if (retval == NSS_STATUS_TRYAGAIN)
__set_errno (EAGAIN);
nis_freeresult (res);
return retval;
}
if (res->objects.objects_len > 1)
{
/*
* More than one principal with same uid?
* something wrong with cred table. Should be unique
* Warn user and continue.
*/
printf (_("DES entry for netname %s not unique\n"), netname);
nis_freeresult (res);
return NSS_STATUS_SUCCESS;
}
len = ENTRY_LEN (res->objects.objects_val, 3);
memcpy (pkey, ENTRY_VAL (res->objects.objects_val,3), len);
pkey[len] = 0;
cptr = strchr (pkey, ':');
if (cptr)
cptr[0] = '\0';
nis_freeresult (res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd)
{
nis_result *res;
enum nss_status retval;
char buf[NIS_MAXNAMELEN+2];
char *domain, *cptr;
int len;
skey[0] = 0;
if (netname == NULL)
{
__set_errno (EINVAL);
return NSS_STATUS_UNAVAIL;
}
domain = strchr (netname, '@');
if (!domain)
return NSS_STATUS_UNAVAIL;
domain++;
snprintf (buf, NIS_MAXNAMELEN,
"[auth_name=%s,auth_type=DES],cred.org_dir.%s",
netname, domain);
if (buf[strlen(buf)-1] != '.')
strcat(buf, ".");
res = nis_list (buf, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH,
NULL, NULL);
retval = niserr2nss (res->status);
if (retval != NSS_STATUS_SUCCESS)
{
if (retval == NSS_STATUS_TRYAGAIN)
__set_errno (EAGAIN);
nis_freeresult (res);
return retval;
}
if (res->objects.objects_len > 1)
{
/*
* More than one principal with same uid?
* something wrong with cred table. Should be unique
* Warn user and continue.
*/
printf (_("DES entry for netname %s not unique\n"), netname);
nis_freeresult (res);
return NSS_STATUS_SUCCESS;
}
len = ENTRY_LEN (res->objects.objects_val, 4);
memcpy (buf, ENTRY_VAL (res->objects.objects_val,4), len);
skey[len] = 0;
cptr = strchr (skey, ':');
if (cptr)
cptr[0] = '\0';
nis_freeresult (res);
if (!xdecrypt (buf, passwd))
return NSS_STATUS_SUCCESS;
if (memcmp (buf, &(buf[HEXKEYBYTES]), KEYCHECKSUMSIZE) != 0)
return NSS_STATUS_SUCCESS;
buf[HEXKEYBYTES] = 0;
strcpy (skey, buf);
return NSS_STATUS_SUCCESS;
}
/* Parse information from the passed string.
The format of the string passed is gid,grp,grp, ... */
static enum nss_status
parse_grp_str (const char *s, gid_t *gidp, int *gidlenp, gid_t *gidlist)
{
int gidlen;
if (!s || (!isdigit (*s)))
{
syslog (LOG_ERR, "netname2user: missing group id list in '%s'.", s);
return NSS_STATUS_NOTFOUND;
}
*gidp = (atoi (s));
gidlen = 0;
while ((s = strchr (s, ',')) != NULL)
{
s++;
gidlist[gidlen++] = atoi (s);
}
*gidlenp = gidlen;
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
gid_t *gidp, int *gidlenp, gid_t *gidlist)
{
char *domain;
nis_result *res;
char sname[NIS_MAXNAMELEN+1]; /* search criteria + table name */
char principal[NIS_MAXNAMELEN+1];
int len;
/* 1. Get home domain of user. */
domain = strchr (netname, '@');
if (! domain)
return NSS_STATUS_UNAVAIL;
domain++; /* skip '@' */
/* 2. Get user's nisplus principal name. */
if ((strlen (netname) + strlen (domain)+45) >
(size_t) NIS_MAXNAMELEN)
return NSS_STATUS_UNAVAIL;
snprintf (sname, NIS_MAXNAMELEN,
"[auth_name=%s,auth_type=DES],cred.org_dir.%s",
netname, 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_SUCCESS:
case NIS_S_SUCCESS:
break; /* go and do something useful */
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;
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)
{
/*
* A netname belonging to more than one principal?
* Something wrong with cred table. should be unique.
* Warn user and continue.
*/
syslog (LOG_ALERT,
_("netname2user: DES entry for %s in directory %s not unique"),
netname, domain);
}
len = ENTRY_LEN(res->objects.objects_val, 0);
strncpy(principal, ENTRY_VAL(res->objects.objects_val, 0), len);
principal[len] = '\0';
nis_freeresult(res);
if (principal[0] == '\0')
return NSS_STATUS_UNAVAIL;
/*
* 3. Use principal name to look up uid/gid information in
* LOCAL entry in **local** cred table.
*/
domain = nis_local_directory ();
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",
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;
}
if (res->objects.objects_len > 1)
{
/*
* A principal can have more than one LOCAL entry?
* Something wrong with cred table.
* Warn user and continue.
*/
syslog(LOG_ALERT,
_("netname2user: LOCAL entry for %s in directory %s not unique"),
netname, domain);
}
/* Fetch the uid */
*uidp = (atoi (ENTRY_VAL (res->objects.objects_val, 2)));
if (*uidp == 0)
{
syslog (LOG_ERR, _("netname2user: should not have uid 0"));
return NSS_STATUS_NOTFOUND;
}
parse_grp_str (ENTRY_VAL (res->objects.objects_val, 3),
gidp, gidlenp, gidlist);
nis_freeresult (res);
return NSS_STATUS_SUCCESS;
}

View File

@ -0,0 +1,293 @@
/* 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 <nss.h>
#include <errno.h>
#include <pwd.h>
#include <string.h>
#include <libc-lock.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
#include "nss-nisplus.h"
__libc_lock_define_initialized (static, lock)
static nis_result *result = NULL;
static nis_name *names = NULL;
#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)
static 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 -1;
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 -1;
if (NISENTRYLEN(0, 0, result) >= room_left)
{
/* The line is too long for our buffer. */
no_more_room:
__set_errno (ERANGE);
return -1;
}
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;
}
enum nss_status
_nss_nisplus_setpwent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_endpwent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nisplus_getpwent_r (struct passwd *pw, char *buffer, size_t buflen)
{
int parse_res;
/* Get the next entry until we found a correct one. */
do
{
if (result == NULL)
{
names = nis_getnames ("passwd.org_dir");
if (names == NULL || names[0] == NULL)
return NSS_STATUS_UNAVAIL;
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_pwent (result, pw, buffer, buflen);
} while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getpwent_r (struct passwd *result, char *buffer, size_t buflen)
{
int status;
__libc_lock_lock (lock);
status = internal_nisplus_getpwent_r (result, buffer, buflen);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_getpwnam_r (const char *name, struct passwd *pw,
char *buffer, size_t buflen)
{
int parse_res;
if (name == NULL || strlen (name) > 8)
return NSS_STATUS_NOTFOUND;
else
{
nis_result *result;
char buf[strlen (name) + 24];
sprintf(buf, "[name=%s],passwd.org_dir", name);
result = nis_list(buf, EXPAND_NAME, 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_pwent (result, pw, 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;
}
}
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];
sprintf(buf, "[uid=%d],passwd.org_dir", uid);
result = nis_list(buf, EXPAND_NAME, 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_pwent (result, pw, 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

@ -0,0 +1,284 @@
/* 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 <nss.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <libc-lock.h>
#include <rpc/netdb.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
#include "nss-nisplus.h"
__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,);
)
#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)
static int
_nss_nisplus_parse_rpcent (nis_result *result, struct rpcent *rpc,
char *buffer, size_t buflen)
{
char *p = buffer;
size_t room_left = buflen;
int i;
struct parser_data *data = (void *) buffer;
if (result == NULL)
return -1;
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,
"rpc_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3)
return -1;
memset (p, '\0', room_left);
/* Generate the rpc entry format and use the normal parser */
if (NISENTRYLEN (0, 0, result) +1 > room_left)
{
__set_errno (ERANGE);
return -1;
}
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 -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 */
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)
{
__set_errno (ERANGE);
return -1;
}
strcat (p, " ");
strncat (p, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));
room_left -= (NISENTRYLEN (i, 1, result) + 1);
}
return _nss_files_parse_rpcent (p, rpc, data, buflen);
}
enum nss_status
_nss_nisplus_setrpcent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_endrpcent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nisplus_getrpcent_r (struct rpcent *rpc, char *buffer,
size_t buflen)
{
int parse_res;
/* Get the next entry until we found a correct one. */
do
{
if (result == NULL)
{
names = nis_getnames ("rpc.org_dir");
if (names == NULL || names[0] == NULL)
return NSS_STATUS_UNAVAIL;
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_rpcent (result, rpc, buffer, buflen);
} while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getrpcent_r (struct rpcent *result, char *buffer,
size_t buflen)
{
int status;
__libc_lock_lock (lock);
status = internal_nisplus_getrpcent_r (result, buffer, buflen);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_getrpcbyname_r (const char *name, struct rpcent *rpc,
char *buffer, size_t buflen)
{
int parse_res;
if (name == NULL)
return NSS_STATUS_NOTFOUND;
else
{
nis_result *result;
char buf[strlen (name) + 255];
/* 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);
/* 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,
"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);
else
sprintf (buf, "[cname=%s],rpc.org_dir", NISENTRYVAL(0, 0, result));
nis_freeresult (result);
result = nis_list(buf, EXPAND_NAME, 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_rpcent (result, rpc, 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;
}
}
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];
snprintf (buf, sizeof (buf), "[number=%d],rpc.org_dir", number);
result = nis_list(buf, EXPAND_NAME, 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_rpcent (result, rpc, 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

@ -0,0 +1,308 @@
/* 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 <nss.h>
#include <errno.h>
#include <ctype.h>
#include <netdb.h>
#include <string.h>
#include <libc-lock.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
#include "nss-nisplus.h"
__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);
)
#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)
static int
_nss_nisplus_parse_servent (nis_result *result, struct servent *serv,
char *buffer, size_t buflen)
{
char *p = buffer;
size_t room_left = buflen;
int i;
struct parser_data *data = (void *) buffer;
if (result == NULL)
return -1;
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)
return -1;
memset (p, '\0', room_left);
/* Generate the services entry format and use the normal parser */
if (NISENTRYLEN (0, 0, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
}
strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
room_left -= (NISENTRYLEN (0, 0, result) + 1);
if (NISENTRYLEN (0, 3, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
}
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 -1;
}
strcat (p, "/");
strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result));
room_left -= (NISENTRYLEN (0, 2, result) + 1);
for (i = 1; i < result->objects.objects_len; i++)
{
if (NISENTRYLEN (i, 1, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
}
strcat (p, " ");
strcat (p, NISENTRYVAL (i, 1, result));
room_left -= (NISENTRYLEN (i, 1, result) + 1);
}
return _nss_files_parse_servent (p, serv, data, buflen);
}
enum nss_status
_nss_nisplus_setservent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_endservent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nisplus_getservent_r (struct servent *serv, char *buffer,
size_t buflen)
{
int parse_res;
/* Get the next entry until we found a correct one. */
do
{
if (result == NULL)
{
names = nis_getnames ("services.org_dir");
if (names == NULL || names[0] == NULL)
return NSS_STATUS_UNAVAIL;
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_servent (result, serv, buffer, buflen);
}
while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getservent_r (struct servent *result, char *buffer,
size_t buflen)
{
int status;
__libc_lock_lock (lock);
status = internal_nisplus_getservent_r (result, buffer, buflen);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_getservbyname_r (const char *name, const char *protocol,
struct servent *serv,
char *buffer, size_t buflen)
{
int parse_res;
if (name == NULL || protocol == NULL)
{
__set_errno (EINVAL);
return NSS_STATUS_NOTFOUND;
}
else
{
nis_result *result;
char buf[strlen (name) + 255];
/* 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);
/* 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,
"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);
else
sprintf (buf, "[cname=%s,proto=%s],services.org_dir",
NISENTRYVAL (0, 0, result), protocol);
nis_freeresult (result);
result = nis_list (buf, EXPAND_NAME, 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);
if (parse_res)
return NSS_STATUS_SUCCESS;
if (!parse_res && errno == ERANGE)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
}
enum nss_status
_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 (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)
{
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);
if (parse_res)
return NSS_STATUS_SUCCESS;
if (!parse_res && errno == ERANGE)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}

View File

@ -0,0 +1,262 @@
/* 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 <nss.h>
#include <errno.h>
#include <shadow.h>
#include <string.h>
#include <libc-lock.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
#include "nss-nisplus.h"
__libc_lock_define_initialized (static, lock)
static nis_result *result = NULL;
static nis_name *names = NULL;
#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)
static 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;
char *line, *cp;
if (result == NULL)
return -1;
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 -1;
if (NISENTRYLEN(0, 0, result) >= room_left)
{
/* The line is too long for our buffer. */
no_more_room:
__set_errno (ERANGE);
return -1;
}
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;
line = NISENTRYVAL (0, 7, result);
cp = strchr (line, ':');
if (cp == NULL)
return 0;
*cp++ = '\0';
sp->sp_lstchg = atoi (line);
line = cp;
cp = strchr (line, ':');
if (cp == NULL)
return 0;
*cp++ = '\0';
sp->sp_min = atoi(line);
line = cp;
cp = strchr (line, ':');
if (cp == NULL)
return 0;
*cp++ = '\0';
sp->sp_max = atoi(line);
line = cp;
cp = strchr (line, ':');
if (cp == NULL)
return 0;
*cp++ = '\0';
sp->sp_warn = atoi(line);
line = cp;
cp = strchr (line, ':');
if (cp == NULL)
return 0;
*cp++ = '\0';
sp->sp_inact = atoi(line);
line = cp;
cp = strchr (line, ':');
if (cp == NULL)
return 0;
*cp++ = '\0';
sp->sp_expire = atoi(line);
line = cp;
if (line == NULL)
return 0;
sp->sp_flag = atoi(line);
return 1;
}
enum nss_status
_nss_nisplus_setspent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_endspent (void)
{
__libc_lock_lock (lock);
if (result)
nis_freeresult (result);
result = NULL;
if (names)
{
nis_freenames (names);
names = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nisplus_getspent_r (struct spwd *sp, char *buffer, size_t buflen)
{
int parse_res;
/* Get the next entry until we found a correct one. */
do
{
if (result == NULL)
{
names = nis_getnames ("passwd.org_dir");
if (names == NULL || names[0] == NULL)
return NSS_STATUS_UNAVAIL;
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_spent (result, sp, buffer, buflen);
} while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getspent_r (struct spwd *result, char *buffer, size_t buflen)
{
int status;
__libc_lock_lock (lock);
status = internal_nisplus_getspent_r (result, buffer, buflen);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_getspnam_r (const char *name, struct spwd *sp,
char *buffer, size_t buflen)
{
int parse_res;
if (name == NULL || strlen (name) > 8)
return NSS_STATUS_NOTFOUND;
else
{
nis_result *result;
char buf[strlen (name) + 24];
sprintf (buf, "[name=%s],passwd.org_dir", name);
result = nis_list (buf, EXPAND_NAME, 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_spent (result, sp, 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;
}
}

1008
nis/rpcsvc/nis.h Normal file

File diff suppressed because it is too large Load Diff

446
nis/rpcsvc/nis.x Normal file
View File

@ -0,0 +1,446 @@
%/*
% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
% * unrestricted use provided that this legend is included on all tape
% * media and as a part of the software program in whole or part. Users
% * may copy or modify Sun RPC without charge, but are not authorized
% * to license or distribute it to anyone else except as part of a product or
% * program developed by the user or with the express written consent of
% * Sun Microsystems, Inc.
% *
% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
% *
% * Sun RPC is provided with no support and without any obligation on the
% * part of Sun Microsystems, Inc. to assist in its use, correction,
% * modification or enhancement.
% *
% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
% * OR ANY PART THEREOF.
% *
% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
% * or profits or other special, indirect and consequential damages, even if
% * Sun has been advised of the possibility of such damages.
% *
% * Sun Microsystems, Inc.
% * 2550 Garcia Avenue
% * Mountain View, California 94043
% */
/*
* From 4.1 : @(#)nis.x 1.61 Copyright 1989 Sun Microsystems
*
* RPC Language Protocol description file for NIS Plus
* This version : 1.61
* Last Modified : 3/19/91
*/
#ifdef RPC_HDR
%/*
% * nis.h
% *
% * This file is the main include file for NIS clients. It contains
% * both the client library function defines and the various data
% * structures used by the NIS service. It includes the file nis_tags.h
% * which defines the tag values. This allows the tags to change without
% * having to change the nis.x file.
% *
% * NOTE : DO NOT EDIT THIS FILE! It is automatically generated when
% * rpcgen is run on the nis.x file. Note that there is a
% * simple sed script to remove some unneeded lines. (See the
% * Makefile target nis.h)
% *
% */
%#include <rpcsvc/nis_tags.h>
#endif
/* This gets stuffed into the source files. */
#if RPC_HDR
%#include <rpc/xdr.h>
#endif
#if RPC_SVC
%#include "nis_svc.h"
#endif
/* Include the RPC Language description of NIS objects */
#include "nis_object.x"
/* Errors that can be returned by the service */
enum nis_error {
NIS_SUCCESS = 0, /* A-ok, let's rock n roll */
NIS_S_SUCCESS = 1, /* Name found (maybe) */
NIS_NOTFOUND = 2, /* Name definitely not found */
NIS_S_NOTFOUND = 3, /* Name maybe not found */
NIS_CACHEEXPIRED = 4, /* Name exists but cache out of date */
NIS_NAMEUNREACHABLE = 5, /* Can't get there from here */
NIS_UNKNOWNOBJ = 6, /* Object type is bogus */
NIS_TRYAGAIN = 7, /* I'm busy, call back */
NIS_SYSTEMERROR = 8, /* Out of band failure */
NIS_CHAINBROKEN = 9, /* First/Next warning */
NIS_PERMISSION = 10, /* Not enough permission to access */
NIS_NOTOWNER = 11, /* You don't own it, sorry */
NIS_NOT_ME = 12, /* I don't serve this name */
NIS_NOMEMORY = 13, /* Outta VM! Help! */
NIS_NAMEEXISTS = 14, /* Can't create over another name */
NIS_NOTMASTER = 15, /* I'm justa secondaray, don't ask me */
NIS_INVALIDOBJ = 16, /* Object is broken somehow */
NIS_BADNAME = 17, /* Unparsable name */
NIS_NOCALLBACK = 18, /* Couldn't talk to call back proc */
NIS_CBRESULTS = 19, /* Results being called back to you */
NIS_NOSUCHNAME = 20, /* Name unknown */
NIS_NOTUNIQUE = 21, /* Value is not uniques (entry) */
NIS_IBMODERROR = 22, /* Inf. Base. Modify error. */
NIS_NOSUCHTABLE = 23, /* Name for table was wrong */
NIS_TYPEMISMATCH = 24, /* Entry and table type mismatch */
NIS_LINKNAMEERROR = 25, /* Link points to bogus name */
NIS_PARTIAL = 26, /* Partial success, found table */
NIS_TOOMANYATTRS = 27, /* Too many attributes */
NIS_RPCERROR = 28, /* RPC error encountered */
NIS_BADATTRIBUTE = 29, /* Bad or invalid attribute */
NIS_NOTSEARCHABLE = 30, /* Non-searchable object searched */
NIS_CBERROR = 31, /* Error during callback (svc crash) */
NIS_FOREIGNNS = 32, /* Foreign Namespace */
NIS_BADOBJECT = 33, /* Malformed object structure */
NIS_NOTSAMEOBJ = 34, /* Object swapped during deletion */
NIS_MODFAIL = 35, /* Failure during a Modify. */
NIS_BADREQUEST = 36, /* Illegal query for table */
NIS_NOTEMPTY = 37, /* Attempt to remove a non-empty tbl */
NIS_COLDSTART_ERR = 38, /* Error accesing the cold start file */
NIS_RESYNC = 39, /* Transaction log too far out of date */
NIS_FAIL = 40, /* NIS operation failed. */
NIS_UNAVAIL = 41, /* NIS+ service is unavailable (client) */
NIS_RES2BIG = 42, /* NIS+ result too big for datagram */
NIS_SRVAUTH = 43, /* NIS+ server wasn't authenticated. */
NIS_CLNTAUTH = 44, /* NIS+ Client wasn't authenticated. */
NIS_NOFILESPACE = 45, /* NIS+ server ran out of disk space */
NIS_NOPROC = 46, /* NIS+ server couldn't create new proc */
NIS_DUMPLATER = 47 /* NIS+ server already has dump child */
};
/*
* Structure definitions for the parameters and results of the actual
* NIS RPC calls.
*
* This is the standard result (in the protocol) of most of the nis
* requests.
*/
struct nis_result {
nis_error status; /* Status of the response */
nis_object objects<>; /* objects found */
netobj cookie; /* Cookie Data */
u_long zticks; /* server ticks */
u_long dticks; /* DBM ticks. */
u_long aticks; /* Cache (accel) ticks */
u_long cticks; /* Client ticks */
};
/*
* A Name Service request
* This request is used to access the name space, ns_name is the name
* of the object within the namespace and the object is it's value, for
* add/modify, a copy of the original for remove.
*/
struct ns_request {
nis_name ns_name; /* Name in the NIS name space */
nis_object ns_object<1>; /* Optional Object (add/remove) */
};
/*
* An information base request
* This request includes the NIS name of the table we wish to search, the
* search criteria in the form of attribute/value pairs and an optional
* callback program number. If the callback program number is provided
* the server will send back objects one at a time, otherwise it will
* return them all in the response.
*/
struct ib_request {
nis_name ibr_name; /* The name of the Table */
nis_attr ibr_srch<>; /* The search critereia */
u_long ibr_flags; /* Optional flags */
nis_object ibr_obj<1>; /* optional object (add/modify) */
nis_server ibr_cbhost<1>; /* Optional callback info */
u_long ibr_bufsize; /* Optional first/next bufsize */
netobj ibr_cookie; /* The first/next cookie */
};
/*
* This argument to the PING call notifies the replicas that something in
* a directory has changed and this is it's timestamp. The replica will use
* the timestamp to determine if its resync operation was successful.
*/
struct ping_args {
nis_name dir; /* Directory that had the change */
u_long stamp; /* timestamp of the transaction */
};
/*
* These are the type of entries that are stored in the transaction log,
* note that modifications will appear as two entries, for names, they have
* a "OLD" entry followed by a "NEW" entry. For entries in tables, there
* is a remove followed by an add. It is done this way so that we can read
* the log backwards to back out transactions and forwards to propogate
* updated.
*/
enum log_entry_t {
LOG_NOP = 0,
ADD_NAME = 1, /* Name Added to name space */
REM_NAME = 2, /* Name removed from name space */
MOD_NAME_OLD = 3, /* Name was modified in the name space */
MOD_NAME_NEW = 4, /* Name was modified in the name space */
ADD_IBASE = 5, /* Entry added to information base */
REM_IBASE = 6, /* Entry removed from information base */
MOD_IBASE = 7, /* Entry was modified in information base */
UPD_STAMP = 8 /* Update timestamp (used as fenceposts) */
};
/*
* This result is returned from the name service when it is requested to
* dump logged entries from its transaction log. Information base updates
* will have the name of the information base in the le_name field and
* a canonical set of attribute/value pairs to fully specify the entry's
* 'name'.
*/
struct log_entry {
u_long le_time; /* Time in seconds */
log_entry_t le_type; /* Type of log entry */
nis_name le_princp; /* Principal making the change */
nis_name le_name; /* Name of table/dir involved */
nis_attr le_attrs<>; /* List of AV pairs. */
nis_object le_object; /* Actual object value */
};
struct log_result {
nis_error lr_status; /* The status itself */
netobj lr_cookie; /* Used by the dump callback */
log_entry lr_entries<>; /* zero or more entries */
};
struct cp_result {
nis_error cp_status; /* Status of the checkpoint */
u_long cp_zticks; /* Service 'ticks' */
u_long cp_dticks; /* Database 'ticks' */
};
/*
* This structure defines a generic NIS tag list. The taglist contains
* zero or tags, each of which is a type and a value. (u_long).
* These are used to report statistics (see tag definitions below)
* and to set or reset state variables.
*/
struct nis_tag {
u_long tag_type; /* Statistic tag (may vary) */
string tag_val<1024>; /* Statistic value may also vary */
};
struct nis_taglist {
nis_tag tags<>; /* List of tags */
};
struct dump_args {
nis_name da_dir; /* Directory to dump */
u_long da_time; /* From this timestamp */
nis_server da_cbhost<1>; /* Callback to use. */
};
struct fd_args {
nis_name dir_name; /* The directory we're looking for */
nis_name requester; /* Host principal name for signature */
};
struct fd_result {
nis_error status; /* Status returned by function */
nis_name source; /* Source of this answer */
opaque dir_data<>; /* Directory Data (XDR'ed) */
opaque signature<>; /* Signature of the source */
};
/*
* What's going on here? Well, it's like this. When the service
* is being compiled it wants to have the service definition specific
* info included, and when the client is being compiled it wants that
* info. This includes the appropriate file which was generated by
* make in the protocols directory (probably /usr/include/rpcsvc).
*/
#ifdef RPC_SVC
%#include "nis_svc.h"
#endif
#ifdef RPC_CLNT
%#include "nis_clnt.h"
#endif
program NIS_PROG {
/* RPC Language description of the NIS+ protocol */
version NIS_VERSION {
/* The name service functions */
nis_result NIS_LOOKUP(ns_request) = 1;
nis_result NIS_ADD(ns_request) = 2;
nis_result NIS_MODIFY(ns_request) = 3;
nis_result NIS_REMOVE(ns_request) = 4;
/* The information base functions */
nis_result NIS_IBLIST(ib_request) = 5;
nis_result NIS_IBADD(ib_request) = 6;
nis_result NIS_IBMODIFY(ib_request) = 7;
nis_result NIS_IBREMOVE(ib_request) = 8;
nis_result NIS_IBFIRST(ib_request) = 9;
nis_result NIS_IBNEXT(ib_request) = 10;
/* NIS Administrative functions */
fd_result NIS_FINDDIRECTORY(fd_args) = 12;
/* If fetch and optionally reset statistics */
nis_taglist NIS_STATUS(nis_taglist) = 14;
/* Dump changes to directory since time in da_time */
log_result NIS_DUMPLOG(dump_args) = 15;
/* Dump contents of directory named */
log_result NIS_DUMP(dump_args) = 16;
/* Check status of callback thread */
bool NIS_CALLBACK(netobj) = 17;
/* Return last update time for named dir */
u_long NIS_CPTIME(nis_name) = 18;
/* Checkpoint directory or table named */
cp_result NIS_CHECKPOINT(nis_name) = 19;
/* Send 'status changed' ping to replicates */
void NIS_PING(ping_args) = 20;
/* Modify server behaviour (such as debugging) */
nis_taglist NIS_SERVSTATE(nis_taglist) = 21;
/* Create a Directory */
nis_error NIS_MKDIR(nis_name) = 22;
/* Remove a Directory */
nis_error NIS_RMDIR(nis_name) = 23;
/* Update public keys of a directory object */
nis_error NIS_UPDKEYS(nis_name) = 24;
} = 3;
} = 100300;
/*
* Included below are the defines that become part of nis.h,
* they are technically not part of the protocol, but do define
* key aspects of the implementation and are therefore useful
* in building a conforming server or client.
*/
#if RPC_HDR
%/*
% * Generic "hash" datastructures, used by all types of hashed data.
% */
%struct nis_hash_data {
% nis_name name; /* NIS name of hashed item */
% int keychain; /* It's hash key (for pop) */
% struct nis_hash_data *next; /* Hash collision pointer */
% struct nis_hash_data *prv_item; /* A serial, doubly linked list */
% struct nis_hash_data *nxt_item; /* of items in the hash table */
%};
%typedef struct nis_hash_data NIS_HASH_ITEM;
%
%struct nis_hash_table {
% NIS_HASH_ITEM *keys[64]; /* A hash table of items */
% NIS_HASH_ITEM *first; /* The first "item" in serial list */
%};
%typedef struct nis_hash_table NIS_HASH_TABLE;
%
%/* Structure for storing dynamically allocated static data */
%struct nis_sdata {
% void *buf; /* Memory allocation pointer */
% u_long size; /* Buffer size */
%};
%
%/* Generic client creating flags */
%#define ZMH_VC 1
%#define ZMH_DG 2
%#define ZMH_AUTH 4
%
%/* Testing Access rights for objects */
%
%#define NIS_READ_ACC 1
%#define NIS_MODIFY_ACC 2
%#define NIS_CREATE_ACC 4
%#define NIS_DESTROY_ACC 8
%/* Test macros. a == access rights, m == desired rights. */
%#define WORLD(a, m) (((a) & (m)) != 0)
%#define GROUP(a, m) (((a) & ((m) << 8)) != 0)
%#define OWNER(a, m) (((a) & ((m) << 16)) != 0)
%#define NOBODY(a, m) (((a) & ((m) << 24)) != 0)
%
%#define OATYPE(d, n) (((d)->do_armask.do_armask_val+n)->oa_otype)
%#define OARIGHTS(d, n) (((d)->do_armask.do_armask_val+n)->oa_rights)
%#define WORLD_DEFAULT (NIS_READ_ACC)
%#define GROUP_DEFAULT (NIS_READ_ACC << 8)
%#define OWNER_DEFAULT ((NIS_READ_ACC +\
NIS_MODIFY_ACC +\
NIS_CREATE_ACC +\
NIS_DESTROY_ACC) << 16)
%#define DEFAULT_RIGHTS (WORLD_DEFAULT | GROUP_DEFAULT | OWNER_DEFAULT)
%
%/* Result manipulation defines ... */
%#define NIS_RES_NUMOBJ(x) ((x)->objects.objects_len)
%#define NIS_RES_OBJECT(x) ((x)->objects.objects_val)
%#define NIS_RES_COOKIE(x) ((x)->cookie)
%#define NIS_RES_STATUS(x) ((x)->status)
%
%/* These defines make getting at the variant part of the object easier. */
%#define TA_data zo_data.objdata_u.ta_data
%#define EN_data zo_data.objdata_u.en_data
%#define DI_data zo_data.objdata_u.di_data
%#define LI_data zo_data.objdata_u.li_data
%#define GR_data zo_data.objdata_u.gr_data
%
%#define __type_of(o) ((o)->zo_data.zo_type)
%
%/* Declarations for the internal subroutines in nislib.c */
%enum name_pos {SAME_NAME, HIGHER_NAME, LOWER_NAME, NOT_SEQUENTIAL, BAD_NAME};
%typedef enum name_pos name_pos;
%
%/*
% * Defines for getting at column data in entry objects. Because RPCGEN
% * generates some rather wordy structures, we create some defines that
% * collapse the needed keystrokes to access a particular value using
% * these definitions they take an nis_object *, and an int and return
% * a u_char * for Value, and an int for length.
% */
%#define ENTRY_VAL(obj, col) \
% (obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val
%#define ENTRY_LEN(obj, col) \
% (obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len
%
%#ifdef __cplusplus
%}
%#endif
%
%/* Prototypes, and extern declarations for the NIS library functions. */
%#include <rpcsvc/nislib.h>
%#endif /* __NIS_RPCGEN_H */
%/* EDIT_START */
%
%/*
% * nis_3.h
% *
% * This file contains definitions that are only of interest to the actual
% * service daemon and client stubs. Normal users of NIS will not include
% * this file.
% *
% * NOTE : This include file is automatically created by a combination
% * of rpcgen and sed. DO NOT EDIT IT, change the nis.x file instead
% * and then remake this file.
% */
%#ifndef __nis_3_h
%#define __nis_3_h
%#ifdef __cplusplus
%extern "C" {
%#endif
#endif

287
nis/rpcsvc/nis_object.x Normal file
View File

@ -0,0 +1,287 @@
/*
* nis_object.x
*
* Copyright (c) 1988-1992 Sun Microsystems Inc
* All Rights Reserved.
*/
%#pragma ident "@(#)nis_object.x 1.7 92/07/14 SMI"
#if RPC_HDR
%
%#ifndef __nis_object_h
%#define __nis_object_h
%
#endif
/*
* This file defines the format for a NIS object in RPC language.
* It is included by the main .x file and the database access protocol
* file. It is common because both of them need to deal with the same
* type of object. Generating the actual code though is a bit messy because
* the nis.x file and the nis_dba.x file will generate xdr routines to
* encode/decode objects when only one set is needed. Such is life when
* one is using rpcgen.
*
* Note, the protocol doesn't specify any limits on such things as
* maximum name length, number of attributes, etc. These are enforced
* by the database backend. When you hit them you will no. Also see
* the db_getlimits() function for fetching the limit values.
*
*/
/* Some manifest constants, chosen to maximize flexibility without
* plugging the wire full of data.
*/
const NIS_MAXSTRINGLEN = 255;
const NIS_MAXNAMELEN = 1024;
const NIS_MAXATTRNAME = 32;
const NIS_MAXATTRVAL = 2048;
const NIS_MAXCOLUMNS = 64;
const NIS_MAXATTR = 16;
const NIS_MAXPATH = 1024;
const NIS_MAXREPLICAS = 128;
const NIS_MAXLINKS = 16;
const NIS_PK_NONE = 0; /* no public key (unix/sys auth) */
const NIS_PK_DH = 1; /* Public key is Diffie-Hellman type */
const NIS_PK_RSA = 2; /* Public key if RSA type */
const NIS_PK_KERB = 3; /* Use kerberos style authentication */
/*
* The fundamental name type of NIS. The name may consist of two parts,
* the first being the fully qualified name, and the second being an
* optional set of attribute/value pairs.
*/
struct nis_attr {
string zattr_ndx<>; /* name of the index */
opaque zattr_val<>; /* Value for the attribute. */
};
typedef string nis_name<>; /* The NIS name itself. */
/* NIS object types are defined by the following enumeration. The numbers
* they use are based on the following scheme :
* 0 - 1023 are reserved for Sun,
* 1024 - 2047 are defined to be private to a particular tree.
* 2048 - 4095 are defined to be user defined.
* 4096 - ... are reserved for future use.
*/
enum zotypes {
BOGUS_OBJ = 0, /* Uninitialized object structure */
NO_OBJ = 1, /* NULL object (no data) */
DIRECTORY_OBJ = 2, /* Directory object describing domain */
GROUP_OBJ = 3, /* Group object (a list of names) */
TABLE_OBJ = 4, /* Table object (a database schema) */
ENTRY_OBJ = 5, /* Entry object (a database record) */
LINK_OBJ = 6, /* A name link. */
PRIVATE_OBJ = 7 /* Private object (all opaque data) */
};
/*
* The types of Name services NIS knows about. They are enumerated
* here. The Binder code will use this type to determine if it has
* a set of library routines that will access the indicated name service.
*/
enum nstype {
UNKNOWN = 0,
NIS = 1, /* Nis Plus Service */
SUNYP = 2, /* Old NIS Service */
IVY = 3, /* Nis Plus Plus Service */
DNS = 4, /* Domain Name Service */
X500 = 5, /* ISO/CCCIT X.500 Service */
DNANS = 6, /* Digital DECNet Name Service */
XCHS = 7, /* Xerox ClearingHouse Service */
CDS= 8
};
/*
* DIRECTORY - The name service object. These objects identify other name
* servers that are serving some portion of the name space. Each has a
* type associated with it. The resolver library will note whether or not
* is has the needed routines to access that type of service.
* The oarmask structure defines an access rights mask on a per object
* type basis for the name spaces. The only bits currently used are
* create and destroy. By enabling or disabling these access rights for
* a specific object type for a one of the accessor entities (owner,
* group, world) the administrator can control what types of objects
* may be freely added to the name space and which require the
* administrator's approval.
*/
struct oar_mask {
u_long oa_rights; /* Access rights mask */
zotypes oa_otype; /* Object type */
};
struct endpoint {
string uaddr<>;
string family<>; /* Transport family (INET, OSI, etc) */
string proto<>; /* Protocol (TCP, UDP, CLNP, etc) */
};
/*
* Note: pkey is a netobj which is limited to 1024 bytes which limits the
* keysize to 8192 bits. This is consider to be a reasonable limit for
* the expected lifetime of this service.
*/
struct nis_server {
nis_name name; /* Principal name of the server */
endpoint ep<>; /* Universal addr(s) for server */
u_long key_type; /* Public key type */
netobj pkey; /* server's public key */
};
struct directory_obj {
nis_name do_name; /* Name of the directory being served */
nstype do_type; /* one of NIS, DNS, IVY, YP, or X.500 */
nis_server do_servers<>; /* <0> == Primary name server */
u_long do_ttl; /* Time To Live (for caches) */
oar_mask do_armask<>; /* Create/Destroy rights by object type */
};
/*
* ENTRY - This is one row of data from an information base.
* The type value is used by the client library to convert the entry to
* it's internal structure representation. The Table name is a back pointer
* to the table where the entry is stored. This allows the client library
* to determine where to send a request if the client wishes to change this
* entry but got to it through a LINK rather than directly.
* If the entry is a "standalone" entry then this field is void.
*/
const EN_BINARY = 1; /* Indicates value is binary data */
const EN_CRYPT = 2; /* Indicates the value is encrypted */
const EN_XDR = 4; /* Indicates the value is XDR encoded */
const EN_MODIFIED = 8; /* Indicates entry is modified. */
const EN_ASN1 = 64; /* Means contents use ASN.1 encoding */
struct entry_col {
u_long ec_flags; /* Flags for this value */
opaque ec_value<>; /* It's textual value */
};
struct entry_obj {
string en_type<>; /* Type of entry such as "passwd" */
entry_col en_cols<>; /* Value for the entry */
};
/*
* GROUP - The group object contains a list of NIS principal names. Groups
* are used to authorize principals. Each object has a set of access rights
* for members of its group. Principal names in groups are in the form
* name.directory and recursive groups are expressed as @groupname.directory
*/
struct group_obj {
u_long gr_flags; /* Flags controlling group */
nis_name gr_members<>; /* List of names in group */
};
/*
* LINK - This is the LINK object. It is quite similar to a symbolic link
* in the UNIX filesystem. The attributes in the main object structure are
* relative to the LINK data and not what it points to (like the file system)
* "modify" privleges here indicate the right to modify what the link points
* at and not to modify that actual object pointed to by the link.
*/
struct link_obj {
zotypes li_rtype; /* Real type of the object */
nis_attr li_attrs<>; /* Attribute/Values for tables */
nis_name li_name; /* The object's real NIS name */
};
/*
* TABLE - This is the table object. It implements a simple
* data base that applications and use for configuration or
* administration purposes. The role of the table is to group together
* a set of related entries. Tables are the simple database component
* of NIS. Like many databases, tables are logically divided into columns
* and rows. The columns are labeled with indexes and each ENTRY makes
* up a row. Rows may be addressed within the table by selecting one
* or more indexes, and values for those indexes. Each row which has
* a value for the given index that matches the desired value is returned.
* Within the definition of each column there is a flags variable, this
* variable contains flags which determine whether or not the column is
* searchable, contains binary data, and access rights for the entry objects
* column value.
*/
const TA_BINARY = 1; /* Means table data is binary */
const TA_CRYPT = 2; /* Means value should be encrypted */
const TA_XDR = 4; /* Means value is XDR encoded */
const TA_SEARCHABLE = 8; /* Means this column is searchable */
const TA_CASE = 16; /* Means this column is Case Sensitive */
const TA_MODIFIED = 32; /* Means this columns attrs are modified*/
const TA_ASN1 = 64; /* Means contents use ASN.1 encoding */
struct table_col {
string tc_name<64>; /* Column Name */
u_long tc_flags; /* control flags */
u_long tc_rights; /* Access rights mask */
};
struct table_obj {
string ta_type<64>; /* Table type such as "passwd" */
int ta_maxcol; /* Total number of columns */
u_char ta_sep; /* Separator character */
table_col ta_cols<>; /* The number of table indexes */
string ta_path<>; /* A search path for this table */
};
/*
* This union joins together all of the currently known objects.
*/
union objdata switch (zotypes zo_type) {
case DIRECTORY_OBJ :
struct directory_obj di_data;
case GROUP_OBJ :
struct group_obj gr_data;
case TABLE_OBJ :
struct table_obj ta_data;
case ENTRY_OBJ:
struct entry_obj en_data;
case LINK_OBJ :
struct link_obj li_data;
case PRIVATE_OBJ :
opaque po_data<>;
case NO_OBJ :
void;
case BOGUS_OBJ :
void;
default :
void;
};
/*
* This is the basic NIS object data type. It consists of a generic part
* which all objects contain, and a specialized part which varies depending
* on the type of the object. All of the specialized sections have been
* described above. You might have wondered why they all start with an
* integer size, followed by the useful data. The answer is, when the
* server doesn't recognize the type returned it treats it as opaque data.
* And the definition for opaque data is {int size; char *data;}. In this
* way, servers and utility routines that do not understand a given type
* may still pass it around. One has to be careful in setting
* this variable accurately, it must take into account such things as
* XDR padding of structures etc. The best way to set it is to note one's
* position in the XDR encoding stream, encode the structure, look at the
* new position and calculate the size.
*/
struct nis_oid {
u_long ctime; /* Time of objects creation */
u_long mtime; /* Time of objects modification */
};
struct nis_object {
nis_oid zo_oid; /* object identity verifier. */
nis_name zo_name; /* The NIS name for this object */
nis_name zo_owner; /* NIS name of object owner. */
nis_name zo_group; /* NIS name of access group. */
nis_name zo_domain; /* The administrator for the object */
u_long zo_access; /* Access rights (owner, group, world) */
u_long zo_ttl; /* Object's time to live in seconds. */
objdata zo_data; /* Data structure for this type */
};
#if RPC_HDR
%
%#endif /* if __nis_object_h */
%
#endif

95
nis/rpcsvc/nis_tags.h Normal file
View File

@ -0,0 +1,95 @@
/*
* Copyright (c) 1991, Sun Microsystems Inc.
*/
/*
* nis_tags.h
*
* This file contains the tags and statistics definitions. It is
* automatically included by nis.h
*/
#ifndef _RPCSVC_NIS_TAGS_H
#define _RPCSVC_NIS_TAGS_H
#pragma ident "@(#)nis_tags.h 1.13 95/02/17 SMI"
/* from file: zns_tags.h 1.7 Copyright (c) 1990 Sun Microsystems */
#ifdef __cplusplus
extern "C" {
#endif
#define NIS_DIR "data"
/* Lookup and List function flags */
#define FOLLOW_LINKS (1<<0) /* Follow link objects */
#define FOLLOW_PATH (1<<1) /* Follow the path in a table */
#define HARD_LOOKUP (1<<2) /* Block until successful */
#define ALL_RESULTS (1<<3) /* Retrieve all results */
#define NO_CACHE (1<<4) /* Do not return 'cached' results */
#define MASTER_ONLY (1<<5) /* Get value only from master server */
#define EXPAND_NAME (1<<6) /* Expand partitially qualified names */
/* Semantic modification for table operations flags */
#define RETURN_RESULT (1<<7) /* Return resulting object to client */
#define ADD_OVERWRITE (1<<8) /* Allow overwrites on ADD */
#define REM_MULTIPLE (1<<9) /* Allow wildcard deletes */
#define MOD_SAMEOBJ (1<<10) /* Check modified object before write */
#define ADD_RESERVED (1<<11) /* Spare ADD semantic */
#define REM_RESERVED (1<<12) /* Spare REM semantic */
#define MOD_EXCLUSIVE (1<<13) /* Modify no overwrite on modified keys */
/* Transport specific modifications to the operation */
#define USE_DGRAM (1<<16) /* Use a datagram transport */
#define NO_AUTHINFO (1<<17) /* Don't bother attaching auth info */
/*
* Declarations for "standard" NIS+ tags
* State variable tags have values 0 - 2047
* Statistic tags have values 2048 - 65535
* User Tags have values >2^16
*/
#define TAG_DEBUG 1 /* set debug level */
#define TAG_STATS 2 /* Enable/disable statistics */
#define TAG_GCACHE 3 /* Flush the Group Cache */
#define TAG_GCACHE_ALL TAG_GCACHE
#define TAG_DCACHE 4 /* Flush the directory cache */
#define TAG_DCACHE_ONE TAG_DCACHE
#define TAG_OCACHE 5 /* Flush the Object Cache */
#define TAG_SECURE 6 /* Set the security level */
#define TAG_TCACHE_ONE 7 /* Flush the table cache */
#define TAG_DCACHE_ALL 8 /* Flush entire directory cache */
#define TAG_TCACHE_ALL 9 /* Flush entire table cache */
#define TAG_GCACHE_ONE 10 /* Flush one group object */
#define TAG_DCACHE_ONE_REFRESH 11 /* Flush and refresh one DO */
#define TAG_OPSTATS 2048 /* NIS+ operations statistics */
#define TAG_THREADS 2049 /* Child process/thread status */
#define TAG_HEAP 2050 /* Heap usage statistics */
#define TAG_UPDATES 2051 /* Updates to this service */
#define TAG_VISIBLE 2052 /* First update that isn't replicated */
#define TAG_S_DCACHE 2053 /* Directory cache statistics */
#define TAG_S_OCACHE 2054 /* Object cache statistics */
#define TAG_S_GCACHE 2055 /* Group cache statistics */
#define TAG_S_STORAGE 2056 /* Group cache statistics */
#define TAG_UPTIME 2057 /* Time that server has been up */
#define TAG_DIRLIST 2058 /* Dir served by this server */
#define TAG_NISCOMPAT 2059 /* Whether supports NIS compat mode */
#define TAG_DNSFORWARDING 2060 /* Whether DNS forwarding supported */
#define TAG_SECURITY_LEVEL 2061 /* Security level of the server */
#define TAG_ROOTSERVER 2062 /* Whether root server */
/*
* Declarations for the Group object flags. Currently
* there are only 3.
*/
#define IMPMEM_GROUPS 1 /* Implicit Membership allowed */
#define RECURS_GROUPS 2 /* Recursive Groups allowed */
#define NEGMEM_GROUPS 4 /* Negative Groups allowed */
#ifdef __cplusplus
}
#endif
#endif /* _RPCSVC_NIS_TAGS_H */

165
nis/rpcsvc/nislib.h Normal file
View File

@ -0,0 +1,165 @@
/* 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 __RPCSVC_NISLIB_H__
#define __RPCSVC_NISLIB_H__
#include <features.h>
__BEGIN_DECLS
/*
** nis_names
*/
extern nis_result *nis_lookup __P ((__const nis_name, const u_long));
extern nis_result *nis_add __P ((__const nis_name, const nis_object *));
extern nis_result *nis_remove __P ((__const nis_name, const nis_object *));
extern nis_result *nis_modify __P ((__const nis_name, const nis_object *));
/*
** nis_table
*/
extern nis_result *nis_list __P ((__const nis_name, const u_long,
int (*)(__const nis_name,
__const nis_object *,
__const void *), __const void *));
extern nis_result *nis_add_entry __P ((__const nis_name, __const nis_object *,
__const u_long));
extern nis_result *nis_modify_entry __P ((__const nis_name,
__const nis_object *,
__const u_long));
extern nis_result *nis_remove_entry __P ((__const nis_name,
__const nis_object *,
__const u_long));
extern nis_result *nis_first_entry __P ((__const nis_name));
extern nis_result *nis_next_entry __P ((__const nis_name, __const netobj *));
/*
** nis_server
*/
extern nis_error nis_mkdir __P ((__const nis_name, __const nis_server *));
extern nis_error nis_rmdir __P ((__const nis_name, __const nis_server *));
extern nis_error nis_servstate __P ((__const nis_server *, __const nis_tag *,
__const int, nis_tag **));
extern nis_error nis_stats __P ((__const nis_server *, __const nis_tag *,
__const int, nis_tag **));
extern void nis_freetags __P ((nis_tag *, __const int));
extern nis_server **nis_getservlist __P ((__const nis_name));
extern void nis_freeservlist __P ((nis_server **));
/*
** nis_subr
*/
extern nis_name nis_leaf_of __P ((__const nis_name));
extern nis_name nis_leaf_of_r __P ((__const nis_name, char *, size_t));
extern nis_name nis_name_of __P ((__const nis_name));
extern nis_name nis_name_of_r __P ((__const nis_name, char *, size_t));
extern nis_name nis_domain_of __P ((__const nis_name));
extern nis_name nis_domain_of_r __P ((__const nis_name, char *, size_t));
extern nis_name *nis_getnames __P ((__const nis_name));
extern void nis_freenames __P ((nis_name *));
extern name_pos nis_dir_cmp __P ((nis_name, nis_name));
extern nis_object *nis_clone_object __P ((__const nis_object *, nis_object *));
extern void nis_destroy_object __P ((nis_object *));
extern void nis_print_object __P ((__const nis_object *));
/*
** nis_local_names
*/
extern nis_name nis_local_group __P ((void));
extern nis_name nis_local_directory __P ((void));
extern nis_name nis_local_principal __P ((void));
extern nis_name nis_local_host __P ((void));
/*
** nis_error
*/
extern const char *nis_sperrno __P ((__const nis_error));
extern void nis_perror __P ((__const nis_error, __const char *));
extern void nis_lerror __P ((__const nis_error, __const char *));
extern char *nis_sperror __P ((__const nis_error, __const char *));
extern char *nis_sperror_r __P ((__const nis_error, __const char *,
char *, size_t));
/*
** nis_groups
*/
extern bool_t nis_ismember __P ((__const nis_name, __const nis_name));
extern nis_error nis_addmember __P ((__const nis_name, __const nis_name));
extern nis_error nis_removemember __P ((__const nis_name, __const nis_name));
extern nis_error nis_creategroup __P ((__const nis_name, __const u_long));
extern nis_error nis_destroygroup __P ((__const nis_name));
extern void nis_print_group_entry __P ((__const nis_name));
extern nis_error nis_verifygroup __P ((__const nis_name));
/*
** nis_ping
*/
extern void nis_ping __P ((__const nis_name, __const u_long,
__const nis_object *));
extern nis_result *nis_checkpoint __P ((__const nis_name));
/*
** nis_print (XXX INTERNAL FUNCTIONS, SHOULD NOT BE USED !!)
*/
extern void nis_print_result __P ((__const nis_result *));
extern void nis_print_rights __P ((__const u_long));
extern void nis_print_directory __P ((__const directory_obj *));
extern void nis_print_group __P ((__const group_obj *));
extern void nis_print_table __P ((__const table_obj *));
extern void nis_print_link __P ((__const link_obj *));
extern void nis_print_entry __P ((__const entry_obj *));
/*
** nis_file (XXX INTERNAL FUNCTIONS, SHOULD NOT BE USED !!)
*/
extern directory_obj *readColdStartFile __P ((void));
extern bool_t writeColdStartFile __P ((__const directory_obj *));
extern nis_object *nis_read_obj __P ((__const char *));
extern bool_t nis_write_obj __P ((__const char *, __const nis_object *));
/*
** nis_clone - (XXX INTERNAL FUNCTIONS, SHOULD NOT BE USED !!)
*/
extern directory_obj *nis_clone_directory __P ((__const directory_obj *,
directory_obj *));
extern group_obj *nis_clone_group __P ((__const group_obj *, group_obj *));
extern table_obj *nis_clone_table __P ((__const table_obj *, table_obj *));
extern entry_obj *nis_clone_entry __P ((__const entry_obj *, entry_obj *));
extern link_obj *nis_clone_link __P ((__const link_obj *, link_obj *));
extern objdata *nis_clone_objdata __P ((__const objdata *, objdata *));
extern nis_result *nis_clone_result __P ((__const nis_result *, nis_result *));
/*
** nis_free - nis_freeresult
*/
extern void nis_freeresult __P ((nis_result *));
/* (XXX INTERNAL FUNCTIONS, SHOULD NOT BE USED !!) */
extern void nis_free_attr __P ((nis_attr *));
extern void nis_free_request __P ((ib_request *));
extern void nis_free_endpoints __P ((endpoint *, int));
extern void nis_free_servers __P ((nis_server *, int));
extern void nis_free_directory __P ((directory_obj *));
extern void nis_free_group __P ((group_obj *));
extern void nis_free_table __P ((table_obj *));
extern void nis_free_entry __P ((entry_obj *));
extern void nis_free_link __P ((link_obj *));
extern void nis_free_object __P ((nis_object *));
/* This is the SUN definition, but I don't know for what we need
the directory_obj parameter */
/* extern fd_result *nis_finddirectory __P ((directory_obj *, nis_name)); */
extern fd_result *__nis_finddirectory __P ((nis_name));
extern int __start_clock(int);
extern u_long __stop_clock(int);
__END_DECLS
#endif /* __RPCSVC_NISLIB_H__ */

View File

@ -41,8 +41,8 @@ LINE_PARSER
DB_LOOKUP (servbyname, 1 + strlen (name), (".%s/%s", name, proto),
{
/* Must match both protocol and name. */
if (strcmp (result->s_proto, proto))
/* Must match both protocol (if specified) and name. */
if (proto != NULL && strcmp (result->s_proto, proto))
continue;
LOOKUP_NAME (s_name, s_aliases)
},

View File

@ -52,6 +52,29 @@ main (void)
jump (value + 1);
}
if (!lose && value == 10)
{
/* Do a second test, this time without `setjmp' being a macro. */
#undef setjmp
value = setjmp (env);
if (value != last_value + 1)
{
fputs("Shouldn't have ", stdout);
lose = 1;
}
last_value = value;
switch (value)
{
case 0:
puts("Saved environment.");
jump (0);
default:
printf ("Jumped to %d.\n", value);
if (value < 10)
jump (value + 1);
}
}
if (lose || value != 10)
puts ("Test FAILED!");
else

View File

@ -56,13 +56,15 @@ alpha-.*-linux.* libnss_dns=1.1
alpha-.*-linux.* libnss_db=1.1
alpha-.*-linux.* libnss_compat=1.1
alpha-.*-linux.* libnss_nis=1.1
alpha-.*-linux.* libnss_nisplus=1.1
.*-.*-.* libnss_files=1
.*-.*-.* libnss_dns=1
.*-.*-.* libnss_db=1
.*-.*-.* libnss_compat=1
.*-.*-.* libnss_nis=1
.*-.*-.* libnss_nisplus=1
# Version for libnsl with YP functions.
# Version for libnsl with YP and NIS+ functions.
alpha-.*-linux.* libnsl=1.1
.*-.*-.* libnsl=1

View File

@ -132,9 +132,9 @@ setenv (name, value, replace)
return -1;
}
*ep = new;
memcpy (*ep, name, namelen);
(*ep)[namelen] = '=';
}
memcpy (*ep, name, namelen);
(*ep)[namelen] = '=';
memcpy (&(*ep)[namelen + 1], value, vallen);
}

View File

@ -1,21 +1,21 @@
/* setjmp for i386.
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Copyright (C) 1995, 1996, 1997 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 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.
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., 675 Mass Ave,
Cambridge, MA 02139, USA. */
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 <sysdep.h>
#define _ASM
@ -24,7 +24,9 @@ Cambridge, MA 02139, USA. */
/* Binary compatibility entry point. */
ENTRY (__setjmp)
popl %eax /* Pop return address. */
popl %ecx /* Pop jmp_buf. */
pushl $0 /* Push zero argument. */
pushl %ecx /* Push jmp_buf. */
pushl %eax /* Push back return address. */
ENTRY (__sigsetjmp)

View File

@ -64,6 +64,13 @@ nan: .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
ENTRY(__ieee754_pow)
fldl 12(%esp) // y
fxam
#ifdef PIC
call 1f
1: popl %ecx
addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
#endif
fnstsw
movb %ah, %dl
andb $0x45, %ah
@ -76,12 +83,6 @@ ENTRY(__ieee754_pow)
cmpb $0x01, %ah // is y == NaN ?
je 30f
#ifdef PIC
call 1f
1: popl %ecx
addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
#endif
fldl 4(%esp) // x : y
subl $8,%esp

View File

@ -64,6 +64,13 @@ nan: .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
ENTRY(__ieee754_powf)
flds 8(%esp) // y
fxam
#ifdef PIC
call 1f
1: popl %ecx
addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
#endif
fnstsw
movb %ah, %dl
andb $0x45, %ah
@ -76,12 +83,6 @@ ENTRY(__ieee754_powf)
cmpb $0x01, %ah // is y == NaN ?
je 30f
#ifdef PIC
call 1f
1: popl %ecx
addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
#endif
flds 4(%esp) // x : y
subl $4, %esp

View File

@ -64,6 +64,13 @@ nan: .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
ENTRY(__ieee754_powl)
fldt 16(%esp) // y
fxam
#ifdef PIC
call 1f
1: popl %ecx
addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
#endif
fnstsw
movb %ah, %dl
andb $0x45, %ah
@ -76,12 +83,6 @@ ENTRY(__ieee754_powl)
cmpb $0x01, %ah // is y == NaN ?
je 30f
#ifdef PIC
call 1f
1: popl %ecx
addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
#endif
fldt 4(%esp) // x : y
subl $8,%esp

View File

@ -62,5 +62,6 @@ ENTRY (__longjmp)
lfd 30,((JB_FPRS+16*2)*4)(3)
lwz 31,((JB_GPRS+17)*4)(3)
lfd 31,((JB_FPRS+17*2)*4)(3)
mr 3,4
blr
END (__longjmp)

View File

@ -25,5 +25,9 @@
ENTRY (_setjmp)
li 4,0 /* Set second argument to 0. */
b C_SYMBOL_NAME(__sigsetjmp)
#ifdef PIC
b __sigsetjmp@plt
#else
b __sigsetjmp
#endif
END (_setjmp)

View File

@ -0,0 +1,33 @@
/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. PowerPC version.
Copyright (C) 1994, 1997 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. */
/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
We cannot do it in C because it must be a tail-call, so frame-unwinding
in setjmp doesn't clobber the state restored by longjmp. */
#include <sysdep.h>
ENTRY (setjmp)
li 4,1 /* Set second argument to 1. */
#ifdef PIC
b __sigsetjmp@plt
#else
b __sigsetjmp
#endif
END (setjmp)

View File

@ -26,6 +26,14 @@
/* stuff for the PLT */
#define PLT_INITIAL_ENTRY_WORDS 18
#define PLT_LONGBRANCH_ENTRY_WORDS 10
#define PLT_DOUBLE_SIZE (1<<13)
#define PLT_ENTRY_START_WORDS(entry_number) \
(PLT_INITIAL_ENTRY_WORDS + (entry_number)*2 + \
((entry_number) > PLT_DOUBLE_SIZE ? \
((entry_number) - PLT_DOUBLE_SIZE)*2 : \
0))
#define PLT_DATA_START_WORDS(num_entries) PLT_ENTRY_START_WORDS(num_entries)
#define OPCODE_ADDI(rd,ra,simm) \
(0x38000000 | (rd) << 21 | (ra) << 16 | (simm) & 0xffff)
#define OPCODE_ADDIS(rd,ra,simm) \
@ -44,6 +52,19 @@
#define OPCODE_LI(rd,simm) OPCODE_ADDI(rd,0,simm)
#define OPCODE_SLWI(ra,rs,sh) OPCODE_RLWINM(ra,rs,sh,0,31-sh)
#define PPC_DCBST(where) asm __volatile__ ("dcbst 0,%0" : : "r"(where))
+#define PPC_SYNC asm __volatile__ ("sync")
+#define PPC_ISYNC asm __volatile__ ("sync; isync")
+#define PPC_ICBI(where) asm __volatile__ ("icbi 0,%0" : : "r"(where))
/* Use this when you've modified some code, but it won't be in the
instruction fetch queue (or when it doesn't matter if it is). */
#define MODIFIED_CODE_NOQUEUE(where) \
do { PPC_DCBST(where); PPC_SYNC; PPC_ICBI(where); } while (0)
/* Use this when it might be in the instruction queue. */
#define MODIFIED_CODE(where) \
do { PPC_DCBST(where); PPC_SYNC; PPC_ICBI(where); PPC_ISYNC; } while (0)
/* Return nonzero iff E_MACHINE is compatible with the running host. */
static inline int
@ -53,7 +74,8 @@ elf_machine_matches_host (Elf32_Half e_machine)
}
/* Return the link-time address of _DYNAMIC, the first value in the GOT. */
/* Return the link-time address of _DYNAMIC, stored as
the first value in the GOT. */
static inline Elf32_Addr
elf_machine_dynamic (void)
{
@ -79,11 +101,11 @@ elf_machine_load_address (void)
get confused.
asm ("bcl 20,31,0f ;"
"0: mflr 0 ;"
"lis %0,0b@ha;"
"addi %0,%0,0b@l;"
"subf %0,%0,0"
: "=b" (addr) : : "r0", "lr");
"0: mflr 0 ;"
"lis %0,0b@ha;"
"addi %0,%0,0b@l;"
"subf %0,%0,0"
: "=b" (addr) : : "r0", "lr");
doesn't work, because the linker doesn't have to (and in fact doesn't)
update the @ha and @l references; the loader (which runs after this
@ -134,7 +156,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
if (rinfo == R_PPC_NONE)
return;
if (sym && ELF32_ST_TYPE (sym->st_info) == STT_SECTION ||
assert (sym != NULL);
if (ELF32_ST_TYPE (sym->st_info) == STT_SECTION ||
rinfo == R_PPC_RELATIVE)
{
/* Has already been relocated. */
@ -143,133 +166,124 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
}
else
{
assert (sym != NULL);
if (rinfo == R_PPC_JMP_SLOT)
loadbase = (Elf32_Word) (char *) RESOLVE (&sym,
version, DL_LOOKUP_NOPLT);
int flags;
/* We never want to use a PLT entry as the destination of a
reloc, when what is being relocated is a branch. This is
partly for efficiency, but mostly so we avoid loops. */
if (rinfo == R_PPC_REL24 ||
rinfo == R_PPC_ADDR24 ||
rinfo == R_PPC_JMP_SLOT)
flags = DL_LOOKUP_NOPLT;
else if (rinfo == R_PPC_COPY)
flags = DL_LOOKUP_NOEXEC;
else
loadbase = (Elf32_Word) (char *) RESOLVE (&sym, version, 0);
flags = 0;
loadbase = (Elf32_Word) (char *) (RESOLVE (&sym, version, flags));
if (sym == NULL)
{
/* Weak symbol that wasn't actually defined anywhere. */
assert (loadbase == 0);
assert(loadbase == 0);
finaladdr = reloc->r_addend;
}
else
finaladdr = (loadbase + (Elf32_Word)(char *)sym->st_value
+ reloc->r_addend);
finaladdr = (loadbase + (Elf32_Word) (char *) sym->st_value +
reloc->r_addend);
}
switch (rinfo)
/* This is an if/else if chain because GCC 2.7.2.[012] turns case
statements into non-PIC table lookups. When a later version
comes out that fixes this, this should be changed. */
if (rinfo == R_PPC_ADDR16_LO)
{
case R_PPC_UADDR16:
case R_PPC_ADDR16_LO:
case R_PPC_ADDR16:
*(Elf32_Half*) reloc_addr = finaladdr;
break;
case R_PPC_ADDR16_HI:
}
else if (rinfo == R_PPC_ADDR16_HI)
{
*(Elf32_Half*) reloc_addr = finaladdr >> 16;
break;
case R_PPC_ADDR16_HA:
}
else if (rinfo == R_PPC_ADDR16_HA)
{
*(Elf32_Half*) reloc_addr = finaladdr + 0x8000 >> 16;
break;
case R_PPC_REL24:
{
Elf32_Sword delta = finaladdr - (Elf32_Word) (char *) reloc_addr;
assert (delta << 6 >> 6 == delta);
*reloc_addr = *reloc_addr & 0xfc000003 | delta & 0x3fffffc;
}
break;
case R_PPC_UADDR32:
case R_PPC_GLOB_DAT:
case R_PPC_ADDR32:
case R_PPC_RELATIVE:
}
else if (rinfo == R_PPC_REL24)
{
Elf32_Sword delta = finaladdr - (Elf32_Word) (char *) reloc_addr;
assert (delta << 6 >> 6 == delta);
*reloc_addr = *reloc_addr & 0xfc000003 | delta & 0x3fffffc;
}
else if (rinfo == R_PPC_UADDR32 ||
rinfo == R_PPC_GLOB_DAT ||
rinfo == R_PPC_ADDR32 ||
rinfo == R_PPC_RELATIVE)
{
*reloc_addr = finaladdr;
break;
case R_PPC_ADDR24:
}
else if (rinfo == R_PPC_ADDR24)
{
assert (finaladdr << 6 >> 6 == finaladdr);
*reloc_addr = *reloc_addr & 0xfc000003 | finaladdr & 0x3fffffc;
break;
case R_PPC_REL14_BRTAKEN:
case R_PPC_REL14_BRNTAKEN:
case R_PPC_REL14:
{
Elf32_Sword delta = finaladdr - (Elf32_Word) (char *) reloc_addr;
*reloc_addr = *reloc_addr & 0xffdf0003 | delta & 0xfffc;
if (rinfo == R_PPC_REL14_BRTAKEN && delta >= 0 ||
rinfo == R_PPC_REL14_BRNTAKEN && delta < 0)
*reloc_addr |= 0x00200000;
}
break;
case R_PPC_COPY:
{
/* Can't use memcpy (because we can't call any functions here). */
int i;
for (i = 0; i < sym->st_size; ++i)
((unsigned char *) reloc_addr)[i] =
((unsigned char *)finaladdr)[i];
}
break;
case R_PPC_REL32:
}
else if (rinfo == R_PPC_COPY)
{
/* Memcpy is safe to use here, because ld.so doesn't have any
COPY relocs (it's self-contained). */
memcpy (reloc_addr, (char *) finaladdr, sym->st_size);
}
else if (rinfo == R_PPC_REL32)
{
*reloc_addr = finaladdr - (Elf32_Word) (char *) reloc_addr;
break;
case R_PPC_JMP_SLOT:
if (finaladdr <= 0x01fffffc || finaladdr >= 0xfe000000)
*reloc_addr = OPCODE_BA (finaladdr);
}
else if (rinfo == R_PPC_JMP_SLOT)
{
Elf32_Sword delta = finaladdr - (Elf32_Word) (char *) reloc_addr;
if (delta << 6 >> 6 == delta)
*reloc_addr = OPCODE_B(delta);
else if (finaladdr <= 0x01fffffc || finaladdr >= 0xfe000000)
*reloc_addr = OPCODE_BA(finaladdr);
else
{
Elf32_Sword delta = finaladdr - (Elf32_Word) (char *) reloc_addr;
if (delta <= 0x01fffffc && delta >= 0xfe000000)
*reloc_addr = OPCODE_B (delta);
Elf32_Word *plt = (Elf32_Word *)((char *)map->l_addr +
map->l_info[DT_PLTGOT]->d_un.d_val);
Elf32_Word index = (reloc_addr - plt - PLT_INITIAL_ENTRY_WORDS)/2;
Elf32_Word offset = index * 2 + PLT_INITIAL_ENTRY_WORDS;
if (index >= PLT_DOUBLE_SIZE)
{
/* Slots greater than or equal to 2^13 have 4 words
available instead of two. */
plt[offset ] = OPCODE_LI (11,finaladdr);
plt[offset+1] = OPCODE_ADDIS (11,11,finaladdr + 0x8000 >> 16);
plt[offset+2] = OPCODE_MTCTR (11);
plt[offset+3] = OPCODE_BCTR ();
}
else
{
Elf32_Word *plt =
(Elf32_Word *) ((char *) map->l_addr
+ map->l_info[DT_PLTGOT]->d_un.d_val);
Elf32_Word index =((reloc_addr - plt - PLT_INITIAL_ENTRY_WORDS)
/ 2);
int num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val
/ sizeof (Elf32_Rela));
int rel_offset_words = (PLT_INITIAL_ENTRY_WORDS
+ num_plt_entries * 2);
Elf32_Word num_plt_entries;
Elf32_Word rel_offset_words;
if (index >= (1 << 13))
{
/* Indexes greater than or equal to 2^13 have 4
words available instead of two. */
plt[index * 2 + PLT_INITIAL_ENTRY_WORDS] =
OPCODE_LI (11, finaladdr);
plt[index * 2 + 1 + PLT_INITIAL_ENTRY_WORDS] =
OPCODE_ADDIS (11, 11, finaladdr + 0x8000 >> 16);
plt[index * 2 + 2 + PLT_INITIAL_ENTRY_WORDS] =
OPCODE_MTCTR (11);
plt[index * 2 + 2 + PLT_INITIAL_ENTRY_WORDS] =
OPCODE_BCTR ();
}
else
{
plt[index * 2 + PLT_INITIAL_ENTRY_WORDS] =
OPCODE_LI (11, index * 4);
plt[index * 2 + 1 + PLT_INITIAL_ENTRY_WORDS] =
OPCODE_B(-(4 * (index * 2 + 1 + PLT_INITIAL_ENTRY_WORDS
+ PLT_LONGBRANCH_ENTRY_WORDS)));
plt[index + rel_offset_words] = finaladdr;
}
num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val
/ sizeof(Elf32_Rela));
rel_offset_words = PLT_DATA_START_WORDS (num_plt_entries);
plt[offset ] = OPCODE_LI (11,index * 4);
plt[offset+1] = OPCODE_B (-(4 * (offset + 1
- PLT_LONGBRANCH_ENTRY_WORDS)));
plt[index + rel_offset_words] = finaladdr;
}
}
break;
default:
assert (! "unexpected dynamic reloc type");
MODIFIED_CODE(reloc_addr);
}
else
assert (! "unexpected dynamic reloc type");
if (rinfo == R_PPC_ADDR16_LO ||
rinfo == R_PPC_ADDR16_HI ||
rinfo == R_PPC_ADDR16_HA ||
rinfo == R_PPC_REL24 ||
rinfo == R_PPC_ADDR24)
MODIFIED_CODE_NOQUEUE (reloc_addr);
}
#define ELF_MACHINE_NO_REL 1
@ -282,64 +296,58 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
/* Set up the loaded object described by L so its unrelocated PLT
entries will jump to the on-demand fixup code in dl-runtime.c. */
/* This code does not presently work if there are more than 2^13 PLT
entries. */
static inline void
elf_machine_runtime_setup (struct link_map *map, int lazy)
{
Elf32_Word *plt;
int i;
Elf32_Word num_plt_entries;
Elf32_Word rel_offset_words;
extern void _dl_runtime_resolve (void);
if (map->l_info[DT_JMPREL])
{
int i;
/* Fill in the PLT. Its initial contents are directed to a
function earlier in the PLT which arranges for the dynamic
linker to be called back. */
plt = (Elf32_Word *) ((char *) map->l_addr +
map->l_info[DT_PLTGOT]->d_un.d_val);
num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val
/ sizeof (Elf32_Rela));
rel_offset_words = PLT_INITIAL_ENTRY_WORDS + num_plt_entries * 2;
Elf32_Word *plt = (Elf32_Word *) ((char *) map->l_addr
+ map->l_info[DT_PLTGOT]->d_un.d_val);
Elf32_Word num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val
/ sizeof (Elf32_Rela));
Elf32_Word rel_offset_words = PLT_DATA_START_WORDS (num_plt_entries);
extern void _dl_runtime_resolve (void);
Elf32_Word size_modified;
if (lazy)
for (i = 0; i < num_plt_entries; i++)
if (i >= (1 << 13))
{
plt[i * 2 + (i - (1 << 13)) * 2 + PLT_INITIAL_ENTRY_WORDS] =
OPCODE_LI (11, i * 4);
plt[i * 2 + (i - (1 << 13)) * 2 + 1 + PLT_INITIAL_ENTRY_WORDS] =
OPCODE_ADDIS (11, 11, i * 4 + 0x8000 >> 16);
plt[i * 2 + (i - (1 << 13)) * 2 + 2 + PLT_INITIAL_ENTRY_WORDS] =
OPCODE_B (-(4 * ( i * 2 + 1 + PLT_INITIAL_ENTRY_WORDS)));
}
else
{
plt[i * 2 + PLT_INITIAL_ENTRY_WORDS] = OPCODE_LI (11, i * 4);
plt[i * 2 + 1 + PLT_INITIAL_ENTRY_WORDS] =
OPCODE_B (-(4 * (i * 2 + 1 + PLT_INITIAL_ENTRY_WORDS)));
}
/* Multiply index of entry, by 0xC. */
plt[0] = OPCODE_SLWI (12, 11, 1);
plt[1] = OPCODE_ADD (11, 12, 11);
if ((Elf32_Word) (char *) _dl_runtime_resolve <= 0x01fffffc ||
(Elf32_Word) (char *) _dl_runtime_resolve >= 0xfe000000)
{
plt[2] = OPCODE_LI (12, (Elf32_Word) (char *) map);
plt[3] = OPCODE_ADDIS (12, 12,
(Elf32_Word) (char *) map + 0x8000 >> 16);
plt[4] = OPCODE_BA ((Elf32_Word) (char *) _dl_runtime_resolve);
Elf32_Word offset = PLT_ENTRY_START_WORDS(i);
if (i >= PLT_DOUBLE_SIZE)
{
plt[offset ] = OPCODE_LI (11, i * 4);
plt[offset+1] = OPCODE_ADDIS (11, 11, i * 4 + 0x8000 >> 16);
plt[offset+2] = OPCODE_B (-(4 * (offset + 2)));
}
else
{
plt[offset ] = OPCODE_LI (11, i * 4);
plt[offset+1] = OPCODE_B(-(4 * (offset + 1)));
}
/* Multiply index of entry, by 0xC. */
plt[0] = OPCODE_SLWI (12, 11, 1);
plt[1] = OPCODE_ADD (11, 12, 11);
if ((Elf32_Word) (char *) _dl_runtime_resolve <= 0x01fffffc
|| (Elf32_Word) (char *) _dl_runtime_resolve >= 0xfe000000)
{
plt[2] = OPCODE_LI (12, (Elf32_Word) (char *) map);
plt[3] = OPCODE_ADDIS (12, 12,
(Elf32_Word) (char *) map + 0x8000 >> 16);
plt[4] = OPCODE_BA ((Elf32_Word) (char *) _dl_runtime_resolve);
}
}
else
{
plt[2] = OPCODE_LI (12, (Elf32_Word) (char *) _dl_runtime_resolve);
plt[3] = OPCODE_ADDIS (12, 12, 0x8000 +
((Elf32_Word) (char *) _dl_runtime_resolve
>> 16));
plt[3] = OPCODE_ADDIS(12, 12, 0x8000 +
((Elf32_Word) (char *) _dl_runtime_resolve
>> 16));
plt[4] = OPCODE_MTCTR (12);
plt[5] = OPCODE_LI (12, (Elf32_Word) (char *) map);
plt[6] = OPCODE_ADDIS (12, 12, ((Elf32_Word) (char *) map
@ -347,21 +355,28 @@ elf_machine_runtime_setup (struct link_map *map, int lazy)
plt[7] = OPCODE_BCTR ();
}
plt[PLT_LONGBRANCH_ENTRY_WORDS] =
OPCODE_ADDIS (11, 11, ((Elf32_Word) (char*) (plt+rel_offset_words)
+ 0x8000 >> 16));
OPCODE_ADDIS (11, 11, (Elf32_Word) (char*) (plt + rel_offset_words)
+ 0x8000 >> 16);
plt[PLT_LONGBRANCH_ENTRY_WORDS+1] =
OPCODE_LWZ (11, (Elf32_Word) (char*) (plt + rel_offset_words), 11);
OPCODE_LWZ(11,(Elf32_Word)(char*)(plt+rel_offset_words),11);
plt[PLT_LONGBRANCH_ENTRY_WORDS+2] = OPCODE_MTCTR (11);
plt[PLT_LONGBRANCH_ENTRY_WORDS+3] = OPCODE_BCTR ();
size_modified = lazy ? rel_offset_words : PLT_INITIAL_ENTRY_WORDS;
/* Now we need to keep the caches in sync. */
for (i = 0; i < size_modified; i+=8)
PPC_DCBST (plt + i);
PPC_SYNC;
for (i = 0; i < size_modified; i+=8)
PPC_ICBI (plt + i);
PPC_ISYNC;
}
}
static inline void
elf_machine_lazy_rel (struct link_map *map, const Elf32_Rela *reloc)
{
if (ELF32_R_TYPE (reloc->r_info) != R_PPC_JMP_SLOT)
assert (! "unexpected PLT reloc type");
assert (ELF32_R_TYPE (reloc->r_info) == R_PPC_JMP_SLOT);
/* elf_machine_runtime_setup handles this. */
}
@ -369,17 +384,23 @@ elf_machine_lazy_rel (struct link_map *map, const Elf32_Rela *reloc)
#define elf_machine_relplt elf_machine_rela
/* This code is used in dl-runtime.c to call the `fixup' function
and then redirect to the address it returns. */
and then redirect to the address it returns. It is called
from code built in the PLT by elf_machine_runtime_setup. */
#define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\
.section \".text\"
.align 2
.globl _dl_runtime_resolve
.type _dl_runtime_resolve,@function
_dl_runtime_resolve:
# We need to save the registers used to pass parameters.
# We build a stack frame to put them in.
stwu 1,-48(1)
mflr 0
stw 3,16(1)
stw 4,20(1)
stw 0,52(1)
stw 5,24(1)
# We also need to save some of the condition register fields.
mfcr 0
stw 6,28(1)
stw 7,32(1)
@ -387,10 +408,13 @@ _dl_runtime_resolve:
stw 9,40(1)
stw 10,44(1)
stw 0,12(1)
# The code that calls this has put parameters for `fixup' in r12 and r11.
mr 3,12
mr 4,11
bl fixup
# 'fixup' returns the address we want to branch to.
mtctr 3
# Put the registers back...
lwz 0,52(1)
lwz 10,44(1)
lwz 9,40(1)
@ -403,37 +427,40 @@ _dl_runtime_resolve:
lwz 5,24(1)
lwz 4,20(1)
lwz 3,16(1)
# ...unwind the stack frame, and jump to the PLT entry we updated.
addi 1,1,48
bctr
0:
.size _dl_runtime_resolve,0b-_dl_runtime_resolve
# undo '.section text'.
.previous
");
/* Initial entry point code for the dynamic linker.
The C function `_dl_start' is the real entry point;
its return value is the user program's entry point. */
/* FIXME! We don't make provision for calling _dl_fini,
because Linux/PPC is somewhat broken. */
its return value is the user program's entry point. */
#define RTLD_START \
asm ("\
.text
.align 2
.align 2
.globl _start
.type _start,@function
.type _start,@function
_start:
# We start with the following on the stack, from top:
# argc (4 bytes)
# arguments for program (terminated by NULL)
# environment variables (terminated by NULL)
# arguments for the program loader
# FIXME: perhaps this should do the same trick as elf/start.c?
# Call _dl_start with one parameter pointing at argc
mr 3,1
mr 3,1
# (we have to frob the stack pointer a bit to allow room for
# _dl_start to save the link register)
li 4,0
addi 1,1,-16
stw 4,0(1)
bl _dl_start@local
li 4,0
addi 1,1,-16
stw 4,0(1)
bl _dl_start@local
# Now, we do our main work of calling initialisation procedures.
# The ELF ABI doesn't say anything about parameters for these,
@ -442,10 +469,10 @@ _start:
# passed by value!).
# put our GOT pointer in r31
bl _GLOBAL_OFFSET_TABLE_-4@local
mflr 31
bl _GLOBAL_OFFSET_TABLE_-4@local
mflr 31
# the address of _start in r30
mr 30,3
mr 30,3
# &_dl_argc in 29, &_dl_argv in 27, and _dl_default_scope in 28
lwz 28,_dl_default_scope@got(31)
lwz 29,_dl_argc@got(31)
@ -499,13 +526,19 @@ _start:
mtlr 0
# and also clear _dl_starting_up
lwz 26,_dl_starting_up@got(31)
stw 0,0(3)
stw 0,0(26)
# go do it!
bctr
0:
.size _start,0b-_start
# undo '.section text'.
.previous
");
#define ELF_PREFERRED_ADDRESS_DATA static ElfW(Addr) _dl_preferred_address = 0;
#define ELF_PREFERRED_ADDRESS(loader, maplength, mapstartpref) \
#define ELF_PREFERRED_ADDRESS_DATA \
static ElfW(Addr) _dl_preferred_address = 0;
#define ELF_PREFERRED_ADDRESS(loader, maplength, mapstartpref) \
( { \
ElfW(Addr) prefd; \
if (mapstartpref != 0 && _dl_preferred_address == 0) \
@ -516,13 +549,14 @@ _start:
prefd = 0; \
else \
prefd = _dl_preferred_address = \
(_dl_preferred_address - maplength - 0x10000) & \
~(_dl_pagesize - 1); \
((_dl_preferred_address - maplength - 0x10000) \
& ~(_dl_pagesize - 1)); \
prefd; \
} )
#define ELF_FIXED_ADDRESS(loader, mapstart) \
#define ELF_FIXED_ADDRESS(loader, mapstart) \
( { \
if (mapstart != 0 && _dl_preferred_address == 0) \
if (mapstart != 0 && _dl_preferred_address < mapstart) \
_dl_preferred_address = mapstart; \
} )

View File

@ -26,22 +26,27 @@
/* Just a little assembler stub before gcc gets its hands on our
stack pointer... */
asm ("\
.text
.section \".text\"
.align 2
.globl _start
_start:
# save the stack pointer, in case we're statically linked under Linux
mr 8,1
mr 8,1
# set up an initial stack frame, and clear the LR
addi 1,1,-16
clrrwi 1,1,4
li 0,0
stw 0,0(1)
mtlr 0
addi 1,1,-16
clrrwi 1,1,4
li 0,0
stw 0,0(1)
mtlr 0
# set r13 to point at the 'small data area'
lis 13,_SDA_BASE_@ha
addi 13,13,_SDA_BASE_@l
lis 13,_SDA_BASE_@ha
addi 13,13,_SDA_BASE_@l
# and continue below.
b __start1
b __start1
0:
.size _start,0b-_start
# undo '.section text'.
.previous
");
/* Define a symbol for the first piece of initialized data. */
@ -53,38 +58,46 @@ weak_alias (__data_start, data_start)
void (*_mach_init_routine) (void);
void (*_thread_init_routine) (void);
void __libc_init_first (int argc, char **argv, char **envp);
int main (int argc, char **argv, char **envp, void *auxvec);
extern void __libc_init_first (int argc, char **argv, char **envp);
extern int main (int argc, char **argv, char **envp, void *auxvec);
#ifdef HAVE_INITFINI
void _init (void);
void _fini (void);
extern void _init (void);
extern void _fini (void);
#endif
#if 0
/* I'd like to say this, but it causes GCC to strip the whole procedure
from the object file (this is sort of reasonable, because you've told
GCC that the procedure is unused). :-( */
static void __start1(int argc, char **argv, char **envp,
void *auxvec, void (*exitfn) (void), char **arguments)
void *auxvec, void (*exitfn) (void),
char **stack_on_entry)
__attribute__ ((unused));
static void
static
#endif
void
__start1(int argc, char **argv, char **envp,
void *auxvec, void (*exitfn) (void),
char **arguments)
char **stack_on_entry)
{
/* the PPC SVR4 ABI says that the top thing on the stack will
be a NULL pointer, so if not we assume that we're being called
as a statically-linked program by Linux. */
int abi_compliant_startup = *arguments == NULL;
if (!abi_compliant_startup)
{
argc = *(int *) arguments;
argv = arguments+1;
envp = argv+argc+1;
auxvec = envp;
while (auxvec != NULL)
auxvec++;
auxvec++;
exitfn = NULL;
}
as a statically-linked program by Linux... */
if (*stack_on_entry != NULL)
{
/* ...in which case, we have argc as the top thing on the
stack, followed by argv (NULL-terminated), envp (likewise),
and the auxilary vector. */
argc = *(int *) stack_on_entry;
argv = stack_on_entry + 1;
envp = argv + argc + 1;
auxvec = envp;
while (*(char **) auxvec != NULL)
++auxvec;
++auxvec;
exitfn = NULL;
}
if (exitfn != NULL)
atexit (exitfn);

View File

@ -62,5 +62,9 @@ ENTRY (__sigsetjmp)
stfd 30,((JB_FPRS+16*2)*4)(3)
stw 31,((JB_GPRS+17)*4)(3)
stfd 31,((JB_FPRS+17*2)*4)(3)
#ifdef PIC
b __sigjmp_save@plt
#else
b __sigjmp_save
#endif
END (__sigsetjmp)

View File

@ -1 +1,4 @@
setrgid.c
setruid.c
bsdstat.h
bsdtty.h

View File

@ -1 +1,2 @@
direct.h
sysv_termio.h

View File

@ -21,6 +21,7 @@ netinet/igmp.h
netinet/in_systm.h
netinet/ip_fw.h
netinet/ip_icmp.h
netinet/tcp.h
netinet/udp.h
netipx/ipx.h
nfs/nfs.h

View File

@ -27,7 +27,6 @@
#ifdef __USE_GNU
#define O_READ O_RDONLY /* Open for reading. */
#define O_WRITE O_WRONLY /* Open for writing. */
#define O_NORW 0 /* Open without R/W access. */
#endif
/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
located on an ext2 file system */

View File

@ -27,7 +27,6 @@
#ifdef __USE_GNU
#define O_READ O_RDONLY /* Open for reading. */
#define O_WRITE O_WRONLY /* Open for writing. */
#define O_NORW 0 /* Open without R/W access. */
#endif
/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
located on an ext2 file system */

View File

@ -51,7 +51,7 @@ __BEGIN_DECLS
#define PPP_MTU 1500 /* Default MTU (size of Info field) */
#define PPP_MAXMRU 65000 /* Largest MRU we allow */
#define PPP_VERSION "2.3.0"
#define PPP_VERSION "2.2.0"
#define PPP_MAGIC 0x5002 /* Magic value for the ppp structure */
#define PROTO_IPX 0x002b /* protocol numbers */
#define PROTO_DNA_RT 0x0027 /* DNA Routing */

View File

@ -71,4 +71,8 @@ child:
badargs:
li 3,-EINVAL
error:
#ifdef PIC
b __syscall_error@plt
#else
b __syscall_error
#endif

View File

@ -0,0 +1,237 @@
/* Operating system support for run-time dynamic linker. Linux/PPC version.
Copyright (C) 1995, 1996, 1997 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 <elf.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <link.h>
#include <unistd.h>
#include <stdarg.h>
#include <string.h>
extern int _dl_argc;
extern char **_dl_argv;
extern char **_environ;
extern size_t _dl_pagesize;
extern void _end;
extern void _start (void);
int __libc_enable_secure;
int __libc_multiple_libcs; /* Defining this here avoids the inclusion
of init-first. */
ElfW(Addr)
_dl_sysdep_start (void **start_argptr,
void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum,
ElfW(Addr) *user_entry))
{
const ElfW(Phdr) *phdr = NULL;
ElfW(Word) phnum = 0;
ElfW(Addr) user_entry;
ElfW(auxv_t) *av;
uid_t uid = 0;
uid_t euid = 0;
gid_t gid = 0;
gid_t egid = 0;
unsigned int seen;
user_entry = (ElfW(Addr)) &_start;
_dl_argc = *(long *) start_argptr;
_dl_argv = (char **) start_argptr + 1;
_environ = &_dl_argv[_dl_argc + 1];
start_argptr = (void **) _environ;
while (*start_argptr)
++start_argptr;
++start_argptr;
if (*start_argptr == 0 &&
((unsigned)(char *)start_argptr & 0xF) != 0)
{
unsigned test_sap = (int)(char *)start_argptr;
test_sap = test_sap + 0xF & ~0xF;
if (*(long *)(char *)test_sap == AT_PHDR)
start_argptr = (void **)(char *)test_sap;
}
seen = 0;
#define M(type) (1 << (type))
for (av = (void *) start_argptr;
av->a_type != AT_NULL;
seen |= M ((++av)->a_type))
switch (av->a_type)
{
case AT_PHDR:
phdr = av->a_un.a_ptr;
break;
case AT_PHNUM:
phnum = av->a_un.a_val;
break;
case AT_PAGESZ:
_dl_pagesize = av->a_un.a_val;
break;
case AT_ENTRY:
user_entry = av->a_un.a_val;
break;
case AT_UID:
uid = av->a_un.a_val;
break;
case AT_GID:
gid = av->a_un.a_val;
break;
case AT_EUID:
euid = av->a_un.a_val;
break;
case AT_EGID:
egid = av->a_un.a_val;
break;
}
/* Linux doesn't provide us with any of these values on the stack
when the dynamic linker is run directly as a program. */
#define SEE(UID, uid) if ((seen & M (AT_##UID)) == 0) uid = __get##uid ()
SEE (UID, uid);
SEE (GID, gid);
SEE (EUID, euid);
SEE (EGID, egid);
__libc_enable_secure = uid != euid || gid != egid;
__brk (0); /* Initialize the break. */
if (__sbrk (0) == &_end)
{
/* The dynamic linker was run as a program, and so the initial break
starts just after our bss, at &_end. The malloc in dl-minimal.c
will consume the rest of this page, so tell the kernel to move the
break up that far. When the user program examines its break, it
will see this new value and not clobber our data. */
size_t pg = __getpagesize ();
__sbrk (pg - ((&_end - (void *) 0) & pg));
__sbrk (pg - ((&_end - (void *) 0) & (pg - 1)));
}
(*dl_main) (phdr, phnum, &user_entry);
return user_entry;
}
void
_dl_sysdep_start_cleanup (void)
{
}
#ifndef MAP_ANON
/* This is only needed if the system doesn't support MAP_ANON. */
int
_dl_sysdep_open_zero_fill (void)
{
return __open ("/dev/zero", O_RDONLY);
}
#endif
/* Read the whole contents of FILE into new mmap'd space with given
protections. *SIZEP gets the size of the file. */
void *
_dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
{
void *result;
struct stat st;
int fd = __open (file, O_RDONLY);
if (fd < 0)
return NULL;
if (__fstat (fd, &st) < 0)
result = NULL;
else
{
/* Map a copy of the file contents. */
result = __mmap (0, st.st_size, prot,
#ifdef MAP_COPY
MAP_COPY
#else
MAP_PRIVATE
#endif
#ifdef MAP_FILE
| MAP_FILE
#endif
, fd, 0);
if (result == (void *) -1)
result = NULL;
else
*sizep = st.st_size;
}
__close (fd);
return result;
}
void
_dl_sysdep_fatal (const char *msg, ...)
{
va_list ap;
va_start (ap, msg);
do
{
size_t len = strlen (msg);
__write (STDERR_FILENO, msg, len);
msg = va_arg (ap, const char *);
} while (msg);
va_end (ap);
_exit (127);
}
void
_dl_sysdep_error (const char *msg, ...)
{
va_list ap;
va_start (ap, msg);
do
{
size_t len = strlen (msg);
__write (STDERR_FILENO, msg, len);
msg = va_arg (ap, const char *);
} while (msg);
va_end (ap);
}
void
_dl_sysdep_message (const char *msg, ...)
{
va_list ap;
va_start (ap, msg);
do
{
size_t len = strlen (msg);
__write (STDOUT_FILENO, msg, len);
msg = va_arg (ap, const char *);
} while (msg);
va_end (ap);
}

View File

@ -0,0 +1,25 @@
#ifndef _SYS_KERNEL_TERMIOS_H
#define _SYS_KERNEL_TERMIOS_H 1
/* The following corresponds to the values from the Linux 2.0.28 kernel. */
/* We need the definition of tcflag_t, cc_t, and speed_t. */
#include <termbits.h>
#define __KERNEL_NCCS 19
struct __kernel_termios
{
tcflag_t c_iflag; /* input mode flags */
tcflag_t c_oflag; /* output mode flags */
tcflag_t c_cflag; /* control mode flags */
tcflag_t c_lflag; /* local mode flags */
cc_t c_cc[__KERNEL_NCCS]; /* control characters */
cc_t c_line; /* line discipline */
int c_ispeed; /* input speed */
int c_ospeed; /* output speed */
};
#define _HAVE_C_ISPEED 1
#define _HAVE_C_OSPEED 1
#endif /* sys/kernel_termios.h */

View File

@ -76,7 +76,11 @@ ENTRY(P(__,socket))
DO_CALL(SYS_ify(socketcall))
addi 1,1,48
bnslr
#ifdef PIC
b __syscall_error@plt
#else
b __syscall_error
#endif
PSEUDO_END (P(__,socket))

View File

@ -0,0 +1,79 @@
/* Copyright (C) 1992, 1995, 1996, 1997 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. */
#ifndef _STATBUF_H
#define _STATBUF_H 1
/* Versions of the `struct stat' data structure. */
#define _STAT_VER_LINUX 1
#define _STAT_VER_SVR4 2
#define _STAT_VER _STAT_VER_LINUX /* The one defined below. */
/* Versions of the `xmknod' interface. */
#define _MKNOD_VER_LINUX 1
#define _MKNOD_VER_SVR4 2
#define _MKNOD_VER _MKNOD_VER_LINUX /* The bits defined below. */
struct stat
{
unsigned int st_dev; /* Device. */
unsigned int st_ino; /* File serial number. */
unsigned int st_mode; /* File mode. */
unsigned short int st_nlink; /* Link count. */
unsigned int st_uid; /* User ID of the file's owner. */
unsigned int st_gid; /* Group ID of the file's group.*/
unsigned int st_rdev; /* Device number, if device. */
long int st_size; /* Size of file, in bytes. */
unsigned long int st_blksize; /* Optimal block size for I/O. */
#define _STATBUF_ST_BLKSIZE /* Tell code we have this member. */
unsigned long int st_blocks; /* Number of 512-byte blocks allocated. */
unsigned long int st_atime; /* Time of last access. */
unsigned long int __unused1;
unsigned long int st_mtime; /* Time of last modification. */
unsigned long int __unused2;
unsigned long int st_ctime; /* Time of last status change. */
unsigned long int __unused3;
unsigned long int __unused4;
unsigned long int __unused5;
};
/* Encoding of the file mode. */
#define __S_IFMT 0170000 /* These bits determine file type. */
/* File types. */
#define __S_IFDIR 0040000 /* Directory. */
#define __S_IFCHR 0020000 /* Character device. */
#define __S_IFBLK 0060000 /* Block device. */
#define __S_IFREG 0100000 /* Regular file. */
#define __S_IFIFO 0010000 /* FIFO. */
#define __S_IFLNK 0120000 /* Symbolic link. */
#define __S_IFSOCK 0140000 /* Socket. */
/* Protection bits. */
#define __S_ISUID 04000 /* Set user ID on execution. */
#define __S_ISGID 02000 /* Set group ID on execution. */
#define __S_ISVTX 01000 /* Save swapped text after use (sticky). */
#define __S_IREAD 0400 /* Read by owner. */
#define __S_IWRITE 0200 /* Write by owner. */
#define __S_IEXEC 0100 /* Execute by owner. */
#endif /* statbuf.h */

View File

@ -28,5 +28,9 @@ ENTRY (syscall)
mr 7,8
sc
bnslr
#ifdef PIC
b __syscall_error@plt
#else
b __syscall_error
#endif
PSEUDO_END (syscall)

View File

@ -41,13 +41,21 @@
li 0,syscall; \
sc
#ifdef PIC
#define PSEUDO(name, syscall_name, args) \
.text; \
ENTRY (name) \
DO_CALL (SYS_ify (syscall_name)); \
bnslr; \
b __syscall_error@plt
#else
#define PSEUDO(name, syscall_name, args) \
.text; \
ENTRY (name) \
DO_CALL (SYS_ify (syscall_name)); \
bnslr; \
bnslr; \
b __syscall_error
#endif
#define ret /* Nothing (should be 'blr', but never reached). */
#endif /* ASSEMBLER */

View File

@ -17,9 +17,7 @@
Boston, MA 02111-1307, USA. */
#ifndef _TERMBITS_H
#define _TERMBITS_H
#include <linux/posix_types.h>
#define _TERMBITS_H 1
typedef unsigned char cc_t;
typedef unsigned int speed_t;
@ -31,14 +29,14 @@ typedef unsigned int tcflag_t;
* concerning namespace pollution.
*/
#define NCCS 19
#define NCCS 32
struct termios {
tcflag_t c_iflag; /* input mode flags */
tcflag_t c_oflag; /* output mode flags */
tcflag_t c_cflag; /* control mode flags */
tcflag_t c_lflag; /* local mode flags */
cc_t c_cc[NCCS]; /* control characters */
cc_t c_line; /* line discipline (== c_cc[19]) */
cc_t c_cc[NCCS]; /* control characters */
speed_t c_ispeed; /* input speed */
speed_t c_ospeed; /* output speed */
};
@ -219,80 +217,6 @@ struct ltchars {
char t_lnextc;
};
#define FIOCLEX _IO('f', 1)
#define FIONCLEX _IO('f', 2)
#define FIOASYNC _IOW('f', 125, int)
#define FIONBIO _IOW('f', 126, int)
#define FIONREAD _IOR('f', 127, int)
#define TIOCINQ FIONREAD
#define TIOCGETP _IOR('t', 8, struct sgttyb)
#define TIOCSETP _IOW('t', 9, struct sgttyb)
#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */
#define TIOCSETC _IOW('t', 17, struct tchars)
#define TIOCGETC _IOR('t', 18, struct tchars)
#define TCGETS _IOR('t', 19, struct termios)
#define TCSETS _IOW('t', 20, struct termios)
#define TCSETSW _IOW('t', 21, struct termios)
#define TCSETSF _IOW('t', 22, struct termios)
#define TCGETA _IOR('t', 23, struct termio)
#define TCSETA _IOW('t', 24, struct termio)
#define TCSETAW _IOW('t', 25, struct termio)
#define TCSETAF _IOW('t', 28, struct termio)
#define TCSBRK _IO('t', 29)
#define TCXONC _IO('t', 30)
#define TCFLSH _IO('t', 31)
#define TIOCSWINSZ _IOW('t', 103, struct winsize)
#define TIOCGWINSZ _IOR('t', 104, struct winsize)
#define TIOCSTART _IO('t', 110) /* start output, like ^Q */
#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */
#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */
#define TIOCGLTC _IOR('t', 116, struct ltchars)
#define TIOCSLTC _IOW('t', 117, struct ltchars)
#define TIOCSPGRP _IOW('t', 118, int)
#define TIOCGPGRP _IOR('t', 119, int)
#define TIOCEXCL 0x540C
#define TIOCNXCL 0x540D
#define TIOCSCTTY 0x540E
#define TIOCSTI 0x5412
#define TIOCMGET 0x5415
#define TIOCMBIS 0x5416
#define TIOCMBIC 0x5417
#define TIOCMSET 0x5418
#define TIOCGSOFTCAR 0x5419
#define TIOCSSOFTCAR 0x541A
#define TIOCLINUX 0x541C
#define TIOCCONS 0x541D
#define TIOCGSERIAL 0x541E
#define TIOCSSERIAL 0x541F
#define TIOCPKT 0x5420
#define TIOCNOTTY 0x5422
#define TIOCSETD 0x5423
#define TIOCGETD 0x5424
#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
#define TIOCSERCONFIG 0x5453
#define TIOCSERGWILD 0x5454
#define TIOCSERSWILD 0x5455
#define TIOCGLCKTRMIOS 0x5456
#define TIOCSLCKTRMIOS 0x5457
#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
#define TIOCSERGETLSR 0x5459 /* Get line status register */
#define TIOCSERGETMULTI 0x545A /* Get multiport config */
#define TIOCSERSETMULTI 0x545B /* Set multiport config */
#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
/* Used for packet mode */
#define TIOCPKT_DATA 0
#define TIOCPKT_FLUSHREAD 1

View File

@ -0,0 +1,71 @@
/* readv supports all Linux kernels >= 2.0.
Copyright (C) 1997 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,
read to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <errno.h>
#include <stddef.h>
#include <sys/param.h>
#include <sys/uio.h>
extern ssize_t __syscall_readv __P ((int, __const struct iovec *, int));
/* Not all versions of the kernel support the large number of records. */
#undef MAX_IOVEC
#ifdef UIO_FASTIOV
# define MAX_IOVEC UIO_FASTIOV
#else
# define MAX_IOVEC 8 /* 8 is a safe number. */
#endif
/* We should deal with kernel which have a smaller UIO_MAXIOV as well
as a very big count. */
ssize_t
readv (fd, vector, count)
int fd;
const struct iovec *vector;
int count;
{
int errno_saved = errno;
ssize_t bytes_read;
bytes_read = __syscall_readv (fd, vector, count);
if (bytes_read < 0 && errno == EINVAL && count > MAX_IOVEC)
{
int i;
/* Restore the old error value as if nothing happened. */
__set_errno (errno_saved);
bytes_read = 0;
for (i = 0; i < count; i += MAX_IOVEC)
{
ssize_t bytes = __syscall_readv (fd, vector + i,
MIN (count - i, MAX_IOVEC));
if (bytes < 0)
return bytes;
bytes_read += bytes;
}
}
return bytes_read;
}

View File

@ -56,7 +56,12 @@ setresuid EXTRA setresuid 3 setresuid
sigpending - sigpending 1 sigpending
sigprocmask - sigprocmask 3 __sigprocmask sigprocmask
sigreturn - sigreturn 1 __sigreturn sigreturn
sys_fstat fxstat fstat 2 __syscall_fstat
sys_mknod xmknod mknod 3 __syscall_mknod
sys_lstat lxstat lstat 2 __syscall_lstat
sys_readv readv readv 3 __syscall_readv
sys_stat xstat stat 2 __syscall_stat
sys_writev writev writev 3 __syscall_writev
sysinfo EXTRA sysinfo 1 sysinfo
swapon - swapon 2 swapon
umount EXTRA umount 1 __umount umount

View File

@ -0,0 +1,68 @@
/* writev supports all Linux kernels >= 2.0.
Copyright (C) 1997 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 <errno.h>
#include <stddef.h>
#include <sys/param.h>
#include <sys/uio.h>
extern ssize_t __syscall_writev __P ((int, const struct iovec *, int));
/* Not all versions of the kernel support the large number of records. */
#undef MAX_IOVEC
#ifdef UIO_FASTIOV
# define MAX_IOVEC UIO_FASTIOV
#else
# define MAX_IOVEC 8 /* 8 is a safe number. */
#endif
/* We should deal with kernel which have a smaller UIO_MAXIOV as well
as a very big count. */
ssize_t
writev (fd, vector, count)
int fd;
const struct iovec *vector;
int count;
{
int errno_saved = errno;
ssize_t bytes_written;
bytes_written = __syscall_writev (fd, vector, count);
if (bytes_written < 0 && errno == EINVAL && count > MAX_IOVEC)
{
int i;
/* Restore the old error value as if nothing happened. */
__set_errno (errno_saved);
bytes_written = 0;
for (i = 0; i < count; i += MAX_IOVEC)
{
ssize_t bytes = __syscall_writev (fd, vector + i,
MIN (count - i, MAX_IOVEC));
if (bytes < 0)
return bytes_written > 0 ? bytes_written : bytes;
}
}
return bytes_written;
}

View File

@ -0,0 +1 @@
__setpgid.c

View File

@ -1,2 +1,4 @@
__getpgid.c
__setpgid.c
sysconfig.h
siginfo.h

View File

@ -64,7 +64,7 @@ __offtime (t, offset, tp)
while (days < 0 || days >= (__isleap (y) ? 366 : 365))
{
/* Guess a corrected year, assuming 365 days per year. */
int yg = y + days / 365 - (days % 365 < 0);
long int yg = y + days / 365 - (days % 365 < 0);
/* Adjust DAYS and Y to match the guessed year. */
days -= ((yg - y) * 365