Add nsswitch support. By creating an /etc/nsswitch.conf file, you can

configure FreeBSD so that various databases such as passwd and group can be
looked up using flat files, NIS, or Hesiod.

= Hesiod has been added to libc (see hesiod(3)).

= A library routine for parsing nsswitch.conf and invoking callback
  functions as specified has been added to libc (see nsdispatch(3)).

= The following C library functions have been modified to use nsdispatch:
    . getgrent, getgrnam, getgrgid
    . getpwent, getpwnam, getpwuid
    . getusershell
    . getaddrinfo
    . gethostbyname, gethostbyname2, gethostbyaddr
    . getnetbyname, getnetbyaddr
    . getipnodebyname, getipnodebyaddr, getnodebyname, getnodebyaddr

= host.conf has been removed from src/etc.  rc.network has been modified
  to warn that host.conf is no longer used at boot time.  In addition, if
  there is a host.conf but no nsswitch.conf, the latter is created at boot
  time from the former.

Obtained from:	NetBSD
This commit is contained in:
Jacques Vidrine 2000-09-06 18:16:48 +00:00
parent 57a12c8e24
commit 248aee623c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=65532
71 changed files with 5477 additions and 2926 deletions

View File

@ -6,7 +6,7 @@ SUBDIR= sendmail
BIN1= amd.map apmd.conf auth.conf \
crontab csh.cshrc csh.login csh.logout \
dhclient.conf dm.conf fbtab ftpusers gettytab group \
hosts hosts.allow host.conf hosts.equiv hosts.lpd \
hosts hosts.allow hosts.equiv hosts.lpd \
inetd.conf login.access login.conf \
motd modems networks newsyslog.conf \
pam.conf phones pim6dd.conf pim6sd.conf \

View File

@ -1,7 +0,0 @@
# $FreeBSD$
# First try the /etc/hosts file
hosts
# Now try the nameserver next.
bind
# If you have YP/NIS configured, uncomment the next line
# nis

View File

@ -4,7 +4,7 @@
# This file should contain the addresses and aliases
# for local hosts that share this file.
# In the presence of the domain name service or NIS, this file may
# not be consulted at all; see /etc/host.conf for the resolution order.
# not be consulted at all; see /etc/nsswitch.conf for the resolution order.
#
#
::1 localhost localhost.my.domain myname.my.domain

View File

@ -13,6 +13,18 @@
network_pass1() {
echo -n 'Doing initial network setup:'
# Convert host.conf to nsswitch.conf if necessary
if [ -f "/etc/host.conf" ]; then
echo ""
echo "Warning: /etc/host.conf is no longer used"
if [ -f "/etc/nsswitch.conf" ]; then
echo " /etc/nsswitch.conf will be used instead"
else
echo " /etc/nsswitch.conf will be created for you"
convert_host_conf /etc/host.conf /etc/nsswitch.conf
fi
fi
# Set the host name if it is not already set
#
if [ -z "`hostname -s`" ]; then
@ -681,3 +693,20 @@ network_pass4() {
echo '.'
network_pass4_done=YES
}
convert_host_conf() {
host_conf=$1; shift;
nsswitch_conf=$1; shift;
awk ' \
/^[:blank:]*#/ { next } \
/(hosts|local|file)/ { nsswitch[c] = "files"; c++; next } \
/(dns|bind)/ { nsswitch[c] = "dns"; c++; next } \
/nis/ { nsswitch[c] = "nis"; c++; next } \
{ printf "Warning: unrecognized line [%s]", $0 > "/dev/stderr" } \
END { \
printf "hosts: "; \
for (i in nsswitch) printf "%s ", nsswitch[i]; \
printf "\n"; \
}' < $host_conf > $nsswitch_conf
}

View File

@ -13,6 +13,18 @@
network_pass1() {
echo -n 'Doing initial network setup:'
# Convert host.conf to nsswitch.conf if necessary
if [ -f "/etc/host.conf" ]; then
echo ""
echo "Warning: /etc/host.conf is no longer used"
if [ -f "/etc/nsswitch.conf" ]; then
echo " /etc/nsswitch.conf will be used instead"
else
echo " /etc/nsswitch.conf will be created for you"
convert_host_conf /etc/host.conf /etc/nsswitch.conf
fi
fi
# Set the host name if it is not already set
#
if [ -z "`hostname -s`" ]; then
@ -681,3 +693,20 @@ network_pass4() {
echo '.'
network_pass4_done=YES
}
convert_host_conf() {
host_conf=$1; shift;
nsswitch_conf=$1; shift;
awk ' \
/^[:blank:]*#/ { next } \
/(hosts|local|file)/ { nsswitch[c] = "files"; c++; next } \
/(dns|bind)/ { nsswitch[c] = "dns"; c++; next } \
/nis/ { nsswitch[c] = "nis"; c++; next } \
{ printf "Warning: unrecognized line [%s]", $0 > "/dev/stderr" } \
END { \
printf "hosts: "; \
for (i in nsswitch) printf "%s ", nsswitch[i]; \
printf "\n"; \
}' < $host_conf > $nsswitch_conf
}

View File

@ -13,6 +13,18 @@
network_pass1() {
echo -n 'Doing initial network setup:'
# Convert host.conf to nsswitch.conf if necessary
if [ -f "/etc/host.conf" ]; then
echo ""
echo "Warning: /etc/host.conf is no longer used"
if [ -f "/etc/nsswitch.conf" ]; then
echo " /etc/nsswitch.conf will be used instead"
else
echo " /etc/nsswitch.conf will be created for you"
convert_host_conf /etc/host.conf /etc/nsswitch.conf
fi
fi
# Set the host name if it is not already set
#
if [ -z "`hostname -s`" ]; then
@ -681,3 +693,20 @@ network_pass4() {
echo '.'
network_pass4_done=YES
}
convert_host_conf() {
host_conf=$1; shift;
nsswitch_conf=$1; shift;
awk ' \
/^[:blank:]*#/ { next } \
/(hosts|local|file)/ { nsswitch[c] = "files"; c++; next } \
/(dns|bind)/ { nsswitch[c] = "dns"; c++; next } \
/nis/ { nsswitch[c] = "nis"; c++; next } \
{ printf "Warning: unrecognized line [%s]", $0 > "/dev/stderr" } \
END { \
printf "hosts: "; \
for (i in nsswitch) printf "%s ", nsswitch[i]; \
printf "\n"; \
}' < $host_conf > $nsswitch_conf
}

View File

@ -13,6 +13,18 @@
network_pass1() {
echo -n 'Doing initial network setup:'
# Convert host.conf to nsswitch.conf if necessary
if [ -f "/etc/host.conf" ]; then
echo ""
echo "Warning: /etc/host.conf is no longer used"
if [ -f "/etc/nsswitch.conf" ]; then
echo " /etc/nsswitch.conf will be used instead"
else
echo " /etc/nsswitch.conf will be created for you"
convert_host_conf /etc/host.conf /etc/nsswitch.conf
fi
fi
# Set the host name if it is not already set
#
if [ -z "`hostname -s`" ]; then
@ -681,3 +693,20 @@ network_pass4() {
echo '.'
network_pass4_done=YES
}
convert_host_conf() {
host_conf=$1; shift;
nsswitch_conf=$1; shift;
awk ' \
/^[:blank:]*#/ { next } \
/(hosts|local|file)/ { nsswitch[c] = "files"; c++; next } \
/(dns|bind)/ { nsswitch[c] = "dns"; c++; next } \
/nis/ { nsswitch[c] = "nis"; c++; next } \
{ printf "Warning: unrecognized line [%s]", $0 > "/dev/stderr" } \
END { \
printf "hosts: "; \
for (i in nsswitch) printf "%s ", nsswitch[i]; \
printf "\n"; \
}' < $host_conf > $nsswitch_conf
}

View File

@ -13,6 +13,18 @@
network_pass1() {
echo -n 'Doing initial network setup:'
# Convert host.conf to nsswitch.conf if necessary
if [ -f "/etc/host.conf" ]; then
echo ""
echo "Warning: /etc/host.conf is no longer used"
if [ -f "/etc/nsswitch.conf" ]; then
echo " /etc/nsswitch.conf will be used instead"
else
echo " /etc/nsswitch.conf will be created for you"
convert_host_conf /etc/host.conf /etc/nsswitch.conf
fi
fi
# Set the host name if it is not already set
#
if [ -z "`hostname -s`" ]; then
@ -681,3 +693,20 @@ network_pass4() {
echo '.'
network_pass4_done=YES
}
convert_host_conf() {
host_conf=$1; shift;
nsswitch_conf=$1; shift;
awk ' \
/^[:blank:]*#/ { next } \
/(hosts|local|file)/ { nsswitch[c] = "files"; c++; next } \
/(dns|bind)/ { nsswitch[c] = "dns"; c++; next } \
/nis/ { nsswitch[c] = "nis"; c++; next } \
{ printf "Warning: unrecognized line [%s]", $0 > "/dev/stderr" } \
END { \
printf "hosts: "; \
for (i in nsswitch) printf "%s ", nsswitch[i]; \
printf "\n"; \
}' < $host_conf > $nsswitch_conf
}

View File

@ -13,6 +13,18 @@
network_pass1() {
echo -n 'Doing initial network setup:'
# Convert host.conf to nsswitch.conf if necessary
if [ -f "/etc/host.conf" ]; then
echo ""
echo "Warning: /etc/host.conf is no longer used"
if [ -f "/etc/nsswitch.conf" ]; then
echo " /etc/nsswitch.conf will be used instead"
else
echo " /etc/nsswitch.conf will be created for you"
convert_host_conf /etc/host.conf /etc/nsswitch.conf
fi
fi
# Set the host name if it is not already set
#
if [ -z "`hostname -s`" ]; then
@ -681,3 +693,20 @@ network_pass4() {
echo '.'
network_pass4_done=YES
}
convert_host_conf() {
host_conf=$1; shift;
nsswitch_conf=$1; shift;
awk ' \
/^[:blank:]*#/ { next } \
/(hosts|local|file)/ { nsswitch[c] = "files"; c++; next } \
/(dns|bind)/ { nsswitch[c] = "dns"; c++; next } \
/nis/ { nsswitch[c] = "nis"; c++; next } \
{ printf "Warning: unrecognized line [%s]", $0 > "/dev/stderr" } \
END { \
printf "hosts: "; \
for (i in nsswitch) printf "%s ", nsswitch[i]; \
printf "\n"; \
}' < $host_conf > $nsswitch_conf
}

View File

@ -13,6 +13,18 @@
network_pass1() {
echo -n 'Doing initial network setup:'
# Convert host.conf to nsswitch.conf if necessary
if [ -f "/etc/host.conf" ]; then
echo ""
echo "Warning: /etc/host.conf is no longer used"
if [ -f "/etc/nsswitch.conf" ]; then
echo " /etc/nsswitch.conf will be used instead"
else
echo " /etc/nsswitch.conf will be created for you"
convert_host_conf /etc/host.conf /etc/nsswitch.conf
fi
fi
# Set the host name if it is not already set
#
if [ -z "`hostname -s`" ]; then
@ -681,3 +693,20 @@ network_pass4() {
echo '.'
network_pass4_done=YES
}
convert_host_conf() {
host_conf=$1; shift;
nsswitch_conf=$1; shift;
awk ' \
/^[:blank:]*#/ { next } \
/(hosts|local|file)/ { nsswitch[c] = "files"; c++; next } \
/(dns|bind)/ { nsswitch[c] = "dns"; c++; next } \
/nis/ { nsswitch[c] = "nis"; c++; next } \
{ printf "Warning: unrecognized line [%s]", $0 > "/dev/stderr" } \
END { \
printf "hosts: "; \
for (i in nsswitch) printf "%s ", nsswitch[i]; \
printf "\n"; \
}' < $host_conf > $nsswitch_conf
}

View File

@ -10,7 +10,8 @@ CLEANFILES= osreldate.h version vers.c
SUBDIR= rpcsvc
FILES= a.out.h ar.h assert.h bitstring.h ctype.h db.h dirent.h disktab.h \
dlfcn.h elf.h err.h fnmatch.h fstab.h \
fts.h glob.h grp.h strhash.h histedit.h ieeefp.h ifaddrs.h iso646.h \
fts.h glob.h grp.h strhash.h \
hesiod.h histedit.h ieeefp.h ifaddrs.h iso646.h \
libgen.h limits.h link.h locale.h malloc.h memory.h mpool.h \
ndbm.h netdb.h nl_types.h nlist.h objformat.h \
paths.h pthread.h pthread_np.h pwd.h \

98
include/hesiod.h Normal file
View File

@ -0,0 +1,98 @@
/* $NetBSD: hesiod.h,v 1.3 1999/01/24 23:53:18 lukem Exp $ */
/* $FreeBSD$ */
/*-
* Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 1996 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#ifndef _HESIOD_H_
#define _HESIOD_H_
/* Application-visible indication that we have the new interfaces */
#define HESIOD_INTERFACES
/* Configuration information. */
#ifndef _PATH_HESIOD_CONF /* Configuration file. */
#define _PATH_HESIOD_CONF "/etc/hesiod.conf"
#endif
#define DEF_RHS "" /* Defaults if HESIOD_CONF */
#define DEF_LHS "" /* file is not present. */
/* Error codes (for backwards compatibility) */
#define HES_ER_UNINIT -1 /* uninitialized */
#define HES_ER_OK 0 /* no error */
#define HES_ER_NOTFOUND 1 /* Hesiod name not found by server */
#define HES_ER_CONFIG 2 /* local problem (no config file?) */
#define HES_ER_NET 3 /* network problem */
/* Declaration of routines */
#include <sys/cdefs.h>
__BEGIN_DECLS
int hesiod_init __P((void **));
char **hesiod_resolve __P((void *, const char *, const char *));
void hesiod_free_list __P((void *, char **));
char *hesiod_to_bind __P((void *, const char *, const char *));
void hesiod_end __P((void *));
/* backwards compatibility */
int hes_init __P((void));
char *hes_to_bind __P((const char *, const char *));
char **hes_resolve __P((const char *, const char *));
int hes_error __P((void));
void hes_free __P((char **));
__END_DECLS
#endif /* ! _HESIOD_H_ */

View File

@ -240,18 +240,8 @@ void _setnethtent __P((int));
void _endnethtent __P((void));
void _setnetdnsent __P((int));
void _endnetdnsent __P((void));
struct hostent * _gethostbyhtname __P((const char *, int));
struct hostent * _gethostbydnsname __P((const char *, int));
struct hostent * _gethostbynisname __P((const char *, int));
struct hostent * _gethostbyhtaddr __P((const char *, int, int));
struct hostent * _gethostbydnsaddr __P((const char *, int, int));
struct hostent * _gethostbynisaddr __P((const char *, int, int));
struct netent * _getnetbyhtname __P((const char *));
struct netent * _getnetbydnsname __P((const char *));
struct netent * _getnetbynisname __P((const char *));
struct netent * _getnetbyhtaddr __P((unsigned long, int));
struct netent * _getnetbydnsaddr __P((unsigned long, int));
struct netent * _getnetbynisaddr __P((unsigned long, int));
void _map_v4v6_address __P((const char *src, char *dst));
void _map_v4v6_hostent __P((struct hostent *hp, char **bp, int *len));
__END_DECLS

188
include/nsswitch.h Normal file
View File

@ -0,0 +1,188 @@
/* $NetBSD: nsswitch.h,v 1.6 1999/01/26 01:04:07 lukem Exp $ */
/* $FreeBSD$ */
/*-
* Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Luke Mewburn.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _NSSWITCH_H
#define _NSSWITCH_H 1
#include <sys/types.h>
#if __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#ifndef _PATH_NS_CONF
#define _PATH_NS_CONF "/etc/nsswitch.conf"
#endif
#define NS_CONTINUE 0
#define NS_RETURN 1
#define NS_SUCCESS (1<<0) /* entry was found */
#define NS_UNAVAIL (1<<1) /* source not responding, or corrupt */
#define NS_NOTFOUND (1<<2) /* source responded 'no such entry' */
#define NS_TRYAGAIN (1<<3) /* source busy, may respond to retrys */
#define NS_STATUSMASK 0x000000ff /* bitmask to get the status flags */
/*
* currently implemented sources
*/
#define NSSRC_FILES "files" /* local files */
#define NSSRC_DNS "dns" /* DNS; IN for hosts, HS for others */
#define NSSRC_NIS "nis" /* YP/NIS */
#define NSSRC_COMPAT "compat" /* passwd,group in YP compat mode */
/*
* currently implemented databases
*/
#define NSDB_HOSTS "hosts"
#define NSDB_GROUP "group"
#define NSDB_GROUP_COMPAT "group_compat"
#define NSDB_NETGROUP "netgroup"
#define NSDB_NETWORKS "networks"
#define NSDB_PASSWD "passwd"
#define NSDB_PASSWD_COMPAT "passwd_compat"
#define NSDB_SHELLS "shells"
/*
* suggested databases to implement
*/
#define NSDB_ALIASES "aliases"
#define NSDB_AUTH "auth"
#define NSDB_AUTOMOUNT "automount"
#define NSDB_BOOTPARAMS "bootparams"
#define NSDB_ETHERS "ethers"
#define NSDB_EXPORTS "exports"
#define NSDB_NETMASKS "netmasks"
#define NSDB_PHONES "phones"
#define NSDB_PRINTCAP "printcap"
#define NSDB_PROTOCOLS "protocols"
#define NSDB_REMOTE "remote"
#define NSDB_RPC "rpc"
#define NSDB_SENDMAILVARS "sendmailvars"
#define NSDB_SERVICES "services"
#define NSDB_TERMCAP "termcap"
#define NSDB_TTYS "ttys"
/*
* ns_dtab - `nsswitch dispatch table'
* contains an entry for each source and the appropriate function to call
*/
typedef struct {
const char *src;
int (*callback)(void *retval, void *cb_data, va_list ap);
void *cb_data;
} ns_dtab;
/*
* macros to help build an ns_dtab[]
*/
#define NS_FILES_CB(F,C) { NSSRC_FILES, F, C },
#define NS_COMPAT_CB(F,C) { NSSRC_COMPAT, F, C },
#ifdef HESIOD
# define NS_DNS_CB(F,C) { NSSRC_DNS, F, C },
#else
# define NS_DNS_CB(F,C)
#endif
#ifdef YP
# define NS_NIS_CB(F,C) { NSSRC_NIS, F, C },
#else
# define NS_NIS_CB(F,C)
#endif
/*
* ns_src - `nsswitch source'
* used by the nsparser routines to store a mapping between a source
* and its dispatch control flags for a given database.
*/
typedef struct {
const char *name;
u_int32_t flags;
} ns_src;
/*
* default sourcelist (if nsswitch.conf is missing, corrupt,
* or the requested database doesn't have an entry.
*/
extern const ns_src __nsdefaultsrc[];
#ifdef _NS_PRIVATE
/*
* private data structures for back-end nsswitch implementation
*/
/*
* ns_dbt - `nsswitch database thang'
* for each database in /etc/nsswitch.conf there is a ns_dbt, with its
* name and a list of ns_src's containing the source information.
*/
typedef struct {
const char *name; /* name of database */
ns_src *srclist; /* list of sources */
int srclistsize; /* size of srclist */
} ns_dbt;
#endif /* _NS_PRIVATE */
#include <sys/cdefs.h>
__BEGIN_DECLS
extern int nsdispatch __P((void *, const ns_dtab [], const char *,
const char *, const ns_src [], ...));
#ifdef _NS_PRIVATE
extern void _nsdbtaddsrc __P((ns_dbt *, const ns_src *));
extern void _nsdbtdump __P((const ns_dbt *));
extern const ns_dbt *_nsdbtget __P((const char *));
extern void _nsdbtput __P((const ns_dbt *));
extern void _nsyyerror __P((const char *));
extern int _nsyylex __P((void));
extern int _nsyylineno;
#endif /* _NS_PRIVATE */
__END_DECLS
#endif /* !_NSSWITCH_H */

View File

@ -39,6 +39,9 @@ NOASM=
CFLAGS+= -DYP
.include "${.CURDIR}/../libc/yp/Makefile.inc"
.endif
.if !defined(NO_HESIOD_LIBC)
CFLAGS+= -DHESIOD
.endif
# If there are no machine dependent sources, append all the
# machine-independent sources:

View File

@ -19,7 +19,7 @@ SRCS+= _rand48.c _spinlock_stub.c alarm.c arc4random.c assert.c \
lockf.c lrand48.c mrand48.c msgctl.c \
msgget.c msgrcv.c msgsnd.c nice.c \
nlist.c nrand48.c ntp_gettime.c opendir.c \
pause.c popen.c psignal.c pwcache.c raise.c readdir.c rewinddir.c \
pause.c popen.c psignal.c pw_scan.c pwcache.c raise.c readdir.c rewinddir.c \
posixshm.c \
scandir.c seed48.c seekdir.c semconfig.c semctl.c semget.c semop.c \
setdomainname.c sethostname.c setjmperr.c setmode.c setproctitle.c \

View File

@ -125,25 +125,6 @@ The
.Fn endgrent
function
closes any open files.
.Sh YP/NIS INTERACTION
When the
.Xr yp 4
group database is enabled, the
.Fn getgrnam
and
.Fn getgrgid
functions use the YP maps
.Dq Li group.byname
and
.Dq Li group.bygid ,
respectively, if the requested group is not found in the local
.Pa /etc/group
file. The
.Fn getgrent
function will step through the YP map
.Dq Li group.byname
if the entire map is enabled as described in
.Xr group 5 .
.Sh RETURN VALUES
The functions
.Fn getgrent ,
@ -171,7 +152,8 @@ group database file
.Sh SEE ALSO
.Xr getpwent 3 ,
.Xr yp 4 ,
.Xr group 5
.Xr group 5 ,
.Xr nsswitch.conf 5
.Sh HISTORY
The functions
.Fn endgrent ,
@ -206,3 +188,17 @@ a pointer to that object.
Subsequent calls to
the same function
will modify the same object.
.Pp
The functions
.Fn getgrent ,
.Fn endgrent ,
.Fn setgroupent ,
and
.Fn setgrent
are fairly useless in a networked environment and should be
avoided, if possible.
.Fn getgrent
makes no attempt to suppress duplicate information if multiple
sources are specified in
.Xr nsswitch.conf 5 .

File diff suppressed because it is too large Load Diff

View File

@ -137,24 +137,6 @@ If the process which calls them has an effective uid of 0, the encrypted
password will be returned, otherwise, the password field of the returned
structure will point to the string
.Ql * .
.Sh YP/NIS INTERACTION
When the
.Xr yp 4
password database is enabled, the
.Fn getpwnam
and
.Fn getpwuid
functions use the YP maps
.Dq Li passwd.byname
and
.Dq Li passwd.byuid ,
respectively, if the requested password entry is not found in the
local database. The
.Fn getpwent
function will step through the YP map
.Dq Li passwd.byname
if the entire map is enabled as described in
.Xr passwd 5 .
.Sh RETURN VALUES
The functions
.Fn getpwent ,
@ -187,6 +169,7 @@ A Version 7 format password file
.Xr getlogin 2 ,
.Xr getgrent 3 ,
.Xr yp 4 ,
.Xr nsswitch.conf 5 ,
.Xr passwd 5 ,
.Xr pwd_mkdb 8 ,
.Xr vipw 8
@ -220,3 +203,16 @@ a pointer to that object.
Subsequent calls to
the same function
will modify the same object.
.Pp
The functions
.Fn getpwent ,
.Fn endpwent ,
.Fn setpassent ,
and
.Fn setpwent
are fairly useless in a networked environment and should be
avoided, if possible.
.Fn getpwent
makes no attempt to suppress duplicate information if multiple
sources are specified in
.Xr nsswitch.conf 5

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,6 @@
.\" $NetBSD: getusershell.3,v 1.6 1999/03/22 19:44:42 garbled Exp $
.\" $FreeBSD$
.\"
.\" Copyright (c) 1985, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
@ -30,16 +33,15 @@
.\" SUCH DAMAGE.
.\"
.\" @(#)getusershell.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
.Dd June 4, 1993
.Dd January 16, 1999
.Dt GETUSERSHELL 3
.Os BSD 4.3
.Os
.Sh NAME
.Nm getusershell ,
.Nm setusershell ,
.Nm endusershell
.Nd get legal user shells
.Nd get valid user shells
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
@ -54,18 +56,16 @@
The
.Fn getusershell
function
returns a pointer to a legal user shell as defined by the
system manager in the file
.Pa /etc/shells .
If
.Pa /etc/shells
is unreadable or does not exist,
returns a pointer to a valid user shell as defined by the
system manager in the shells database as described in
.Xr shells 5 .
If the shells database is not available,
.Fn getusershell
behaves as if
.Pa /bin/sh
and
.Pa /bin/csh
were listed in the file.
were listed.
.Pp
The
.Fn getusershell
@ -86,6 +86,7 @@ The routine
returns a null pointer (0) on
.Dv EOF .
.Sh SEE ALSO
.Xr nsswitch.conf 5 ,
.Xr shells 5
.Sh HISTORY
The
@ -96,7 +97,6 @@ function appeared in
The
.Fn getusershell
function leaves its result in an internal static object and returns
a pointer to that object.
Subsequent calls to
a pointer to that object. Subsequent calls to
.Fn getusershell
will modify the same object.

View File

@ -1,3 +1,5 @@
/* $NetBSD: getusershell.c,v 1.17 1999/01/25 01:09:34 lukem Exp $ */
/*
* Copyright (c) 1985, 1993
* The Regents of the University of California. All rights reserved.
@ -29,111 +31,248 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)getusershell.c 8.1 (Berkeley) 6/4/93";
static char rcsid[] =
"$FreeBSD$";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <nsswitch.h>
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stringlist.h>
#include <unistd.h>
#ifdef HESIOD
#include <hesiod.h>
#endif
#ifdef YP
#include <rpc/rpc.h>
#include <rpcsvc/ypclnt.h>
#include <rpcsvc/yp_prot.h>
#endif
/*
* Local shells should NOT be added here. They should be added in
* /etc/shells.
*/
static char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL };
static char **curshell, **shells, *strings;
static char **initshells __P((void));
static const char *const okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL };
static const char *const *curshell;
static StringList *sl;
static const char *const *initshells __P((void));
/*
* Get a list of shells from _PATH_SHELLS, if it exists.
* Get a list of shells from "shells" nsswitch database
*/
char *
getusershell()
getusershell(void)
{
char *ret;
if (curshell == NULL)
curshell = initshells();
ret = *curshell;
/*LINTED*/
ret = (char *)*curshell;
if (ret != NULL)
curshell++;
return (ret);
}
void
endusershell()
endusershell(void)
{
if (shells != NULL)
free(shells);
shells = NULL;
if (strings != NULL)
free(strings);
strings = NULL;
if (sl)
sl_free(sl, 1);
sl = NULL;
curshell = NULL;
}
void
setusershell()
setusershell(void)
{
curshell = initshells();
}
static char **
initshells()
{
register char **sp, *cp;
register FILE *fp;
struct stat statb;
if (shells != NULL)
free(shells);
shells = NULL;
if (strings != NULL)
free(strings);
strings = NULL;
static int _local_initshells __P((void *, void *, va_list));
/*ARGSUSED*/
static int
_local_initshells(rv, cb_data, ap)
void *rv;
void *cb_data;
va_list ap;
{
char *sp, *cp;
FILE *fp;
char line[MAXPATHLEN + 2];
if (sl)
sl_free(sl, 1);
sl = sl_init();
if ((fp = fopen(_PATH_SHELLS, "r")) == NULL)
return (okshells);
if (fstat(fileno(fp), &statb) == -1) {
(void)fclose(fp);
return (okshells);
}
if ((strings = malloc((u_int)statb.st_size)) == NULL) {
(void)fclose(fp);
return (okshells);
}
shells = calloc((unsigned)statb.st_size / 3, sizeof (char *));
if (shells == NULL) {
(void)fclose(fp);
free(strings);
strings = NULL;
return (okshells);
}
sp = shells;
cp = strings;
return NS_UNAVAIL;
sp = cp = line;
while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
while (*cp != '#' && *cp != '/' && *cp != '\0')
cp++;
if (*cp == '#' || *cp == '\0')
continue;
*sp++ = cp;
while (!isspace((unsigned char)*cp) && *cp != '#' && *cp != '\0')
sp = cp;
while (!isspace(*cp) && *cp != '#' && *cp != '\0')
cp++;
*cp++ = '\0';
sl_add(sl, strdup(sp));
}
*sp = NULL;
(void)fclose(fp);
return (shells);
return NS_SUCCESS;
}
#ifdef HESIOD
static int _dns_initshells __P((void *, void *, va_list));
/*ARGSUSED*/
static int
_dns_initshells(rv, cb_data, ap)
void *rv;
void *cb_data;
va_list ap;
{
char shellname[] = "shells-XXXXX";
int hsindex, hpi, r;
char **hp;
void *context;
if (sl)
sl_free(sl, 1);
sl = sl_init();
r = NS_UNAVAIL;
if (hesiod_init(&context) == -1)
return (r);
for (hsindex = 0; ; hsindex++) {
snprintf(shellname, sizeof(shellname)-1, "shells-%d", hsindex);
hp = hesiod_resolve(context, shellname, "shells");
if (hp == NULL) {
if (errno == ENOENT) {
if (hsindex == 0)
r = NS_NOTFOUND;
else
r = NS_SUCCESS;
}
break;
} else {
for (hpi = 0; hp[hpi]; hpi++)
sl_add(sl, hp[hpi]);
free(hp);
}
}
hesiod_end(context);
return (r);
}
#endif /* HESIOD */
#ifdef YP
static int _nis_initshells __P((void *, void *, va_list));
/*ARGSUSED*/
static int
_nis_initshells(rv, cb_data, ap)
void *rv;
void *cb_data;
va_list ap;
{
static char *ypdomain;
if (sl)
sl_free(sl, 1);
sl = sl_init();
if (ypdomain == NULL) {
switch (yp_get_default_domain(&ypdomain)) {
case 0:
break;
case YPERR_RESRC:
return NS_TRYAGAIN;
default:
return NS_UNAVAIL;
}
}
for (;;) {
char *ypcur = NULL;
int ypcurlen = 0; /* XXX: GCC */
char *key, *data;
int keylen, datalen;
int r;
key = data = NULL;
if (ypcur) {
r = yp_next(ypdomain, "shells", ypcur, ypcurlen,
&key, &keylen, &data, &datalen);
free(ypcur);
switch (r) {
case 0:
break;
case YPERR_NOMORE:
free(key);
free(data);
return NS_SUCCESS;
default:
free(key);
free(data);
return NS_UNAVAIL;
}
ypcur = key;
ypcurlen = keylen;
} else {
if (yp_first(ypdomain, "shells", &ypcur,
&ypcurlen, &data, &datalen)) {
free(data);
return NS_UNAVAIL;
}
}
data[datalen] = '\0'; /* clear trailing \n */
sl_add(sl, data);
}
}
#endif /* YP */
static const char *const *
initshells()
{
static const ns_dtab dtab[] = {
NS_FILES_CB(_local_initshells, NULL)
NS_DNS_CB(_dns_initshells, NULL)
NS_NIS_CB(_nis_initshells, NULL)
{ 0 }
};
if (sl)
sl_free(sl, 1);
sl = sl_init();
if (nsdispatch(NULL, dtab, NSDB_SHELLS, "initshells", __nsdefaultsrc)
!= NS_SUCCESS) {
if (sl)
sl_free(sl, 1);
sl = NULL;
return (okshells);
}
sl_add(sl, NULL);
return (const char *const *)(sl->sl_str);
}

View File

@ -66,12 +66,10 @@ static const char rcsid[] =
* it will be set based on the existance of PW_SCAN_BIG_IDS in the
* environment.
*/
int pw_big_ids_warning = -1;
static int pw_big_ids_warning = -1;
int
pw_scan(bp, pw)
char *bp;
struct passwd *pw;
__pw_scan(char *bp, struct passwd *pw, int flags)
{
uid_t id;
int root;
@ -97,20 +95,23 @@ pw_scan(bp, pw)
pw->pw_fields |= _PWF_UID;
else {
if (pw->pw_name[0] != '+' && pw->pw_name[0] != '-') {
warnx("no uid for user %s", pw->pw_name);
if (flags & _PWSCAN_WARN)
warnx("no uid for user %s", pw->pw_name);
return (0);
}
}
id = strtoul(p, (char **)NULL, 10);
if (errno == ERANGE) {
warnx("%s > max uid value (%u)", p, ULONG_MAX);
if (flags & _PWSCAN_WARN)
warnx("%s > max uid value (%u)", p, ULONG_MAX);
return (0);
}
if (root && id) {
warnx("root uid should be 0");
if (flags & _PWSCAN_WARN)
warnx("root uid should be 0");
return (0);
}
if (pw_big_ids_warning && id > USHRT_MAX) {
if (flags & _PWSCAN_WARN && pw_big_ids_warning && id > USHRT_MAX) {
warnx("%s > recommended max uid value (%u)", p, USHRT_MAX);
/*return (0);*/ /* THIS SHOULD NOT BE FATAL! */
}
@ -121,28 +122,30 @@ pw_scan(bp, pw)
if(p[0]) pw->pw_fields |= _PWF_GID;
id = strtoul(p, (char **)NULL, 10);
if (errno == ERANGE) {
warnx("%s > max gid value (%u)", p, ULONG_MAX);
if (flags & _PWSCAN_WARN)
warnx("%s > max gid value (%u)", p, ULONG_MAX);
return (0);
}
if (pw_big_ids_warning && id > USHRT_MAX) {
if (flags & _PWSCAN_WARN && pw_big_ids_warning && id > USHRT_MAX) {
warnx("%s > recommended max gid value (%u)", p, USHRT_MAX);
/* return (0); This should not be fatal! */
}
pw->pw_gid = id;
pw->pw_class = strsep(&bp, ":"); /* class */
if(pw->pw_class[0]) pw->pw_fields |= _PWF_CLASS;
if (!(p = strsep(&bp, ":"))) /* change */
goto fmt;
if(p[0]) pw->pw_fields |= _PWF_CHANGE;
pw->pw_change = atol(p);
if (!(p = strsep(&bp, ":"))) /* expire */
goto fmt;
if(p[0]) pw->pw_fields |= _PWF_EXPIRE;
pw->pw_expire = atol(p);
if (flags & _PWSCAN_MASTER ) {
pw->pw_class = strsep(&bp, ":"); /* class */
if(pw->pw_class[0]) pw->pw_fields |= _PWF_CLASS;
if (!(p = strsep(&bp, ":"))) /* change */
goto fmt;
if(p[0]) pw->pw_fields |= _PWF_CHANGE;
pw->pw_change = atol(p);
if (!(p = strsep(&bp, ":"))) /* expire */
goto fmt;
if(p[0]) pw->pw_fields |= _PWF_EXPIRE;
pw->pw_expire = atol(p);
}
if (!(pw->pw_gecos = strsep(&bp, ":"))) /* gecos */
goto fmt;
if(pw->pw_gecos[0]) pw->pw_fields |= _PWF_GECOS;
@ -158,7 +161,8 @@ pw_scan(bp, pw)
if (root && *p) /* empty == /bin/sh */
for (setusershell();;) {
if (!(sh = getusershell())) {
warnx("warning, unknown root shell");
if (flags & _PWSCAN_WARN)
warnx("warning, unknown root shell");
break;
}
if (!strcmp(p, sh))
@ -167,7 +171,9 @@ pw_scan(bp, pw)
if(p[0]) pw->pw_fields |= _PWF_SHELL;
if ((p = strsep(&bp, ":"))) { /* too many */
fmt: warnx("corrupted entry");
fmt:
if (flags & _PWSCAN_WARN)
warnx("corrupted entry");
return (0);
}
return (1);

View File

@ -35,6 +35,7 @@
* $FreeBSD$
*/
extern int pw_big_ids_warning;
#define _PWSCAN_MASTER 0x01
#define _PWSCAN_WARN 0x02
extern int pw_scan __P((char *, struct passwd *));
extern int __pw_scan __P((char *, struct passwd *, int));

View File

@ -9,19 +9,32 @@ SRCS+= addr2ascii.c ascii2addr.c base64.c ether_addr.c getaddrinfo.c \
getifaddrs.c getnameinfo.c \
getnetbydns.c getnetbyht.c getnetbynis.c getnetnamadr.c \
getproto.c getprotoent.c getprotoname.c getservbyname.c \
getservbyport.c getservent.c herror.c inet_addr.c ifname.c \
inet_lnaof.c \
getservbyport.c getservent.c herror.c hesiod.c inet_addr.c \
ifname.c inet_lnaof.c \
inet_makeaddr.c inet_net_ntop.c inet_net_pton.c inet_neta.c \
inet_netof.c inet_network.c inet_ntoa.c inet_ntop.c \
inet_pton.c ip6opt.c linkaddr.c map_v4v6.c name6.c ns_addr.c \
ns_name.c ns_netint.c \
ns_ntoa.c ns_parse.c ns_print.c ns_ttl.c nsap_addr.c \
rcmd.c recv.c res_comp.c res_data.c res_debug.c \
ns_ntoa.c ns_parse.c ns_print.c ns_ttl.c \
nsdispatch.c nslexer.c nsparser.c \
nsap_addr.c rcmd.c recv.c res_comp.c res_data.c res_debug.c \
res_init.c res_mkquery.c res_mkupdate.c res_query.c res_send.c \
res_update.c rthdr.c send.c vars.c
# not supported: iso_addr.c
CFLAGS+=-DINET6
CFLAGS+=-DINET6 -I${.OBJDIR}
YFLAGS+=-p_nsyy
LFLAGS+=-P_nsyy
CLEANFILES+=nsparser.c nslexer.c nsparser.h
nsparser.h: nsparser.c
mv y.tab.h ${.TARGET}
nslexer.c: nslexer.l nsparser.h
${LEX} ${LFLAGS} -o/dev/stdout ${.IMPSRC} | \
sed -e '/YY_BUF_SIZE/s/16384/1024/' >${.TARGET}
# machine-dependent net sources
.include "${.CURDIR}/../libc/${MACHINE_ARCH}/net/Makefile.inc"
@ -29,9 +42,10 @@ CFLAGS+=-DINET6
.if ${LIB} == "c"
MAN3+= addr2ascii.3 byteorder.3 ethers.3 getaddrinfo.3 gethostbyname.3 \
getifaddrs.3 getipnodebyname.3 \
getnameinfo.3 getnetent.3 getprotoent.3 getservent.3 if_indextoname.3 \
getnameinfo.3 getnetent.3 getprotoent.3 getservent.3 hesiod.3 \
if_indextoname.3 \
inet.3 inet6_option_space.3 inet6_rthdr_space.3 linkaddr.3 \
rcmd.3 resolver.3
nsdispatch.3 rcmd.3 resolver.3
# not installed: iso_addr.3 ns.3
MLINKS+=addr2ascii.3 ascii2addr.3

View File

@ -496,9 +496,9 @@ freeaddrinfo(res0);
.Ed
.\"
.Sh FILES
.Bl -tag -width /etc/resolv.conf -compact
.Bl -tag -width /etc/nsswitch.conf -compact
.It Pa /etc/hosts
.It Pa /etc/host.conf
.It Pa /etc/nsswitch.conf
.It Pa /etc/resolv.conf
.El
.\"

View File

@ -1,4 +1,4 @@
/* $FreeBSD$ */
/* $FreeBSD$ */
/* $KAME: getaddrinfo.c,v 1.15 2000/07/09 04:37:24 itojun Exp $ */
/*
@ -103,14 +103,18 @@
#include <stdio.h>
#include <errno.h>
#include <syslog.h>
#include <stdarg.h>
#include <nsswitch.h>
#if defined(__KAME__) && defined(INET6)
# define FAITH
#endif
#define SUCCESS 0
#define ANY 0
#define YES 1
#define NO 0
#define SUCCESS 0
#define ANY 0
#define YES 1
#define NO 0
static const char in_addrany[] = { 0, 0, 0, 0 };
static const char in6_addrany[] = {
@ -127,7 +131,7 @@ static const struct afd {
int a_socklen;
int a_off;
const char *a_addrany;
const char *a_loopback;
const char *a_loopback;
int a_scoped;
} afdl [] = {
#ifdef INET6
@ -153,9 +157,9 @@ struct explore {
int e_protocol;
const char *e_protostr;
int e_wild;
#define WILD_AF(ex) ((ex)->e_wild & 0x01)
#define WILD_SOCKTYPE(ex) ((ex)->e_wild & 0x02)
#define WILD_PROTOCOL(ex) ((ex)->e_wild & 0x04)
#define WILD_AF(ex) ((ex)->e_wild & 0x01)
#define WILD_SOCKTYPE(ex) ((ex)->e_wild & 0x02)
#define WILD_PROTOCOL(ex) ((ex)->e_wild & 0x04)
};
static const struct explore explore[] = {
@ -177,11 +181,17 @@ static const struct explore explore[] = {
};
#ifdef INET6
#define PTON_MAX 16
#define PTON_MAX 16
#else
#define PTON_MAX 4
#define PTON_MAX 4
#endif
static const ns_src default_dns_files[] = {
{ NSSRC_FILES, NS_SUCCESS },
{ NSSRC_DNS, NS_SUCCESS },
{ 0 }
};
#if PACKETSZ > 1024
#define MAXPACKET PACKETSZ
#else
@ -223,24 +233,22 @@ static int addrconfig __P((struct addrinfo *));
static int ip6_str2scopeid __P((char *, struct sockaddr_in6 *));
#endif
static struct addrinfo *getanswer __P((const querybuf *, int, const char *,
int, const struct addrinfo *));
static int _dns_getaddrinfo __P((const struct addrinfo *, const char *,
struct addrinfo **));
static struct addrinfo *_gethtent __P((FILE *fp, const char *,
const struct addrinfo *));
static int _files_getaddrinfo __P((const struct addrinfo *, const char *,
struct addrinfo **));
static struct addrinfo *getanswer __P((const querybuf *, int, const char *, int,
const struct addrinfo *));
static int _dns_getaddrinfo __P((void *, void *, va_list));
static void _sethtent __P((void));
static void _endhtent __P((void));
static struct addrinfo *_gethtent __P((const char *, const struct addrinfo *));
static int _files_getaddrinfo __P((void *, void *, va_list));
#ifdef YP
static int _nis_getaddrinfo __P((const struct addrinfo *, const char *,
struct addrinfo **));
static struct addrinfo *_yphostent __P((char *, const struct addrinfo *));
static int _yp_getaddrinfo __P((void *, void *, va_list));
#endif
static int res_queryN __P((const char *, struct res_target *));
static int res_searchN __P((const char *, struct res_target *));
static int res_querydomainN __P((const char *, const char *,
struct res_target *));
struct res_target *));
static char *ai_errlist[] = {
"Success",
@ -263,35 +271,9 @@ static char *ai_errlist[] = {
"Unknown error", /* EAI_MAX */
};
/*
* Select order host function.
*/
#define MAXHOSTCONF 4
#ifndef HOSTCONF
# define HOSTCONF "/etc/host.conf"
#endif /* !HOSTCONF */
struct _hostconf {
int (*byname)(const struct addrinfo *, const char *,
struct addrinfo **);
};
/* default order */
static struct _hostconf _hostconf[MAXHOSTCONF] = {
_dns_getaddrinfo,
_files_getaddrinfo,
#ifdef ICMPNL
NULL,
#endif /* ICMPNL */
};
static int _hostconf_init_done;
static void _hostconf_init(void);
/* XXX macros that make external reference is BAD. */
#define GET_AI(ai, afd, addr) \
#define GET_AI(ai, afd, addr) \
do { \
/* external reference: pai, error, and label free */ \
(ai) = get_ai(pai, (afd), (addr)); \
@ -301,7 +283,7 @@ do { \
} \
} while (/*CONSTCOND*/0)
#define GET_PORT(ai, serv) \
#define GET_PORT(ai, serv) \
do { \
/* external reference: error and label free */ \
error = get_port((ai), (serv), 0); \
@ -309,7 +291,7 @@ do { \
goto free; \
} while (/*CONSTCOND*/0)
#define GET_CANONNAME(ai, str) \
#define GET_CANONNAME(ai, str) \
do { \
/* external reference: pai, error and label free */ \
error = get_canonname(pai, (ai), (str)); \
@ -317,7 +299,7 @@ do { \
goto free; \
} while (/*CONSTCOND*/0)
#define ERR(err) \
#define ERR(err) \
do { \
/* external reference: error, and label bad */ \
error = (err); \
@ -325,9 +307,9 @@ do { \
/*NOTREACHED*/ \
} while (/*CONSTCOND*/0)
#define MATCH_FAMILY(x, y, w) \
#define MATCH_FAMILY(x, y, w) \
((x) == (y) || (/*CONSTCOND*/(w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC)))
#define MATCH(x, y, w) \
#define MATCH(x, y, w) \
((x) == (y) || (/*CONSTCOND*/(w) && ((x) == ANY || (y) == ANY)))
char *
@ -470,7 +452,7 @@ getaddrinfo(hostname, servname, hints, res)
*/
if (MATCH_FAMILY(pai->ai_family, PF_INET, 1)
#ifdef PF_INET6
|| MATCH_FAMILY(pai->ai_family, PF_INET6, 1)
|| MATCH_FAMILY(pai->ai_family, PF_INET6, 1)
#endif
) {
ai0 = *pai; /* backup *pai */
@ -501,11 +483,9 @@ getaddrinfo(hostname, servname, hints, res)
if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))
continue;
if (!MATCH(pai->ai_socktype, ex->e_socktype,
WILD_SOCKTYPE(ex)))
if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex)))
continue;
if (!MATCH(pai->ai_protocol, ex->e_protocol,
WILD_PROTOCOL(ex)))
if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex)))
continue;
if (pai->ai_family == PF_UNSPEC)
@ -518,8 +498,7 @@ getaddrinfo(hostname, servname, hints, res)
if (hostname == NULL)
error = explore_null(pai, servname, &cur->ai_next);
else
error = explore_numeric_scope(pai, hostname, servname,
&cur->ai_next);
error = explore_numeric_scope(pai, hostname, servname, &cur->ai_next);
if (error)
goto free;
@ -561,11 +540,11 @@ getaddrinfo(hostname, servname, hints, res)
continue;
if (!MATCH(pai->ai_socktype, ex->e_socktype,
WILD_SOCKTYPE(ex))) {
WILD_SOCKTYPE(ex))) {
continue;
}
if (!MATCH(pai->ai_protocol, ex->e_protocol,
WILD_PROTOCOL(ex))) {
WILD_PROTOCOL(ex))) {
continue;
}
@ -574,7 +553,8 @@ getaddrinfo(hostname, servname, hints, res)
if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
pai->ai_protocol = ex->e_protocol;
error = explore_fqdn(pai, hostname, servname, &cur->ai_next);
error = explore_fqdn(pai, hostname, servname,
&cur->ai_next);
while (cur && cur->ai_next)
cur = cur->ai_next;
@ -602,82 +582,6 @@ getaddrinfo(hostname, servname, hints, res)
return error;
}
static char *
_hgetword(char **pp)
{
char c, *p, *ret;
const char *sp;
static const char sep[] = "# \t\n";
ret = NULL;
for (p = *pp; (c = *p) != '\0'; p++) {
for (sp = sep; *sp != '\0'; sp++) {
if (c == *sp)
break;
}
if (c == '#')
p[1] = '\0'; /* ignore rest of line */
if (ret == NULL) {
if (*sp == '\0')
ret = p;
} else {
if (*sp != '\0') {
*p++ = '\0';
break;
}
}
}
*pp = p;
if (ret == NULL || *ret == '\0')
return NULL;
return ret;
}
/*
* Initialize hostconf structure.
*/
static void
_hostconf_init(void)
{
FILE *fp;
int n;
char *p, *line;
char buf[BUFSIZ];
_hostconf_init_done = 1;
n = 0;
p = HOSTCONF;
if ((fp = fopen(p, "r")) == NULL)
return;
while (n < MAXHOSTCONF && fgets(buf, sizeof(buf), fp)) {
line = buf;
if ((p = _hgetword(&line)) == NULL)
continue;
do {
if (strcmp(p, "hosts") == 0
|| strcmp(p, "local") == 0
|| strcmp(p, "file") == 0
|| strcmp(p, "files") == 0)
_hostconf[n++].byname = _files_getaddrinfo;
else if (strcmp(p, "dns") == 0
|| strcmp(p, "bind") == 0)
_hostconf[n++].byname = _dns_getaddrinfo;
#ifdef YP
else if (strcmp(p, "nis") == 0)
_hostconf[n++].byname = _nis_getaddrinfo;
#endif
} while ((p = _hgetword(&line)) != NULL);
}
fclose(fp);
if (n < 0) {
/* no keyword found. do not change default configuration */
return;
}
for (; n < MAXHOSTCONF; n++)
_hostconf[n].byname = NULL;
}
/*
* FQDN hostname, DNS lookup
*/
@ -690,10 +594,15 @@ explore_fqdn(pai, hostname, servname, res)
{
struct addrinfo *result;
struct addrinfo *cur;
int error = 0, i;
int error = 0;
static const ns_dtab dtab[] = {
NS_FILES_CB(_files_getaddrinfo, NULL)
{ NSSRC_DNS, _dns_getaddrinfo, NULL }, /* force -DHESIOD */
NS_NIS_CB(_yp_getaddrinfo, NULL)
{ 0 }
};
result = NULL;
*res = NULL;
/*
* if the servname does not match socktype/protocol, ignore it.
@ -701,23 +610,30 @@ explore_fqdn(pai, hostname, servname, res)
if (get_portmatch(pai, servname) != 0)
return 0;
if (!_hostconf_init_done)
_hostconf_init();
for (i = 0; i < MAXHOSTCONF; i++) {
if (!_hostconf[i].byname)
continue;
error = (*_hostconf[i].byname)(pai, hostname, &result);
if (error != 0)
continue;
switch (nsdispatch(&result, dtab, NSDB_HOSTS, "getaddrinfo",
default_dns_files, hostname, pai)) {
case NS_TRYAGAIN:
error = EAI_AGAIN;
goto free;
case NS_UNAVAIL:
error = EAI_FAIL;
goto free;
case NS_NOTFOUND:
error = EAI_NODATA;
goto free;
case NS_SUCCESS:
error = 0;
for (cur = result; cur; cur = cur->ai_next) {
GET_PORT(cur, servname);
/* canonname should be filled already */
}
*res = result;
return 0;
break;
}
*res = result;
return 0;
free:
if (result)
freeaddrinfo(result);
@ -887,6 +803,7 @@ explore_numeric_scope(pai, hostname, servname, res)
afd = find_afd(pai->ai_family);
if (afd == NULL)
return 0;
if (!afd->a_scoped)
return explore_numeric(pai, hostname, servname, res);
@ -1003,14 +920,13 @@ get_ai(pai, afd, addr)
ai->ai_addr->sa_len = afd->a_socklen;
ai->ai_addrlen = afd->a_socklen;
ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
p = (char *)(ai->ai_addr);
p = (char *)(void *)(ai->ai_addr);
#ifdef FAITH
if (translate == 1)
memcpy(p + afd->a_off, &faith_prefix, afd->a_addrlen);
memcpy(p + afd->a_off, &faith_prefix, (size_t)afd->a_addrlen);
else
#endif
memcpy(p + afd->a_off, addr, afd->a_addrlen);
memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen);
return ai;
}
@ -1152,7 +1068,6 @@ addrconfig(pai)
else
_close(s);
}
}
if (af != AF_UNSPEC) {
if ((s = socket(af, SOCK_DGRAM, 0)) < 0)
@ -1212,6 +1127,7 @@ ip6_str2scopeid(scope, sin6)
static const char AskedForGot[] =
"gethostby*.getanswer: asked for \"%s\", got \"%s\"";
#endif
static FILE *hostf = NULL;
static struct addrinfo *
getanswer(answer, anslen, qname, qtype, pai)
@ -1415,17 +1331,21 @@ getanswer(answer, anslen, qname, qtype, pai)
/*ARGSUSED*/
static int
_dns_getaddrinfo(pai, hostname, res)
const struct addrinfo *pai;
const char *hostname;
struct addrinfo **res;
_dns_getaddrinfo(rv, cb_data, ap)
void *rv;
void *cb_data;
va_list ap;
{
struct addrinfo *ai;
querybuf buf, buf2;
const char *name;
const struct addrinfo *pai;
struct addrinfo sentinel, *cur;
struct res_target q, q2;
name = va_arg(ap, char *);
pai = va_arg(ap, const struct addrinfo *);
memset(&q, 0, sizeof(q2));
memset(&q2, 0, sizeof(q2));
memset(&sentinel, 0, sizeof(sentinel));
@ -1457,10 +1377,10 @@ _dns_getaddrinfo(pai, hostname, res)
q.anslen = sizeof(buf);
break;
default:
return EAI_FAIL;
return NS_UNAVAIL;
}
if (res_searchN(hostname, &q) < 0)
return EAI_NODATA;
if (res_searchN(name, &q) < 0)
return NS_NOTFOUND;
ai = getanswer(&buf, q.n, q.name, q.qtype, pai);
if (ai) {
cur->ai_next = ai;
@ -1475,19 +1395,36 @@ _dns_getaddrinfo(pai, hostname, res)
if (sentinel.ai_next == NULL)
switch (h_errno) {
case HOST_NOT_FOUND:
return EAI_NODATA;
return NS_NOTFOUND;
case TRY_AGAIN:
return EAI_AGAIN;
return NS_TRYAGAIN;
default:
return EAI_FAIL;
return NS_UNAVAIL;
}
*res = sentinel.ai_next;
return 0;
*((struct addrinfo **)rv) = sentinel.ai_next;
return NS_SUCCESS;
}
static void
_sethtent()
{
if (!hostf)
hostf = fopen(_PATH_HOSTS, "r" );
else
rewind(hostf);
}
static void
_endhtent()
{
if (hostf) {
(void) fclose(hostf);
hostf = NULL;
}
}
static struct addrinfo *
_gethtent(hostf, name, pai)
FILE *hostf;
_gethtent(name, pai)
const char *name;
const struct addrinfo *pai;
{
@ -1498,6 +1435,8 @@ _gethtent(hostf, name, pai)
const char *addr;
char hostbuf[8*1024];
if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" )))
return (NULL);
again:
if (!(p = fgets(hostbuf, sizeof hostbuf, hostf)))
return (NULL);
@ -1557,102 +1496,181 @@ _gethtent(hostf, name, pai)
/*ARGSUSED*/
static int
_files_getaddrinfo(pai, hostname, res)
const struct addrinfo *pai;
const char *hostname;
struct addrinfo **res;
_files_getaddrinfo(rv, cb_data, ap)
void *rv;
void *cb_data;
va_list ap;
{
FILE *hostf;
const char *name;
const struct addrinfo *pai;
struct addrinfo sentinel, *cur;
struct addrinfo *p;
sentinel.ai_next = NULL;
name = va_arg(ap, char *);
pai = va_arg(ap, struct addrinfo *);
memset(&sentinel, 0, sizeof(sentinel));
cur = &sentinel;
if ((hostf = fopen(_PATH_HOSTS, "r")) == NULL)
return EAI_FAIL;
while ((p = _gethtent(hostf, hostname, pai)) != NULL) {
_sethtent();
while ((p = _gethtent(name, pai)) != NULL) {
cur->ai_next = p;
while (cur && cur->ai_next)
cur = cur->ai_next;
}
fclose(hostf);
_endhtent();
if (!sentinel.ai_next)
return EAI_NODATA;
*res = sentinel.ai_next;
return 0;
*((struct addrinfo **)rv) = sentinel.ai_next;
if (sentinel.ai_next == NULL)
return NS_NOTFOUND;
return NS_SUCCESS;
}
#ifdef YP
/*ARGSUSED*/
static int
_nis_getaddrinfo(pai, hostname, res)
const struct addrinfo *pai;
const char *hostname;
struct addrinfo **res;
{
struct hostent *hp;
int h_error;
int af;
struct addrinfo sentinel, *cur;
int i;
const struct afd *afd;
int error;
static char *__ypdomain;
sentinel.ai_next = NULL;
/*ARGSUSED*/
static struct addrinfo *
_yphostent(line, pai)
char *line;
const struct addrinfo *pai;
{
struct addrinfo sentinel, *cur;
struct addrinfo hints, *res, *res0;
int error;
char *p = line;
const char *addr, *canonname;
char *nextline;
char *cp;
addr = canonname = NULL;
memset(&sentinel, 0, sizeof(sentinel));
cur = &sentinel;
af = (pai->ai_family == AF_UNSPEC) ? AF_INET : pai->ai_family;
if (af != AF_INET)
return (EAI_ADDRFAMILY);
nextline:
/* terminate line */
cp = strchr(p, '\n');
if (cp) {
*cp++ = '\0';
nextline = cp;
} else
nextline = NULL;
if ((hp = _gethostbynisname(hostname, af)) == NULL) {
switch (errno) {
/* XXX: should be filled in */
default:
error = EAI_FAIL;
break;
cp = strpbrk(p, " \t");
if (cp == NULL) {
if (canonname == NULL)
return (NULL);
else
goto done;
}
*cp++ = '\0';
addr = p;
while (cp && *cp) {
if (*cp == ' ' || *cp == '\t') {
cp++;
continue;
}
} else if (hp->h_name == NULL ||
hp->h_name[0] == 0 || hp->h_addr_list[0] == NULL) {
hp = NULL;
error = EAI_FAIL;
if (!canonname)
canonname = cp;
if ((cp = strpbrk(cp, " \t")) != NULL)
*cp++ = '\0';
}
if (hp == NULL)
return error;
hints = *pai;
hints.ai_flags = AI_NUMERICHOST;
error = getaddrinfo(addr, NULL, &hints, &res0);
if (error == 0) {
for (res = res0; res; res = res->ai_next) {
/* cover it up */
res->ai_flags = pai->ai_flags;
for (i = 0; hp->h_addr_list[i] != NULL; i++) {
if (hp->h_addrtype != af)
continue;
afd = find_afd(hp->h_addrtype);
if (afd == NULL)
continue;
GET_AI(cur->ai_next, afd, hp->h_addr_list[i]);
if ((pai->ai_flags & AI_CANONNAME) != 0) {
/*
* RFC2553 says that ai_canonname will be set only for
* the first element. we do it for all the elements,
* just for convenience.
*/
GET_CANONNAME(cur->ai_next, hp->h_name);
if (pai->ai_flags & AI_CANONNAME)
(void)get_canonname(pai, res, canonname);
}
} else
res0 = NULL;
if (res0) {
cur->ai_next = res0;
while (cur && cur->ai_next)
cur = cur->ai_next;
}
*res = sentinel.ai_next;
return 0;
if (nextline) {
p = nextline;
goto nextline;
}
free:
if (sentinel.ai_next)
freeaddrinfo(sentinel.ai_next);
return error;
done:
return sentinel.ai_next;
}
/*ARGSUSED*/
static int
_yp_getaddrinfo(rv, cb_data, ap)
void *rv;
void *cb_data;
va_list ap;
{
struct addrinfo sentinel, *cur;
struct addrinfo *ai = NULL;
static char *__ypcurrent;
int __ypcurrentlen, r;
const char *name;
const struct addrinfo *pai;
name = va_arg(ap, char *);
pai = va_arg(ap, const struct addrinfo *);
memset(&sentinel, 0, sizeof(sentinel));
cur = &sentinel;
if (!__ypdomain) {
if (_yp_check(&__ypdomain) == 0)
return NS_UNAVAIL;
}
if (__ypcurrent)
free(__ypcurrent);
__ypcurrent = NULL;
/* hosts.byname is only for IPv4 (Solaris8) */
if (pai->ai_family == PF_UNSPEC || pai->ai_family == PF_INET) {
r = yp_match(__ypdomain, "hosts.byname", name,
(int)strlen(name), &__ypcurrent, &__ypcurrentlen);
if (r == 0) {
struct addrinfo ai4;
ai4 = *pai;
ai4.ai_family = AF_INET;
ai = _yphostent(__ypcurrent, &ai4);
if (ai) {
cur->ai_next = ai;
while (cur && cur->ai_next)
cur = cur->ai_next;
}
}
}
/* ipnodes.byname can hold both IPv4/v6 */
r = yp_match(__ypdomain, "ipnodes.byname", name,
(int)strlen(name), &__ypcurrent, &__ypcurrentlen);
if (r == 0) {
ai = _yphostent(__ypcurrent, pai);
if (ai) {
cur->ai_next = ai;
while (cur && cur->ai_next)
cur = cur->ai_next;
}
}
if (sentinel.ai_next == NULL) {
h_errno = HOST_NOT_FOUND;
return NS_NOTFOUND;
}
*((struct addrinfo **)rv) = sentinel.ai_next;
return NS_SUCCESS;
}
#endif

View File

@ -74,6 +74,8 @@ static char rcsid[] = "$FreeBSD$";
#include <ctype.h>
#include <errno.h>
#include <syslog.h>
#include <stdarg.h>
#include <nsswitch.h>
#include "res_config.h"
@ -474,19 +476,23 @@ __dns_getanswer(answer, anslen, qname, qtype)
return(gethostanswer((const querybuf *)answer, anslen, qname, qtype));
}
struct hostent *
_gethostbydnsname(name, af)
int
_dns_gethostbyname(void *rval, void *cb_data, va_list ap)
{
const char *name;
int af;
{
querybuf buf;
register const char *cp;
char *bp;
int n, size, type, len;
name = va_arg(ap, const char *);
af = va_arg(ap, int);
*(struct hostent **)rval = NULL;
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return (NULL);
return NS_UNAVAIL;
}
switch (af) {
@ -501,7 +507,7 @@ _gethostbydnsname(name, af)
default:
h_errno = NETDB_INTERNAL;
errno = EAFNOSUPPORT;
return (NULL);
return NS_UNAVAIL;
}
host.h_addrtype = af;
@ -531,7 +537,7 @@ _gethostbydnsname(name, af)
*/
if (inet_pton(af, name, host_addr) <= 0) {
h_errno = HOST_NOT_FOUND;
return (NULL);
return NS_NOTFOUND;
}
strncpy(hostbuf, name, MAXDNAME);
hostbuf[MAXDNAME] = '\0';
@ -546,7 +552,8 @@ _gethostbydnsname(name, af)
if (_res.options & RES_USE_INET6)
_map_v4v6_hostent(&host, &bp, &len);
h_errno = NETDB_SUCCESS;
return (&host);
*(struct hostent **)rval = &host;
return NS_SUCCESS;
}
if (!isdigit((unsigned char)*cp) && *cp != '.')
break;
@ -564,7 +571,7 @@ _gethostbydnsname(name, af)
*/
if (inet_pton(af, name, host_addr) <= 0) {
h_errno = HOST_NOT_FOUND;
return (NULL);
return NS_NOTFOUND;
}
strncpy(hostbuf, name, MAXDNAME);
hostbuf[MAXDNAME] = '\0';
@ -577,7 +584,8 @@ _gethostbydnsname(name, af)
h_addr_ptrs[1] = NULL;
host.h_addr_list = h_addr_ptrs;
h_errno = NETDB_SUCCESS;
return (&host);
*(struct hostent **)rval = &host;
return NS_SUCCESS;
}
if (!isxdigit((unsigned char)*cp) && *cp != ':' && *cp != '.')
break;
@ -585,17 +593,18 @@ _gethostbydnsname(name, af)
if ((n = res_search(name, C_IN, type, buf.buf, sizeof(buf))) < 0) {
dprintf("res_search failed (%d)\n", n);
return (NULL);
return NS_UNAVAIL;
}
return (gethostanswer(&buf, n, name, type));
*(struct hostent **)rval = gethostanswer(&buf, n, name, type);
return (*(struct hostent **)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND;
}
struct hostent *
_gethostbydnsaddr(addr, len, af)
int
_dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
{
const char *addr; /* XXX should have been def'd as u_char! */
int len, af;
{
const u_char *uaddr = (const u_char *)addr;
const u_char *uaddr;
static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
int n, size;
@ -608,10 +617,17 @@ _gethostbydnsaddr(addr, len, af)
u_long old_options;
char hname2[MAXDNAME+1];
#endif /*SUNSECURITY*/
addr = va_arg(ap, const char *);
uaddr = (const u_char *)addr;
len = va_arg(ap, int);
af = va_arg(ap, int);
*(struct hostent **)rval = NULL;
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return (NULL);
return NS_UNAVAIL;
}
if (af == AF_INET6 && len == IN6ADDRSZ &&
(!bcmp(uaddr, mapped, sizeof mapped) ||
@ -632,12 +648,12 @@ _gethostbydnsaddr(addr, len, af)
default:
errno = EAFNOSUPPORT;
h_errno = NETDB_INTERNAL;
return (NULL);
return NS_UNAVAIL;
}
if (size != len) {
errno = EINVAL;
h_errno = NETDB_INTERNAL;
return (NULL);
return NS_UNAVAIL;
}
switch (af) {
case AF_INET:
@ -662,14 +678,14 @@ _gethostbydnsaddr(addr, len, af)
n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf);
if (n < 0) {
dprintf("res_query failed (%d)\n", n);
return (NULL);
return NS_UNAVAIL;
}
if (n > sizeof buf.buf) {
dprintf("static buffer is too small (%d)\n", n);
return (NULL);
return NS_UNAVAIL;
}
if (!(hp = gethostanswer(&buf, n, qbuf, T_PTR)))
return (NULL); /* h_errno was set by gethostanswer() */
return NS_NOTFOUND; /* h_errno was set by gethostanswer() */
#ifdef SUNSECURITY
if (af == AF_INET) {
/*
@ -687,7 +703,7 @@ _gethostbydnsaddr(addr, len, af)
hname2, inet_ntoa(*((struct in_addr *)addr)));
_res.options = old_options;
h_errno = HOST_NOT_FOUND;
return (NULL);
return NS_NOTFOUND;
}
_res.options = old_options;
for (haddr = rhp->h_addr_list; *haddr; haddr++)
@ -698,7 +714,7 @@ _gethostbydnsaddr(addr, len, af)
"gethostbyaddr: A record of %s != PTR record [%s]",
hname2, inet_ntoa(*((struct in_addr *)addr)));
h_errno = HOST_NOT_FOUND;
return (NULL);
return NS_NOTFOUND;
}
}
#endif /*SUNSECURITY*/
@ -713,7 +729,8 @@ _gethostbydnsaddr(addr, len, af)
hp->h_length = IN6ADDRSZ;
}
h_errno = NETDB_SUCCESS;
return (hp);
*(struct hostent **)rval = hp;
return (hp != NULL) ? NS_SUCCESS : NS_NOTFOUND;
}
#ifdef RESOLVSORT

View File

@ -65,6 +65,8 @@ static char rcsid[] = "$FreeBSD$";
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <stdarg.h>
#include <nsswitch.h>
#include <arpa/nameser.h> /* XXX */
#include <resolv.h> /* XXX */
@ -163,13 +165,16 @@ gethostent()
return (&host);
}
struct hostent *
_gethostbyhtname(name, af)
int
_ht_gethostbyname(void *rval, void *cb_data, va_list ap)
{
const char *name;
int af;
{
register struct hostent *p;
register char **cp;
name = va_arg(ap, const char *);
af = va_arg(ap, int);
sethostent(0);
while ((p = gethostent()) != NULL) {
@ -183,20 +188,28 @@ _gethostbyhtname(name, af)
}
found:
endhostent();
return (p);
*(struct hostent **)rval = p;
return (p != NULL) ? NS_SUCCESS : NS_NOTFOUND;
}
struct hostent *
_gethostbyhtaddr(addr, len, af)
int
_ht_gethostbyaddr(void *rval, void *cb_data, va_list ap)
{
const char *addr;
int len, af;
{
register struct hostent *p;
addr = va_arg(ap, const char *);
len = va_arg(ap, int);
af = va_arg(ap, int);
sethostent(0);
while ((p = gethostent()) != NULL)
if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len))
break;
endhostent();
return (p);
*(struct hostent **)rval = p;
return (p != NULL) ? NS_SUCCESS : NS_NOTFOUND;
}

View File

@ -78,10 +78,15 @@ following structure describing an internet host
referenced by name or by address, respectively.
This structure contains either the information obtained from the name server,
.Xr named 8 ,
or broken-out fields from a line in
.Pa /etc/hosts .
If the local name server is not running these routines do a lookup in
.Pa /etc/hosts .
broken-out fields from a line in
.Pa /etc/hosts ,
or database entries supplied by the
.Xr yp 4
system.
The order of the lookups is controlled by the
.Sq hosts
entry in
.Xr nsswitch.conf 5 .
.Bd -literal
struct hostent {
char *h_name; /* official name of host */
@ -188,9 +193,9 @@ value of the
.Fa err
parameter.
.Sh FILES
.Bl -tag -width /etc/resolv.conf -compact
.Bl -tag -width /etc/nsswitch.conf -compact
.It Pa /etc/hosts
.It Pa /etc/host.conf
.It Pa /etc/nsswitch.conf
.It Pa /etc/resolv.conf
.El
.Sh DIAGNOSTICS

View File

@ -39,6 +39,8 @@ static char rcsid[] = "$FreeBSD$";
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <stdarg.h>
#include <nsswitch.h>
#ifdef YP
#include <rpc/rpc.h>
#include <rpcsvc/yp_prot.h>
@ -52,7 +54,6 @@ static char rcsid[] = "$FreeBSD$";
static char *host_aliases[MAXALIASES];
static char hostaddr[MAXADDRS];
static char *host_addrs[2];
#endif /* YP */
static struct hostent *
_gethostbynis(name, map, af)
@ -60,7 +61,6 @@ _gethostbynis(name, map, af)
char *map;
int af;
{
#ifdef YP
register char *cp, **q;
char *result;
int resultlen,size;
@ -122,24 +122,64 @@ _gethostbynis(name, map, af)
}
*q = NULL;
return (&h);
#else
return (NULL);
}
#endif /* YP */
/* XXX _gethostbynisname/_gethostbynisaddr only used by getaddrinfo */
struct hostent *
_gethostbynisname(const char *name, int af)
{
#ifdef YP
return _gethostbynis(name, "hosts.byname", af);
#else
return NULL;
#endif
}
struct hostent *
_gethostbynisname(name, af)
_gethostbynisaddr(const char *addr, int len, int af)
{
#ifdef YP
return _gethostbynis(inet_ntoa(*(struct in_addr *)addr),
"hosts.byaddr", af);
#else
return NULL;
#endif
}
int
_nis_gethostbyname(void *rval, void *cb_data, va_list ap)
{
#ifdef YP
const char *name;
int af;
{
return _gethostbynis(name, "hosts.byname", af);
name = va_arg(ap, const char *);
af = va_arg(ap, int);
*(struct hostent **)rval = _gethostbynis(name, "hosts.byname", af);
return (*(struct hostent **)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND;
#else
return NS_UNAVAIL;
#endif
}
struct hostent *
_gethostbynisaddr(addr, len, af)
int
_nis_gethostbyaddr(void *rval, void *cb_data, va_list ap)
{
#ifdef YP
const char *addr;
int len;
int af;
{
return _gethostbynis(inet_ntoa(*(struct in_addr *)addr),"hosts.byaddr", af);
addr = va_arg(ap, const char *);
len = va_arg(ap, int);
af = va_arg(ap, int);
*(struct hostent **)rval =_gethostbynis(inet_ntoa(*(struct in_addr *)addr),"hosts.byaddr", af);
return (*(struct hostent **)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND;
#else
return NS_UNAVAIL;
#endif
}

View File

@ -37,87 +37,25 @@ static char rcsid[] = "$FreeBSD$";
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <stdarg.h>
#include <nsswitch.h>
#include <arpa/nameser.h> /* XXX hack for _res */
#include <resolv.h> /* XXX hack for _res */
#define _PATH_HOSTCONF "/etc/host.conf"
extern int _ht_gethostbyname(void *, void *, va_list);
extern int _dns_gethostbyname(void *, void *, va_list);
extern int _nis_gethostbyname(void *, void *, va_list);
extern int _ht_gethostbyaddr(void *, void *, va_list);
extern int _dns_gethostbyaddr(void *, void *, va_list);
extern int _nis_gethostbyaddr(void *, void *, va_list);
enum service_type {
SERVICE_NONE = 0,
SERVICE_BIND,
SERVICE_HOSTS,
SERVICE_NIS };
#define SERVICE_MAX SERVICE_NIS
static struct {
const char *name;
enum service_type type;
} service_names[] = {
{ "hosts", SERVICE_HOSTS },
{ "/etc/hosts", SERVICE_HOSTS },
{ "hosttable", SERVICE_HOSTS },
{ "htable", SERVICE_HOSTS },
{ "bind", SERVICE_BIND },
{ "dns", SERVICE_BIND },
{ "domain", SERVICE_BIND },
{ "yp", SERVICE_NIS },
{ "yellowpages", SERVICE_NIS },
{ "nis", SERVICE_NIS },
{ 0, SERVICE_NONE }
/* Host lookup order if nsswitch.conf is broken or nonexistant */
static const ns_src default_src[] = {
{ NSSRC_FILES, NS_SUCCESS },
{ NSSRC_DNS, NS_SUCCESS },
{ 0 }
};
static enum service_type service_order[SERVICE_MAX + 1];
static int service_done = 0;
static enum service_type
get_service_name(const char *name) {
int i;
for(i = 0; service_names[i].type != SERVICE_NONE; i++) {
if(!strcasecmp(name, service_names[i].name)) {
return service_names[i].type;
}
}
return SERVICE_NONE;
}
static void
init_services()
{
char *cp, *p, buf[BUFSIZ];
register int cc = 0;
FILE *fd;
if ((fd = (FILE *)fopen(_PATH_HOSTCONF, "r")) == NULL) {
/* make some assumptions */
service_order[0] = SERVICE_BIND;
service_order[1] = SERVICE_HOSTS;
service_order[2] = SERVICE_NONE;
} else {
while (fgets(buf, BUFSIZ, fd) != NULL && cc < SERVICE_MAX) {
if(buf[0] == '#')
continue;
p = buf;
while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')
;
if (cp == NULL)
continue;
do {
if (isalpha((unsigned char)cp[0])) {
service_order[cc] = get_service_name(cp);
if(service_order[cc] != SERVICE_NONE)
cc++;
}
while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')
;
} while(cp != NULL && cc < SERVICE_MAX);
}
service_order[cc] = SERVICE_NONE;
fclose(fd);
}
service_done = 1;
}
struct hostent *
gethostbyname(const char *name)
{
@ -135,56 +73,44 @@ struct hostent *
gethostbyname2(const char *name, int type)
{
struct hostent *hp = 0;
int nserv = 0;
int rval;
if (!service_done)
init_services();
static const ns_dtab dtab[] = {
NS_FILES_CB(_ht_gethostbyname, NULL)
{ NSSRC_DNS, _dns_gethostbyname, NULL },
NS_NIS_CB(_nis_gethostbyname, NULL) /* force -DHESIOD */
{ 0 }
};
rval = nsdispatch((void *)&hp, dtab, NSDB_HOSTS, "gethostbyname",
default_src, name, type);
while (!hp) {
switch (service_order[nserv]) {
case SERVICE_NONE:
return NULL;
case SERVICE_HOSTS:
hp = _gethostbyhtname(name, type);
break;
case SERVICE_BIND:
hp = _gethostbydnsname(name, type);
break;
case SERVICE_NIS:
hp = _gethostbynisname(name, type);
break;
}
nserv++;
}
return hp;
if (rval != NS_SUCCESS)
return NULL;
else
return hp;
}
struct hostent *
gethostbyaddr(const char *addr, int len, int type)
{
struct hostent *hp = 0;
int nserv = 0;
int rval;
if (!service_done)
init_services();
static const ns_dtab dtab[] = {
NS_FILES_CB(_ht_gethostbyaddr, NULL)
{ NSSRC_DNS, _dns_gethostbyaddr, NULL },
NS_NIS_CB(_nis_gethostbyaddr, NULL) /* force -DHESIOD */
{ 0 }
};
while (!hp) {
switch (service_order[nserv]) {
case SERVICE_NONE:
return 0;
case SERVICE_HOSTS:
hp = _gethostbyhtaddr(addr, len, type);
break;
case SERVICE_BIND:
hp = _gethostbydnsaddr(addr, len, type);
break;
case SERVICE_NIS:
hp = _gethostbynisaddr(addr, len, type);
break;
}
nserv++;
}
return hp;
rval = nsdispatch((void *)&hp, dtab, NSDB_HOSTS, "gethostbyaddr",
default_src, addr, len, type);
if (rval != NS_SUCCESS)
return NULL;
else
return hp;
}
#ifdef _THREAD_SAFE

View File

@ -405,9 +405,9 @@ or
.Fn getipnodebyaddr .
.\"
.Sh FILES
.Bl -tag -width /etc/resolv.conf -compact
.Bl -tag -width /etc/nsswitch.conf -compact
.It Pa /etc/hosts
.It Pa /etc/host.conf
.It Pa /etc/nsswitch.conf
.It Pa /etc/resolv.conf
.El
.\"
@ -429,6 +429,7 @@ The meanings of each error code are described in
.Xr gethostbyname 3 ,
.Xr gethostbyaddr 3 ,
.Xr hosts 5 ,
.Xr nsswitch.conf 5 ,
.Xr services 5 ,
.Xr hostname 7 ,
.Xr named 8

View File

@ -226,9 +226,9 @@ printf("host=%s\\n", hbuf);
.Ed
.\"
.Sh FILES
.Bl -tag -width /etc/resolv.conf -compact
.Bl -tag -width /etc/nsswitch.conf -compact
.It Pa /etc/hosts
.It Pa /etc/host.conf
.It Pa /etc/nsswitch.conf
.It Pa /etc/resolv.conf
.El
.\"

View File

@ -77,6 +77,8 @@ static char rcsid[] = "$FreeBSD$";
#include <string.h>
#include <unistd.h>
#include <syslog.h>
#include <stdarg.h>
#include <nsswitch.h>
#include "res_config.h"
@ -218,11 +220,11 @@ static char *net_aliases[MAXALIASES], netbuf[PACKETSZ];
return (NULL);
}
struct netent *
_getnetbydnsaddr(net, net_type)
register unsigned long net;
register int net_type;
int
_dns_getnetbyaddr(void *rval, void *cb_data, va_list ap)
{
unsigned long net;
int net_type;
unsigned int netbr[4];
int nn, anslen;
querybuf buf;
@ -230,8 +232,13 @@ _getnetbydnsaddr(net, net_type)
unsigned long net2;
struct netent *net_entry;
net = va_arg(ap, unsigned long);
net_type = va_arg(ap, int);
*(struct netent **)rval = NULL;
if (net_type != AF_INET)
return (NULL);
return NS_UNAVAIL;
for (nn = 4, net2 = net; net2; net2 >>= 8)
netbr[--nn] = net2 & 0xff;
@ -257,7 +264,7 @@ _getnetbydnsaddr(net, net_type)
if (_res.options & RES_DEBUG)
printf("res_query failed\n");
#endif
return (NULL);
return NS_UNAVAIL;
}
net_entry = getnetanswer(&buf, anslen, BYADDR);
if (net_entry) {
@ -267,22 +274,27 @@ _getnetbydnsaddr(net, net_type)
while ((u_net & 0xff) == 0 && u_net != 0)
u_net >>= 8;
net_entry->n_net = u_net;
return (net_entry);
*(struct netent **)rval = net_entry;
return NS_SUCCESS;
}
return (NULL);
return NS_NOTFOUND;
}
struct netent *
_getnetbydnsname(net)
register const char *net;
int
_dns_getnetbyname(void *rval, void *cb_data, va_list ap)
{
const char *net;
int anslen;
querybuf buf;
char qbuf[MAXDNAME];
net = va_arg(ap, const char *);
*(struct netent**)rval = NULL;
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return (NULL);
return NS_UNAVAIL;
}
strncpy(qbuf, net, sizeof(qbuf) - 1);
qbuf[sizeof(qbuf) - 1] = '\0';
@ -292,9 +304,10 @@ _getnetbydnsname(net)
if (_res.options & RES_DEBUG)
printf("res_query failed\n");
#endif
return (NULL);
return NS_UNAVAIL;
}
return getnetanswer(&buf, anslen, BYNAME);
*(struct netent**)rval = getnetanswer(&buf, anslen, BYNAME);
return (*(struct netent**)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND;
}
void

View File

@ -55,6 +55,8 @@ static chat rcsid[] = "$FreeBSD$";
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <nsswitch.h>
#define MAXALIASES 35
@ -135,13 +137,15 @@ getnetent()
return (&net);
}
struct netent *
_getnetbyhtname(name)
register const char *name;
int
_ht_getnetbyname(void *rval, void *cb_data, va_list ap)
{
const char *name;
register struct netent *p;
register char **cp;
name = va_arg(ap, const char *);
setnetent(_net_stayopen);
while ( (p = getnetent()) ) {
if (strcasecmp(p->n_name, name) == 0)
@ -153,21 +157,26 @@ _getnetbyhtname(name)
found:
if (!_net_stayopen)
endnetent();
return (p);
*(struct netent **)rval = p;
return (p != NULL) ? NS_SUCCESS : NS_NOTFOUND;
}
struct netent *
_getnetbyhtaddr(net, type)
register unsigned long net;
register int type;
int
_ht_getnetbyaddr(void *rval, void *cb_data, va_list ap)
{
unsigned long net;
int type;
register struct netent *p;
net = va_arg(ap, unsigned long);
type = va_arg(ap, int);
setnetent(_net_stayopen);
while ( (p = getnetent()) )
if (p->n_addrtype == type && p->n_net == net)
break;
if (!_net_stayopen)
endnetent();
return (p);
*(struct netent **)rval = p;
return (p != NULL) ? NS_SUCCESS : NS_NOTFOUND;
}

View File

@ -38,6 +38,8 @@ static char rcsid[] = "$FreeBSD$";
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <stdarg.h>
#include <nsswitch.h>
#include <arpa/nameser.h>
#ifdef YP
#include <rpc/rpc.h>
@ -50,15 +52,10 @@ static char rcsid[] = "$FreeBSD$";
#ifdef YP
static char *host_aliases[MAXALIASES];
#endif /* YP */
static struct netent *
_getnetbynis(name, map, af)
const char *name;
char *map;
int af;
_getnetbynis(const char *name, char *map, int af)
{
#ifdef YP
register char *cp, **q;
static char *result;
int resultlen;
@ -117,32 +114,45 @@ _getnetbynis(name, map, af)
}
*q = NULL;
return (&h);
#else
return (NULL);
#endif
}
#endif /* YP */
struct netent *
_getnetbynisname(name)
const char *name;
int
_nis_getnetbyname(void *rval, void *cb_data, va_list ap)
{
return _getnetbynis(name, "networks.byname", AF_INET);
#ifdef YP
const char *name;
name = va_arg(ap, const char *);
*(struct netent **)rval = _getnetbynis(name, "networks.byname", AF_INET);
return (*(struct netent **)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND;
#else
return NS_UNAVAIL;
#endif
}
struct netent *
_getnetbynisaddr(addr, af)
int
_nis_getnetbyaddr(void *rval, void *cb_data, va_list ap)
{
#ifdef YP
unsigned long addr;
int af;
{
char *str, *cp;
unsigned long net2;
int nn;
unsigned int netbr[4];
char buf[MAXDNAME];
addr = va_arg(ap, unsigned long);
af = va_arg(ap, int);
*(struct netent **)rval = NULL;
if (af != AF_INET) {
errno = EAFNOSUPPORT;
return (NULL);
return NS_UNAVAIL;
}
for (nn = 4, net2 = addr; net2; net2 >>= 8) {
@ -173,5 +183,9 @@ _getnetbynisaddr(addr, af)
cp = str + (strlen(str) - 2);
}
return _getnetbynis(str, "networks.byaddr", af);
*(struct netent **)rval = _getnetbynis(str, "networks.byaddr", af);
return (*(struct netent**)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND;
#else
return NS_UNAVAIL;
#endif /* YP */
}

View File

@ -64,10 +64,18 @@ and
.Fn getnetbyaddr
functions
each return a pointer to an object with the
following structure
containing the broken-out
fields of a line in the network data base,
.Pa /etc/networks .
following structure describing an internet network.
This structure contains either the information obtained
from the nameserver,
.Xr named 8 ,
broken-out fields of a line in the network data base
.Pa /etc/networks ,
or entries supplied by the
.Xr yp 4
system. The order of the lookups is controlled by the
`networks' entry in
.Xr nsswitch.conf 5 .
.Pp
.Bd -literal -offset indent
struct netent {
char *n_name; /* official name of net */
@ -129,8 +137,10 @@ must be
.Dv AF_INET .
Network numbers are supplied in host order.
.Sh FILES
.Bl -tag -width /etc/networks -compact
.Bl -tag -width /etc/nsswitch.conf -compact
.It Pa /etc/networks
.It Pa /etc/nsswitch.conf
.It Pa /etc/resolv.conf
.El
.Sh DIAGNOSTICS
Null pointer

View File

@ -36,142 +36,66 @@ static char rcsid[] = "$FreeBSD$";
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <stdarg.h>
#include <nsswitch.h>
#ifndef _PATH_NETCONF
#define _PATH_NETCONF "/etc/host.conf"
#endif
extern int _ht_getnetbyname(void *, void *, va_list);
extern int _dns_getnetbyname(void *, void *, va_list);
extern int _nis_getnetbyname(void *, void *, va_list);
extern int _ht_getnetbyaddr(void *, void *, va_list);
extern int _dns_getnetbyaddr(void *, void *, va_list);
extern int _nis_getnetbyaddr(void *, void *, va_list);
enum service_type {
SERVICE_NONE = 0,
SERVICE_BIND,
SERVICE_TABLE,
SERVICE_NIS };
#define SERVICE_MAX SERVICE_NIS
static struct {
const char *name;
enum service_type type;
} service_names[] = {
{ "hosts", SERVICE_TABLE },
{ "/etc/hosts", SERVICE_TABLE },
{ "hosttable", SERVICE_TABLE },
{ "htable", SERVICE_TABLE },
{ "bind", SERVICE_BIND },
{ "dns", SERVICE_BIND },
{ "domain", SERVICE_BIND },
{ "yp", SERVICE_NIS },
{ "yellowpages", SERVICE_NIS },
{ "nis", SERVICE_NIS },
{ 0, SERVICE_NONE }
/* Network lookup order if nsswitch.conf is broken or nonexistant */
static const ns_src default_src[] = {
{ NSSRC_FILES, NS_SUCCESS },
{ NSSRC_DNS, NS_SUCCESS },
{ 0 }
};
static enum service_type service_order[SERVICE_MAX + 1];
static int service_done = 0;
static enum service_type
get_service_name(const char *name) {
int i;
for(i = 0; service_names[i].type != SERVICE_NONE; i++) {
if(!strcasecmp(name, service_names[i].name)) {
return service_names[i].type;
}
}
return SERVICE_NONE;
}
static void
init_services()
{
char *cp, *p, buf[BUFSIZ];
register int cc = 0;
FILE *fd;
if ((fd = (FILE *)fopen(_PATH_NETCONF, "r")) == NULL) {
/* make some assumptions */
service_order[0] = SERVICE_TABLE;
service_order[1] = SERVICE_NONE;
} else {
while (fgets(buf, BUFSIZ, fd) != NULL && cc < SERVICE_MAX) {
if(buf[0] == '#')
continue;
p = buf;
while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')
;
if (cp == NULL)
continue;
do {
if (isalpha((unsigned char)cp[0])) {
service_order[cc] = get_service_name(cp);
if(service_order[cc] != SERVICE_NONE)
cc++;
}
while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')
;
} while(cp != NULL && cc < SERVICE_MAX);
}
service_order[cc] = SERVICE_NONE;
fclose(fd);
}
service_done = 1;
}
struct netent *
getnetbyname(const char *name)
{
struct netent *hp = 0;
int nserv = 0;
int rval;
if (!service_done)
init_services();
while (!hp) {
switch (service_order[nserv]) {
case SERVICE_NONE:
return NULL;
case SERVICE_TABLE:
hp = _getnetbyhtname(name);
break;
case SERVICE_BIND:
hp = _getnetbydnsname(name);
break;
case SERVICE_NIS:
hp = _getnetbynisname(name);
break;
}
nserv++;
}
return hp;
static const ns_dtab dtab[] = {
NS_FILES_CB(_ht_getnetbyname, NULL)
{ NSSRC_DNS, _dns_getnetbyname, NULL },
NS_NIS_CB(_nis_getnetbyname, NULL) /* force -DHESIOD */
{ 0 }
};
rval = nsdispatch((void *)&hp, dtab, NSDB_NETWORKS, "getnetbyname",
default_src, name);
if (rval != NS_SUCCESS)
return NULL;
else
return hp;
}
struct netent *
getnetbyaddr(addr, af)
u_long addr;
int af;
getnetbyaddr(u_long addr, int af)
{
struct netent *hp = 0;
int nserv = 0;
int rval;
if (!service_done)
init_services();
static const ns_dtab dtab[] = {
NS_FILES_CB(_ht_getnetbyaddr, NULL)
{ NSSRC_DNS, _dns_getnetbyaddr, NULL },
NS_NIS_CB(_nis_getnetbyaddr, NULL) /* force -DHESIOD */
{ 0 }
};
while (!hp) {
switch (service_order[nserv]) {
case SERVICE_NONE:
return 0;
case SERVICE_TABLE:
hp = _getnetbyhtaddr(addr, af);
break;
case SERVICE_BIND:
hp = _getnetbydnsaddr(addr, af);
break;
case SERVICE_NIS:
hp = _getnetbynisaddr(addr, af);
break;
}
nserv++;
}
return hp;
rval = nsdispatch((void *)&hp, dtab, NSDB_HOSTS, "getnetbyaddr",
default_src, addr, af);
if (rval != NS_SUCCESS)
return NULL;
else
return hp;
}
void

136
lib/libc/net/hesiod.3 Normal file
View File

@ -0,0 +1,136 @@
.\" $NetBSD: hesiod.3,v 1.1 1999/01/25 03:43:04 lukem Exp $
.\" $FreeBSD$
.\"
.\" from: #Id: hesiod.3,v 1.9.2.1 1997/01/03 21:02:23 ghudson Exp #
.\"
.\" Copyright 1988, 1996 by the Massachusetts Institute of Technology.
.\"
.\" Permission to use, copy, modify, and distribute this
.\" software and its documentation for any purpose and without
.\" fee is hereby granted, provided that the above copyright
.\" notice appear in all copies and that both that copyright
.\" notice and this permission notice appear in supporting
.\" documentation, and that the name of M.I.T. not be used in
.\" advertising or publicity pertaining to distribution of the
.\" software without specific, written prior permission.
.\" M.I.T. makes no representations about the suitability of
.\" this software for any purpose. It is provided "as is"
.\" without express or implied warranty.
.\"
.TH HESIOD 3 "30 November 1996"
.SH NAME
hesiod, hesiod_init, hesiod_resolve, hesiod_free_list, hesiod_to_bind, hesiod_end \- Hesiod name server interface library
.SH SYNOPSIS
.nf
.B #include <hesiod.h>
.PP
.B int hesiod_init(void **\fIcontext\fP)
.B char **hesiod_resolve(void *\fIcontext\fP, const char *\fIname\fP,
.B const char *\fItype\fP)
.B void hesiod_free_list(void *\fIcontext\fP, char **\fIlist\fP);
.B char *hesiod_to_bind(void *\fIcontext\fP, const char *\fIname\fP,
.B const char *\fItype\fP)
.B void hesiod_end(void *\fIcontext\fP)
.PP
.B cc file.c -lhesiod
.fi
.SH DESCRIPTION
This family of functions allows you to perform lookups of Hesiod
information, which is stored as text records in the Domain Name
Service. To perform lookups, you must first initialize a
.IR context ,
an opaque object which stores information used internally by the
library between calls.
.I hesiod_init
initializes a context, storing a pointer to the context in the
location pointed to by the
.I context
argument.
.I hesiod_end
frees the resources used by a context.
.PP
.I hesiod_resolve
is the primary interface to the library. If successful, it returns a
list of one or more strings giving the records matching
.I name
and
.IR type .
The last element of the list is followed by a NULL pointer. It is the
caller's responsibility to call
.I hesiod_free_list
to free the resources used by the returned list.
.PP
.I hesiod_to_bind
converts
.I name
and
.I type
into the DNS name used by
.IR hesiod_resolve .
It is the caller's responsibility to free the returned string using
.IR free .
.SH RETURN VALUES
If successful,
.I hesiod_init
returns 0; otherwise it returns \-1 and sets
.I errno
to indicate the error. On failure,
.I hesiod_resolve
and
.I hesiod_to_bind
return NULL and set the global variable
.I errno
to indicate the error.
.SH ENVIRONMENT
If the environment variable
.B HES_DOMAIN
is set, it will override the domain in the Hesiod configuration file.
If the environment variable
.B HESIOD_CONFIG
is set, it specifies the location of the Hesiod configuration file.
.SH SEE ALSO
`Hesiod - Project Athena Technical Plan -- Name Service', named(8),
hesiod.conf(5)
.SH ERRORS
Hesiod calls may fail because of:
.IP ENOMEM
Insufficient memory was available to carry out the requested
operation.
.IP ENOEXEC
.I hesiod_init
failed because the Hesiod configuration file was invalid.
.IP ECONNREFUSED
.I hesiod_resolve
failed because no name server could be contacted to answer the query.
.IP EMSGSIZE
.I hesiod_resolve
or
.I hesiod_to_bind
failed because the query or response was too big to fit into the
packet buffers.
.IP ENOENT
.I hesiod_resolve
failed because the name server had no text records matching
.I name
and
.IR type ,
or
.I hesiod_to_bind
failed because the
.I name
argument had a domain extension which could not be resolved with type
``rhs-extension'' in the local Hesiod domain.
.SH AUTHOR
Steve Dyer, IBM/Project Athena
.br
Greg Hudson, MIT Team Athena
.br
Copyright 1987, 1988, 1995, 1996 by the Massachusetts Institute of Technology.
.SH BUGS
The strings corresponding to the
.I errno
values set by the Hesiod functions are not particularly indicative of
what went wrong, especially for
.I ENOEXEC
and
.IR ENOENT .

572
lib/libc/net/hesiod.c Normal file
View File

@ -0,0 +1,572 @@
/* $NetBSD: hesiod.c,v 1.9 1999/02/11 06:16:38 simonb Exp $ */
/* Copyright (c) 1996 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/* Copyright 1996 by the Massachusetts Institute of Technology.
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
/* This file is part of the hesiod library. It implements the core
* portion of the hesiod resolver.
*
* This file is loosely based on an interim version of hesiod.c from
* the BIND IRS library, which was in turn based on an earlier version
* of this file. Extensive changes have been made on each step of the
* path.
*
* This implementation is not truly thread-safe at the moment because
* it uses res_send() and accesses _res.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
static char *orig_rcsid = "$NetBSD: hesiod.c,v 1.9 1999/02/11 06:16:38 simonb Exp $";
static char *rcsid = "$FreeBSD$";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <ctype.h>
#include <errno.h>
#include <hesiod.h>
#include <resolv.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct hesiod_p {
char *lhs; /* normally ".ns" */
char *rhs; /* AKA the default hesiod domain */
int classes[2]; /* The class search order. */
};
#define MAX_HESRESP 1024
static int read_config_file __P((struct hesiod_p *, const char *));
static char **get_txt_records __P((int, const char *));
static int init_context __P((void));
static void translate_errors __P((void));
/*
* hesiod_init --
* initialize a hesiod_p.
*/
int
hesiod_init(context)
void **context;
{
struct hesiod_p *ctx;
const char *p, *configname;
ctx = malloc(sizeof(struct hesiod_p));
if (ctx) {
*context = ctx;
configname = getenv("HESIOD_CONFIG");
if (!configname)
configname = _PATH_HESIOD_CONF;
if (read_config_file(ctx, configname) >= 0) {
/*
* The default rhs can be overridden by an
* environment variable.
*/
p = getenv("HES_DOMAIN");
if (p) {
if (ctx->rhs)
free(ctx->rhs);
ctx->rhs = malloc(strlen(p) + 2);
if (ctx->rhs) {
*ctx->rhs = '.';
strcpy(ctx->rhs + 1,
(*p == '.') ? p + 1 : p);
return 0;
} else
errno = ENOMEM;
} else
return 0;
}
} else
errno = ENOMEM;
if (ctx->lhs)
free(ctx->lhs);
if (ctx->rhs)
free(ctx->rhs);
if (ctx)
free(ctx);
return -1;
}
/*
* hesiod_end --
* Deallocates the hesiod_p.
*/
void
hesiod_end(context)
void *context;
{
struct hesiod_p *ctx = (struct hesiod_p *) context;
free(ctx->rhs);
if (ctx->lhs)
free(ctx->lhs);
free(ctx);
}
/*
* hesiod_to_bind --
* takes a hesiod (name, type) and returns a DNS
* name which is to be resolved.
*/
char *
hesiod_to_bind(void *context, const char *name, const char *type)
{
struct hesiod_p *ctx = (struct hesiod_p *) context;
char bindname[MAXDNAME], *p, *ret, **rhs_list = NULL;
const char *rhs;
int len;
strcpy(bindname, name);
/*
* Find the right right hand side to use, possibly
* truncating bindname.
*/
p = strchr(bindname, '@');
if (p) {
*p++ = 0;
if (strchr(p, '.'))
rhs = name + (p - bindname);
else {
rhs_list = hesiod_resolve(context, p, "rhs-extension");
if (rhs_list)
rhs = *rhs_list;
else {
errno = ENOENT;
return NULL;
}
}
} else
rhs = ctx->rhs;
/* See if we have enough room. */
len = strlen(bindname) + 1 + strlen(type);
if (ctx->lhs)
len += strlen(ctx->lhs) + ((ctx->lhs[0] != '.') ? 1 : 0);
len += strlen(rhs) + ((rhs[0] != '.') ? 1 : 0);
if (len > sizeof(bindname) - 1) {
if (rhs_list)
hesiod_free_list(context, rhs_list);
errno = EMSGSIZE;
return NULL;
}
/* Put together the rest of the domain. */
strcat(bindname, ".");
strcat(bindname, type);
/* Only append lhs if it isn't empty. */
if (ctx->lhs && ctx->lhs[0] != '\0' ) {
if (ctx->lhs[0] != '.')
strcat(bindname, ".");
strcat(bindname, ctx->lhs);
}
if (rhs[0] != '.')
strcat(bindname, ".");
strcat(bindname, rhs);
/* rhs_list is no longer needed, since we're done with rhs. */
if (rhs_list)
hesiod_free_list(context, rhs_list);
/* Make a copy of the result and return it to the caller. */
ret = strdup(bindname);
if (!ret)
errno = ENOMEM;
return ret;
}
/*
* hesiod_resolve --
* Given a hesiod name and type, return an array of strings returned
* by the resolver.
*/
char **
hesiod_resolve(context, name, type)
void *context;
const char *name;
const char *type;
{
struct hesiod_p *ctx = (struct hesiod_p *) context;
char *bindname, **retvec;
bindname = hesiod_to_bind(context, name, type);
if (!bindname)
return NULL;
retvec = get_txt_records(ctx->classes[0], bindname);
if (retvec == NULL && errno == ENOENT && ctx->classes[1])
retvec = get_txt_records(ctx->classes[1], bindname);
free(bindname);
return retvec;
}
/*ARGSUSED*/
void
hesiod_free_list(context, list)
void *context;
char **list;
{
char **p;
if (list == NULL)
return;
for (p = list; *p; p++)
free(*p);
free(list);
}
/* read_config_file --
* Parse the /etc/hesiod.conf file. Returns 0 on success,
* -1 on failure. On failure, it might leave values in ctx->lhs
* or ctx->rhs which need to be freed by the caller.
*/
static int
read_config_file(ctx, filename)
struct hesiod_p *ctx;
const char *filename;
{
char *key, *data, *p, **which;
char buf[MAXDNAME + 7];
int n;
FILE *fp;
/* Set default query classes. */
ctx->classes[0] = C_IN;
ctx->classes[1] = C_HS;
/* Try to open the configuration file. */
fp = fopen(filename, "r");
if (!fp) {
/* Use compiled in default domain names. */
ctx->lhs = strdup(DEF_LHS);
ctx->rhs = strdup(DEF_RHS);
if (ctx->lhs && ctx->rhs)
return 0;
else {
errno = ENOMEM;
return -1;
}
}
ctx->lhs = NULL;
ctx->rhs = NULL;
while (fgets(buf, sizeof(buf), fp) != NULL) {
p = buf;
if (*p == '#' || *p == '\n' || *p == '\r')
continue;
while (*p == ' ' || *p == '\t')
p++;
key = p;
while (*p != ' ' && *p != '\t' && *p != '=')
p++;
*p++ = 0;
while (isspace(*p) || *p == '=')
p++;
data = p;
while (!isspace(*p))
p++;
*p = 0;
if (strcasecmp(key, "lhs") == 0 ||
strcasecmp(key, "rhs") == 0) {
which = (strcasecmp(key, "lhs") == 0)
? &ctx->lhs : &ctx->rhs;
*which = strdup(data);
if (!*which) {
errno = ENOMEM;
return -1;
}
} else {
if (strcasecmp(key, "classes") == 0) {
n = 0;
while (*data && n < 2) {
p = data;
while (*p && *p != ',')
p++;
if (*p)
*p++ = 0;
if (strcasecmp(data, "IN") == 0)
ctx->classes[n++] = C_IN;
else
if (strcasecmp(data, "HS") == 0)
ctx->classes[n++] =
C_HS;
data = p;
}
while (n < 2)
ctx->classes[n++] = 0;
}
}
}
fclose(fp);
if (!ctx->rhs || ctx->classes[0] == 0 ||
ctx->classes[0] == ctx->classes[1]) {
errno = ENOEXEC;
return -1;
}
return 0;
}
/*
* get_txt_records --
* Given a DNS class and a DNS name, do a lookup for TXT records, and
* return a list of them.
*/
static char **
get_txt_records(qclass, name)
int qclass;
const char *name;
{
HEADER *hp;
unsigned char qbuf[PACKETSZ], abuf[MAX_HESRESP], *p, *eom, *eor;
char *dst, **list;
int ancount, qdcount, i, j, n, skip, type, class, len;
/* Make sure the resolver is initialized. */
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
return NULL;
/* Construct the query. */
n = res_mkquery(QUERY, name, qclass, T_TXT, NULL, 0,
NULL, qbuf, PACKETSZ);
if (n < 0)
return NULL;
/* Send the query. */
n = res_send(qbuf, n, abuf, MAX_HESRESP);
if (n < 0) {
errno = ECONNREFUSED;
return NULL;
}
/* Parse the header of the result. */
hp = (HEADER *) (void *) abuf;
ancount = ntohs(hp->ancount);
qdcount = ntohs(hp->qdcount);
p = abuf + sizeof(HEADER);
eom = abuf + n;
/*
* Skip questions, trying to get to the answer section
* which follows.
*/
for (i = 0; i < qdcount; i++) {
skip = dn_skipname(p, eom);
if (skip < 0 || p + skip + QFIXEDSZ > eom) {
errno = EMSGSIZE;
return NULL;
}
p += skip + QFIXEDSZ;
}
/* Allocate space for the text record answers. */
list = malloc((ancount + 1) * sizeof(char *));
if (!list) {
errno = ENOMEM;
return NULL;
}
/* Parse the answers. */
j = 0;
for (i = 0; i < ancount; i++) {
/* Parse the header of this answer. */
skip = dn_skipname(p, eom);
if (skip < 0 || p + skip + 10 > eom)
break;
type = p[skip + 0] << 8 | p[skip + 1];
class = p[skip + 2] << 8 | p[skip + 3];
len = p[skip + 8] << 8 | p[skip + 9];
p += skip + 10;
if (p + len > eom) {
errno = EMSGSIZE;
break;
}
/* Skip entries of the wrong class and type. */
if (class != qclass || type != T_TXT) {
p += len;
continue;
}
/* Allocate space for this answer. */
list[j] = malloc((size_t)len);
if (!list[j]) {
errno = ENOMEM;
break;
}
dst = list[j++];
/* Copy answer data into the allocated area. */
eor = p + len;
while (p < eor) {
n = (unsigned char) *p++;
if (p + n > eor) {
errno = EMSGSIZE;
break;
}
memcpy(dst, p, (size_t)n);
p += n;
dst += n;
}
if (p < eor) {
errno = EMSGSIZE;
break;
}
*dst = 0;
}
/*
* If we didn't terminate the loop normally, something
* went wrong.
*/
if (i < ancount) {
for (i = 0; i < j; i++)
free(list[i]);
free(list);
return NULL;
}
if (j == 0) {
errno = ENOENT;
free(list);
return NULL;
}
list[j] = NULL;
return list;
}
/*
* COMPATIBILITY FUNCTIONS
*/
static int inited = 0;
static void *context;
static int errval = HES_ER_UNINIT;
int
hes_init()
{
init_context();
return errval;
}
char *
hes_to_bind(name, type)
const char *name;
const char *type;
{
static char *bindname;
if (init_context() < 0)
return NULL;
if (bindname)
free(bindname);
bindname = hesiod_to_bind(context, name, type);
if (!bindname)
translate_errors();
return bindname;
}
char **
hes_resolve(name, type)
const char *name;
const char *type;
{
static char **list;
if (init_context() < 0)
return NULL;
/*
* In the old Hesiod interface, the caller was responsible for
* freeing the returned strings but not the vector of strings itself.
*/
if (list)
free(list);
list = hesiod_resolve(context, name, type);
if (!list)
translate_errors();
return list;
}
int
hes_error()
{
return errval;
}
void
hes_free(hp)
char **hp;
{
hesiod_free_list(context, hp);
}
static int
init_context()
{
if (!inited) {
inited = 1;
if (hesiod_init(&context) < 0) {
errval = HES_ER_CONFIG;
return -1;
}
errval = HES_ER_OK;
}
return 0;
}
static void
translate_errors()
{
switch (errno) {
case ENOENT:
errval = HES_ER_NOTFOUND;
break;
case ECONNREFUSED:
case EMSGSIZE:
errval = HES_ER_NET;
break;
case ENOMEM:
default:
/* Not a good match, but the best we can do. */
errval = HES_ER_CONFIG;
break;
}
}

View File

@ -109,6 +109,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <nsswitch.h>
#include <unistd.h>
#ifndef _PATH_HOSTS
@ -169,110 +171,32 @@ static char *_hgetword(char **pp);
static int _mapped_addr_enabled(void);
static FILE *_files_open(int *errp);
static struct hostent *_files_ghbyname(const char *name, int af, int *errp);
static struct hostent *_files_ghbyaddr(const void *addr, int addrlen, int af, int *errp);
static int _files_ghbyname(void *, void *, va_list);
static int _files_ghbyaddr(void *, void *, va_list);
static void _files_shent(int stayopen);
static void _files_ehent(void);
#ifdef YP
static struct hostent *_nis_ghbyname(const char *name, int af, int *errp);
static struct hostent *_nis_ghbyaddr(const void *addr, int addrlen, int af, int *errp);
static int _nis_ghbyname(void *, void *, va_list);
static int _nis_ghbyaddr(void *, void *, va_list);
#endif
static struct hostent *_dns_ghbyname(const char *name, int af, int *errp);
static struct hostent *_dns_ghbyaddr(const void *addr, int addrlen, int af, int *errp);
static int _dns_ghbyname(void *, void *, va_list);
static int _dns_ghbyaddr(void *, void *, va_list);
static void _dns_shent(int stayopen);
static void _dns_ehent(void);
#ifdef ICMPNL
static struct hostent *_icmp_ghbyaddr(const void *addr, int addrlen, int af, int *errp);
static int _icmp_ghbyaddr(void *, void *, va_list);
#endif /* ICMPNL */
/*
* Select order host function.
*/
#define MAXHOSTCONF 4
#ifndef HOSTCONF
# define HOSTCONF "/etc/host.conf"
#endif /* !HOSTCONF */
struct _hostconf {
struct hostent *(*byname)(const char *name, int af, int *errp);
struct hostent *(*byaddr)(const void *addr, int addrlen, int af, int *errp);
};
/* default order */
static struct _hostconf _hostconf[MAXHOSTCONF] = {
{ _dns_ghbyname, _dns_ghbyaddr },
{ _files_ghbyname, _files_ghbyaddr },
/* Host lookup order if nsswitch.conf is broken or nonexistant */
static const ns_src default_src[] = {
{ NSSRC_FILES, NS_SUCCESS },
{ NSSRC_DNS, NS_SUCCESS },
#ifdef ICMPNL
{ NULL, _icmp_ghbyaddr },
#endif /* ICMPNL */
};
static int _hostconf_init_done;
static void _hostconf_init(void);
/*
* Initialize hostconf structure.
*/
static void
_hostconf_init(void)
{
FILE *fp;
int n;
char *p, *line;
char buf[BUFSIZ];
_hostconf_init_done = 1;
n = 0;
p = HOSTCONF;
if ((fp = fopen(p, "r")) == NULL)
return;
while (n < MAXHOSTCONF && fgets(buf, sizeof(buf), fp)) {
line = buf;
if ((p = _hgetword(&line)) == NULL)
continue;
do {
if (strcmp(p, "hosts") == 0
|| strcmp(p, "local") == 0
|| strcmp(p, "file") == 0
|| strcmp(p, "files") == 0) {
_hostconf[n].byname = _files_ghbyname;
_hostconf[n].byaddr = _files_ghbyaddr;
n++;
}
else if (strcmp(p, "dns") == 0
|| strcmp(p, "bind") == 0) {
_hostconf[n].byname = _dns_ghbyname;
_hostconf[n].byaddr = _dns_ghbyaddr;
n++;
}
#ifdef YP
else if (strcmp(p, "nis") == 0) {
_hostconf[n].byname = _nis_ghbyname;
_hostconf[n].byaddr = _nis_ghbyaddr;
n++;
}
#define NSSRC_ICMP "icmp"
{ NSSRC_ICMP, NS_SUCCESS },
#endif
#ifdef ICMPNL
else if (strcmp(p, "icmp") == 0) {
_hostconf[n].byname = NULL;
_hostconf[n].byaddr = _icmp_ghbyaddr;
n++;
}
#endif /* ICMPNL */
} while ((p = _hgetword(&line)) != NULL);
}
fclose(fp);
if (n < 0) {
/* no keyword found. do not change default configuration */
return;
}
for (; n < MAXHOSTCONF; n++) {
_hostconf[n].byname = NULL;
_hostconf[n].byaddr = NULL;
}
}
{ 0 }
};
/*
* Check if kernel supports mapped address.
@ -311,7 +235,14 @@ static struct hostent *
_ghbyname(const char *name, int af, int flags, int *errp)
{
struct hostent *hp;
int i;
int i, rval;
static const ns_dtab dtab[] = {
NS_FILES_CB(_files_ghbyname, NULL)
{ NSSRC_DNS, _dns_ghbyname, NULL },
NS_NIS_CB(_nis_ghbyname, NULL)
{ 0 }
};
if (flags & AI_ADDRCONFIG) {
int s;
@ -342,13 +273,9 @@ _ghbyname(const char *name, int af, int flags, int *errp)
}
}
for (i = 0; i < MAXHOSTCONF; i++) {
if (_hostconf[i].byname
&& (hp = (*_hostconf[i].byname)(name, af, errp)) != NULL)
return hp;
}
return NULL;
rval = nsdispatch(&hp, dtab, NSDB_HOSTS, "ghbyname", default_src,
name, af, errp);
return (rval == NS_SUCCESS) ? hp : NULL;
}
/* getipnodebyname() internal routine for multiple query(PF_UNSPEC) support. */
@ -392,9 +319,6 @@ _getipnodebyname_multi(const char *name, int af, int flags, int *errp)
return _hpaddr(af, name, &addrbuf, errp);
}
if (!_hostconf_init_done)
_hostconf_init();
*errp = HOST_NOT_FOUND;
hp = _ghbyname(name, af, flags, errp);
@ -436,13 +360,23 @@ struct hostent *
getipnodebyaddr(const void *src, size_t len, int af, int *errp)
{
struct hostent *hp;
int i;
int i, rval;
#ifdef INET6
struct in6_addr addrbuf;
#else
struct in_addr addrbuf;
#endif
static const ns_dtab dtab[] = {
NS_FILES_CB(_files_ghbyaddr, NULL)
{ NSSRC_DNS, _dns_ghbyaddr, NULL },
NS_NIS_CB(_nis_ghbyaddr, NULL)
#ifdef ICMPNL
{ NSSRC_ICMP, _icmp_ghbyaddr, NULL },
#endif
{ 0 }
};
*errp = HOST_NOT_FOUND;
switch (af) {
@ -484,15 +418,9 @@ getipnodebyaddr(const void *src, size_t len, int af, int *errp)
return NULL;
}
if (!_hostconf_init_done)
_hostconf_init();
for (i = 0; i < MAXHOSTCONF; i++) {
if (_hostconf[i].byaddr
&& (hp = (*_hostconf[i].byaddr)(src, len, af, errp)) != NULL)
return hp;
}
return NULL;
rval = nsdispatch(&hp, dtab, NSDB_HOSTS, "ghbyaddr", default_src,
src, len, af, errp);
return (rval == NS_SUCCESS) ? hp : NULL;
}
void
@ -828,9 +756,12 @@ _files_open(int *errp)
return fp;
}
static struct hostent *
_files_ghbyname(const char *name, int af, int *errp)
static int
_files_ghbyname(void *rval, void *cb_data, va_list ap)
{
const char *name;
int af;
int *errp;
int match, nalias;
char *p, *line, *addrstr, *cname;
FILE *fp;
@ -840,8 +771,14 @@ _files_ghbyname(const char *name, int af, int *errp)
char buf[BUFSIZ];
int af0 = af;
name = va_arg(ap, const char *);
af = va_arg(ap, int);
errp = va_arg(ap, int *);
*(struct hostent **)rval = NULL;
if ((fp = _files_open(errp)) == NULL)
return NULL;
return NS_UNAVAIL;
rethp = hp = NULL;
while (fgets(buf, sizeof(buf), fp)) {
@ -906,12 +843,17 @@ _files_ghbyname(const char *name, int af, int *errp)
rethp = _hpmerge(rethp, hp, errp);
}
fclose(fp);
return rethp;
*(struct hostent **)rval = rethp;
return (rethp != NULL) ? NS_SUCCESS : NS_NOTFOUND;
}
static struct hostent *
_files_ghbyaddr(const void *addr, int addrlen, int af, int *errp)
static int
_files_ghbyaddr(void *rval, void *cb_data, va_list ap)
{
const void *addr;
int addrlen;
int af;
int *errp;
int nalias;
char *p, *line;
FILE *fp;
@ -920,8 +862,15 @@ _files_ghbyaddr(const void *addr, int addrlen, int af, int *errp)
union inx_addr addrbuf;
char buf[BUFSIZ];
addr = va_arg(ap, const void *);
addrlen = va_arg(ap, int);
af = va_arg(ap, int);
errp = va_arg(ap, int *);
*(struct hostent**)rval = NULL;
if ((fp = _files_open(errp)) == NULL)
return NULL;
return NS_UNAVAIL;
hp = NULL;
while (fgets(buf, sizeof(buf), fp)) {
line = buf;
@ -950,7 +899,8 @@ _files_ghbyaddr(const void *addr, int addrlen, int af, int *errp)
break;
}
fclose(fp);
return hp;
*(struct hostent **)rval = hp;
return (hp != NULL) ? NS_SUCCESS : NS_NOTFOUND;
}
#ifdef YP
@ -959,11 +909,18 @@ _files_ghbyaddr(const void *addr, int addrlen, int af, int *errp)
*
* XXX actually a hack, these are INET4 specific.
*/
static struct hostent *
_nis_ghbyname(const char *name, int af, int *errp)
static int
_nis_ghbyname(void *rval, void *cb_data, va_list ap)
{
const char *name;
int af;
int *errp;
struct hostent *hp = NULL;
name = va_arg(ap, const char *);
af = va_arg(ap, int);
errp = va_arg(ap, int *);
if (af == AF_UNSPEC)
af = AF_INET;
if (af == AF_INET) {
@ -971,21 +928,32 @@ _nis_ghbyname(const char *name, int af, int *errp)
if (hp != NULL)
hp = _hpcopy(hp, errp);
}
return (hp);
*(struct hostent **)rval = hp;
return (hp != NULL) ? NS_SUCCESS : NS_NOTFOUND;
}
static struct hostent *
_nis_ghbyaddr(const void *addr, int addrlen, int af, int *errp)
static int
_nis_ghbyaddr(void *rval, void *cb_data, va_list ap)
{
const void *addr;
int addrlen;
int af;
int *errp;
struct hostent *hp = NULL;
addr = va_arg(ap, const void *);
addrlen = va_arg(ap, int);
af = va_arg(ap, int);
if (af == AF_INET) {
hp = _gethostbynisaddr(addr, addrlen, af);
if (hp != NULL)
hp = _hpcopy(hp, errp);
}
return (hp);
*(struct hostent **)rval = hp;
return (hp != NULL) ? NS_SUCCESS : NS_NOTFOUND;
}
#endif
@ -1486,14 +1454,21 @@ _res_search_multi(name, rtl, errp)
return (NULL);
}
static struct hostent *
_dns_ghbyname(const char *name, int af, int *errp)
static int
_dns_ghbyname(void *rval, void *cb_data, va_list ap)
{
const char *name;
int af;
int *errp;
struct __res_type_list *rtl, rtl4;
#ifdef INET6
struct __res_type_list rtl6;
#endif
name = va_arg(ap, const char *);
af = va_arg(ap, int);
errp = va_arg(ap, int *);
#ifdef INET6
switch (af) {
case AF_UNSPEC:
@ -1514,12 +1489,17 @@ _dns_ghbyname(const char *name, int af, int *errp)
SLIST_NEXT(&rtl4, rtl_entry) = NULL; rtl4.rtl_type = T_A;
rtl = &rtl4;
#endif
return(_res_search_multi(name, rtl, errp));
*(struct hostent **)rval = _res_search_multi(name, rtl, errp);
return (*(struct hostent **)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND;
}
static struct hostent *
_dns_ghbyaddr(const void *addr, int addrlen, int af, int *errp)
static int
_dns_ghbyaddr(void *rval, void *cb_data, va_list ap)
{
const void *addr;
int addrlen;
int af;
int *errp;
int n;
struct hostent *hp;
u_char c, *cp;
@ -1533,16 +1513,23 @@ _dns_ghbyaddr(const void *addr, int addrlen, int af, int *errp)
char qbuf[MAXDNAME+1];
char *hlist[2];
addr = va_arg(ap, const void *);
addrlen = va_arg(ap, int);
af = va_arg(ap, int);
errp = va_arg(ap, int *);
*(struct hostent **)rval = NULL;
#ifdef INET6
/* XXX */
if (af == AF_INET6 && IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)addr))
return NULL;
return NS_NOTFOUND;
#endif
if ((_res.options & RES_INIT) == 0) {
if (res_init() < 0) {
*errp = h_errno;
return NULL;
return NS_UNAVAIL;
}
}
memset(&hbuf, 0, sizeof(hbuf));
@ -1585,17 +1572,18 @@ _dns_ghbyaddr(const void *addr, int addrlen, int af, int *errp)
n = res_query(qbuf, C_IN, T_PTR, buf.buf, sizeof buf.buf);
if (n < 0) {
*errp = h_errno;
return NULL;
return NS_UNAVAIL;
}
hp = getanswer(&buf, n, qbuf, T_PTR, &hbuf, errp);
if (!hp)
return NULL;
return NS_NOTFOUND;
hbuf.h_addrtype = af;
hbuf.h_length = addrlen;
hbuf.h_addr_list = hlist;
hlist[0] = (char *)addr;
hlist[1] = NULL;
return _hpcopy(&hbuf, errp);
*(struct hostent **)rval = _hpcopy(&hbuf, errp);
return NS_SUCCESS;
}
static void

231
lib/libc/net/nsdispatch.3 Normal file
View File

@ -0,0 +1,231 @@
.\" $NetBSD: nsdispatch.3,v 1.8 1999/03/22 19:44:53 garbled Exp $
.\" $FreeBSD$
.\"
.\" Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
.\" by Luke Mewburn.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the NetBSD
.\" Foundation, Inc. and its contributors.
.\" 4. Neither the name of The NetBSD Foundation nor the names of its
.\" contributors may be used to endorse or promote products derived
.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd January 19, 1999
.Dt NSDISPATCH 3
.Os
.Sh NAME
.Nm nsdispatch
.Nd name-service switch dispatcher routine
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.Fd #include <nsswitch.h>
.Ft int
.Fo nsdispatch
.Fa "void *retval"
.Fa "const ns_dtab dtab[]"
.Fa "const char *database"
.Fa "const char *method"
.Fa "const ns_src defaults[]"
.Fa "..."
.Fc
.Sh DESCRIPTION
The
.Fn nsdispatch
function invokes the callback functions specified in
.Va dtab
in the order given in
.Pa /etc/nsswitch.conf
for the database
.Va database
until a successful entry is found.
.Pp
.Va retval
is passed to each callback function to modify as necessary
(to pass back to the caller of
.Fn nsdispatch )
.Pp
.Va dtab
is an array of
.Va ns_dtab
structures, which have the following format:
.Bd -literal -offset indent
typedef struct {
const char *src;
int (*cb)(void *retval, void *cb_data, va_list ap);
void *cb_data;
} ns_dtab;
.Ed
.Pp
.Bd -ragged -offset indent
For each source type that is implemented, an entry with
.Va src
set to the name of the source,
.Va cb
defined as a function which handles that source, and
.Va cb_data
is used to pass arbritrary data to the callback function.
The last entry in
.Va dtab
should contain
.Dv NULL
values for
.Va src ,
.Va cb ,
and
.Va cb_data .
.Ed
.Pp
.Va method
is usually the name of the function calling
.Fn nsdispatch .
When dynamic loading is supported, a symbol constructed from
.Va database ,
the current source, and
.Va method
will be used as the name to invoke the dynamically loaded function.
.Pp
.Va defaults
contains a list of default sources to try in the case of
a missing or corrupt
.Xr nsswitch.conf 5 ,
or if there isn't a relevant entry for
.Va database .
It is an array of
.Va ns_src
structures, which have the following format:
.Bd -literal -offset indent
typedef struct {
const char *src;
u_int32_t flags;
} ns_src;
.Ed
.Pp
.Bd -ragged -offset indent
For each default source type, an entry with
.Va src
set to the name of the source, and
.Va flags
set to the relevant flags
(usually
.Dv NS_SUCCESS ;
refer to
.Sx Callback return values
for more information).
The last entry in
.Va defaults
should have
.Va src
set to
.Dv NULL
and
.Va flags
set to 0.
.Pp
For convenience, a global variable defined as:
.Dl extern const ns_src __nsdefaultsrc[];
exists which contains a single default entry for
.Sq files
for use by callers which don't require complicated default rules.
.Ed
.Pp
.Va Sq ...
are optional extra arguments, which
are passed to the appropriate callback function as a variable argument
list of the type
.Va va_list .
.Ss Valid source types
Whilst there is support for arbitrary sources, the following
#defines for commonly implementated sources are available:
.Bl -column NS_COMPAT COMPAT -offset indent
.Sy #define value
.It NSSRC_FILES "files"
.It NSSRC_DNS "dns"
.It NSSRC_NIS "nis"
.It NSSRC_COMPAT "compat"
.El
.Pp
Refer to
.Xr nsswitch.conf 5
for a complete description of what each source type is.
.Pp
.Ss Callback return values
The callback functions should return one of the following values
depending upon status of the lookup:
.Bl -column NS_NOTFOUND -offset indent
.Sy "Return value" Status code
.It NS_SUCCESS success
.It NS_NOTFOUND notfound
.It NS_UNAVAIL unavail
.It NS_TRYAGAIN tryagain
.El
.Pp
Refer to
.Xr nsswitch.conf 5
for a complete description of what each status code is.
.Pp
.Nm
returns the value of the callback that caused the dispatcher to finish,
or NS_NOTFOUND otherwise.
.Sh SEE ALSO
.Xr hesiod 3 ,
.Xr stdarg 3 ,
.Xr ypclnt 3 ,
.Xr nsswitch.conf 5
.Sh HISTORY
The
.Nm
routines first appeared in
.Fx 4.1 .
They were imported from the
.Nx
Project,
where they appeared first in
.Nx 1.4 .
.Sh AUTHORS
Luke Mewburn
.Aq lukem@netbsd.org
wrote this freely distributable name-service switch implementation,
using ideas from the
.Tn ULTRIX
.Xr svc.conf 5
and
.Tn Solaris
.Xr nsswitch.conf 4
manual pages.
.Sh BUGS
The
.Nm
routines are not thread safe.
This will be rectified in the future.
.Pp
Currently there is no support for dynamically loadable dispatcher callback
functions.
It is anticipated that this will be added in the future in the back-end
without requiring changes to code that invokes
.Fn nsdispatch .

270
lib/libc/net/nsdispatch.c Normal file
View File

@ -0,0 +1,270 @@
/* $NetBSD: nsdispatch.c,v 1.9 1999/01/25 00:16:17 lukem Exp $ */
/*-
* Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Luke Mewburn.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
static char *rcsid =
"$FreeBSD$";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <err.h>
#include <fcntl.h>
#define _NS_PRIVATE
#include <nsswitch.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/*
* default sourcelist: `files'
*/
const ns_src __nsdefaultsrc[] = {
{ NSSRC_FILES, NS_SUCCESS },
{ 0 },
};
static int _nsmapsize = 0;
static ns_dbt *_nsmap = NULL;
/*
* size of dynamic array chunk for _nsmap and _nsmap[x].srclist
*/
#define NSELEMSPERCHUNK 8
int _nscmp __P((const void *, const void *));
int
_nscmp(a, b)
const void *a;
const void *b;
{
return (strcasecmp(((const ns_dbt *)a)->name,
((const ns_dbt *)b)->name));
}
void
_nsdbtaddsrc(dbt, src)
ns_dbt *dbt;
const ns_src *src;
{
if ((dbt->srclistsize % NSELEMSPERCHUNK) == 0) {
dbt->srclist = (ns_src *)realloc(dbt->srclist,
(dbt->srclistsize + NSELEMSPERCHUNK) * sizeof(ns_src));
if (dbt->srclist == NULL)
err(1, "nsdispatch: memory allocation failure");
}
memmove(&dbt->srclist[dbt->srclistsize++], src, sizeof(ns_src));
}
void
_nsdbtdump(dbt)
const ns_dbt *dbt;
{
int i;
printf("%s (%d source%s):", dbt->name, dbt->srclistsize,
dbt->srclistsize == 1 ? "" : "s");
for (i = 0; i < dbt->srclistsize; i++) {
printf(" %s", dbt->srclist[i].name);
if (!(dbt->srclist[i].flags &
(NS_UNAVAIL|NS_NOTFOUND|NS_TRYAGAIN)) &&
(dbt->srclist[i].flags & NS_SUCCESS))
continue;
printf(" [");
if (!(dbt->srclist[i].flags & NS_SUCCESS))
printf(" SUCCESS=continue");
if (dbt->srclist[i].flags & NS_UNAVAIL)
printf(" UNAVAIL=return");
if (dbt->srclist[i].flags & NS_NOTFOUND)
printf(" NOTFOUND=return");
if (dbt->srclist[i].flags & NS_TRYAGAIN)
printf(" TRYAGAIN=return");
printf(" ]");
}
printf("\n");
}
const ns_dbt *
_nsdbtget(name)
const char *name;
{
static time_t confmod;
struct stat statbuf;
ns_dbt dbt;
extern FILE *_nsyyin;
extern int _nsyyparse __P((void));
dbt.name = name;
if (confmod) {
if (stat(_PATH_NS_CONF, &statbuf) == -1)
return (NULL);
if (confmod < statbuf.st_mtime) {
int i, j;
for (i = 0; i < _nsmapsize; i++) {
for (j = 0; j < _nsmap[i].srclistsize; j++) {
if (_nsmap[i].srclist[j].name != NULL) {
/*LINTED const cast*/
free((void *)
_nsmap[i].srclist[j].name);
}
}
if (_nsmap[i].srclist)
free(_nsmap[i].srclist);
if (_nsmap[i].name) {
/*LINTED const cast*/
free((void *)_nsmap[i].name);
}
}
if (_nsmap)
free(_nsmap);
_nsmap = NULL;
_nsmapsize = 0;
confmod = 0;
}
}
if (!confmod) {
if (stat(_PATH_NS_CONF, &statbuf) == -1)
return (NULL);
_nsyyin = fopen(_PATH_NS_CONF, "r");
if (_nsyyin == NULL)
return (NULL);
_nsyyparse();
(void)fclose(_nsyyin);
qsort(_nsmap, (size_t)_nsmapsize, sizeof(ns_dbt), _nscmp);
confmod = statbuf.st_mtime;
}
return (bsearch(&dbt, _nsmap, (size_t)_nsmapsize, sizeof(ns_dbt),
_nscmp));
}
void
_nsdbtput(dbt)
const ns_dbt *dbt;
{
int i;
for (i = 0; i < _nsmapsize; i++) {
if (_nscmp(dbt, &_nsmap[i]) == 0) {
/* overwrite existing entry */
if (_nsmap[i].srclist != NULL)
free(_nsmap[i].srclist);
memmove(&_nsmap[i], dbt, sizeof(ns_dbt));
return;
}
}
if ((_nsmapsize % NSELEMSPERCHUNK) == 0) {
_nsmap = (ns_dbt *)realloc(_nsmap,
(_nsmapsize + NSELEMSPERCHUNK) * sizeof(ns_dbt));
if (_nsmap == NULL)
err(1, "nsdispatch: memory allocation failure");
}
memmove(&_nsmap[_nsmapsize++], dbt, sizeof(ns_dbt));
}
int
#if __STDC__
nsdispatch(void *retval, const ns_dtab disp_tab[], const char *database,
const char *method, const ns_src defaults[], ...)
#else
nsdispatch(retval, disp_tab, database, method, defaults, va_alist)
void *retval;
const ns_dtab disp_tab[];
const char *database;
const char *method;
const ns_src defaults[];
va_dcl
#endif
{
va_list ap;
int i, curdisp, result;
const ns_dbt *dbt;
const ns_src *srclist;
int srclistsize;
dbt = _nsdbtget(database);
if (dbt != NULL) {
srclist = dbt->srclist;
srclistsize = dbt->srclistsize;
} else {
srclist = defaults;
srclistsize = 0;
while (srclist[srclistsize].name != NULL)
srclistsize++;
}
result = 0;
for (i = 0; i < srclistsize; i++) {
for (curdisp = 0; disp_tab[curdisp].src != NULL; curdisp++)
if (strcasecmp(disp_tab[curdisp].src,
srclist[i].name) == 0)
break;
result = 0;
if (disp_tab[curdisp].callback) {
#if __STDC__
va_start(ap, defaults);
#else
va_start(ap);
#endif
result = disp_tab[curdisp].callback(retval,
disp_tab[curdisp].cb_data, ap);
va_end(ap);
if (result & srclist[i].flags) {
break;
}
}
}
return (result ? result : NS_NOTFOUND);
}

116
lib/libc/net/nslexer.l Normal file
View File

@ -0,0 +1,116 @@
%{
/* $NetBSD: nslexer.l,v 1.3 1999/01/25 00:16:17 lukem Exp $ */
/*-
* Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Luke Mewburn.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
static char *rcsid =
"$FreeBSD$";
#endif /* LIBC_SCCS and not lint */
#include <ctype.h>
#include <err.h>
#define _NS_PRIVATE
#include <nsswitch.h>
#include <string.h>
#include "nsparser.h"
#define YY_NO_UNPUT
%}
%option yylineno
BLANK [ \t]
CR \n
STRING [a-zA-Z][a-zA-Z0-9_]*
%%
{BLANK}+ ; /* skip whitespace */
#.* ; /* skip comments */
\\{CR} ; /* allow continuation */
{CR} return NL;
[sS][uU][cC][cC][eE][sS][sS] return SUCCESS;
[uU][nN][aA][vV][aA][iI][lL] return UNAVAIL;
[nN][oO][tT][fF][oO][uU][nN][dD] return NOTFOUND;
[tT][rR][yY][aA][gG][aA][iI][nN] return TRYAGAIN;
[rR][eE][tT][uU][rR][nN] return RETURN;
[cC][oO][nN][tT][iI][nN][uU][eE] return CONTINUE;
{STRING} {
char *p;
int i;
if ((p = strdup(yytext)) == NULL)
err(1, "nsdispatch: memory allocation failure");
for (i = 0; i < strlen(p); i++) {
if (isupper((unsigned char)p[i]))
p[i] = tolower((unsigned char)p[i]);
}
_nsyylval.str = p;
return STRING;
}
[:=\[\]] return yytext[0];
. ; /* ignore all else */
%%
#undef _nsyywrap
int
_nsyywrap()
{
return 1;
} /* _nsyywrap */
void
_nsyyerror(msg)
const char *msg;
{
warnx("%s line %d: %s at '%s'", _PATH_NS_CONF, yylineno, msg, yytext);
} /* _nsyyerror */

175
lib/libc/net/nsparser.y Normal file
View File

@ -0,0 +1,175 @@
%{
/* $NetBSD: nsparser.y,v 1.3 1999/01/25 00:16:18 lukem Exp $ */
/*-
* Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Luke Mewburn.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
static char *rcsid =
"$FreeBSD$";
#endif /* LIBC_SCCS and not lint */
#include <err.h>
#define _NS_PRIVATE
#include <nsswitch.h>
#include <stdio.h>
#include <string.h>
static void _nsaddsrctomap __P((const char *));
static ns_dbt curdbt;
static ns_src cursrc;
%}
%union {
char *str;
int mapval;
}
%token NL
%token SUCCESS UNAVAIL NOTFOUND TRYAGAIN
%token RETURN CONTINUE
%token <str> STRING
%type <mapval> Status Action
%%
File
: /* empty */
| Lines
;
Lines
: Entry
| Lines Entry
;
Entry
: NL
| Database ':' NL
| Database ':' Srclist NL
{
_nsdbtput(&curdbt);
}
;
Database
: STRING
{
curdbt.name = yylval.str;
curdbt.srclist = NULL;
curdbt.srclistsize = 0;
}
;
Srclist
: Item
| Srclist Item
;
Item
: STRING
{
cursrc.flags = NS_SUCCESS;
_nsaddsrctomap($1);
}
| STRING '[' { cursrc.flags = NS_SUCCESS; } Criteria ']'
{
_nsaddsrctomap($1);
}
;
Criteria
: Criterion
| Criteria Criterion
;
Criterion
: Status '=' Action
{
if ($3) /* if action == RETURN set RETURN bit */
cursrc.flags |= $1;
else /* else unset it */
cursrc.flags &= ~$1;
}
;
Status
: SUCCESS { $$ = NS_SUCCESS; }
| UNAVAIL { $$ = NS_UNAVAIL; }
| NOTFOUND { $$ = NS_NOTFOUND; }
| TRYAGAIN { $$ = NS_TRYAGAIN; }
;
Action
: RETURN { $$ = 1L; }
| CONTINUE { $$ = 0L; }
;
%%
static void
_nsaddsrctomap(elem)
const char *elem;
{
int i, lineno;
extern int _nsyylineno;
extern char * _nsyytext;
lineno = _nsyylineno - (*_nsyytext == '\n' ? 1 : 0);
if (curdbt.srclistsize > 0) {
if ((strcasecmp(elem, NSSRC_COMPAT) == 0) ||
(strcasecmp(curdbt.srclist[0].name, NSSRC_COMPAT) == 0)) {
/* XXX: syslog the following */
warnx("%s line %d: 'compat' used with other sources",
_PATH_NS_CONF, lineno);
return;
}
}
for (i = 0; i < curdbt.srclistsize; i++) {
if (strcasecmp(curdbt.srclist[i].name, elem) == 0) {
/* XXX: syslog the following */
warnx("%s line %d: duplicate source '%s'",
_PATH_NS_CONF, lineno, elem);
return;
}
}
cursrc.name = elem;
_nsdbtaddsrc(&curdbt, &cursrc);
}

View File

@ -78,7 +78,6 @@ static HitList etc_files [] = {
{ JUST_COPY, "gettytab", TRUE, NULL },
{ JUST_COPY, "gnats", TRUE, NULL },
{ JUST_COPY, "group", FALSE, NULL },
{ JUST_COPY, "host.conf", TRUE, NULL },
{ JUST_COPY, "hosts", TRUE, NULL },
{ JUST_COPY, "hosts.equiv", TRUE, NULL },
{ JUST_COPY, "hosts.lpd", TRUE, NULL },
@ -96,6 +95,7 @@ static HitList etc_files [] = {
{ JUST_COPY, "namedb", TRUE, NULL },
{ JUST_COPY, "networks", TRUE, NULL },
{ JUST_COPY, "newsyslog.conf", TRUE, NULL },
{ JUST_COPY, "nsswitch.conf", TRUE, NULL },
{ JUST_COPY, "pam.conf", TRUE, NULL },
{ JUST_COPY, "passwd", TRUE, NULL },
{ JUST_COPY, "periodic", TRUE, NULL },

View File

@ -62,17 +62,16 @@ the old distribution are not deleted.
System configuration is preserved by retaining and restoring the
previous version of the following files:
Xaccel.ini, XF86Config, adduser.conf, aliases, aliases.db, amd.map,
aliases, aliases.db, auth.conf, crontab, csh.cshrc, csh.login,
csh.logout, cvsupfile, disktab, dm.conf, dumpdates, exports,
fbtab, fstab, ftpusers, gettytab, gnats, group, host.conf, hosts,
hosts.equiv, hosts.lpd, inetd.conf, kerberosIV, localtime, login.access,
login.conf, mail.rc, make.conf, manpath.config, master.passwd, modems,
motd, namedb, networks, newsyslog.conf, pam.conf, passwd, periodic,
phones, ppp, printcap, profile, protocols, pwd.db, rc.conf.local,
rc.firewall, rc.local, remote, resolv.conf, rmt, sendmail.cf,
sendmail.cw, services, shells, skeykeys, spwd.db, syslog.conf,
ttys, uucp
Xaccel.ini, adduser.conf, aliases, aliases.db, amd.map, crontab,
csh.cshrc, csh.login, csh.logout, daily, disktab, dm.conf, exports,
fbtab, fstab, ftpusers, gettytab, gnats, group, hosts, hosts.equiv,
hosts.lpd, inetd.conf, kerberosIV, localtime, login.access,
mail.rc, make.conf, manpath.config, master.passwd, mib.txt, modems,
monthly, motd, namedb, networks, nsswitch.conf, passwd, phones,
ppp, printcap, profile, protocols, pwd.db, rc, rc.firewall,
rc.i386, rc.local, rc.network, rc.conf, remote, resolv.conf, rmt,
security, sendmail.cf, services, shells, skeykeys, spwd.db,
supfile, syslog.conf, termcap, ttys, uucp, weekly
The versions of these files which correspond to the new version are
moved to /etc/upgrade/. The system administrator may peruse these new

View File

@ -11,7 +11,7 @@ SRCS+= alloc.c bpf.c conflex.c convert.c dispatch.c errwarn.c ethernet.c \
parse.c print.c raw.c socket.c tables.c tree.c upf.c
CFLAGS+= -I${DIST_DIR}/includes -I${DIST_DIR}
CFLAGS+= -DCLIENT_PATH='"PATH=/sbin:/bin:/usr/sbin:/usr/bin"'
CFLAGS+= -DCLIENT_PATH='"PATH=/sbin:/bin:/usr/sbin:/usr/bin"' -Dwarn=dhcp_warn
MAN5= dhclient.conf.5 dhclient.leases.5 dhcp-options.5
MAN8= dhclient.8 dhclient-script.8

View File

@ -20,7 +20,6 @@ fbtab - configuration file for login(1)
ftpusers - user restriction file for ftpd(8)
gettytab - defines port configuration for getty(8)
group - group permissions file (see group(5))
host.conf - defines name resolution order for gethostbyname(3)
hosts - see hosts(5)
hosts.equiv - defines system-wide trusted hosts (see ruserok(3))
hosts.lpd - defines trusted hosts for lpd(8)
@ -36,6 +35,7 @@ motd - sample Message of the Day
netstart - network startup script run from /etc/rc
networks - see networks(5)
newsyslog.conf - configuration for system log file rotator newsyslog(8)
nsswitch.conf - name-service switch config file (see nsswitch.conf(5))
pam.conf - configuration file for pam(8)
pccard_ether - confiuration script for ethernet pccards (see pccardd(8))
phones - phone number database for tip(1)

View File

@ -57,14 +57,8 @@ daemon makes direct
library calls since there are no
functions in the standard C library for reading bootparams.
.Tn NIS
support for the hosts, services and rpc databases is enabled by
uncommenting the
.Em nis
line in
.Pa /etc/host.conf .
.Tn NIS
support for the remaining services is
activated by adding a special '+' entry to the appropriate file.
support is enabled in
.Xr nsswitch.conf .
.Pp
The
.Nm YP

View File

@ -4,11 +4,12 @@
#MISSING: dump.5 plot.5
MAN5= a.out.5 acct.5 core.5 devfs.5 dir.5 disktab.5 ethers.5 \
elf.5 fbtab.5 fdesc.5 forward.5 fs.5 fstab.5 group.5 \
hesiod.conf.5 \
hosts.5 hosts.equiv.5 hosts.lpd.5 intro.5 kernfs.5 link.5 \
linprocfs.5 mailer.conf.5 motd.5 networks.5 passwd.5 pbm.5 \
periodic.conf.5 phones.5 procfs.5 protocols.5 rc.conf.5 \
remote.5 resolver.5 services.5 shells.5 stab.5 sysctl.conf.5 \
types.5 utmp.5
linprocfs.5 mailer.conf.5 motd.5 networks.5 nsswitch.conf.5 \
passwd.5 pbm.5 periodic.conf.5 \
phones.5 procfs.5 protocols.5 rc.conf.5 remote.5 resolver.5 \
services.5 shells.5 stab.5 sysctl.conf.5 types.5 utmp.5
MLINKS= dir.5 dirent.5
MLINKS+=fs.5 inode.5

View File

@ -39,6 +39,14 @@
.Nm group
.Nd format of the group permissions file
.Sh DESCRIPTION
The
.Nm
file is the local source of group information. It
can be used in conjunction with the Hesiod domain
`group', and the NIS maps `group.byname' and `group.bygid',
as controlled by
.Xr nsswitch.conf 5 .
.Pp
The file
.Aq Pa /etc/group
consists of newline separated
@ -107,28 +115,6 @@ entry and does not need to be added to that group in the
.\" char **gr_mem; /* group members */
.\" };
.\" .Ed
.Sh YP/NIS INTERACTION
The
.Pa /etc/group
file can be configured to enable the YP/NIS group database.
An entry whose
.Ar name
field consists of a plus sign (`+') followed by a group name, will be
replaced internally to the C library with the YP/NIS group entry for the
named group. An entry whose
.Ar name
field consists of a single plus sign with no group name following,
will be replaced with the entire YP/NIS
.Dq Li group.byname
map.
.Pp
If the YP/NIS group database is enabled for any reason, all reverse
lookups (i.e.,
.Fn getgrgid )
will use the entire database, even if only a few groups are enabled.
Thus, the group name returned by
.Fn getgrgid
is not guaranteed to have a valid forward mapping.
.Sh LIMITS
There are various limitations which are explained in
the function where they occur; see section
@ -156,6 +142,7 @@ may still have this limits.
.Xr getgrent 3 ,
.Xr initgroups 3 ,
.Xr yp 4 ,
.Xr nsswitch.conf 5 ,
.Xr passwd 5
.Sh BUGS
The
@ -168,10 +155,5 @@ A
.Nm
file format appeared in
.At v6 .
The YP/NIS functionality is modeled after
.Tn SunOS
and first appeared in
.Tn FreeBSD
1.1.
Support for comments first appeared in
.Fx 3.0 .

View File

@ -0,0 +1,53 @@
.\" $NetBSD: hesiod.conf.5,v 1.2 1999/01/25 22:37:06 lukem Exp $
.\" $FreeBSD$
.\"
.\" from: #Id: hesiod.conf.5,v 1.1 1996/12/08 21:36:38 ghudson Exp #
.\"
.\" Copyright 1996 by the Massachusetts Institute of Technology.
.\"
.\" Permission to use, copy, modify, and distribute this
.\" software and its documentation for any purpose and without
.\" fee is hereby granted, provided that the above copyright
.\" notice appear in all copies and that both that copyright
.\" notice and this permission notice appear in supporting
.\" documentation, and that the name of M.I.T. not be used in
.\" advertising or publicity pertaining to distribution of the
.\" software without specific, written prior permission.
.\" M.I.T. makes no representations about the suitability of
.\" this software for any purpose. It is provided "as is"
.\" without express or implied warranty.
.\"
.TH HESIOD.CONF 5 "30 November 1996"
.SH NAME
hesiod.conf \- Configuration file for the Hesiod library
.SH DESCRIPTION
The file hesiod.conf determines the behavior of the Hesiod library.
Blank lines and lines beginning with a `#' character are ignored. All
other lines should be of the form
.I variable
=
.IR value ,
where the value should be a single word. Possible variables and
values are:
.IP lhs
Specifies the domain prefix used for Hesiod queries. In almost all
cases, you should specify ``lhs=.ns''. The default value if you do
not specify an lhs value is no domain prefix, which is not compatible
with most Hesiod domains.
.IP rhs
Specifies the default Hesiod domain; this value may be overridden by
the
.B HES_DOMAIN
environment variable. You must specify an rhs line for the Hesiod
library to work properly.
.IP classes
Specifies which DNS classes Hesiod should do lookups in. Possible
values are IN (the preferred class) and HS (the deprecated class,
still used by some sites). You may specify both classes separated by
a comma to try one class first and then the other if no entry is
available in the first class. The default value of the classes
variable is ``IN,HS''.
.SH SEE ALSO
hesiod(3)
.SH BUGS
The default value for ``lhs'' should probably be more reasonable.

View File

@ -43,6 +43,9 @@ The
.Nm hosts
file contains information regarding
the known hosts on the network.
It can be used in conjunction with DNS, and the NIS
maps `hosts.byaddr' and `hosts.byname', as controlled by
.Xr nsswitch.conf 5 .
For each host a single line should be present
with the following information:
.Bd -unfilled -offset indent
@ -98,6 +101,7 @@ file resides in
.El
.Sh SEE ALSO
.Xr gethostbyname 3 ,
.Xr nsswitch.conf 5 ,
.Xr ifconfig 8 ,
.Xr named 8
.Rs

View File

@ -0,0 +1,266 @@
.\" $NetBSD: nsswitch.conf.5,v 1.14 1999/03/17 20:19:47 garbled Exp $
.\" $FreeBSD$
.\"
.\" Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
.\" by Luke Mewburn.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by Luke Mewburn.
.\" 4. The name of the author may not be used to endorse or promote products
.\" derived from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
.\" OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
.\" TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
.\" USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd January 22, 1998
.Dt NSSWITCH.CONF 5
.Os
.Sh NAME
.Nm nsswitch.conf
.Nd name-service switch configuration file
.Sh DESCRIPTION
The
.Nm
file specifies how the
.Xr nsdispatch 3
(name-service switch dispatcher) routines in the C library should operate.
.Pp
The configuration file controls how a process looks up various databases
containing information regarding hosts, users (passwords), groups, etc.
Each database comes from a source (such as local files, DNS, and
.Tn NIS ) ,
and the order to look up the sources is specified in
.Nm nsswitch.conf .
.Pp
Each entry in
.Nm
consists of a database name, and a space separated list of sources.
Each source can have an optional trailing criterion that determines
whether the next listed source is used, or the search terminates at
the current source.
Each criterion consists of one or more status codes, and actions to
take if that status code occurs.
.Ss Sources
The following sources are implemented:
.Bl -column "compat" -offset indent -compact
.Sy Source Description
.It files Local files, such as
.Pa /etc/hosts ,
and
.Pa /etc/passwd .
.It dns Internet Domain Name System.
.Dq hosts
and
.Sq networks
use
.Sy IN
class entries, all other databases use
.Sy HS
class (Hesiod) entries.
.It nis NIS (formerly YP)
.It compat support
.Sq +/-
in the
.Dq passwd
and
.Dq group
databases.
If this is present, it must be the only source for that entry.
.El
.Ss Databases
The following databases are used by the following C library functions:
.Bl -column "networks" -offset indent -compact
.Sy Database Used by
.It group
.Xr getgrent 3
.It hosts
.Xr gethostbyname 3
.It networks
.Xr getnetbyname 3
.It passwd
.Xr getpwent 3
.It shells
.Xr getusershell 3
.El
.Ss Status codes
The following status codes are available:
.Bl -column "tryagain" -offset indent -compact
.Sy Status Description
.It success The requested entry was found.
.It notfound The entry is not present at this source.
.It tryagain The source is busy, and may respond to retries.
.It unavail The source is not responding, or entry is corrupt.
.El
.Ss Actions
For each of the status codes, one of two actions is possible:
.Bl -column "continue" -offset indent -compact
.Sy Action Description
.It continue Try the next source
.It return Return with the current result
.El
.Ss Format of file
A
.Tn BNF
description of the syntax of
.Nm
is:
.Bl -column "<criterion>" -offset indent
.It <entry> ::=
<database> ":" [<source> [<criteria>]]*
.It <criteria> ::=
"[" <criterion>+ "]"
.It <criterion> ::=
<status> "=" <action>
.It <status> ::=
"success" | "notfound" | "unavail" | "tryagain"
.It <action> ::=
"return" | "continue"
.El
.Pp
Each entry starts on a new line in the file.
A
.Sq #
delimits a comment to end of line.
Blank lines are ignored.
A
.Sq \e
at the end of a line escapes the newline, and causes the next line to
be a continuation of the current line.
All entries are case-insensitive.
.Pp
The default criteria is to return on
.Dq success ,
and continue on anything else (i.e,
.Li [success=return notfound=continue unavail=continue tryagain=continue]
).
.Ss Compat mode: +/- syntax
In historical multi-source implementations, the
.Sq +
and
.Sq -
characters are used to specify the importing of user password and
group information from
.Tn NIS .
Although
.Nm
provides alternative methods of accessing distributed sources such as
.Tn NIS ,
specifying a sole source of
.Dq compat
will provide the historical behaviour.
.Pp
An alternative source for the information accessed via
.Sq +/-
can be used by specifying
.Dq passwd_compat: source .
.Dq source
in this case can be
.Sq dns ,
.Sq nis ,
or
any other source except for
.Sq files
and
.Sq compat .
.Ss Notes
Historically, many of the databases had enumeration functions, often of
the form
.Fn getXXXent .
These made sense when the databases were in local files, but don't make
sense or have lesser relevance when there are possibly multiple sources,
each of an unknown size.
The interfaces are still provided for compatibility, but the source
may not be able to provide complete entries, or duplicate entries may
be retrieved if multiple sources that contain similar information are
specified.
.Pp
To ensure compatibility with previous and current implementations, the
.Dq compat
source must appear alone for a given database.
.Ss Default source lists
If, for any reason,
.Nm nsswitch.conf
doesn't exist, or it has missing or corrupt entries,
.Xr nsdispatch 3
will default to an entry of
.Dq files
for the requested database.
Exceptions are:
.Bl -column passwd_compat "dns files" -offset indent
.Sy Database Default source list
.It group compat
.It group_compat nis
.It hosts dns files
.It passwd compat
.It passwd_compat nis
.El
.Sh FILES
.Bl -tag -width /etc/nsswitch.conf -compact
.It Pa /etc/nsswitch.conf
The file
.Nm
resides in
.Pa /etc .
.El
.Sh EXAMPLES
To lookup hosts in
.Pa /etc/hosts
and then from the DNS, and lookup user information from
.Tn NIS
then files, use:
.Bl -column "passwd:" -offset indent
.It hosts: files dns
.It passwd: nis [notfound=return] files
.It group: nis [notfound=return] files
.El
.Pp
The criteria
.Dq [notfound=return]
sets a policy of "if the user is notfound in nis, don't try files."
This treats nis as the authoritive source of information, except
when the server is down.
.Sh SEE ALSO
.Xr nsdispatch 3 ,
.Xr resolv.conf 5 ,
.Xr named 8 ,
.Xr ypbind 8
.Sh HISTORY
The
.Nm
file format first appeared in
.Fx 4.1 .
It was imported from the
.Nx
Project, where it appeared first in
.Nx 1.4 .
.Sh AUTHORS
Luke Mewburn
.Aq lukem@netbsd.org
wrote this freely distributable name-service switch implementation,
using ideas from the
.Tn ULTRIX
.Xr svc.conf 5
and
.Tn Solaris
.Xr nsswitch.conf 4
manual pages.

View File

@ -1,5 +1,8 @@
.\" $NetBSD: passwd.5,v 1.12.2.2 1999/12/17 23:14:50 he Exp $
.\"
.\" Copyright (c) 1988, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\" Portions Copyright (c) 1994, Jason Downs. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@ -32,20 +35,37 @@
.\" From: @(#)passwd.5 8.1 (Berkeley) 6/5/93
.\" $FreeBSD$
.\"
.Dd September 29, 1994
.Dd January 16, 1999
.Dt PASSWD 5
.Os
.Sh NAME
.Nm passwd
.Nm passwd ,
.Nm master.passwd
.Nd format of the password file
.Sh DESCRIPTION
The
.Nm passwd
files are files consisting of newline separated records, one per user,
containing ten colon
.Pq Ql \&:
separated fields. These fields are as
follows:
files are the local source of password information.
They can be used in conjunction with the Hesiod domains
.Sq passwd
and
.Sq uid ,
and the
.Tn NIS
maps
.Sq passwd.byname ,
.Sq passwd.byuid ,
.Sq master.passwd.byname ,
and
.Sq master.passwd.byuid ,
as controlled by
.Xr nsswitch.conf 5 .
.Pp
The
.Nm master.passwd
file is readable only by root, and consists of newline separated
records, one per user, containing ten colon (``:'') separated
fields. These fields are as follows:
.Pp
.Bl -tag -width password -offset indent
.It name
@ -59,7 +79,7 @@ User's id.
.It gid
User's login group id.
.It class
User's login class.
User's general classification (unused).
.It change
Password change time.
.It expire
@ -72,9 +92,14 @@ User's home directory.
User's login shell.
.El
.Pp
Lines whose first non-whitespace character is a pound-sign (#)
are comments, and are ignored. Blank lines which consist
only of spaces, tabs or newlines are also ignored.
The
.Nm
file is generated from the
.Nm master.password
file by
.Xr pwd_mkdb 8 ,
has the class, change, and expire fields removed, and the password
field replaced by a ``*''.
.Pp
The
.Ar name
@ -85,17 +110,15 @@ across the system (and often across a group of systems) since they
control file access.
.Pp
While it is possible to have multiple entries with identical login names
and/or identical uids, it is usually a mistake to do so. Routines
and/or identical user id's, it is usually a mistake to do so. Routines
that manipulate these files will often return only one of the multiple
entries, and that one by random selection.
.Pp
The login name must never begin with a hyphen
.Pq Ql \&- ;
also, it is strongly
suggested that neither upper-case characters nor dots
.Pq Ql \&.
be part
of the name, as this tends to confuse mailers.
The login name must never begin with a hyphen (``-''); also, it is strongly
suggested that neither upper-case characters or dots (``.'') be part
of the name, as this tends to confuse mailers. No field may contain a
colon (``:'') as this has been used historically to separate the fields
in the user database.
.Pp
The password field is the
.Em encrypted
@ -106,73 +129,66 @@ field is empty, no password will be required to gain access to the
machine. This is almost invariably a mistake.
Because these files contain the encrypted user passwords, they should
not be readable by anyone without appropriate privileges.
Administrative accounts have a password field containing an asterisk
.Ql \&*
which disallows normal logins.
.Pp
The group field is the group that the user will be placed in upon login.
Although this system supports multiple groups (see
Since this system supports multiple groups (see
.Xr groups 1 )
this field indicates the user's primary group.
Secondary group memberships are selected in
.Pa /etc/group .
this field currently has little special meaning.
.Pp
The
.Ar class
field is a key for a user's login class.
Login classes are defined in
field is a key for a user's login class. Login classes
are defined in
.Xr login.conf 5 ,
which is a
which is a
.Xr termcap 5
style database of user attributes, accounting, resource and
environment settings.
style database of user attributes, accounting, resource,
and environment settings.
.Pp
The
.Ar change
field is the number in seconds,
.Dv GMT ,
from the epoch, until the
field is the number of seconds from the epoch,
.Dv UTC ,
until the
password for the account must be changed.
This field may be left empty or set to 0 to turn off the
password aging feature.
This field may be left empty to turn off the password aging feature.
.Pp
The
.Ar expire
field is the number in seconds,
.Dv GMT ,
from the epoch, until the
field is the number of seconds from the epoch,
.Dv UTC ,
until the
account expires.
This field may be left empty or set to 0 to turn off the account
aging feature.
This field may be left empty to turn off the account aging feature.
.Pp
The
.Ar gecos
field normally contains comma
.Pq Ql \&,
separated subfields as follows:
field normally contains comma (``,'') separated subfields as follows:
.Pp
.Bl -bullet -compact -offset indent
.It
.Bl -tag -width office -offset indent -compact
.It name
user's full name
.It
user's office location
.It
.It office
user's office number
.It wphone
user's work phone number
.It
.It hphone
user's home phone number
.El
.Pp
This information is used by the
The full name may contain a ampersand (``&'') which will be replaced by
the capitalized login name when the gecos field is displayed or used
by various programs such as
.Xr finger 1 ,
.Xr sendmail 8 ,
etc.
.Pp
The office and phone number subfields are used by the
.Xr finger 1
program, and the first field used by the system mailer.
If an ampersand
.Pq Ql \&&
character appears within the fullname field, programs that
use this field will substitute it with a capitalized version
of the account's login name.
program, and possibly other applications.
.Pp
The user's home directory is the full
.Tn UNIX
.Ux
path name where the user
will be placed on login.
.Pp
@ -182,589 +198,119 @@ If there is nothing in the
field, the Bourne shell
.Pq Pa /bin/sh
is assumed.
For security reasons, if the shell is set to a script that disallows
access to the system (the
.Xr nologin 8
script, for example), care should be taken not to import any environment
variables. With
.Xr sh 1 ,
this can be done by specifying the
.Fl p
flag.
Check the specific shell documentation to determine how this is
done with other shells.
.Sh YP/NIS INTERACTION
.Ss Enabling access to NIS passwd data
The system administrator can configure
.Tn FreeBSD
to use NIS/YP for
its password information by adding special records to the
.Pa /etc/master.passwd
file.
These entries should be added with
.Xr vipw 8
so that the changes can be properly merged with the hashed
password databases and the
.Pa /etc/passwd
file (
.Pa /etc/passwd
should never be edited manually). Alternatively, the administrator
can modify
.Pa /etc/master.passwd
in some other way and then manually update the password databases with
.Xr pwd_mkdb 8 .
.Pp
The simplest way to activate NIS is to add an empty record
with only a plus sign
.Pq Ql \&+
in the name field, such as this:
.Bd -literal -offset indent
+:::::::::
.Ed
The
.Ql \&+
will tell the
.Xr getpwent 3
routines in
.Tn FreeBSD Ns 's
standard C library to begin using the NIS passwd maps
for lookups.
.Pp
Note that the entry shown above is known as a
.Em wildcard
entry, because it matches all users (the
.Ql \&+
without any other information
matches everybody) and allows all NIS password data to be retrieved
unaltered.
However, by
specifying a username or netgroup next to the
.Ql \&+
in the NIS
entry, the administrator can affect what data are extracted from the
NIS passwd maps and how it is interpreted.
Here are a few example
records that illustrate this feature (note that you can have several
NIS entries in a single
.Pa master.passwd
file):
.Bd -literal -offset indent
-mitnick:::::::::
+@staff:::::::::
+@permitted-users:::::::::
+dennis:::::::::
+ken:::::::::/bin/csh
+@rejected-users::32767:32767::::::/bin/false
.Ed
Specific usernames are listed explicitly while netgroups are signified
by a preceding
.Ql \&@ .
In the above example, users in the
.Dq staff
and
.Dq permitted-users
netgroups will have their password information
read from NIS and used unaltered.
In other words, they will be allowed
normal access to the machine.
Users
.Dq ken
and
.Dq dennis ,
who have
been named explicitly rather than through a netgroup, will also have
their password data read from NIS,
.Em except
that user
.Dq ken
will have his shell remapped to
.Pa /bin/csh .
This means that value for his shell specified in the NIS password map
will be overridden by the value specified in the special NIS entry in
the local
.Pa master.passwd
file.
User
.Dq ken
may have been assigned the csh shell because his
NIS password entry specified a different shell that may not be
installed on the client machine for political or technical reasons.
Meanwhile, users in the
.Dq rejected-users
netgroup are prevented
from logging in because their UIDs, GIDs and shells have been overridden
with invalid values.
.Pp
User
.Dq mitnick
will be be ignored entirely because his entry is
specified with a
.Ql \&-
instead of a
.Ql \&+ .
A minus entry can be used
to block out certain NIS password entries completely; users whose
password data has been excluded in this way are not recognized by
the system at all.
(Any overrides specified with minus entries are
also ignored since there is no point in processing override information
for a user that the system isn't going to recognize in the first place.)
In general, a minus entry is used to specifically exclude a user
who might otherwise be granted access because he happens to be a
member of an authorized netgroup.
For example, if
.Dq mitnick
is
a member of the
.Dq permitted-users
netgroup and must, for whatever
the reason, be permitted to remain in that netgroup (possibly to
retain access to other machines within the domain), the administrator
can still deny him access to a particular system with a minus entry.
Also, it is sometimes easier to explicitly list those users who are not
allowed access rather than generate a possibly complicated list of
users who are allowed access and omit the rest.
.Pp
Note that the plus and minus entries are evaluated in order from
first to last with the first match taking precedence.
This means
the system will only use the first entry that matches a particular user.
If, using the same example, there is a user
.Dq foo
who is a member of both the
.Dq staff
netgroup and the
.Dq rejected-users
netgroup, he will be admitted to
the system because the above example lists the entry for
.Dq staff
before the entry for
.Dq rejected-users .
If the order were reversed,
user
.Dq foo
would be flagged as a
.Dq rejected-user
instead and denied access.
.Pp
Lastly, any NIS password database records that do not match against
at least one of the users or netgroups specified by the NIS access
entries in the
.Pa /etc/master.passwd
file will be ignored (along with any users specified using minus
entries). In our example shown above, we do not have a wildcard
entry at the end of the list; therefore, the system will not recognize
anyone except
.Dq ken ,
.Dq dennis ,
the
.Dq staff
netgroup, and the
.Dq permitted-users
netgroup as authorized users.
The
.Dq rejected-users
netgroup will
be recognized but all members will have their shells remapped and
therefore be denied access.
All other NIS password records
will be ignored.
The administrator may add a wildcard entry to the
end of the list such as:
.Bd -literal -offset indent
+:::::::::/sbin/nologin
.Ed
This entry acts as a catch-all for all users that don't match against
any of the other entries.
This technique is sometimes useful when it is
desirable to have the system be able to recognize all users in a
particular NIS domain without necessarily granting them login access.
See the description of the shell field regarding security concerns when using
a shell script as the login shell.
.Pp
The primary use of this
.Pa override
feature is to permit the administrator
to enforce access restrictions on NIS client systems.
Users can be
granted access to one group of machines and denied access to other
machines simply by adding or removing them from a particular netgroup.
Since the netgroup database can also be accessed via NIS, this allows
access restrictions to be administered from a single location, namely
the NIS master server; once a host's access list has been set in
.Pa /etc/master.passwd ,
it need not be modified again unless new netgroups are created.
.Sh NOTES
.Ss Shadow passwords through NIS
.Tn FreeBSD
uses a shadow password scheme: users' encrypted passwords
are stored only in
.Pa /etc/master.passwd
and
.Pa /etc/spwd.db ,
which are readable and writable only by the superuser.
This is done
to prevent users from running the encrypted passwords through
password-guessing programs and gaining unauthorized access to
other users' accounts.
NIS does not support a standard means of
password shadowing, which implies that placing your password data
into the NIS passwd maps totally defeats the security of
.Tn FreeBSD Ns 's
password shadowing system.
.Pp
.Tn FreeBSD
provides a few special features to help get around this
problem.
It is possible to implement password shadowing between
.Tn FreeBSD
NIS clients and
.Tn FreeBSD
NIS servers.
The
.Xr getpwent 3
routines will search for a
.Pa master.passwd.byname
and
.Pa master.passwd.byuid
maps which should contain the same data found in the
.Pa /etc/master.passwd
file.
If the maps exist,
.Tn FreeBSD
will attempt to use them for user
authentication instead of the standard
.Pa passwd.byname
and
.Pa passwd.byuid
.Sh HESIOD SUPPORT
If
.Sq dns
is specified for the
.Sq passwd
database in
.Xr nsswitch.conf 5 ,
then
.Nm
lookups occur from the
.Sq passwd
Hesiod domain.
.Sh NIS SUPPORT
If
.Sq nis
is specified for the
.Sq passwd
database in
.Xr nsswitch.conf 5 ,
then
.Nm
lookups occur from the
.Sq passwd.byname ,
.Sq passwd.byuid ,
.Sq master.passwd.byname ,
and
.Sq master.passwd.byuid
.Tn NIS
maps.
.Tn FreeBSD Ns 's
.Xr ypserv 8
will also check client requests to make sure they originate on a
privileged port.
Since only the superuser is allowed to bind to
a privileged port, the server can tell if the requesting user
is the superuser; all requests from non-privileged users to access
the
.Pa master.passwd
maps will be refused.
Since all user authentication programs run
with superuser privilege, they should have the required access to
users' encrypted password data while normal users will only
be allowed access to the standard
.Pa passwd
maps which contain no password information.
.Sh COMPAT SUPPORT
If
.Sq compat
is specified for the
.Sq passwd
database, and either
.Sq dns
or
.Sq nis
is specified for the
.Sq passwd_compat
database in
.Xr nsswitch.conf 5 ,
then the
.Nm
file also supports standard
.Sq +/-
exclusions and inclusions, based on user names and netgroups.
.Pp
Note that this feature cannot be used in an environment with
.No non- Ns Tn FreeBSD
systems.
Note also that a truly determined user with
unrestricted access to your network could still compromise the
.Pa master.passwd
maps.
.Ss UID and GID remapping with NIS overrides
Unlike
.Tn SunOS
and other operating systems that use Sun's NIS code,
.Tn FreeBSD
allows the user to override
.Pa all
of the fields in a user's NIS
.Pa passwd
entry.
For example, consider the following
.Pa /etc/master.passwd
entry:
.Bd -literal -offset indent
+@foo-users:???:666:666:0:0:0:Bogus user:/home/bogus:/bin/bogus
.Ed
This entry will cause all users in the `foo-users' netgroup to
have
.Pa all
of their password information overridden, including UIDs,
GIDs and passwords.
The result is that all `foo-users' will be
locked out of the system, since their passwords will be remapped
to invalid values.
Lines beginning with a ``-'' (minus sign) are entries marked as being excluded
from any following inclusions, which are marked with a ``+'' (plus sign).
.Pp
This is important to remember because most people are accustomed to
using an NIS wildcard entry that looks like this:
.Bd -literal -offset indent
+:*:0:0:::
.Ed
This often leads to new
.Tn FreeBSD
administrators choosing NIS entries for their
.Pa master.passwd
files that look like this:
.Bd -literal -offset indent
+:*:0:0::::::
.Ed
Or worse, this
.Bd -literal -offset indent
+::0:0::::::
.Ed
.Sy DO _NOT_ PUT ENTRIES LIKE THIS IN YOUR
.Sy Pa master.passwd
.Sy FILE!!
The first tells
.Tn FreeBSD
to remap all passwords to
.Ql \&*
(which
will prevent anybody from logging in) and to remap all UIDs and GIDs
to 0 (which will make everybody appear to be the superuser). The
second case just maps all UIDs and GIDs to 0, which means that
all users will appear to be root!
If the second character of the line is a ``@'' (at sign), the operation
involves the user fields of all entries in the netgroup specified by the
remaining characters of the
.Ar name
field.
Otherwise, the remainder of the
.Ar name
field is assumed to be a specific user name.
.Pp
.Ss Compatibility of NIS override evaluation
When Sun originally added NIS support to their
.Xr getpwent 3
routines, they took into account the fact that the
.Tn SunOS
password
.Pa /etc/passwd
file is in plain
.Tn ASCII
format.
The
.Tn SunOS
documentation claims that
adding a
.Ql \&+
entry to the password file causes the contents of
the NIS password database to be
.Dq inserted
at the position in the file where the
.Ql \&+
entry appears.
If, for example, the
administrator places a
.Ql \&+::::::
entry in the middle of
.Pa /etc/passwd ,
then the entire contents of the NIS password map would appear
as though it had been copied into the middle of the password
file.
If the administrator places
.Ql \&+::::::
entries at both the middle and the end of
.Pa /etc/passwd ,
then the NIS password map would appear twice: once in the middle
of the file and once at the end.
(By using override entries
instead of simple wildcards, other combinations could be achieved.)
.Pp
By contrast,
.Fx
does not have a single
.Tn ASCII
password file: it
has a hashed password database.
This database does not have an
easily-defined beginning, middle or end, which makes it very hard
to design a scheme that is 100% compatible with
.Tn SunOS .
For example,
the
.Fn getpwnam
The ``+'' token may also be alone in the
.Ar name
field, which causes all users from either the Hesiod domain
.Nm
(with
.Sq passwd_compat: dns )
or
.Sq passwd.byname
and
.Fn getpwuid
functions in
.Tn FreeBSD
are designed to do direct queries to the
hash database rather than a linear search.
This approach is faster
on systems where the password database is large.
However, when
using direct database queries, the system does not know or care
about the order of the original password file, and therefore
it cannot easily apply the same override logic used by
.Tn SunOS .
.Sq passwd.byuid
.Tn NIS
maps (with
.Sq passwd_compat: nis )
to be included.
.Pp
Instead,
.Tn FreeBSD
groups all the NIS override entries together
and constructs a filter out of them.
Each NIS password entry
is compared against the override filter exactly once and
treated accordingly: if the filter allows the entry through
unaltered, it's treated unaltered; if the filter calls for remapping
of fields, then fields are remapped; if the filter calls for
explicit exclusion (i.e., the entry matches a
.Ql \&-
override), the entry is ignored; if the entry doesn't match against any
of the filter specifications, it's discarded.
.Pp
Again, note that the NIS
.Ql \&+
and
.Ql \&-
entries themselves are handled in the order in which they were specified
in the
.Pa /etc/master.passwd
file, since doing otherwise would lead to unpredictable behavior.
.Pp
The end result is that
.Tn FreeBSD Ns 's
provides a very close approximation
of
.Tn SunOS Ns 's
behavior while maintaining the database paradigm, though the
.Xr getpwent 3
functions do behave somewhat differently from their
.Tn SunOS
counterparts.
The primary differences are:
.Bl -bullet -offset indent
.It
Each NIS password map record can be mapped into the password
local password space only once.
.It
The placement of the NIS
.Ql \&+
and
.Ql \&-
entries does not necessarily
affect where NIS password records will be mapped into
the password space.
.El
.Pp
In 99% of all
.Tn FreeBSD
configurations, NIS client behavior will be
indistinguishable from that of
.Tn SunOS
or other similar systems.
Even
so, users should be aware of these architectural differences.
.Pp
.Ss Using groups instead of netgroups for NIS overrides
.Tn FreeBSD
offers the capability to do override matching based on
user groups rather than netgroups.
If, for example, an NIS entry
is specified as:
.Bd -literal -offset indent
+@operator:::::::::
.Ed
the system will first try to match users against a netgroup called
.Ql operator .
If an
.Ql operator
netgroup doesn't exist, the system
will try to match users against the normal
.Ql operator
group instead.
.Ss Changes in behavior from older versions of FreeBSD
There have been several bug fixes and improvements in
.Tn FreeBSD Ns 's
NIS/YP handling, some of which have caused changes in behavior.
While the behavior changes are generally positive, it is important
that users and system administrators be aware of them:
.Bl -enum -offset indent
.It
In versions prior to 2.0.5, reverse lookups (i.e. using
.Fn getpwuid )
would not have overrides applied, which is to say that it
was possible for
.Fn getpwuid
to return a login name that
.Fn getpwnam
would not recognize.
This has been fixed: overrides specified
in
.Pa /etc/master.passwd
now apply to all
.Xr getpwent 3
functions.
.It
Prior to
.Fx 2.0.5 ,
netgroup overrides did not work at
all, largely because
.Tn FreeBSD
did not have support for reading
netgroups through NIS.
Again, this has been fixed, and
netgroups can be specified just as in
.Tn SunOS
and similar NIS-capable
systems.
.It
.Tn FreeBSD
now has NIS server capabilities and supports the use
of
.Pa master.passwd
NIS maps in addition to the standard Sixth Edition format
.Pa passwd
maps.
This means that you can specify change, expiration and class
information through NIS, provided you use a
.Tn FreeBSD
system as
the NIS server.
.El
.Sh FILES
.Bl -tag -width /etc/master.passwd -compact
.It Pa /etc/passwd
.Tn ASCII
password file, with passwords removed
.It Pa /etc/pwd.db
.Xr db 3 -format
password database, with passwords removed
.It Pa /etc/master.passwd
.Tn ASCII
password file, with passwords intact
.It Pa /etc/spwd.db
.Xr db 3 -format
password database, with passwords intact
.El
If the entry contains non-empty
.Ar uid
or
.Ar gid
fields, the specified numbers will override the information retrieved
from the Hesiod domain or the
.Tn NIS
maps. As well, if the
.Ar gecos,
.Ar dir
or
.Ar shell
entries contain text, it will override the information included via
Hesiod or
.Tn NIS .
On some systems, the
.Ar passwd
field may also be overridden.
.Sh SEE ALSO
.Xr chpass 1 ,
.Xr login 1 ,
.Xr passwd 1 ,
.Xr getpwent 3 ,
.Xr login_getclass 3 ,
.Xr yp 4 ,
.Xr login.conf 5 ,
.Xr netgroup 5 ,
.Xr adduser 8 ,
.Xr pw 8 ,
.Xr pwd_mkdb 8 ,
.Xr vipw 8
.Xr vipw 8 ,
.Xr yp 8
.Pp
.%T "Managing NFS and NIS"
(O'Reilly & Associates)
.Sh BUGS
User information should (and eventually will) be stored elsewhere.
.Pp
The YP/NIS password database makes encrypted passwords visible to
ordinary users, thus making password cracking easier unless you use
shadow passwords with the
.Pa master.passwd
maps and
.Tn FreeBSD Ns 's
.Xr ypserv 8
server.
.Pp
Unless you're using
.Tn FreeBSD Ns 's
.Xr ypserv 8 ,
which supports the use of
.Pa master.passwd
type maps,
the YP/NIS password database will be in old-style (Sixth Edition) format,
which means that site-wide values for user login class, password
expiration date, and other fields present in the current format
will not be available when a
.Tn FreeBSD
system is used as a client with
a standard NIS server.
Placing
Sq compat
exclusions in the file after any inclusions will have
unexpected results.
.Sh COMPATIBILITY
The password file format has changed since
.Bx 4.3 .
@ -776,10 +322,9 @@ The additional fields
and
.Dq expire
are added, but are turned off by default.
These fields can then be set using
.Xr vipw 8
or
.Xr pw 8 .
Class is currently not implemented, but change and expire are; to set them,
use the current day in seconds from the epoch + whatever number of seconds
of offset you want.
.Bd -literal -offset indent
BEGIN { FS = ":"}
{ print $1 ":" $2 ":" $3 ":" $4 "::0:0:" $5 ":" $6 ":" $7 }
@ -789,14 +334,15 @@ A
.Nm
file format appeared in
.At v6 .
The YP/NIS functionality is modeled after
.Tn SunOS
and first appeared in
.Fx 1.1
The override capability is new in
.Fx 2.0 .
The override capability was updated to properly support netgroups
in
.Fx 2.0.5 .
Support for comments first appeared in
.Fx 3.0 .
.Pp
The
.Tn NIS
.Nm
file format first appeared in SunOS.
.Pp
The Hesiod support first appeared in
.Fx 4.1 .
It was imported from the
.Nx
Project, where it first appeared in
.Nx 1.4 .

View File

@ -57,14 +57,8 @@ daemon makes direct
library calls since there are no
functions in the standard C library for reading bootparams.
.Tn NIS
support for the hosts, services and rpc databases is enabled by
uncommenting the
.Em nis
line in
.Pa /etc/host.conf .
.Tn NIS
support for the remaining services is
activated by adding a special '+' entry to the appropriate file.
support is enabled in
.Xr nsswitch.conf .
.Pp
The
.Nm YP

View File

@ -10,8 +10,9 @@ GENSRCS=yp.h yp_clnt.c yppasswd.h yppasswd_clnt.c yppasswd_private.h \
BINMODE=4555
.PATH: ${.CURDIR}/../../usr.sbin/pwd_mkdb ${.CURDIR}/../../usr.sbin/vipw \
${.CURDIR}/../../libexec/ypxfr \
${.CURDIR}/../../usr.sbin/rpc.yppasswdd
CFLAGS+=-I${.CURDIR}/../../usr.sbin/pwd_mkdb -I${.CURDIR}/../../usr.sbin/vipw
${.CURDIR}/../../usr.sbin/rpc.yppasswdd \
${.CURDIR}/../../lib/libc/gen
CFLAGS+=-I${.CURDIR}/../../usr.sbin/pwd_mkdb -I${.CURDIR}/../../usr.sbin/vipw -I${.CURDIR}/../../lib/libc/gen
LINKS= ${BINDIR}/chpass ${BINDIR}/chfn
LINKS+= ${BINDIR}/chpass ${BINDIR}/chsh
LINKS+= ${BINDIR}/chpass ${BINDIR}/ypchpass

View File

@ -204,7 +204,7 @@ main(argc, argv)
if (uid)
baduser();
pw = &lpw;
if (!pw_scan(arg, pw))
if (!__pw_scan(arg, pw, _PWSCAN_WARN|_PWSCAN_MASTER))
exit(1);
}
username = pw->pw_name;

View File

@ -264,5 +264,5 @@ bad: (void)fclose(fp);
return (0);
}
free(p);
return (pw_scan(buf, pw));
return (__pw_scan(buf, pw, _PWSCAN_WARN|_PWSCAN_MASTER));
}

5
usr.bin/hesinfo/Makefile Normal file
View File

@ -0,0 +1,5 @@
# $FreeBSD$
PROG= hesinfo
.include <bsd.prog.mk>

226
usr.bin/hesinfo/hesinfo.1 Normal file
View File

@ -0,0 +1,226 @@
.\" $NetBSD: hesinfo.1,v 1.1 1999/01/25 22:45:55 lukem Exp $
.\" $FreeBSD$
.\"
.\" from: #Id: hesinfo.1,v 1.9 1996/11/07 01:57:12 ghudson Exp #
.\"
.\" Copyright 1987, 1996 by the Massachusetts Institute of Technology.
.\"
.\" Permission to use, copy, modify, and distribute this
.\" software and its documentation for any purpose and without
.\" fee is hereby granted, provided that the above copyright
.\" notice appear in all copies and that both that copyright
.\" notice and this permission notice appear in supporting
.\" documentation, and that the name of M.I.T. not be used in
.\" advertising or publicity pertaining to distribution of the
.\" software without specific, written prior permission.
.\" M.I.T. makes no representations about the suitability of
.\" this software for any purpose. It is provided "as is"
.\" without express or implied warranty.
.TH HESINFO 1 "27 October 1996"
.FM mit
.SH NAME
hesinfo \- find out what is stored in the Hesiod database
.SH SYNOPSIS
.nf
hesinfo \fI[-bl]\fR \fIHesiodName\fR \fIHesiodNameType\fR
.SH DESCRIPTION
.I hesinfo
takes two arguments, a name to be resolved and a string, known
as a HesiodNameType. It then prints the information returned by
the Hesiod nameserver.
.PP
The value returned by
.B hesinfo
is of the type
.I HesiodNameType.
.PP
.I hesinfo
understands the following options:
.TP
.B -l
Selects long format.
.TP
.B -b
Prints the fully-qualified string passed to the nameserver.
.PP
.SS VALID Hesiod_Names
The following types of identifiers may be used in the
.I HesiodName
argument to
.B hesinfo.
These values will be resolved by accessing the
.B hesiod
database.
.TP
.B \<username>
the 8-character-or-less string used to identify users or classes
(e.g. joeuser, root, 1.00, etc).
Used with the
.I Hesiod_Name_Types
.BR passwd,
.BR pobox,
and
.BR filsys.
.TP
.B \<uid>
the id number assigned to a user.
.TP
.B \<groupid>
the id number assigned to a group.
.TP
.B \<groupname>
a name identifying a unique group.
.TP
.B \<file-system-name>
the name of an athena file system.
.TP
.B \<rvd server>:<pack>
the name of an rvd's server and pack seperated by a colon.
.TP
.B \<nfs server>:<partition>
the name of an nfs server and its partition seperated by a colon.
.TP
.B \<workstation-name>
the machine name of an Athena workstation (e.g. E40-343-3).
.TP
.B \<service-name>
name of an Athena service (e.g. Zephyr).
.TP
.B \<service-type>
name of Unix service (valid entries are defined in /etc/services).
.TP
.B \<printer-name>
name of a printer.
.TP
.B \<printer-cluster-name>
name of an Athena print cluster.
.TP
.B \<foo>
some
.B hesinfo
calls (e.g.
.B prclusterlist
) do not require a specific
.I HesiodName
argument. However, you must include a dummy string (e.g. 'foo') for
.B hesinfo
to work properly.
.PP
.SS VALID Hesiod_Name_Types
The following symbols are valid substitutions for the
.I HesiodNameType
argument to
.B hesinfo.
.TP
.B \ passwd
returns string suitable for inclusion in
.I /etc/passwd,
searching with
.B <username>.
.TP
.B \ pobox
returns information on the pobox assigned to the user specified by
.I HesiodName,
searching with
.B <username>.
.TP
.B \ uid
returns string suitable for inclusion in
.I /etc/passwd,
searching with
.B <uid>.
.TP
.B \ gid
returns string suitable for inclusion in
.I /etc/group,
searching with
.B <groupid>.
.TP
.B \ group
returns string suitable for inclusion in
.I /etc/group,
searching with
.B <groupname>.
.TP
.B \ grplist
returns subgroups included in superset
defined by
.B <groupname>.
.TP
.B \ filsys
returns file system type, export point, server, mount mode, and import point
for the following valid
.I HesiodNames
(see above)
.B - <file system name>, <username>, <rvd server>:<pack>,
.B and <nfs server>:<partition>
.TP
.B \ cluster
returns information about the local cluster the workstation, specified by
.B <workstation name>.
Included is information about the local file and print servers. This
information is accesses by
.B clusterinfo
at boot time.
.TP
.B \ sloc
returns network name of service host for
.B <service-name>.
.TP
.B \ service
returns Internet protocol type and protocol service port for
.B <service-type>.
.TP
.B \ pcap
returns a valid entry for /etc/printcap for
.B <printer-name>.
.TP
.B \ prcluserlist
returns a list of print clusters.
.TP
.B \ prcluster
returns a list of printers in a cluster specified by
.B <printer-cluster-name>.
.SH FILES
/etc/hesiod.conf
.SH "SEE ALSO"
`Hesiod - Project Athena Technical Plan -- Name Service', named(8), hesiod(3)
.SH AUTHOR
Steve Dyer, IBM/Project Athena
.br
Copyright 1987, 1988, 1996 by the Massachusetts Institute of Technology.
.br

116
usr.bin/hesinfo/hesinfo.c Normal file
View File

@ -0,0 +1,116 @@
/* $NetBSD: hesinfo.c,v 1.1 1999/01/25 22:45:55 lukem Exp $ */
/* Copyright 1988, 1996 by the Massachusetts Institute of Technology.
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
/* This file is a simple driver for the Hesiod library. */
#include <sys/cdefs.h>
#ifndef lint
static char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
#include <err.h>
#include <errno.h>
#include <hesiod.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main __P((int, char **));
extern char *__progname;
int
main(argc, argv)
int argc;
char **argv;
{
char **list, **p, *bindname, *name, *type;
int lflag = 0, errflg = 0, bflag = 0, c;
void *context;
while ((c = getopt(argc, argv, "lb")) != -1) {
switch (c) {
case 'l':
lflag = 1;
break;
case 'b':
bflag = 1;
break;
default:
errflg++;
break;
}
}
if (argc - optind != 2 || errflg) {
fprintf(stderr, "Usage: %s [-bl] name type\n", __progname);
fprintf(stderr, "\t-l selects long format\n");
fprintf(stderr, "\t-b also does hes_to_bind conversion\n");
exit(2);
}
name = argv[optind];
type = argv[optind + 1];
if (hesiod_init(&context) < 0) {
if (errno == ENOEXEC)
warnx(
"hesiod_init: Invalid Hesiod configuration file.");
else
warn("hesiod_init");
}
/* Display bind name if requested. */
if (bflag) {
if (lflag)
printf("hes_to_bind(%s, %s) expands to\n", name, type);
bindname = hesiod_to_bind(context, name, type);
if (!bindname) {
if (lflag)
printf("nothing\n");
if (errno == ENOENT)
warnx("hesiod_to_bind: Unknown rhs-extension.");
else
warn("hesiod_to_bind");
exit(1);
}
printf("%s\n", bindname);
free(bindname);
if (lflag)
printf("which ");
}
if (lflag)
printf("resolves to\n");
/* Do the hesiod resolve and check for errors. */
list = hesiod_resolve(context, name, type);
if (!list) {
if (lflag)
printf("nothing\n");
if (errno == ENOENT)
warnx("hesiod_resolve: Hesiod name not found.");
else
warn("hesiod_resolve");
exit(1);
}
/* Display the results. */
for (p = list; *p; p++)
printf("%s\n", *p);
hesiod_free_list(context, list);
hesiod_end(context);
exit(0);
}

View File

@ -1,5 +1,9 @@
# $FreeBSD$
# @(#)Makefile 8.1 (Berkeley) 6/6/93
.PATH: ${.CURDIR}/../../lib/libc/gen # for pw_scan.c
CFLAGS+= -I${.CURDIR}/../../lib/libc/gen # for pw_scan.h
PROG= pwd_mkdb
SRCS= pw_scan.c pwd_mkdb.c
MAN8= pwd_mkdb.8

View File

@ -1,174 +0,0 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
#if 0
static char sccsid[] = "@(#)pw_scan.c 8.3 (Berkeley) 4/2/94";
#endif
static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
/*
* This module is used to "verify" password entries by chpass(1) and
* pwd_mkdb(8).
*/
#include <sys/param.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "pw_scan.h"
/*
* Some software assumes that IDs are short. We should emit warnings
* for id's which can not be stored in a short, but we are more liberal
* by default, warning for IDs greater than USHRT_MAX.
*
* If pw_big_ids_warning is anything other than -1 on entry to pw_scan()
* it will be set based on the existance of PW_SCAN_BIG_IDS in the
* environment.
*/
int pw_big_ids_warning = -1;
int
pw_scan(bp, pw)
char *bp;
struct passwd *pw;
{
uid_t id;
int root;
char *p, *sh;
if (pw_big_ids_warning == -1)
pw_big_ids_warning = getenv("PW_SCAN_BIG_IDS") == NULL ? 1 : 0;
pw->pw_fields = 0;
if (!(pw->pw_name = strsep(&bp, ":"))) /* login */
goto fmt;
root = !strcmp(pw->pw_name, "root");
if(pw->pw_name[0] && (pw->pw_name[0] != '+' || pw->pw_name[1] == '\0'))
pw->pw_fields |= _PWF_NAME;
if (!(pw->pw_passwd = strsep(&bp, ":"))) /* passwd */
goto fmt;
if(pw->pw_passwd[0]) pw->pw_fields |= _PWF_PASSWD;
if (!(p = strsep(&bp, ":"))) /* uid */
goto fmt;
if (p[0])
pw->pw_fields |= _PWF_UID;
else {
if (pw->pw_name[0] != '+' && pw->pw_name[0] != '-') {
warnx("no uid for user %s", pw->pw_name);
return (0);
}
}
id = strtoul(p, (char **)NULL, 10);
if (errno == ERANGE) {
warnx("%s > max uid value (%u)", p, ULONG_MAX);
return (0);
}
if (root && id) {
warnx("root uid should be 0");
return (0);
}
if (pw_big_ids_warning && id > USHRT_MAX) {
warnx("%s > recommended max uid value (%u)", p, USHRT_MAX);
/*return (0);*/ /* THIS SHOULD NOT BE FATAL! */
}
pw->pw_uid = id;
if (!(p = strsep(&bp, ":"))) /* gid */
goto fmt;
if(p[0]) pw->pw_fields |= _PWF_GID;
id = strtoul(p, (char **)NULL, 10);
if (errno == ERANGE) {
warnx("%s > max gid value (%u)", p, ULONG_MAX);
return (0);
}
if (pw_big_ids_warning && id > USHRT_MAX) {
warnx("%s > recommended max gid value (%u)", p, USHRT_MAX);
/* return (0); This should not be fatal! */
}
pw->pw_gid = id;
pw->pw_class = strsep(&bp, ":"); /* class */
if(pw->pw_class[0]) pw->pw_fields |= _PWF_CLASS;
if (!(p = strsep(&bp, ":"))) /* change */
goto fmt;
if(p[0]) pw->pw_fields |= _PWF_CHANGE;
pw->pw_change = atol(p);
if (!(p = strsep(&bp, ":"))) /* expire */
goto fmt;
if(p[0]) pw->pw_fields |= _PWF_EXPIRE;
pw->pw_expire = atol(p);
if (!(pw->pw_gecos = strsep(&bp, ":"))) /* gecos */
goto fmt;
if(pw->pw_gecos[0]) pw->pw_fields |= _PWF_GECOS;
if (!(pw->pw_dir = strsep(&bp, ":"))) /* directory */
goto fmt;
if(pw->pw_dir[0]) pw->pw_fields |= _PWF_DIR;
if (!(pw->pw_shell = strsep(&bp, ":"))) /* shell */
goto fmt;
p = pw->pw_shell;
if (root && *p) /* empty == /bin/sh */
for (setusershell();;) {
if (!(sh = getusershell())) {
warnx("warning, unknown root shell");
break;
}
if (!strcmp(p, sh))
break;
}
if(p[0]) pw->pw_fields |= _PWF_SHELL;
if ((p = strsep(&bp, ":"))) { /* too many */
fmt: warnx("corrupted entry");
return (0);
}
return (1);
}

View File

@ -1,40 +0,0 @@
/*-
* Copyright (c) 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)pw_scan.h 8.1 (Berkeley) 4/1/94
*
* $FreeBSD$
*/
extern int pw_big_ids_warning;
extern int pw_scan __P((char *, struct passwd *));

View File

@ -520,7 +520,7 @@ scan(fp, pw)
} else
is_comment = 0;
if (!pw_scan(line, pw)) {
if (!__pw_scan(line, pw, _PWSCAN_WARN|_PWSCAN_MASTER)) {
warnx("at line #%d", lcnt);
fmt: errno = EFTYPE; /* XXX */
error(pname);

View File

@ -111,7 +111,7 @@ If this name is not in the DNS but is in
the DNS lookup
can cause a delayed RARP response, so in this situation it is reccommended to
configure
.Pa /etc/host.conf
.Xr nsswitch.conf
to read
.Pa /etc/hosts
first.

View File

@ -78,7 +78,6 @@ static HitList etc_files [] = {
{ JUST_COPY, "gettytab", TRUE, NULL },
{ JUST_COPY, "gnats", TRUE, NULL },
{ JUST_COPY, "group", FALSE, NULL },
{ JUST_COPY, "host.conf", TRUE, NULL },
{ JUST_COPY, "hosts", TRUE, NULL },
{ JUST_COPY, "hosts.equiv", TRUE, NULL },
{ JUST_COPY, "hosts.lpd", TRUE, NULL },
@ -96,6 +95,7 @@ static HitList etc_files [] = {
{ JUST_COPY, "namedb", TRUE, NULL },
{ JUST_COPY, "networks", TRUE, NULL },
{ JUST_COPY, "newsyslog.conf", TRUE, NULL },
{ JUST_COPY, "nsswitch.conf", TRUE, NULL },
{ JUST_COPY, "pam.conf", TRUE, NULL },
{ JUST_COPY, "passwd", TRUE, NULL },
{ JUST_COPY, "periodic", TRUE, NULL },

View File

@ -435,8 +435,8 @@ within the filesystem.
the
.Tn NIS
maps
.It Pa /etc/host.conf
resolver configuration file
.It Pa /etc/nsswitch.conf
name switch configuration file
.It Pa /var/yp/securenets
host access control file
.El