Checkin of BIND 9.2.3 (libbind.so).
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7204 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
BIND 9.2.3 ported to OpenBeOS
|
||||
|
||||
This file contains important information for developers who want to port BIND to OpenBeOS.
|
||||
I created config.h, port_before.h, and port_after.h with the BIND configure script and fixed some mistakes that the script made.
|
||||
|
||||
Our private folder are:
|
||||
headers (some headers are not defined in OpenBeOS)
|
||||
src (functions that are not part of OpenBeOS, e.g.: strsep)
|
||||
|
||||
Porting issues:
|
||||
BIND wants to include sys/un.h and utmp.h. We do not have these, so I put empty headers into the private headers folder.
|
||||
|
||||
strsep() is not defined although we #define NEED_STRSEP in port_after.h. I put it in our private src folder.
|
||||
|
||||
OpenBeOS defines pselect(), but we turned NEEDS_PSELECT in port_after.h on because it is not present in BeOS.
|
||||
As long as we do not have a working kernel this should be #define'd. When we can do a real OpenBeOS port we should #undef it again.
|
||||
|
||||
Added sources for compatibility:
|
||||
arc4random.c
|
||||
ethers.c
|
||||
pthread_emu.c
|
||||
|
||||
Changes made to the sources and headers:
|
||||
netdb.h and resolv.h: simplified by removing unneeded checks for other platforms
|
||||
|
||||
irs/gai_strerror and irs/irs_data.c: Changed the initialization of the mutex lock and rewrote TLS to use BeOS functions
|
||||
because we do not have full pthread support.
|
||||
@@ -0,0 +1,186 @@
|
||||
SubDir OBOS_TOP src kits network libbind ;
|
||||
|
||||
UsePrivateHeaders net ;
|
||||
UseHeaders [ FDirName $(SUBDIR) headers ] ;
|
||||
|
||||
# our libroot contains functions that are missing in BeOS (e.g.: strlcat)
|
||||
SEARCH_SOURCE += [ FDirName $(OBOS_TOP) src kernel libroot posix pthread ] ;
|
||||
SEARCH_SOURCE += [ FDirName $(OBOS_TOP) src kernel libroot posix string ] ;
|
||||
|
||||
# private sources for this port
|
||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) src ] ;
|
||||
|
||||
# BIND sources
|
||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) dst ] ;
|
||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) inet ] ;
|
||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) irs ] ;
|
||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) isc ] ;
|
||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) nameser ] ;
|
||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) resolv ] ;
|
||||
|
||||
{
|
||||
# we want to have the xxx_r functions, too
|
||||
local defines = _REENTRANT=1 NO_SOCKADDR_UN=1 ;
|
||||
defines = [ FDefines $(defines) ] ;
|
||||
SubDirCcFlags $(defines) ;
|
||||
SubDirC++Flags $(defines) ;
|
||||
}
|
||||
|
||||
SharedLibrary "bind" :
|
||||
# dst
|
||||
dst_api.c
|
||||
hmac_link.c
|
||||
md5_dgst.c
|
||||
support.c
|
||||
|
||||
# inet
|
||||
inet_addr.c
|
||||
inet_cidr_ntop.c
|
||||
inet_cidr_pton.c
|
||||
inet_data.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
|
||||
nsap_addr.c
|
||||
|
||||
# irs
|
||||
dns.c
|
||||
dns_gr.c
|
||||
dns_ho.c
|
||||
dns_nw.c
|
||||
dns_pr.c
|
||||
dns_pw.c
|
||||
dns_sv.c
|
||||
gai_strerror.c
|
||||
gen.c
|
||||
gen_gr.c
|
||||
gen_ho.c
|
||||
gen_ng.c
|
||||
gen_nw.c
|
||||
gen_pr.c
|
||||
gen_pw.c
|
||||
gen_sv.c
|
||||
getaddrinfo.c
|
||||
getgrent.c
|
||||
getgrent_r.c
|
||||
gethostent.c
|
||||
gethostent_r.c
|
||||
getnameinfo.c
|
||||
getnetent.c
|
||||
getnetent_r.c
|
||||
getnetgrent.c
|
||||
getnetgrent_r.c
|
||||
getprotoent.c
|
||||
getprotoent_r.c
|
||||
getpwent.c
|
||||
getpwent_r.c
|
||||
getservent.c
|
||||
getservent_r.c
|
||||
hesiod.c
|
||||
irp.c
|
||||
irp_gr.c
|
||||
irp_ho.c
|
||||
irp_ng.c
|
||||
irp_nw.c
|
||||
irp_pr.c
|
||||
irp_pw.c
|
||||
irp_sv.c
|
||||
irpmarshall.c
|
||||
irs_data.c
|
||||
lcl.c
|
||||
lcl_gr.c
|
||||
lcl_ho.c
|
||||
lcl_ng.c
|
||||
lcl_nw.c
|
||||
lcl_pr.c
|
||||
lcl_pw.c
|
||||
lcl_sv.c
|
||||
nis.c
|
||||
nis_gr.c
|
||||
nis_ho.c
|
||||
nis_ng.c
|
||||
nis_nw.c
|
||||
nis_pr.c
|
||||
nis_pw.c
|
||||
nis_sv.c
|
||||
nul_ng.c
|
||||
util.c
|
||||
|
||||
# isc (not used)
|
||||
assertions.c
|
||||
base64.c
|
||||
bitncmp.c
|
||||
ctl_clnt.c
|
||||
ctl_p.c
|
||||
ctl_srvr.c
|
||||
ev_connects.c
|
||||
ev_files.c
|
||||
ev_streams.c
|
||||
ev_timers.c
|
||||
ev_waits.c
|
||||
eventlib.c
|
||||
heap.c
|
||||
hex.c
|
||||
logging.c
|
||||
memcluster.c
|
||||
movefile.c
|
||||
tree.c
|
||||
|
||||
# nameser
|
||||
ns_date.c
|
||||
ns_name.c
|
||||
ns_netint.c
|
||||
ns_parse.c
|
||||
ns_print.c
|
||||
ns_samedomain.c
|
||||
ns_sign.c
|
||||
ns_ttl.c
|
||||
ns_verify.c
|
||||
|
||||
# resolv
|
||||
herror.c
|
||||
res_comp.c
|
||||
res_data.c
|
||||
res_debug.c
|
||||
res_findzonecut.c
|
||||
res_init.c
|
||||
res_mkquery.c
|
||||
res_mkupdate.c
|
||||
res_query.c
|
||||
res_send.c
|
||||
res_sendsigned.c
|
||||
res_update.c
|
||||
|
||||
# functions from our libroot
|
||||
pthread_mutex.c
|
||||
pthread_mutexattr.c
|
||||
strlcat.c
|
||||
|
||||
# private functions
|
||||
arc4random.c
|
||||
ethers.c
|
||||
pthread_emu.c
|
||||
strsep.c
|
||||
;
|
||||
|
||||
LinkSharedOSLibs libbind.so :
|
||||
be # BeOS defines syslog in libbe.so
|
||||
socket ;
|
||||
|
||||
# Installation -- in the test directory for the time being
|
||||
OBOSInstallRelSymLink install-networking
|
||||
: [ FDirName $(OBOS_TEST_DIR) kits net lib ]
|
||||
: libbind.so
|
||||
: installed-networking-test ;
|
||||
|
||||
Package openbeos-networkingkit-cvs :
|
||||
libbind.so :
|
||||
# boot home config lib ;
|
||||
boot home Desktop openbeos-networkingkit lib ;
|
||||
@@ -0,0 +1,46 @@
|
||||
/* config.h. Generated by configure. */
|
||||
/* #undef _SOCKADDR_LEN */
|
||||
#define HAVE_FCNTL_H 1
|
||||
/* #undef HAVE_PATHS_H */
|
||||
/* #undef HAVE_SYS_TIMERS_H */
|
||||
/* #undef SYS_CDEFS_H */
|
||||
/* #undef _POSIX_PTHREAD_SEMANTICS */
|
||||
/* #undef POSIX_GETPWUID_R */
|
||||
/* #undef POSIX_GETPWNAM_R */
|
||||
/* #undef POSIX_GETGRGID_R */
|
||||
/* #undef POSIX_GETGRNAM_R */
|
||||
|
||||
/* #undef NEED_SETGROUPENT */
|
||||
/* #undef NEED_GETGROUPLIST */
|
||||
|
||||
/* define if prototype for getgrnam_r() is required */
|
||||
/* #undef NEED_GETGRNAM_R */
|
||||
/* #undef NEED_GETGRGID_R */
|
||||
/* #undef NEED_GETGRENT_R */
|
||||
/* #undef NEED_SETGRENT_R */
|
||||
/* #undef NEED_ENDGRENT_R */
|
||||
|
||||
/* #undef NEED_INNETGR_R */
|
||||
/* #undef NEED_SETNETGRENT_R */
|
||||
/* #undef NEED_ENDNETGRENT_R */
|
||||
|
||||
/* #undef NEED_GETPWNAM_R */
|
||||
/* #undef NEED_GETPWUID_R */
|
||||
/* #undef NEED_SETPWENT_R */
|
||||
/* #undef NEED_SETPASSENT_R */
|
||||
/* #undef NEED_SETPWENT_R */
|
||||
/* #undef NEED_GETPWENT_R */
|
||||
/* #undef NEED_ENDPWENT_R */
|
||||
|
||||
/* #undef NEED_SETPASSENT */
|
||||
|
||||
/* #undef HAS_PW_CLASS */
|
||||
|
||||
/* Shut up warnings about sputaux in stdio.h on BSD/OS pre-4.1 */
|
||||
/* #undef SHUTUP_SPUTAUX */
|
||||
#ifdef SHUTUP_SPUTAUX
|
||||
struct __sFILE;
|
||||
extern __inline int __sputaux(int _c, struct __sFILE *_p);
|
||||
#endif
|
||||
/* #undef BROKEN_IN6ADDR_INIT_MACROS */
|
||||
#define HAVE_STRLCAT 1
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,154 @@
|
||||
#ifndef DST_INTERNAL_H
|
||||
#define DST_INTERNAL_H
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc.
|
||||
*
|
||||
* 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 TRUSTED INFORMATION SYSTEMS
|
||||
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
* TRUSTED INFORMATION SYSTEMS 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 THE SOFTWARE.
|
||||
*/
|
||||
#include <limits.h>
|
||||
#include <sys/param.h>
|
||||
#if (!defined(BSD)) || (BSD < 199306)
|
||||
# include <sys/bitypes.h>
|
||||
#else
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
# ifdef POSIX_PATH_MAX
|
||||
# define PATH_MAX POSIX_PATH_MAX
|
||||
# else
|
||||
# define PATH_MAX 255 /* this is the value of POSIX_PATH_MAX */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef struct dst_key {
|
||||
char *dk_key_name; /* name of the key */
|
||||
int dk_key_size; /* this is the size of the key in bits */
|
||||
int dk_proto; /* what protocols this key can be used for */
|
||||
int dk_alg; /* algorithm number from key record */
|
||||
u_int32_t dk_flags; /* and the flags of the public key */
|
||||
u_int16_t dk_id; /* identifier of the key */
|
||||
void *dk_KEY_struct; /* pointer to key in crypto pkg fmt */
|
||||
struct dst_func *dk_func; /* point to cryptto pgk specific function table */
|
||||
} DST_KEY;
|
||||
#define HAS_DST_KEY
|
||||
|
||||
#include <isc/dst.h>
|
||||
/*
|
||||
* define what crypto systems are supported for RSA,
|
||||
* BSAFE is prefered over RSAREF; only one can be set at any time
|
||||
*/
|
||||
#if defined(BSAFE) && defined(RSAREF)
|
||||
# error "Cannot have both BSAFE and RSAREF defined"
|
||||
#endif
|
||||
|
||||
/* Declare dst_lib specific constants */
|
||||
#define KEY_FILE_FORMAT "1.2"
|
||||
|
||||
/* suffixes for key file names */
|
||||
#define PRIVATE_KEY "private"
|
||||
#define PUBLIC_KEY "key"
|
||||
|
||||
/* error handling */
|
||||
#ifdef REPORT_ERRORS
|
||||
#define EREPORT(str) printf str
|
||||
#else
|
||||
#define EREPORT(str) (void)0
|
||||
#endif
|
||||
|
||||
/* use our own special macro to FRRE memory */
|
||||
|
||||
#ifndef SAFE_FREE
|
||||
#define SAFE_FREE(a) \
|
||||
do{if(a != NULL){memset(a,0, sizeof(*a)); free(a); a=NULL;}} while (0)
|
||||
#define SAFE_FREE2(a,s) if (a != NULL && s > 0){memset(a,0, s);free(a); a=NULL;}
|
||||
#endif
|
||||
|
||||
typedef struct dst_func {
|
||||
int (*sign)(const int mode, DST_KEY *key, void **context,
|
||||
const u_int8_t *data, const int len,
|
||||
u_int8_t *signature, const int sig_len);
|
||||
int (*verify)(const int mode, DST_KEY *key, void **context,
|
||||
const u_int8_t *data, const int len,
|
||||
const u_int8_t *signature, const int sig_len);
|
||||
int (*compare)(const DST_KEY *key1, const DST_KEY *key2);
|
||||
int (*generate)(DST_KEY *key, int parms);
|
||||
void *(*destroy)(void *key);
|
||||
/* conversion functions */
|
||||
int (*to_dns_key)(const DST_KEY *key, u_int8_t *out,
|
||||
const int out_len);
|
||||
int (*from_dns_key)(DST_KEY *key, const u_int8_t *str,
|
||||
const int str_len);
|
||||
int (*to_file_fmt)(const DST_KEY *key, char *out,
|
||||
const int out_len);
|
||||
int (*from_file_fmt)(DST_KEY *key, const char *out,
|
||||
const int out_len);
|
||||
|
||||
} dst_func;
|
||||
|
||||
extern dst_func *dst_t_func[DST_MAX_ALGS];
|
||||
extern const char *key_file_fmt_str;
|
||||
extern const char *dst_path;
|
||||
|
||||
#ifndef DST_HASH_SIZE
|
||||
#define DST_HASH_SIZE 20 /* RIPEMD160 and SHA-1 are 20 bytes MD5 is 16 */
|
||||
#endif
|
||||
|
||||
int dst_bsafe_init(void);
|
||||
|
||||
int dst_rsaref_init(void);
|
||||
|
||||
int dst_hmac_md5_init(void);
|
||||
|
||||
int dst_cylink_init(void);
|
||||
|
||||
int dst_eay_dss_init(void);
|
||||
|
||||
/* from higher level support routines */
|
||||
int dst_s_calculate_bits( const u_int8_t *str, const int max_bits);
|
||||
int dst_s_verify_str( const char **buf, const char *str);
|
||||
|
||||
|
||||
/* conversion between dns names and key file names */
|
||||
size_t dst_s_filename_length( const char *name, const char *suffix);
|
||||
int dst_s_build_filename( char *filename, const char *name,
|
||||
u_int16_t id, int alg, const char *suffix,
|
||||
size_t filename_length);
|
||||
|
||||
FILE *dst_s_fopen (const char *filename, const char *mode, int perm);
|
||||
|
||||
/*
|
||||
* read and write network byte order into u_int?_t
|
||||
* all of these should be retired
|
||||
*/
|
||||
u_int16_t dst_s_get_int16( const u_int8_t *buf);
|
||||
void dst_s_put_int16( u_int8_t *buf, const u_int16_t val);
|
||||
|
||||
u_int32_t dst_s_get_int32( const u_int8_t *buf);
|
||||
void dst_s_put_int32( u_int8_t *buf, const u_int32_t val);
|
||||
|
||||
#ifdef DUMP
|
||||
# undef DUMP
|
||||
# define DUMP(a,b,c,d) dst_s_dump(a,b,c,d)
|
||||
#else
|
||||
# define DUMP(a,b,c,d)
|
||||
#endif
|
||||
void
|
||||
dst_s_dump(const int mode, const u_char *data, const int size,
|
||||
const char *msg);
|
||||
|
||||
|
||||
|
||||
#endif /* DST_INTERNAL_H */
|
||||
@@ -0,0 +1,468 @@
|
||||
#ifdef HMAC_MD5
|
||||
#ifndef LINT
|
||||
static const char rcsid[] = "$Header: /tmp/bonefish/open-beos/current/src/kits/network/libbind/dst/hmac_link.c,v 1.1 2004/04/15 16:03:27 wkornew Exp $";
|
||||
#endif
|
||||
/*
|
||||
* Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc.
|
||||
*
|
||||
* 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 TRUSTED INFORMATION SYSTEMS
|
||||
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
* TRUSTED INFORMATION SYSTEMS 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 THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file contains an implementation of the HMAC-MD5 algorithm.
|
||||
*/
|
||||
#include "port_before.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <memory.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include "dst_internal.h"
|
||||
#ifdef USE_MD5
|
||||
# include "md5.h"
|
||||
# ifndef _MD5_H_
|
||||
# define _MD5_H_ 1 /* make sure we do not include rsaref md5.h file */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
|
||||
#define HMAC_LEN 64
|
||||
#define HMAC_IPAD 0x36
|
||||
#define HMAC_OPAD 0x5c
|
||||
#define MD5_LEN 16
|
||||
|
||||
|
||||
typedef struct hmackey {
|
||||
u_char hk_ipad[64], hk_opad[64];
|
||||
} HMAC_Key;
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* dst_hmac_md5_sign
|
||||
* Call HMAC signing functions to sign a block of data.
|
||||
* There are three steps to signing, INIT (initialize structures),
|
||||
* UPDATE (hash (more) data), FINAL (generate a signature). This
|
||||
* routine performs one or more of these steps.
|
||||
* Parameters
|
||||
* mode SIG_MODE_INIT, SIG_MODE_UPDATE and/or SIG_MODE_FINAL.
|
||||
* priv_key key to use for signing.
|
||||
* context the context to be used in this digest
|
||||
* data data to be signed.
|
||||
* len length in bytes of data.
|
||||
* signature location to store signature.
|
||||
* sig_len size of the signature location
|
||||
* returns
|
||||
* N Success on SIG_MODE_FINAL = returns signature length in bytes
|
||||
* 0 Success on SIG_MODE_INIT and UPDATE
|
||||
* <0 Failure
|
||||
*/
|
||||
|
||||
static int
|
||||
dst_hmac_md5_sign(const int mode, DST_KEY *d_key, void **context,
|
||||
const u_char *data, const int len,
|
||||
u_char *signature, const int sig_len)
|
||||
{
|
||||
HMAC_Key *key;
|
||||
int sign_len = 0;
|
||||
MD5_CTX *ctx = NULL;
|
||||
|
||||
if (mode & SIG_MODE_INIT)
|
||||
ctx = (MD5_CTX *) malloc(sizeof(*ctx));
|
||||
else if (context)
|
||||
ctx = (MD5_CTX *) *context;
|
||||
if (ctx == NULL)
|
||||
return (-1);
|
||||
|
||||
if (d_key == NULL || d_key->dk_KEY_struct == NULL)
|
||||
return (-1);
|
||||
key = (HMAC_Key *) d_key->dk_KEY_struct;
|
||||
|
||||
if (mode & SIG_MODE_INIT) {
|
||||
MD5Init(ctx);
|
||||
MD5Update(ctx, key->hk_ipad, HMAC_LEN);
|
||||
}
|
||||
|
||||
if ((mode & SIG_MODE_UPDATE) && (data && len > 0))
|
||||
MD5Update(ctx, data, len);
|
||||
|
||||
if (mode & SIG_MODE_FINAL) {
|
||||
if (signature == NULL || sig_len < MD5_LEN)
|
||||
return (SIGN_FINAL_FAILURE);
|
||||
MD5Final(signature, ctx);
|
||||
|
||||
/* perform outer MD5 */
|
||||
MD5Init(ctx);
|
||||
MD5Update(ctx, key->hk_opad, HMAC_LEN);
|
||||
MD5Update(ctx, signature, MD5_LEN);
|
||||
MD5Final(signature, ctx);
|
||||
sign_len = MD5_LEN;
|
||||
SAFE_FREE(ctx);
|
||||
}
|
||||
else {
|
||||
if (context == NULL)
|
||||
return (-1);
|
||||
*context = (void *) ctx;
|
||||
}
|
||||
return (sign_len);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* dst_hmac_md5_verify()
|
||||
* Calls HMAC verification routines. There are three steps to
|
||||
* verification, INIT (initialize structures), UPDATE (hash (more) data),
|
||||
* FINAL (generate a signature). This routine performs one or more of
|
||||
* these steps.
|
||||
* Parameters
|
||||
* mode SIG_MODE_INIT, SIG_MODE_UPDATE and/or SIG_MODE_FINAL.
|
||||
* dkey key to use for verify.
|
||||
* data data signed.
|
||||
* len length in bytes of data.
|
||||
* signature signature.
|
||||
* sig_len length in bytes of signature.
|
||||
* returns
|
||||
* 0 Success
|
||||
* <0 Failure
|
||||
*/
|
||||
|
||||
static int
|
||||
dst_hmac_md5_verify(const int mode, DST_KEY *d_key, void **context,
|
||||
const u_char *data, const int len,
|
||||
const u_char *signature, const int sig_len)
|
||||
{
|
||||
HMAC_Key *key;
|
||||
MD5_CTX *ctx = NULL;
|
||||
|
||||
if (mode & SIG_MODE_INIT)
|
||||
ctx = (MD5_CTX *) malloc(sizeof(*ctx));
|
||||
else if (context)
|
||||
ctx = (MD5_CTX *) *context;
|
||||
if (ctx == NULL)
|
||||
return (-1);
|
||||
|
||||
if (d_key == NULL || d_key->dk_KEY_struct == NULL)
|
||||
return (-1);
|
||||
|
||||
key = (HMAC_Key *) d_key->dk_KEY_struct;
|
||||
if (mode & SIG_MODE_INIT) {
|
||||
MD5Init(ctx);
|
||||
MD5Update(ctx, key->hk_ipad, HMAC_LEN);
|
||||
}
|
||||
if ((mode & SIG_MODE_UPDATE) && (data && len > 0))
|
||||
MD5Update(ctx, data, len);
|
||||
|
||||
if (mode & SIG_MODE_FINAL) {
|
||||
u_char digest[MD5_LEN];
|
||||
if (signature == NULL || key == NULL || sig_len != MD5_LEN)
|
||||
return (VERIFY_FINAL_FAILURE);
|
||||
MD5Final(digest, ctx);
|
||||
|
||||
/* perform outer MD5 */
|
||||
MD5Init(ctx);
|
||||
MD5Update(ctx, key->hk_opad, HMAC_LEN);
|
||||
MD5Update(ctx, digest, MD5_LEN);
|
||||
MD5Final(digest, ctx);
|
||||
|
||||
SAFE_FREE(ctx);
|
||||
if (memcmp(digest, signature, MD5_LEN) != 0)
|
||||
return (VERIFY_FINAL_FAILURE);
|
||||
}
|
||||
else {
|
||||
if (context == NULL)
|
||||
return (-1);
|
||||
*context = (void *) ctx;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* dst_buffer_to_hmac_md5
|
||||
* Converts key from raw data to an HMAC Key
|
||||
* This function gets in a pointer to the data
|
||||
* Parameters
|
||||
* hkey the HMAC key to be filled in
|
||||
* key the key in raw format
|
||||
* keylen the length of the key
|
||||
* Return
|
||||
* 0 Success
|
||||
* <0 Failure
|
||||
*/
|
||||
static int
|
||||
dst_buffer_to_hmac_md5(DST_KEY *dkey, const u_char *key, const int keylen)
|
||||
{
|
||||
int i;
|
||||
HMAC_Key *hkey = NULL;
|
||||
MD5_CTX ctx;
|
||||
int local_keylen = keylen;
|
||||
|
||||
if (dkey == NULL || key == NULL || keylen < 0)
|
||||
return (-1);
|
||||
|
||||
if ((hkey = (HMAC_Key *) malloc(sizeof(HMAC_Key))) == NULL)
|
||||
return (-2);
|
||||
|
||||
memset(hkey->hk_ipad, 0, sizeof(hkey->hk_ipad));
|
||||
memset(hkey->hk_opad, 0, sizeof(hkey->hk_opad));
|
||||
|
||||
/* if key is longer than HMAC_LEN bytes reset it to key=MD5(key) */
|
||||
if (keylen > HMAC_LEN) {
|
||||
u_char tk[MD5_LEN];
|
||||
MD5Init(&ctx);
|
||||
MD5Update(&ctx, key, keylen);
|
||||
MD5Final(tk, &ctx);
|
||||
memset((void *) &ctx, 0, sizeof(ctx));
|
||||
key = tk;
|
||||
local_keylen = MD5_LEN;
|
||||
}
|
||||
/* start out by storing key in pads */
|
||||
memcpy(hkey->hk_ipad, key, local_keylen);
|
||||
memcpy(hkey->hk_opad, key, local_keylen);
|
||||
|
||||
/* XOR key with hk_ipad and opad values */
|
||||
for (i = 0; i < HMAC_LEN; i++) {
|
||||
hkey->hk_ipad[i] ^= HMAC_IPAD;
|
||||
hkey->hk_opad[i] ^= HMAC_OPAD;
|
||||
}
|
||||
dkey->dk_key_size = local_keylen;
|
||||
dkey->dk_KEY_struct = (void *) hkey;
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* dst_hmac_md5_key_to_file_format
|
||||
* Encodes an HMAC Key into the portable file format.
|
||||
* Parameters
|
||||
* hkey HMAC KEY structure
|
||||
* buff output buffer
|
||||
* buff_len size of output buffer
|
||||
* Return
|
||||
* 0 Failure - null input hkey
|
||||
* -1 Failure - not enough space in output area
|
||||
* N Success - Length of data returned in buff
|
||||
*/
|
||||
|
||||
static int
|
||||
dst_hmac_md5_key_to_file_format(const DST_KEY *dkey, char *buff,
|
||||
const int buff_len)
|
||||
{
|
||||
char *bp;
|
||||
int len, b_len, i, key_len;
|
||||
u_char key[HMAC_LEN];
|
||||
HMAC_Key *hkey;
|
||||
|
||||
if (dkey == NULL || dkey->dk_KEY_struct == NULL)
|
||||
return (0);
|
||||
if (buff == NULL || buff_len <= (int) strlen(key_file_fmt_str))
|
||||
return (-1); /* no OR not enough space in output area */
|
||||
|
||||
hkey = (HMAC_Key *) dkey->dk_KEY_struct;
|
||||
memset(buff, 0, buff_len); /* just in case */
|
||||
/* write file header */
|
||||
sprintf(buff, key_file_fmt_str, KEY_FILE_FORMAT, KEY_HMAC_MD5, "HMAC");
|
||||
|
||||
bp = (char *) strchr(buff, '\0');
|
||||
b_len = buff_len - (bp - buff);
|
||||
|
||||
memset(key, 0, HMAC_LEN);
|
||||
for (i = 0; i < HMAC_LEN; i++)
|
||||
key[i] = hkey->hk_ipad[i] ^ HMAC_IPAD;
|
||||
for (i = HMAC_LEN - 1; i >= 0; i--)
|
||||
if (key[i] != 0)
|
||||
break;
|
||||
key_len = i + 1;
|
||||
|
||||
strcat(bp, "Key: ");
|
||||
bp += strlen("Key: ");
|
||||
b_len = buff_len - (bp - buff);
|
||||
|
||||
len = b64_ntop(key, key_len, bp, b_len);
|
||||
if (len < 0)
|
||||
return (-1);
|
||||
bp += len;
|
||||
*(bp++) = '\n';
|
||||
*bp = '\0';
|
||||
b_len = buff_len - (bp - buff);
|
||||
|
||||
return (buff_len - b_len);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* dst_hmac_md5_key_from_file_format
|
||||
* Converts contents of a key file into an HMAC key.
|
||||
* Parameters
|
||||
* hkey structure to put key into
|
||||
* buff buffer containing the encoded key
|
||||
* buff_len the length of the buffer
|
||||
* Return
|
||||
* n >= 0 Foot print of the key converted
|
||||
* n < 0 Error in conversion
|
||||
*/
|
||||
|
||||
static int
|
||||
dst_hmac_md5_key_from_file_format(DST_KEY *dkey, const char *buff,
|
||||
const int buff_len)
|
||||
{
|
||||
const char *p = buff, *eol;
|
||||
u_char key[HMAC_LEN+1]; /* b64_pton needs more than 64 bytes do decode
|
||||
* it should probably be fixed rather than doing
|
||||
* this
|
||||
*/
|
||||
u_char *tmp;
|
||||
int key_len, len;
|
||||
|
||||
if (dkey == NULL)
|
||||
return (-2);
|
||||
if (buff == NULL || buff_len < 0)
|
||||
return (-1);
|
||||
|
||||
memset(key, 0, sizeof(key));
|
||||
|
||||
if (!dst_s_verify_str(&p, "Key: "))
|
||||
return (-3);
|
||||
|
||||
eol = strchr(p, '\n');
|
||||
if (eol == NULL)
|
||||
return (-4);
|
||||
len = eol - p;
|
||||
tmp = malloc(len + 2);
|
||||
memcpy(tmp, p, len);
|
||||
*(tmp + len) = 0x0;
|
||||
key_len = b64_pton((char *)tmp, key, HMAC_LEN+1); /* see above */
|
||||
SAFE_FREE2(tmp, len + 2);
|
||||
|
||||
if (dst_buffer_to_hmac_md5(dkey, key, key_len) < 0) {
|
||||
return (-6);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* dst_hmac_md5_to_dns_key()
|
||||
* function to extract hmac key from DST_KEY structure
|
||||
* intput:
|
||||
* in_key: HMAC-MD5 key
|
||||
* output:
|
||||
* out_str: buffer to write ot
|
||||
* out_len: size of output buffer
|
||||
* returns:
|
||||
* number of bytes written to output buffer
|
||||
*/
|
||||
static int
|
||||
dst_hmac_md5_to_dns_key(const DST_KEY *in_key, u_char *out_str,
|
||||
const int out_len)
|
||||
{
|
||||
|
||||
HMAC_Key *hkey;
|
||||
int i;
|
||||
|
||||
if (in_key == NULL || in_key->dk_KEY_struct == NULL ||
|
||||
out_len <= in_key->dk_key_size || out_str == NULL)
|
||||
return (-1);
|
||||
|
||||
hkey = (HMAC_Key *) in_key->dk_KEY_struct;
|
||||
for (i = 0; i < in_key->dk_key_size; i++)
|
||||
out_str[i] = hkey->hk_ipad[i] ^ HMAC_IPAD;
|
||||
return (i);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* dst_hmac_md5_compare_keys
|
||||
* Compare two keys for equality.
|
||||
* Return
|
||||
* 0 The keys are equal
|
||||
* NON-ZERO The keys are not equal
|
||||
*/
|
||||
|
||||
static int
|
||||
dst_hmac_md5_compare_keys(const DST_KEY *key1, const DST_KEY *key2)
|
||||
{
|
||||
HMAC_Key *hkey1 = (HMAC_Key *) key1->dk_KEY_struct;
|
||||
HMAC_Key *hkey2 = (HMAC_Key *) key2->dk_KEY_struct;
|
||||
return memcmp(hkey1->hk_ipad, hkey2->hk_ipad, HMAC_LEN);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* dst_hmac_md5_free_key_structure
|
||||
* Frees all (none) dynamically allocated structures in hkey
|
||||
*/
|
||||
|
||||
static void *
|
||||
dst_hmac_md5_free_key_structure(void *key)
|
||||
{
|
||||
HMAC_Key *hkey = key;
|
||||
SAFE_FREE(hkey);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* dst_hmac_md5_generate_key
|
||||
* Creates a HMAC key of size size with a maximum size of 63 bytes
|
||||
* generating a HMAC key larger than 63 bytes makes no sense as that key
|
||||
* is digested before use.
|
||||
*/
|
||||
|
||||
static int
|
||||
dst_hmac_md5_generate_key(DST_KEY *key, const int nothing)
|
||||
{
|
||||
(void)key;
|
||||
(void)nothing;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* dst_hmac_md5_init() Function to answer set up function pointers for HMAC
|
||||
* related functions
|
||||
*/
|
||||
int
|
||||
dst_hmac_md5_init()
|
||||
{
|
||||
if (dst_t_func[KEY_HMAC_MD5] != NULL)
|
||||
return (1);
|
||||
dst_t_func[KEY_HMAC_MD5] = malloc(sizeof(struct dst_func));
|
||||
if (dst_t_func[KEY_HMAC_MD5] == NULL)
|
||||
return (0);
|
||||
memset(dst_t_func[KEY_HMAC_MD5], 0, sizeof(struct dst_func));
|
||||
dst_t_func[KEY_HMAC_MD5]->sign = dst_hmac_md5_sign;
|
||||
dst_t_func[KEY_HMAC_MD5]->verify = dst_hmac_md5_verify;
|
||||
dst_t_func[KEY_HMAC_MD5]->compare = dst_hmac_md5_compare_keys;
|
||||
dst_t_func[KEY_HMAC_MD5]->generate = dst_hmac_md5_generate_key;
|
||||
dst_t_func[KEY_HMAC_MD5]->destroy = dst_hmac_md5_free_key_structure;
|
||||
dst_t_func[KEY_HMAC_MD5]->to_dns_key = dst_hmac_md5_to_dns_key;
|
||||
dst_t_func[KEY_HMAC_MD5]->from_dns_key = dst_buffer_to_hmac_md5;
|
||||
dst_t_func[KEY_HMAC_MD5]->to_file_fmt = dst_hmac_md5_key_to_file_format;
|
||||
dst_t_func[KEY_HMAC_MD5]->from_file_fmt = dst_hmac_md5_key_from_file_format;
|
||||
return (1);
|
||||
}
|
||||
|
||||
#else
|
||||
#define dst_hmac_md5_init __dst_hmac_md5_init
|
||||
|
||||
int
|
||||
dst_hmac_md5_init(){
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,101 @@
|
||||
/* crypto/md/md5.h */
|
||||
/* Copyright (C) 1995-1997 Eric Young ([email protected])
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young ([email protected]).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson ([email protected]).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* 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 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 cryptographic software written by
|
||||
* Eric Young ([email protected])"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson ([email protected])"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#ifndef HEADER_MD5_H
|
||||
#define HEADER_MD5_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MD5_CBLOCK 64
|
||||
#define MD5_LBLOCK 16
|
||||
#define MD5_BLOCK 16
|
||||
#define MD5_LAST_BLOCK 56
|
||||
#define MD5_LENGTH_BLOCK 8
|
||||
#define MD5_DIGEST_LENGTH 16
|
||||
|
||||
typedef struct MD5state_st
|
||||
{
|
||||
unsigned long A,B,C,D;
|
||||
unsigned long Nl,Nh;
|
||||
unsigned long data[MD5_LBLOCK];
|
||||
int num;
|
||||
} MD5_CTX;
|
||||
|
||||
#ifndef NOPROTO
|
||||
void MD5_Init(MD5_CTX *c);
|
||||
void MD5_Update(MD5_CTX *c, const unsigned char *data, unsigned long len);
|
||||
void MD5_Final(unsigned char *md, MD5_CTX *c);
|
||||
unsigned char *MD5(unsigned char *d, unsigned long n, unsigned char *md);
|
||||
#else
|
||||
void MD5_Init();
|
||||
void MD5_Update();
|
||||
void MD5_Final();
|
||||
unsigned char *MD5();
|
||||
#endif
|
||||
|
||||
/* to provide backward compatabilty to RSAREF calls [email protected] 1997/11/14 */
|
||||
#define MD5Init(c) MD5_Init(c)
|
||||
#define MD5Update(c,data, len) MD5_Update(c,data,len)
|
||||
#define MD5Final(md, c) MD5_Final(md, c)
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,370 @@
|
||||
/* crypto/md/md5_dgst.c */
|
||||
/* Copyright (C) 1995-1997 Eric Young ([email protected])
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young ([email protected]).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson ([email protected]).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* 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 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 cryptographic software written by
|
||||
* Eric Young ([email protected])"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson ([email protected])"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#ifdef USE_MD5 /* Added by [email protected] 1998/1/26 */
|
||||
#include <port_before.h>
|
||||
#include <stdio.h>
|
||||
#include "md5_locl.h"
|
||||
#include <port_after.h>
|
||||
|
||||
const char *MD5_version="MD5 part of SSLeay 0.8.1 19-Jul-1997";
|
||||
|
||||
/* Implemented from RFC1321 The MD5 Message-Digest Algorithm
|
||||
*/
|
||||
|
||||
#define INIT_DATA_A (unsigned long)0x67452301L
|
||||
#define INIT_DATA_B (unsigned long)0xefcdab89L
|
||||
#define INIT_DATA_C (unsigned long)0x98badcfeL
|
||||
#define INIT_DATA_D (unsigned long)0x10325476L
|
||||
|
||||
#ifndef NOPROTO
|
||||
static void md5_block(MD5_CTX *c, unsigned long *p);
|
||||
#else
|
||||
static void md5_block();
|
||||
#endif
|
||||
|
||||
void MD5_Init(c)
|
||||
MD5_CTX *c;
|
||||
{
|
||||
c->A=INIT_DATA_A;
|
||||
c->B=INIT_DATA_B;
|
||||
c->C=INIT_DATA_C;
|
||||
c->D=INIT_DATA_D;
|
||||
c->Nl=0;
|
||||
c->Nh=0;
|
||||
c->num=0;
|
||||
}
|
||||
|
||||
void MD5_Update(c, data, len)
|
||||
MD5_CTX *c;
|
||||
register const unsigned char *data;
|
||||
unsigned long len;
|
||||
{
|
||||
register ULONG *p;
|
||||
int sw,sc;
|
||||
ULONG l;
|
||||
|
||||
if (len == 0) return;
|
||||
|
||||
l=(c->Nl+(len<<3))&0xffffffffL;
|
||||
/* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
|
||||
* Wei Dai <[email protected]> for pointing it out. */
|
||||
if (l < c->Nl) /* overflow */
|
||||
c->Nh++;
|
||||
c->Nh+=(len>>29);
|
||||
c->Nl=l;
|
||||
|
||||
if (c->num != 0)
|
||||
{
|
||||
p=c->data;
|
||||
sw=c->num>>2;
|
||||
sc=c->num&0x03;
|
||||
|
||||
if ((c->num+len) >= MD5_CBLOCK)
|
||||
{
|
||||
l= p[sw];
|
||||
p_c2l(data,l,sc);
|
||||
p[sw++]=l;
|
||||
for (; sw<MD5_LBLOCK; sw++)
|
||||
{
|
||||
c2l(data,l);
|
||||
p[sw]=l;
|
||||
}
|
||||
len-=(MD5_CBLOCK-c->num);
|
||||
|
||||
md5_block(c,p);
|
||||
c->num=0;
|
||||
/* drop through and do the rest */
|
||||
}
|
||||
else
|
||||
{
|
||||
int ew,ec;
|
||||
|
||||
c->num+=(int)len;
|
||||
if ((sc+len) < 4) /* ugly, add char's to a word */
|
||||
{
|
||||
l= p[sw];
|
||||
p_c2l_p(data,l,sc,len);
|
||||
p[sw]=l;
|
||||
}
|
||||
else
|
||||
{
|
||||
ew=(c->num>>2);
|
||||
ec=(c->num&0x03);
|
||||
l= p[sw];
|
||||
p_c2l(data,l,sc);
|
||||
p[sw++]=l;
|
||||
for (; sw < ew; sw++)
|
||||
{ c2l(data,l); p[sw]=l; }
|
||||
if (ec)
|
||||
{
|
||||
c2l_p(data,l,ec);
|
||||
p[sw]=l;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* we now can process the input data in blocks of MD5_CBLOCK
|
||||
* chars and save the leftovers to c->data. */
|
||||
p=c->data;
|
||||
while (len >= MD5_CBLOCK)
|
||||
{
|
||||
#if defined(L_ENDIAN) || defined(B_ENDIAN)
|
||||
memcpy(p,data,MD5_CBLOCK);
|
||||
data+=MD5_CBLOCK;
|
||||
#ifdef B_ENDIAN
|
||||
for (sw=(MD5_LBLOCK/4); sw; sw--)
|
||||
{
|
||||
Endian_Reverse32(p[0]);
|
||||
Endian_Reverse32(p[1]);
|
||||
Endian_Reverse32(p[2]);
|
||||
Endian_Reverse32(p[3]);
|
||||
p+=4;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
for (sw=(MD5_LBLOCK/4); sw; sw--)
|
||||
{
|
||||
c2l(data,l); *(p++)=l;
|
||||
c2l(data,l); *(p++)=l;
|
||||
c2l(data,l); *(p++)=l;
|
||||
c2l(data,l); *(p++)=l;
|
||||
}
|
||||
#endif
|
||||
p=c->data;
|
||||
md5_block(c,p);
|
||||
len-=MD5_CBLOCK;
|
||||
}
|
||||
sc=(int)len;
|
||||
c->num=sc;
|
||||
if (sc)
|
||||
{
|
||||
sw=sc>>2; /* words to copy */
|
||||
#ifdef L_ENDIAN
|
||||
p[sw]=0;
|
||||
memcpy(p,data,sc);
|
||||
#else
|
||||
sc&=0x03;
|
||||
for ( ; sw; sw--)
|
||||
{ c2l(data,l); *(p++)=l; }
|
||||
c2l_p(data,l,sc);
|
||||
*p=l;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void md5_block(c, X)
|
||||
MD5_CTX *c;
|
||||
register ULONG *X;
|
||||
{
|
||||
register ULONG A,B,C,D;
|
||||
|
||||
A=c->A;
|
||||
B=c->B;
|
||||
C=c->C;
|
||||
D=c->D;
|
||||
|
||||
/* Round 0 */
|
||||
R0(A,B,C,D,X[ 0], 7,0xd76aa478L);
|
||||
R0(D,A,B,C,X[ 1],12,0xe8c7b756L);
|
||||
R0(C,D,A,B,X[ 2],17,0x242070dbL);
|
||||
R0(B,C,D,A,X[ 3],22,0xc1bdceeeL);
|
||||
R0(A,B,C,D,X[ 4], 7,0xf57c0fafL);
|
||||
R0(D,A,B,C,X[ 5],12,0x4787c62aL);
|
||||
R0(C,D,A,B,X[ 6],17,0xa8304613L);
|
||||
R0(B,C,D,A,X[ 7],22,0xfd469501L);
|
||||
R0(A,B,C,D,X[ 8], 7,0x698098d8L);
|
||||
R0(D,A,B,C,X[ 9],12,0x8b44f7afL);
|
||||
R0(C,D,A,B,X[10],17,0xffff5bb1L);
|
||||
R0(B,C,D,A,X[11],22,0x895cd7beL);
|
||||
R0(A,B,C,D,X[12], 7,0x6b901122L);
|
||||
R0(D,A,B,C,X[13],12,0xfd987193L);
|
||||
R0(C,D,A,B,X[14],17,0xa679438eL);
|
||||
R0(B,C,D,A,X[15],22,0x49b40821L);
|
||||
/* Round 1 */
|
||||
R1(A,B,C,D,X[ 1], 5,0xf61e2562L);
|
||||
R1(D,A,B,C,X[ 6], 9,0xc040b340L);
|
||||
R1(C,D,A,B,X[11],14,0x265e5a51L);
|
||||
R1(B,C,D,A,X[ 0],20,0xe9b6c7aaL);
|
||||
R1(A,B,C,D,X[ 5], 5,0xd62f105dL);
|
||||
R1(D,A,B,C,X[10], 9,0x02441453L);
|
||||
R1(C,D,A,B,X[15],14,0xd8a1e681L);
|
||||
R1(B,C,D,A,X[ 4],20,0xe7d3fbc8L);
|
||||
R1(A,B,C,D,X[ 9], 5,0x21e1cde6L);
|
||||
R1(D,A,B,C,X[14], 9,0xc33707d6L);
|
||||
R1(C,D,A,B,X[ 3],14,0xf4d50d87L);
|
||||
R1(B,C,D,A,X[ 8],20,0x455a14edL);
|
||||
R1(A,B,C,D,X[13], 5,0xa9e3e905L);
|
||||
R1(D,A,B,C,X[ 2], 9,0xfcefa3f8L);
|
||||
R1(C,D,A,B,X[ 7],14,0x676f02d9L);
|
||||
R1(B,C,D,A,X[12],20,0x8d2a4c8aL);
|
||||
/* Round 2 */
|
||||
R2(A,B,C,D,X[ 5], 4,0xfffa3942L);
|
||||
R2(D,A,B,C,X[ 8],11,0x8771f681L);
|
||||
R2(C,D,A,B,X[11],16,0x6d9d6122L);
|
||||
R2(B,C,D,A,X[14],23,0xfde5380cL);
|
||||
R2(A,B,C,D,X[ 1], 4,0xa4beea44L);
|
||||
R2(D,A,B,C,X[ 4],11,0x4bdecfa9L);
|
||||
R2(C,D,A,B,X[ 7],16,0xf6bb4b60L);
|
||||
R2(B,C,D,A,X[10],23,0xbebfbc70L);
|
||||
R2(A,B,C,D,X[13], 4,0x289b7ec6L);
|
||||
R2(D,A,B,C,X[ 0],11,0xeaa127faL);
|
||||
R2(C,D,A,B,X[ 3],16,0xd4ef3085L);
|
||||
R2(B,C,D,A,X[ 6],23,0x04881d05L);
|
||||
R2(A,B,C,D,X[ 9], 4,0xd9d4d039L);
|
||||
R2(D,A,B,C,X[12],11,0xe6db99e5L);
|
||||
R2(C,D,A,B,X[15],16,0x1fa27cf8L);
|
||||
R2(B,C,D,A,X[ 2],23,0xc4ac5665L);
|
||||
/* Round 3 */
|
||||
R3(A,B,C,D,X[ 0], 6,0xf4292244L);
|
||||
R3(D,A,B,C,X[ 7],10,0x432aff97L);
|
||||
R3(C,D,A,B,X[14],15,0xab9423a7L);
|
||||
R3(B,C,D,A,X[ 5],21,0xfc93a039L);
|
||||
R3(A,B,C,D,X[12], 6,0x655b59c3L);
|
||||
R3(D,A,B,C,X[ 3],10,0x8f0ccc92L);
|
||||
R3(C,D,A,B,X[10],15,0xffeff47dL);
|
||||
R3(B,C,D,A,X[ 1],21,0x85845dd1L);
|
||||
R3(A,B,C,D,X[ 8], 6,0x6fa87e4fL);
|
||||
R3(D,A,B,C,X[15],10,0xfe2ce6e0L);
|
||||
R3(C,D,A,B,X[ 6],15,0xa3014314L);
|
||||
R3(B,C,D,A,X[13],21,0x4e0811a1L);
|
||||
R3(A,B,C,D,X[ 4], 6,0xf7537e82L);
|
||||
R3(D,A,B,C,X[11],10,0xbd3af235L);
|
||||
R3(C,D,A,B,X[ 2],15,0x2ad7d2bbL);
|
||||
R3(B,C,D,A,X[ 9],21,0xeb86d391L);
|
||||
|
||||
c->A+=A&0xffffffffL;
|
||||
c->B+=B&0xffffffffL;
|
||||
c->C+=C&0xffffffffL;
|
||||
c->D+=D&0xffffffffL;
|
||||
}
|
||||
|
||||
void MD5_Final(md, c)
|
||||
unsigned char *md;
|
||||
MD5_CTX *c;
|
||||
{
|
||||
register int i,j;
|
||||
register ULONG l;
|
||||
register ULONG *p;
|
||||
static unsigned char end[4]={0x80,0x00,0x00,0x00};
|
||||
unsigned char *cp=end;
|
||||
|
||||
/* c->num should definitly have room for at least one more byte. */
|
||||
p=c->data;
|
||||
j=c->num;
|
||||
i=j>>2;
|
||||
|
||||
/* purify often complains about the following line as an
|
||||
* Uninitialized Memory Read. While this can be true, the
|
||||
* following p_c2l macro will reset l when that case is true.
|
||||
* This is because j&0x03 contains the number of 'valid' bytes
|
||||
* already in p[i]. If and only if j&0x03 == 0, the UMR will
|
||||
* occur but this is also the only time p_c2l will do
|
||||
* l= *(cp++) instead of l|= *(cp++)
|
||||
* Many thanks to Alex Tang <[email protected]> for pickup this
|
||||
* 'potential bug' */
|
||||
#ifdef PURIFY
|
||||
if ((j&0x03) == 0) p[i]=0;
|
||||
#endif
|
||||
l=p[i];
|
||||
p_c2l(cp,l,j&0x03);
|
||||
p[i]=l;
|
||||
i++;
|
||||
/* i is the next 'undefined word' */
|
||||
if (c->num >= MD5_LAST_BLOCK)
|
||||
{
|
||||
for (; i<MD5_LBLOCK; i++)
|
||||
p[i]=0;
|
||||
md5_block(c,p);
|
||||
i=0;
|
||||
}
|
||||
for (; i<(MD5_LBLOCK-2); i++)
|
||||
p[i]=0;
|
||||
p[MD5_LBLOCK-2]=c->Nl;
|
||||
p[MD5_LBLOCK-1]=c->Nh;
|
||||
md5_block(c,p);
|
||||
cp=md;
|
||||
l=c->A; l2c(l,cp);
|
||||
l=c->B; l2c(l,cp);
|
||||
l=c->C; l2c(l,cp);
|
||||
l=c->D; l2c(l,cp);
|
||||
|
||||
/* clear stuff, md5_block may be leaving some stuff on the stack
|
||||
* but I'm not worried :-) */
|
||||
c->num=0;
|
||||
/* memset((char *)&c,0,sizeof(c));*/
|
||||
}
|
||||
|
||||
#ifdef undef
|
||||
int printit(l)
|
||||
unsigned long *l;
|
||||
{
|
||||
int i,ii;
|
||||
|
||||
for (i=0; i<2; i++)
|
||||
{
|
||||
for (ii=0; ii<8; ii++)
|
||||
{
|
||||
fprintf(stderr,"%08lx ",l[i*8+ii]);
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* USE_MD5 */
|
||||
@@ -0,0 +1,190 @@
|
||||
/* crypto/md/md5_locl.h */
|
||||
/* Copyright (C) 1995-1997 Eric Young ([email protected])
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young ([email protected]).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson ([email protected]).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* 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 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 cryptographic software written by
|
||||
* Eric Young ([email protected])"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson ([email protected])"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 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.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "md5.h"
|
||||
|
||||
#define ULONG unsigned long
|
||||
#define UCHAR unsigned char
|
||||
#define UINT unsigned int
|
||||
|
||||
#if defined(NOCONST)
|
||||
#define const
|
||||
#endif
|
||||
|
||||
#undef c2l
|
||||
#define c2l(c,l) (l = ((unsigned long)(*((c)++))) , \
|
||||
l|=(((unsigned long)(*((c)++)))<< 8), \
|
||||
l|=(((unsigned long)(*((c)++)))<<16), \
|
||||
l|=(((unsigned long)(*((c)++)))<<24))
|
||||
|
||||
#undef p_c2l
|
||||
#define p_c2l(c,l,n) { \
|
||||
switch (n) { \
|
||||
case 0: l =((unsigned long)(*((c)++))); \
|
||||
case 1: l|=((unsigned long)(*((c)++)))<< 8; \
|
||||
case 2: l|=((unsigned long)(*((c)++)))<<16; \
|
||||
case 3: l|=((unsigned long)(*((c)++)))<<24; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* NOTE the pointer is not incremented at the end of this */
|
||||
#undef c2l_p
|
||||
#define c2l_p(c,l,n) { \
|
||||
l=0; \
|
||||
(c)+=n; \
|
||||
switch (n) { \
|
||||
case 3: l =((unsigned long)(*(--(c))))<<16; \
|
||||
case 2: l|=((unsigned long)(*(--(c))))<< 8; \
|
||||
case 1: l|=((unsigned long)(*(--(c)))) ; \
|
||||
} \
|
||||
}
|
||||
|
||||
#undef p_c2l_p
|
||||
#define p_c2l_p(c,l,sc,len) { \
|
||||
switch (sc) \
|
||||
{ \
|
||||
case 0: l =((unsigned long)(*((c)++))); \
|
||||
if (--len == 0) break; \
|
||||
case 1: l|=((unsigned long)(*((c)++)))<< 8; \
|
||||
if (--len == 0) break; \
|
||||
case 2: l|=((unsigned long)(*((c)++)))<<16; \
|
||||
} \
|
||||
}
|
||||
|
||||
#undef l2c
|
||||
#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>>16)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>>24)&0xff))
|
||||
|
||||
/* NOTE - c is not incremented as per l2c */
|
||||
#undef l2cn
|
||||
#define l2cn(l1,l2,c,n) { \
|
||||
c+=n; \
|
||||
switch (n) { \
|
||||
case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
|
||||
case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
|
||||
case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
|
||||
case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
|
||||
case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
|
||||
case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
|
||||
case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
|
||||
case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* A nice byte order reversal from Wei Dai <[email protected]> */
|
||||
#if defined(WIN32)
|
||||
/* 5 instructions with rotate instruction, else 9 */
|
||||
#define Endian_Reverse32(a) \
|
||||
{ \
|
||||
unsigned long l=(a); \
|
||||
(a)=((ROTATE(l,8)&0x00FF00FF)|(ROTATE(l,24)&0xFF00FF00)); \
|
||||
}
|
||||
#else
|
||||
/* 6 instructions with rotate instruction, else 8 */
|
||||
#define Endian_Reverse32(a) \
|
||||
{ \
|
||||
unsigned long l=(a); \
|
||||
l=(((l&0xFF00FF00)>>8L)|((l&0x00FF00FF)<<8L)); \
|
||||
(a)=ROTATE(l,16L); \
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
#define F(x,y,z) (((x) & (y)) | ((~(x)) & (z)))
|
||||
#define G(x,y,z) (((x) & (z)) | ((y) & (~(z))))
|
||||
*/
|
||||
|
||||
/* As pointed out by Wei Dai <[email protected]>, the above can be
|
||||
* simplified to the code below. Wei attributes these optimisations
|
||||
* to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
|
||||
*/
|
||||
#define F(x,y,z) ((((y) ^ (z)) & (x)) ^ (z))
|
||||
#define G(x,y,z) ((((x) ^ (y)) & (z)) ^ (y))
|
||||
#define H(x,y,z) ((x) ^ (y) ^ (z))
|
||||
#define I(x,y,z) (((x) | (~(z))) ^ (y))
|
||||
|
||||
#undef ROTATE
|
||||
#if defined(WIN32)
|
||||
#define ROTATE(a,n) _lrotl(a,n)
|
||||
#else
|
||||
#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
|
||||
#endif
|
||||
|
||||
|
||||
#define R0(a,b,c,d,k,s,t) { \
|
||||
a+=((k)+(t)+F((b),(c),(d))); \
|
||||
a=ROTATE(a,s); \
|
||||
a+=b; };\
|
||||
|
||||
#define R1(a,b,c,d,k,s,t) { \
|
||||
a+=((k)+(t)+G((b),(c),(d))); \
|
||||
a=ROTATE(a,s); \
|
||||
a+=b; };
|
||||
|
||||
#define R2(a,b,c,d,k,s,t) { \
|
||||
a+=((k)+(t)+H((b),(c),(d))); \
|
||||
a=ROTATE(a,s); \
|
||||
a+=b; };
|
||||
|
||||
#define R3(a,b,c,d,k,s,t) { \
|
||||
a+=((k)+(t)+I((b),(c),(d))); \
|
||||
a=ROTATE(a,s); \
|
||||
a+=b; };
|
||||
@@ -0,0 +1,350 @@
|
||||
static const char rcsid[] = "$Header: /tmp/bonefish/open-beos/current/src/kits/network/libbind/dst/support.c,v 1.1 2004/04/15 16:03:28 wkornew Exp $";
|
||||
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc.
|
||||
*
|
||||
* 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 TRUSTED INFORMATION SYSTEMS
|
||||
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
* TRUSTED INFORMATION SYSTEMS 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 THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include "dst_internal.h"
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
/*
|
||||
* dst_s_verify_str()
|
||||
* Validate that the input string(*str) is at the head of the input
|
||||
* buffer(**buf). If so, move the buffer head pointer (*buf) to
|
||||
* the first byte of data following the string(*str).
|
||||
* Parameters
|
||||
* buf Input buffer.
|
||||
* str Input string.
|
||||
* Return
|
||||
* 0 *str is not the head of **buff
|
||||
* 1 *str is the head of **buff, *buf is is advanced to
|
||||
* the tail of **buf.
|
||||
*/
|
||||
|
||||
int
|
||||
dst_s_verify_str(const char **buf, const char *str)
|
||||
{
|
||||
int b, s;
|
||||
if (*buf == NULL) /* error checks */
|
||||
return (0);
|
||||
if (str == NULL || *str == '\0')
|
||||
return (1);
|
||||
|
||||
b = strlen(*buf); /* get length of strings */
|
||||
s = strlen(str);
|
||||
if (s > b || strncmp(*buf, str, s)) /* check if same */
|
||||
return (0); /* not a match */
|
||||
(*buf) += s; /* advance pointer */
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* dst_s_calculate_bits
|
||||
* Given a binary number represented in a u_char[], determine
|
||||
* the number of significant bits used.
|
||||
* Parameters
|
||||
* str An input character string containing a binary number.
|
||||
* max_bits The maximum possible significant bits.
|
||||
* Return
|
||||
* N The number of significant bits in str.
|
||||
*/
|
||||
|
||||
int
|
||||
dst_s_calculate_bits(const u_char *str, const int max_bits)
|
||||
{
|
||||
const u_char *p = str;
|
||||
u_char i, j = 0x80;
|
||||
int bits;
|
||||
for (bits = max_bits; *p == 0x00 && bits > 0; p++)
|
||||
bits -= 8;
|
||||
for (i = *p; (i & j) != j; j >>= 1)
|
||||
bits--;
|
||||
return (bits);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* calculates a checksum used in dst for an id.
|
||||
* takes an array of bytes and a length.
|
||||
* returns a 16 bit checksum.
|
||||
*/
|
||||
u_int16_t
|
||||
dst_s_id_calc(const u_char *key, const int keysize)
|
||||
{
|
||||
u_int32_t ac;
|
||||
const u_char *kp = key;
|
||||
int size = keysize;
|
||||
|
||||
if (!key || (keysize <= 0))
|
||||
return (-1);
|
||||
|
||||
for (ac = 0; size > 1; size -= 2, kp += 2)
|
||||
ac += ((*kp) << 8) + *(kp + 1);
|
||||
|
||||
if (size > 0)
|
||||
ac += ((*kp) << 8);
|
||||
ac += (ac >> 16) & 0xffff;
|
||||
|
||||
return (ac & 0xffff);
|
||||
}
|
||||
|
||||
/*
|
||||
* dst_s_dns_key_id() Function to calculate DNSSEC footprint from KEY record
|
||||
* rdata
|
||||
* Input:
|
||||
* dns_key_rdata: the raw data in wire format
|
||||
* rdata_len: the size of the input data
|
||||
* Output:
|
||||
* the key footprint/id calculated from the key data
|
||||
*/
|
||||
u_int16_t
|
||||
dst_s_dns_key_id(const u_char *dns_key_rdata, const int rdata_len)
|
||||
{
|
||||
if (!dns_key_rdata)
|
||||
return 0;
|
||||
|
||||
/* compute id */
|
||||
if (dns_key_rdata[3] == KEY_RSA) /* Algorithm RSA */
|
||||
return dst_s_get_int16((const u_char *)
|
||||
&dns_key_rdata[rdata_len - 3]);
|
||||
else if (dns_key_rdata[3] == KEY_HMAC_MD5)
|
||||
/* compatibility */
|
||||
return 0;
|
||||
else
|
||||
/* compute a checksum on the key part of the key rr */
|
||||
return dst_s_id_calc(dns_key_rdata, rdata_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* dst_s_get_int16
|
||||
* This routine extracts a 16 bit integer from a two byte character
|
||||
* string. The character string is assumed to be in network byte
|
||||
* order and may be unaligned. The number returned is in host order.
|
||||
* Parameter
|
||||
* buf A two byte character string.
|
||||
* Return
|
||||
* The converted integer value.
|
||||
*/
|
||||
|
||||
u_int16_t
|
||||
dst_s_get_int16(const u_char *buf)
|
||||
{
|
||||
register u_int16_t a = 0;
|
||||
a = ((u_int16_t)(buf[0] << 8)) | ((u_int16_t)(buf[1]));
|
||||
return (a);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dst_s_get_int32
|
||||
* This routine extracts a 32 bit integer from a four byte character
|
||||
* string. The character string is assumed to be in network byte
|
||||
* order and may be unaligned. The number returned is in host order.
|
||||
* Parameter
|
||||
* buf A four byte character string.
|
||||
* Return
|
||||
* The converted integer value.
|
||||
*/
|
||||
|
||||
u_int32_t
|
||||
dst_s_get_int32(const u_char *buf)
|
||||
{
|
||||
register u_int32_t a = 0;
|
||||
a = ((u_int32_t)(buf[0] << 24)) | ((u_int32_t)(buf[1] << 16)) |
|
||||
((u_int32_t)(buf[2] << 8)) | ((u_int32_t)(buf[3]));
|
||||
return (a);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dst_s_put_int16
|
||||
* Take a 16 bit integer and store the value in a two byte
|
||||
* character string. The integer is assumed to be in network
|
||||
* order and the string is returned in host order.
|
||||
*
|
||||
* Parameters
|
||||
* buf Storage for a two byte character string.
|
||||
* val 16 bit integer.
|
||||
*/
|
||||
|
||||
void
|
||||
dst_s_put_int16(u_int8_t *buf, const u_int16_t val)
|
||||
{
|
||||
buf[0] = (u_int8_t)(val >> 8);
|
||||
buf[1] = (u_int8_t)(val);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dst_s_put_int32
|
||||
* Take a 32 bit integer and store the value in a four byte
|
||||
* character string. The integer is assumed to be in network
|
||||
* order and the string is returned in host order.
|
||||
*
|
||||
* Parameters
|
||||
* buf Storage for a four byte character string.
|
||||
* val 32 bit integer.
|
||||
*/
|
||||
|
||||
void
|
||||
dst_s_put_int32(u_int8_t *buf, const u_int32_t val)
|
||||
{
|
||||
buf[0] = (u_int8_t)(val >> 24);
|
||||
buf[1] = (u_int8_t)(val >> 16);
|
||||
buf[2] = (u_int8_t)(val >> 8);
|
||||
buf[3] = (u_int8_t)(val);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dst_s_filename_length
|
||||
*
|
||||
* This function returns the number of bytes needed to hold the
|
||||
* filename for a key file. '/', '\' and ':' are not allowed.
|
||||
* form: K<keyname>+<alg>+<id>.<suffix>
|
||||
*
|
||||
* Returns 0 if the filename would contain either '\', '/' or ':'
|
||||
*/
|
||||
size_t
|
||||
dst_s_filename_length(const char *name, const char *suffix)
|
||||
{
|
||||
if (name == NULL)
|
||||
return (0);
|
||||
if (strrchr(name, '\\'))
|
||||
return (0);
|
||||
if (strrchr(name, '/'))
|
||||
return (0);
|
||||
if (strrchr(name, ':'))
|
||||
return (0);
|
||||
if (suffix == NULL)
|
||||
return (0);
|
||||
if (strrchr(suffix, '\\'))
|
||||
return (0);
|
||||
if (strrchr(suffix, '/'))
|
||||
return (0);
|
||||
if (strrchr(suffix, ':'))
|
||||
return (0);
|
||||
return (1 + strlen(name) + 6 + strlen(suffix));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dst_s_build_filename ()
|
||||
* Builds a key filename from the key name, it's id, and a
|
||||
* suffix. '\', '/' and ':' are not allowed. fA filename is of the
|
||||
* form: K<keyname><id>.<suffix>
|
||||
* form: K<keyname>+<alg>+<id>.<suffix>
|
||||
*
|
||||
* Returns -1 if the conversion fails:
|
||||
* if the filename would be too long for space allotted
|
||||
* if the filename would contain a '\', '/' or ':'
|
||||
* Returns 0 on success
|
||||
*/
|
||||
|
||||
int
|
||||
dst_s_build_filename(char *filename, const char *name, u_int16_t id,
|
||||
int alg, const char *suffix, size_t filename_length)
|
||||
{
|
||||
u_int32_t my_id;
|
||||
if (filename == NULL)
|
||||
return (-1);
|
||||
memset(filename, 0, filename_length);
|
||||
if (name == NULL)
|
||||
return (-1);
|
||||
if (suffix == NULL)
|
||||
return (-1);
|
||||
if (filename_length < 1 + strlen(name) + 4 + 6 + 1 + strlen(suffix))
|
||||
return (-1);
|
||||
my_id = id;
|
||||
sprintf(filename, "K%s+%03d+%05d.%s", name, alg, my_id,
|
||||
(const char *) suffix);
|
||||
if (strrchr(filename, '/'))
|
||||
return (-1);
|
||||
if (strrchr(filename, '\\'))
|
||||
return (-1);
|
||||
if (strrchr(filename, ':'))
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* dst_s_fopen ()
|
||||
* Open a file in the dst_path directory. If perm is specified, the
|
||||
* file is checked for existence first, and not opened if it exists.
|
||||
* Parameters
|
||||
* filename File to open
|
||||
* mode Mode to open the file (passed directly to fopen)
|
||||
* perm File permission, if creating a new file.
|
||||
* Returns
|
||||
* NULL Failure
|
||||
* NON-NULL (FILE *) of opened file.
|
||||
*/
|
||||
FILE *
|
||||
dst_s_fopen(const char *filename, const char *mode, int perm)
|
||||
{
|
||||
FILE *fp;
|
||||
char pathname[PATH_MAX];
|
||||
size_t plen = sizeof(pathname);
|
||||
|
||||
if (*dst_path != '\0') {
|
||||
strcpy(pathname, dst_path);
|
||||
plen -= strlen(pathname);
|
||||
}
|
||||
else
|
||||
pathname[0] = '\0';
|
||||
|
||||
if (plen > strlen(filename))
|
||||
strncpy(&pathname[PATH_MAX - plen], filename, plen-1);
|
||||
else
|
||||
return (NULL);
|
||||
|
||||
fp = fopen(pathname, mode);
|
||||
if (perm)
|
||||
chmod(pathname, perm);
|
||||
return (fp);
|
||||
}
|
||||
|
||||
void
|
||||
dst_s_dump(const int mode, const u_char *data, const int size,
|
||||
const char *msg)
|
||||
{
|
||||
UNUSED(data);
|
||||
|
||||
if (size > 0) {
|
||||
#ifdef LONG_TEST
|
||||
static u_char scratch[1000];
|
||||
int n ;
|
||||
n = b64_ntop(data, scratch, size, sizeof(scratch));
|
||||
printf("%s: %x %d %s\n", msg, mode, n, scratch);
|
||||
#else
|
||||
printf("%s,%x %d\n", msg, mode, size);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef PTHREAD_EMU_H
|
||||
#define PTHREAD_EMU_H
|
||||
|
||||
#include <TLS.h>
|
||||
#include <pthread.h>
|
||||
#include <OS.h>
|
||||
|
||||
|
||||
typedef int32 pthread_key_t;
|
||||
|
||||
|
||||
extern pthread_mutex_t pthread_mutex_static_initializer(void);
|
||||
|
||||
extern int pthread_key_create(pthread_key_t *key, void (*destructor)(void *));
|
||||
extern int pthread_setspecific(pthread_key_t key, void *value);
|
||||
extern void *pthread_getspecific(pthread_key_t key);
|
||||
|
||||
|
||||
#endif /* PTHREAD_EMU_H */
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef _SYS_UN_H
|
||||
#define _SYS_UN_H
|
||||
|
||||
|
||||
/* TODO: implement */
|
||||
|
||||
|
||||
#endif /* _SYS_UN_H */
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef UTMP_H
|
||||
#define UTMP_H
|
||||
|
||||
|
||||
/* TODO: implement */
|
||||
|
||||
|
||||
#endif /* UTMP_H */
|
||||
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1990, 1993
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
|
||||
*
|
||||
* 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, and that
|
||||
* the name of Digital Equipment Corporation not be used in advertising or
|
||||
* publicity pertaining to distribution of the document or software without
|
||||
* specific, written prior permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
|
||||
* CORPORATION 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1996-1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
|
||||
static const char rcsid[] = "$Id: inet_addr.c,v 1.1 2004/04/15 16:03:28 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
/*
|
||||
* Ascii internet address interpretation routine.
|
||||
* The value returned is in network order.
|
||||
*/
|
||||
u_long
|
||||
inet_addr(const char *cp) {
|
||||
struct in_addr val;
|
||||
|
||||
if (inet_aton(cp, &val))
|
||||
return (val.s_addr);
|
||||
return (INADDR_NONE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether "cp" is a valid ascii representation
|
||||
* of an Internet address and convert to a binary address.
|
||||
* Returns 1 if the address is valid, 0 if not.
|
||||
* This replaces inet_addr, the return value from which
|
||||
* cannot distinguish between failure and a local broadcast address.
|
||||
*/
|
||||
int
|
||||
inet_aton(const char *cp, struct in_addr *addr) {
|
||||
u_long val;
|
||||
int base, n;
|
||||
char c;
|
||||
u_int8_t parts[4];
|
||||
u_int8_t *pp = parts;
|
||||
int digit;
|
||||
|
||||
c = *cp;
|
||||
for (;;) {
|
||||
/*
|
||||
* Collect number up to ``.''.
|
||||
* Values are specified as for C:
|
||||
* 0x=hex, 0=octal, isdigit=decimal.
|
||||
*/
|
||||
if (!isdigit((unsigned char)c))
|
||||
return (0);
|
||||
val = 0; base = 10; digit = 0;
|
||||
if (c == '0') {
|
||||
c = *++cp;
|
||||
if (c == 'x' || c == 'X')
|
||||
base = 16, c = *++cp;
|
||||
else {
|
||||
base = 8;
|
||||
digit = 1 ;
|
||||
}
|
||||
}
|
||||
for (;;) {
|
||||
if (isascii(c) && isdigit((unsigned char)c)) {
|
||||
if (base == 8 && (c == '8' || c == '9'))
|
||||
return (0);
|
||||
val = (val * base) + (c - '0');
|
||||
c = *++cp;
|
||||
digit = 1;
|
||||
} else if (base == 16 && isascii(c) &&
|
||||
isxdigit((unsigned char)c)) {
|
||||
val = (val << 4) |
|
||||
(c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
|
||||
c = *++cp;
|
||||
digit = 1;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
if (c == '.') {
|
||||
/*
|
||||
* Internet format:
|
||||
* a.b.c.d
|
||||
* a.b.c (with c treated as 16 bits)
|
||||
* a.b (with b treated as 24 bits)
|
||||
*/
|
||||
if (pp >= parts + 3 || val > 0xff)
|
||||
return (0);
|
||||
*pp++ = val;
|
||||
c = *++cp;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Check for trailing characters.
|
||||
*/
|
||||
if (c != '\0' && (!isascii(c) || !isspace((unsigned char)c)))
|
||||
return (0);
|
||||
/*
|
||||
* Did we get a valid digit?
|
||||
*/
|
||||
if (!digit)
|
||||
return (0);
|
||||
/*
|
||||
* Concoct the address according to
|
||||
* the number of parts specified.
|
||||
*/
|
||||
n = pp - parts + 1;
|
||||
switch (n) {
|
||||
case 1: /* a -- 32 bits */
|
||||
break;
|
||||
|
||||
case 2: /* a.b -- 8.24 bits */
|
||||
if (val > 0xffffff)
|
||||
return (0);
|
||||
val |= parts[0] << 24;
|
||||
break;
|
||||
|
||||
case 3: /* a.b.c -- 8.8.16 bits */
|
||||
if (val > 0xffff)
|
||||
return (0);
|
||||
val |= (parts[0] << 24) | (parts[1] << 16);
|
||||
break;
|
||||
|
||||
case 4: /* a.b.c.d -- 8.8.8.8 bits */
|
||||
if (val > 0xff)
|
||||
return (0);
|
||||
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
|
||||
break;
|
||||
}
|
||||
if (addr != NULL)
|
||||
addr->s_addr = htonl(val);
|
||||
return (1);
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Copyright (c) 1998,1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: inet_cidr_ntop.c,v 1.1 2004/04/15 16:03:28 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) ((size_t)sprintf x)
|
||||
#endif
|
||||
|
||||
static char * inet_cidr_ntop_ipv4 __P((const u_char *src, int bits,
|
||||
char *dst, size_t size));
|
||||
static char * inet_cidr_ntop_ipv6 __P((const u_char *src, int bits,
|
||||
char *dst, size_t size));
|
||||
|
||||
/*
|
||||
* char *
|
||||
* inet_cidr_ntop(af, src, bits, dst, size)
|
||||
* convert network address from network to presentation format.
|
||||
* "src"'s size is determined from its "af".
|
||||
* return:
|
||||
* pointer to dst, or NULL if an error occurred (check errno).
|
||||
* note:
|
||||
* 192.5.5.1/28 has a nonzero host part, which means it isn't a network
|
||||
* as called for by inet_net_ntop() but it can be a host address with
|
||||
* an included netmask.
|
||||
* author:
|
||||
* Paul Vixie (ISC), October 1998
|
||||
*/
|
||||
char *
|
||||
inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size) {
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_cidr_ntop_ipv4(src, bits, dst, size));
|
||||
case AF_INET6:
|
||||
return (inet_cidr_ntop_ipv6(src, bits, dst, size));
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
decoct(const u_char *src, int bytes, char *dst, size_t size) {
|
||||
char *odst = dst;
|
||||
char *t;
|
||||
int b;
|
||||
|
||||
for (b = 1; b <= bytes; b++) {
|
||||
if (size < sizeof "255.")
|
||||
return (0);
|
||||
t = dst;
|
||||
dst += SPRINTF((dst, "%u", *src++));
|
||||
if (b != bytes) {
|
||||
*dst++ = '.';
|
||||
*dst = '\0';
|
||||
}
|
||||
size -= (size_t)(dst - t);
|
||||
}
|
||||
return (dst - odst);
|
||||
}
|
||||
|
||||
/*
|
||||
* static char *
|
||||
* inet_cidr_ntop_ipv4(src, bits, dst, size)
|
||||
* convert IPv4 network address from network to presentation format.
|
||||
* "src"'s size is determined from its "af".
|
||||
* return:
|
||||
* pointer to dst, or NULL if an error occurred (check errno).
|
||||
* note:
|
||||
* network byte order assumed. this means 192.5.5.240/28 has
|
||||
* 0b11110000 in its fourth octet.
|
||||
* author:
|
||||
* Paul Vixie (ISC), October 1998
|
||||
*/
|
||||
static char *
|
||||
inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) {
|
||||
char *odst = dst;
|
||||
size_t len = 4;
|
||||
size_t b;
|
||||
size_t bytes;
|
||||
|
||||
if ((bits < -1) || (bits > 32)) {
|
||||
errno = EINVAL;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Find number of significant bytes in address. */
|
||||
if (bits == -1)
|
||||
len = 4;
|
||||
else
|
||||
for (len = 1, b = 1 ; b < 4; b++)
|
||||
if (*(src + b))
|
||||
len = b + 1;
|
||||
|
||||
/* Format whole octets plus nonzero trailing octets. */
|
||||
bytes = (((bits <= 0) ? 1 : bits) + 7) / 8;
|
||||
if (len > bytes)
|
||||
bytes = len;
|
||||
b = decoct(src, bytes, dst, size);
|
||||
if (b == 0)
|
||||
goto emsgsize;
|
||||
dst += b;
|
||||
size -= b;
|
||||
|
||||
if (bits != -1) {
|
||||
/* Format CIDR /width. */
|
||||
if (size < sizeof "/32")
|
||||
goto emsgsize;
|
||||
dst += SPRINTF((dst, "/%u", bits));
|
||||
}
|
||||
|
||||
return (odst);
|
||||
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static char *
|
||||
inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) {
|
||||
/*
|
||||
* Note that int32_t and int16_t need only be "at least" large enough
|
||||
* to contain a value of the specified size. On some systems, like
|
||||
* Crays, there is no such thing as an integer variable with 16 bits.
|
||||
* Keep this in mind if you think this function should have been coded
|
||||
* to use pointer overlays. All the world's not a VAX.
|
||||
*/
|
||||
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255/128"];
|
||||
char *tp;
|
||||
struct { int base, len; } best, cur;
|
||||
u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
|
||||
int i;
|
||||
|
||||
if ((bits < -1) || (bits > 128)) {
|
||||
errno = EINVAL;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Preprocess:
|
||||
* Copy the input (bytewise) array into a wordwise array.
|
||||
* Find the longest run of 0x00's in src[] for :: shorthanding.
|
||||
*/
|
||||
memset(words, '\0', sizeof words);
|
||||
for (i = 0; i < NS_IN6ADDRSZ; i++)
|
||||
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||
best.base = -1;
|
||||
cur.base = -1;
|
||||
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
|
||||
if (words[i] == 0) {
|
||||
if (cur.base == -1)
|
||||
cur.base = i, cur.len = 1;
|
||||
else
|
||||
cur.len++;
|
||||
} else {
|
||||
if (cur.base != -1) {
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
cur.base = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cur.base != -1) {
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
}
|
||||
if (best.base != -1 && best.len < 2)
|
||||
best.base = -1;
|
||||
|
||||
/*
|
||||
* Format the result.
|
||||
*/
|
||||
tp = tmp;
|
||||
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
|
||||
/* Are we inside the best run of 0x00's? */
|
||||
if (best.base != -1 && i >= best.base &&
|
||||
i < (best.base + best.len)) {
|
||||
if (i == best.base)
|
||||
*tp++ = ':';
|
||||
continue;
|
||||
}
|
||||
/* Are we following an initial run of 0x00s or any real hex? */
|
||||
if (i != 0)
|
||||
*tp++ = ':';
|
||||
/* Is this address an encapsulated IPv4? */
|
||||
if (i == 6 && best.base == 0 && (best.len == 6 ||
|
||||
(best.len == 7 && words[7] != 0x0001) ||
|
||||
(best.len == 5 && words[5] == 0xffff))) {
|
||||
int n;
|
||||
|
||||
if (src[15] || bits == -1 || bits > 120)
|
||||
n = 4;
|
||||
else if (src[14] || bits > 112)
|
||||
n = 3;
|
||||
else
|
||||
n = 2;
|
||||
n = decoct(src+12, n, tp, sizeof tmp - (tp - tmp));
|
||||
if (n == 0) {
|
||||
errno = EMSGSIZE;
|
||||
return (NULL);
|
||||
}
|
||||
tp += strlen(tp);
|
||||
break;
|
||||
}
|
||||
tp += SPRINTF((tp, "%x", words[i]));
|
||||
}
|
||||
|
||||
/* Was it a trailing run of 0x00's? */
|
||||
if (best.base != -1 && (best.base + best.len) ==
|
||||
(NS_IN6ADDRSZ / NS_INT16SZ))
|
||||
*tp++ = ':';
|
||||
*tp = '\0';
|
||||
|
||||
if (bits != -1)
|
||||
tp += SPRINTF((tp, "/%u", bits));
|
||||
|
||||
/*
|
||||
* Check for overflow, copy, and we're done.
|
||||
*/
|
||||
if ((size_t)(tp - tmp) > size) {
|
||||
errno = EMSGSIZE;
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
return (dst);
|
||||
}
|
||||
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
* Copyright (c) 1998,1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: inet_cidr_pton.c,v 1.1 2004/04/15 16:03:28 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <isc/assertions.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) ((size_t)sprintf x)
|
||||
#endif
|
||||
|
||||
static int inet_cidr_pton_ipv4 __P((const char *src, u_char *dst,
|
||||
int *bits, int ipv6));
|
||||
static int inet_cidr_pton_ipv6 __P((const char *src, u_char *dst,
|
||||
int *bits));
|
||||
|
||||
static int getbits(const char *, int ipv6);
|
||||
|
||||
/*
|
||||
* int
|
||||
* inet_cidr_pton(af, src, dst, *bits)
|
||||
* convert network address from presentation to network format.
|
||||
* accepts inet_pton()'s input for this "af" plus trailing "/CIDR".
|
||||
* "dst" is assumed large enough for its "af". "bits" is set to the
|
||||
* /CIDR prefix length, which can have defaults (like /32 for IPv4).
|
||||
* return:
|
||||
* -1 if an error occurred (inspect errno; ENOENT means bad format).
|
||||
* 0 if successful conversion occurred.
|
||||
* note:
|
||||
* 192.5.5.1/28 has a nonzero host part, which means it isn't a network
|
||||
* as called for by inet_net_pton() but it can be a host address with
|
||||
* an included netmask.
|
||||
* author:
|
||||
* Paul Vixie (ISC), October 1998
|
||||
*/
|
||||
int
|
||||
inet_cidr_pton(int af, const char *src, void *dst, int *bits) {
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_cidr_pton_ipv4(src, dst, bits, 0));
|
||||
case AF_INET6:
|
||||
return (inet_cidr_pton_ipv6(src, dst, bits));
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
static const char digits[] = "0123456789";
|
||||
|
||||
static int
|
||||
inet_cidr_pton_ipv4(const char *src, u_char *dst, int *pbits, int ipv6) {
|
||||
const u_char *odst = dst;
|
||||
int n, ch, tmp, bits;
|
||||
size_t size = 4;
|
||||
|
||||
/* Get the mantissa. */
|
||||
while (ch = *src++, (isascii(ch) && isdigit(ch))) {
|
||||
tmp = 0;
|
||||
do {
|
||||
n = strchr(digits, ch) - digits;
|
||||
INSIST(n >= 0 && n <= 9);
|
||||
tmp *= 10;
|
||||
tmp += n;
|
||||
if (tmp > 255)
|
||||
goto enoent;
|
||||
} while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch));
|
||||
if (size-- == 0)
|
||||
goto emsgsize;
|
||||
*dst++ = (u_char) tmp;
|
||||
if (ch == '\0' || ch == '/')
|
||||
break;
|
||||
if (ch != '.')
|
||||
goto enoent;
|
||||
}
|
||||
|
||||
/* Get the prefix length if any. */
|
||||
bits = -1;
|
||||
if (ch == '/' && dst > odst) {
|
||||
bits = getbits(src, ipv6);
|
||||
if (bits == -2)
|
||||
goto enoent;
|
||||
} else if (ch != '\0')
|
||||
goto enoent;
|
||||
|
||||
/* Prefix length can default to /32 only if all four octets spec'd. */
|
||||
if (bits == -1) {
|
||||
if (dst - odst == 4)
|
||||
bits = ipv6 ? 128 : 32;
|
||||
else
|
||||
goto enoent;
|
||||
}
|
||||
|
||||
/* If nothing was written to the destination, we found no address. */
|
||||
if (dst == odst)
|
||||
goto enoent;
|
||||
|
||||
/* If prefix length overspecifies mantissa, life is bad. */
|
||||
if (((bits - (ipv6 ? 96 : 0)) / 8) > (dst - odst))
|
||||
goto enoent;
|
||||
|
||||
/* Extend address to four octets. */
|
||||
while (size-- > 0)
|
||||
*dst++ = 0;
|
||||
|
||||
*pbits = bits;
|
||||
return (0);
|
||||
|
||||
enoent:
|
||||
errno = ENOENT;
|
||||
return (-1);
|
||||
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
inet_cidr_pton_ipv6(const char *src, u_char *dst, int *pbits) {
|
||||
static const char xdigits_l[] = "0123456789abcdef",
|
||||
xdigits_u[] = "0123456789ABCDEF";
|
||||
u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
|
||||
const char *xdigits, *curtok;
|
||||
int ch, saw_xdigit;
|
||||
u_int val;
|
||||
int bits;
|
||||
|
||||
memset((tp = tmp), '\0', NS_IN6ADDRSZ);
|
||||
endp = tp + NS_IN6ADDRSZ;
|
||||
colonp = NULL;
|
||||
/* Leading :: requires some special handling. */
|
||||
if (*src == ':')
|
||||
if (*++src != ':')
|
||||
return (0);
|
||||
curtok = src;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
bits = -1;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
|
||||
pch = strchr((xdigits = xdigits_u), ch);
|
||||
if (pch != NULL) {
|
||||
val <<= 4;
|
||||
val |= (pch - xdigits);
|
||||
if (val > 0xffff)
|
||||
return (0);
|
||||
saw_xdigit = 1;
|
||||
continue;
|
||||
}
|
||||
if (ch == ':') {
|
||||
curtok = src;
|
||||
if (!saw_xdigit) {
|
||||
if (colonp)
|
||||
return (0);
|
||||
colonp = tp;
|
||||
continue;
|
||||
} else if (*src == '\0') {
|
||||
return (0);
|
||||
}
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (u_char) (val >> 8) & 0xff;
|
||||
*tp++ = (u_char) val & 0xff;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
|
||||
inet_cidr_pton_ipv4(curtok, tp, &bits, 1) == 0) {
|
||||
tp += NS_INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
break; /* '\0' was seen by inet_pton4(). */
|
||||
}
|
||||
if (ch == '/') {
|
||||
bits = getbits(src, 1);
|
||||
if (bits == -2)
|
||||
goto enoent;
|
||||
break;
|
||||
}
|
||||
goto enoent;
|
||||
}
|
||||
if (saw_xdigit) {
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
goto emsgsize;
|
||||
*tp++ = (u_char) (val >> 8) & 0xff;
|
||||
*tp++ = (u_char) val & 0xff;
|
||||
}
|
||||
if (colonp != NULL) {
|
||||
/*
|
||||
* Since some memmove()'s erroneously fail to handle
|
||||
* overlapping regions, we'll do the shift by hand.
|
||||
*/
|
||||
const int n = tp - colonp;
|
||||
int i;
|
||||
|
||||
if (tp == endp)
|
||||
goto enoent;
|
||||
for (i = 1; i <= n; i++) {
|
||||
endp[- i] = colonp[n - i];
|
||||
colonp[n - i] = 0;
|
||||
}
|
||||
tp = endp;
|
||||
}
|
||||
|
||||
memcpy(dst, tmp, NS_IN6ADDRSZ);
|
||||
|
||||
*pbits = bits;
|
||||
return (0);
|
||||
|
||||
enoent:
|
||||
errno = ENOENT;
|
||||
return (-1);
|
||||
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
getbits(const char *src, int ipv6) {
|
||||
int bits = 0;
|
||||
char *cp, ch;
|
||||
|
||||
if (*src == '\0') /* syntax */
|
||||
return (-2);
|
||||
do {
|
||||
ch = *src++;
|
||||
cp = strchr(digits, ch);
|
||||
if (cp == NULL) /* syntax */
|
||||
return (-2);
|
||||
bits *= 10;
|
||||
bits += cp - digits;
|
||||
if (bits == 0 && *src != '\0') /* no leading zeros */
|
||||
return (-2);
|
||||
if (bits > (ipv6 ? 128 : 32)) /* range error */
|
||||
return (-2);
|
||||
} while (*src != '\0');
|
||||
|
||||
return (bits);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 1995-1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char rcsid[] = "$Id: inet_data.c,v 1.1 2004/04/15 16:03:28 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
const struct in6_addr isc_in6addr_any = IN6ADDR_ANY_INIT;
|
||||
const struct in6_addr isc_in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char sccsid[] = "@(#)inet_lnaof.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
/*
|
||||
* Return the local network address portion of an
|
||||
* internet address; handles class a/b/c network
|
||||
* number formats.
|
||||
*/
|
||||
u_long
|
||||
inet_lnaof(in)
|
||||
struct in_addr in;
|
||||
{
|
||||
register u_long i = ntohl(in.s_addr);
|
||||
|
||||
if (IN_CLASSA(i))
|
||||
return ((i)&IN_CLASSA_HOST);
|
||||
else if (IN_CLASSB(i))
|
||||
return ((i)&IN_CLASSB_HOST);
|
||||
else
|
||||
return ((i)&IN_CLASSC_HOST);
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char sccsid[] = "@(#)inet_makeaddr.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
/*
|
||||
* Formulate an Internet address from network + host. Used in
|
||||
* building addresses stored in the ifnet structure.
|
||||
*/
|
||||
struct in_addr
|
||||
inet_makeaddr(net, host)
|
||||
u_long net, host;
|
||||
{
|
||||
u_long addr;
|
||||
|
||||
if (net < 128)
|
||||
addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST);
|
||||
else if (net < 65536)
|
||||
addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST);
|
||||
else if (net < 16777216L)
|
||||
addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST);
|
||||
else
|
||||
addr = net | host;
|
||||
addr = htonl(addr);
|
||||
return (*(struct in_addr *)&addr);
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.1 2004/04/15 16:03:28 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) ((size_t)sprintf x)
|
||||
#endif
|
||||
|
||||
static char * inet_net_ntop_ipv4 __P((const u_char *src, int bits,
|
||||
char *dst, size_t size));
|
||||
static char * inet_net_ntop_ipv6 __P((const u_char *src, int bits,
|
||||
char *dst, size_t size));
|
||||
|
||||
/*
|
||||
* char *
|
||||
* inet_net_ntop(af, src, bits, dst, size)
|
||||
* convert network number from network to presentation format.
|
||||
* generates CIDR style result always.
|
||||
* return:
|
||||
* pointer to dst, or NULL if an error occurred (check errno).
|
||||
* author:
|
||||
* Paul Vixie (ISC), July 1996
|
||||
*/
|
||||
char *
|
||||
inet_net_ntop(af, src, bits, dst, size)
|
||||
int af;
|
||||
const void *src;
|
||||
int bits;
|
||||
char *dst;
|
||||
size_t size;
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_net_ntop_ipv4(src, bits, dst, size));
|
||||
case AF_INET6:
|
||||
return (inet_net_ntop_ipv6(src, bits, dst, size));
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* static char *
|
||||
* inet_net_ntop_ipv4(src, bits, dst, size)
|
||||
* convert IPv4 network number from network to presentation format.
|
||||
* generates CIDR style result always.
|
||||
* return:
|
||||
* pointer to dst, or NULL if an error occurred (check errno).
|
||||
* note:
|
||||
* network byte order assumed. this means 192.5.5.240/28 has
|
||||
* 0b11110000 in its fourth octet.
|
||||
* author:
|
||||
* Paul Vixie (ISC), July 1996
|
||||
*/
|
||||
static char *
|
||||
inet_net_ntop_ipv4(src, bits, dst, size)
|
||||
const u_char *src;
|
||||
int bits;
|
||||
char *dst;
|
||||
size_t size;
|
||||
{
|
||||
char *odst = dst;
|
||||
char *t;
|
||||
u_int m;
|
||||
int b;
|
||||
|
||||
if (bits < 0 || bits > 32) {
|
||||
errno = EINVAL;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (bits == 0) {
|
||||
if (size < sizeof "0")
|
||||
goto emsgsize;
|
||||
*dst++ = '0';
|
||||
size--;
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
/* Format whole octets. */
|
||||
for (b = bits / 8; b > 0; b--) {
|
||||
if (size <= sizeof "255.")
|
||||
goto emsgsize;
|
||||
t = dst;
|
||||
dst += SPRINTF((dst, "%u", *src++));
|
||||
if (b > 1) {
|
||||
*dst++ = '.';
|
||||
*dst = '\0';
|
||||
}
|
||||
size -= (size_t)(dst - t);
|
||||
}
|
||||
|
||||
/* Format partial octet. */
|
||||
b = bits % 8;
|
||||
if (b > 0) {
|
||||
if (size <= sizeof ".255")
|
||||
goto emsgsize;
|
||||
t = dst;
|
||||
if (dst != odst)
|
||||
*dst++ = '.';
|
||||
m = ((1 << b) - 1) << (8 - b);
|
||||
dst += SPRINTF((dst, "%u", *src & m));
|
||||
size -= (size_t)(dst - t);
|
||||
}
|
||||
|
||||
/* Format CIDR /width. */
|
||||
if (size <= sizeof "/32")
|
||||
goto emsgsize;
|
||||
dst += SPRINTF((dst, "/%u", bits));
|
||||
return (odst);
|
||||
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* static char *
|
||||
* inet_net_ntop_ipv6(src, bits, fakebits, dst, size)
|
||||
* convert IPv6 network number from network to presentation format.
|
||||
* generates CIDR style result always. Picks the shortest representation
|
||||
* unless the IP is really IPv4.
|
||||
* always prints specified number of bits (bits).
|
||||
* return:
|
||||
* pointer to dst, or NULL if an error occurred (check errno).
|
||||
* note:
|
||||
* network byte order assumed. this means 192.5.5.240/28 has
|
||||
* 0x11110000 in its fourth octet.
|
||||
* author:
|
||||
* Vadim Kogan (UCB), June 2001
|
||||
* Original version (IPv4) by Paul Vixie (ISC), July 1996
|
||||
*/
|
||||
|
||||
static char *
|
||||
inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) {
|
||||
u_int m;
|
||||
int b;
|
||||
int p;
|
||||
int zero_s, zero_l, tmp_zero_s, tmp_zero_l;
|
||||
int i;
|
||||
int is_ipv4 = 0;
|
||||
unsigned char inbuf[16];
|
||||
char outbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
|
||||
char *cp;
|
||||
int words;
|
||||
u_char *s;
|
||||
|
||||
if (bits < 0 || bits > 128) {
|
||||
errno = EINVAL;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
cp = outbuf;
|
||||
|
||||
if (bits == 0) {
|
||||
*cp++ = ':';
|
||||
*cp++ = ':';
|
||||
*cp = '\0';
|
||||
} else {
|
||||
/* Copy src to private buffer. Zero host part. */
|
||||
p = (bits + 7) / 8;
|
||||
memcpy(inbuf, src, p);
|
||||
memset(inbuf + p, 0, 16 - p);
|
||||
b = bits % 8;
|
||||
if (b != 0) {
|
||||
m = ~0 << (8 - b);
|
||||
inbuf[p-1] &= m;
|
||||
}
|
||||
|
||||
s = inbuf;
|
||||
|
||||
/* how many words need to be displayed in output */
|
||||
words = (bits + 15) / 16;
|
||||
if (words == 1)
|
||||
words = 2;
|
||||
|
||||
/* Find the longest substring of zero's */
|
||||
zero_s = zero_l = tmp_zero_s = tmp_zero_l = 0;
|
||||
for (i = 0; i < (words * 2); i += 2) {
|
||||
if ((s[i] | s[i+1]) == 0) {
|
||||
if (tmp_zero_l == 0)
|
||||
tmp_zero_s = i / 2;
|
||||
tmp_zero_l++;
|
||||
} else {
|
||||
if (tmp_zero_l && zero_l < tmp_zero_l) {
|
||||
zero_s = tmp_zero_s;
|
||||
zero_l = tmp_zero_l;
|
||||
tmp_zero_l = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tmp_zero_l && zero_l < tmp_zero_l) {
|
||||
zero_s = tmp_zero_s;
|
||||
zero_l = tmp_zero_l;
|
||||
}
|
||||
|
||||
if (zero_l != words && zero_s == 0 && ((zero_l == 6) ||
|
||||
((zero_l == 5 && s[10] == 0xff && s[11] == 0xff) ||
|
||||
((zero_l == 7 && s[14] != 0 && s[15] != 1)))))
|
||||
is_ipv4 = 1;
|
||||
|
||||
/* Format whole words. */
|
||||
for (p = 0; p < words; p++) {
|
||||
if (zero_l != 0 && p >= zero_s && p < zero_s + zero_l) {
|
||||
/* Time to skip some zeros */
|
||||
if (p == zero_s)
|
||||
*cp++ = ':';
|
||||
if (p == words - 1)
|
||||
*cp++ = ':';
|
||||
s++;
|
||||
s++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_ipv4 && p > 5 ) {
|
||||
*cp++ = (p == 6) ? ':' : '.';
|
||||
cp += SPRINTF((cp, "%u", *s++));
|
||||
/* we can potentially drop the last octet */
|
||||
if (p != 7 || bits > 120) {
|
||||
*cp++ = '.';
|
||||
cp += SPRINTF((cp, "%u", *s++));
|
||||
}
|
||||
} else {
|
||||
if (cp != outbuf)
|
||||
*cp++ = ':';
|
||||
cp += SPRINTF((cp, "%x", *s * 256 + s[1]));
|
||||
s += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Format CIDR /width. */
|
||||
SPRINTF((cp, "/%u", bits));
|
||||
if (strlen(outbuf) + 1 > size)
|
||||
goto emsgsize;
|
||||
strcpy(dst, outbuf);
|
||||
|
||||
return (dst);
|
||||
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (NULL);
|
||||
}
|
||||
@@ -0,0 +1,399 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: inet_net_pton.c,v 1.1 2004/04/15 16:03:28 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <isc/assertions.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) ((size_t)sprintf x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* static int
|
||||
* inet_net_pton_ipv4(src, dst, size)
|
||||
* convert IPv4 network number from presentation to network format.
|
||||
* accepts hex octets, hex strings, decimal octets, and /CIDR.
|
||||
* "size" is in bytes and describes "dst".
|
||||
* return:
|
||||
* number of bits, either imputed classfully or specified with /CIDR,
|
||||
* or -1 if some failure occurred (check errno). ENOENT means it was
|
||||
* not an IPv4 network specification.
|
||||
* note:
|
||||
* network byte order assumed. this means 192.5.5.240/28 has
|
||||
* 0b11110000 in its fourth octet.
|
||||
* author:
|
||||
* Paul Vixie (ISC), June 1996
|
||||
*/
|
||||
static int
|
||||
inet_net_pton_ipv4( const char *src, u_char *dst, size_t size) {
|
||||
static const char xdigits[] = "0123456789abcdef";
|
||||
static const char digits[] = "0123456789";
|
||||
int n, ch, tmp = 0, dirty, bits;
|
||||
const u_char *odst = dst;
|
||||
|
||||
ch = *src++;
|
||||
if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
|
||||
&& isascii((unsigned char)(src[1]))
|
||||
&& isxdigit((unsigned char)(src[1]))) {
|
||||
/* Hexadecimal: Eat nybble string. */
|
||||
if (size <= 0)
|
||||
goto emsgsize;
|
||||
dirty = 0;
|
||||
src++; /* skip x or X. */
|
||||
while ((ch = *src++) != '\0' && isascii(ch) && isxdigit(ch)) {
|
||||
if (isupper(ch))
|
||||
ch = tolower(ch);
|
||||
n = strchr(xdigits, ch) - xdigits;
|
||||
INSIST(n >= 0 && n <= 15);
|
||||
if (dirty == 0)
|
||||
tmp = n;
|
||||
else
|
||||
tmp = (tmp << 4) | n;
|
||||
if (++dirty == 2) {
|
||||
if (size-- <= 0)
|
||||
goto emsgsize;
|
||||
*dst++ = (u_char) tmp;
|
||||
dirty = 0;
|
||||
}
|
||||
}
|
||||
if (dirty) { /* Odd trailing nybble? */
|
||||
if (size-- <= 0)
|
||||
goto emsgsize;
|
||||
*dst++ = (u_char) (tmp << 4);
|
||||
}
|
||||
} else if (isascii(ch) && isdigit(ch)) {
|
||||
/* Decimal: eat dotted digit string. */
|
||||
for (;;) {
|
||||
tmp = 0;
|
||||
do {
|
||||
n = strchr(digits, ch) - digits;
|
||||
INSIST(n >= 0 && n <= 9);
|
||||
tmp *= 10;
|
||||
tmp += n;
|
||||
if (tmp > 255)
|
||||
goto enoent;
|
||||
} while ((ch = *src++) != '\0' &&
|
||||
isascii(ch) && isdigit(ch));
|
||||
if (size-- <= 0)
|
||||
goto emsgsize;
|
||||
*dst++ = (u_char) tmp;
|
||||
if (ch == '\0' || ch == '/')
|
||||
break;
|
||||
if (ch != '.')
|
||||
goto enoent;
|
||||
ch = *src++;
|
||||
if (!isascii(ch) || !isdigit(ch))
|
||||
goto enoent;
|
||||
}
|
||||
} else
|
||||
goto enoent;
|
||||
|
||||
bits = -1;
|
||||
if (ch == '/' && isascii((unsigned char)(src[0])) &&
|
||||
isdigit((unsigned char)(src[0])) && dst > odst) {
|
||||
/* CIDR width specifier. Nothing can follow it. */
|
||||
ch = *src++; /* Skip over the /. */
|
||||
bits = 0;
|
||||
do {
|
||||
n = strchr(digits, ch) - digits;
|
||||
INSIST(n >= 0 && n <= 9);
|
||||
bits *= 10;
|
||||
bits += n;
|
||||
} while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch));
|
||||
if (ch != '\0')
|
||||
goto enoent;
|
||||
if (bits > 32)
|
||||
goto emsgsize;
|
||||
}
|
||||
|
||||
/* Firey death and destruction unless we prefetched EOS. */
|
||||
if (ch != '\0')
|
||||
goto enoent;
|
||||
|
||||
/* If nothing was written to the destination, we found no address. */
|
||||
if (dst == odst)
|
||||
goto enoent;
|
||||
/* If no CIDR spec was given, infer width from net class. */
|
||||
if (bits == -1) {
|
||||
if (*odst >= 240) /* Class E */
|
||||
bits = 32;
|
||||
else if (*odst >= 224) /* Class D */
|
||||
bits = 4;
|
||||
else if (*odst >= 192) /* Class C */
|
||||
bits = 24;
|
||||
else if (*odst >= 128) /* Class B */
|
||||
bits = 16;
|
||||
else /* Class A */
|
||||
bits = 8;
|
||||
/* If imputed mask is narrower than specified octets, widen. */
|
||||
if (bits >= 8 && bits < ((dst - odst) * 8))
|
||||
bits = (dst - odst) * 8;
|
||||
}
|
||||
/* Extend network to cover the actual mask. */
|
||||
while (bits > ((dst - odst) * 8)) {
|
||||
if (size-- <= 0)
|
||||
goto emsgsize;
|
||||
*dst++ = '\0';
|
||||
}
|
||||
return (bits);
|
||||
|
||||
enoent:
|
||||
errno = ENOENT;
|
||||
return (-1);
|
||||
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
getbits(const char *src, int *bitsp) {
|
||||
static const char digits[] = "0123456789";
|
||||
int n;
|
||||
int val;
|
||||
char ch;
|
||||
|
||||
val = 0;
|
||||
n = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
pch = strchr(digits, ch);
|
||||
if (pch != NULL) {
|
||||
if (n++ != 0 && val == 0) /* no leading zeros */
|
||||
return (0);
|
||||
val *= 10;
|
||||
val += (pch - digits);
|
||||
if (val > 128) /* range */
|
||||
return (0);
|
||||
continue;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
if (n == 0)
|
||||
return (0);
|
||||
*bitsp = val;
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
getv4(const char *src, u_char *dst, int *bitsp) {
|
||||
static const char digits[] = "0123456789";
|
||||
u_char *odst = dst;
|
||||
int n;
|
||||
u_int val;
|
||||
char ch;
|
||||
|
||||
val = 0;
|
||||
n = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
pch = strchr(digits, ch);
|
||||
if (pch != NULL) {
|
||||
if (n++ != 0 && val == 0) /* no leading zeros */
|
||||
return (0);
|
||||
val *= 10;
|
||||
val += (pch - digits);
|
||||
if (val > 255) /* range */
|
||||
return (0);
|
||||
continue;
|
||||
}
|
||||
if (ch == '.' || ch == '/') {
|
||||
if (dst - odst > 3) /* too many octets? */
|
||||
return (0);
|
||||
*dst++ = val;
|
||||
if (ch == '/')
|
||||
return (getbits(src, bitsp));
|
||||
val = 0;
|
||||
n = 0;
|
||||
continue;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
if (n == 0)
|
||||
return (0);
|
||||
if (dst - odst > 3) /* too many octets? */
|
||||
return (0);
|
||||
*dst++ = val;
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
inet_net_pton_ipv6(const char *src, u_char *dst, size_t size) {
|
||||
static const char xdigits_l[] = "0123456789abcdef",
|
||||
xdigits_u[] = "0123456789ABCDEF";
|
||||
u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
|
||||
const char *xdigits, *curtok;
|
||||
int ch, saw_xdigit;
|
||||
u_int val;
|
||||
int digits;
|
||||
int bits;
|
||||
size_t bytes;
|
||||
int words;
|
||||
int ipv4;
|
||||
|
||||
memset((tp = tmp), '\0', NS_IN6ADDRSZ);
|
||||
endp = tp + NS_IN6ADDRSZ;
|
||||
colonp = NULL;
|
||||
/* Leading :: requires some special handling. */
|
||||
if (*src == ':')
|
||||
if (*++src != ':')
|
||||
goto enoent;
|
||||
curtok = src;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
digits = 0;
|
||||
bits = -1;
|
||||
ipv4 = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
|
||||
pch = strchr((xdigits = xdigits_u), ch);
|
||||
if (pch != NULL) {
|
||||
val <<= 4;
|
||||
val |= (pch - xdigits);
|
||||
if (++digits > 4)
|
||||
goto enoent;
|
||||
saw_xdigit = 1;
|
||||
continue;
|
||||
}
|
||||
if (ch == ':') {
|
||||
curtok = src;
|
||||
if (!saw_xdigit) {
|
||||
if (colonp)
|
||||
goto enoent;
|
||||
colonp = tp;
|
||||
continue;
|
||||
} else if (*src == '\0')
|
||||
goto enoent;
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (u_char) (val >> 8) & 0xff;
|
||||
*tp++ = (u_char) val & 0xff;
|
||||
saw_xdigit = 0;
|
||||
digits = 0;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
|
||||
getv4(curtok, tp, &bits) > 0) {
|
||||
tp += NS_INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
ipv4 = 1;
|
||||
break; /* '\0' was seen by inet_pton4(). */
|
||||
}
|
||||
if (ch == '/' && getbits(src, &bits) > 0)
|
||||
break;
|
||||
goto enoent;
|
||||
}
|
||||
if (saw_xdigit) {
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
goto enoent;
|
||||
*tp++ = (u_char) (val >> 8) & 0xff;
|
||||
*tp++ = (u_char) val & 0xff;
|
||||
}
|
||||
if (bits == -1)
|
||||
bits = 128;
|
||||
|
||||
words = (bits + 15) / 16;
|
||||
if (words < 2)
|
||||
words = 2;
|
||||
if (ipv4)
|
||||
words = 8;
|
||||
endp = tmp + 2 * words;
|
||||
|
||||
if (colonp != NULL) {
|
||||
/*
|
||||
* Since some memmove()'s erroneously fail to handle
|
||||
* overlapping regions, we'll do the shift by hand.
|
||||
*/
|
||||
const int n = tp - colonp;
|
||||
int i;
|
||||
|
||||
if (tp == endp)
|
||||
goto enoent;
|
||||
for (i = 1; i <= n; i++) {
|
||||
endp[- i] = colonp[n - i];
|
||||
colonp[n - i] = 0;
|
||||
}
|
||||
tp = endp;
|
||||
}
|
||||
if (tp != endp)
|
||||
goto enoent;
|
||||
|
||||
bytes = (bits + 7) / 8;
|
||||
if (bytes > size)
|
||||
goto emsgsize;
|
||||
memcpy(dst, tmp, bytes);
|
||||
return (bits);
|
||||
|
||||
enoent:
|
||||
errno = ENOENT;
|
||||
return (-1);
|
||||
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* int
|
||||
* inet_net_pton(af, src, dst, size)
|
||||
* convert network number from presentation to network format.
|
||||
* accepts hex octets, hex strings, decimal octets, and /CIDR.
|
||||
* "size" is in bytes and describes "dst".
|
||||
* return:
|
||||
* number of bits, either imputed classfully or specified with /CIDR,
|
||||
* or -1 if some failure occurred (check errno). ENOENT means it was
|
||||
* not a valid network specification.
|
||||
* author:
|
||||
* Paul Vixie (ISC), June 1996
|
||||
*/
|
||||
int
|
||||
inet_net_pton(int af, const char *src, void *dst, size_t size) {
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_net_pton_ipv4(src, dst, size));
|
||||
case AF_INET6:
|
||||
return (inet_net_pton_ipv6(src, dst, size));
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: inet_neta.c,v 1.1 2004/04/15 16:03:28 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) ((size_t)sprintf x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* char *
|
||||
* inet_neta(src, dst, size)
|
||||
* format a u_long network number into presentation format.
|
||||
* return:
|
||||
* pointer to dst, or NULL if an error occurred (check errno).
|
||||
* note:
|
||||
* format of ``src'' is as for inet_network().
|
||||
* author:
|
||||
* Paul Vixie (ISC), July 1996
|
||||
*/
|
||||
char *
|
||||
inet_neta(src, dst, size)
|
||||
u_long src;
|
||||
char *dst;
|
||||
size_t size;
|
||||
{
|
||||
char *odst = dst;
|
||||
char *tp;
|
||||
|
||||
while (src & 0xffffffff) {
|
||||
u_char b = (src & 0xff000000) >> 24;
|
||||
|
||||
src <<= 8;
|
||||
if (b) {
|
||||
if (size < sizeof "255.")
|
||||
goto emsgsize;
|
||||
tp = dst;
|
||||
dst += SPRINTF((dst, "%u", b));
|
||||
if (src != 0L) {
|
||||
*dst++ = '.';
|
||||
*dst = '\0';
|
||||
}
|
||||
size -= (size_t)(dst - tp);
|
||||
}
|
||||
}
|
||||
if (dst == odst) {
|
||||
if (size < sizeof "0.0.0.0")
|
||||
goto emsgsize;
|
||||
strcpy(dst, "0.0.0.0");
|
||||
}
|
||||
return (odst);
|
||||
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (NULL);
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char sccsid[] = "@(#)inet_netof.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
/*
|
||||
* Return the network number from an internet
|
||||
* address; handles class a/b/c network #'s.
|
||||
*/
|
||||
u_long
|
||||
inet_netof(in)
|
||||
struct in_addr in;
|
||||
{
|
||||
register u_long i = ntohl(in.s_addr);
|
||||
|
||||
if (IN_CLASSA(i))
|
||||
return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
|
||||
else if (IN_CLASSB(i))
|
||||
return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
|
||||
else
|
||||
return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char sccsid[] = "@(#)inet_network.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
/*
|
||||
* Internet network address interpretation routine.
|
||||
* The library routines call this routine to interpret
|
||||
* network numbers.
|
||||
*/
|
||||
u_long
|
||||
inet_network(cp)
|
||||
register const char *cp;
|
||||
{
|
||||
register u_long val, base, n, i;
|
||||
register char c;
|
||||
u_long parts[4], *pp = parts;
|
||||
int digit;
|
||||
|
||||
again:
|
||||
val = 0; base = 10; digit = 0;
|
||||
if (*cp == '0')
|
||||
digit = 1, base = 8, cp++;
|
||||
if (*cp == 'x' || *cp == 'X')
|
||||
base = 16, cp++;
|
||||
while ((c = *cp) != 0) {
|
||||
if (isdigit((unsigned char)c)) {
|
||||
if (base == 8 && (c == '8' || c == '9'))
|
||||
return (INADDR_NONE);
|
||||
val = (val * base) + (c - '0');
|
||||
cp++;
|
||||
digit = 1;
|
||||
continue;
|
||||
}
|
||||
if (base == 16 && isxdigit((unsigned char)c)) {
|
||||
val = (val << 4) +
|
||||
(c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
|
||||
cp++;
|
||||
digit = 1;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!digit)
|
||||
return (INADDR_NONE);
|
||||
if (*cp == '.') {
|
||||
if (pp >= parts + 4 || val > 0xff)
|
||||
return (INADDR_NONE);
|
||||
*pp++ = val, cp++;
|
||||
goto again;
|
||||
}
|
||||
if (*cp && !isspace(*cp&0xff))
|
||||
return (INADDR_NONE);
|
||||
*pp++ = val;
|
||||
n = pp - parts;
|
||||
if (n > 4)
|
||||
return (INADDR_NONE);
|
||||
for (val = 0, i = 0; i < n; i++) {
|
||||
val <<= 8;
|
||||
val |= parts[i] & 0xff;
|
||||
}
|
||||
return (val);
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char sccsid[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93";
|
||||
static const char rcsid[] = "$Id: inet_ntoa.c,v 1.1 2004/04/15 16:03:28 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
/*
|
||||
* Convert network-format internet address
|
||||
* to base 256 d.d.d.d representation.
|
||||
*/
|
||||
/*const*/ char *
|
||||
inet_ntoa(struct in_addr in) {
|
||||
static char ret[18];
|
||||
|
||||
strcpy(ret, "[inet_ntoa error]");
|
||||
(void) inet_ntop(AF_INET, &in, ret, sizeof ret);
|
||||
return (ret);
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Copyright (c) 1996-1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: inet_ntop.c,v 1.1 2004/04/15 16:03:28 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) ((size_t)sprintf x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* WARNING: Don't even consider trying to compile this on a system where
|
||||
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||
*/
|
||||
|
||||
static const char *inet_ntop4 __P((const u_char *src, char *dst, size_t size));
|
||||
static const char *inet_ntop6 __P((const u_char *src, char *dst, size_t size));
|
||||
|
||||
/* char *
|
||||
* inet_ntop(af, src, dst, size)
|
||||
* convert a network format address to presentation format.
|
||||
* return:
|
||||
* pointer to presentation format address (`dst'), or NULL (see errno).
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
const char *
|
||||
inet_ntop(af, src, dst, size)
|
||||
int af;
|
||||
const void *src;
|
||||
char *dst;
|
||||
size_t size;
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_ntop4(src, dst, size));
|
||||
case AF_INET6:
|
||||
return (inet_ntop6(src, dst, size));
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (NULL);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* const char *
|
||||
* inet_ntop4(src, dst, size)
|
||||
* format an IPv4 address
|
||||
* return:
|
||||
* `dst' (as a const)
|
||||
* notes:
|
||||
* (1) uses no statics
|
||||
* (2) takes a u_char* not an in_addr as input
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static const char *
|
||||
inet_ntop4(src, dst, size)
|
||||
const u_char *src;
|
||||
char *dst;
|
||||
size_t size;
|
||||
{
|
||||
static const char fmt[] = "%u.%u.%u.%u";
|
||||
char tmp[sizeof "255.255.255.255"];
|
||||
|
||||
if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) >= size) {
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
return (dst);
|
||||
}
|
||||
|
||||
/* const char *
|
||||
* inet_ntop6(src, dst, size)
|
||||
* convert IPv6 binary address into presentation (printable) format
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static const char *
|
||||
inet_ntop6(src, dst, size)
|
||||
const u_char *src;
|
||||
char *dst;
|
||||
size_t size;
|
||||
{
|
||||
/*
|
||||
* Note that int32_t and int16_t need only be "at least" large enough
|
||||
* to contain a value of the specified size. On some systems, like
|
||||
* Crays, there is no such thing as an integer variable with 16 bits.
|
||||
* Keep this in mind if you think this function should have been coded
|
||||
* to use pointer overlays. All the world's not a VAX.
|
||||
*/
|
||||
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
|
||||
struct { int base, len; } best, cur;
|
||||
u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Preprocess:
|
||||
* Copy the input (bytewise) array into a wordwise array.
|
||||
* Find the longest run of 0x00's in src[] for :: shorthanding.
|
||||
*/
|
||||
memset(words, '\0', sizeof words);
|
||||
for (i = 0; i < NS_IN6ADDRSZ; i++)
|
||||
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||
best.base = -1;
|
||||
cur.base = -1;
|
||||
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
|
||||
if (words[i] == 0) {
|
||||
if (cur.base == -1)
|
||||
cur.base = i, cur.len = 1;
|
||||
else
|
||||
cur.len++;
|
||||
} else {
|
||||
if (cur.base != -1) {
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
cur.base = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cur.base != -1) {
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
}
|
||||
if (best.base != -1 && best.len < 2)
|
||||
best.base = -1;
|
||||
|
||||
/*
|
||||
* Format the result.
|
||||
*/
|
||||
tp = tmp;
|
||||
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
|
||||
/* Are we inside the best run of 0x00's? */
|
||||
if (best.base != -1 && i >= best.base &&
|
||||
i < (best.base + best.len)) {
|
||||
if (i == best.base)
|
||||
*tp++ = ':';
|
||||
continue;
|
||||
}
|
||||
/* Are we following an initial run of 0x00s or any real hex? */
|
||||
if (i != 0)
|
||||
*tp++ = ':';
|
||||
/* Is this address an encapsulated IPv4? */
|
||||
if (i == 6 && best.base == 0 && (best.len == 6 ||
|
||||
(best.len == 7 && words[7] != 0x0001) ||
|
||||
(best.len == 5 && words[5] == 0xffff))) {
|
||||
if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
|
||||
return (NULL);
|
||||
tp += strlen(tp);
|
||||
break;
|
||||
}
|
||||
tp += SPRINTF((tp, "%x", words[i]));
|
||||
}
|
||||
/* Was it a trailing run of 0x00's? */
|
||||
if (best.base != -1 && (best.base + best.len) ==
|
||||
(NS_IN6ADDRSZ / NS_INT16SZ))
|
||||
*tp++ = ':';
|
||||
*tp++ = '\0';
|
||||
|
||||
/*
|
||||
* Check for overflow, copy, and we're done.
|
||||
*/
|
||||
if ((size_t)(tp - tmp) > size) {
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
return (dst);
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: inet_pton.c,v 1.1 2004/04/15 16:03:28 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "port_after.h"
|
||||
|
||||
/*
|
||||
* WARNING: Don't even consider trying to compile this on a system where
|
||||
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||
*/
|
||||
|
||||
static int inet_pton4 __P((const char *src, u_char *dst));
|
||||
static int inet_pton6 __P((const char *src, u_char *dst));
|
||||
|
||||
/* int
|
||||
* inet_pton(af, src, dst)
|
||||
* convert from presentation format (which usually means ASCII printable)
|
||||
* to network format (which is usually some kind of binary format).
|
||||
* return:
|
||||
* 1 if the address was valid for the specified address family
|
||||
* 0 if the address wasn't valid (`dst' is untouched in this case)
|
||||
* -1 if some other error occurred (`dst' is untouched in this case, too)
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
int
|
||||
inet_pton(af, src, dst)
|
||||
int af;
|
||||
const char *src;
|
||||
void *dst;
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_pton4(src, dst));
|
||||
case AF_INET6:
|
||||
return (inet_pton6(src, dst));
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (-1);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* int
|
||||
* inet_pton4(src, dst)
|
||||
* like inet_aton() but without all the hexadecimal and shorthand.
|
||||
* return:
|
||||
* 1 if `src' is a valid dotted quad, else 0.
|
||||
* notice:
|
||||
* does not touch `dst' unless it's returning 1.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton4(src, dst)
|
||||
const char *src;
|
||||
u_char *dst;
|
||||
{
|
||||
static const char digits[] = "0123456789";
|
||||
int saw_digit, octets, ch;
|
||||
u_char tmp[NS_INADDRSZ], *tp;
|
||||
|
||||
saw_digit = 0;
|
||||
octets = 0;
|
||||
*(tp = tmp) = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if ((pch = strchr(digits, ch)) != NULL) {
|
||||
u_int new = *tp * 10 + (pch - digits);
|
||||
|
||||
if (saw_digit && *tp == 0)
|
||||
return (0);
|
||||
if (new > 255)
|
||||
return (0);
|
||||
*tp = new;
|
||||
if (!saw_digit) {
|
||||
if (++octets > 4)
|
||||
return (0);
|
||||
saw_digit = 1;
|
||||
}
|
||||
} else if (ch == '.' && saw_digit) {
|
||||
if (octets == 4)
|
||||
return (0);
|
||||
*++tp = 0;
|
||||
saw_digit = 0;
|
||||
} else
|
||||
return (0);
|
||||
}
|
||||
if (octets < 4)
|
||||
return (0);
|
||||
memcpy(dst, tmp, NS_INADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* int
|
||||
* inet_pton6(src, dst)
|
||||
* convert presentation level address to network order binary form.
|
||||
* return:
|
||||
* 1 if `src' is a valid [RFC1884 2.2] address, else 0.
|
||||
* notice:
|
||||
* (1) does not touch `dst' unless it's returning 1.
|
||||
* (2) :: in a full address is silently ignored.
|
||||
* credit:
|
||||
* inspired by Mark Andrews.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton6(src, dst)
|
||||
const char *src;
|
||||
u_char *dst;
|
||||
{
|
||||
static const char xdigits_l[] = "0123456789abcdef",
|
||||
xdigits_u[] = "0123456789ABCDEF";
|
||||
u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
|
||||
const char *xdigits, *curtok;
|
||||
int ch, saw_xdigit;
|
||||
u_int val;
|
||||
|
||||
memset((tp = tmp), '\0', NS_IN6ADDRSZ);
|
||||
endp = tp + NS_IN6ADDRSZ;
|
||||
colonp = NULL;
|
||||
/* Leading :: requires some special handling. */
|
||||
if (*src == ':')
|
||||
if (*++src != ':')
|
||||
return (0);
|
||||
curtok = src;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
|
||||
pch = strchr((xdigits = xdigits_u), ch);
|
||||
if (pch != NULL) {
|
||||
val <<= 4;
|
||||
val |= (pch - xdigits);
|
||||
if (val > 0xffff)
|
||||
return (0);
|
||||
saw_xdigit = 1;
|
||||
continue;
|
||||
}
|
||||
if (ch == ':') {
|
||||
curtok = src;
|
||||
if (!saw_xdigit) {
|
||||
if (colonp)
|
||||
return (0);
|
||||
colonp = tp;
|
||||
continue;
|
||||
} else if (*src == '\0') {
|
||||
return (0);
|
||||
}
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (u_char) (val >> 8) & 0xff;
|
||||
*tp++ = (u_char) val & 0xff;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
|
||||
inet_pton4(curtok, tp) > 0) {
|
||||
tp += NS_INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
break; /* '\0' was seen by inet_pton4(). */
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
if (saw_xdigit) {
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (u_char) (val >> 8) & 0xff;
|
||||
*tp++ = (u_char) val & 0xff;
|
||||
}
|
||||
if (colonp != NULL) {
|
||||
/*
|
||||
* Since some memmove()'s erroneously fail to handle
|
||||
* overlapping regions, we'll do the shift by hand.
|
||||
*/
|
||||
const int n = tp - colonp;
|
||||
int i;
|
||||
|
||||
if (tp == endp)
|
||||
return (0);
|
||||
for (i = 1; i <= n; i++) {
|
||||
endp[- i] = colonp[n - i];
|
||||
colonp[n - i] = 0;
|
||||
}
|
||||
tp = endp;
|
||||
}
|
||||
if (tp != endp)
|
||||
return (0);
|
||||
memcpy(dst, tmp, NS_IN6ADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 1996-1999 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 DISCLAI!
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANT!
|
||||
* 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 TH!
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: nsap_addr.c,v 1.1 2004/04/15 16:03:28 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
static char
|
||||
xtob(int c) {
|
||||
return (c - (((c >= '0') && (c <= '9')) ? '0' : '7'));
|
||||
}
|
||||
|
||||
u_int
|
||||
inet_nsap_addr(const char *ascii, u_char *binary, int maxlen) {
|
||||
u_char c, nib;
|
||||
u_int len = 0;
|
||||
|
||||
if (ascii[0] != '0' || (ascii[1] != 'x' && ascii[1] != 'X'))
|
||||
return (0);
|
||||
ascii += 2;
|
||||
|
||||
while ((c = *ascii++) != '\0' && len < (u_int)maxlen) {
|
||||
if (c == '.' || c == '+' || c == '/')
|
||||
continue;
|
||||
if (!isascii(c))
|
||||
return (0);
|
||||
if (islower(c))
|
||||
c = toupper(c);
|
||||
if (isxdigit(c)) {
|
||||
nib = xtob(c);
|
||||
c = *ascii++;
|
||||
if (c != '\0') {
|
||||
c = toupper(c);
|
||||
if (isxdigit(c)) {
|
||||
*binary++ = (nib << 4) | xtob(c);
|
||||
len++;
|
||||
} else
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
return (len);
|
||||
}
|
||||
|
||||
char *
|
||||
inet_nsap_ntoa(int binlen, const u_char *binary, char *ascii) {
|
||||
int nib;
|
||||
int i;
|
||||
static char tmpbuf[2+255*3];
|
||||
char *start;
|
||||
|
||||
if (ascii)
|
||||
start = ascii;
|
||||
else {
|
||||
ascii = tmpbuf;
|
||||
start = tmpbuf;
|
||||
}
|
||||
|
||||
*ascii++ = '0';
|
||||
*ascii++ = 'x';
|
||||
|
||||
if (binlen > 255)
|
||||
binlen = 255;
|
||||
|
||||
for (i = 0; i < binlen; i++) {
|
||||
nib = *binary >> 4;
|
||||
*ascii++ = nib + (nib < 10 ? '0' : '7');
|
||||
nib = *binary++ & 0x0f;
|
||||
*ascii++ = nib + (nib < 10 ? '0' : '7');
|
||||
if (((i % 2) == 0 && (i + 1) < binlen))
|
||||
*ascii++ = '.';
|
||||
}
|
||||
*ascii = '\0';
|
||||
return (start);
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (c) 1996-1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: dns.c,v 1.1 2004/04/15 16:03:28 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* dns.c --- this is the top-level accessor function for the dns
|
||||
*/
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <resolv.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "hesiod.h"
|
||||
#include "dns_p.h"
|
||||
|
||||
/* forward */
|
||||
|
||||
static void dns_close(struct irs_acc *);
|
||||
static struct __res_state * dns_res_get(struct irs_acc *);
|
||||
static void dns_res_set(struct irs_acc *, struct __res_state *,
|
||||
void (*)(void *));
|
||||
|
||||
/* public */
|
||||
|
||||
struct irs_acc *
|
||||
irs_dns_acc(const char *options) {
|
||||
struct irs_acc *acc;
|
||||
struct dns_p *dns;
|
||||
|
||||
UNUSED(options);
|
||||
|
||||
if (!(acc = memget(sizeof *acc))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(acc, 0x5e, sizeof *acc);
|
||||
if (!(dns = memget(sizeof *dns))) {
|
||||
errno = ENOMEM;
|
||||
memput(acc, sizeof *acc);
|
||||
return (NULL);
|
||||
}
|
||||
memset(dns, 0x5e, sizeof *dns);
|
||||
dns->res = NULL;
|
||||
dns->free_res = NULL;
|
||||
if (hesiod_init(&dns->hes_ctx) < 0) {
|
||||
/*
|
||||
* We allow the dns accessor class to initialize
|
||||
* despite hesiod failing to initialize correctly,
|
||||
* since dns host queries don't depend on hesiod.
|
||||
*/
|
||||
dns->hes_ctx = NULL;
|
||||
}
|
||||
acc->private = dns;
|
||||
#ifdef WANT_IRS_GR
|
||||
acc->gr_map = irs_dns_gr;
|
||||
#else
|
||||
acc->gr_map = NULL;
|
||||
#endif
|
||||
#ifdef WANT_IRS_PW
|
||||
acc->pw_map = irs_dns_pw;
|
||||
#else
|
||||
acc->pw_map = NULL;
|
||||
#endif
|
||||
acc->sv_map = irs_dns_sv;
|
||||
acc->pr_map = irs_dns_pr;
|
||||
acc->ho_map = irs_dns_ho;
|
||||
acc->nw_map = irs_dns_nw;
|
||||
acc->ng_map = irs_nul_ng;
|
||||
acc->res_get = dns_res_get;
|
||||
acc->res_set = dns_res_set;
|
||||
acc->close = dns_close;
|
||||
return (acc);
|
||||
}
|
||||
|
||||
/* methods */
|
||||
static struct __res_state *
|
||||
dns_res_get(struct irs_acc *this) {
|
||||
struct dns_p *dns = (struct dns_p *)this->private;
|
||||
|
||||
if (dns->res == NULL) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (res == NULL)
|
||||
return (NULL);
|
||||
memset(dns->res, 0, sizeof *dns->res);
|
||||
dns_res_set(this, res, free);
|
||||
}
|
||||
|
||||
if ((dns->res->options & RES_INIT) == 0 &&
|
||||
res_ninit(dns->res) < 0)
|
||||
return (NULL);
|
||||
|
||||
return (dns->res);
|
||||
}
|
||||
|
||||
static void
|
||||
dns_res_set(struct irs_acc *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct dns_p *dns = (struct dns_p *)this->private;
|
||||
|
||||
if (dns->res && dns->free_res) {
|
||||
res_nclose(dns->res);
|
||||
(*dns->free_res)(dns->res);
|
||||
}
|
||||
dns->res = res;
|
||||
dns->free_res = free_res;
|
||||
}
|
||||
|
||||
static void
|
||||
dns_close(struct irs_acc *this) {
|
||||
struct dns_p *dns;
|
||||
|
||||
dns = (struct dns_p *)this->private;
|
||||
if (dns->res && dns->free_res)
|
||||
(*dns->free_res)(dns->res);
|
||||
if (dns->hes_ctx)
|
||||
hesiod_end(dns->hes_ctx);
|
||||
memput(dns, sizeof *dns);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* Copyright (c) 1996-1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: dns_gr.c,v 1.1 2004/04/15 16:03:28 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* dns_gr.c --- this file contains the functions for accessing
|
||||
* group information from Hesiod.
|
||||
*/
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_GR
|
||||
static int __bind_irs_gr_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "hesiod.h"
|
||||
#include "dns_p.h"
|
||||
|
||||
/* Types. */
|
||||
|
||||
struct pvt {
|
||||
/*
|
||||
* This is our private accessor data. It has a shared hesiod context.
|
||||
*/
|
||||
struct dns_p * dns;
|
||||
/*
|
||||
* Need space to store the entries read from the group file.
|
||||
* The members list also needs space per member, and the
|
||||
* strings making up the user names must be allocated
|
||||
* somewhere. Rather than doing lots of small allocations,
|
||||
* we keep one buffer and resize it as needed.
|
||||
*/
|
||||
struct group group;
|
||||
size_t nmemb; /* Malloc'd max index of gr_mem[]. */
|
||||
char * membuf;
|
||||
size_t membufsize;
|
||||
};
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static struct group * gr_next(struct irs_gr *);
|
||||
static struct group * gr_byname(struct irs_gr *, const char *);
|
||||
static struct group * gr_bygid(struct irs_gr *, gid_t);
|
||||
static void gr_rewind(struct irs_gr *);
|
||||
static void gr_close(struct irs_gr *);
|
||||
static int gr_list(struct irs_gr *, const char *,
|
||||
gid_t, gid_t *, int *);
|
||||
static void gr_minimize(struct irs_gr *);
|
||||
static struct __res_state * gr_res_get(struct irs_gr *);
|
||||
static void gr_res_set(struct irs_gr *,
|
||||
struct __res_state *,
|
||||
void (*)(void *));
|
||||
|
||||
static struct group * get_hes_group(struct irs_gr *this,
|
||||
const char *name,
|
||||
const char *type);
|
||||
|
||||
/* Public. */
|
||||
|
||||
struct irs_gr *
|
||||
irs_dns_gr(struct irs_acc *this) {
|
||||
struct dns_p *dns = (struct dns_p *)this->private;
|
||||
struct irs_gr *gr;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!dns || !dns->hes_ctx) {
|
||||
errno = ENODEV;
|
||||
return (NULL);
|
||||
}
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->dns = dns;
|
||||
if (!(gr = memget(sizeof *gr))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(gr, 0x5e, sizeof *gr);
|
||||
gr->private = pvt;
|
||||
gr->next = gr_next;
|
||||
gr->byname = gr_byname;
|
||||
gr->bygid = gr_bygid;
|
||||
gr->rewind = gr_rewind;
|
||||
gr->close = gr_close;
|
||||
gr->list = gr_list;
|
||||
gr->minimize = gr_minimize;
|
||||
gr->res_get = gr_res_get;
|
||||
gr->res_set = gr_res_set;
|
||||
return (gr);
|
||||
}
|
||||
|
||||
/* methods */
|
||||
|
||||
static void
|
||||
gr_close(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->group.gr_mem)
|
||||
free(pvt->group.gr_mem);
|
||||
if (pvt->membuf)
|
||||
free(pvt->membuf);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_next(struct irs_gr *this) {
|
||||
|
||||
UNUSED(this);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_byname(struct irs_gr *this, const char *name) {
|
||||
return (get_hes_group(this, name, "group"));
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_bygid(struct irs_gr *this, gid_t gid) {
|
||||
char name[32];
|
||||
|
||||
sprintf(name, "%ld", (long)gid);
|
||||
return (get_hes_group(this, name, "gid"));
|
||||
}
|
||||
|
||||
static void
|
||||
gr_rewind(struct irs_gr *this) {
|
||||
|
||||
UNUSED(this);
|
||||
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
static int
|
||||
gr_list(struct irs_gr *this, const char *name,
|
||||
gid_t basegid, gid_t *groups, int *ngroups)
|
||||
{
|
||||
UNUSED(this);
|
||||
UNUSED(name);
|
||||
UNUSED(basegid);
|
||||
UNUSED(groups);
|
||||
|
||||
*ngroups = 0;
|
||||
/* There's some way to do this in Hesiod. */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static void
|
||||
gr_minimize(struct irs_gr *this) {
|
||||
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
static struct group *
|
||||
get_hes_group(struct irs_gr *this, const char *name, const char *type) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char **hes_list, *cp, **new;
|
||||
size_t num_members = 0;
|
||||
u_long t;
|
||||
|
||||
hes_list = hesiod_resolve(pvt->dns->hes_ctx, name, type);
|
||||
if (!hes_list)
|
||||
return (NULL);
|
||||
|
||||
/*
|
||||
* Copy the returned hesiod string into storage space.
|
||||
*/
|
||||
if (pvt->membuf)
|
||||
free(pvt->membuf);
|
||||
pvt->membuf = strdup(*hes_list);
|
||||
hesiod_free_list(pvt->dns->hes_ctx, hes_list);
|
||||
|
||||
cp = pvt->membuf;
|
||||
pvt->group.gr_name = cp;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
pvt->group.gr_passwd = cp;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
errno = 0;
|
||||
t = strtoul(cp, NULL, 10);
|
||||
if (errno == ERANGE)
|
||||
goto cleanup;
|
||||
pvt->group.gr_gid = (gid_t) t;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
cp++;
|
||||
|
||||
/*
|
||||
* Parse the members out.
|
||||
*/
|
||||
while (*cp) {
|
||||
if (num_members+1 >= pvt->nmemb || pvt->group.gr_mem == NULL) {
|
||||
pvt->nmemb += 10;
|
||||
new = realloc(pvt->group.gr_mem,
|
||||
pvt->nmemb * sizeof(char *));
|
||||
if (new == NULL)
|
||||
goto cleanup;
|
||||
pvt->group.gr_mem = new;
|
||||
}
|
||||
pvt->group.gr_mem[num_members++] = cp;
|
||||
if (!(cp = strchr(cp, ',')))
|
||||
break;
|
||||
*cp++ = '\0';
|
||||
}
|
||||
if (!pvt->group.gr_mem) {
|
||||
pvt->group.gr_mem = malloc(sizeof(char*));
|
||||
if (!pvt->group.gr_mem)
|
||||
goto cleanup;
|
||||
}
|
||||
pvt->group.gr_mem[num_members] = NULL;
|
||||
|
||||
return (&pvt->group);
|
||||
|
||||
cleanup:
|
||||
if (pvt->group.gr_mem) {
|
||||
free(pvt->group.gr_mem);
|
||||
pvt->group.gr_mem = NULL;
|
||||
}
|
||||
if (pvt->membuf) {
|
||||
free(pvt->membuf);
|
||||
pvt->membuf = NULL;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
gr_res_get(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
|
||||
return (__hesiod_res_get(dns->hes_ctx));
|
||||
}
|
||||
|
||||
static void
|
||||
gr_res_set(struct irs_gr *this, struct __res_state * res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
|
||||
__hesiod_res_set(dns->hes_ctx, res, free_res);
|
||||
}
|
||||
|
||||
#endif /* WANT_IRS_GR */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,594 @@
|
||||
/*
|
||||
* Copyright (c) 1996-1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: dns_nw.c,v 1.1 2004/04/15 16:03:28 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Imports. */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "dns_p.h"
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) sprintf x
|
||||
#endif
|
||||
|
||||
/* Definitions. */
|
||||
|
||||
#define MAXALIASES 35
|
||||
|
||||
#define MAXPACKET (64*1024)
|
||||
|
||||
struct pvt {
|
||||
struct nwent net;
|
||||
char * ali[MAXALIASES];
|
||||
char buf[BUFSIZ+1];
|
||||
struct __res_state * res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
typedef union {
|
||||
long al;
|
||||
char ac;
|
||||
} align;
|
||||
|
||||
enum by_what { by_addr, by_name };
|
||||
|
||||
/* Forwards. */
|
||||
|
||||
static void nw_close(struct irs_nw *);
|
||||
static struct nwent * nw_byname(struct irs_nw *, const char *, int);
|
||||
static struct nwent * nw_byaddr(struct irs_nw *, void *, int, int);
|
||||
static struct nwent * nw_next(struct irs_nw *);
|
||||
static void nw_rewind(struct irs_nw *);
|
||||
static void nw_minimize(struct irs_nw *);
|
||||
static struct __res_state * nw_res_get(struct irs_nw *this);
|
||||
static void nw_res_set(struct irs_nw *this,
|
||||
struct __res_state *res,
|
||||
void (*free_res)(void *));
|
||||
|
||||
static struct nwent * get1101byaddr(struct irs_nw *, u_char *, int);
|
||||
static struct nwent * get1101byname(struct irs_nw *, const char *);
|
||||
static struct nwent * get1101answer(struct irs_nw *,
|
||||
u_char *ansbuf, int anslen,
|
||||
enum by_what by_what,
|
||||
int af, const char *name,
|
||||
const u_char *addr, int addrlen);
|
||||
static struct nwent * get1101mask(struct irs_nw *this, struct nwent *);
|
||||
static int make1101inaddr(const u_char *, int, char *, int);
|
||||
static void normalize_name(char *name);
|
||||
static int init(struct irs_nw *this);
|
||||
|
||||
/* Exports. */
|
||||
|
||||
struct irs_nw *
|
||||
irs_dns_nw(struct irs_acc *this) {
|
||||
struct irs_nw *nw;
|
||||
struct pvt *pvt;
|
||||
|
||||
UNUSED(this);
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
if (!(nw = memget(sizeof *nw))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(nw, 0x5e, sizeof *nw);
|
||||
nw->private = pvt;
|
||||
nw->close = nw_close;
|
||||
nw->byname = nw_byname;
|
||||
nw->byaddr = nw_byaddr;
|
||||
nw->next = nw_next;
|
||||
nw->rewind = nw_rewind;
|
||||
nw->minimize = nw_minimize;
|
||||
nw->res_get = nw_res_get;
|
||||
nw->res_set = nw_res_set;
|
||||
return (nw);
|
||||
}
|
||||
|
||||
/* Methods. */
|
||||
|
||||
static void
|
||||
nw_close(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
nw_minimize(this);
|
||||
|
||||
if (pvt->res && pvt->free_res)
|
||||
(*pvt->free_res)(pvt->res);
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
nw_byname(struct irs_nw *this, const char *name, int af) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (get1101byname(this, name));
|
||||
default:
|
||||
(void)NULL;
|
||||
}
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
errno = EAFNOSUPPORT;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
nw_byaddr(struct irs_nw *this, void *net, int len, int af) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (get1101byaddr(this, net, len));
|
||||
default:
|
||||
(void)NULL;
|
||||
}
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
errno = EAFNOSUPPORT;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
nw_next(struct irs_nw *this) {
|
||||
|
||||
UNUSED(this);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
nw_rewind(struct irs_nw *this) {
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
static void
|
||||
nw_minimize(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->res)
|
||||
res_nclose(pvt->res);
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
nw_res_get(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (!res) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
nw_res_set(this, res, free);
|
||||
}
|
||||
|
||||
return (pvt->res);
|
||||
}
|
||||
|
||||
static void
|
||||
nw_res_set(struct irs_nw *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->res && pvt->free_res) {
|
||||
res_nclose(pvt->res);
|
||||
(*pvt->free_res)(pvt->res);
|
||||
}
|
||||
|
||||
pvt->res = res;
|
||||
pvt->free_res = free_res;
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
static struct nwent *
|
||||
get1101byname(struct irs_nw *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
u_char *ansbuf;
|
||||
int anslen;
|
||||
struct nwent *result;
|
||||
|
||||
ansbuf = memget(MAXPACKET);
|
||||
if (ansbuf == NULL) {
|
||||
errno = ENOMEM;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
}
|
||||
anslen = res_nsearch(pvt->res, name, C_IN, T_PTR, ansbuf, MAXPACKET);
|
||||
if (anslen < 0) {
|
||||
memput(ansbuf, MAXPACKET);
|
||||
return (NULL);
|
||||
}
|
||||
result = get1101mask(this, get1101answer(this, ansbuf, anslen, by_name,
|
||||
AF_INET, name, NULL, 0));
|
||||
memput(ansbuf, MAXPACKET);
|
||||
return (result);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
get1101byaddr(struct irs_nw *this, u_char *net, int len) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char qbuf[sizeof "255.255.255.255.in-addr.arpa"];
|
||||
struct nwent *result;
|
||||
u_char *ansbuf;
|
||||
int anslen;
|
||||
|
||||
if (len < 1 || len > 32) {
|
||||
errno = EINVAL;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
}
|
||||
if (make1101inaddr(net, len, qbuf, sizeof qbuf) < 0)
|
||||
return (NULL);
|
||||
ansbuf = memget(MAXPACKET);
|
||||
if (ansbuf == NULL) {
|
||||
errno = ENOMEM;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
}
|
||||
anslen = res_nquery(pvt->res, qbuf, C_IN, T_PTR, ansbuf, MAXPACKET);
|
||||
if (anslen < 0) {
|
||||
memput(ansbuf, MAXPACKET);
|
||||
return (NULL);
|
||||
}
|
||||
result = get1101mask(this, get1101answer(this, ansbuf, anslen, by_addr,
|
||||
AF_INET, NULL, net, len));
|
||||
memput(ansbuf, MAXPACKET);
|
||||
return (result);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
get1101answer(struct irs_nw *this,
|
||||
u_char *ansbuf, int anslen, enum by_what by_what,
|
||||
int af, const char *name, const u_char *addr, int addrlen)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
int type, class, ancount, qdcount, haveanswer;
|
||||
char *bp, *ep, **ap;
|
||||
u_char *cp, *eom;
|
||||
HEADER *hp;
|
||||
|
||||
/* Initialize, and parse header. */
|
||||
eom = ansbuf + anslen;
|
||||
if (ansbuf + HFIXEDSZ > eom) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
}
|
||||
hp = (HEADER *)ansbuf;
|
||||
cp = ansbuf + HFIXEDSZ;
|
||||
qdcount = ntohs(hp->qdcount);
|
||||
while (qdcount-- > 0) {
|
||||
int n = dn_skipname(cp, eom);
|
||||
cp += n + QFIXEDSZ;
|
||||
if (n < 0 || cp > eom) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
ancount = ntohs(hp->ancount);
|
||||
if (!ancount) {
|
||||
if (hp->aa)
|
||||
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
|
||||
else
|
||||
RES_SET_H_ERRNO(pvt->res, TRY_AGAIN);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Prepare a return structure. */
|
||||
bp = pvt->buf;
|
||||
ep = pvt->buf + sizeof(pvt->buf);
|
||||
pvt->net.n_name = NULL;
|
||||
pvt->net.n_aliases = pvt->ali;
|
||||
pvt->net.n_addrtype = af;
|
||||
pvt->net.n_addr = NULL;
|
||||
pvt->net.n_length = addrlen;
|
||||
|
||||
/* Save input key if given. */
|
||||
switch (by_what) {
|
||||
case by_name:
|
||||
if (name != NULL) {
|
||||
int n = strlen(name) + 1;
|
||||
|
||||
if (n > (ep - bp)) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
}
|
||||
#ifdef HAVE_STRLCPY
|
||||
strlcpy(bp, name, ep - bp);
|
||||
pvt->net.n_name = bp;
|
||||
#else
|
||||
pvt->net.n_name = strcpy(bp, name);
|
||||
#endif
|
||||
bp += n;
|
||||
}
|
||||
break;
|
||||
case by_addr:
|
||||
if (addr != NULL && addrlen != 0) {
|
||||
int n = addrlen / 8 + ((addrlen % 8) != 0);
|
||||
|
||||
if (INADDRSZ > (ep - bp)) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
}
|
||||
memset(bp, 0, INADDRSZ);
|
||||
memcpy(bp, addr, n);
|
||||
pvt->net.n_addr = bp;
|
||||
bp += INADDRSZ;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Parse the answer, collect aliases. */
|
||||
ap = pvt->ali;
|
||||
haveanswer = 0;
|
||||
while (--ancount >= 0 && cp < eom) {
|
||||
int n = dn_expand(ansbuf, eom, cp, bp, ep - bp);
|
||||
|
||||
cp += n; /* Owner */
|
||||
if (n < 0 || !maybe_dnok(pvt->res, bp) ||
|
||||
cp + 3 * INT16SZ + INT32SZ > eom) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
}
|
||||
GETSHORT(type, cp); /* Type */
|
||||
GETSHORT(class, cp); /* Class */
|
||||
cp += INT32SZ; /* TTL */
|
||||
GETSHORT(n, cp); /* RDLENGTH */
|
||||
if (class == C_IN && type == T_PTR) {
|
||||
int nn;
|
||||
|
||||
nn = dn_expand(ansbuf, eom, cp, bp, ep - bp);
|
||||
if (nn < 0 || !maybe_hnok(pvt->res, bp) || nn != n) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
}
|
||||
normalize_name(bp);
|
||||
switch (by_what) {
|
||||
case by_addr: {
|
||||
if (pvt->net.n_name == NULL)
|
||||
pvt->net.n_name = bp;
|
||||
else if (ns_samename(pvt->net.n_name, bp) == 1)
|
||||
break;
|
||||
else
|
||||
*ap++ = bp;
|
||||
nn = strlen(bp) + 1;
|
||||
bp += nn;
|
||||
haveanswer++;
|
||||
break;
|
||||
}
|
||||
case by_name: {
|
||||
u_int b1, b2, b3, b4;
|
||||
|
||||
if (pvt->net.n_addr != NULL ||
|
||||
sscanf(bp, "%u.%u.%u.%u.in-addr.arpa",
|
||||
&b1, &b2, &b3, &b4) != 4)
|
||||
break;
|
||||
if ((ep - bp) < INADDRSZ) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
}
|
||||
pvt->net.n_addr = bp;
|
||||
*bp++ = b4;
|
||||
*bp++ = b3;
|
||||
*bp++ = b2;
|
||||
*bp++ = b1;
|
||||
pvt->net.n_length = INADDRSZ * 8;
|
||||
haveanswer++;
|
||||
}
|
||||
}
|
||||
}
|
||||
cp += n; /* RDATA */
|
||||
}
|
||||
if (!haveanswer) {
|
||||
RES_SET_H_ERRNO(pvt->res, TRY_AGAIN);
|
||||
return (NULL);
|
||||
}
|
||||
*ap = NULL;
|
||||
|
||||
return (&pvt->net);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
get1101mask(struct irs_nw *this, struct nwent *nwent) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char qbuf[sizeof "255.255.255.255.in-addr.arpa"], owner[MAXDNAME];
|
||||
int anslen, type, class, ancount, qdcount;
|
||||
u_char *ansbuf, *cp, *eom;
|
||||
HEADER *hp;
|
||||
|
||||
if (!nwent)
|
||||
return (NULL);
|
||||
if (make1101inaddr(nwent->n_addr, nwent->n_length, qbuf, sizeof qbuf)
|
||||
< 0) {
|
||||
/* "First, do no harm." */
|
||||
return (nwent);
|
||||
}
|
||||
|
||||
ansbuf = memget(MAXPACKET);
|
||||
if (ansbuf == NULL) {
|
||||
errno = ENOMEM;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
}
|
||||
/* Query for the A RR that would hold this network's mask. */
|
||||
anslen = res_nquery(pvt->res, qbuf, C_IN, T_A, ansbuf, MAXPACKET);
|
||||
if (anslen < HFIXEDSZ) {
|
||||
memput(ansbuf, MAXPACKET);
|
||||
return (nwent);
|
||||
}
|
||||
|
||||
/* Initialize, and parse header. */
|
||||
hp = (HEADER *)ansbuf;
|
||||
cp = ansbuf + HFIXEDSZ;
|
||||
eom = ansbuf + anslen;
|
||||
qdcount = ntohs(hp->qdcount);
|
||||
while (qdcount-- > 0) {
|
||||
int n = dn_skipname(cp, eom);
|
||||
cp += n + QFIXEDSZ;
|
||||
if (n < 0 || cp > eom) {
|
||||
memput(ansbuf, MAXPACKET);
|
||||
return (nwent);
|
||||
}
|
||||
}
|
||||
ancount = ntohs(hp->ancount);
|
||||
|
||||
/* Parse the answer, collect aliases. */
|
||||
while (--ancount >= 0 && cp < eom) {
|
||||
int n = dn_expand(ansbuf, eom, cp, owner, sizeof owner);
|
||||
|
||||
if (n < 0 || !maybe_dnok(pvt->res, owner))
|
||||
break;
|
||||
cp += n; /* Owner */
|
||||
if (cp + 3 * INT16SZ + INT32SZ > eom)
|
||||
break;
|
||||
GETSHORT(type, cp); /* Type */
|
||||
GETSHORT(class, cp); /* Class */
|
||||
cp += INT32SZ; /* TTL */
|
||||
GETSHORT(n, cp); /* RDLENGTH */
|
||||
if (cp + n > eom)
|
||||
break;
|
||||
if (n == INADDRSZ && class == C_IN && type == T_A &&
|
||||
ns_samename(qbuf, owner) == 1) {
|
||||
/* This A RR indicates the actual netmask. */
|
||||
int nn, mm;
|
||||
|
||||
nwent->n_length = 0;
|
||||
for (nn = 0; nn < INADDRSZ; nn++)
|
||||
for (mm = 7; mm >= 0; mm--)
|
||||
if (cp[nn] & (1 << mm))
|
||||
nwent->n_length++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
cp += n; /* RDATA */
|
||||
}
|
||||
memput(ansbuf, MAXPACKET);
|
||||
return (nwent);
|
||||
}
|
||||
|
||||
static int
|
||||
make1101inaddr(const u_char *net, int bits, char *name, int size) {
|
||||
int n, m;
|
||||
char *ep;
|
||||
|
||||
ep = name + size;
|
||||
|
||||
/* Zero fill any whole bytes left out of the prefix. */
|
||||
for (n = (32 - bits) / 8; n > 0; n--) {
|
||||
if (ep - name < (int)(sizeof "0."))
|
||||
goto emsgsize;
|
||||
m = SPRINTF((name, "0."));
|
||||
name += m;
|
||||
}
|
||||
|
||||
/* Format the partial byte, if any, within the prefix. */
|
||||
if ((n = bits % 8) != 0) {
|
||||
if (ep - name < (int)(sizeof "255."))
|
||||
goto emsgsize;
|
||||
m = SPRINTF((name, "%u.",
|
||||
net[bits / 8] & ~((1 << (8 - n)) - 1)));
|
||||
name += m;
|
||||
}
|
||||
|
||||
/* Format the whole bytes within the prefix. */
|
||||
for (n = bits / 8; n > 0; n--) {
|
||||
if (ep - name < (int)(sizeof "255."))
|
||||
goto emsgsize;
|
||||
m = SPRINTF((name, "%u.", net[n - 1]));
|
||||
name += m;
|
||||
}
|
||||
|
||||
/* Add the static text. */
|
||||
if (ep - name < (int)(sizeof "in-addr.arpa"))
|
||||
goto emsgsize;
|
||||
(void) SPRINTF((name, "in-addr.arpa"));
|
||||
return (0);
|
||||
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static void
|
||||
normalize_name(char *name) {
|
||||
char *t;
|
||||
|
||||
/* Make lower case. */
|
||||
for (t = name; *t; t++)
|
||||
if (isascii((unsigned char)*t) && isupper((unsigned char)*t))
|
||||
*t = tolower(*t);
|
||||
|
||||
/* Remove trailing dots. */
|
||||
while (t > name && t[-1] == '.')
|
||||
*--t = '\0';
|
||||
}
|
||||
|
||||
static int
|
||||
init(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res && !nw_res_get(this))
|
||||
return (-1);
|
||||
if (((pvt->res->options & RES_INIT) == 0) &&
|
||||
res_ninit(pvt->res) == -1)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 1996-1999 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: dns_p.h,v 1.1 2004/04/15 16:03:28 wkornew Exp $
|
||||
*/
|
||||
|
||||
#ifndef _DNS_P_H_INCLUDED
|
||||
#define _DNS_P_H_INCLUDED
|
||||
|
||||
#define maybe_ok(res, nm, ok) (((res)->options & RES_NOCHECKNAME) != 0 || \
|
||||
(ok)(nm) != 0)
|
||||
#define maybe_hnok(res, hn) maybe_ok((res), (hn), res_hnok)
|
||||
#define maybe_dnok(res, dn) maybe_ok((res), (dn), res_dnok)
|
||||
|
||||
/*
|
||||
* Object state.
|
||||
*/
|
||||
struct dns_p {
|
||||
void *hes_ctx;
|
||||
struct __res_state *res;
|
||||
void (*free_res) __P((void *));
|
||||
};
|
||||
|
||||
/*
|
||||
* Methods.
|
||||
*/
|
||||
|
||||
extern struct irs_gr * irs_dns_gr __P((struct irs_acc *));
|
||||
extern struct irs_pw * irs_dns_pw __P((struct irs_acc *));
|
||||
extern struct irs_sv * irs_dns_sv __P((struct irs_acc *));
|
||||
extern struct irs_pr * irs_dns_pr __P((struct irs_acc *));
|
||||
extern struct irs_ho * irs_dns_ho __P((struct irs_acc *));
|
||||
extern struct irs_nw * irs_dns_nw __P((struct irs_acc *));
|
||||
|
||||
#endif /*_DNS_P_H_INCLUDED*/
|
||||
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: dns_pr.c,v 1.1 2004/04/15 16:03:28 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "hesiod.h"
|
||||
#include "dns_p.h"
|
||||
|
||||
/* Types. */
|
||||
|
||||
struct pvt {
|
||||
struct dns_p * dns;
|
||||
struct protoent proto;
|
||||
char * prbuf;
|
||||
};
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static void pr_close(struct irs_pr *);
|
||||
static struct protoent * pr_byname(struct irs_pr *, const char *);
|
||||
static struct protoent * pr_bynumber(struct irs_pr *, int);
|
||||
static struct protoent * pr_next(struct irs_pr *);
|
||||
static void pr_rewind(struct irs_pr *);
|
||||
static void pr_minimize(struct irs_pr *);
|
||||
static struct __res_state * pr_res_get(struct irs_pr *);
|
||||
static void pr_res_set(struct irs_pr *,
|
||||
struct __res_state *,
|
||||
void (*)(void *));
|
||||
|
||||
static struct protoent * parse_hes_list(struct irs_pr *, char **);
|
||||
|
||||
/* Public. */
|
||||
|
||||
struct irs_pr *
|
||||
irs_dns_pr(struct irs_acc *this) {
|
||||
struct dns_p *dns = (struct dns_p *)this->private;
|
||||
struct pvt *pvt;
|
||||
struct irs_pr *pr;
|
||||
|
||||
if (!dns->hes_ctx) {
|
||||
errno = ENODEV;
|
||||
return (NULL);
|
||||
}
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
if (!(pr = memget(sizeof *pr))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pr, 0x5e, sizeof *pr);
|
||||
pvt->dns = dns;
|
||||
pr->private = pvt;
|
||||
pr->byname = pr_byname;
|
||||
pr->bynumber = pr_bynumber;
|
||||
pr->next = pr_next;
|
||||
pr->rewind = pr_rewind;
|
||||
pr->close = pr_close;
|
||||
pr->minimize = pr_minimize;
|
||||
pr->res_get = pr_res_get;
|
||||
pr->res_set = pr_res_set;
|
||||
return (pr);
|
||||
}
|
||||
|
||||
/* Methods. */
|
||||
|
||||
static void
|
||||
pr_close(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->proto.p_aliases)
|
||||
free(pvt->proto.p_aliases);
|
||||
if (pvt->prbuf)
|
||||
free(pvt->prbuf);
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct protoent *
|
||||
pr_byname(struct irs_pr *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
struct protoent *proto;
|
||||
char **hes_list;
|
||||
|
||||
if (!(hes_list = hesiod_resolve(dns->hes_ctx, name, "protocol")))
|
||||
return (NULL);
|
||||
|
||||
proto = parse_hes_list(this, hes_list);
|
||||
hesiod_free_list(dns->hes_ctx, hes_list);
|
||||
return (proto);
|
||||
}
|
||||
|
||||
static struct protoent *
|
||||
pr_bynumber(struct irs_pr *this, int num) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
struct protoent *proto;
|
||||
char numstr[16];
|
||||
char **hes_list;
|
||||
|
||||
sprintf(numstr, "%d", num);
|
||||
if (!(hes_list = hesiod_resolve(dns->hes_ctx, numstr, "protonum")))
|
||||
return (NULL);
|
||||
|
||||
proto = parse_hes_list(this, hes_list);
|
||||
hesiod_free_list(dns->hes_ctx, hes_list);
|
||||
return (proto);
|
||||
}
|
||||
|
||||
static struct protoent *
|
||||
pr_next(struct irs_pr *this) {
|
||||
UNUSED(this);
|
||||
errno = ENODEV;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
pr_rewind(struct irs_pr *this) {
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
static void
|
||||
pr_minimize(struct irs_pr *this) {
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
pr_res_get(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
|
||||
return (__hesiod_res_get(dns->hes_ctx));
|
||||
}
|
||||
|
||||
static void
|
||||
pr_res_set(struct irs_pr *this, struct __res_state * res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
|
||||
__hesiod_res_set(dns->hes_ctx, res, free_res);
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
static struct protoent *
|
||||
parse_hes_list(struct irs_pr *this, char **hes_list) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char *p, *cp, **cpp, **new;
|
||||
int num = 0;
|
||||
int max = 0;
|
||||
|
||||
for (cpp = hes_list; *cpp; cpp++) {
|
||||
cp = *cpp;
|
||||
|
||||
/* Strip away comments, if any. */
|
||||
if ((p = strchr(cp, '#')))
|
||||
*p = 0;
|
||||
|
||||
/* Skip blank lines. */
|
||||
p = cp;
|
||||
while (*p && !isspace((unsigned char)*p))
|
||||
p++;
|
||||
if (!*p)
|
||||
continue;
|
||||
|
||||
/* OK, we've got a live one. Let's parse it for real. */
|
||||
if (pvt->prbuf)
|
||||
free(pvt->prbuf);
|
||||
pvt->prbuf = strdup(cp);
|
||||
|
||||
p = pvt->prbuf;
|
||||
pvt->proto.p_name = p;
|
||||
while (*p && !isspace((unsigned char)*p))
|
||||
p++;
|
||||
if (!*p)
|
||||
continue;
|
||||
*p++ = '\0';
|
||||
|
||||
pvt->proto.p_proto = atoi(p);
|
||||
while (*p && !isspace((unsigned char)*p))
|
||||
p++;
|
||||
if (*p)
|
||||
*p++ = '\0';
|
||||
|
||||
while (*p) {
|
||||
if ((num + 1) >= max || !pvt->proto.p_aliases) {
|
||||
max += 10;
|
||||
new = realloc(pvt->proto.p_aliases,
|
||||
max * sizeof(char *));
|
||||
if (!new) {
|
||||
errno = ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
pvt->proto.p_aliases = new;
|
||||
}
|
||||
pvt->proto.p_aliases[num++] = p;
|
||||
while (*p && !isspace((unsigned char)*p))
|
||||
p++;
|
||||
if (*p)
|
||||
*p++ = '\0';
|
||||
}
|
||||
if (!pvt->proto.p_aliases)
|
||||
pvt->proto.p_aliases = malloc(sizeof(char *));
|
||||
if (!pvt->proto.p_aliases)
|
||||
goto cleanup;
|
||||
pvt->proto.p_aliases[num] = NULL;
|
||||
return (&pvt->proto);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (pvt->proto.p_aliases) {
|
||||
free(pvt->proto.p_aliases);
|
||||
pvt->proto.p_aliases = NULL;
|
||||
}
|
||||
if (pvt->prbuf) {
|
||||
free(pvt->prbuf);
|
||||
pvt->prbuf = NULL;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: dns_pw.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_PW
|
||||
static int __bind_irs_pw_unneeded;
|
||||
#else
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "hesiod.h"
|
||||
#include "dns_p.h"
|
||||
|
||||
/* Types. */
|
||||
|
||||
struct pvt {
|
||||
struct dns_p * dns;
|
||||
struct passwd passwd;
|
||||
char * pwbuf;
|
||||
};
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static void pw_close(struct irs_pw *);
|
||||
static struct passwd * pw_byname(struct irs_pw *, const char *);
|
||||
static struct passwd * pw_byuid(struct irs_pw *, uid_t);
|
||||
static struct passwd * pw_next(struct irs_pw *);
|
||||
static void pw_rewind(struct irs_pw *);
|
||||
static void pw_minimize(struct irs_pw *);
|
||||
static struct __res_state * pw_res_get(struct irs_pw *);
|
||||
static void pw_res_set(struct irs_pw *,
|
||||
struct __res_state *,
|
||||
void (*)(void *));
|
||||
|
||||
static struct passwd * getpwcommon(struct irs_pw *, const char *,
|
||||
const char *);
|
||||
|
||||
/* Public. */
|
||||
|
||||
struct irs_pw *
|
||||
irs_dns_pw(struct irs_acc *this) {
|
||||
struct dns_p *dns = (struct dns_p *)this->private;
|
||||
struct irs_pw *pw;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!dns || !dns->hes_ctx) {
|
||||
errno = ENODEV;
|
||||
return (NULL);
|
||||
}
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->dns = dns;
|
||||
if (!(pw = memget(sizeof *pw))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pw, 0x5e, sizeof *pw);
|
||||
pw->private = pvt;
|
||||
pw->close = pw_close;
|
||||
pw->byname = pw_byname;
|
||||
pw->byuid = pw_byuid;
|
||||
pw->next = pw_next;
|
||||
pw->rewind = pw_rewind;
|
||||
pw->minimize = pw_minimize;
|
||||
pw->res_get = pw_res_get;
|
||||
pw->res_set = pw_res_set;
|
||||
return (pw);
|
||||
}
|
||||
|
||||
/* Methods. */
|
||||
|
||||
static void
|
||||
pw_close(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->pwbuf)
|
||||
free(pvt->pwbuf);
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
pw_byname(struct irs_pw *this, const char *nam) {
|
||||
return (getpwcommon(this, nam, "passwd"));
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
pw_byuid(struct irs_pw *this, uid_t uid) {
|
||||
char uidstr[16];
|
||||
|
||||
sprintf(uidstr, "%lu", (u_long)uid);
|
||||
return (getpwcommon(this, uidstr, "uid"));
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
pw_next(struct irs_pw *this) {
|
||||
UNUSED(this);
|
||||
errno = ENODEV;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
pw_rewind(struct irs_pw *this) {
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
static void
|
||||
pw_minimize(struct irs_pw *this) {
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
pw_res_get(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
|
||||
return (__hesiod_res_get(dns->hes_ctx));
|
||||
}
|
||||
|
||||
static void
|
||||
pw_res_set(struct irs_pw *this, struct __res_state * res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
|
||||
__hesiod_res_set(dns->hes_ctx, res, free_res);
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
static struct passwd *
|
||||
getpwcommon(struct irs_pw *this, const char *arg, const char *type) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char **hes_list, *cp;
|
||||
|
||||
if (!(hes_list = hesiod_resolve(pvt->dns->hes_ctx, arg, type)))
|
||||
return (NULL);
|
||||
if (!*hes_list) {
|
||||
hesiod_free_list(pvt->dns->hes_ctx, hes_list);
|
||||
errno = ENOENT;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
memset(&pvt->passwd, 0, sizeof pvt->passwd);
|
||||
if (pvt->pwbuf)
|
||||
free(pvt->pwbuf);
|
||||
pvt->pwbuf = strdup(*hes_list);
|
||||
hesiod_free_list(pvt->dns->hes_ctx, hes_list);
|
||||
|
||||
cp = pvt->pwbuf;
|
||||
pvt->passwd.pw_name = cp;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
pvt->passwd.pw_passwd = cp;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
pvt->passwd.pw_uid = atoi(cp);
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
pvt->passwd.pw_gid = atoi(cp);
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
pvt->passwd.pw_gecos = cp;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
pvt->passwd.pw_dir = cp;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
pvt->passwd.pw_shell = cp;
|
||||
return (&pvt->passwd);
|
||||
|
||||
cleanup:
|
||||
free(pvt->pwbuf);
|
||||
pvt->pwbuf = NULL;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
#endif /* WANT_IRS_PW */
|
||||
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: dns_sv.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "hesiod.h"
|
||||
#include "dns_p.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
struct pvt {
|
||||
struct dns_p * dns;
|
||||
struct servent serv;
|
||||
char * svbuf;
|
||||
struct __res_state * res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static void sv_close(struct irs_sv *);
|
||||
static struct servent * sv_byname(struct irs_sv *,
|
||||
const char *, const char *);
|
||||
static struct servent * sv_byport(struct irs_sv *, int, const char *);
|
||||
static struct servent * sv_next(struct irs_sv *);
|
||||
static void sv_rewind(struct irs_sv *);
|
||||
static void sv_minimize(struct irs_sv *);
|
||||
#ifdef SV_RES_SETGET
|
||||
static struct __res_state * sv_res_get(struct irs_sv *);
|
||||
static void sv_res_set(struct irs_sv *,
|
||||
struct __res_state *,
|
||||
void (*)(void *));
|
||||
#endif
|
||||
|
||||
static struct servent * parse_hes_list(struct irs_sv *,
|
||||
char **, const char *);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_sv *
|
||||
irs_dns_sv(struct irs_acc *this) {
|
||||
struct dns_p *dns = (struct dns_p *)this->private;
|
||||
struct irs_sv *sv;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!dns || !dns->hes_ctx) {
|
||||
errno = ENODEV;
|
||||
return (NULL);
|
||||
}
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->dns = dns;
|
||||
if (!(sv = memget(sizeof *sv))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(sv, 0x5e, sizeof *sv);
|
||||
sv->private = pvt;
|
||||
sv->byname = sv_byname;
|
||||
sv->byport = sv_byport;
|
||||
sv->next = sv_next;
|
||||
sv->rewind = sv_rewind;
|
||||
sv->close = sv_close;
|
||||
sv->minimize = sv_minimize;
|
||||
#ifdef SV_RES_SETGET
|
||||
sv->res_get = sv_res_get;
|
||||
sv->res_set = sv_res_set;
|
||||
#else
|
||||
sv->res_get = NULL; /* sv_res_get; */
|
||||
sv->res_set = NULL; /* sv_res_set; */
|
||||
#endif
|
||||
return (sv);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
sv_close(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->serv.s_aliases)
|
||||
free(pvt->serv.s_aliases);
|
||||
if (pvt->svbuf)
|
||||
free(pvt->svbuf);
|
||||
|
||||
if (pvt->res && pvt->free_res)
|
||||
(*pvt->free_res)(pvt->res);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct servent *
|
||||
sv_byname(struct irs_sv *this, const char *name, const char *proto) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
struct servent *s;
|
||||
char **hes_list;
|
||||
|
||||
if (!(hes_list = hesiod_resolve(dns->hes_ctx, name, "service")))
|
||||
return (NULL);
|
||||
|
||||
s = parse_hes_list(this, hes_list, proto);
|
||||
hesiod_free_list(dns->hes_ctx, hes_list);
|
||||
return (s);
|
||||
}
|
||||
|
||||
static struct servent *
|
||||
sv_byport(struct irs_sv *this, int port, const char *proto) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
struct servent *s;
|
||||
char portstr[16];
|
||||
char **hes_list;
|
||||
|
||||
sprintf(portstr, "%d", ntohs(port));
|
||||
if (!(hes_list = hesiod_resolve(dns->hes_ctx, portstr, "port")))
|
||||
return (NULL);
|
||||
|
||||
s = parse_hes_list(this, hes_list, proto);
|
||||
hesiod_free_list(dns->hes_ctx, hes_list);
|
||||
return (s);
|
||||
}
|
||||
|
||||
static struct servent *
|
||||
sv_next(struct irs_sv *this) {
|
||||
UNUSED(this);
|
||||
errno = ENODEV;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
sv_rewind(struct irs_sv *this) {
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static struct servent *
|
||||
parse_hes_list(struct irs_sv *this, char **hes_list, const char *proto) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char *p, *cp, **cpp, **new;
|
||||
int proto_len;
|
||||
int num = 0;
|
||||
int max = 0;
|
||||
|
||||
for (cpp = hes_list; *cpp; cpp++) {
|
||||
cp = *cpp;
|
||||
|
||||
/* Strip away comments, if any. */
|
||||
if ((p = strchr(cp, '#')))
|
||||
*p = 0;
|
||||
|
||||
/* Check to make sure the protocol matches. */
|
||||
p = cp;
|
||||
while (*p && !isspace((unsigned char)*p))
|
||||
p++;
|
||||
if (!*p)
|
||||
continue;
|
||||
if (proto) {
|
||||
proto_len = strlen(proto);
|
||||
if (strncasecmp(++p, proto, proto_len) != 0)
|
||||
continue;
|
||||
if (p[proto_len] && !isspace(p[proto_len]&0xff))
|
||||
continue;
|
||||
}
|
||||
/* OK, we've got a live one. Let's parse it for real. */
|
||||
if (pvt->svbuf)
|
||||
free(pvt->svbuf);
|
||||
pvt->svbuf = strdup(cp);
|
||||
|
||||
p = pvt->svbuf;
|
||||
pvt->serv.s_name = p;
|
||||
while (*p && !isspace(*p&0xff))
|
||||
p++;
|
||||
if (!*p)
|
||||
continue;
|
||||
*p++ = '\0';
|
||||
|
||||
pvt->serv.s_proto = p;
|
||||
while (*p && !isspace(*p&0xff))
|
||||
p++;
|
||||
if (!*p)
|
||||
continue;
|
||||
*p++ = '\0';
|
||||
|
||||
pvt->serv.s_port = htons((u_short) atoi(p));
|
||||
while (*p && !isspace(*p&0xff))
|
||||
p++;
|
||||
if (*p)
|
||||
*p++ = '\0';
|
||||
|
||||
while (*p) {
|
||||
if ((num + 1) >= max || !pvt->serv.s_aliases) {
|
||||
max += 10;
|
||||
new = realloc(pvt->serv.s_aliases,
|
||||
max * sizeof(char *));
|
||||
if (!new) {
|
||||
errno = ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
pvt->serv.s_aliases = new;
|
||||
}
|
||||
pvt->serv.s_aliases[num++] = p;
|
||||
while (*p && !isspace(*p&0xff))
|
||||
p++;
|
||||
if (*p)
|
||||
*p++ = '\0';
|
||||
}
|
||||
if (!pvt->serv.s_aliases)
|
||||
pvt->serv.s_aliases = malloc(sizeof(char *));
|
||||
if (!pvt->serv.s_aliases)
|
||||
goto cleanup;
|
||||
pvt->serv.s_aliases[num] = NULL;
|
||||
return (&pvt->serv);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (pvt->serv.s_aliases) {
|
||||
free(pvt->serv.s_aliases);
|
||||
pvt->serv.s_aliases = NULL;
|
||||
}
|
||||
if (pvt->svbuf) {
|
||||
free(pvt->svbuf);
|
||||
pvt->svbuf = NULL;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
sv_minimize(struct irs_sv *this) {
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
#ifdef SV_RES_SETGET
|
||||
static struct __res_state *
|
||||
sv_res_get(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
|
||||
return (__hesiod_res_get(dns->hes_ctx));
|
||||
}
|
||||
|
||||
static void
|
||||
sv_res_set(struct irs_sv *this, struct __res_state * res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
|
||||
__hesiod_res_set(dns->hes_ctx, res, free_res);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2001 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.
|
||||
*/
|
||||
|
||||
#include <port_before.h>
|
||||
#include <netdb.h>
|
||||
#include <port_after.h>
|
||||
|
||||
#ifdef DO_PTHREADS
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
static const char *gai_errlist[] = {
|
||||
"no error",
|
||||
"address family not supported for name",/* EAI_ADDRFAMILY */
|
||||
"temporary failure", /* EAI_AGAIN */
|
||||
"invalid flags", /* EAI_BADFLAGS */
|
||||
"permanent failure", /* EAI_FAIL */
|
||||
"address family not supported", /* EAI_FAMILY */
|
||||
"memory failure", /* EAI_MEMORY */
|
||||
"no address", /* EAI_NODATA */
|
||||
"unknown name or service", /* EAI_NONAME */
|
||||
"service not supported for socktype", /* EAI_SERVICE */
|
||||
"socktype not supported", /* EAI_SOCKTYPE */
|
||||
"system failure", /* EAI_SYSTEM */
|
||||
"bad hints", /* EAI_BADHINTS */
|
||||
"bad protocol", /* EAI_PROTOCOL */
|
||||
|
||||
"unknown error" /* Must be last. */
|
||||
};
|
||||
|
||||
static const int gai_nerr = (sizeof(gai_errlist)/sizeof(*gai_errlist));
|
||||
|
||||
#define EAI_BUFSIZE 128
|
||||
|
||||
const char *
|
||||
gai_strerror(int ecode) {
|
||||
#ifndef DO_PTHREADS
|
||||
static char buf[EAI_BUFSIZE];
|
||||
#else /* DO_PTHREADS */
|
||||
static pthread_mutex_t lock;
|
||||
static pthread_key_t key;
|
||||
static int once = 0;
|
||||
char *buf;
|
||||
#endif
|
||||
|
||||
if (ecode >= 0 && ecode < (gai_nerr - 1))
|
||||
return (gai_errlist[ecode]);
|
||||
|
||||
#ifdef DO_PTHREADS
|
||||
if (!once) {
|
||||
// OpenBeOS compatibility: this is a function call, thus it must be
|
||||
// initialized here and not at when allocating 'lock'
|
||||
lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
pthread_mutex_lock(&lock);
|
||||
if (!once++)
|
||||
key = tls_allocate();
|
||||
pthread_mutex_unlock(&lock);
|
||||
}
|
||||
|
||||
buf = tls_get(key);
|
||||
if (buf == NULL) {
|
||||
buf = malloc(EAI_BUFSIZE);
|
||||
if (buf == NULL)
|
||||
return ("unknown error");
|
||||
on_exit_thread(free, buf);
|
||||
tls_set(key, buf);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* XXX This really should be snprintf(buf, EAI_BUFSIZE, ...).
|
||||
* It is safe until message catalogs are used.
|
||||
*/
|
||||
sprintf(buf, "%s: %d", gai_errlist[gai_nerr - 1], ecode);
|
||||
return (buf);
|
||||
}
|
||||
@@ -0,0 +1,430 @@
|
||||
/*
|
||||
* Copyright (c) 1996-1999 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.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: gen.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* this is the top level dispatcher
|
||||
*
|
||||
* The dispatcher is implemented as an accessor class; it is an
|
||||
* accessor class that calls other accessor classes, as controlled by a
|
||||
* configuration file.
|
||||
*
|
||||
* A big difference between this accessor class and others is that the
|
||||
* map class initializers are NULL, and the map classes are already
|
||||
* filled in with method functions that will do the right thing.
|
||||
*/
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <isc/assertions.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "gen_p.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
struct nameval {
|
||||
const char * name;
|
||||
int val;
|
||||
};
|
||||
|
||||
static const struct nameval acc_names[irs_nacc+1] = {
|
||||
{ "local", irs_lcl },
|
||||
{ "dns", irs_dns },
|
||||
{ "nis", irs_nis },
|
||||
{ "irp", irs_irp },
|
||||
{ NULL, irs_nacc }
|
||||
};
|
||||
|
||||
typedef struct irs_acc *(*accinit) __P((const char *options));
|
||||
|
||||
static const accinit accs[irs_nacc+1] = {
|
||||
irs_lcl_acc,
|
||||
irs_dns_acc,
|
||||
#ifdef WANT_IRS_NIS
|
||||
irs_nis_acc,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
irs_irp_acc,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct nameval map_names[irs_nmap+1] = {
|
||||
{ "group", irs_gr },
|
||||
{ "passwd", irs_pw },
|
||||
{ "services", irs_sv },
|
||||
{ "protocols", irs_pr },
|
||||
{ "hosts", irs_ho },
|
||||
{ "networks", irs_nw },
|
||||
{ "netgroup", irs_ng },
|
||||
{ NULL, irs_nmap }
|
||||
};
|
||||
|
||||
static const struct nameval option_names[] = {
|
||||
{ "merge", IRS_MERGE },
|
||||
{ "continue", IRS_CONTINUE },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void gen_close(struct irs_acc *);
|
||||
static struct __res_state * gen_res_get(struct irs_acc *);
|
||||
static void gen_res_set(struct irs_acc *, struct __res_state *,
|
||||
void (*)(void *));
|
||||
static int find_name(const char *, const struct nameval nv[]);
|
||||
static void init_map_rules(struct gen_p *, const char *conf_file);
|
||||
static struct irs_rule *release_rule(struct irs_rule *);
|
||||
static int add_rule(struct gen_p *,
|
||||
enum irs_map_id, enum irs_acc_id,
|
||||
const char *);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_acc *
|
||||
irs_gen_acc(const char *options, const char *conf_file) {
|
||||
struct irs_acc *acc;
|
||||
struct gen_p *irs;
|
||||
|
||||
if (!(acc = memget(sizeof *acc))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(acc, 0x5e, sizeof *acc);
|
||||
if (!(irs = memget(sizeof *irs))) {
|
||||
errno = ENOMEM;
|
||||
memput(acc, sizeof *acc);
|
||||
return (NULL);
|
||||
}
|
||||
memset(irs, 0x5e, sizeof *irs);
|
||||
irs->options = strdup(options);
|
||||
irs->res = NULL;
|
||||
irs->free_res = NULL;
|
||||
memset(irs->accessors, 0, sizeof irs->accessors);
|
||||
memset(irs->map_rules, 0, sizeof irs->map_rules);
|
||||
init_map_rules(irs, conf_file);
|
||||
acc->private = irs;
|
||||
#ifdef WANT_IRS_GR
|
||||
acc->gr_map = irs_gen_gr;
|
||||
#else
|
||||
acc->gr_map = NULL;
|
||||
#endif
|
||||
#ifdef WANT_IRS_PW
|
||||
acc->pw_map = irs_gen_pw;
|
||||
#else
|
||||
acc->pw_map = NULL;
|
||||
#endif
|
||||
acc->sv_map = irs_gen_sv;
|
||||
acc->pr_map = irs_gen_pr;
|
||||
acc->ho_map = irs_gen_ho;
|
||||
acc->nw_map = irs_gen_nw;
|
||||
acc->ng_map = irs_gen_ng;
|
||||
acc->res_get = gen_res_get;
|
||||
acc->res_set = gen_res_set;
|
||||
acc->close = gen_close;
|
||||
return (acc);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static struct __res_state *
|
||||
gen_res_get(struct irs_acc *this) {
|
||||
struct gen_p *irs = (struct gen_p *)this->private;
|
||||
|
||||
if (irs->res == NULL) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (res == NULL)
|
||||
return (NULL);
|
||||
memset(res, 0, sizeof *res);
|
||||
gen_res_set(this, res, free);
|
||||
}
|
||||
|
||||
if (((irs->res->options & RES_INIT) == 0) && res_ninit(irs->res) < 0)
|
||||
return (NULL);
|
||||
|
||||
return (irs->res);
|
||||
}
|
||||
|
||||
static void
|
||||
gen_res_set(struct irs_acc *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct gen_p *irs = (struct gen_p *)this->private;
|
||||
#if 0
|
||||
struct irs_rule *rule;
|
||||
struct irs_ho *ho;
|
||||
struct irs_nw *nw;
|
||||
#endif
|
||||
|
||||
if (irs->res && irs->free_res) {
|
||||
res_nclose(irs->res);
|
||||
(*irs->free_res)(irs->res);
|
||||
}
|
||||
|
||||
irs->res = res;
|
||||
irs->free_res = free_res;
|
||||
|
||||
#if 0
|
||||
for (rule = irs->map_rules[irs_ho]; rule; rule = rule->next) {
|
||||
ho = rule->inst->ho;
|
||||
|
||||
(*ho->res_set)(ho, res, NULL);
|
||||
}
|
||||
for (rule = irs->map_rules[irs_nw]; rule; rule = rule->next) {
|
||||
nw = rule->inst->nw;
|
||||
|
||||
(*nw->res_set)(nw, res, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
gen_close(struct irs_acc *this) {
|
||||
struct gen_p *irs = (struct gen_p *)this->private;
|
||||
int n;
|
||||
|
||||
/* Search rules. */
|
||||
for (n = 0; n < irs_nmap; n++)
|
||||
while (irs->map_rules[n] != NULL)
|
||||
irs->map_rules[n] = release_rule(irs->map_rules[n]);
|
||||
|
||||
/* Access methods. */
|
||||
for (n = 0; n < irs_nacc; n++) {
|
||||
/* Map objects. */
|
||||
if (irs->accessors[n].gr != NULL)
|
||||
(*irs->accessors[n].gr->close)(irs->accessors[n].gr);
|
||||
if (irs->accessors[n].pw != NULL)
|
||||
(*irs->accessors[n].pw->close)(irs->accessors[n].pw);
|
||||
if (irs->accessors[n].sv != NULL)
|
||||
(*irs->accessors[n].sv->close)(irs->accessors[n].sv);
|
||||
if (irs->accessors[n].pr != NULL)
|
||||
(*irs->accessors[n].pr->close)(irs->accessors[n].pr);
|
||||
if (irs->accessors[n].ho != NULL)
|
||||
(*irs->accessors[n].ho->close)(irs->accessors[n].ho);
|
||||
if (irs->accessors[n].nw != NULL)
|
||||
(*irs->accessors[n].nw->close)(irs->accessors[n].nw);
|
||||
if (irs->accessors[n].ng != NULL)
|
||||
(*irs->accessors[n].ng->close)(irs->accessors[n].ng);
|
||||
/* Enclosing accessor. */
|
||||
if (irs->accessors[n].acc != NULL)
|
||||
(*irs->accessors[n].acc->close)(irs->accessors[n].acc);
|
||||
}
|
||||
|
||||
/* The options string was strdup'd. */
|
||||
free((void*)irs->options);
|
||||
|
||||
if (irs->res && irs->free_res)
|
||||
(*irs->free_res)(irs->res);
|
||||
|
||||
/* The private data container. */
|
||||
memput(irs, sizeof *irs);
|
||||
|
||||
/* The object. */
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static int
|
||||
find_name(const char *name, const struct nameval names[]) {
|
||||
int n;
|
||||
|
||||
for (n = 0; names[n].name != NULL; n++)
|
||||
if (strcmp(name, names[n].name) == 0)
|
||||
return (names[n].val);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static struct irs_rule *
|
||||
release_rule(struct irs_rule *rule) {
|
||||
struct irs_rule *next = rule->next;
|
||||
|
||||
memput(rule, sizeof *rule);
|
||||
return (next);
|
||||
}
|
||||
|
||||
static int
|
||||
add_rule(struct gen_p *irs,
|
||||
enum irs_map_id map, enum irs_acc_id acc,
|
||||
const char *options)
|
||||
{
|
||||
struct irs_rule **rules, *last, *tmp, *new;
|
||||
struct irs_inst *inst;
|
||||
const char *cp;
|
||||
int n;
|
||||
|
||||
#ifndef WANT_IRS_GR
|
||||
if (map == irs_gr)
|
||||
return (-1);
|
||||
#endif
|
||||
#ifndef WANT_IRS_PW
|
||||
if (map == irs_pw)
|
||||
return (-1);
|
||||
#endif
|
||||
#ifndef WANT_IRS_NIS
|
||||
if (acc == irs_nis)
|
||||
return (-1);
|
||||
#endif
|
||||
new = memget(sizeof *new);
|
||||
if (new == NULL)
|
||||
return (-1);
|
||||
memset(new, 0x5e, sizeof *new);
|
||||
new->next = NULL;
|
||||
|
||||
new->inst = &irs->accessors[acc];
|
||||
|
||||
new->flags = 0;
|
||||
cp = options;
|
||||
while (cp && *cp) {
|
||||
char option[50], *next;
|
||||
|
||||
next = strchr(cp, ',');
|
||||
if (next)
|
||||
n = next++ - cp;
|
||||
else
|
||||
n = strlen(cp);
|
||||
if ((size_t)n > sizeof option - 1)
|
||||
n = sizeof option - 1;
|
||||
strncpy(option, cp, n);
|
||||
option[n] = '\0';
|
||||
|
||||
n = find_name(option, option_names);
|
||||
if (n >= 0)
|
||||
new->flags |= n;
|
||||
|
||||
cp = next;
|
||||
}
|
||||
|
||||
rules = &irs->map_rules[map];
|
||||
for (last = NULL, tmp = *rules;
|
||||
tmp != NULL;
|
||||
last = tmp, tmp = tmp->next)
|
||||
(void)NULL;
|
||||
if (last == NULL)
|
||||
*rules = new;
|
||||
else
|
||||
last->next = new;
|
||||
|
||||
/* Try to instantiate map accessors for this if necessary & approp. */
|
||||
inst = &irs->accessors[acc];
|
||||
if (inst->acc == NULL && accs[acc] != NULL)
|
||||
inst->acc = (*accs[acc])(irs->options);
|
||||
if (inst->acc != NULL) {
|
||||
if (inst->gr == NULL && inst->acc->gr_map != NULL)
|
||||
inst->gr = (*inst->acc->gr_map)(inst->acc);
|
||||
if (inst->pw == NULL && inst->acc->pw_map != NULL)
|
||||
inst->pw = (*inst->acc->pw_map)(inst->acc);
|
||||
if (inst->sv == NULL && inst->acc->sv_map != NULL)
|
||||
inst->sv = (*inst->acc->sv_map)(inst->acc);
|
||||
if (inst->pr == NULL && inst->acc->pr_map != NULL)
|
||||
inst->pr = (*inst->acc->pr_map)(inst->acc);
|
||||
if (inst->ho == NULL && inst->acc->ho_map != NULL)
|
||||
inst->ho = (*inst->acc->ho_map)(inst->acc);
|
||||
if (inst->nw == NULL && inst->acc->nw_map != NULL)
|
||||
inst->nw = (*inst->acc->nw_map)(inst->acc);
|
||||
if (inst->ng == NULL && inst->acc->ng_map != NULL)
|
||||
inst->ng = (*inst->acc->ng_map)(inst->acc);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
default_map_rules(struct gen_p *irs) {
|
||||
/* Install time honoured and proved BSD style rules as default. */
|
||||
add_rule(irs, irs_gr, irs_lcl, "");
|
||||
add_rule(irs, irs_pw, irs_lcl, "");
|
||||
add_rule(irs, irs_sv, irs_lcl, "");
|
||||
add_rule(irs, irs_pr, irs_lcl, "");
|
||||
add_rule(irs, irs_ho, irs_dns, "continue");
|
||||
add_rule(irs, irs_ho, irs_lcl, "");
|
||||
add_rule(irs, irs_nw, irs_dns, "continue");
|
||||
add_rule(irs, irs_nw, irs_lcl, "");
|
||||
add_rule(irs, irs_ng, irs_lcl, "");
|
||||
}
|
||||
|
||||
static void
|
||||
init_map_rules(struct gen_p *irs, const char *conf_file) {
|
||||
char line[1024], pattern[40], mapname[20], accname[20], options[100];
|
||||
FILE *conf;
|
||||
|
||||
if (conf_file == NULL)
|
||||
conf_file = _PATH_IRS_CONF ;
|
||||
|
||||
/* A conf file of "" means compiled in defaults. Irpd wants this */
|
||||
if (conf_file[0] == '\0' || (conf = fopen(conf_file, "r")) == NULL) {
|
||||
default_map_rules(irs);
|
||||
return;
|
||||
}
|
||||
(void) sprintf(pattern, "%%%ds %%%ds %%%ds\n",
|
||||
sizeof mapname, sizeof accname, sizeof options);
|
||||
while (fgets(line, sizeof line, conf)) {
|
||||
enum irs_map_id map;
|
||||
enum irs_acc_id acc;
|
||||
char *tmp;
|
||||
int n;
|
||||
|
||||
for (tmp = line;
|
||||
isascii((unsigned char)*tmp) &&
|
||||
isspace((unsigned char)*tmp);
|
||||
tmp++)
|
||||
(void)NULL;
|
||||
if (*tmp == '#' || *tmp == '\n' || *tmp == '\0')
|
||||
continue;
|
||||
n = sscanf(tmp, pattern, mapname, accname, options);
|
||||
if (n < 2)
|
||||
continue;
|
||||
if (n < 3)
|
||||
options[0] = '\0';
|
||||
|
||||
n = find_name(mapname, map_names);
|
||||
INSIST(n < irs_nmap);
|
||||
if (n < 0)
|
||||
continue;
|
||||
map = (enum irs_map_id) n;
|
||||
|
||||
n = find_name(accname, acc_names);
|
||||
INSIST(n < irs_nacc);
|
||||
if (n < 0)
|
||||
continue;
|
||||
acc = (enum irs_acc_id) n;
|
||||
|
||||
add_rule(irs, map, acc, options);
|
||||
}
|
||||
fclose(conf);
|
||||
}
|
||||
@@ -0,0 +1,482 @@
|
||||
/*
|
||||
* Copyright (c) 1996-1999 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.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: gen_gr.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_GR
|
||||
static int __bind_irs_gr_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <isc/assertions.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "gen_p.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
struct pvt {
|
||||
struct irs_rule * rules;
|
||||
struct irs_rule * rule;
|
||||
struct irs_gr * gr;
|
||||
/*
|
||||
* Need space to store the entries read from the group file.
|
||||
* The members list also needs space per member, and the
|
||||
* strings making up the user names must be allocated
|
||||
* somewhere. Rather than doing lots of small allocations,
|
||||
* we keep one buffer and resize it as needed.
|
||||
*/
|
||||
struct group group;
|
||||
size_t nmemb; /* Malloc'd max index of gr_mem[]. */
|
||||
char * membuf;
|
||||
size_t membufsize;
|
||||
struct __res_state * res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void gr_close(struct irs_gr *);
|
||||
static struct group * gr_next(struct irs_gr *);
|
||||
static struct group * gr_byname(struct irs_gr *, const char *);
|
||||
static struct group * gr_bygid(struct irs_gr *, gid_t);
|
||||
static void gr_rewind(struct irs_gr *);
|
||||
static int gr_list(struct irs_gr *, const char *,
|
||||
gid_t, gid_t *, int *);
|
||||
static void gr_minimize(struct irs_gr *);
|
||||
static struct __res_state * gr_res_get(struct irs_gr *);
|
||||
static void gr_res_set(struct irs_gr *,
|
||||
struct __res_state *,
|
||||
void (*)(void *));
|
||||
|
||||
static void grmerge(struct irs_gr *gr, const struct group *src,
|
||||
int preserve);
|
||||
|
||||
static int countvec(char **vec);
|
||||
static int isnew(char **old, char *new);
|
||||
static int countnew(char **old, char **new);
|
||||
static size_t sizenew(char **old, char **new);
|
||||
static int newgid(int, gid_t *, gid_t);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_gr *
|
||||
irs_gen_gr(struct irs_acc *this) {
|
||||
struct gen_p *accpvt = (struct gen_p *)this->private;
|
||||
struct irs_gr *gr;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(gr = memget(sizeof *gr))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(gr, 0x5e, sizeof *gr);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(gr, sizeof *gr);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->rules = accpvt->map_rules[irs_gr];
|
||||
pvt->rule = pvt->rules;
|
||||
gr->private = pvt;
|
||||
gr->close = gr_close;
|
||||
gr->next = gr_next;
|
||||
gr->byname = gr_byname;
|
||||
gr->bygid = gr_bygid;
|
||||
gr->rewind = gr_rewind;
|
||||
gr->list = gr_list;
|
||||
gr->minimize = gr_minimize;
|
||||
gr->res_get = gr_res_get;
|
||||
gr->res_set = gr_res_set;
|
||||
return (gr);
|
||||
}
|
||||
|
||||
/* Methods. */
|
||||
|
||||
static void
|
||||
gr_close(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_next(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct group *rval;
|
||||
struct irs_gr *gr;
|
||||
|
||||
while (pvt->rule) {
|
||||
gr = pvt->rule->inst->gr;
|
||||
rval = (*gr->next)(gr);
|
||||
if (rval)
|
||||
return (rval);
|
||||
if (!(pvt->rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
pvt->rule = pvt->rule->next;
|
||||
if (pvt->rule) {
|
||||
gr = pvt->rule->inst->gr;
|
||||
(*gr->rewind)(gr);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_byname(struct irs_gr *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct group *tval;
|
||||
struct irs_gr *gr;
|
||||
int dirty;
|
||||
|
||||
dirty = 0;
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
gr = rule->inst->gr;
|
||||
tval = (*gr->byname)(gr, name);
|
||||
if (tval) {
|
||||
grmerge(this, tval, dirty++);
|
||||
if (!(rule->flags & IRS_MERGE))
|
||||
break;
|
||||
} else {
|
||||
if (!(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dirty)
|
||||
return (&pvt->group);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_bygid(struct irs_gr *this, gid_t gid) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct group *tval;
|
||||
struct irs_gr *gr;
|
||||
int dirty;
|
||||
|
||||
dirty = 0;
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
gr = rule->inst->gr;
|
||||
tval = (*gr->bygid)(gr, gid);
|
||||
if (tval) {
|
||||
grmerge(this, tval, dirty++);
|
||||
if (!(rule->flags & IRS_MERGE))
|
||||
break;
|
||||
} else {
|
||||
if (!(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dirty)
|
||||
return (&pvt->group);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gr_rewind(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_gr *gr;
|
||||
|
||||
pvt->rule = pvt->rules;
|
||||
if (pvt->rule) {
|
||||
gr = pvt->rule->inst->gr;
|
||||
(*gr->rewind)(gr);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
gr_list(struct irs_gr *this, const char *name,
|
||||
gid_t basegid, gid_t *groups, int *ngroups)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct irs_gr *gr;
|
||||
int t_ngroups, maxgroups;
|
||||
gid_t *t_groups;
|
||||
int n, t, rval = 0;
|
||||
|
||||
maxgroups = *ngroups;
|
||||
*ngroups = 0;
|
||||
t_groups = (gid_t *)malloc(maxgroups * sizeof(gid_t));
|
||||
if (!t_groups) {
|
||||
errno = ENOMEM;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
t_ngroups = maxgroups;
|
||||
gr = rule->inst->gr;
|
||||
t = (*gr->list)(gr, name, basegid, t_groups, &t_ngroups);
|
||||
for (n = 0; n < t_ngroups; n++) {
|
||||
if (newgid(*ngroups, groups, t_groups[n])) {
|
||||
if (*ngroups == maxgroups) {
|
||||
rval = -1;
|
||||
goto done;
|
||||
}
|
||||
groups[(*ngroups)++] = t_groups[n];
|
||||
}
|
||||
}
|
||||
if (t == 0) {
|
||||
if (!(rule->flags & IRS_MERGE))
|
||||
break;
|
||||
} else {
|
||||
if (!(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
}
|
||||
done:
|
||||
free(t_groups);
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static void
|
||||
gr_minimize(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_gr *gr = rule->inst->gr;
|
||||
|
||||
(*gr->minimize)(gr);
|
||||
}
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
gr_res_get(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (!res) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
gr_res_set(this, res, free);
|
||||
}
|
||||
|
||||
return (pvt->res);
|
||||
}
|
||||
|
||||
static void
|
||||
gr_res_set(struct irs_gr *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
if (pvt->res && pvt->free_res) {
|
||||
res_nclose(pvt->res);
|
||||
(*pvt->free_res)(pvt->res);
|
||||
}
|
||||
|
||||
pvt->res = res;
|
||||
pvt->free_res = free_res;
|
||||
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_gr *gr = rule->inst->gr;
|
||||
|
||||
if (gr->res_set)
|
||||
(*gr->res_set)(gr, pvt->res, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
static void
|
||||
grmerge(struct irs_gr *this, const struct group *src, int preserve) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char *cp, **m, **p, *oldmembuf, *ep;
|
||||
int n, ndst, nnew;
|
||||
size_t used;
|
||||
|
||||
if (!preserve) {
|
||||
pvt->group.gr_gid = src->gr_gid;
|
||||
if (pvt->nmemb < 1) {
|
||||
m = malloc(sizeof *m);
|
||||
if (!m) {
|
||||
/* No harm done, no work done. */
|
||||
return;
|
||||
}
|
||||
pvt->group.gr_mem = m;
|
||||
pvt->nmemb = 1;
|
||||
}
|
||||
pvt->group.gr_mem[0] = NULL;
|
||||
}
|
||||
ndst = countvec(pvt->group.gr_mem);
|
||||
nnew = countnew(pvt->group.gr_mem, src->gr_mem);
|
||||
|
||||
/*
|
||||
* Make sure destination member array is large enough.
|
||||
* p points to new portion.
|
||||
*/
|
||||
n = ndst + nnew + 1;
|
||||
if ((size_t)n > pvt->nmemb) {
|
||||
m = realloc(pvt->group.gr_mem, n * sizeof *m);
|
||||
if (!m) {
|
||||
/* No harm done, no work done. */
|
||||
return;
|
||||
}
|
||||
pvt->group.gr_mem = m;
|
||||
pvt->nmemb = n;
|
||||
}
|
||||
p = pvt->group.gr_mem + ndst;
|
||||
|
||||
/*
|
||||
* Enlarge destination membuf; cp points at new portion.
|
||||
*/
|
||||
n = sizenew(pvt->group.gr_mem, src->gr_mem);
|
||||
INSIST((nnew == 0) == (n == 0));
|
||||
if (!preserve) {
|
||||
n += strlen(src->gr_name) + 1;
|
||||
n += strlen(src->gr_passwd) + 1;
|
||||
}
|
||||
if (n == 0) {
|
||||
/* No work to do. */
|
||||
return;
|
||||
}
|
||||
used = preserve ? pvt->membufsize : 0;
|
||||
cp = malloc(used + n);
|
||||
if (!cp) {
|
||||
/* No harm done, no work done. */
|
||||
return;
|
||||
}
|
||||
ep = cp + used + n;
|
||||
if (used != 0)
|
||||
memcpy(cp, pvt->membuf, used);
|
||||
oldmembuf = pvt->membuf;
|
||||
pvt->membuf = cp;
|
||||
pvt->membufsize = used + n;
|
||||
cp += used;
|
||||
|
||||
/*
|
||||
* Adjust group.gr_mem.
|
||||
*/
|
||||
if (pvt->membuf != oldmembuf)
|
||||
for (m = pvt->group.gr_mem; *m; m++)
|
||||
*m = pvt->membuf + (*m - oldmembuf);
|
||||
|
||||
/*
|
||||
* Add new elements.
|
||||
*/
|
||||
for (m = src->gr_mem; *m; m++)
|
||||
if (isnew(pvt->group.gr_mem, *m)) {
|
||||
*p++ = cp;
|
||||
*p = NULL;
|
||||
#ifdef HAVE_STRLCPY
|
||||
strlcpy(cp, *m, ep - cp);
|
||||
#else
|
||||
strcpy(cp, *m);
|
||||
#endif
|
||||
cp += strlen(cp) + 1;
|
||||
}
|
||||
if (preserve) {
|
||||
pvt->group.gr_name = pvt->membuf +
|
||||
(pvt->group.gr_name - oldmembuf);
|
||||
pvt->group.gr_passwd = pvt->membuf +
|
||||
(pvt->group.gr_passwd - oldmembuf);
|
||||
} else {
|
||||
pvt->group.gr_name = cp;
|
||||
#ifdef HAVE_STRLCPY
|
||||
strlcpy(cp, src->gr_name, ep - cp);
|
||||
#else
|
||||
strcpy(cp, src->gr_name);
|
||||
#endif
|
||||
cp += strlen(src->gr_name) + 1;
|
||||
pvt->group.gr_passwd = cp;
|
||||
#ifdef HAVE_STRLCPY
|
||||
strlcpy(cp, src->gr_passwd, ep - cp);
|
||||
#else
|
||||
strcpy(cp, src->gr_passwd);
|
||||
#endif
|
||||
cp += strlen(src->gr_passwd) + 1;
|
||||
}
|
||||
if (oldmembuf != NULL)
|
||||
free(oldmembuf);
|
||||
INSIST(cp >= pvt->membuf && cp <= &pvt->membuf[pvt->membufsize]);
|
||||
}
|
||||
|
||||
static int
|
||||
countvec(char **vec) {
|
||||
int n = 0;
|
||||
|
||||
while (*vec++)
|
||||
n++;
|
||||
return (n);
|
||||
}
|
||||
|
||||
static int
|
||||
isnew(char **old, char *new) {
|
||||
for (; *old; old++)
|
||||
if (strcmp(*old, new) == 0)
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
countnew(char **old, char **new) {
|
||||
int n = 0;
|
||||
|
||||
for (; *new; new++)
|
||||
n += isnew(old, *new);
|
||||
return (n);
|
||||
}
|
||||
|
||||
static size_t
|
||||
sizenew(char **old, char **new) {
|
||||
size_t n = 0;
|
||||
|
||||
for (; *new; new++)
|
||||
if (isnew(old, *new))
|
||||
n += strlen(*new) + 1;
|
||||
return (n);
|
||||
}
|
||||
|
||||
static int
|
||||
newgid(int ngroups, gid_t *groups, gid_t group) {
|
||||
ngroups--, groups++;
|
||||
for (; ngroups-- > 0; groups++)
|
||||
if (*groups == group)
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
#endif /* WANT_IRS_GR */
|
||||
@@ -0,0 +1,391 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: gen_ho.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "gen_p.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
struct pvt {
|
||||
struct irs_rule * rules;
|
||||
struct irs_rule * rule;
|
||||
struct irs_ho * ho;
|
||||
struct __res_state * res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
/* Forwards */
|
||||
|
||||
static void ho_close(struct irs_ho *this);
|
||||
static struct hostent * ho_byname(struct irs_ho *this, const char *name);
|
||||
static struct hostent * ho_byname2(struct irs_ho *this, const char *name,
|
||||
int af);
|
||||
static struct hostent * ho_byaddr(struct irs_ho *this, const void *addr,
|
||||
int len, int af);
|
||||
static struct hostent * ho_next(struct irs_ho *this);
|
||||
static void ho_rewind(struct irs_ho *this);
|
||||
static void ho_minimize(struct irs_ho *this);
|
||||
static struct __res_state * ho_res_get(struct irs_ho *this);
|
||||
static void ho_res_set(struct irs_ho *this,
|
||||
struct __res_state *res,
|
||||
void (*free_res)(void *));
|
||||
static struct addrinfo * ho_addrinfo(struct irs_ho *this, const char *name,
|
||||
const struct addrinfo *pai);
|
||||
|
||||
static int init(struct irs_ho *this);
|
||||
|
||||
/* Exports */
|
||||
|
||||
struct irs_ho *
|
||||
irs_gen_ho(struct irs_acc *this) {
|
||||
struct gen_p *accpvt = (struct gen_p *)this->private;
|
||||
struct irs_ho *ho;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
if (!(ho = memget(sizeof *ho))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(ho, 0x5e, sizeof *ho);
|
||||
pvt->rules = accpvt->map_rules[irs_ho];
|
||||
pvt->rule = pvt->rules;
|
||||
ho->private = pvt;
|
||||
ho->close = ho_close;
|
||||
ho->byname = ho_byname;
|
||||
ho->byname2 = ho_byname2;
|
||||
ho->byaddr = ho_byaddr;
|
||||
ho->next = ho_next;
|
||||
ho->rewind = ho_rewind;
|
||||
ho->minimize = ho_minimize;
|
||||
ho->res_get = ho_res_get;
|
||||
ho->res_set = ho_res_set;
|
||||
ho->addrinfo = ho_addrinfo;
|
||||
return (ho);
|
||||
}
|
||||
|
||||
/* Methods. */
|
||||
|
||||
static void
|
||||
ho_close(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
ho_minimize(this);
|
||||
if (pvt->res && pvt->free_res)
|
||||
(*pvt->free_res)(pvt->res);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_byname(struct irs_ho *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct hostent *rval;
|
||||
struct irs_ho *ho;
|
||||
int therrno = NETDB_INTERNAL;
|
||||
int softerror = 0;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
ho = rule->inst->ho;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
errno = 0;
|
||||
rval = (*ho->byname)(ho, name);
|
||||
if (rval != NULL)
|
||||
return (rval);
|
||||
if (softerror == 0 &&
|
||||
pvt->res->res_h_errno != HOST_NOT_FOUND &&
|
||||
pvt->res->res_h_errno != NETDB_INTERNAL) {
|
||||
softerror = 1;
|
||||
therrno = pvt->res->res_h_errno;
|
||||
}
|
||||
if (rule->flags & IRS_CONTINUE)
|
||||
continue;
|
||||
/*
|
||||
* The value TRY_AGAIN can mean that the service
|
||||
* is not available, or just that this particular name
|
||||
* cannot be resolved now. We use the errno ECONNREFUSED
|
||||
* to distinguish. If a lookup sets that errno when
|
||||
* H_ERRNO is TRY_AGAIN, we continue to try other lookup
|
||||
* functions, otherwise we return the TRY_AGAIN error.
|
||||
*/
|
||||
if (pvt->res->res_h_errno != TRY_AGAIN || errno != ECONNREFUSED)
|
||||
break;
|
||||
}
|
||||
if (softerror != 0 && pvt->res->res_h_errno == HOST_NOT_FOUND)
|
||||
RES_SET_H_ERRNO(pvt->res, therrno);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_byname2(struct irs_ho *this, const char *name, int af) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct hostent *rval;
|
||||
struct irs_ho *ho;
|
||||
int therrno = NETDB_INTERNAL;
|
||||
int softerror = 0;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
ho = rule->inst->ho;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
errno = 0;
|
||||
rval = (*ho->byname2)(ho, name, af);
|
||||
if (rval != NULL)
|
||||
return (rval);
|
||||
if (softerror == 0 &&
|
||||
pvt->res->res_h_errno != HOST_NOT_FOUND &&
|
||||
pvt->res->res_h_errno != NETDB_INTERNAL) {
|
||||
softerror = 1;
|
||||
therrno = pvt->res->res_h_errno;
|
||||
}
|
||||
if (rule->flags & IRS_CONTINUE)
|
||||
continue;
|
||||
/*
|
||||
* See the comments in ho_byname() explaining
|
||||
* the interpretation of TRY_AGAIN and ECONNREFUSED.
|
||||
*/
|
||||
if (pvt->res->res_h_errno != TRY_AGAIN || errno != ECONNREFUSED)
|
||||
break;
|
||||
}
|
||||
if (softerror != 0 && pvt->res->res_h_errno == HOST_NOT_FOUND)
|
||||
RES_SET_H_ERRNO(pvt->res, therrno);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct hostent *rval;
|
||||
struct irs_ho *ho;
|
||||
int therrno = NETDB_INTERNAL;
|
||||
int softerror = 0;
|
||||
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
ho = rule->inst->ho;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
errno = 0;
|
||||
rval = (*ho->byaddr)(ho, addr, len, af);
|
||||
if (rval != NULL)
|
||||
return (rval);
|
||||
if (softerror == 0 &&
|
||||
pvt->res->res_h_errno != HOST_NOT_FOUND &&
|
||||
pvt->res->res_h_errno != NETDB_INTERNAL) {
|
||||
softerror = 1;
|
||||
therrno = pvt->res->res_h_errno;
|
||||
}
|
||||
|
||||
if (rule->flags & IRS_CONTINUE)
|
||||
continue;
|
||||
/*
|
||||
* See the comments in ho_byname() explaining
|
||||
* the interpretation of TRY_AGAIN and ECONNREFUSED.
|
||||
*/
|
||||
if (pvt->res->res_h_errno != TRY_AGAIN || errno != ECONNREFUSED)
|
||||
break;
|
||||
}
|
||||
if (softerror != 0 && pvt->res->res_h_errno == HOST_NOT_FOUND)
|
||||
RES_SET_H_ERRNO(pvt->res, therrno);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_next(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct hostent *rval;
|
||||
struct irs_ho *ho;
|
||||
|
||||
while (pvt->rule) {
|
||||
ho = pvt->rule->inst->ho;
|
||||
rval = (*ho->next)(ho);
|
||||
if (rval)
|
||||
return (rval);
|
||||
if (!(pvt->rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
pvt->rule = pvt->rule->next;
|
||||
if (pvt->rule) {
|
||||
ho = pvt->rule->inst->ho;
|
||||
(*ho->rewind)(ho);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
ho_rewind(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_ho *ho;
|
||||
|
||||
pvt->rule = pvt->rules;
|
||||
if (pvt->rule) {
|
||||
ho = pvt->rule->inst->ho;
|
||||
(*ho->rewind)(ho);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ho_minimize(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
if (pvt->res)
|
||||
res_nclose(pvt->res);
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_ho *ho = rule->inst->ho;
|
||||
|
||||
(*ho->minimize)(ho);
|
||||
}
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
ho_res_get(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (!res) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
ho_res_set(this, res, free);
|
||||
}
|
||||
|
||||
return (pvt->res);
|
||||
}
|
||||
|
||||
static void
|
||||
ho_res_set(struct irs_ho *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
if (pvt->res && pvt->free_res) {
|
||||
res_nclose(pvt->res);
|
||||
(*pvt->free_res)(pvt->res);
|
||||
}
|
||||
|
||||
pvt->res = res;
|
||||
pvt->free_res = free_res;
|
||||
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_ho *ho = rule->inst->ho;
|
||||
|
||||
(*ho->res_set)(ho, pvt->res, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static struct addrinfo *
|
||||
ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct addrinfo *rval = NULL;
|
||||
struct irs_ho *ho;
|
||||
int therrno = NETDB_INTERNAL;
|
||||
int softerror = 0;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
ho = rule->inst->ho;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
errno = 0;
|
||||
if (ho->addrinfo == NULL) /* for safety */
|
||||
continue;
|
||||
rval = (*ho->addrinfo)(ho, name, pai);
|
||||
if (rval != NULL)
|
||||
return (rval);
|
||||
if (softerror == 0 &&
|
||||
pvt->res->res_h_errno != HOST_NOT_FOUND &&
|
||||
pvt->res->res_h_errno != NETDB_INTERNAL) {
|
||||
softerror = 1;
|
||||
therrno = pvt->res->res_h_errno;
|
||||
}
|
||||
if (rule->flags & IRS_CONTINUE)
|
||||
continue;
|
||||
/*
|
||||
* See the comments in ho_byname() explaining
|
||||
* the interpretation of TRY_AGAIN and ECONNREFUSED.
|
||||
*/
|
||||
if (pvt->res->res_h_errno != TRY_AGAIN ||
|
||||
errno != ECONNREFUSED)
|
||||
break;
|
||||
}
|
||||
if (softerror != 0 && pvt->res->res_h_errno == HOST_NOT_FOUND)
|
||||
RES_SET_H_ERRNO(pvt->res, therrno);
|
||||
if (rval)
|
||||
freeaddrinfo(rval);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
init(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res && !ho_res_get(this))
|
||||
return (-1);
|
||||
|
||||
if (((pvt->res->options & RES_INIT) == 0) &&
|
||||
(res_ninit(pvt->res) == -1))
|
||||
return (-1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: gen_ng.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "gen_p.h"
|
||||
|
||||
/* Types */
|
||||
|
||||
struct pvt {
|
||||
struct irs_rule * rules;
|
||||
struct irs_rule * rule;
|
||||
char * curgroup;
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void ng_close(struct irs_ng *);
|
||||
static int ng_next(struct irs_ng *, const char **,
|
||||
const char **, const char **);
|
||||
static int ng_test(struct irs_ng *, const char *,
|
||||
const char *, const char *,
|
||||
const char *);
|
||||
static void ng_rewind(struct irs_ng *, const char *);
|
||||
static void ng_minimize(struct irs_ng *);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_ng *
|
||||
irs_gen_ng(struct irs_acc *this) {
|
||||
struct gen_p *accpvt = (struct gen_p *)this->private;
|
||||
struct irs_ng *ng;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(ng = memget(sizeof *ng))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(ng, 0x5e, sizeof *ng);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(ng, sizeof *ng);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->rules = accpvt->map_rules[irs_ng];
|
||||
pvt->rule = pvt->rules;
|
||||
ng->private = pvt;
|
||||
ng->close = ng_close;
|
||||
ng->next = ng_next;
|
||||
ng->test = ng_test;
|
||||
ng->rewind = ng_rewind;
|
||||
ng->minimize = ng_minimize;
|
||||
return (ng);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
ng_close(struct irs_ng *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
ng_minimize(this);
|
||||
if (pvt->curgroup)
|
||||
free(pvt->curgroup);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static int
|
||||
ng_next(struct irs_ng *this, const char **host, const char **user,
|
||||
const char **domain)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_ng *ng;
|
||||
|
||||
while (pvt->rule) {
|
||||
ng = pvt->rule->inst->ng;
|
||||
if ((*ng->next)(ng, host, user, domain) == 1)
|
||||
return (1);
|
||||
if (!(pvt->rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
pvt->rule = pvt->rule->next;
|
||||
if (pvt->rule) {
|
||||
ng = pvt->rule->inst->ng;
|
||||
(*ng->rewind)(ng, pvt->curgroup);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ng_test(struct irs_ng *this, const char *name,
|
||||
const char *user, const char *host, const char *domain)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct irs_ng *ng;
|
||||
int rval;
|
||||
|
||||
rval = 0;
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
ng = rule->inst->ng;
|
||||
rval = (*ng->test)(ng, name, user, host, domain);
|
||||
if (rval || !(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static void
|
||||
ng_rewind(struct irs_ng *this, const char *group) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_ng *ng;
|
||||
|
||||
pvt->rule = pvt->rules;
|
||||
if (pvt->rule) {
|
||||
if (pvt->curgroup)
|
||||
free(pvt->curgroup);
|
||||
pvt->curgroup = strdup(group);
|
||||
ng = pvt->rule->inst->ng;
|
||||
(*ng->rewind)(ng, pvt->curgroup);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ng_minimize(struct irs_ng *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_ng *ng = rule->inst->ng;
|
||||
|
||||
(*ng->minimize)(ng);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: gen_nw.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <resolv.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "gen_p.h"
|
||||
|
||||
/* Types */
|
||||
|
||||
struct pvt {
|
||||
struct irs_rule * rules;
|
||||
struct irs_rule * rule;
|
||||
struct __res_state * res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void nw_close(struct irs_nw*);
|
||||
static struct nwent * nw_next(struct irs_nw *);
|
||||
static struct nwent * nw_byname(struct irs_nw *, const char *, int);
|
||||
static struct nwent * nw_byaddr(struct irs_nw *, void *, int, int);
|
||||
static void nw_rewind(struct irs_nw *);
|
||||
static void nw_minimize(struct irs_nw *);
|
||||
static struct __res_state * nw_res_get(struct irs_nw *this);
|
||||
static void nw_res_set(struct irs_nw *this,
|
||||
struct __res_state *res,
|
||||
void (*free_res)(void *));
|
||||
|
||||
static int init(struct irs_nw *this);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_nw *
|
||||
irs_gen_nw(struct irs_acc *this) {
|
||||
struct gen_p *accpvt = (struct gen_p *)this->private;
|
||||
struct irs_nw *nw;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
if (!(nw = memget(sizeof *nw))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(nw, 0x5e, sizeof *nw);
|
||||
pvt->rules = accpvt->map_rules[irs_nw];
|
||||
pvt->rule = pvt->rules;
|
||||
nw->private = pvt;
|
||||
nw->close = nw_close;
|
||||
nw->next = nw_next;
|
||||
nw->byname = nw_byname;
|
||||
nw->byaddr = nw_byaddr;
|
||||
nw->rewind = nw_rewind;
|
||||
nw->minimize = nw_minimize;
|
||||
nw->res_get = nw_res_get;
|
||||
nw->res_set = nw_res_set;
|
||||
return (nw);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
nw_close(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
nw_minimize(this);
|
||||
|
||||
if (pvt->res && pvt->free_res)
|
||||
(*pvt->free_res)(pvt->res);
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
nw_next(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct nwent *rval;
|
||||
struct irs_nw *nw;
|
||||
|
||||
if (init(this) == -1)
|
||||
return(NULL);
|
||||
|
||||
while (pvt->rule) {
|
||||
nw = pvt->rule->inst->nw;
|
||||
rval = (*nw->next)(nw);
|
||||
if (rval)
|
||||
return (rval);
|
||||
if (!(pvt->rules->flags & IRS_CONTINUE))
|
||||
break;
|
||||
pvt->rule = pvt->rule->next;
|
||||
if (pvt->rule) {
|
||||
nw = pvt->rule->inst->nw;
|
||||
(*nw->rewind)(nw);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
nw_byname(struct irs_nw *this, const char *name, int type) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct nwent *rval;
|
||||
struct irs_nw *nw;
|
||||
|
||||
if (init(this) == -1)
|
||||
return(NULL);
|
||||
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
nw = rule->inst->nw;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
rval = (*nw->byname)(nw, name, type);
|
||||
if (rval != NULL)
|
||||
return (rval);
|
||||
if (pvt->res->res_h_errno != TRY_AGAIN &&
|
||||
!(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
nw_byaddr(struct irs_nw *this, void *net, int length, int type) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct nwent *rval;
|
||||
struct irs_nw *nw;
|
||||
|
||||
if (init(this) == -1)
|
||||
return(NULL);
|
||||
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
nw = rule->inst->nw;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
rval = (*nw->byaddr)(nw, net, length, type);
|
||||
if (rval != NULL)
|
||||
return (rval);
|
||||
if (pvt->res->res_h_errno != TRY_AGAIN &&
|
||||
!(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
nw_rewind(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_nw *nw;
|
||||
|
||||
pvt->rule = pvt->rules;
|
||||
if (pvt->rule) {
|
||||
nw = pvt->rule->inst->nw;
|
||||
(*nw->rewind)(nw);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nw_minimize(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
if (pvt->res)
|
||||
res_nclose(pvt->res);
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_nw *nw = rule->inst->nw;
|
||||
|
||||
(*nw->minimize)(nw);
|
||||
}
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
nw_res_get(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (!res) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
nw_res_set(this, res, free);
|
||||
}
|
||||
|
||||
return (pvt->res);
|
||||
}
|
||||
|
||||
static void
|
||||
nw_res_set(struct irs_nw *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
if (pvt->res && pvt->free_res) {
|
||||
res_nclose(pvt->res);
|
||||
(*pvt->free_res)(pvt->res);
|
||||
}
|
||||
|
||||
pvt->res = res;
|
||||
pvt->free_res = free_res;
|
||||
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_nw *nw = rule->inst->nw;
|
||||
|
||||
(*nw->res_set)(nw, pvt->res, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
init(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res && !nw_res_get(this))
|
||||
return (-1);
|
||||
if (((pvt->res->options & RES_INIT) == 0) &&
|
||||
res_ninit(pvt->res) == -1)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: gen_p.h,v 1.1 2004/04/15 16:03:29 wkornew Exp $
|
||||
*/
|
||||
|
||||
/* Notes:
|
||||
* We hope to create a complete set of thread-safe entry points someday,
|
||||
* which will mean a set of getXbyY() functions that take as an argument
|
||||
* a pointer to the map class, which will have a pointer to the private
|
||||
* data, which will be used preferentially to the static variables that
|
||||
* are necessary to support the "classic" interface. This "classic"
|
||||
* interface will then be reimplemented as stubs on top of the thread
|
||||
* safe modules, and will keep the map class pointers as their only
|
||||
* static data. HOWEVER, we are not there yet. So while we will call
|
||||
* the just-barely-converted map class methods with map class pointers,
|
||||
* right now they probably all still use statics. We're not fooling
|
||||
* anybody, and we're not trying to (yet).
|
||||
*/
|
||||
|
||||
#ifndef _GEN_P_H_INCLUDED
|
||||
#define _GEN_P_H_INCLUDED
|
||||
|
||||
/*
|
||||
* These are the access methods.
|
||||
*/
|
||||
enum irs_acc_id {
|
||||
irs_lcl, /* Local. */
|
||||
irs_dns, /* DNS or Hesiod. */
|
||||
irs_nis, /* Sun NIS ("YP"). */
|
||||
irs_irp, /* IR protocol. */
|
||||
irs_nacc
|
||||
};
|
||||
|
||||
/*
|
||||
* These are the map types.
|
||||
*/
|
||||
enum irs_map_id {
|
||||
irs_gr, /* "group" */
|
||||
irs_pw, /* "passwd" */
|
||||
irs_sv, /* "services" */
|
||||
irs_pr, /* "protocols" */
|
||||
irs_ho, /* "hosts" */
|
||||
irs_nw, /* "networks" */
|
||||
irs_ng, /* "netgroup" */
|
||||
irs_nmap
|
||||
};
|
||||
|
||||
/*
|
||||
* This is an accessor instance.
|
||||
*/
|
||||
struct irs_inst {
|
||||
struct irs_acc *acc;
|
||||
struct irs_gr * gr;
|
||||
struct irs_pw * pw;
|
||||
struct irs_sv * sv;
|
||||
struct irs_pr * pr;
|
||||
struct irs_ho * ho;
|
||||
struct irs_nw * nw;
|
||||
struct irs_ng * ng;
|
||||
};
|
||||
|
||||
/*
|
||||
* This is a search rule for some map type.
|
||||
*/
|
||||
struct irs_rule {
|
||||
struct irs_rule * next;
|
||||
struct irs_inst * inst;
|
||||
int flags;
|
||||
};
|
||||
#define IRS_MERGE 0x0001 /* Don't stop if acc. has data? */
|
||||
#define IRS_CONTINUE 0x0002 /* Don't stop if acc. has no data? */
|
||||
|
||||
/*
|
||||
* This is the private data for a search access class.
|
||||
*/
|
||||
struct gen_p {
|
||||
char * options;
|
||||
struct irs_rule * map_rules[(int)irs_nmap];
|
||||
struct irs_inst accessors[(int)irs_nacc];
|
||||
struct __res_state * res;
|
||||
void (*free_res) __P((void *));
|
||||
};
|
||||
|
||||
/*
|
||||
* Externs.
|
||||
*/
|
||||
|
||||
extern struct irs_acc * irs_gen_acc __P((const char *, const char *conf_file));
|
||||
extern struct irs_gr * irs_gen_gr __P((struct irs_acc *));
|
||||
extern struct irs_pw * irs_gen_pw __P((struct irs_acc *));
|
||||
extern struct irs_sv * irs_gen_sv __P((struct irs_acc *));
|
||||
extern struct irs_pr * irs_gen_pr __P((struct irs_acc *));
|
||||
extern struct irs_ho * irs_gen_ho __P((struct irs_acc *));
|
||||
extern struct irs_nw * irs_gen_nw __P((struct irs_acc *));
|
||||
extern struct irs_ng * irs_gen_ng __P((struct irs_acc *));
|
||||
|
||||
#endif /*_IRS_P_H_INCLUDED*/
|
||||
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: gen_pr.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <resolv.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "gen_p.h"
|
||||
|
||||
/* Types */
|
||||
|
||||
struct pvt {
|
||||
struct irs_rule * rules;
|
||||
struct irs_rule * rule;
|
||||
struct __res_state * res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void pr_close(struct irs_pr*);
|
||||
static struct protoent * pr_next(struct irs_pr *);
|
||||
static struct protoent * pr_byname(struct irs_pr *, const char *);
|
||||
static struct protoent * pr_bynumber(struct irs_pr *, int);
|
||||
static void pr_rewind(struct irs_pr *);
|
||||
static void pr_minimize(struct irs_pr *);
|
||||
static struct __res_state * pr_res_get(struct irs_pr *);
|
||||
static void pr_res_set(struct irs_pr *,
|
||||
struct __res_state *,
|
||||
void (*)(void *));
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_pr *
|
||||
irs_gen_pr(struct irs_acc *this) {
|
||||
struct gen_p *accpvt = (struct gen_p *)this->private;
|
||||
struct irs_pr *pr;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(pr = memget(sizeof *pr))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pr, 0x5e, sizeof *pr);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(pr, sizeof *pr);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->rules = accpvt->map_rules[irs_pr];
|
||||
pvt->rule = pvt->rules;
|
||||
pr->private = pvt;
|
||||
pr->close = pr_close;
|
||||
pr->next = pr_next;
|
||||
pr->byname = pr_byname;
|
||||
pr->bynumber = pr_bynumber;
|
||||
pr->rewind = pr_rewind;
|
||||
pr->minimize = pr_minimize;
|
||||
pr->res_get = pr_res_get;
|
||||
pr->res_set = pr_res_set;
|
||||
return (pr);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
pr_close(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct protoent *
|
||||
pr_next(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct protoent *rval;
|
||||
struct irs_pr *pr;
|
||||
|
||||
while (pvt->rule) {
|
||||
pr = pvt->rule->inst->pr;
|
||||
rval = (*pr->next)(pr);
|
||||
if (rval)
|
||||
return (rval);
|
||||
if (!(pvt->rules->flags & IRS_CONTINUE))
|
||||
break;
|
||||
pvt->rule = pvt->rule->next;
|
||||
if (pvt->rule) {
|
||||
pr = pvt->rule->inst->pr;
|
||||
(*pr->rewind)(pr);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct protoent *
|
||||
pr_byname(struct irs_pr *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct protoent *rval;
|
||||
struct irs_pr *pr;
|
||||
|
||||
rval = NULL;
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
pr = rule->inst->pr;
|
||||
rval = (*pr->byname)(pr, name);
|
||||
if (rval || !(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static struct protoent *
|
||||
pr_bynumber(struct irs_pr *this, int proto) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct protoent *rval;
|
||||
struct irs_pr *pr;
|
||||
|
||||
rval = NULL;
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
pr = rule->inst->pr;
|
||||
rval = (*pr->bynumber)(pr, proto);
|
||||
if (rval || !(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static void
|
||||
pr_rewind(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_pr *pr;
|
||||
|
||||
pvt->rule = pvt->rules;
|
||||
if (pvt->rule) {
|
||||
pr = pvt->rule->inst->pr;
|
||||
(*pr->rewind)(pr);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pr_minimize(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_pr *pr = rule->inst->pr;
|
||||
|
||||
(*pr->minimize)(pr);
|
||||
}
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
pr_res_get(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (!res) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
pr_res_set(this, res, free);
|
||||
}
|
||||
|
||||
return (pvt->res);
|
||||
}
|
||||
|
||||
static void
|
||||
pr_res_set(struct irs_pr *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
if (pvt->res && pvt->free_res) {
|
||||
res_nclose(pvt->res);
|
||||
(*pvt->free_res)(pvt->res);
|
||||
}
|
||||
|
||||
pvt->res = res;
|
||||
pvt->free_res = free_res;
|
||||
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_pr *pr = rule->inst->pr;
|
||||
|
||||
if (pr->res_set)
|
||||
(*pr->res_set)(pr, pvt->res, NULL);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: gen_pw.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_PW
|
||||
static int __bind_irs_pw_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "gen_p.h"
|
||||
|
||||
/* Types */
|
||||
|
||||
struct pvt {
|
||||
struct irs_rule * rules;
|
||||
struct irs_rule * rule;
|
||||
struct __res_state * res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void pw_close(struct irs_pw *);
|
||||
static struct passwd * pw_next(struct irs_pw *);
|
||||
static struct passwd * pw_byname(struct irs_pw *, const char *);
|
||||
static struct passwd * pw_byuid(struct irs_pw *, uid_t);
|
||||
static void pw_rewind(struct irs_pw *);
|
||||
static void pw_minimize(struct irs_pw *);
|
||||
static struct __res_state * pw_res_get(struct irs_pw *);
|
||||
static void pw_res_set(struct irs_pw *,
|
||||
struct __res_state *,
|
||||
void (*)(void *));
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_pw *
|
||||
irs_gen_pw(struct irs_acc *this) {
|
||||
struct gen_p *accpvt = (struct gen_p *)this->private;
|
||||
struct irs_pw *pw;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(pw = memget(sizeof *pw))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pw, 0x5e, sizeof *pw);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(pw, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->rules = accpvt->map_rules[irs_pw];
|
||||
pvt->rule = pvt->rules;
|
||||
pw->private = pvt;
|
||||
pw->close = pw_close;
|
||||
pw->next = pw_next;
|
||||
pw->byname = pw_byname;
|
||||
pw->byuid = pw_byuid;
|
||||
pw->rewind = pw_rewind;
|
||||
pw->minimize = pw_minimize;
|
||||
pw->res_get = pw_res_get;
|
||||
pw->res_set = pw_res_set;
|
||||
return (pw);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
pw_close(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
pw_next(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct passwd *rval;
|
||||
struct irs_pw *pw;
|
||||
|
||||
while (pvt->rule) {
|
||||
pw = pvt->rule->inst->pw;
|
||||
rval = (*pw->next)(pw);
|
||||
if (rval)
|
||||
return (rval);
|
||||
if (!(pvt->rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
pvt->rule = pvt->rule->next;
|
||||
if (pvt->rule) {
|
||||
pw = pvt->rule->inst->pw;
|
||||
(*pw->rewind)(pw);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
pw_rewind(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_pw *pw;
|
||||
|
||||
pvt->rule = pvt->rules;
|
||||
if (pvt->rule) {
|
||||
pw = pvt->rule->inst->pw;
|
||||
(*pw->rewind)(pw);
|
||||
}
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
pw_byname(struct irs_pw *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct passwd *rval;
|
||||
struct irs_pw *pw;
|
||||
|
||||
rval = NULL;
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
pw = rule->inst->pw;
|
||||
rval = (*pw->byname)(pw, name);
|
||||
if (rval || !(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
pw_byuid(struct irs_pw *this, uid_t uid) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct passwd *rval;
|
||||
struct irs_pw *pw;
|
||||
|
||||
rval = NULL;
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
pw = rule->inst->pw;
|
||||
rval = (*pw->byuid)(pw, uid);
|
||||
if (rval || !(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static void
|
||||
pw_minimize(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_pw *pw = rule->inst->pw;
|
||||
|
||||
(*pw->minimize)(pw);
|
||||
}
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
pw_res_get(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (!res) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
pw_res_set(this, res, free);
|
||||
}
|
||||
|
||||
return (pvt->res);
|
||||
}
|
||||
|
||||
static void
|
||||
pw_res_set(struct irs_pw *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
if (pvt->res && pvt->free_res) {
|
||||
res_nclose(pvt->res);
|
||||
(*pvt->free_res)(pvt->res);
|
||||
}
|
||||
|
||||
pvt->res = res;
|
||||
pvt->free_res = free_res;
|
||||
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_pw *pw = rule->inst->pw;
|
||||
|
||||
if (pw->res_set)
|
||||
(*pw->res_set)(pw, pvt->res, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* WANT_IRS_PW */
|
||||
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: gen_sv.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "gen_p.h"
|
||||
|
||||
/* Types */
|
||||
|
||||
struct pvt {
|
||||
struct irs_rule * rules;
|
||||
struct irs_rule * rule;
|
||||
struct __res_state * res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void sv_close(struct irs_sv*);
|
||||
static struct servent * sv_next(struct irs_sv *);
|
||||
static struct servent * sv_byname(struct irs_sv *, const char *,
|
||||
const char *);
|
||||
static struct servent * sv_byport(struct irs_sv *, int, const char *);
|
||||
static void sv_rewind(struct irs_sv *);
|
||||
static void sv_minimize(struct irs_sv *);
|
||||
static struct __res_state * sv_res_get(struct irs_sv *);
|
||||
static void sv_res_set(struct irs_sv *,
|
||||
struct __res_state *,
|
||||
void (*)(void *));
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_sv *
|
||||
irs_gen_sv(struct irs_acc *this) {
|
||||
struct gen_p *accpvt = (struct gen_p *)this->private;
|
||||
struct irs_sv *sv;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(sv = memget(sizeof *sv))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(sv, 0x5e, sizeof *sv);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(sv, sizeof *sv);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->rules = accpvt->map_rules[irs_sv];
|
||||
pvt->rule = pvt->rules;
|
||||
sv->private = pvt;
|
||||
sv->close = sv_close;
|
||||
sv->next = sv_next;
|
||||
sv->byname = sv_byname;
|
||||
sv->byport = sv_byport;
|
||||
sv->rewind = sv_rewind;
|
||||
sv->minimize = sv_minimize;
|
||||
sv->res_get = sv_res_get;
|
||||
sv->res_set = sv_res_set;
|
||||
return (sv);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
sv_close(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct servent *
|
||||
sv_next(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct servent *rval;
|
||||
struct irs_sv *sv;
|
||||
|
||||
while (pvt->rule) {
|
||||
sv = pvt->rule->inst->sv;
|
||||
rval = (*sv->next)(sv);
|
||||
if (rval)
|
||||
return (rval);
|
||||
if (!(pvt->rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
pvt->rule = pvt->rule->next;
|
||||
if (pvt->rule) {
|
||||
sv = pvt->rule->inst->sv;
|
||||
(*sv->rewind)(sv);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct servent *
|
||||
sv_byname(struct irs_sv *this, const char *name, const char *proto) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct servent *rval;
|
||||
struct irs_sv *sv;
|
||||
|
||||
rval = NULL;
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
sv = rule->inst->sv;
|
||||
rval = (*sv->byname)(sv, name, proto);
|
||||
if (rval || !(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static struct servent *
|
||||
sv_byport(struct irs_sv *this, int port, const char *proto) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct servent *rval;
|
||||
struct irs_sv *sv;
|
||||
|
||||
rval = NULL;
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
sv = rule->inst->sv;
|
||||
rval = (*sv->byport)(sv, port, proto);
|
||||
if (rval || !(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static void
|
||||
sv_rewind(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_sv *sv;
|
||||
|
||||
pvt->rule = pvt->rules;
|
||||
if (pvt->rule) {
|
||||
sv = pvt->rule->inst->sv;
|
||||
(*sv->rewind)(sv);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sv_minimize(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_sv *sv = rule->inst->sv;
|
||||
|
||||
(*sv->minimize)(sv);
|
||||
}
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
sv_res_get(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (!res) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
sv_res_set(this, res, free);
|
||||
}
|
||||
|
||||
return (pvt->res);
|
||||
}
|
||||
|
||||
static void
|
||||
sv_res_set(struct irs_sv *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
if (pvt->res && pvt->free_res) {
|
||||
res_nclose(pvt->res);
|
||||
(*pvt->free_res)(pvt->res);
|
||||
}
|
||||
|
||||
pvt->res = res;
|
||||
pvt->free_res = free_res;
|
||||
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_sv *sv = rule->inst->sv;
|
||||
|
||||
if (sv->res_set)
|
||||
(*sv->res_set)(sv, pvt->res, NULL);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
* Copyright (c) 1996-1999 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.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: getgrent.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#if !defined(WANT_IRS_GR) || defined(__BIND_NOSTATIC)
|
||||
static int __bind_irs_gr_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_data.h"
|
||||
|
||||
/* Forward */
|
||||
|
||||
static struct net_data *init(void);
|
||||
void endgrent(void);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct group *
|
||||
getgrent() {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getgrent_p(net_data));
|
||||
}
|
||||
|
||||
struct group *
|
||||
getgrnam(const char *name) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getgrnam_p(name, net_data));
|
||||
}
|
||||
|
||||
struct group *
|
||||
getgrgid(gid_t gid) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getgrgid_p(gid, net_data));
|
||||
}
|
||||
|
||||
int
|
||||
setgroupent(int stayopen) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (setgroupent_p(stayopen, net_data));
|
||||
}
|
||||
|
||||
#ifdef SETGRENT_VOID
|
||||
void
|
||||
setgrent(void) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
setgrent_p(net_data);
|
||||
}
|
||||
#else
|
||||
int
|
||||
setgrent(void) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (setgrent_p(net_data));
|
||||
}
|
||||
#endif /* SETGRENT_VOID */
|
||||
|
||||
void
|
||||
endgrent() {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
endgrent_p(net_data);
|
||||
}
|
||||
|
||||
int
|
||||
getgrouplist(GETGROUPLIST_ARGS) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getgrouplist_p(name, basegid, groups, ngroups, net_data));
|
||||
}
|
||||
|
||||
/* Shared private. */
|
||||
|
||||
struct group *
|
||||
getgrent_p(struct net_data *net_data) {
|
||||
struct irs_gr *gr;
|
||||
|
||||
if (!net_data || !(gr = net_data->gr))
|
||||
return (NULL);
|
||||
net_data->gr_last = (*gr->next)(gr);
|
||||
return (net_data->gr_last);
|
||||
}
|
||||
|
||||
struct group *
|
||||
getgrnam_p(const char *name, struct net_data *net_data) {
|
||||
struct irs_gr *gr;
|
||||
|
||||
if (!net_data || !(gr = net_data->gr))
|
||||
return (NULL);
|
||||
if (net_data->gr_stayopen && net_data->gr_last &&
|
||||
!strcmp(net_data->gr_last->gr_name, name))
|
||||
return (net_data->gr_last);
|
||||
net_data->gr_last = (*gr->byname)(gr, name);
|
||||
if (!net_data->gr_stayopen)
|
||||
endgrent();
|
||||
return (net_data->gr_last);
|
||||
}
|
||||
|
||||
struct group *
|
||||
getgrgid_p(gid_t gid, struct net_data *net_data) {
|
||||
struct irs_gr *gr;
|
||||
|
||||
if (!net_data || !(gr = net_data->gr))
|
||||
return (NULL);
|
||||
if (net_data->gr_stayopen && net_data->gr_last &&
|
||||
(gid_t)net_data->gr_last->gr_gid == gid)
|
||||
return (net_data->gr_last);
|
||||
net_data->gr_last = (*gr->bygid)(gr, gid);
|
||||
if (!net_data->gr_stayopen)
|
||||
endgrent();
|
||||
return (net_data->gr_last);
|
||||
}
|
||||
|
||||
int
|
||||
setgroupent_p(int stayopen, struct net_data *net_data) {
|
||||
struct irs_gr *gr;
|
||||
|
||||
if (!net_data || !(gr = net_data->gr))
|
||||
return (0);
|
||||
(*gr->rewind)(gr);
|
||||
net_data->gr_stayopen = (stayopen != 0);
|
||||
if (stayopen == 0)
|
||||
net_data_minimize(net_data);
|
||||
return (1);
|
||||
}
|
||||
|
||||
#ifdef SETGRENT_VOID
|
||||
void
|
||||
setgrent_p(struct net_data *net_data) {
|
||||
(void)setgroupent_p(0, net_data);
|
||||
}
|
||||
#else
|
||||
int
|
||||
setgrent_p(struct net_data *net_data) {
|
||||
return (setgroupent_p(0, net_data));
|
||||
}
|
||||
#endif /* SETGRENT_VOID */
|
||||
|
||||
void
|
||||
endgrent_p(struct net_data *net_data) {
|
||||
struct irs_gr *gr;
|
||||
|
||||
if ((net_data != NULL) && ((gr = net_data->gr) != NULL))
|
||||
(*gr->minimize)(gr);
|
||||
}
|
||||
|
||||
int
|
||||
getgrouplist_p(const char *name, gid_t basegid, gid_t *groups, int *ngroups,
|
||||
struct net_data *net_data) {
|
||||
struct irs_gr *gr;
|
||||
|
||||
if (!net_data || !(gr = net_data->gr)) {
|
||||
*ngroups = 0;
|
||||
return (-1);
|
||||
}
|
||||
return ((*gr->list)(gr, name, basegid, groups, ngroups));
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static struct net_data *
|
||||
init() {
|
||||
struct net_data *net_data;
|
||||
|
||||
if (!(net_data = net_data_init(NULL)))
|
||||
goto error;
|
||||
if (!net_data->gr) {
|
||||
net_data->gr = (*net_data->irs->gr_map)(net_data->irs);
|
||||
|
||||
if (!net_data->gr || !net_data->res) {
|
||||
error:
|
||||
errno = EIO;
|
||||
return (NULL);
|
||||
}
|
||||
(*net_data->gr->res_set)(net_data->gr, net_data->res,
|
||||
NULL);
|
||||
}
|
||||
|
||||
return (net_data);
|
||||
}
|
||||
|
||||
#endif /* WANT_IRS_GR */
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (c) 1998-1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: getgrent_r.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <port_before.h>
|
||||
#if !defined(_REENTRANT) || !defined(DO_PTHREADS) || !defined(WANT_IRS_PW)
|
||||
static int getgrent_r_not_required = 0;
|
||||
#else
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#if (defined(POSIX_GETGRNAM_R) || defined(POSIX_GETGRGID_R)) && \
|
||||
defined(_POSIX_PTHREAD_SEMANTICS)
|
||||
/* turn off solaris remapping in <grp.h> */
|
||||
#define _UNIX95
|
||||
#undef _POSIX_PTHREAD_SEMANTICS
|
||||
#include <grp.h>
|
||||
#define _POSIX_PTHREAD_SEMANTICS 1
|
||||
#else
|
||||
#include <grp.h>
|
||||
#endif
|
||||
#include <sys/param.h>
|
||||
#include <port_after.h>
|
||||
|
||||
#ifdef GROUP_R_RETURN
|
||||
|
||||
static int
|
||||
copy_group(struct group *, struct group *, char *buf, int buflen);
|
||||
|
||||
/* POSIX 1003.1c */
|
||||
#ifdef POSIX_GETGRNAM_R
|
||||
int
|
||||
__posix_getgrnam_r(const char *name, struct group *gptr,
|
||||
char *buf, int buflen, struct group **result) {
|
||||
#else
|
||||
int
|
||||
getgrnam_r(const char *name, struct group *gptr,
|
||||
char *buf, size_t buflen, struct group **result) {
|
||||
#endif
|
||||
struct group *ge = getgrnam(name);
|
||||
int res;
|
||||
|
||||
if (ge == NULL) {
|
||||
*result = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
res = copy_group(ge, gptr, buf, buflen);
|
||||
*result = res ? NULL : gptr;
|
||||
return (res);
|
||||
}
|
||||
|
||||
#ifdef POSIX_GETGRNAM_R
|
||||
struct group *
|
||||
getgrnam_r(const char *name, struct group *gptr,
|
||||
char *buf, int buflen) {
|
||||
struct group *ge = getgrnam(name);
|
||||
int res;
|
||||
|
||||
if (ge == NULL)
|
||||
return (NULL);
|
||||
res = copy_group(ge, gptr, buf, buflen);
|
||||
return (res ? NULL : gptr);
|
||||
}
|
||||
#endif /* POSIX_GETGRNAM_R */
|
||||
|
||||
/* POSIX 1003.1c */
|
||||
#ifdef POSIX_GETGRGID_R
|
||||
int
|
||||
__posix_getgrgid_r(gid_t gid, struct group *gptr,
|
||||
char *buf, int buflen, struct group **result) {
|
||||
#else /* POSIX_GETGRGID_R */
|
||||
int
|
||||
getgrgid_r(gid_t gid, struct group *gptr,
|
||||
char *buf, size_t buflen, struct group **result) {
|
||||
#endif /* POSIX_GETGRGID_R */
|
||||
struct group *ge = getgrgid(gid);
|
||||
int res;
|
||||
|
||||
if (ge == NULL) {
|
||||
*result = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
res = copy_group(ge, gptr, buf, buflen);
|
||||
*result = res ? NULL : gptr;
|
||||
return (res);
|
||||
}
|
||||
|
||||
#ifdef POSIX_GETGRGID_R
|
||||
struct group *
|
||||
getgrgid_r(gid_t gid, struct group *gptr,
|
||||
char *buf, int buflen) {
|
||||
struct group *ge = getgrgid(gid);
|
||||
int res;
|
||||
|
||||
if (ge == NULL)
|
||||
return (NULL);
|
||||
|
||||
res = copy_group(ge, gptr, buf, buflen);
|
||||
return (res ? NULL : gptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These assume a single context is in operation per thread.
|
||||
* If this is not the case we will need to call irs directly
|
||||
* rather than through the base functions.
|
||||
*/
|
||||
|
||||
GROUP_R_RETURN
|
||||
getgrent_r(struct group *gptr, GROUP_R_ARGS) {
|
||||
struct group *ge = getgrent();
|
||||
int res;
|
||||
|
||||
if (ge == NULL) {
|
||||
return (GROUP_R_BAD);
|
||||
}
|
||||
|
||||
res = copy_group(ge, gptr, buf, buflen);
|
||||
return (res ? GROUP_R_BAD : GROUP_R_OK);
|
||||
}
|
||||
|
||||
GROUP_R_SET_RETURN
|
||||
setgrent_r(GROUP_R_ENT_ARGS) {
|
||||
|
||||
setgrent();
|
||||
#ifdef GROUP_R_SET_RESULT
|
||||
return (GROUP_R_SET_RESULT);
|
||||
#endif
|
||||
}
|
||||
|
||||
GROUP_R_END_RETURN
|
||||
endgrent_r(GROUP_R_ENT_ARGS) {
|
||||
|
||||
endgrent();
|
||||
GROUP_R_END_RESULT(GROUP_R_OK);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/* XXX irs does not have a fgetgrent() */
|
||||
GROUP_R_RETURN
|
||||
fgetgrent_r(FILE *f, struct group *gptr, GROUP_R_ARGS) {
|
||||
struct group *ge = fgetgrent(f);
|
||||
int res;
|
||||
|
||||
if (ge == NULL)
|
||||
return (GROUP_R_BAD);
|
||||
|
||||
res = copy_group(ge, gptr, buf, buflen);
|
||||
return (res ? GROUP_R_BAD : GROUP_R_OK);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Private */
|
||||
|
||||
static int
|
||||
copy_group(struct group *ge, struct group *gptr, char *buf, int buflen) {
|
||||
char *cp;
|
||||
int i, n;
|
||||
int numptr, len;
|
||||
|
||||
/* Find out the amount of space required to store the answer. */
|
||||
numptr = 1; /* NULL ptr */
|
||||
len = (char *)ALIGN(buf) - buf;
|
||||
for (i = 0; ge->gr_mem[i]; i++, numptr++) {
|
||||
len += strlen(ge->gr_mem[i]) + 1;
|
||||
}
|
||||
len += strlen(ge->gr_name) + 1;
|
||||
len += strlen(ge->gr_passwd) + 1;
|
||||
len += numptr * sizeof(char*);
|
||||
|
||||
if (len > buflen) {
|
||||
errno = ERANGE;
|
||||
return (ERANGE);
|
||||
}
|
||||
|
||||
/* copy group id */
|
||||
gptr->gr_gid = ge->gr_gid;
|
||||
|
||||
cp = (char *)ALIGN(buf) + numptr * sizeof(char *);
|
||||
|
||||
/* copy official name */
|
||||
n = strlen(ge->gr_name) + 1;
|
||||
strcpy(cp, ge->gr_name);
|
||||
gptr->gr_name = cp;
|
||||
cp += n;
|
||||
|
||||
/* copy member list */
|
||||
gptr->gr_mem = (char **)ALIGN(buf);
|
||||
for (i = 0 ; ge->gr_mem[i]; i++) {
|
||||
n = strlen(ge->gr_mem[i]) + 1;
|
||||
strcpy(cp, ge->gr_mem[i]);
|
||||
gptr->gr_mem[i] = cp;
|
||||
cp += n;
|
||||
}
|
||||
gptr->gr_mem[i] = NULL;
|
||||
|
||||
/* copy password */
|
||||
n = strlen(ge->gr_passwd) + 1;
|
||||
strcpy(cp, ge->gr_passwd);
|
||||
gptr->gr_passwd = cp;
|
||||
cp += n;
|
||||
|
||||
return (0);
|
||||
}
|
||||
#else /* GROUP_R_RETURN */
|
||||
static int getgrent_r_unknown_system = 0;
|
||||
#endif /* GROUP_R_RETURN */
|
||||
#endif /* !def(_REENTRANT) || !def(DO_PTHREADS) || !def(WANT_IRS_PW) */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
* Copyright (c) 1998-1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: gethostent_r.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <port_before.h>
|
||||
#if !defined(_REENTRANT) || !defined(DO_PTHREADS)
|
||||
static int gethostent_r_not_required = 0;
|
||||
#else
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/param.h>
|
||||
#include <port_after.h>
|
||||
|
||||
#ifdef HOST_R_RETURN
|
||||
|
||||
static HOST_R_RETURN
|
||||
copy_hostent(struct hostent *, struct hostent *, HOST_R_COPY_ARGS);
|
||||
|
||||
HOST_R_RETURN
|
||||
gethostbyname_r(const char *name, struct hostent *hptr, HOST_R_ARGS) {
|
||||
struct hostent *he = gethostbyname(name);
|
||||
#ifdef HOST_R_SETANSWER
|
||||
int n = 0;
|
||||
#endif
|
||||
|
||||
HOST_R_ERRNO;
|
||||
|
||||
#ifdef HOST_R_SETANSWER
|
||||
if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) == 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = hptr;
|
||||
|
||||
return (n);
|
||||
#else
|
||||
if (he == NULL)
|
||||
return (HOST_R_BAD);
|
||||
|
||||
return (copy_hostent(he, hptr, HOST_R_COPY));
|
||||
#endif
|
||||
}
|
||||
|
||||
HOST_R_RETURN
|
||||
gethostbyaddr_r(const char *addr, int len, int type,
|
||||
struct hostent *hptr, HOST_R_ARGS) {
|
||||
struct hostent *he = gethostbyaddr(addr, len, type);
|
||||
#ifdef HOST_R_SETANSWER
|
||||
int n = 0;
|
||||
#endif
|
||||
|
||||
HOST_R_ERRNO;
|
||||
|
||||
#ifdef HOST_R_SETANSWER
|
||||
if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) == 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = hptr;
|
||||
|
||||
return (n);
|
||||
#else
|
||||
if (he == NULL)
|
||||
return (HOST_R_BAD);
|
||||
|
||||
return (copy_hostent(he, hptr, HOST_R_COPY));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* These assume a single context is in operation per thread.
|
||||
* If this is not the case we will need to call irs directly
|
||||
* rather than through the base functions.
|
||||
*/
|
||||
|
||||
HOST_R_RETURN
|
||||
gethostent_r(struct hostent *hptr, HOST_R_ARGS) {
|
||||
struct hostent *he = gethostent();
|
||||
#ifdef HOST_R_SETANSWER
|
||||
int n = 0;
|
||||
#endif
|
||||
|
||||
HOST_R_ERRNO;
|
||||
|
||||
#ifdef HOST_R_SETANSWER
|
||||
if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) == 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = hptr;
|
||||
|
||||
return (n);
|
||||
#else
|
||||
if (he == NULL)
|
||||
return (HOST_R_BAD);
|
||||
|
||||
return (copy_hostent(he, hptr, HOST_R_COPY));
|
||||
#endif
|
||||
}
|
||||
|
||||
HOST_R_SET_RETURN
|
||||
#ifdef HOST_R_ENT_ARGS
|
||||
sethostent_r(int stay_open, HOST_R_ENT_ARGS)
|
||||
#else
|
||||
sethostent_r(int stay_open)
|
||||
#endif
|
||||
{
|
||||
sethostent(stay_open);
|
||||
#ifdef HOST_R_SET_RESULT
|
||||
return (HOST_R_SET_RESULT);
|
||||
#endif
|
||||
}
|
||||
|
||||
HOST_R_END_RETURN
|
||||
#ifdef HOST_R_ENT_ARGS
|
||||
endhostent_r(HOST_R_ENT_ARGS)
|
||||
#else
|
||||
endhostent_r(void)
|
||||
#endif
|
||||
{
|
||||
endhostent();
|
||||
HOST_R_END_RESULT(HOST_R_OK);
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
#ifndef HOSTENT_DATA
|
||||
static HOST_R_RETURN
|
||||
copy_hostent(struct hostent *he, struct hostent *hptr, HOST_R_COPY_ARGS) {
|
||||
char *cp;
|
||||
char **ptr;
|
||||
int i, n;
|
||||
int nptr, len;
|
||||
|
||||
/* Find out the amount of space required to store the answer. */
|
||||
nptr = 2; /* NULL ptrs */
|
||||
len = (char *)ALIGN(buf) - buf;
|
||||
for (i = 0; he->h_addr_list[i]; i++, nptr++) {
|
||||
len += he->h_length;
|
||||
}
|
||||
for (i = 0; he->h_aliases[i]; i++, nptr++) {
|
||||
len += strlen(he->h_aliases[i]) + 1;
|
||||
}
|
||||
len += strlen(he->h_name) + 1;
|
||||
len += nptr * sizeof(char*);
|
||||
|
||||
if (len > buflen) {
|
||||
errno = ERANGE;
|
||||
return (HOST_R_BAD);
|
||||
}
|
||||
|
||||
/* copy address size and type */
|
||||
hptr->h_addrtype = he->h_addrtype;
|
||||
n = hptr->h_length = he->h_length;
|
||||
|
||||
ptr = (char **)ALIGN(buf);
|
||||
cp = (char *)ALIGN(buf) + nptr * sizeof(char *);
|
||||
|
||||
/* copy address list */
|
||||
hptr->h_addr_list = ptr;
|
||||
for (i = 0; he->h_addr_list[i]; i++ , ptr++) {
|
||||
memcpy(cp, he->h_addr_list[i], n);
|
||||
hptr->h_addr_list[i] = cp;
|
||||
cp += n;
|
||||
}
|
||||
hptr->h_addr_list[i] = NULL;
|
||||
ptr++;
|
||||
|
||||
/* copy official name */
|
||||
n = strlen(he->h_name) + 1;
|
||||
strcpy(cp, he->h_name);
|
||||
hptr->h_name = cp;
|
||||
cp += n;
|
||||
|
||||
/* copy aliases */
|
||||
hptr->h_aliases = ptr;
|
||||
for (i = 0 ; he->h_aliases[i]; i++) {
|
||||
n = strlen(he->h_aliases[i]) + 1;
|
||||
strcpy(cp, he->h_aliases[i]);
|
||||
hptr->h_aliases[i] = cp;
|
||||
cp += n;
|
||||
}
|
||||
hptr->h_aliases[i] = NULL;
|
||||
|
||||
return (HOST_R_OK);
|
||||
}
|
||||
#else /* !HOSTENT_DATA */
|
||||
static int
|
||||
copy_hostent(struct hostent *he, struct hostent *hptr, HOST_R_COPY_ARGS) {
|
||||
char *cp, *eob;
|
||||
int i, n;
|
||||
|
||||
/* copy address size and type */
|
||||
hptr->h_addrtype = he->h_addrtype;
|
||||
n = hptr->h_length = he->h_length;
|
||||
|
||||
/* copy up to first 35 addresses */
|
||||
i = 0;
|
||||
cp = hdptr->hostaddr;
|
||||
eob = hdptr->hostaddr + sizeof(hdptr->hostaddr);
|
||||
hptr->h_addr_list = hdptr->h_addr_ptrs;
|
||||
while (he->h_addr_list[i] && i < (_MAXADDRS)) {
|
||||
if (n < (eob - cp)) {
|
||||
memcpy(cp, he->h_addr_list[i], n);
|
||||
hptr->h_addr_list[i] = cp;
|
||||
cp += n;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
hptr->h_addr_list[i] = NULL;
|
||||
|
||||
/* copy official name */
|
||||
cp = hdptr->hostbuf;
|
||||
eob = hdptr->hostbuf + sizeof(hdptr->hostbuf);
|
||||
if ((n = strlen(he->h_name) + 1) < (eob - cp)) {
|
||||
strcpy(cp, he->h_name);
|
||||
hptr->h_name = cp;
|
||||
cp += n;
|
||||
} else {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* copy aliases */
|
||||
i = 0;
|
||||
hptr->h_aliases = hdptr->host_aliases;
|
||||
while (he->h_aliases[i] && i < (_MAXALIASES-1)) {
|
||||
if ((n = strlen(he->h_aliases[i]) + 1) < (eob - cp)) {
|
||||
strcpy(cp, he->h_aliases[i]);
|
||||
hptr->h_aliases[i] = cp;
|
||||
cp += n;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
hptr->h_aliases[i] = NULL;
|
||||
|
||||
return (HOST_R_OK);
|
||||
}
|
||||
#endif /* !HOSTENT_DATA */
|
||||
#else /* HOST_R_RETURN */
|
||||
static int gethostent_r_unknown_system = 0;
|
||||
#endif /* HOST_R_RETURN */
|
||||
#endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
|
||||
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
* Issues to be discussed:
|
||||
* - Thread safe-ness must be checked
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* 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 WIDE Project and
|
||||
* its contributors.
|
||||
* 4. Neither the name of the project 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 PROJECT 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 PROJECT 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 <port_before.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <port_after.h>
|
||||
|
||||
/*
|
||||
* Note that a_off will be dynamically adjusted so that to be consistent
|
||||
* with the definition of sockaddr_in{,6}.
|
||||
* The value presented below is just a guess.
|
||||
*/
|
||||
static struct afd {
|
||||
int a_af;
|
||||
int a_addrlen;
|
||||
size_t a_socklen;
|
||||
int a_off;
|
||||
} afdl [] = {
|
||||
/* first entry is linked last... */
|
||||
{PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
|
||||
offsetof(struct sockaddr_in, sin_addr)},
|
||||
{PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
|
||||
offsetof(struct sockaddr_in6, sin6_addr)},
|
||||
{0, 0, 0, 0},
|
||||
};
|
||||
|
||||
struct sockinet {
|
||||
#ifdef HAVE_SA_LEN
|
||||
u_char si_len;
|
||||
#endif
|
||||
u_char si_family;
|
||||
u_short si_port;
|
||||
};
|
||||
|
||||
static int ip6_parsenumeric __P((const struct sockaddr *, const char *, char *,
|
||||
size_t, int));
|
||||
#ifdef HAVE_SIN6_SCOPE_ID
|
||||
static int ip6_sa2str __P((const struct sockaddr_in6 *, char *, size_t, int));
|
||||
#endif
|
||||
|
||||
int
|
||||
getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
|
||||
const struct sockaddr *sa;
|
||||
size_t salen;
|
||||
char *host;
|
||||
size_t hostlen;
|
||||
char *serv;
|
||||
size_t servlen;
|
||||
int flags;
|
||||
{
|
||||
struct afd *afd;
|
||||
struct servent *sp;
|
||||
struct hostent *hp;
|
||||
u_short port;
|
||||
#ifdef HAVE_SA_LEN
|
||||
size_t len;
|
||||
#endif
|
||||
int family, i;
|
||||
const char *addr;
|
||||
char *p;
|
||||
char numserv[512];
|
||||
char numaddr[512];
|
||||
const struct sockaddr_in6 *sin6;
|
||||
|
||||
if (sa == NULL)
|
||||
return EAI_FAIL;
|
||||
|
||||
#ifdef HAVE_SA_LEN
|
||||
len = sa->sa_len;
|
||||
if (len != salen) return EAI_FAIL;
|
||||
#endif
|
||||
|
||||
family = sa->sa_family;
|
||||
for (i = 0; afdl[i].a_af; i++)
|
||||
if (afdl[i].a_af == family) {
|
||||
afd = &afdl[i];
|
||||
goto found;
|
||||
}
|
||||
return EAI_FAMILY;
|
||||
|
||||
found:
|
||||
if (salen != afd->a_socklen) return EAI_FAIL;
|
||||
|
||||
port = ((const struct sockinet *)sa)->si_port; /* network byte order */
|
||||
addr = (const char *)sa + afd->a_off;
|
||||
|
||||
if (serv == NULL || servlen == 0) {
|
||||
/*
|
||||
* rfc2553bis says that serv == NULL or servlen == 0 means that
|
||||
* the caller does not want the result.
|
||||
*/
|
||||
} else if (flags & NI_NUMERICSERV) {
|
||||
sprintf(numserv, "%d", ntohs(port));
|
||||
if (strlen(numserv) > servlen)
|
||||
return EAI_MEMORY;
|
||||
strcpy(serv, numserv);
|
||||
} else {
|
||||
sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp");
|
||||
if (sp) {
|
||||
if (strlen(sp->s_name) + 1 > servlen)
|
||||
return EAI_MEMORY;
|
||||
strcpy(serv, sp->s_name);
|
||||
} else
|
||||
return EAI_NONAME;
|
||||
}
|
||||
|
||||
switch (sa->sa_family) {
|
||||
case AF_INET:
|
||||
if (ntohl(*(const u_long *)addr) >> IN_CLASSA_NSHIFT == 0)
|
||||
flags |= NI_NUMERICHOST;
|
||||
break;
|
||||
case AF_INET6:
|
||||
sin6 = (const struct sockaddr_in6 *)sa;
|
||||
switch (sin6->sin6_addr.s6_addr[0]) {
|
||||
case 0x00:
|
||||
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
|
||||
;
|
||||
else if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))
|
||||
;
|
||||
else
|
||||
flags |= NI_NUMERICHOST;
|
||||
break;
|
||||
default:
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
|
||||
flags |= NI_NUMERICHOST;
|
||||
else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
|
||||
flags |= NI_NUMERICHOST;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (host == NULL || hostlen == 0) {
|
||||
/*
|
||||
* rfc2553bis says that host == NULL or hostlen == 0 means that
|
||||
* the caller does not want the result.
|
||||
*/
|
||||
} else if (flags & NI_NUMERICHOST) {
|
||||
goto numeric;
|
||||
} else {
|
||||
hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
|
||||
|
||||
if (hp) {
|
||||
if (flags & NI_NOFQDN) {
|
||||
p = strchr(hp->h_name, '.');
|
||||
if (p) *p = '\0';
|
||||
}
|
||||
if (strlen(hp->h_name) + 1 > hostlen)
|
||||
return EAI_MEMORY;
|
||||
strcpy(host, hp->h_name);
|
||||
} else {
|
||||
if (flags & NI_NAMEREQD)
|
||||
return EAI_NONAME;
|
||||
numeric:
|
||||
switch(afd->a_af) {
|
||||
case AF_INET6:
|
||||
{
|
||||
int error;
|
||||
|
||||
if ((error = ip6_parsenumeric(sa, addr, host,
|
||||
hostlen,
|
||||
flags)) != 0)
|
||||
return(error);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
if (inet_ntop(afd->a_af, addr, numaddr,
|
||||
sizeof(numaddr)) == NULL)
|
||||
return EAI_NONAME;
|
||||
if (strlen(numaddr) + 1 > hostlen)
|
||||
return EAI_MEMORY;
|
||||
strcpy(host, numaddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
ip6_parsenumeric(const struct sockaddr *sa, const char *addr, char *host,
|
||||
size_t hostlen, int flags)
|
||||
{
|
||||
size_t numaddrlen;
|
||||
char numaddr[512];
|
||||
|
||||
#ifndef HAVE_SIN6_SCOPE_ID
|
||||
UNUSED(sa);
|
||||
UNUSED(flags);
|
||||
#endif
|
||||
|
||||
if (inet_ntop(AF_INET6, addr, numaddr, sizeof(numaddr))
|
||||
== NULL)
|
||||
return EAI_SYSTEM;
|
||||
|
||||
numaddrlen = strlen(numaddr);
|
||||
if (numaddrlen + 1 > hostlen) /* don't forget terminator */
|
||||
return EAI_MEMORY;
|
||||
strcpy(host, numaddr);
|
||||
|
||||
#ifdef HAVE_SIN6_SCOPE_ID
|
||||
if (((const struct sockaddr_in6 *)sa)->sin6_scope_id) {
|
||||
char scopebuf[MAXHOSTNAMELEN]; /* XXX */
|
||||
int scopelen;
|
||||
|
||||
/* ip6_sa2str never fails */
|
||||
scopelen = ip6_sa2str((const struct sockaddr_in6 *)sa,
|
||||
scopebuf, sizeof(scopebuf), flags);
|
||||
|
||||
if (scopelen + 1 + numaddrlen + 1 > hostlen)
|
||||
return EAI_MEMORY;
|
||||
|
||||
/* construct <numeric-addr><delim><scopeid> */
|
||||
memcpy(host + numaddrlen + 1, scopebuf,
|
||||
scopelen);
|
||||
host[numaddrlen] = SCOPE_DELIMITER;
|
||||
host[numaddrlen + 1 + scopelen] = '\0';
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SIN6_SCOPE_ID
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
ip6_sa2str(const struct sockaddr_in6 *sa6, char *buf,
|
||||
size_t bufsiz, int flags)
|
||||
{
|
||||
#ifdef USE_IFNAMELINKID
|
||||
unsigned int ifindex = (unsigned int)sa6->sin6_scope_id;
|
||||
const struct in6_addr *a6 = &sa6->sin6_addr;
|
||||
#endif
|
||||
char tmp[64];
|
||||
|
||||
#ifdef NI_NUMERICSCOPE
|
||||
if (flags & NI_NUMERICSCOPE) {
|
||||
sprintf(tmp, "%u", sa6->sin6_scope_id);
|
||||
if (bufsiz != 0) {
|
||||
strncpy(buf, tmp, bufsiz - 1);
|
||||
buf[bufsiz - 1] = '\0';
|
||||
}
|
||||
return(strlen(tmp));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_IFNAMELINKID
|
||||
/*
|
||||
* For a link-local address, convert the index to an interface
|
||||
* name, assuming a one-to-one mapping between links and interfaces.
|
||||
* Note, however, that this assumption is stronger than the
|
||||
* specification of the scoped address architecture; the
|
||||
* specficication says that more than one interfaces can belong to
|
||||
* a single link.
|
||||
*/
|
||||
|
||||
/* if_indextoname() does not take buffer size. not a good api... */
|
||||
if ((IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) &&
|
||||
bufsiz >= IF_NAMESIZE) {
|
||||
char *p = if_indextoname(ifindex, buf);
|
||||
if (p) {
|
||||
return(strlen(p));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* last resort */
|
||||
sprintf(tmp, "%u", sa6->sin6_scope_id);
|
||||
if (bufsiz != 0) {
|
||||
strncpy(buf, tmp, bufsiz - 1);
|
||||
buf[bufsiz - 1] = '\0';
|
||||
}
|
||||
return(strlen(tmp));
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,343 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: getnetent.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#if !defined(__BIND_NOSTATIC)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "irs_data.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
struct pvt {
|
||||
struct netent netent;
|
||||
char * aliases[1];
|
||||
char name[MAXDNAME + 1];
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static struct net_data *init(void);
|
||||
static struct netent *nw_to_net(struct nwent *, struct net_data *);
|
||||
static void freepvt(struct net_data *);
|
||||
static struct netent *fakeaddr(const char *, int af, struct net_data *);
|
||||
|
||||
/* Portability */
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
# define INADDR_NONE 0xffffffff
|
||||
#endif
|
||||
|
||||
/* Public */
|
||||
|
||||
struct netent *
|
||||
getnetent() {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getnetent_p(net_data));
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetbyname(const char *name) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getnetbyname_p(name, net_data));
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetbyaddr(unsigned long net, int type) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getnetbyaddr_p(net, type, net_data));
|
||||
}
|
||||
|
||||
void
|
||||
setnetent(int stayopen) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
setnetent_p(stayopen, net_data);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
endnetent() {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
endnetent_p(net_data);
|
||||
}
|
||||
|
||||
/* Shared private. */
|
||||
|
||||
struct netent *
|
||||
getnetent_p(struct net_data *net_data) {
|
||||
struct irs_nw *nw;
|
||||
|
||||
if (!net_data || !(nw = net_data->nw))
|
||||
return (NULL);
|
||||
net_data->nww_last = (*nw->next)(nw);
|
||||
net_data->nw_last = nw_to_net(net_data->nww_last, net_data);
|
||||
return (net_data->nw_last);
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetbyname_p(const char *name, struct net_data *net_data) {
|
||||
struct irs_nw *nw;
|
||||
struct netent *np;
|
||||
char **nap;
|
||||
|
||||
if (!net_data || !(nw = net_data->nw))
|
||||
return (NULL);
|
||||
if (net_data->nw_stayopen && net_data->nw_last) {
|
||||
if (!strcmp(net_data->nw_last->n_name, name))
|
||||
return (net_data->nw_last);
|
||||
for (nap = net_data->nw_last->n_aliases; nap && *nap; nap++)
|
||||
if (!strcmp(name, *nap))
|
||||
return (net_data->nw_last);
|
||||
}
|
||||
if ((np = fakeaddr(name, AF_INET, net_data)) != NULL)
|
||||
return (np);
|
||||
net_data->nww_last = (*nw->byname)(nw, name, AF_INET);
|
||||
net_data->nw_last = nw_to_net(net_data->nww_last, net_data);
|
||||
if (!net_data->nw_stayopen)
|
||||
endnetent();
|
||||
return (net_data->nw_last);
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetbyaddr_p(unsigned long net, int type, struct net_data *net_data) {
|
||||
struct irs_nw *nw;
|
||||
u_char addr[4];
|
||||
int bits;
|
||||
|
||||
if (!net_data || !(nw = net_data->nw))
|
||||
return (NULL);
|
||||
if (net_data->nw_stayopen && net_data->nw_last)
|
||||
if (type == net_data->nw_last->n_addrtype &&
|
||||
net == net_data->nw_last->n_net)
|
||||
return (net_data->nw_last);
|
||||
|
||||
/* cannonize net(host order) */
|
||||
if (net < 256) {
|
||||
net <<= 24;
|
||||
bits = 8;
|
||||
} else if (net < 65536) {
|
||||
net <<= 16;
|
||||
bits = 16;
|
||||
} else if (net < 16777216) {
|
||||
net <<= 8;
|
||||
bits = 24;
|
||||
} else
|
||||
bits = 32;
|
||||
|
||||
/* convert to net order */
|
||||
addr[0] = (0xFF000000 & net) >> 24;
|
||||
addr[1] = (0x00FF0000 & net) >> 16;
|
||||
addr[2] = (0x0000FF00 & net) >> 8;
|
||||
addr[3] = (0x000000FF & net);
|
||||
|
||||
/* reduce bits to as close to natural number as possible */
|
||||
if ((bits == 32) && (addr[0] < 224) && (addr[3] == 0)) {
|
||||
if ((addr[0] < 192) && (addr[2] == 0)) {
|
||||
if ((addr[0] < 128) && (addr[1] == 0))
|
||||
bits = 8;
|
||||
else
|
||||
bits = 16;
|
||||
} else {
|
||||
bits = 24;
|
||||
}
|
||||
}
|
||||
|
||||
net_data->nww_last = (*nw->byaddr)(nw, addr, bits, AF_INET);
|
||||
net_data->nw_last = nw_to_net(net_data->nww_last, net_data);
|
||||
if (!net_data->nw_stayopen)
|
||||
endnetent();
|
||||
return (net_data->nw_last);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
setnetent_p(int stayopen, struct net_data *net_data) {
|
||||
struct irs_nw *nw;
|
||||
|
||||
if (!net_data || !(nw = net_data->nw))
|
||||
return;
|
||||
freepvt(net_data);
|
||||
(*nw->rewind)(nw);
|
||||
net_data->nw_stayopen = (stayopen != 0);
|
||||
if (stayopen == 0)
|
||||
net_data_minimize(net_data);
|
||||
}
|
||||
|
||||
void
|
||||
endnetent_p(struct net_data *net_data) {
|
||||
struct irs_nw *nw;
|
||||
|
||||
if ((net_data != NULL) && ((nw = net_data->nw) != NULL))
|
||||
(*nw->minimize)(nw);
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static struct net_data *
|
||||
init() {
|
||||
struct net_data *net_data;
|
||||
|
||||
if (!(net_data = net_data_init(NULL)))
|
||||
goto error;
|
||||
if (!net_data->nw) {
|
||||
net_data->nw = (*net_data->irs->nw_map)(net_data->irs);
|
||||
|
||||
if (!net_data->nw || !net_data->res) {
|
||||
error:
|
||||
errno = EIO;
|
||||
return (NULL);
|
||||
}
|
||||
(*net_data->nw->res_set)(net_data->nw, net_data->res, NULL);
|
||||
}
|
||||
|
||||
return (net_data);
|
||||
}
|
||||
|
||||
static void
|
||||
freepvt(struct net_data *net_data) {
|
||||
if (net_data->nw_data) {
|
||||
free(net_data->nw_data);
|
||||
net_data->nw_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct netent *
|
||||
fakeaddr(const char *name, int af, struct net_data *net_data) {
|
||||
struct pvt *pvt;
|
||||
const char *cp;
|
||||
u_long tmp;
|
||||
|
||||
if (af != AF_INET) {
|
||||
/* XXX should support IPv6 some day */
|
||||
errno = EAFNOSUPPORT;
|
||||
RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
}
|
||||
if (!isascii((unsigned char)(name[0])) ||
|
||||
!isdigit((unsigned char)(name[0])))
|
||||
return (NULL);
|
||||
for (cp = name; *cp; ++cp)
|
||||
if (!isascii(*cp) || (!isdigit((unsigned char)*cp) && *cp != '.'))
|
||||
return (NULL);
|
||||
if (*--cp == '.')
|
||||
return (NULL);
|
||||
|
||||
/* All-numeric, no dot at the end. */
|
||||
|
||||
tmp = inet_network(name);
|
||||
if (tmp == INADDR_NONE) {
|
||||
RES_SET_H_ERRNO(net_data->res, HOST_NOT_FOUND);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Valid network number specified.
|
||||
* Fake up a netent as if we'd actually
|
||||
* done a lookup.
|
||||
*/
|
||||
freepvt(net_data);
|
||||
net_data->nw_data = malloc(sizeof (struct pvt));
|
||||
if (!net_data->nw_data) {
|
||||
errno = ENOMEM;
|
||||
RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
}
|
||||
pvt = net_data->nw_data;
|
||||
|
||||
strncpy(pvt->name, name, MAXDNAME);
|
||||
pvt->name[MAXDNAME] = '\0';
|
||||
pvt->netent.n_name = pvt->name;
|
||||
pvt->netent.n_addrtype = AF_INET;
|
||||
pvt->netent.n_aliases = pvt->aliases;
|
||||
pvt->aliases[0] = NULL;
|
||||
pvt->netent.n_net = tmp;
|
||||
|
||||
return (&pvt->netent);
|
||||
}
|
||||
|
||||
static struct netent *
|
||||
nw_to_net(struct nwent *nwent, struct net_data *net_data) {
|
||||
struct pvt *pvt;
|
||||
u_long addr = 0;
|
||||
int i;
|
||||
int msbyte;
|
||||
|
||||
if (!nwent || nwent->n_addrtype != AF_INET)
|
||||
return (NULL);
|
||||
freepvt(net_data);
|
||||
net_data->nw_data = malloc(sizeof (struct pvt));
|
||||
if (!net_data->nw_data) {
|
||||
errno = ENOMEM;
|
||||
RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
}
|
||||
pvt = net_data->nw_data;
|
||||
pvt->netent.n_name = nwent->n_name;
|
||||
pvt->netent.n_aliases = nwent->n_aliases;
|
||||
pvt->netent.n_addrtype = nwent->n_addrtype;
|
||||
|
||||
/*
|
||||
* What this code does: Converts net addresses from network to host form.
|
||||
*
|
||||
* msbyte: the index of the most significant byte in the n_addr array.
|
||||
*
|
||||
* Shift bytes in significant order into addr. When all signicant
|
||||
* bytes are in, zero out bits in the LSB that are not part of the network.
|
||||
*/
|
||||
msbyte = nwent->n_length / 8 +
|
||||
((nwent->n_length % 8) != 0 ? 1 : 0) - 1;
|
||||
for (i = 0; i <= msbyte; i++)
|
||||
addr = (addr << 8) | ((unsigned char *)nwent->n_addr)[i];
|
||||
i = (32 - nwent->n_length) % 8;
|
||||
if (i != 0)
|
||||
addr &= ~((1 << (i + 1)) - 1);
|
||||
pvt->netent.n_net = addr;
|
||||
return (&pvt->netent);
|
||||
}
|
||||
|
||||
#endif /*__BIND_NOSTATIC*/
|
||||
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright (c) 1998-1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: getnetent_r.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <port_before.h>
|
||||
#if !defined(_REENTRANT) || !defined(DO_PTHREADS)
|
||||
static int getnetent_r_not_required = 0;
|
||||
#else
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/param.h>
|
||||
#include <port_after.h>
|
||||
|
||||
#ifdef NET_R_RETURN
|
||||
|
||||
static NET_R_RETURN
|
||||
copy_netent(struct netent *, struct netent *, NET_R_COPY_ARGS);
|
||||
|
||||
NET_R_RETURN
|
||||
getnetbyname_r(const char *name, struct netent *nptr, NET_R_ARGS) {
|
||||
struct netent *ne = getnetbyname(name);
|
||||
#ifdef NET_R_SETANSWER
|
||||
int n = 0;
|
||||
|
||||
if (ne == NULL || (n = copy_netent(ne, nptr, NET_R_COPY)) != 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = ne;
|
||||
if (ne == NULL)
|
||||
*h_errnop = h_errno;
|
||||
return (n);
|
||||
#else
|
||||
if (ne == NULL)
|
||||
return (NET_R_BAD);
|
||||
|
||||
return (copy_netent(ne, nptr, NET_R_COPY));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef GETNETBYADDR_ADDR_T
|
||||
#define GETNETBYADDR_ADDR_T long
|
||||
#endif
|
||||
NET_R_RETURN
|
||||
getnetbyaddr_r(GETNETBYADDR_ADDR_T addr, int type, struct netent *nptr, NET_R_ARGS) {
|
||||
struct netent *ne = getnetbyaddr(addr, type);
|
||||
#ifdef NET_R_SETANSWER
|
||||
int n = 0;
|
||||
|
||||
if (ne == NULL || (n = copy_netent(ne, nptr, NET_R_COPY)) != 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = ne;
|
||||
if (ne == NULL)
|
||||
*h_errnop = h_errno;
|
||||
return (n);
|
||||
#else
|
||||
|
||||
if (ne == NULL)
|
||||
return (NET_R_BAD);
|
||||
|
||||
return (copy_netent(ne, nptr, NET_R_COPY));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* These assume a single context is in operation per thread.
|
||||
* If this is not the case we will need to call irs directly
|
||||
* rather than through the base functions.
|
||||
*/
|
||||
|
||||
NET_R_RETURN
|
||||
getnetent_r(struct netent *nptr, NET_R_ARGS) {
|
||||
struct netent *ne = getnetent();
|
||||
#ifdef NET_R_SETANSWER
|
||||
int n = 0;
|
||||
|
||||
if (ne == NULL || (n = copy_netent(ne, nptr, NET_R_COPY)) != 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = ne;
|
||||
if (ne == NULL)
|
||||
*h_errnop = h_errno;
|
||||
return (n);
|
||||
#else
|
||||
|
||||
if (ne == NULL)
|
||||
return (NET_R_BAD);
|
||||
|
||||
return (copy_netent(ne, nptr, NET_R_COPY));
|
||||
#endif
|
||||
}
|
||||
|
||||
NET_R_SET_RETURN
|
||||
#ifdef NET_R_ENT_ARGS
|
||||
setnetent_r(int stay_open, NET_R_ENT_ARGS)
|
||||
#else
|
||||
setnetent_r(int stay_open)
|
||||
#endif
|
||||
{
|
||||
setnetent(stay_open);
|
||||
#ifdef NET_R_SET_RESULT
|
||||
return (NET_R_SET_RESULT);
|
||||
#endif
|
||||
}
|
||||
|
||||
NET_R_END_RETURN
|
||||
#ifdef NET_R_ENT_ARGS
|
||||
endnetent_r(NET_R_ENT_ARGS)
|
||||
#else
|
||||
endnetent_r()
|
||||
#endif
|
||||
{
|
||||
endnetent();
|
||||
NET_R_END_RESULT(NET_R_OK);
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
#ifndef NETENT_DATA
|
||||
static NET_R_RETURN
|
||||
copy_netent(struct netent *ne, struct netent *nptr, NET_R_COPY_ARGS) {
|
||||
char *cp;
|
||||
int i, n;
|
||||
int numptr, len;
|
||||
|
||||
/* Find out the amount of space required to store the answer. */
|
||||
numptr = 1; /* NULL ptr */
|
||||
len = (char *)ALIGN(buf) - buf;
|
||||
for (i = 0; ne->n_aliases[i]; i++, numptr++) {
|
||||
len += strlen(ne->n_aliases[i]) + 1;
|
||||
}
|
||||
len += strlen(ne->n_name) + 1;
|
||||
len += numptr * sizeof(char*);
|
||||
|
||||
if (len > (int)buflen) {
|
||||
errno = ERANGE;
|
||||
return (NET_R_BAD);
|
||||
}
|
||||
|
||||
/* copy net value and type */
|
||||
nptr->n_addrtype = ne->n_addrtype;
|
||||
nptr->n_net = ne->n_net;
|
||||
|
||||
cp = (char *)ALIGN(buf) + numptr * sizeof(char *);
|
||||
|
||||
/* copy official name */
|
||||
n = strlen(ne->n_name) + 1;
|
||||
strcpy(cp, ne->n_name);
|
||||
nptr->n_name = cp;
|
||||
cp += n;
|
||||
|
||||
/* copy aliases */
|
||||
nptr->n_aliases = (char **)ALIGN(buf);
|
||||
for (i = 0 ; ne->n_aliases[i]; i++) {
|
||||
n = strlen(ne->n_aliases[i]) + 1;
|
||||
strcpy(cp, ne->n_aliases[i]);
|
||||
nptr->n_aliases[i] = cp;
|
||||
cp += n;
|
||||
}
|
||||
nptr->n_aliases[i] = NULL;
|
||||
|
||||
return (NET_R_OK);
|
||||
}
|
||||
#else /* !NETENT_DATA */
|
||||
static int
|
||||
copy_netent(struct netent *ne, struct netent *nptr, NET_R_COPY_ARGS) {
|
||||
char *cp, *eob;
|
||||
int i, n;
|
||||
|
||||
/* copy net value and type */
|
||||
nptr->n_addrtype = ne->n_addrtype;
|
||||
nptr->n_net = ne->n_net;
|
||||
|
||||
/* copy official name */
|
||||
cp = ndptr->line;
|
||||
eob = ndptr->line + sizeof(ndptr->line);
|
||||
if ((n = strlen(ne->n_name) + 1) < (eob - cp)) {
|
||||
strcpy(cp, ne->n_name);
|
||||
nptr->n_name = cp;
|
||||
cp += n;
|
||||
} else {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* copy aliases */
|
||||
i = 0;
|
||||
nptr->n_aliases = ndptr->net_aliases;
|
||||
while (ne->n_aliases[i] && i < (_MAXALIASES-1)) {
|
||||
if ((n = strlen(ne->n_aliases[i]) + 1) < (eob - cp)) {
|
||||
strcpy(cp, ne->n_aliases[i]);
|
||||
nptr->n_aliases[i] = cp;
|
||||
cp += n;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
nptr->n_aliases[i] = NULL;
|
||||
|
||||
return (NET_R_OK);
|
||||
}
|
||||
#endif /* !NETENT_DATA */
|
||||
#else /* NET_R_RETURN */
|
||||
static int getnetent_r_unknown_system = 0;
|
||||
#endif /* NET_R_RETURN */
|
||||
#endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: getnetgrent.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#if !defined(__BIND_NOSTATIC)
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_data.h"
|
||||
|
||||
/* Forward */
|
||||
|
||||
static struct net_data *init(void);
|
||||
|
||||
|
||||
/* Public */
|
||||
|
||||
#ifndef SETNETGRENT_ARGS
|
||||
#define SETNETGRENT_ARGS const char *netgroup
|
||||
#endif
|
||||
void
|
||||
setnetgrent(SETNETGRENT_ARGS) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
setnetgrent_p(netgroup, net_data);
|
||||
}
|
||||
|
||||
void
|
||||
endnetgrent(void) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
endnetgrent_p(net_data);
|
||||
}
|
||||
|
||||
#ifndef INNETGR_ARGS
|
||||
#define INNETGR_ARGS const char *netgroup, const char *host, \
|
||||
const char *user, const char *domain
|
||||
#endif
|
||||
int
|
||||
innetgr(INNETGR_ARGS) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (innetgr_p(netgroup, host, user, domain, net_data));
|
||||
}
|
||||
|
||||
int
|
||||
getnetgrent(char **host, char **user, char **domain) {
|
||||
struct net_data *net_data = init();
|
||||
const char *ch, *cu, *cd;
|
||||
int ret;
|
||||
|
||||
ret = getnetgrent_p(&ch, &cu, &cd, net_data);
|
||||
if (ret != 1)
|
||||
return (ret);
|
||||
|
||||
DE_CONST(ch, *host);
|
||||
DE_CONST(cu, *user);
|
||||
DE_CONST(cd, *domain);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* Shared private. */
|
||||
|
||||
void
|
||||
setnetgrent_p(const char *netgroup, struct net_data *net_data) {
|
||||
struct irs_ng *ng;
|
||||
|
||||
if ((net_data != NULL) && ((ng = net_data->ng) != NULL))
|
||||
(*ng->rewind)(ng, netgroup);
|
||||
}
|
||||
|
||||
void
|
||||
endnetgrent_p(struct net_data *net_data) {
|
||||
struct irs_ng *ng;
|
||||
|
||||
if (!net_data)
|
||||
return;
|
||||
if ((ng = net_data->ng) != NULL)
|
||||
(*ng->close)(ng);
|
||||
net_data->ng = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
innetgr_p(const char *netgroup, const char *host,
|
||||
const char *user, const char *domain,
|
||||
struct net_data *net_data) {
|
||||
struct irs_ng *ng;
|
||||
|
||||
if (!net_data || !(ng = net_data->ng))
|
||||
return (0);
|
||||
return ((*ng->test)(ng, netgroup, host, user, domain));
|
||||
}
|
||||
|
||||
int
|
||||
getnetgrent_p(const char **host, const char **user, const char **domain,
|
||||
struct net_data *net_data ) {
|
||||
struct irs_ng *ng;
|
||||
|
||||
if (!net_data || !(ng = net_data->ng))
|
||||
return (0);
|
||||
return ((*ng->next)(ng, host, user, domain));
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static struct net_data *
|
||||
init(void) {
|
||||
struct net_data *net_data;
|
||||
|
||||
if (!(net_data = net_data_init(NULL)))
|
||||
goto error;
|
||||
if (!net_data->ng) {
|
||||
net_data->ng = (*net_data->irs->ng_map)(net_data->irs);
|
||||
if (!net_data->ng) {
|
||||
error:
|
||||
errno = EIO;
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return (net_data);
|
||||
}
|
||||
|
||||
#endif /*__BIND_NOSTATIC*/
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 1998-1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: getnetgrent_r.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <port_before.h>
|
||||
#if !defined(_REENTRANT) || !defined(DO_PTHREADS)
|
||||
static int getnetgrent_r_not_required = 0;
|
||||
#else
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <stdlib.h>
|
||||
#include <port_after.h>
|
||||
|
||||
#ifdef NGR_R_RETURN
|
||||
|
||||
static NGR_R_RETURN
|
||||
copy_protoent(char **, char **, char **, const char *, const char *,
|
||||
const char *, NGR_R_COPY_ARGS);
|
||||
|
||||
NGR_R_RETURN
|
||||
innetgr_r(const char *netgroup, const char *host, const char *user,
|
||||
const char *domain) {
|
||||
char *ng, *ho, *us, *dom;
|
||||
|
||||
DE_CONST(netgroup, ng);
|
||||
DE_CONST(host, ho);
|
||||
DE_CONST(user, us);
|
||||
DE_CONST(domain, dom);
|
||||
|
||||
return (innetgr(ng, ho, us, dom));
|
||||
}
|
||||
|
||||
/*
|
||||
* These assume a single context is in operation per thread.
|
||||
* If this is not the case we will need to call irs directly
|
||||
* rather than through the base functions.
|
||||
*/
|
||||
|
||||
NGR_R_RETURN
|
||||
getnetgrent_r(char **machinep, char **userp, char **domainp, NGR_R_ARGS) {
|
||||
char *mp, *up, *dp;
|
||||
int res = getnetgrent(&mp, &up, &dp);
|
||||
|
||||
if (res != 1)
|
||||
return (res);
|
||||
|
||||
return (copy_protoent(machinep, userp, domainp,
|
||||
mp, up, dp, NGR_R_COPY));
|
||||
}
|
||||
|
||||
NGR_R_SET_RETURN
|
||||
#ifdef NGR_R_ENT_ARGS
|
||||
setnetgrent_r(const char *netgroup, NGR_R_ENT_ARGS)
|
||||
#else
|
||||
setnetgrent_r(const char *netgroup)
|
||||
#endif
|
||||
{
|
||||
setnetgrent(netgroup);
|
||||
#ifdef NGR_R_PRIVATE
|
||||
*buf = NULL;
|
||||
#endif
|
||||
#ifdef NGR_R_SET_RESULT
|
||||
return (NGR_R_SET_RESULT);
|
||||
#endif
|
||||
}
|
||||
|
||||
NGR_R_END_RETURN
|
||||
#ifdef NGR_R_ENT_ARGS
|
||||
endnetgrent_r(NGR_R_ENT_ARGS)
|
||||
#else
|
||||
endnetgrent_r(void)
|
||||
#endif
|
||||
{
|
||||
endnetgrent();
|
||||
#ifdef NGR_R_PRIVATE
|
||||
if (*buf != NULL)
|
||||
free(*buf);
|
||||
*buf = NULL;
|
||||
#endif
|
||||
NGR_R_END_RESULT(NGR_R_OK);
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static int
|
||||
copy_protoent(char **machinep, char **userp, char **domainp,
|
||||
const char *mp, const char *up, const char *dp,
|
||||
NGR_R_COPY_ARGS) {
|
||||
char *cp;
|
||||
int n;
|
||||
int len;
|
||||
|
||||
/* Find out the amount of space required to store the answer. */
|
||||
len = 0;
|
||||
if (mp != NULL) len += strlen(mp) + 1;
|
||||
if (up != NULL) len += strlen(up) + 1;
|
||||
if (dp != NULL) len += strlen(dp) + 1;
|
||||
|
||||
#ifdef NGR_R_PRIVATE
|
||||
free(*buf);
|
||||
*buf = malloc(len);
|
||||
if (*buf == NULL)
|
||||
return(NGR_R_BAD);
|
||||
cp = *buf;
|
||||
#else
|
||||
if (len > (int)buflen) {
|
||||
errno = ERANGE;
|
||||
return (NGR_R_BAD);
|
||||
}
|
||||
cp = buf;
|
||||
#endif
|
||||
|
||||
|
||||
if (mp != NULL) {
|
||||
n = strlen(mp) + 1;
|
||||
strcpy(cp, mp);
|
||||
*machinep = cp;
|
||||
cp += n;
|
||||
} else
|
||||
*machinep = NULL;
|
||||
|
||||
if (up != NULL) {
|
||||
n = strlen(up) + 1;
|
||||
strcpy(cp, up);
|
||||
*userp = cp;
|
||||
cp += n;
|
||||
} else
|
||||
*userp = NULL;
|
||||
|
||||
if (dp != NULL) {
|
||||
n = strlen(dp) + 1;
|
||||
strcpy(cp, dp);
|
||||
*domainp = cp;
|
||||
cp += n;
|
||||
} else
|
||||
*domainp = NULL;
|
||||
|
||||
return (NGR_R_OK);
|
||||
}
|
||||
#else /* NGR_R_RETURN */
|
||||
static int getnetgrent_r_unknown_system = 0;
|
||||
#endif /* NGR_R_RETURN */
|
||||
#endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
|
||||
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: getprotoent.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#if !defined(__BIND_NOSTATIC)
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_data.h"
|
||||
|
||||
/* Forward */
|
||||
|
||||
static struct net_data *init(void);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct protoent *
|
||||
getprotoent() {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getprotoent_p(net_data));
|
||||
}
|
||||
|
||||
struct protoent *
|
||||
getprotobyname(const char *name) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getprotobyname_p(name, net_data));
|
||||
}
|
||||
|
||||
struct protoent *
|
||||
getprotobynumber(int proto) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getprotobynumber_p(proto, net_data));
|
||||
}
|
||||
|
||||
void
|
||||
setprotoent(int stayopen) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
setprotoent_p(stayopen, net_data);
|
||||
}
|
||||
|
||||
void
|
||||
endprotoent() {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
endprotoent_p(net_data);
|
||||
}
|
||||
|
||||
/* Shared private. */
|
||||
|
||||
struct protoent *
|
||||
getprotoent_p(struct net_data *net_data) {
|
||||
struct irs_pr *pr;
|
||||
|
||||
if (!net_data || !(pr = net_data->pr))
|
||||
return (NULL);
|
||||
net_data->pr_last = (*pr->next)(pr);
|
||||
return (net_data->pr_last);
|
||||
}
|
||||
|
||||
struct protoent *
|
||||
getprotobyname_p(const char *name, struct net_data *net_data) {
|
||||
struct irs_pr *pr;
|
||||
char **pap;
|
||||
|
||||
if (!net_data || !(pr = net_data->pr))
|
||||
return (NULL);
|
||||
if (net_data->pr_stayopen && net_data->pr_last) {
|
||||
if (!strcmp(net_data->pr_last->p_name, name))
|
||||
return (net_data->pr_last);
|
||||
for (pap = net_data->pr_last->p_aliases; pap && *pap; pap++)
|
||||
if (!strcmp(name, *pap))
|
||||
return (net_data->pr_last);
|
||||
}
|
||||
net_data->pr_last = (*pr->byname)(pr, name);
|
||||
if (!net_data->pr_stayopen)
|
||||
endprotoent();
|
||||
return (net_data->pr_last);
|
||||
}
|
||||
|
||||
struct protoent *
|
||||
getprotobynumber_p(int proto, struct net_data *net_data) {
|
||||
struct irs_pr *pr;
|
||||
|
||||
if (!net_data || !(pr = net_data->pr))
|
||||
return (NULL);
|
||||
if (net_data->pr_stayopen && net_data->pr_last)
|
||||
if (net_data->pr_last->p_proto == proto)
|
||||
return (net_data->pr_last);
|
||||
net_data->pr_last = (*pr->bynumber)(pr, proto);
|
||||
if (!net_data->pr_stayopen)
|
||||
endprotoent();
|
||||
return (net_data->pr_last);
|
||||
}
|
||||
|
||||
void
|
||||
setprotoent_p(int stayopen, struct net_data *net_data) {
|
||||
struct irs_pr *pr;
|
||||
|
||||
if (!net_data || !(pr = net_data->pr))
|
||||
return;
|
||||
(*pr->rewind)(pr);
|
||||
net_data->pr_stayopen = (stayopen != 0);
|
||||
if (stayopen == 0)
|
||||
net_data_minimize(net_data);
|
||||
}
|
||||
|
||||
void
|
||||
endprotoent_p(struct net_data *net_data) {
|
||||
struct irs_pr *pr;
|
||||
|
||||
if ((net_data != NULL) && ((pr = net_data->pr) != NULL))
|
||||
(*pr->minimize)(pr);
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static struct net_data *
|
||||
init() {
|
||||
struct net_data *net_data;
|
||||
|
||||
if (!(net_data = net_data_init(NULL)))
|
||||
goto error;
|
||||
if (!net_data->pr) {
|
||||
net_data->pr = (*net_data->irs->pr_map)(net_data->irs);
|
||||
|
||||
if (!net_data->pr || !net_data->res) {
|
||||
error:
|
||||
errno = EIO;
|
||||
return (NULL);
|
||||
}
|
||||
(*net_data->pr->res_set)(net_data->pr, net_data->res, NULL);
|
||||
}
|
||||
|
||||
return (net_data);
|
||||
}
|
||||
|
||||
#endif /*__BIND_NOSTATIC*/
|
||||
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* Copyright (c) 1998-1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: getprotoent_r.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <port_before.h>
|
||||
#if !defined(_REENTRANT) || !defined(DO_PTHREADS)
|
||||
static int getprotoent_r_not_required = 0;
|
||||
#else
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <port_after.h>
|
||||
|
||||
#ifdef PROTO_R_RETURN
|
||||
|
||||
static PROTO_R_RETURN
|
||||
copy_protoent(struct protoent *, struct protoent *, PROTO_R_COPY_ARGS);
|
||||
|
||||
PROTO_R_RETURN
|
||||
getprotobyname_r(const char *name, struct protoent *pptr, PROTO_R_ARGS) {
|
||||
struct protoent *pe = getprotobyname(name);
|
||||
#ifdef PROTO_R_SETANSWER
|
||||
int n = 0;
|
||||
|
||||
if (pe == NULL || (n = copy_protoent(pe, pptr, PROTO_R_COPY)) != 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = pptr;
|
||||
|
||||
return (n);
|
||||
#else
|
||||
if (pe == NULL)
|
||||
return (PROTO_R_BAD);
|
||||
|
||||
return (copy_protoent(pe, pptr, PROTO_R_COPY));
|
||||
#endif
|
||||
}
|
||||
|
||||
PROTO_R_RETURN
|
||||
getprotobynumber_r(int proto, struct protoent *pptr, PROTO_R_ARGS) {
|
||||
struct protoent *pe = getprotobynumber(proto);
|
||||
#ifdef PROTO_R_SETANSWER
|
||||
int n = 0;
|
||||
|
||||
if (pe == NULL || (n = copy_protoent(pe, pptr, PROTO_R_COPY)) != 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = pptr;
|
||||
|
||||
return (n);
|
||||
#else
|
||||
if (pe == NULL)
|
||||
return (PROTO_R_BAD);
|
||||
|
||||
return (copy_protoent(pe, pptr, PROTO_R_COPY));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* These assume a single context is in operation per thread.
|
||||
* If this is not the case we will need to call irs directly
|
||||
* rather than through the base functions.
|
||||
*/
|
||||
|
||||
PROTO_R_RETURN
|
||||
getprotoent_r(struct protoent *pptr, PROTO_R_ARGS) {
|
||||
struct protoent *pe = getprotoent();
|
||||
#ifdef PROTO_R_SETANSWER
|
||||
int n = 0;
|
||||
|
||||
if (pe == NULL || (n = copy_protoent(pe, pptr, PROTO_R_COPY)) != 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = pptr;
|
||||
|
||||
return (n);
|
||||
#else
|
||||
if (pe == NULL)
|
||||
return (PROTO_R_BAD);
|
||||
|
||||
return (copy_protoent(pe, pptr, PROTO_R_COPY));
|
||||
#endif
|
||||
}
|
||||
|
||||
PROTO_R_SET_RETURN
|
||||
#ifdef PROTO_R_ENT_ARGS
|
||||
setprotoent_r(int stay_open, PROTO_R_ENT_ARGS)
|
||||
#else
|
||||
setprotoent_r(int stay_open)
|
||||
#endif
|
||||
{
|
||||
setprotoent(stay_open);
|
||||
#ifdef PROTO_R_SET_RESULT
|
||||
return (PROTO_R_SET_RESULT);
|
||||
#endif
|
||||
}
|
||||
|
||||
PROTO_R_END_RETURN
|
||||
#ifdef PROTO_R_ENT_ARGS
|
||||
endprotoent_r(PROTO_R_ENT_ARGS)
|
||||
#else
|
||||
endprotoent_r()
|
||||
#endif
|
||||
{
|
||||
endprotoent();
|
||||
PROTO_R_END_RESULT(PROTO_R_OK);
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
#ifndef PROTOENT_DATA
|
||||
static PROTO_R_RETURN
|
||||
copy_protoent(struct protoent *pe, struct protoent *pptr, PROTO_R_COPY_ARGS) {
|
||||
char *cp;
|
||||
int i, n;
|
||||
int numptr, len;
|
||||
|
||||
/* Find out the amount of space required to store the answer. */
|
||||
numptr = 1; /* NULL ptr */
|
||||
len = (char *)ALIGN(buf) - buf;
|
||||
for (i = 0; pe->p_aliases[i]; i++, numptr++) {
|
||||
len += strlen(pe->p_aliases[i]) + 1;
|
||||
}
|
||||
len += strlen(pe->p_name) + 1;
|
||||
len += numptr * sizeof(char*);
|
||||
|
||||
if (len > (int)buflen) {
|
||||
errno = ERANGE;
|
||||
return (PROTO_R_BAD);
|
||||
}
|
||||
|
||||
/* copy protocol value*/
|
||||
pptr->p_proto = pe->p_proto;
|
||||
|
||||
cp = (char *)ALIGN(buf) + numptr * sizeof(char *);
|
||||
|
||||
/* copy official name */
|
||||
n = strlen(pe->p_name) + 1;
|
||||
strcpy(cp, pe->p_name);
|
||||
pptr->p_name = cp;
|
||||
cp += n;
|
||||
|
||||
/* copy aliases */
|
||||
pptr->p_aliases = (char **)ALIGN(buf);
|
||||
for (i = 0 ; pe->p_aliases[i]; i++) {
|
||||
n = strlen(pe->p_aliases[i]) + 1;
|
||||
strcpy(cp, pe->p_aliases[i]);
|
||||
pptr->p_aliases[i] = cp;
|
||||
cp += n;
|
||||
}
|
||||
pptr->p_aliases[i] = NULL;
|
||||
|
||||
return (PROTO_R_OK);
|
||||
}
|
||||
#else /* !PROTOENT_DATA */
|
||||
static int
|
||||
copy_protoent(struct protoent *pe, struct protoent *pptr, PROTO_R_COPY_ARGS) {
|
||||
char *cp, *eob;
|
||||
int i, n;
|
||||
|
||||
/* copy protocol value */
|
||||
pptr->p_proto = pe->p_proto;
|
||||
|
||||
/* copy official name */
|
||||
cp = pdptr->line;
|
||||
eob = pdptr->line + sizeof(pdptr->line);
|
||||
if ((n = strlen(pe->p_name) + 1) < (eob - cp)) {
|
||||
strcpy(cp, pe->p_name);
|
||||
pptr->p_name = cp;
|
||||
cp += n;
|
||||
} else {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* copy aliases */
|
||||
i = 0;
|
||||
pptr->p_aliases = pdptr->proto_aliases;
|
||||
while (pe->p_aliases[i] && i < (_MAXALIASES-1)) {
|
||||
if ((n = strlen(pe->p_aliases[i]) + 1) < (eob - cp)) {
|
||||
strcpy(cp, pe->p_aliases[i]);
|
||||
pptr->p_aliases[i] = cp;
|
||||
cp += n;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
pptr->p_aliases[i] = NULL;
|
||||
|
||||
return (PROTO_R_OK);
|
||||
}
|
||||
#endif /* PROTOENT_DATA */
|
||||
#else /* PROTO_R_RETURN */
|
||||
static int getprotoent_r_unknown_system = 0;
|
||||
#endif /* PROTO_R_RETURN */
|
||||
#endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
|
||||
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: getpwent.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#if !defined(WANT_IRS_PW) || defined(__BIND_NOSTATIC)
|
||||
static int __bind_irs_pw_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_data.h"
|
||||
|
||||
/* Forward */
|
||||
|
||||
static struct net_data * init(void);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct passwd *
|
||||
getpwent(void) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getpwent_p(net_data));
|
||||
}
|
||||
|
||||
struct passwd *
|
||||
getpwnam(const char *name) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getpwnam_p(name, net_data));
|
||||
}
|
||||
|
||||
struct passwd *
|
||||
getpwuid(uid_t uid) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getpwuid_p(uid, net_data));
|
||||
}
|
||||
|
||||
int
|
||||
setpassent(int stayopen) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (setpassent_p(stayopen, net_data));
|
||||
}
|
||||
|
||||
#ifdef SETPWENT_VOID
|
||||
void
|
||||
setpwent() {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
setpwent_p(net_data);
|
||||
}
|
||||
#else
|
||||
int
|
||||
setpwent() {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (setpwent_p(net_data));
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
endpwent() {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
endpwent_p(net_data);
|
||||
}
|
||||
|
||||
/* Shared private. */
|
||||
|
||||
struct passwd *
|
||||
getpwent_p(struct net_data *net_data) {
|
||||
struct irs_pw *pw;
|
||||
|
||||
if (!net_data || !(pw = net_data->pw))
|
||||
return (NULL);
|
||||
net_data->pw_last = (*pw->next)(pw);
|
||||
return (net_data->pw_last);
|
||||
}
|
||||
|
||||
struct passwd *
|
||||
getpwnam_p(const char *name, struct net_data *net_data) {
|
||||
struct irs_pw *pw;
|
||||
|
||||
if (!net_data || !(pw = net_data->pw))
|
||||
return (NULL);
|
||||
if (net_data->pw_stayopen && net_data->pw_last &&
|
||||
!strcmp(net_data->pw_last->pw_name, name))
|
||||
return (net_data->pw_last);
|
||||
net_data->pw_last = (*pw->byname)(pw, name);
|
||||
if (!net_data->pw_stayopen)
|
||||
endpwent();
|
||||
return (net_data->pw_last);
|
||||
}
|
||||
|
||||
struct passwd *
|
||||
getpwuid_p(uid_t uid, struct net_data *net_data) {
|
||||
struct irs_pw *pw;
|
||||
|
||||
if (!net_data || !(pw = net_data->pw))
|
||||
return (NULL);
|
||||
if (net_data->pw_stayopen && net_data->pw_last &&
|
||||
net_data->pw_last->pw_uid == uid)
|
||||
return (net_data->pw_last);
|
||||
net_data->pw_last = (*pw->byuid)(pw, uid);
|
||||
if (!net_data->pw_stayopen)
|
||||
endpwent();
|
||||
return (net_data->pw_last);
|
||||
}
|
||||
|
||||
int
|
||||
setpassent_p(int stayopen, struct net_data *net_data) {
|
||||
struct irs_pw *pw;
|
||||
|
||||
if (!net_data || !(pw = net_data->pw))
|
||||
return (0);
|
||||
(*pw->rewind)(pw);
|
||||
net_data->pw_stayopen = (stayopen != 0);
|
||||
if (stayopen == 0)
|
||||
net_data_minimize(net_data);
|
||||
return (1);
|
||||
}
|
||||
|
||||
#ifdef SETPWENT_VOID
|
||||
void
|
||||
setpwent_p(struct net_data *net_data) {
|
||||
(void) setpassent_p(0, net_data);
|
||||
}
|
||||
#else
|
||||
int
|
||||
setpwent_p(struct net_data *net_data) {
|
||||
return (setpassent_p(0, net_data));
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
endpwent_p(struct net_data *net_data) {
|
||||
struct irs_pw *pw;
|
||||
|
||||
if ((net_data != NULL) && ((pw = net_data->pw) != NULL))
|
||||
(*pw->minimize)(pw);
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static struct net_data *
|
||||
init() {
|
||||
struct net_data *net_data;
|
||||
if (!(net_data = net_data_init(NULL)))
|
||||
goto error;
|
||||
if (!net_data->pw) {
|
||||
net_data->pw = (*net_data->irs->pw_map)(net_data->irs);
|
||||
|
||||
if (!net_data->pw || !net_data->res) {
|
||||
error:
|
||||
errno = EIO;
|
||||
return (NULL);
|
||||
}
|
||||
(*net_data->pw->res_set)(net_data->pw, net_data->res, NULL);
|
||||
}
|
||||
|
||||
return (net_data);
|
||||
}
|
||||
|
||||
#endif /* WANT_IRS_PW */
|
||||
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
* Copyright (c) 1998-1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: getpwent_r.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <port_before.h>
|
||||
#if !defined(_REENTRANT) || !defined(DO_PTHREADS) || !defined(WANT_IRS_PW)
|
||||
static int getpwent_r_not_required = 0;
|
||||
#else
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#if (defined(POSIX_GETPWNAM_R) || defined(POSIX_GETPWUID_R))
|
||||
#if defined(_POSIX_PTHREAD_SEMANTICS)
|
||||
/* turn off solaris remapping in <grp.h> */
|
||||
#undef _POSIX_PTHREAD_SEMANTICS
|
||||
#include <pwd.h>
|
||||
#define _POSIX_PTHREAD_SEMANTICS 1
|
||||
#else
|
||||
#define _UNIX95 1
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
#else
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
#include <port_after.h>
|
||||
|
||||
#ifdef PASS_R_RETURN
|
||||
|
||||
static int
|
||||
copy_passwd(struct passwd *, struct passwd *, char *buf, int buflen);
|
||||
|
||||
/* POSIX 1003.1c */
|
||||
#ifdef POSIX_GETPWNAM_R
|
||||
int
|
||||
__posix_getpwnam_r(const char *login, struct passwd *pwptr,
|
||||
char *buf, size_t buflen, struct passwd **result) {
|
||||
#else
|
||||
int
|
||||
getpwnam_r(const char *login, struct passwd *pwptr,
|
||||
char *buf, size_t buflen, struct passwd **result) {
|
||||
#endif
|
||||
struct passwd *pw = getpwnam(login);
|
||||
int res;
|
||||
|
||||
if (pw == NULL) {
|
||||
*result = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
res = copy_passwd(pw, pwptr, buf, buflen);
|
||||
*result = res ? NULL : pwptr;
|
||||
return (res);
|
||||
}
|
||||
|
||||
#ifdef POSIX_GETPWNAM_R
|
||||
struct passwd *
|
||||
getpwnam_r(const char *login, struct passwd *pwptr, char *buf, int buflen) {
|
||||
struct passwd *pw = getpwnam(login);
|
||||
int res;
|
||||
|
||||
if (pw == NULL)
|
||||
return (NULL);
|
||||
|
||||
res = copy_passwd(pw, pwptr, buf, buflen);
|
||||
return (res ? NULL : pwptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* POSIX 1003.1c */
|
||||
#ifdef POSIX_GETPWUID_R
|
||||
int
|
||||
__posix_getpwuid_r(uid_t uid, struct passwd *pwptr,
|
||||
char *buf, int buflen, struct passwd **result) {
|
||||
#else
|
||||
int
|
||||
getpwuid_r(uid_t uid, struct passwd *pwptr,
|
||||
char *buf, size_t buflen, struct passwd **result) {
|
||||
#endif
|
||||
struct passwd *pw = getpwuid(uid);
|
||||
int res;
|
||||
|
||||
if (pw == NULL) {
|
||||
*result = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
res = copy_passwd(pw, pwptr, buf, buflen);
|
||||
*result = res ? NULL : pwptr;
|
||||
return (res);
|
||||
}
|
||||
|
||||
#ifdef POSIX_GETPWUID_R
|
||||
struct passwd *
|
||||
getpwuid_r(uid_t uid, struct passwd *pwptr, char *buf, int buflen) {
|
||||
struct passwd *pw = getpwuid(uid);
|
||||
int res;
|
||||
|
||||
if (pw == NULL)
|
||||
return (NULL);
|
||||
|
||||
res = copy_passwd(pw, pwptr, buf, buflen);
|
||||
return (res ? NULL : pwptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These assume a single context is in operation per thread.
|
||||
* If this is not the case we will need to call irs directly
|
||||
* rather than through the base functions.
|
||||
*/
|
||||
|
||||
PASS_R_RETURN
|
||||
getpwent_r(struct passwd *pwptr, PASS_R_ARGS) {
|
||||
struct passwd *pw = getpwent();
|
||||
int res;
|
||||
|
||||
if (pw == NULL)
|
||||
return (PASS_R_BAD);
|
||||
|
||||
res = copy_passwd(pw, pwptr, buf, buflen);
|
||||
return (res ? PASS_R_BAD : PASS_R_OK);
|
||||
}
|
||||
|
||||
PASS_R_SET_RETURN
|
||||
#ifdef PASS_R_ENT_ARGS
|
||||
setpassent_r(int stayopen, PASS_R_ENT_ARGS)
|
||||
#else
|
||||
setpassent_r(int stayopen)
|
||||
#endif
|
||||
{
|
||||
|
||||
setpassent(stayopen);
|
||||
#ifdef PASS_R_SET_RESULT
|
||||
return (PASS_R_SET_RESULT);
|
||||
#endif
|
||||
}
|
||||
|
||||
PASS_R_SET_RETURN
|
||||
#ifdef PASS_R_ENT_ARGS
|
||||
setpwent_r(PASS_R_ENT_ARGS)
|
||||
#else
|
||||
setpwent_r(void)
|
||||
#endif
|
||||
{
|
||||
|
||||
setpwent();
|
||||
#ifdef PASS_R_SET_RESULT
|
||||
return (PASS_R_SET_RESULT);
|
||||
#endif
|
||||
}
|
||||
|
||||
PASS_R_END_RETURN
|
||||
#ifdef PASS_R_ENT_ARGS
|
||||
endpwent_r(PASS_R_ENT_ARGS)
|
||||
#else
|
||||
endpwent_r(void)
|
||||
#endif
|
||||
{
|
||||
|
||||
endpwent();
|
||||
PASS_R_END_RESULT(PASS_R_OK);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAS_FGETPWENT
|
||||
PASS_R_RETURN
|
||||
fgetpwent_r(FILE *f, struct passwd *pwptr, PASS_R_COPY_ARGS) {
|
||||
struct passwd *pw = fgetpwent(f);
|
||||
int res;
|
||||
|
||||
if (pw == NULL)
|
||||
return (PASS_R_BAD);
|
||||
|
||||
res = copy_passwd(pw, pwptr, PASS_R_COPY);
|
||||
return (res ? PASS_R_BAD : PASS_R_OK );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Private */
|
||||
|
||||
static int
|
||||
copy_passwd(struct passwd *pw, struct passwd *pwptr, char *buf, int buflen) {
|
||||
char *cp;
|
||||
int n;
|
||||
int len;
|
||||
|
||||
/* Find out the amount of space required to store the answer. */
|
||||
len = strlen(pw->pw_name) + 1;
|
||||
len += strlen(pw->pw_passwd) + 1;
|
||||
#ifdef HAVE_PW_CLASS
|
||||
len += strlen(pw->pw_class) + 1;
|
||||
#endif
|
||||
len += strlen(pw->pw_gecos) + 1;
|
||||
len += strlen(pw->pw_dir) + 1;
|
||||
len += strlen(pw->pw_shell) + 1;
|
||||
|
||||
if (len > buflen) {
|
||||
errno = ERANGE;
|
||||
return (ERANGE);
|
||||
}
|
||||
|
||||
/* copy fixed atomic values*/
|
||||
pwptr->pw_uid = pw->pw_uid;
|
||||
pwptr->pw_gid = pw->pw_gid;
|
||||
#ifdef HAVE_PW_CHANGE
|
||||
pwptr->pw_change = pw->pw_change;
|
||||
#endif
|
||||
#ifdef HAVE_PW_EXPIRE
|
||||
pwptr->pw_expire = pw->pw_expire;
|
||||
#endif
|
||||
|
||||
cp = buf;
|
||||
|
||||
/* copy official name */
|
||||
n = strlen(pw->pw_name) + 1;
|
||||
strcpy(cp, pw->pw_name);
|
||||
pwptr->pw_name = cp;
|
||||
cp += n;
|
||||
|
||||
/* copy password */
|
||||
n = strlen(pw->pw_passwd) + 1;
|
||||
strcpy(cp, pw->pw_passwd);
|
||||
pwptr->pw_passwd = cp;
|
||||
cp += n;
|
||||
|
||||
#ifdef HAVE_PW_CLASS
|
||||
/* copy class */
|
||||
n = strlen(pw->pw_class) + 1;
|
||||
strcpy(cp, pw->pw_class);
|
||||
pwptr->pw_class = cp;
|
||||
cp += n;
|
||||
#endif
|
||||
|
||||
/* copy gecos */
|
||||
n = strlen(pw->pw_gecos) + 1;
|
||||
strcpy(cp, pw->pw_gecos);
|
||||
pwptr->pw_gecos = cp;
|
||||
cp += n;
|
||||
|
||||
/* copy directory */
|
||||
n = strlen(pw->pw_dir) + 1;
|
||||
strcpy(cp, pw->pw_dir);
|
||||
pwptr->pw_dir = cp;
|
||||
cp += n;
|
||||
|
||||
/* copy login shell */
|
||||
n = strlen(pw->pw_shell) + 1;
|
||||
strcpy(cp, pw->pw_shell);
|
||||
pwptr->pw_shell = cp;
|
||||
cp += n;
|
||||
|
||||
return (0);
|
||||
}
|
||||
#else /* PASS_R_RETURN */
|
||||
static int getpwent_r_unknown_system = 0;
|
||||
#endif /* PASS_R_RETURN */
|
||||
#endif /* !def(_REENTRANT) || !def(DO_PTHREADS) || !def(WANT_IRS_PW) */
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: getservent.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#if !defined(__BIND_NOSTATIC)
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_data.h"
|
||||
|
||||
/* Forward */
|
||||
|
||||
static struct net_data *init(void);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct servent *
|
||||
getservent(void) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getservent_p(net_data));
|
||||
}
|
||||
|
||||
struct servent *
|
||||
getservbyname(const char *name, const char *proto) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getservbyname_p(name, proto, net_data));
|
||||
}
|
||||
|
||||
struct servent *
|
||||
getservbyport(int port, const char *proto) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getservbyport_p(port, proto, net_data));
|
||||
}
|
||||
|
||||
void
|
||||
setservent(int stayopen) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
setservent_p(stayopen, net_data);
|
||||
}
|
||||
|
||||
void
|
||||
endservent() {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
endservent_p(net_data);
|
||||
}
|
||||
|
||||
/* Shared private. */
|
||||
|
||||
struct servent *
|
||||
getservent_p(struct net_data *net_data) {
|
||||
struct irs_sv *sv;
|
||||
|
||||
if (!net_data || !(sv = net_data->sv))
|
||||
return (NULL);
|
||||
net_data->sv_last = (*sv->next)(sv);
|
||||
return (net_data->sv_last);
|
||||
}
|
||||
|
||||
struct servent *
|
||||
getservbyname_p(const char *name, const char *proto,
|
||||
struct net_data *net_data) {
|
||||
struct irs_sv *sv;
|
||||
char **sap;
|
||||
|
||||
if (!net_data || !(sv = net_data->sv))
|
||||
return (NULL);
|
||||
if (net_data->sv_stayopen && net_data->sv_last)
|
||||
if (!proto || !strcmp(net_data->sv_last->s_proto, proto)) {
|
||||
if (!strcmp(net_data->sv_last->s_name, name))
|
||||
return (net_data->sv_last);
|
||||
for (sap = net_data->sv_last->s_aliases;
|
||||
sap && *sap; sap++)
|
||||
if (!strcmp(name, *sap))
|
||||
return (net_data->sv_last);
|
||||
}
|
||||
net_data->sv_last = (*sv->byname)(sv, name, proto);
|
||||
if (!net_data->sv_stayopen)
|
||||
endservent();
|
||||
return (net_data->sv_last);
|
||||
}
|
||||
|
||||
struct servent *
|
||||
getservbyport_p(int port, const char *proto, struct net_data *net_data) {
|
||||
struct irs_sv *sv;
|
||||
|
||||
if (!net_data || !(sv = net_data->sv))
|
||||
return (NULL);
|
||||
if (net_data->sv_stayopen && net_data->sv_last)
|
||||
if (port == net_data->sv_last->s_port &&
|
||||
( !proto ||
|
||||
!strcmp(net_data->sv_last->s_proto, proto)))
|
||||
return (net_data->sv_last);
|
||||
net_data->sv_last = (*sv->byport)(sv, port, proto);
|
||||
return (net_data->sv_last);
|
||||
}
|
||||
|
||||
void
|
||||
setservent_p(int stayopen, struct net_data *net_data) {
|
||||
struct irs_sv *sv;
|
||||
|
||||
if (!net_data || !(sv = net_data->sv))
|
||||
return;
|
||||
(*sv->rewind)(sv);
|
||||
net_data->sv_stayopen = (stayopen != 0);
|
||||
if (stayopen == 0)
|
||||
net_data_minimize(net_data);
|
||||
}
|
||||
|
||||
void
|
||||
endservent_p(struct net_data *net_data) {
|
||||
struct irs_sv *sv;
|
||||
|
||||
if ((net_data != NULL) && ((sv = net_data->sv) != NULL))
|
||||
(*sv->minimize)(sv);
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static struct net_data *
|
||||
init() {
|
||||
struct net_data *net_data;
|
||||
|
||||
if (!(net_data = net_data_init(NULL)))
|
||||
goto error;
|
||||
if (!net_data->sv) {
|
||||
net_data->sv = (*net_data->irs->sv_map)(net_data->irs);
|
||||
|
||||
if (!net_data->sv || !net_data->res) {
|
||||
error:
|
||||
errno = EIO;
|
||||
return (NULL);
|
||||
}
|
||||
(*net_data->sv->res_set)(net_data->sv, net_data->res, NULL);
|
||||
}
|
||||
|
||||
return (net_data);
|
||||
}
|
||||
|
||||
#endif /*__BIND_NOSTATIC*/
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (c) 1998-1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: getservent_r.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <port_before.h>
|
||||
#if !defined(_REENTRANT) || !defined(DO_PTHREADS)
|
||||
static int getservent_r_not_required = 0;
|
||||
#else
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/param.h>
|
||||
#include <port_after.h>
|
||||
|
||||
#ifdef SERV_R_RETURN
|
||||
|
||||
static SERV_R_RETURN
|
||||
copy_servent(struct servent *, struct servent *, SERV_R_COPY_ARGS);
|
||||
|
||||
SERV_R_RETURN
|
||||
getservbyname_r(const char *name, const char *proto,
|
||||
struct servent *sptr, SERV_R_ARGS) {
|
||||
struct servent *se = getservbyname(name, proto);
|
||||
#ifdef SERV_R_SETANSWER
|
||||
int n = 0;
|
||||
|
||||
if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = sptr;
|
||||
|
||||
return (n);
|
||||
#else
|
||||
if (se == NULL)
|
||||
return (SERV_R_BAD);
|
||||
|
||||
return (copy_servent(se, sptr, SERV_R_COPY));
|
||||
#endif
|
||||
}
|
||||
|
||||
SERV_R_RETURN
|
||||
getservbyport_r(int port, const char *proto,
|
||||
struct servent *sptr, SERV_R_ARGS) {
|
||||
struct servent *se = getservbyport(port, proto);
|
||||
#ifdef SERV_R_SETANSWER
|
||||
int n = 0;
|
||||
|
||||
if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = sptr;
|
||||
|
||||
return (n);
|
||||
#else
|
||||
if (se == NULL)
|
||||
return (SERV_R_BAD);
|
||||
|
||||
return (copy_servent(se, sptr, SERV_R_COPY));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* These assume a single context is in operation per thread.
|
||||
* If this is not the case we will need to call irs directly
|
||||
* rather than through the base functions.
|
||||
*/
|
||||
|
||||
SERV_R_RETURN
|
||||
getservent_r(struct servent *sptr, SERV_R_ARGS) {
|
||||
struct servent *se = getservent();
|
||||
#ifdef SERV_R_SETANSWER
|
||||
int n = 0;
|
||||
|
||||
if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = sptr;
|
||||
|
||||
return (n);
|
||||
#else
|
||||
if (se == NULL)
|
||||
return (SERV_R_BAD);
|
||||
|
||||
return (copy_servent(se, sptr, SERV_R_COPY));
|
||||
#endif
|
||||
}
|
||||
|
||||
SERV_R_SET_RETURN
|
||||
#ifdef SERV_R_ENT_ARGS
|
||||
setservent_r(int stay_open, SERV_R_ENT_ARGS)
|
||||
#else
|
||||
setservent_r(int stay_open)
|
||||
#endif
|
||||
{
|
||||
|
||||
setservent(stay_open);
|
||||
#ifdef SERV_R_SET_RESULT
|
||||
return (SERV_R_SET_RESULT);
|
||||
#endif
|
||||
}
|
||||
|
||||
SERV_R_END_RETURN
|
||||
#ifdef SERV_R_ENT_ARGS
|
||||
endservent_r(SERV_R_ENT_ARGS)
|
||||
#else
|
||||
endservent_r()
|
||||
#endif
|
||||
{
|
||||
|
||||
endservent();
|
||||
SERV_R_END_RESULT(SERV_R_OK);
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
#ifndef SERVENT_DATA
|
||||
static SERV_R_RETURN
|
||||
copy_servent(struct servent *se, struct servent *sptr, SERV_R_COPY_ARGS) {
|
||||
char *cp;
|
||||
int i, n;
|
||||
int numptr, len;
|
||||
|
||||
/* Find out the amount of space required to store the answer. */
|
||||
numptr = 1; /* NULL ptr */
|
||||
len = (char *)ALIGN(buf) - buf;
|
||||
for (i = 0; se->s_aliases[i]; i++, numptr++) {
|
||||
len += strlen(se->s_aliases[i]) + 1;
|
||||
}
|
||||
len += strlen(se->s_name) + 1;
|
||||
len += strlen(se->s_proto) + 1;
|
||||
len += numptr * sizeof(char*);
|
||||
|
||||
if (len > (int)buflen) {
|
||||
errno = ERANGE;
|
||||
return (SERV_R_BAD);
|
||||
}
|
||||
|
||||
/* copy port value */
|
||||
sptr->s_port = se->s_port;
|
||||
|
||||
cp = (char *)ALIGN(buf) + numptr * sizeof(char *);
|
||||
|
||||
/* copy official name */
|
||||
n = strlen(se->s_name) + 1;
|
||||
strcpy(cp, se->s_name);
|
||||
sptr->s_name = cp;
|
||||
cp += n;
|
||||
|
||||
/* copy aliases */
|
||||
sptr->s_aliases = (char **)ALIGN(buf);
|
||||
for (i = 0 ; se->s_aliases[i]; i++) {
|
||||
n = strlen(se->s_aliases[i]) + 1;
|
||||
strcpy(cp, se->s_aliases[i]);
|
||||
sptr->s_aliases[i] = cp;
|
||||
cp += n;
|
||||
}
|
||||
sptr->s_aliases[i] = NULL;
|
||||
|
||||
/* copy proto */
|
||||
n = strlen(se->s_proto) + 1;
|
||||
strcpy(cp, se->s_proto);
|
||||
sptr->s_proto = cp;
|
||||
cp += n;
|
||||
|
||||
return (SERV_R_OK);
|
||||
}
|
||||
#else /* !SERVENT_DATA */
|
||||
static int
|
||||
copy_servent(struct servent *se, struct servent *sptr, SERV_R_COPY_ARGS) {
|
||||
char *cp, *eob;
|
||||
int i, n;
|
||||
|
||||
/* copy port value */
|
||||
sptr->s_port = se->s_port;
|
||||
|
||||
/* copy official name */
|
||||
cp = ndptr->line;
|
||||
eob = ndptr->line + sizeof(ndptr->line);
|
||||
if ((n = strlen(se->s_name) + 1) < (eob - cp)) {
|
||||
strcpy(cp, se->s_name);
|
||||
sptr->s_name = cp;
|
||||
cp += n;
|
||||
} else {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* copy aliases */
|
||||
i = 0;
|
||||
sptr->s_aliases = ndptr->serv_aliases;
|
||||
while (se->s_aliases[i] && i < (_MAXALIASES-1)) {
|
||||
if ((n = strlen(se->s_aliases[i]) + 1) < (eob - cp)) {
|
||||
strcpy(cp, se->s_aliases[i]);
|
||||
sptr->s_aliases[i] = cp;
|
||||
cp += n;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
sptr->s_aliases[i] = NULL;
|
||||
|
||||
/* copy proto */
|
||||
if ((n = strlen(se->s_proto) + 1) < (eob - cp)) {
|
||||
strcpy(cp, se->s_proto);
|
||||
sptr->s_proto = cp;
|
||||
cp += n;
|
||||
} else {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (SERV_R_OK);
|
||||
}
|
||||
#endif /* !SERVENT_DATA */
|
||||
#else /*SERV_R_RETURN */
|
||||
static int getservent_r_unknown_system = 0;
|
||||
#endif /*SERV_R_RETURN */
|
||||
#endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
|
||||
@@ -0,0 +1,524 @@
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: hesiod.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is primarily maintained by <[email protected]> and <[email protected]>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* hesiod.c --- the core portion of the hesiod resolver.
|
||||
*
|
||||
* This file is derived from the hesiod library from Project Athena;
|
||||
* It has been extensively rewritten by Theodore Ts'o to have a more
|
||||
* thread-safe interface.
|
||||
*/
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "pathnames.h"
|
||||
#include "hesiod.h"
|
||||
#include "hesiod_p.h"
|
||||
|
||||
/* Forward */
|
||||
|
||||
int hesiod_init(void **context);
|
||||
void hesiod_end(void *context);
|
||||
char * hesiod_to_bind(void *context, const char *name,
|
||||
const char *type);
|
||||
char ** hesiod_resolve(void *context, const char *name,
|
||||
const char *type);
|
||||
void hesiod_free_list(void *context, char **list);
|
||||
|
||||
static int parse_config_file(struct hesiod_p *ctx, const char *filename);
|
||||
static char ** get_txt_records(struct hesiod_p *ctx, int class,
|
||||
const char *name);
|
||||
static int init(struct hesiod_p *ctx);
|
||||
|
||||
/* Public */
|
||||
|
||||
/*
|
||||
* This function is called to initialize a hesiod_p.
|
||||
*/
|
||||
int
|
||||
hesiod_init(void **context) {
|
||||
struct hesiod_p *ctx;
|
||||
char *cp;
|
||||
|
||||
ctx = malloc(sizeof(struct hesiod_p));
|
||||
if (ctx == 0) {
|
||||
errno = ENOMEM;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
ctx->LHS = NULL;
|
||||
ctx->RHS = NULL;
|
||||
ctx->res = NULL;
|
||||
|
||||
if (parse_config_file(ctx, _PATH_HESIOD_CONF) < 0) {
|
||||
#ifdef DEF_RHS
|
||||
/*
|
||||
* Use compiled in defaults.
|
||||
*/
|
||||
ctx->LHS = malloc(strlen(DEF_LHS)+1);
|
||||
ctx->RHS = malloc(strlen(DEF_RHS)+1);
|
||||
if (ctx->LHS == 0 || ctx->RHS == 0) {
|
||||
errno = ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
#ifdef HAVE_STRLCPY
|
||||
strlcpy(ctx->LHS, DEF_LHS, strlen(DEF_LHS) + 1);
|
||||
strlcpy(ctx->RHS, DEF_RHS, strlen(DEF_RHS) + 1);
|
||||
#else
|
||||
strcpy(ctx->LHS, DEF_LHS);
|
||||
strcpy(ctx->RHS, DEF_RHS);
|
||||
#endif
|
||||
#else
|
||||
goto cleanup;
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* The default RHS can be overridden by an environment
|
||||
* variable.
|
||||
*/
|
||||
if ((cp = getenv("HES_DOMAIN")) != NULL) {
|
||||
size_t RHSlen = strlen(cp) + 2;
|
||||
if (ctx->RHS)
|
||||
free(ctx->RHS);
|
||||
ctx->RHS = malloc(RHSlen);
|
||||
if (!ctx->RHS) {
|
||||
errno = ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
if (cp[0] == '.') {
|
||||
#ifdef HAVE_STRLCPY
|
||||
strlcpy(ctx->RHS, cp, RHSlen);
|
||||
#else
|
||||
strcpy(ctx->RHS, cp);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef HAVE_STRLCPY
|
||||
strlcpy(ctx->RHS, ".", RHSlen);
|
||||
#else
|
||||
strcpy(ctx->RHS, ".");
|
||||
#endif
|
||||
#ifdef HAVE_STRLCAT
|
||||
strlcat(ctx->RHS, cp, RHSlen);
|
||||
#else
|
||||
strcat(ctx->RHS, cp);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is no default hesiod realm set, we return an
|
||||
* error.
|
||||
*/
|
||||
if (!ctx->RHS) {
|
||||
errno = ENOEXEC;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (res_ninit(ctx->res) < 0)
|
||||
goto cleanup;
|
||||
#endif
|
||||
|
||||
*context = ctx;
|
||||
return (0);
|
||||
|
||||
cleanup:
|
||||
hesiod_end(ctx);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function deallocates the hesiod_p
|
||||
*/
|
||||
void
|
||||
hesiod_end(void *context) {
|
||||
struct hesiod_p *ctx = (struct hesiod_p *) context;
|
||||
int save_errno = errno;
|
||||
|
||||
if (ctx->res)
|
||||
res_nclose(ctx->res);
|
||||
if (ctx->RHS)
|
||||
free(ctx->RHS);
|
||||
if (ctx->LHS)
|
||||
free(ctx->LHS);
|
||||
if (ctx->res && ctx->free_res)
|
||||
(*ctx->free_res)(ctx->res);
|
||||
free(ctx);
|
||||
errno = save_errno;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function 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;
|
||||
char **rhs_list = NULL;
|
||||
const char *RHS, *cp;
|
||||
|
||||
/* Decide what our RHS is, and set cp to the end of the actual name. */
|
||||
if ((cp = strchr(name, '@')) != NULL) {
|
||||
if (strchr(cp + 1, '.'))
|
||||
RHS = cp + 1;
|
||||
else if ((rhs_list = hesiod_resolve(context, cp + 1,
|
||||
"rhs-extension")) != NULL)
|
||||
RHS = *rhs_list;
|
||||
else {
|
||||
errno = ENOENT;
|
||||
return (NULL);
|
||||
}
|
||||
} else {
|
||||
RHS = ctx->RHS;
|
||||
cp = name + strlen(name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate the space we need, including up to three periods and
|
||||
* the terminating NUL.
|
||||
*/
|
||||
if ((bindname = malloc((cp - name) + strlen(type) + strlen(RHS) +
|
||||
(ctx->LHS ? strlen(ctx->LHS) : 0) + 4)) == NULL) {
|
||||
errno = ENOMEM;
|
||||
if (rhs_list)
|
||||
hesiod_free_list(context, rhs_list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Now put together the DNS name. */
|
||||
memcpy(bindname, name, cp - name);
|
||||
bindname[cp - name] = '\0';
|
||||
strcat(bindname, ".");
|
||||
strcat(bindname, type);
|
||||
if (ctx->LHS) {
|
||||
if (ctx->LHS[0] != '.')
|
||||
strcat(bindname, ".");
|
||||
strcat(bindname, ctx->LHS);
|
||||
}
|
||||
if (RHS[0] != '.')
|
||||
strcat(bindname, ".");
|
||||
strcat(bindname, RHS);
|
||||
|
||||
if (rhs_list)
|
||||
hesiod_free_list(context, rhs_list);
|
||||
|
||||
return (bindname);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the core function. Given a hesiod (name, type), it
|
||||
* returns an array of strings returned by the resolver.
|
||||
*/
|
||||
char **
|
||||
hesiod_resolve(void *context, const char *name, const char *type) {
|
||||
struct hesiod_p *ctx = (struct hesiod_p *) context;
|
||||
char *bindname = hesiod_to_bind(context, name, type);
|
||||
char **retvec;
|
||||
|
||||
if (bindname == NULL)
|
||||
return (NULL);
|
||||
if (init(ctx) == -1) {
|
||||
free(bindname);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if ((retvec = get_txt_records(ctx, C_IN, bindname))) {
|
||||
free(bindname);
|
||||
return (retvec);
|
||||
}
|
||||
|
||||
if (errno != ENOENT)
|
||||
return (NULL);
|
||||
|
||||
retvec = get_txt_records(ctx, C_HS, bindname);
|
||||
free(bindname);
|
||||
return (retvec);
|
||||
}
|
||||
|
||||
void
|
||||
hesiod_free_list(void *context, char **list) {
|
||||
char **p;
|
||||
|
||||
UNUSED(context);
|
||||
|
||||
for (p = list; *p; p++)
|
||||
free(*p);
|
||||
free(list);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function parses the /etc/hesiod.conf file
|
||||
*/
|
||||
static int
|
||||
parse_config_file(struct hesiod_p *ctx, const char *filename) {
|
||||
char *key, *data, *cp, **cpp;
|
||||
char buf[MAXDNAME+7];
|
||||
FILE *fp;
|
||||
|
||||
/*
|
||||
* Clear the existing configuration variable, just in case
|
||||
* they're set.
|
||||
*/
|
||||
if (ctx->RHS)
|
||||
free(ctx->RHS);
|
||||
if (ctx->LHS)
|
||||
free(ctx->LHS);
|
||||
ctx->RHS = ctx->LHS = 0;
|
||||
|
||||
/*
|
||||
* Now open and parse the file...
|
||||
*/
|
||||
if (!(fp = fopen(filename, "r")))
|
||||
return (-1);
|
||||
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
cp = buf;
|
||||
if (*cp == '#' || *cp == '\n' || *cp == '\r')
|
||||
continue;
|
||||
while(*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
key = cp;
|
||||
while(*cp != ' ' && *cp != '\t' && *cp != '=')
|
||||
cp++;
|
||||
*cp++ = '\0';
|
||||
|
||||
while(*cp == ' ' || *cp == '\t' || *cp == '=')
|
||||
cp++;
|
||||
data = cp;
|
||||
while(*cp != ' ' && *cp != '\n' && *cp != '\r')
|
||||
cp++;
|
||||
*cp++ = '\0';
|
||||
|
||||
if (strcmp(key, "lhs") == 0)
|
||||
cpp = &ctx->LHS;
|
||||
else if (strcmp(key, "rhs") == 0)
|
||||
cpp = &ctx->RHS;
|
||||
else
|
||||
continue;
|
||||
|
||||
*cpp = malloc(strlen(data) + 1);
|
||||
if (!*cpp) {
|
||||
errno = ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
strcpy(*cpp, data);
|
||||
}
|
||||
fclose(fp);
|
||||
return (0);
|
||||
|
||||
cleanup:
|
||||
fclose(fp);
|
||||
if (ctx->RHS)
|
||||
free(ctx->RHS);
|
||||
if (ctx->LHS)
|
||||
free(ctx->LHS);
|
||||
ctx->RHS = ctx->LHS = 0;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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(struct hesiod_p *ctx, int class, const char *name) {
|
||||
struct {
|
||||
int type; /* RR type */
|
||||
int class; /* RR class */
|
||||
int dlen; /* len of data section */
|
||||
u_char *data; /* pointer to data */
|
||||
} rr;
|
||||
HEADER *hp;
|
||||
u_char qbuf[MAX_HESRESP], abuf[MAX_HESRESP];
|
||||
u_char *cp, *erdata, *eom;
|
||||
char *dst, *edst, **list;
|
||||
int ancount, qdcount;
|
||||
int i, j, n, skip;
|
||||
|
||||
/*
|
||||
* Construct the query and send it.
|
||||
*/
|
||||
n = res_nmkquery(ctx->res, QUERY, name, class, T_TXT, NULL, 0,
|
||||
NULL, qbuf, MAX_HESRESP);
|
||||
if (n < 0) {
|
||||
errno = EMSGSIZE;
|
||||
return (NULL);
|
||||
}
|
||||
n = res_nsend(ctx->res, qbuf, n, abuf, MAX_HESRESP);
|
||||
if (n < 0) {
|
||||
errno = ECONNREFUSED;
|
||||
return (NULL);
|
||||
}
|
||||
if (n < HFIXEDSZ) {
|
||||
errno = EMSGSIZE;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, parse the result.
|
||||
*/
|
||||
hp = (HEADER *) abuf;
|
||||
ancount = ntohs(hp->ancount);
|
||||
qdcount = ntohs(hp->qdcount);
|
||||
cp = abuf + sizeof(HEADER);
|
||||
eom = abuf + n;
|
||||
|
||||
/* Skip query, trying to get to the answer section which follows. */
|
||||
for (i = 0; i < qdcount; i++) {
|
||||
skip = dn_skipname(cp, eom);
|
||||
if (skip < 0 || cp + skip + QFIXEDSZ > eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (NULL);
|
||||
}
|
||||
cp += skip + QFIXEDSZ;
|
||||
}
|
||||
|
||||
list = malloc((ancount + 1) * sizeof(char *));
|
||||
if (!list) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
j = 0;
|
||||
for (i = 0; i < ancount; i++) {
|
||||
skip = dn_skipname(cp, eom);
|
||||
if (skip < 0) {
|
||||
errno = EMSGSIZE;
|
||||
goto cleanup;
|
||||
}
|
||||
cp += skip;
|
||||
if (cp + 3 * INT16SZ + INT32SZ > eom) {
|
||||
errno = EMSGSIZE;
|
||||
goto cleanup;
|
||||
}
|
||||
rr.type = ns_get16(cp);
|
||||
cp += INT16SZ;
|
||||
rr.class = ns_get16(cp);
|
||||
cp += INT16SZ + INT32SZ; /* skip the ttl, too */
|
||||
rr.dlen = ns_get16(cp);
|
||||
cp += INT16SZ;
|
||||
if (cp + rr.dlen > eom) {
|
||||
errno = EMSGSIZE;
|
||||
goto cleanup;
|
||||
}
|
||||
rr.data = cp;
|
||||
cp += rr.dlen;
|
||||
if (rr.class != class || rr.type != T_TXT)
|
||||
continue;
|
||||
if (!(list[j] = malloc(rr.dlen)))
|
||||
goto cleanup;
|
||||
dst = list[j++];
|
||||
edst = dst + rr.dlen;
|
||||
erdata = rr.data + rr.dlen;
|
||||
cp = rr.data;
|
||||
while (cp < erdata) {
|
||||
n = (unsigned char) *cp++;
|
||||
if (cp + n > eom || dst + n > edst) {
|
||||
errno = EMSGSIZE;
|
||||
goto cleanup;
|
||||
}
|
||||
memcpy(dst, cp, n);
|
||||
cp += n;
|
||||
dst += n;
|
||||
}
|
||||
if (cp != erdata) {
|
||||
errno = EMSGSIZE;
|
||||
goto cleanup;
|
||||
}
|
||||
*dst = '\0';
|
||||
}
|
||||
list[j] = NULL;
|
||||
if (j == 0) {
|
||||
errno = ENOENT;
|
||||
goto cleanup;
|
||||
}
|
||||
return (list);
|
||||
|
||||
cleanup:
|
||||
for (i = 0; i < j; i++)
|
||||
free(list[i]);
|
||||
free(list);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
struct __res_state *
|
||||
__hesiod_res_get(void *context) {
|
||||
struct hesiod_p *ctx = context;
|
||||
|
||||
if (!ctx->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (res == NULL) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
__hesiod_res_set(ctx, res, free);
|
||||
}
|
||||
|
||||
return (ctx->res);
|
||||
}
|
||||
|
||||
void
|
||||
__hesiod_res_set(void *context, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct hesiod_p *ctx = context;
|
||||
|
||||
if (ctx->res && ctx->free_res) {
|
||||
res_nclose(ctx->res);
|
||||
(*ctx->free_res)(ctx->res);
|
||||
}
|
||||
|
||||
ctx->res = res;
|
||||
ctx->free_res = free_res;
|
||||
}
|
||||
|
||||
static int
|
||||
init(struct hesiod_p *ctx) {
|
||||
|
||||
if (!ctx->res && !__hesiod_res_get(ctx))
|
||||
return (-1);
|
||||
|
||||
if (((ctx->res->options & RES_INIT) == 0) &&
|
||||
(res_ninit(ctx->res) == -1))
|
||||
return (-1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is primarily maintained by <[email protected]> and <[email protected]>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: hesiod_p.h,v 1.1 2004/04/15 16:03:29 wkornew Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* hesiod_p.h -- private definitions for the hesiod library
|
||||
*/
|
||||
|
||||
#ifndef _HESIOD_P_H_INCLUDED
|
||||
#define _HESIOD_P_H_INCLUDED
|
||||
|
||||
#define DEF_RHS ".Athena.MIT.EDU" /* Defaults if HESIOD_CONF */
|
||||
#define DEF_LHS ".ns" /* file is not */
|
||||
/* present. */
|
||||
struct hesiod_p {
|
||||
char * LHS; /* normally ".ns" */
|
||||
char * RHS; /* AKA the default hesiod domain */
|
||||
struct __res_state * res; /* resolver context */
|
||||
void (*free_res)(void *);
|
||||
void (*res_set)(struct hesiod_p *, struct __res_state *,
|
||||
void (*)(void *));
|
||||
struct __res_state * (*res_get)(struct hesiod_p *);
|
||||
};
|
||||
|
||||
#define MAX_HESRESP 1024
|
||||
|
||||
#endif /*_HESIOD_P_H_INCLUDED*/
|
||||
@@ -0,0 +1,592 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 1998 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.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: irp.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <syslog.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <syslog.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <irp.h>
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "irp_p.h"
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static void irp_close(struct irs_acc *);
|
||||
|
||||
#define LINEINCR 128
|
||||
|
||||
#if !defined(SUN_LEN)
|
||||
#define SUN_LEN(su) \
|
||||
(sizeof (*(su)) - sizeof ((su)->sun_path) + strlen((su)->sun_path))
|
||||
#endif
|
||||
|
||||
|
||||
/* Public */
|
||||
|
||||
|
||||
/* send errors to syslog if true. */
|
||||
int irp_log_errors = 1;
|
||||
|
||||
/*
|
||||
* This module handles the irp module connection to irpd.
|
||||
*
|
||||
* The client expects a synchronous interface to functions like
|
||||
* getpwnam(3), so we can't use the ctl_* i/o library on this end of
|
||||
* the wire (it's used in the server).
|
||||
*/
|
||||
|
||||
/*
|
||||
* irs_acc *irs_irp_acc(const char *options);
|
||||
*
|
||||
* Initialize the irp module.
|
||||
*/
|
||||
struct irs_acc *
|
||||
irs_irp_acc(const char *options) {
|
||||
struct irs_acc *acc;
|
||||
struct irp_p *irp;
|
||||
|
||||
UNUSED(options);
|
||||
|
||||
if (!(acc = memget(sizeof *acc))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(acc, 0x5e, sizeof *acc);
|
||||
if (!(irp = memget(sizeof *irp))) {
|
||||
errno = ENOMEM;
|
||||
free(acc);
|
||||
return (NULL);
|
||||
}
|
||||
irp->inlast = 0;
|
||||
irp->incurr = 0;
|
||||
irp->fdCxn = -1;
|
||||
acc->private = irp;
|
||||
|
||||
#ifdef WANT_IRS_GR
|
||||
acc->gr_map = irs_irp_gr;
|
||||
#else
|
||||
acc->gr_map = NULL;
|
||||
#endif
|
||||
#ifdef WANT_IRS_PW
|
||||
acc->pw_map = irs_irp_pw;
|
||||
#else
|
||||
acc->pw_map = NULL;
|
||||
#endif
|
||||
acc->sv_map = irs_irp_sv;
|
||||
acc->pr_map = irs_irp_pr;
|
||||
acc->ho_map = irs_irp_ho;
|
||||
acc->nw_map = irs_irp_nw;
|
||||
acc->ng_map = irs_irp_ng;
|
||||
acc->close = irp_close;
|
||||
return (acc);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
irs_irp_connection_setup(struct irp_p *cxndata, int *warned) {
|
||||
if (irs_irp_is_connected(cxndata)) {
|
||||
return (0);
|
||||
} else if (irs_irp_connect(cxndata) != 0) {
|
||||
if (warned != NULL && !*warned) {
|
||||
syslog(LOG_ERR, "irpd connection failed: %m\n");
|
||||
(*warned)++;
|
||||
}
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* int irs_irp_connect(void);
|
||||
*
|
||||
* Sets up the connection to the remote irpd server.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* 0 on success, -1 on failure.
|
||||
*
|
||||
*/
|
||||
int
|
||||
irs_irp_connect(struct irp_p *pvt) {
|
||||
int flags;
|
||||
struct sockaddr *addr;
|
||||
struct sockaddr_in iaddr;
|
||||
#ifndef NO_SOCKADDR_UN
|
||||
struct sockaddr_un uaddr;
|
||||
#endif
|
||||
long ipaddr;
|
||||
const char *irphost;
|
||||
int code;
|
||||
char text[256];
|
||||
int socklen = 0;
|
||||
|
||||
if (pvt->fdCxn != -1) {
|
||||
perror("fd != 1");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#ifndef NO_SOCKADDR_UN
|
||||
memset(&uaddr, 0, sizeof uaddr);
|
||||
#endif
|
||||
memset(&iaddr, 0, sizeof iaddr);
|
||||
|
||||
irphost = getenv(IRPD_HOST_ENV);
|
||||
if (irphost == NULL) {
|
||||
irphost = "127.0.0.1";
|
||||
}
|
||||
|
||||
#ifndef NO_SOCKADDR_UN
|
||||
if (irphost[0] == '/') {
|
||||
addr = (struct sockaddr *)&uaddr;
|
||||
strncpy(uaddr.sun_path, irphost, sizeof uaddr.sun_path);
|
||||
uaddr.sun_family = AF_UNIX;
|
||||
socklen = SUN_LEN(&uaddr);
|
||||
#ifdef HAVE_SA_LEN
|
||||
uaddr.sun_len = socklen;
|
||||
#endif
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (inet_pton(AF_INET, irphost, &ipaddr) != 1) {
|
||||
errno = EADDRNOTAVAIL;
|
||||
perror("inet_pton");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
addr = (struct sockaddr *)&iaddr;
|
||||
socklen = sizeof iaddr;
|
||||
#ifdef HAVE_SA_LEN
|
||||
iaddr.sin_len = socklen;
|
||||
#endif
|
||||
iaddr.sin_family = AF_INET;
|
||||
iaddr.sin_port = htons(IRPD_PORT);
|
||||
iaddr.sin_addr.s_addr = ipaddr;
|
||||
}
|
||||
|
||||
|
||||
pvt->fdCxn = socket(addr->sa_family, SOCK_STREAM, PF_UNSPEC);
|
||||
if (pvt->fdCxn < 0) {
|
||||
perror("socket");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (connect(pvt->fdCxn, addr, socklen) != 0) {
|
||||
perror("connect");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
flags = fcntl(pvt->fdCxn, F_GETFL, 0);
|
||||
if (flags < 0) {
|
||||
close(pvt->fdCxn);
|
||||
perror("close");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
flags |= O_NONBLOCK;
|
||||
if (fcntl(pvt->fdCxn, F_SETFL, flags) < 0) {
|
||||
close(pvt->fdCxn);
|
||||
perror("fcntl");
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
code = irs_irp_read_response(pvt, text, sizeof text);
|
||||
if (code != IRPD_WELCOME_CODE) {
|
||||
if (irp_log_errors) {
|
||||
syslog(LOG_WARNING, "Connection failed: %s", text);
|
||||
}
|
||||
irs_irp_disconnect(pvt);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* int irs_irp_is_connected(struct irp_p *pvt);
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* Non-zero if streams are setup to remote.
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
irs_irp_is_connected(struct irp_p *pvt) {
|
||||
return (pvt->fdCxn >= 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void
|
||||
* irs_irp_disconnect(struct irp_p *pvt);
|
||||
*
|
||||
* Closes streams to remote.
|
||||
*/
|
||||
|
||||
void
|
||||
irs_irp_disconnect(struct irp_p *pvt) {
|
||||
if (pvt->fdCxn != -1) {
|
||||
close(pvt->fdCxn);
|
||||
pvt->fdCxn = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
irs_irp_read_line(struct irp_p *pvt, char *buffer, int len) {
|
||||
char *realstart = &pvt->inbuffer[0];
|
||||
char *p, *start, *end;
|
||||
int spare;
|
||||
int i;
|
||||
int buffpos = 0;
|
||||
int left = len - 1;
|
||||
|
||||
while (left > 0) {
|
||||
start = p = &pvt->inbuffer[pvt->incurr];
|
||||
end = &pvt->inbuffer[pvt->inlast];
|
||||
|
||||
while (p != end && *p != '\n')
|
||||
p++;
|
||||
|
||||
if (p == end) {
|
||||
/* Found no newline so shift data down if necessary
|
||||
* and append new data to buffer
|
||||
*/
|
||||
if (start > realstart) {
|
||||
memmove(realstart, start, end - start);
|
||||
pvt->inlast = end - start;
|
||||
start = realstart;
|
||||
pvt->incurr = 0;
|
||||
end = &pvt->inbuffer[pvt->inlast];
|
||||
}
|
||||
|
||||
spare = sizeof (pvt->inbuffer) - pvt->inlast;
|
||||
|
||||
p = end;
|
||||
i = read(pvt->fdCxn, end, spare);
|
||||
if (i < 0) {
|
||||
close(pvt->fdCxn);
|
||||
pvt->fdCxn = -1;
|
||||
return (buffpos > 0 ? buffpos : -1);
|
||||
} else if (i == 0) {
|
||||
return (buffpos);
|
||||
}
|
||||
|
||||
end += i;
|
||||
pvt->inlast += i;
|
||||
|
||||
while (p != end && *p != '\n')
|
||||
p++;
|
||||
}
|
||||
|
||||
if (p == end) {
|
||||
/* full buffer and still no newline */
|
||||
i = sizeof pvt->inbuffer;
|
||||
} else {
|
||||
/* include newline */
|
||||
i = p - start + 1;
|
||||
}
|
||||
|
||||
if (i > left)
|
||||
i = left;
|
||||
memcpy(buffer + buffpos, start, i);
|
||||
pvt->incurr += i;
|
||||
buffpos += i;
|
||||
buffer[buffpos] = '\0';
|
||||
|
||||
if (p != end) {
|
||||
left = 0;
|
||||
} else {
|
||||
left -= i;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "read line: %s\n", buffer);
|
||||
#endif
|
||||
return (buffpos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* int irp_read_response(struct irp_p *pvt);
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* The number found at the beginning of the line read from
|
||||
* FP. 0 on failure(0 is not a legal response code). The
|
||||
* rest of the line is discarded.
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
irs_irp_read_response(struct irp_p *pvt, char *text, size_t textlen) {
|
||||
char line[1024];
|
||||
int code;
|
||||
char *p;
|
||||
|
||||
if (irs_irp_read_line(pvt, line, sizeof line) <= 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
p = strchr(line, '\n');
|
||||
if (p == NULL) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (sscanf(line, "%d", &code) != 1) {
|
||||
code = 0;
|
||||
} else if (text != NULL && textlen > 0) {
|
||||
p = line;
|
||||
while (isspace((unsigned char)*p)) p++;
|
||||
while (isdigit((unsigned char)*p)) p++;
|
||||
while (isspace((unsigned char)*p)) p++;
|
||||
strncpy(text, p, textlen - 1);
|
||||
p[textlen - 1] = '\0';
|
||||
}
|
||||
|
||||
return (code);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* char *irp_read_body(struct irp_p *pvt, size_t *size);
|
||||
*
|
||||
* Read in the body of a response. Terminated by a line with
|
||||
* just a dot on it. Lines should be terminated with a CR-LF
|
||||
* sequence, but we're nt piccky if the CR is missing.
|
||||
* No leading dot escaping is done as the protcol doesn't
|
||||
* use leading dots anywhere.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* Pointer to null-terminated buffer allocated by memget.
|
||||
* *SIZE is set to the length of the buffer.
|
||||
*
|
||||
*/
|
||||
|
||||
char *
|
||||
irs_irp_read_body(struct irp_p *pvt, size_t *size) {
|
||||
char line[1024];
|
||||
u_int linelen;
|
||||
size_t len = LINEINCR;
|
||||
char *buffer = memget(len);
|
||||
int idx = 0;
|
||||
|
||||
for (;;) {
|
||||
if (irs_irp_read_line(pvt, line, sizeof line) <= 0 ||
|
||||
strchr(line, '\n') == NULL)
|
||||
goto death;
|
||||
|
||||
linelen = strlen(line);
|
||||
|
||||
if (line[linelen - 1] != '\n')
|
||||
goto death;
|
||||
|
||||
/* We're not strict about missing \r. Should we be?? */
|
||||
if (linelen > 2 && line[linelen - 2] == '\r') {
|
||||
line[linelen - 2] = '\n';
|
||||
line[linelen - 1] = '\0';
|
||||
linelen--;
|
||||
}
|
||||
|
||||
if (linelen == 2 && line[0] == '.') {
|
||||
*size = len;
|
||||
buffer[idx] = '\0';
|
||||
|
||||
return (buffer);
|
||||
}
|
||||
|
||||
if (linelen > (len - (idx + 1))) {
|
||||
char *p = memget(len + LINEINCR);
|
||||
|
||||
if (p == NULL)
|
||||
goto death;
|
||||
memcpy(p, buffer, len);
|
||||
memput(buffer, len);
|
||||
buffer = p;
|
||||
len += LINEINCR;
|
||||
}
|
||||
|
||||
memcpy(buffer + idx, line, linelen);
|
||||
idx += linelen;
|
||||
}
|
||||
death:
|
||||
memput(buffer, len);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* int irs_irp_get_full_response(struct irp_p *pvt, int *code,
|
||||
* char **body, size_t *bodylen);
|
||||
*
|
||||
* Gets the response to a command. If the response indicates
|
||||
* there's a body to follow(code % 10 == 1), then the
|
||||
* body buffer is allcoated with memget and stored in
|
||||
* *BODY. The length of the allocated body buffer is stored
|
||||
* in *BODY. The caller must give the body buffer back to
|
||||
* memput when done. The results code is stored in *CODE.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* 0 if a result was read. -1 on some sort of failure.
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
irs_irp_get_full_response(struct irp_p *pvt, int *code, char *text,
|
||||
size_t textlen, char **body, size_t *bodylen) {
|
||||
int result = irs_irp_read_response(pvt, text, textlen);
|
||||
|
||||
*body = NULL;
|
||||
|
||||
if (result == 0) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
*code = result;
|
||||
|
||||
/* Code that matches 2xx is a good result code.
|
||||
* Code that matches xx1 means there's a response body coming.
|
||||
*/
|
||||
if ((result / 100) == 2 && (result % 10) == 1) {
|
||||
*body = irs_irp_read_body(pvt, bodylen);
|
||||
if (*body == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* int irs_irp_send_command(struct irp_p *pvt, const char *fmt, ...);
|
||||
*
|
||||
* Sends command to remote connected via the PVT
|
||||
* struture. FMT and args after it are fprintf-like
|
||||
* arguments for formatting.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* 0 on success, -1 on failure.
|
||||
*/
|
||||
|
||||
int
|
||||
irs_irp_send_command(struct irp_p *pvt, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
char buffer[1024];
|
||||
int pos = 0;
|
||||
int i, todo;
|
||||
|
||||
|
||||
if (pvt->fdCxn < 0) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
va_start(ap, fmt);
|
||||
todo = vsprintf(buffer, fmt, ap);
|
||||
va_end(ap);
|
||||
if (todo > (int)sizeof(buffer) - 3) {
|
||||
syslog(LOG_CRIT, "memory overrun in irs_irp_send_command()");
|
||||
exit(1);
|
||||
}
|
||||
strcat(buffer, "\r\n");
|
||||
todo = strlen(buffer);
|
||||
|
||||
while (todo > 0) {
|
||||
i = write(pvt->fdCxn, buffer + pos, todo);
|
||||
#if 0
|
||||
/* XXX brister */
|
||||
fprintf(stderr, "Wrote: \"");
|
||||
fwrite(buffer + pos, sizeof (char), todo, stderr);
|
||||
fprintf(stderr, "\"\n");
|
||||
#endif
|
||||
if (i < 0) {
|
||||
close(pvt->fdCxn);
|
||||
pvt->fdCxn = -1;
|
||||
return (-1);
|
||||
}
|
||||
todo -= i;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/* Methods */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void irp_close(struct irs_acc *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
irp_close(struct irs_acc *this) {
|
||||
struct irp_p *irp = (struct irp_p *)this->private;
|
||||
|
||||
if (irp != NULL) {
|
||||
irs_irp_disconnect(irp);
|
||||
memput(irp, sizeof *irp);
|
||||
}
|
||||
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,408 @@
|
||||
/*
|
||||
* Portions Copyright(c) 1996, 1998 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: irp_gr.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* extern */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_PW
|
||||
static int __bind_irs_gr_unneeded;
|
||||
#else
|
||||
|
||||
#include <syslog.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <irp.h>
|
||||
#include <isc/memcluster.h>
|
||||
#include <isc/irpmarshall.h>
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "lcl_p.h"
|
||||
#include "irp_p.h"
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
|
||||
/* Types. */
|
||||
|
||||
/*
|
||||
* Module for the getnetgrent(3) family to use when connected to a
|
||||
* remote irp daemon.
|
||||
*
|
||||
* See irpd.c for justification of caching done here.
|
||||
*
|
||||
*/
|
||||
|
||||
struct pvt {
|
||||
struct irp_p *girpdata; /* global IRP data */
|
||||
int warned;
|
||||
struct group group;
|
||||
};
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static void gr_close(struct irs_gr *);
|
||||
static struct group * gr_next(struct irs_gr *);
|
||||
static struct group * gr_byname(struct irs_gr *, const char *);
|
||||
static struct group * gr_bygid(struct irs_gr *, gid_t);
|
||||
static void gr_rewind(struct irs_gr *);
|
||||
static void gr_minimize(struct irs_gr *);
|
||||
|
||||
/* Private */
|
||||
static void free_group(struct group *gr);
|
||||
|
||||
|
||||
/* Public. */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct irs_gr * irs_irp_gr(struct irs_acc *this)
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* Initialize the group sub-module.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* Module data.
|
||||
*
|
||||
*/
|
||||
|
||||
struct irs_gr *
|
||||
irs_irp_gr(struct irs_acc *this) {
|
||||
struct irs_gr *gr;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(gr = memget(sizeof *gr))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(gr, 0x0, sizeof *gr);
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(gr, sizeof *gr);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0x0, sizeof *pvt);
|
||||
pvt->girpdata = this->private;
|
||||
|
||||
gr->private = pvt;
|
||||
gr->close = gr_close;
|
||||
gr->next = gr_next;
|
||||
gr->byname = gr_byname;
|
||||
gr->bygid = gr_bygid;
|
||||
gr->rewind = gr_rewind;
|
||||
gr->list = make_group_list;
|
||||
gr->minimize = gr_minimize;
|
||||
return (gr);
|
||||
}
|
||||
|
||||
/* Methods. */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void gr_close(struct irs_gr *this)
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* Close the sub-module.
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
gr_close(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
gr_minimize(this);
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct group * gr_next(struct irs_gr *this)
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* Gets the next group out of the cached data and returns it.
|
||||
*
|
||||
*/
|
||||
|
||||
static struct group *
|
||||
gr_next(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct group *gr = &pvt->group;
|
||||
char *body;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char text[256];
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getgrent") != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
if (irp_log_errors) {
|
||||
syslog(LOG_WARNING, "getgrent failed: %s", text);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETGROUP_OK) {
|
||||
free_group(gr);
|
||||
if (irp_unmarshall_gr(gr, body) != 0) {
|
||||
gr = NULL;
|
||||
}
|
||||
} else {
|
||||
gr = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (gr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct group * gr_byname(struct irs_gr *this, const char *name)
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* Gets a group by name from irpd and returns it.
|
||||
*
|
||||
*/
|
||||
|
||||
static struct group *
|
||||
gr_byname(struct irs_gr *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct group *gr = &pvt->group;
|
||||
char *body;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char text[256];
|
||||
|
||||
|
||||
if (gr->gr_name != NULL && strcmp(name, gr->gr_name) == 0) {
|
||||
return (gr);
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getgrnam %s", name) != 0)
|
||||
return (NULL);
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETGROUP_OK) {
|
||||
free_group(gr);
|
||||
if (irp_unmarshall_gr(gr, body) != 0) {
|
||||
gr = NULL;
|
||||
}
|
||||
} else {
|
||||
gr = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (gr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct group * gr_bygid(struct irs_gr *this, gid_t gid)
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* Gets a group by gid from irpd and returns it.
|
||||
*
|
||||
*/
|
||||
|
||||
static struct group *
|
||||
gr_bygid(struct irs_gr *this, gid_t gid) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct group *gr = &pvt->group;
|
||||
char *body;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char text[256];
|
||||
|
||||
if (gr->gr_name != NULL && (gid_t)gr->gr_gid == gid) {
|
||||
return (gr);
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getgrgid %d", gid) != 0)
|
||||
return (NULL);
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETGROUP_OK) {
|
||||
free_group(gr);
|
||||
if (irp_unmarshall_gr(gr, body) != 0) {
|
||||
gr = NULL;
|
||||
}
|
||||
} else {
|
||||
gr = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (gr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void gr_rewind(struct irs_gr *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
gr_rewind(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char text[256];
|
||||
int code;
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "setgrent") != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
|
||||
if (code != IRPD_GETGROUP_SETOK) {
|
||||
if (irp_log_errors) {
|
||||
syslog(LOG_WARNING, "setgrent failed: %s", text);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void gr_minimize(struct irs_gr *this)
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* Frees up cached data and disconnects(if necessary) from the remote.
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
gr_minimize(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
free_group(&pvt->group);
|
||||
irs_irp_disconnect(pvt->girpdata);
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* static void free_group(struct group *gr);
|
||||
*
|
||||
* Deallocate all the memory irp_unmarshall_gr allocated.
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
free_group(struct group *gr) {
|
||||
char **p;
|
||||
|
||||
if (gr == NULL)
|
||||
return;
|
||||
|
||||
if (gr->gr_name != NULL)
|
||||
free(gr->gr_name);
|
||||
|
||||
if (gr->gr_passwd != NULL)
|
||||
free(gr->gr_passwd);
|
||||
|
||||
for (p = gr->gr_mem ; p != NULL && *p != NULL ; p++)
|
||||
free(*p);
|
||||
|
||||
if (gr->gr_mem)
|
||||
free(gr->gr_mem);
|
||||
|
||||
if (p != NULL)
|
||||
free(p);
|
||||
}
|
||||
|
||||
|
||||
#endif /* WANT_IRS_GR */
|
||||
@@ -0,0 +1,429 @@
|
||||
/*
|
||||
* Portions Copyright (c) 1996,1998 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: irp_ho.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Imports. */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <syslog.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <irp.h>
|
||||
#include <isc/irpmarshall.h>
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "dns_p.h"
|
||||
#include "irp_p.h"
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
/* Definitions. */
|
||||
|
||||
#define MAXALIASES 35
|
||||
#define MAXADDRS 35
|
||||
#define Max(a,b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
|
||||
struct pvt {
|
||||
struct irp_p *girpdata;
|
||||
int warned;
|
||||
struct hostent host;
|
||||
};
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static void ho_close(struct irs_ho *this);
|
||||
static struct hostent * ho_byname(struct irs_ho *this, const char *name);
|
||||
static struct hostent * ho_byname2(struct irs_ho *this, const char *name,
|
||||
int af);
|
||||
static struct hostent * ho_byaddr(struct irs_ho *this, const void *addr,
|
||||
int len, int af);
|
||||
static struct hostent * ho_next(struct irs_ho *this);
|
||||
static void ho_rewind(struct irs_ho *this);
|
||||
static void ho_minimize(struct irs_ho *this);
|
||||
|
||||
static void free_host(struct hostent *ho);
|
||||
static struct addrinfo * ho_addrinfo(struct irs_ho *this, const char *name,
|
||||
const struct addrinfo *pai);
|
||||
|
||||
/* Public. */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct irs_ho * irs_irp_ho(struct irs_acc *this)
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* Initializes the irp_ho module.
|
||||
*
|
||||
*/
|
||||
|
||||
struct irs_ho *
|
||||
irs_irp_ho(struct irs_acc *this) {
|
||||
struct irs_ho *ho;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(ho = memget(sizeof *ho))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(ho, 0x0, sizeof *ho);
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(ho, sizeof *ho);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->girpdata = this->private;
|
||||
|
||||
ho->private = pvt;
|
||||
ho->close = ho_close;
|
||||
ho->byname = ho_byname;
|
||||
ho->byname2 = ho_byname2;
|
||||
ho->byaddr = ho_byaddr;
|
||||
ho->next = ho_next;
|
||||
ho->rewind = ho_rewind;
|
||||
ho->minimize = ho_minimize;
|
||||
ho->addrinfo = ho_addrinfo;
|
||||
|
||||
return (ho);
|
||||
}
|
||||
|
||||
/* Methods. */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void ho_close(struct irs_ho *this)
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* Closes down the module.
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
ho_close(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
ho_minimize(this);
|
||||
|
||||
free_host(&pvt->host);
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct hostent * ho_byname(struct irs_ho *this, const char *name)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct hostent *
|
||||
ho_byname(struct irs_ho *this, const char *name) {
|
||||
return (ho_byname2(this, name, AF_INET));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct hostent * ho_byname2(struct irs_ho *this, const char *name, int af)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct hostent *
|
||||
ho_byname2(struct irs_ho *this, const char *name, int af) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct hostent *ho = &pvt->host;
|
||||
char *body = NULL;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char text[256];
|
||||
|
||||
if (ho->h_name != NULL &&
|
||||
strcmp(name, ho->h_name) == 0 &&
|
||||
af == ho->h_addrtype) {
|
||||
return (ho);
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "gethostbyname2 %s %s",
|
||||
name, ADDR_T_STR(af)) != 0)
|
||||
return (NULL);
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETHOST_OK) {
|
||||
free_host(ho);
|
||||
if (irp_unmarshall_ho(ho, body) != 0) {
|
||||
ho = NULL;
|
||||
}
|
||||
} else {
|
||||
ho = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (ho);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct hostent * ho_byaddr(struct irs_ho *this, const void *addr,
|
||||
* int len, int af)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct hostent *
|
||||
ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct hostent *ho = &pvt->host;
|
||||
char *body = NULL;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char **p;
|
||||
char paddr[MAXPADDRSIZE];
|
||||
char text[256];
|
||||
|
||||
if (ho->h_name != NULL &&
|
||||
af == ho->h_addrtype &&
|
||||
len == ho->h_length) {
|
||||
for (p = ho->h_addr_list ; *p != NULL ; p++) {
|
||||
if (memcmp(*p, addr, len) == 0)
|
||||
return (ho);
|
||||
}
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (inet_ntop(af, addr, paddr, sizeof paddr) == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "gethostbyaddr %s %s",
|
||||
paddr, ADDR_T_STR(af)) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETHOST_OK) {
|
||||
free_host(ho);
|
||||
if (irp_unmarshall_ho(ho, body) != 0) {
|
||||
ho = NULL;
|
||||
}
|
||||
} else {
|
||||
ho = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (ho);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct hostent * ho_next(struct irs_ho *this)
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* The implementation for gethostent(3). The first time it's
|
||||
* called all the data is pulled from the remote(i.e. what
|
||||
* the maximum number of gethostent(3) calls would return)
|
||||
* and that data is cached.
|
||||
*
|
||||
*/
|
||||
|
||||
static struct hostent *
|
||||
ho_next(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct hostent *ho = &pvt->host;
|
||||
char *body;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char text[256];
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "gethostent") != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETHOST_OK) {
|
||||
free_host(ho);
|
||||
if (irp_unmarshall_ho(ho, body) != 0) {
|
||||
ho = NULL;
|
||||
}
|
||||
} else {
|
||||
ho = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (ho);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void ho_rewind(struct irs_ho *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
ho_rewind(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char text[256];
|
||||
int code;
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "sethostent") != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
|
||||
if (code != IRPD_GETHOST_SETOK) {
|
||||
if (irp_log_errors) {
|
||||
syslog(LOG_WARNING, "sethostent failed: %s", text);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void ho_minimize(struct irs_ho *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
ho_minimize(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
free_host(&pvt->host);
|
||||
|
||||
irs_irp_disconnect(pvt->girpdata);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void free_host(struct hostent *ho)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
free_host(struct hostent *ho) {
|
||||
char **p;
|
||||
|
||||
if (ho == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ho->h_name != NULL)
|
||||
free(ho->h_name);
|
||||
|
||||
if (ho->h_aliases != NULL) {
|
||||
for (p = ho->h_aliases ; *p != NULL ; p++)
|
||||
free(*p);
|
||||
free(ho->h_aliases);
|
||||
}
|
||||
|
||||
if (ho->h_addr_list != NULL) {
|
||||
for (p = ho->h_addr_list ; *p != NULL ; p++)
|
||||
free(*p);
|
||||
free(ho->h_addr_list);
|
||||
}
|
||||
}
|
||||
|
||||
/* dummy */
|
||||
static struct addrinfo *
|
||||
ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai)
|
||||
{
|
||||
UNUSED(this);
|
||||
UNUSED(name);
|
||||
UNUSED(pai);
|
||||
return(NULL);
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 1998 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.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: irp_ng.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <irp.h>
|
||||
#include <isc/memcluster.h>
|
||||
#include <isc/irpmarshall.h>
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "irp_p.h"
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
struct pvt {
|
||||
struct irp_p *girpdata;
|
||||
int warned;
|
||||
};
|
||||
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void ng_rewind(struct irs_ng *, const char*);
|
||||
static void ng_close(struct irs_ng *);
|
||||
static int ng_next(struct irs_ng *, const char **, const char **,
|
||||
const char **);
|
||||
static int ng_test(struct irs_ng *, const char *,
|
||||
const char *, const char *,
|
||||
const char *);
|
||||
static void ng_minimize(struct irs_ng *);
|
||||
|
||||
|
||||
/* Public */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct irs_ng * irs_irp_ng(struct irs_acc *this)
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* Intialize the irp netgroup module.
|
||||
*
|
||||
*/
|
||||
|
||||
struct irs_ng *
|
||||
irs_irp_ng(struct irs_acc *this) {
|
||||
struct irs_ng *ng;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(ng = memget(sizeof *ng))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(ng, 0x5e, sizeof *ng);
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(ng, sizeof *ng);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->girpdata = this->private;
|
||||
|
||||
ng->private = pvt;
|
||||
ng->close = ng_close;
|
||||
ng->next = ng_next;
|
||||
ng->test = ng_test;
|
||||
ng->rewind = ng_rewind;
|
||||
ng->minimize = ng_minimize;
|
||||
return (ng);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void ng_close(struct irs_ng *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
ng_close(struct irs_ng *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
ng_minimize(this);
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void ng_rewind(struct irs_ng *this, const char *group)
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
ng_rewind(struct irs_ng *this, const char *group) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char text[256];
|
||||
int code;
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata,
|
||||
"setnetgrent %s", group) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
|
||||
if (code != IRPD_GETNETGR_SETOK) {
|
||||
if (irp_log_errors) {
|
||||
syslog(LOG_WARNING, "setnetgrent(%s) failed: %s",
|
||||
group, text);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* int ng_next(struct irs_ng *this, const char **host, const char **user,
|
||||
* const char **domain)
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* Get the next netgroup item from the cache.
|
||||
*
|
||||
*/
|
||||
|
||||
static int
|
||||
ng_next(struct irs_ng *this, const char **host, const char **user,
|
||||
const char **domain)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
int code;
|
||||
char *body = NULL;
|
||||
size_t bodylen;
|
||||
int rval = 0;
|
||||
char text[256];
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getnetgrent") != 0)
|
||||
return (0);
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETNETGR_OK) {
|
||||
if (irp_unmarshall_ng(host, user, domain, body) == 0) {
|
||||
rval = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (rval);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* int ng_test(struct irs_ng *this, const char *name, const char *host,
|
||||
* const char *user, const char *domain)
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* Search for a match in a netgroup.
|
||||
*
|
||||
*/
|
||||
|
||||
static int
|
||||
ng_test(struct irs_ng *this, const char *name,
|
||||
const char *host, const char *user, const char *domain)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char *body = NULL;
|
||||
size_t bodylen = 0;
|
||||
int code;
|
||||
char text[256];
|
||||
int rval = 0;
|
||||
|
||||
UNUSED(name);
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (irp_marshall_ng(host, user, domain, &body, &bodylen) != 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "innetgr %s", body) == 0) {
|
||||
memput(body, bodylen);
|
||||
|
||||
code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
|
||||
if (code == IRPD_GETNETGR_MATCHES) {
|
||||
rval = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return (rval);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void ng_minimize(struct irs_ng *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
ng_minimize(struct irs_ng *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
irs_irp_disconnect(pvt->girpdata);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Private */
|
||||
|
||||
@@ -0,0 +1,375 @@
|
||||
/*
|
||||
* Portions Copyright (c) 1996,1998 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: irp_nw.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#if 0
|
||||
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <syslog.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <irp.h>
|
||||
#include <isc/irpmarshall.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <isc/misc.h>
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "lcl_p.h"
|
||||
#include "irp_p.h"
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#define MAXALIASES 35
|
||||
#define MAXADDRSIZE 4
|
||||
|
||||
struct pvt {
|
||||
struct irp_p *girpdata;
|
||||
int warned;
|
||||
struct nwent net;
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void nw_close(struct irs_nw *);
|
||||
static struct nwent * nw_byname(struct irs_nw *, const char *, int);
|
||||
static struct nwent * nw_byaddr(struct irs_nw *, void *, int, int);
|
||||
static struct nwent * nw_next(struct irs_nw *);
|
||||
static void nw_rewind(struct irs_nw *);
|
||||
static void nw_minimize(struct irs_nw *);
|
||||
|
||||
static void free_nw(struct nwent *nw);
|
||||
|
||||
|
||||
/* Public */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct irs_nw * irs_irp_nw(struct irs_acc *this)
|
||||
*
|
||||
*/
|
||||
|
||||
struct irs_nw *
|
||||
irs_irp_nw(struct irs_acc *this) {
|
||||
struct irs_nw *nw;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
|
||||
if (!(nw = memget(sizeof *nw))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(nw, 0x0, sizeof *nw);
|
||||
pvt->girpdata = this->private;
|
||||
|
||||
nw->private = pvt;
|
||||
nw->close = nw_close;
|
||||
nw->byname = nw_byname;
|
||||
nw->byaddr = nw_byaddr;
|
||||
nw->next = nw_next;
|
||||
nw->rewind = nw_rewind;
|
||||
nw->minimize = nw_minimize;
|
||||
return (nw);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void nw_close(struct irs_nw *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
nw_close(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
nw_minimize(this);
|
||||
|
||||
free_nw(&pvt->net);
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct nwent * nw_byaddr(struct irs_nw *this, void *net,
|
||||
* int length, int type)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct nwent *
|
||||
nw_byaddr(struct irs_nw *this, void *net, int length, int type) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct nwent *nw = &pvt->net;
|
||||
char *body = NULL;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char paddr[24]; /* bigenough for ip4 w/ cidr spec. */
|
||||
char text[256];
|
||||
|
||||
if (inet_net_ntop(type, net, length, paddr, sizeof paddr) == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getnetbyaddr %s %s",
|
||||
paddr, ADDR_T_STR(type)) != 0)
|
||||
return (NULL);
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETNET_OK) {
|
||||
free_nw(nw);
|
||||
if (irp_unmarshall_nw(nw, body) != 0) {
|
||||
nw = NULL;
|
||||
}
|
||||
} else {
|
||||
nw = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (nw);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct nwent * nw_byname(struct irs_nw *this, const char *name, int type)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct nwent *
|
||||
nw_byname(struct irs_nw *this, const char *name, int type) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct nwent *nw = &pvt->net;
|
||||
char *body = NULL;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char text[256];
|
||||
|
||||
if (nw->n_name != NULL &&
|
||||
strcmp(name, nw->n_name) == 0 &&
|
||||
nw->n_addrtype == type) {
|
||||
return (nw);
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getnetbyname %s", name) != 0)
|
||||
return (NULL);
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETNET_OK) {
|
||||
free_nw(nw);
|
||||
if (irp_unmarshall_nw(nw, body) != 0) {
|
||||
nw = NULL;
|
||||
}
|
||||
} else {
|
||||
nw = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (nw);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void nw_rewind(struct irs_nw *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
nw_rewind(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char text[256];
|
||||
int code;
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "setnetent") != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
|
||||
if (code != IRPD_GETNET_SETOK) {
|
||||
if (irp_log_errors) {
|
||||
syslog(LOG_WARNING, "setnetent failed: %s", text);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct nwent * nw_next(struct irs_nw *this)
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* Prepares the cache if necessary and returns the first, or
|
||||
* next item from it.
|
||||
*/
|
||||
|
||||
static struct nwent *
|
||||
nw_next(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct nwent *nw = &pvt->net;
|
||||
char *body;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char text[256];
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getnetent") != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETNET_OK) {
|
||||
free_nw(nw);
|
||||
if (irp_unmarshall_nw(nw, body) != 0) {
|
||||
nw = NULL;
|
||||
}
|
||||
} else {
|
||||
nw = NULL;
|
||||
}
|
||||
|
||||
return (nw);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void nw_minimize(struct irs_nw *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
nw_minimize(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
irs_irp_disconnect(pvt->girpdata);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* private. */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* static void free_passwd(struct passwd *pw);
|
||||
*
|
||||
* deallocate all the memory irp_unmarshall_pw allocated.
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
free_nw(struct nwent *nw) {
|
||||
char **p;
|
||||
|
||||
if (nw == NULL)
|
||||
return;
|
||||
|
||||
if (nw->n_name != NULL)
|
||||
free(nw->n_name);
|
||||
|
||||
if (nw->n_aliases != NULL) {
|
||||
for (p = nw->n_aliases ; *p != NULL ; p++) {
|
||||
free(*p);
|
||||
}
|
||||
free(nw->n_aliases);
|
||||
}
|
||||
|
||||
if (nw->n_addr != NULL)
|
||||
free(nw->n_addr);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: irp_p.h,v 1.1 2004/04/15 16:03:29 wkornew Exp $
|
||||
*/
|
||||
|
||||
#ifndef _IRP_P_H_INCLUDED
|
||||
#define _IRP_P_H_INCLUDED
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
struct irp_p {
|
||||
char inbuffer[1024];
|
||||
int inlast; /* index of one past the last char in buffer */
|
||||
int incurr; /* index of the next char to be read from buffer */
|
||||
|
||||
int fdCxn;
|
||||
};
|
||||
|
||||
/*
|
||||
* Externs.
|
||||
*/
|
||||
|
||||
extern struct irs_acc * irs_irp_acc __P((const char *));
|
||||
extern struct irs_gr * irs_irp_gr __P((struct irs_acc *));
|
||||
extern struct irs_pw * irs_irp_pw __P((struct irs_acc *));
|
||||
extern struct irs_sv * irs_irp_sv __P((struct irs_acc *));
|
||||
extern struct irs_pr * irs_irp_pr __P((struct irs_acc *));
|
||||
extern struct irs_ho * irs_irp_ho __P((struct irs_acc *));
|
||||
extern struct irs_nw * irs_irp_nw __P((struct irs_acc *));
|
||||
extern struct irs_ng * irs_irp_ng __P((struct irs_acc *));
|
||||
|
||||
int irs_irp_connect(struct irp_p *pvt);
|
||||
int irs_irp_is_connected(struct irp_p *pvt);
|
||||
void irs_irp_disconnect(struct irp_p *pvt);
|
||||
int irs_irp_read_response(struct irp_p *pvt, char *text, size_t textlen);
|
||||
char *irs_irp_read_body(struct irp_p *pvt, size_t *size);
|
||||
int irs_irp_get_full_response(struct irp_p *pvt, int *code,
|
||||
char *text, size_t textlen,
|
||||
char **body, size_t *bodylen);
|
||||
|
||||
extern int irp_log_errors;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,353 @@
|
||||
/*
|
||||
* Portions 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: irp_pr.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* extern */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <syslog.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <netdb.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <irp.h>
|
||||
#include <isc/memcluster.h>
|
||||
#include <isc/irpmarshall.h>
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "lcl_p.h"
|
||||
#include "irp_p.h"
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
|
||||
#define MAXALIASES 35
|
||||
|
||||
/* Types */
|
||||
|
||||
struct pvt {
|
||||
struct irp_p *girpdata;
|
||||
int warned;
|
||||
struct protoent proto;
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void pr_close(struct irs_pr *);
|
||||
static struct protoent * pr_next(struct irs_pr *);
|
||||
static struct protoent * pr_byname(struct irs_pr *, const char *);
|
||||
static struct protoent * pr_bynumber(struct irs_pr *, int);
|
||||
static void pr_rewind(struct irs_pr *);
|
||||
static void pr_minimize(struct irs_pr *);
|
||||
|
||||
static void free_proto(struct protoent *pr);
|
||||
|
||||
/* Public */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct irs_pr * irs_irp_pr(struct irs_acc *this)
|
||||
*
|
||||
*/
|
||||
|
||||
struct irs_pr *
|
||||
irs_irp_pr(struct irs_acc *this) {
|
||||
struct irs_pr *pr;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(pr = memget(sizeof *pr))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pr, 0x0, sizeof *pr);
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(pr, sizeof *pr);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->girpdata = this->private;
|
||||
|
||||
pr->private = pvt;
|
||||
pr->close = pr_close;
|
||||
pr->byname = pr_byname;
|
||||
pr->bynumber = pr_bynumber;
|
||||
pr->next = pr_next;
|
||||
pr->rewind = pr_rewind;
|
||||
pr->minimize = pr_minimize;
|
||||
return (pr);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void pr_close(struct irs_pr *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
pr_close(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
pr_minimize(this);
|
||||
|
||||
free_proto(&pvt->proto);
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct protoent * pr_byname(struct irs_pr *this, const char *name)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct protoent *
|
||||
pr_byname(struct irs_pr *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct protoent *pr = &pvt->proto;
|
||||
char *body = NULL;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
int i;
|
||||
char text[256];
|
||||
|
||||
if (pr->p_name != NULL && strcmp(name, pr->p_name) == 0) {
|
||||
return (pr);
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
i = irs_irp_send_command(pvt->girpdata, "getprotobyname %s", name);
|
||||
if (i != 0)
|
||||
return (NULL);
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETPROTO_OK) {
|
||||
free_proto(pr);
|
||||
if (irp_unmarshall_pr(pr, body) != 0) {
|
||||
pr = NULL;
|
||||
}
|
||||
} else {
|
||||
pr = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (pr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct protoent * pr_bynumber(struct irs_pr *this, int proto)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct protoent *
|
||||
pr_bynumber(struct irs_pr *this, int proto) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct protoent *pr = &pvt->proto;
|
||||
char *body = NULL;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
int i;
|
||||
char text[256];
|
||||
|
||||
if (pr->p_name != NULL && proto == pr->p_proto) {
|
||||
return (pr);
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
i = irs_irp_send_command(pvt->girpdata, "getprotobynumber %d", proto);
|
||||
if (i != 0)
|
||||
return (NULL);
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETPROTO_OK) {
|
||||
free_proto(pr);
|
||||
if (irp_unmarshall_pr(pr, body) != 0) {
|
||||
pr = NULL;
|
||||
}
|
||||
} else {
|
||||
pr = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (pr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void pr_rewind(struct irs_pr *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
pr_rewind(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char text[256];
|
||||
int code;
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "setprotoent") != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
|
||||
if (code != IRPD_GETPROTO_SETOK) {
|
||||
if (irp_log_errors) {
|
||||
syslog(LOG_WARNING, "setprotoent failed: %s", text);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct protoent * pr_next(struct irs_pr *this)
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* Prepares the cache if necessary and returns the next item in it.
|
||||
*
|
||||
*/
|
||||
|
||||
static struct protoent *
|
||||
pr_next(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct protoent *pr = &pvt->proto;
|
||||
char *body;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char text[256];
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getprotoent") != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETPROTO_OK) {
|
||||
free_proto(pr);
|
||||
if (irp_unmarshall_pr(pr, body) != 0) {
|
||||
pr = NULL;
|
||||
}
|
||||
} else {
|
||||
pr = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (pr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void pr_minimize(struct irs_pr *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
pr_minimize(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
irs_irp_disconnect(pvt->girpdata);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* static void free_proto(struct protoent *pw);
|
||||
*
|
||||
* Deallocate all the memory irp_unmarshall_pr allocated.
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
free_proto(struct protoent *pr) {
|
||||
char **p;
|
||||
|
||||
if (pr == NULL)
|
||||
return;
|
||||
|
||||
if (pr->p_name != NULL)
|
||||
free(pr->p_name);
|
||||
|
||||
for (p = pr->p_aliases ; p != NULL && *p != NULL ; p++)
|
||||
free(*p);
|
||||
}
|
||||
@@ -0,0 +1,358 @@
|
||||
/*
|
||||
* Portions 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: irp_pw.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Extern */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_PW
|
||||
static int __bind_irs_pw_unneeded;
|
||||
#else
|
||||
|
||||
#include <syslog.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <db.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <utmp.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <irp.h>
|
||||
#include <isc/memcluster.h>
|
||||
#include <isc/irpmarshall.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "irp_p.h"
|
||||
|
||||
|
||||
/* Types */
|
||||
|
||||
struct pvt {
|
||||
struct irp_p *girpdata; /* global IRP data */
|
||||
int warned;
|
||||
struct passwd passwd; /* password structure */
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void pw_close(struct irs_pw *);
|
||||
static struct passwd * pw_next(struct irs_pw *);
|
||||
static struct passwd * pw_byname(struct irs_pw *, const char *);
|
||||
static struct passwd * pw_byuid(struct irs_pw *, uid_t);
|
||||
static void pw_rewind(struct irs_pw *);
|
||||
static void pw_minimize(struct irs_pw *);
|
||||
|
||||
static void free_passwd(struct passwd *pw);
|
||||
|
||||
/* Public */
|
||||
struct irs_pw *
|
||||
irs_irp_pw(struct irs_acc *this) {
|
||||
struct irs_pw *pw;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(pw = memget(sizeof *pw))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pw, 0, sizeof *pw);
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(pw, sizeof *pw);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->girpdata = this->private;
|
||||
|
||||
pw->private = pvt;
|
||||
pw->close = pw_close;
|
||||
pw->next = pw_next;
|
||||
pw->byname = pw_byname;
|
||||
pw->byuid = pw_byuid;
|
||||
pw->rewind = pw_rewind;
|
||||
pw->minimize = pw_minimize;
|
||||
|
||||
return (pw);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void pw_close(struct irs_pw *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
pw_close(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
pw_minimize(this);
|
||||
|
||||
free_passwd(&pvt->passwd);
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct passwd * pw_next(struct irs_pw *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct passwd *
|
||||
pw_next(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct passwd *pw = &pvt->passwd;
|
||||
char *body;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char text[256];
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getpwent") != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETUSER_OK) {
|
||||
free_passwd(pw);
|
||||
if (irp_unmarshall_pw(pw, body) != 0) {
|
||||
pw = NULL;
|
||||
}
|
||||
} else {
|
||||
pw = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (pw);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct passwd * pw_byname(struct irs_pw *this, const char *name)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct passwd *
|
||||
pw_byname(struct irs_pw *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct passwd *pw = &pvt->passwd;
|
||||
char *body = NULL;
|
||||
char text[256];
|
||||
size_t bodylen;
|
||||
int code;
|
||||
|
||||
if (pw->pw_name != NULL && strcmp(name, pw->pw_name) == 0) {
|
||||
return (pw);
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getpwnam %s", name) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETUSER_OK) {
|
||||
free_passwd(pw);
|
||||
if (irp_unmarshall_pw(pw, body) != 0) {
|
||||
pw = NULL;
|
||||
}
|
||||
} else {
|
||||
pw = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (pw);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct passwd * pw_byuid(struct irs_pw *this, uid_t uid)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct passwd *
|
||||
pw_byuid(struct irs_pw *this, uid_t uid) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char *body;
|
||||
char text[256];
|
||||
size_t bodylen;
|
||||
int code;
|
||||
struct passwd *pw = &pvt->passwd;
|
||||
|
||||
if (pw->pw_name != NULL && pw->pw_uid == uid) {
|
||||
return (pw);
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getpwuid %d", uid) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETUSER_OK) {
|
||||
free_passwd(pw);
|
||||
if (irp_unmarshall_pw(pw, body) != 0) {
|
||||
pw = NULL;
|
||||
}
|
||||
} else {
|
||||
pw = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (pw);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void pw_rewind(struct irs_pw *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
pw_rewind(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char text[256];
|
||||
int code;
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "setpwent") != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
|
||||
if (code != IRPD_GETUSER_SETOK) {
|
||||
if (irp_log_errors) {
|
||||
syslog(LOG_WARNING, "setpwent failed: %s", text);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* void pw_minimize(struct irs_pw *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
pw_minimize(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
irs_irp_disconnect(pvt->girpdata);
|
||||
}
|
||||
|
||||
|
||||
/* Private. */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* static void free_passwd(struct passwd *pw);
|
||||
*
|
||||
* Deallocate all the memory irp_unmarshall_pw allocated.
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
free_passwd(struct passwd *pw) {
|
||||
if (pw == NULL)
|
||||
return;
|
||||
|
||||
if (pw->pw_name != NULL)
|
||||
free(pw->pw_name);
|
||||
|
||||
if (pw->pw_passwd != NULL)
|
||||
free(pw->pw_passwd);
|
||||
|
||||
#ifdef HAVE_PW_CLASS
|
||||
if (pw->pw_class != NULL)
|
||||
free(pw->pw_class);
|
||||
#endif
|
||||
|
||||
if (pw->pw_gecos != NULL)
|
||||
free(pw->pw_gecos);
|
||||
|
||||
if (pw->pw_dir != NULL)
|
||||
free(pw->pw_dir);
|
||||
|
||||
if (pw->pw_shell != NULL)
|
||||
free(pw->pw_shell);
|
||||
}
|
||||
|
||||
#endif /* WANT_IRS_PW */
|
||||
@@ -0,0 +1,369 @@
|
||||
/*
|
||||
* Portions Copyright (c) 1996,1998 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: irp_sv.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* extern */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <syslog.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#ifdef IRS_LCL_SV_DB
|
||||
#include <db.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <irp.h>
|
||||
#include <isc/irpmarshall.h>
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "lcl_p.h"
|
||||
#include "irp_p.h"
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
/* Types */
|
||||
|
||||
struct pvt {
|
||||
struct irp_p *girpdata;
|
||||
int warned;
|
||||
struct servent service;
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void sv_close(struct irs_sv*);
|
||||
static struct servent * sv_next(struct irs_sv *);
|
||||
static struct servent * sv_byname(struct irs_sv *, const char *,
|
||||
const char *);
|
||||
static struct servent * sv_byport(struct irs_sv *, int, const char *);
|
||||
static void sv_rewind(struct irs_sv *);
|
||||
static void sv_minimize(struct irs_sv *);
|
||||
|
||||
static void free_service(struct servent *sv);
|
||||
|
||||
|
||||
|
||||
/* Public */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct irs_sv * irs_irp_sv(struct irs_acc *this)
|
||||
*
|
||||
*/
|
||||
|
||||
struct irs_sv *
|
||||
irs_irp_sv(struct irs_acc *this) {
|
||||
struct irs_sv *sv;
|
||||
struct pvt *pvt;
|
||||
|
||||
if ((sv = memget(sizeof *sv)) == NULL) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(sv, 0x0, sizeof *sv);
|
||||
|
||||
if ((pvt = memget(sizeof *pvt)) == NULL) {
|
||||
memput(sv, sizeof *sv);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->girpdata = this->private;
|
||||
|
||||
sv->private = pvt;
|
||||
sv->close = sv_close;
|
||||
sv->next = sv_next;
|
||||
sv->byname = sv_byname;
|
||||
sv->byport = sv_byport;
|
||||
sv->rewind = sv_rewind;
|
||||
sv->minimize = sv_minimize;
|
||||
|
||||
return (sv);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void sv_close(struct irs_sv *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
sv_close(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
sv_minimize(this);
|
||||
|
||||
free_service(&pvt->service);
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct servent * sv_next(struct irs_sv *this)
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* Fills the cache if necessary and returns the next item from it.
|
||||
*
|
||||
*/
|
||||
|
||||
static struct servent *
|
||||
sv_next(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct servent *sv = &pvt->service;
|
||||
char *body;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char text[256];
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getservent") != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETSERVICE_OK) {
|
||||
free_service(sv);
|
||||
if (irp_unmarshall_sv(sv, body) != 0) {
|
||||
sv = NULL;
|
||||
}
|
||||
} else {
|
||||
sv = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (sv);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct servent * sv_byname(struct irs_sv *this, const char *name,
|
||||
* const char *proto)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct servent *
|
||||
sv_byname(struct irs_sv *this, const char *name, const char *proto) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct servent *sv = &pvt->service;
|
||||
char *body;
|
||||
char text[256];
|
||||
size_t bodylen;
|
||||
int code;
|
||||
|
||||
if (sv->s_name != NULL &&
|
||||
strcmp(name, sv->s_name) == 0 &&
|
||||
strcasecmp(proto, sv->s_proto) == 0) {
|
||||
return (sv);
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getservbyname %s %s",
|
||||
name, proto) != 0)
|
||||
return (NULL);
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETSERVICE_OK) {
|
||||
free_service(sv);
|
||||
if (irp_unmarshall_sv(sv, body) != 0) {
|
||||
sv = NULL;
|
||||
}
|
||||
} else {
|
||||
sv = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (sv);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct servent * sv_byport(struct irs_sv *this, int port,
|
||||
* const char *proto)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct servent *
|
||||
sv_byport(struct irs_sv *this, int port, const char *proto) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct servent *sv = &pvt->service;
|
||||
char *body;
|
||||
size_t bodylen;
|
||||
char text[256];
|
||||
int code;
|
||||
|
||||
if (sv->s_name != NULL &&
|
||||
port == sv->s_port &&
|
||||
strcasecmp(proto, sv->s_proto) == 0) {
|
||||
return (sv);
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getservbyport %d %s",
|
||||
ntohs((short)port), proto) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETSERVICE_OK) {
|
||||
free_service(sv);
|
||||
if (irp_unmarshall_sv(sv, body) != 0) {
|
||||
sv = NULL;
|
||||
}
|
||||
} else {
|
||||
sv = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (sv);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void sv_rewind(struct irs_sv *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
sv_rewind(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char text[256];
|
||||
int code;
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "setservent") != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
|
||||
if (code != IRPD_GETSERVICE_SETOK) {
|
||||
if (irp_log_errors) {
|
||||
syslog(LOG_WARNING, "setservent failed: %s", text);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void sv_minimize(struct irs_sv *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
sv_minimize(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
irs_irp_disconnect(pvt->girpdata);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
free_service(struct servent *sv) {
|
||||
char **p;
|
||||
|
||||
if (sv == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sv->s_name != NULL) {
|
||||
free(sv->s_name);
|
||||
}
|
||||
|
||||
for (p = sv->s_aliases ; p != NULL && *p != NULL ; p++) {
|
||||
free(*p);
|
||||
}
|
||||
|
||||
if (sv->s_proto != NULL) {
|
||||
free(sv->s_proto);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: irs_data.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef __BIND_NOSTATIC
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#ifdef DO_PTHREADS
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include <irs.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_data.h"
|
||||
#undef _res
|
||||
#undef h_errno
|
||||
|
||||
extern struct __res_state _res;
|
||||
extern int h_errno;
|
||||
|
||||
#ifdef DO_PTHREADS
|
||||
static pthread_key_t key;
|
||||
static int once = 0;
|
||||
#else
|
||||
static struct net_data *net_data;
|
||||
#endif
|
||||
|
||||
void
|
||||
irs_destroy(void) {
|
||||
#ifndef DO_PTHREADS
|
||||
if (net_data != NULL)
|
||||
net_data_destroy(net_data);
|
||||
net_data = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
net_data_destroy(void *p) {
|
||||
struct net_data *net_data = p;
|
||||
|
||||
res_ndestroy(net_data->res);
|
||||
if (net_data->gr != NULL) {
|
||||
(*net_data->gr->close)(net_data->gr);
|
||||
net_data->gr = NULL;
|
||||
}
|
||||
if (net_data->pw != NULL) {
|
||||
(*net_data->pw->close)(net_data->pw);
|
||||
net_data->pw = NULL;
|
||||
}
|
||||
if (net_data->sv != NULL) {
|
||||
(*net_data->sv->close)(net_data->sv);
|
||||
net_data->sv = NULL;
|
||||
}
|
||||
if (net_data->pr != NULL) {
|
||||
(*net_data->pr->close)(net_data->pr);
|
||||
net_data->pr = NULL;
|
||||
}
|
||||
if (net_data->ho != NULL) {
|
||||
(*net_data->ho->close)(net_data->ho);
|
||||
net_data->ho = NULL;
|
||||
}
|
||||
if (net_data->nw != NULL) {
|
||||
(*net_data->nw->close)(net_data->nw);
|
||||
net_data->nw = NULL;
|
||||
}
|
||||
if (net_data->ng != NULL) {
|
||||
(*net_data->ng->close)(net_data->ng);
|
||||
net_data->ng = NULL;
|
||||
}
|
||||
if (net_data->ho_data != NULL) {
|
||||
free(net_data->ho_data);
|
||||
net_data->ho_data = NULL;
|
||||
}
|
||||
if (net_data->nw_data != NULL) {
|
||||
free(net_data->nw_data);
|
||||
net_data->nw_data = NULL;
|
||||
}
|
||||
|
||||
(*net_data->irs->close)(net_data->irs);
|
||||
memput(net_data, sizeof *net_data);
|
||||
}
|
||||
|
||||
/* applications that need a specific config file other than
|
||||
* _PATH_IRS_CONF should call net_data_init directly rather than letting
|
||||
* the various wrapper functions make the first call. - brister
|
||||
*/
|
||||
|
||||
struct net_data *
|
||||
net_data_init(const char *conf_file) {
|
||||
#ifdef DO_PTHREADS
|
||||
static pthread_mutex_t keylock;
|
||||
struct net_data *net_data;
|
||||
|
||||
if (!once) {
|
||||
// OpenBeOS compatibility
|
||||
keylock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
pthread_mutex_lock(&keylock);
|
||||
if (!once++)
|
||||
key = tls_allocate();
|
||||
pthread_mutex_unlock(&keylock);
|
||||
}
|
||||
net_data = tls_get(key);
|
||||
#endif
|
||||
if (net_data == NULL) {
|
||||
net_data = net_data_create(conf_file);
|
||||
if (net_data == NULL)
|
||||
return (NULL);
|
||||
#ifdef DO_PTHREADS
|
||||
on_exit_thread(net_data_destroy, net_data);
|
||||
tls_set(key, net_data);
|
||||
#endif
|
||||
}
|
||||
|
||||
return (net_data);
|
||||
}
|
||||
|
||||
struct net_data *
|
||||
net_data_create(const char *conf_file) {
|
||||
struct net_data *net_data;
|
||||
|
||||
net_data = memget(sizeof (struct net_data));
|
||||
if (net_data == NULL)
|
||||
return (NULL);
|
||||
memset(net_data, 0, sizeof (struct net_data));
|
||||
|
||||
if ((net_data->irs = irs_gen_acc("", conf_file)) == NULL) {
|
||||
memput(net_data, sizeof (struct net_data));
|
||||
return (NULL);
|
||||
}
|
||||
#ifndef DO_PTHREADS
|
||||
(*net_data->irs->res_set)(net_data->irs, &_res, NULL);
|
||||
#endif
|
||||
|
||||
net_data->res = (*net_data->irs->res_get)(net_data->irs);
|
||||
if (net_data->res == NULL) {
|
||||
(*net_data->irs->close)(net_data->irs);
|
||||
memput(net_data, sizeof (struct net_data));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if ((net_data->res->options & RES_INIT) == 0 &&
|
||||
res_ninit(net_data->res) == -1) {
|
||||
(*net_data->irs->close)(net_data->irs);
|
||||
memput(net_data, sizeof (struct net_data));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (net_data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
net_data_minimize(struct net_data *net_data) {
|
||||
res_nclose(net_data->res);
|
||||
}
|
||||
|
||||
#ifdef _REENTRANT
|
||||
struct __res_state *
|
||||
__res_state(void) {
|
||||
/* NULL param here means use the default config file. */
|
||||
struct net_data *net_data = net_data_init(NULL);
|
||||
if (net_data && net_data->res)
|
||||
return (net_data->res);
|
||||
|
||||
return (&_res);
|
||||
}
|
||||
#endif
|
||||
|
||||
int *
|
||||
__h_errno(void) {
|
||||
/* NULL param here means use the default config file. */
|
||||
struct net_data *net_data = net_data_init(NULL);
|
||||
if (net_data && net_data->res)
|
||||
return (&net_data->res->res_h_errno);
|
||||
return (&h_errno);
|
||||
}
|
||||
|
||||
void
|
||||
__h_errno_set(struct __res_state *res, int err) {
|
||||
|
||||
h_errno = res->res_h_errno = err;
|
||||
}
|
||||
|
||||
#endif /*__BIND_NOSTATIC*/
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: irs_data.h,v 1.1 2004/04/15 16:03:29 wkornew Exp $
|
||||
*/
|
||||
|
||||
#ifndef __BIND_NOSTATIC
|
||||
|
||||
#define net_data_init __net_data_init
|
||||
|
||||
struct net_data {
|
||||
struct irs_acc * irs;
|
||||
|
||||
struct irs_gr * gr;
|
||||
struct irs_pw * pw;
|
||||
struct irs_sv * sv;
|
||||
struct irs_pr * pr;
|
||||
struct irs_ho * ho;
|
||||
struct irs_nw * nw;
|
||||
struct irs_ng * ng;
|
||||
|
||||
struct group * gr_last;
|
||||
struct passwd * pw_last;
|
||||
struct servent * sv_last;
|
||||
struct protoent * pr_last;
|
||||
struct netent * nw_last; /* should have been ne_last */
|
||||
struct nwent * nww_last;
|
||||
struct hostent * ho_last;
|
||||
|
||||
unsigned int gr_stayopen :1;
|
||||
unsigned int pw_stayopen :1;
|
||||
unsigned int sv_stayopen :1;
|
||||
unsigned int pr_stayopen :1;
|
||||
unsigned int ho_stayopen :1;
|
||||
unsigned int nw_stayopen :1;
|
||||
|
||||
void * nw_data;
|
||||
void * ho_data;
|
||||
|
||||
struct __res_state * res; /* for gethostent.c */
|
||||
|
||||
};
|
||||
|
||||
extern struct net_data * net_data_init(const char *conf_file);
|
||||
extern void net_data_minimize(struct net_data *);
|
||||
|
||||
#endif /*__BIND_NOSTATIC*/
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: irs_p.h,v 1.1 2004/04/15 16:03:29 wkornew Exp $
|
||||
*/
|
||||
|
||||
#ifndef _IRS_P_H_INCLUDED
|
||||
#define _IRS_P_H_INCLUDED
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "pathnames.h"
|
||||
|
||||
#define IRS_SV_MAXALIASES 35
|
||||
|
||||
struct lcl_sv {
|
||||
FILE * fp;
|
||||
char line[BUFSIZ+1];
|
||||
struct servent serv;
|
||||
char * serv_aliases[IRS_SV_MAXALIASES];
|
||||
};
|
||||
|
||||
#define irs_nul_ng __irs_nul_ng
|
||||
#define map_v4v6_address __map_v4v6_address
|
||||
#define make_group_list __make_group_list
|
||||
#define irs_lclsv_fnxt __irs_lclsv_fnxt
|
||||
|
||||
extern void map_v4v6_address(const char *src, char *dst);
|
||||
extern int make_group_list(struct irs_gr *, const char *,
|
||||
gid_t, gid_t *, int *);
|
||||
extern struct irs_ng * irs_nul_ng(struct irs_acc *);
|
||||
extern struct servent * irs_lclsv_fnxt(struct lcl_sv *);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 1996-1999 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.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: lcl.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "lcl_p.h"
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static void lcl_close(struct irs_acc *);
|
||||
static struct __res_state * lcl_res_get(struct irs_acc *);
|
||||
static void lcl_res_set(struct irs_acc *, struct __res_state *,
|
||||
void (*)(void *));
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_acc *
|
||||
irs_lcl_acc(const char *options) {
|
||||
struct irs_acc *acc;
|
||||
struct lcl_p *lcl;
|
||||
|
||||
UNUSED(options);
|
||||
|
||||
if (!(acc = memget(sizeof *acc))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(acc, 0x5e, sizeof *acc);
|
||||
if (!(lcl = memget(sizeof *lcl))) {
|
||||
errno = ENOMEM;
|
||||
free(acc);
|
||||
return (NULL);
|
||||
}
|
||||
memset(lcl, 0x5e, sizeof *lcl);
|
||||
lcl->res = NULL;
|
||||
lcl->free_res = NULL;
|
||||
acc->private = lcl;
|
||||
#ifdef WANT_IRS_GR
|
||||
acc->gr_map = irs_lcl_gr;
|
||||
#else
|
||||
acc->gr_map = NULL;
|
||||
#endif
|
||||
#ifdef WANT_IRS_PW
|
||||
acc->pw_map = irs_lcl_pw;
|
||||
#else
|
||||
acc->pw_map = NULL;
|
||||
#endif
|
||||
acc->sv_map = irs_lcl_sv;
|
||||
acc->pr_map = irs_lcl_pr;
|
||||
acc->ho_map = irs_lcl_ho;
|
||||
acc->nw_map = irs_lcl_nw;
|
||||
acc->ng_map = irs_lcl_ng;
|
||||
acc->res_get = lcl_res_get;
|
||||
acc->res_set = lcl_res_set;
|
||||
acc->close = lcl_close;
|
||||
return (acc);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
static struct __res_state *
|
||||
lcl_res_get(struct irs_acc *this) {
|
||||
struct lcl_p *lcl = (struct lcl_p *)this->private;
|
||||
|
||||
if (lcl->res == NULL) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (res == NULL)
|
||||
return (NULL);
|
||||
memset(res, 0, sizeof *res);
|
||||
lcl_res_set(this, res, free);
|
||||
}
|
||||
|
||||
if ((lcl->res->options & RES_INIT) == 0 &&
|
||||
res_ninit(lcl->res) < 0)
|
||||
return (NULL);
|
||||
|
||||
return (lcl->res);
|
||||
}
|
||||
|
||||
static void
|
||||
lcl_res_set(struct irs_acc *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct lcl_p *lcl = (struct lcl_p *)this->private;
|
||||
|
||||
if (lcl->res && lcl->free_res) {
|
||||
res_nclose(lcl->res);
|
||||
(*lcl->free_res)(lcl->res);
|
||||
}
|
||||
|
||||
lcl->res = res;
|
||||
lcl->free_res = free_res;
|
||||
}
|
||||
|
||||
static void
|
||||
lcl_close(struct irs_acc *this) {
|
||||
struct lcl_p *lcl = (struct lcl_p *)this->private;
|
||||
|
||||
if (lcl) {
|
||||
if (lcl->free_res)
|
||||
(*lcl->free_res)(lcl->res);
|
||||
memput(lcl, sizeof *lcl);
|
||||
}
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
@@ -0,0 +1,354 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1993, 1995
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1996-1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: lcl_gr.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
/* from getgrent.c 8.2 (Berkeley) 3/21/94"; */
|
||||
/* from BSDI Id: getgrent.c,v 2.8 1996/05/28 18:15:14 bostic Exp $ */
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* extern */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_PW
|
||||
static int __bind_irs_gr_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "lcl_p.h"
|
||||
#include "irp_p.h"
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
|
||||
/* Types. */
|
||||
|
||||
struct pvt {
|
||||
FILE * fp;
|
||||
/*
|
||||
* Need space to store the entries read from the group file.
|
||||
* The members list also needs space per member, and the
|
||||
* strings making up the user names must be allocated
|
||||
* somewhere. Rather than doing lots of small allocations,
|
||||
* we keep one buffer and resize it as needed.
|
||||
*/
|
||||
struct group group;
|
||||
size_t nmemb; /* Malloc'd max index of gr_mem[]. */
|
||||
char * membuf;
|
||||
size_t membufsize;
|
||||
};
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static void gr_close(struct irs_gr *);
|
||||
static struct group * gr_next(struct irs_gr *);
|
||||
static struct group * gr_byname(struct irs_gr *, const char *);
|
||||
static struct group * gr_bygid(struct irs_gr *, gid_t);
|
||||
static void gr_rewind(struct irs_gr *);
|
||||
static void gr_minimize(struct irs_gr *);
|
||||
|
||||
static int grstart(struct pvt *);
|
||||
static char * grnext(struct pvt *);
|
||||
static struct group * grscan(struct irs_gr *, int, gid_t, const char *);
|
||||
|
||||
/* Portability. */
|
||||
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0
|
||||
#endif
|
||||
|
||||
/* Public. */
|
||||
|
||||
struct irs_gr *
|
||||
irs_lcl_gr(struct irs_acc *this) {
|
||||
struct irs_gr *gr;
|
||||
struct pvt *pvt;
|
||||
|
||||
UNUSED(this);
|
||||
|
||||
if (!(gr = memget(sizeof *gr))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(gr, 0x5e, sizeof *gr);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(gr, sizeof *gr);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
gr->private = pvt;
|
||||
gr->close = gr_close;
|
||||
gr->next = gr_next;
|
||||
gr->byname = gr_byname;
|
||||
gr->bygid = gr_bygid;
|
||||
gr->rewind = gr_rewind;
|
||||
gr->list = make_group_list;
|
||||
gr->minimize = gr_minimize;
|
||||
gr->res_get = NULL;
|
||||
gr->res_set = NULL;
|
||||
return (gr);
|
||||
}
|
||||
|
||||
/* Methods. */
|
||||
|
||||
static void
|
||||
gr_close(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->fp)
|
||||
(void)fclose(pvt->fp);
|
||||
if (pvt->group.gr_mem)
|
||||
free(pvt->group.gr_mem);
|
||||
if (pvt->membuf)
|
||||
free(pvt->membuf);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_next(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->fp && !grstart(pvt))
|
||||
return (NULL);
|
||||
return (grscan(this, 0, 0, NULL));
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_byname(struct irs_gr *this, const char *name) {
|
||||
if (!grstart((struct pvt *)this->private))
|
||||
return (NULL);
|
||||
return (grscan(this, 1, 0, name));
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_bygid(struct irs_gr *this, gid_t gid) {
|
||||
if (!grstart((struct pvt *)this->private))
|
||||
return (NULL);
|
||||
return (grscan(this, 1, gid, NULL));
|
||||
}
|
||||
|
||||
static void
|
||||
gr_rewind(struct irs_gr *this) {
|
||||
(void) grstart((struct pvt *)this->private);
|
||||
}
|
||||
|
||||
static void
|
||||
gr_minimize(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->fp != NULL) {
|
||||
(void)fclose(pvt->fp);
|
||||
pvt->fp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
static int
|
||||
grstart(struct pvt *pvt) {
|
||||
if (pvt->fp) {
|
||||
if (fseek(pvt->fp, 0L, SEEK_SET) == 0)
|
||||
return (1);
|
||||
(void)fclose(pvt->fp);
|
||||
}
|
||||
if (!(pvt->fp = fopen(_PATH_GROUP, "r")))
|
||||
return (0);
|
||||
if (fcntl(fileno(pvt->fp), F_SETFD, 1) < 0) {
|
||||
fclose(pvt->fp);
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
#define INITIAL_NMEMB 30 /* about 120 bytes */
|
||||
#define INITIAL_BUFSIZ (INITIAL_NMEMB * 8) /* about 240 bytes */
|
||||
|
||||
static char *
|
||||
grnext(struct pvt *pvt) {
|
||||
char *w, *e;
|
||||
int ch;
|
||||
|
||||
/* Make sure we have a buffer. */
|
||||
if (pvt->membuf == NULL) {
|
||||
pvt->membuf = malloc(INITIAL_BUFSIZ);
|
||||
if (pvt->membuf == NULL) {
|
||||
enomem:
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
pvt->membufsize = INITIAL_BUFSIZ;
|
||||
}
|
||||
|
||||
/* Read until EOF or EOL. */
|
||||
w = pvt->membuf;
|
||||
e = pvt->membuf + pvt->membufsize;
|
||||
while ((ch = fgetc(pvt->fp)) != EOF && ch != '\n') {
|
||||
/* Make sure we have room for this character and a \0. */
|
||||
if (w + 1 == e) {
|
||||
size_t o = w - pvt->membuf;
|
||||
size_t n = pvt->membufsize * 2;
|
||||
char *t = realloc(pvt->membuf, n);
|
||||
|
||||
if (t == NULL)
|
||||
goto enomem;
|
||||
pvt->membuf = t;
|
||||
pvt->membufsize = n;
|
||||
w = pvt->membuf + o;
|
||||
e = pvt->membuf + pvt->membufsize;
|
||||
}
|
||||
/* Store it. */
|
||||
*w++ = (char)ch;
|
||||
}
|
||||
|
||||
/* Hitting EOF on the first character really does mean EOF. */
|
||||
if (w == pvt->membuf && ch == EOF) {
|
||||
errno = ENOENT;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Last line of /etc/group need not end with \n; we don't care. */
|
||||
*w = '\0';
|
||||
return (pvt->membuf);
|
||||
}
|
||||
|
||||
static struct group *
|
||||
grscan(struct irs_gr *this, int search, gid_t gid, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
size_t n;
|
||||
char *bp, **m, *p;
|
||||
|
||||
/* Read lines until we find one that matches our search criteria. */
|
||||
for (;;) {
|
||||
if ((bp = grnext(pvt)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
/* Optimize the usual case of searching for a name. */
|
||||
pvt->group.gr_name = strsep(&bp, ":");
|
||||
if (search && name != NULL &&
|
||||
strcmp(pvt->group.gr_name, name) != 0)
|
||||
continue;
|
||||
if (bp == NULL || *bp == '\0')
|
||||
goto corrupt;
|
||||
|
||||
/* Skip past the password field. */
|
||||
pvt->group.gr_passwd = strsep(&bp, ":");
|
||||
if (bp == NULL || *bp == '\0')
|
||||
goto corrupt;
|
||||
|
||||
/* Checking for a gid. */
|
||||
if ((p = strsep(&bp, ":")) == NULL)
|
||||
continue;
|
||||
/*
|
||||
* Unlike the tests above, the test below is supposed to be
|
||||
* testing 'p' and not 'bp', in case you think it's a typo.
|
||||
*/
|
||||
if (p == NULL || *p == '\0') {
|
||||
corrupt:
|
||||
/* warning: corrupted %s file!", _PATH_GROUP */
|
||||
continue;
|
||||
}
|
||||
pvt->group.gr_gid = atoi(p);
|
||||
if (search && name == NULL && (gid_t)pvt->group.gr_gid != gid)
|
||||
continue;
|
||||
|
||||
/* We want this record. */
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Count commas to find out how many members there might be.
|
||||
* Note that commas separate, so if there is one comma there
|
||||
* can be two members (group:*:id:user1,user2). Add another
|
||||
* to account for the NULL terminator. As above, allocate
|
||||
* largest of INITIAL_NMEMB, or 2*n.
|
||||
*/
|
||||
n = 1;
|
||||
if (bp != NULL)
|
||||
for (n = 2, p = bp; (p = strpbrk(p, ", ")) != NULL; ++n)
|
||||
p += strspn(p, ", ");
|
||||
if (n > pvt->nmemb || pvt->group.gr_mem == NULL) {
|
||||
if ((n *= 2) < INITIAL_NMEMB)
|
||||
n = INITIAL_NMEMB;
|
||||
if ((m = realloc(pvt->group.gr_mem, n * sizeof *m)) == NULL)
|
||||
return (NULL);
|
||||
pvt->group.gr_mem = m;
|
||||
pvt->nmemb = n;
|
||||
}
|
||||
|
||||
/* Set the name pointers. */
|
||||
for (m = pvt->group.gr_mem; (p = strsep(&bp, ", ")) != NULL;)
|
||||
if (p[0] != '\0')
|
||||
*m++ = p;
|
||||
*m = NULL;
|
||||
|
||||
return (&pvt->group);
|
||||
}
|
||||
|
||||
#endif /* WANT_IRS_GR */
|
||||
@@ -0,0 +1,576 @@
|
||||
/*
|
||||
* Copyright (c) 1985, 1988, 1993
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1996-1999 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.
|
||||
*/
|
||||
|
||||
/* from gethostnamadr.c 8.1 (Berkeley) 6/4/93 */
|
||||
/* BIND Id: gethnamaddr.c,v 8.15 1996/05/22 04:56:30 vixie Exp $ */
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: lcl_ho.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Imports. */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "dns_p.h"
|
||||
#include "lcl_p.h"
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) sprintf x
|
||||
#endif
|
||||
|
||||
/* Definitions. */
|
||||
|
||||
#define MAXALIASES 35
|
||||
#define MAXADDRS 35
|
||||
#define Max(a,b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
#if PACKETSZ > 1024
|
||||
#define MAXPACKET PACKETSZ
|
||||
#else
|
||||
#define MAXPACKET 1024
|
||||
#endif
|
||||
|
||||
struct pvt {
|
||||
FILE * fp;
|
||||
struct hostent host;
|
||||
char * h_addr_ptrs[MAXADDRS + 1];
|
||||
char * host_aliases[MAXALIASES];
|
||||
char hostbuf[8*1024];
|
||||
u_char host_addr[16]; /* IPv4 or IPv6 */
|
||||
struct __res_state *res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
typedef union {
|
||||
int32_t al;
|
||||
char ac;
|
||||
} align;
|
||||
|
||||
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 };
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static void ho_close(struct irs_ho *this);
|
||||
static struct hostent * ho_byname(struct irs_ho *this, const char *name);
|
||||
static struct hostent * ho_byname2(struct irs_ho *this, const char *name,
|
||||
int af);
|
||||
static struct hostent * ho_byaddr(struct irs_ho *this, const void *addr,
|
||||
int len, int af);
|
||||
static struct hostent * ho_next(struct irs_ho *this);
|
||||
static void ho_rewind(struct irs_ho *this);
|
||||
static void ho_minimize(struct irs_ho *this);
|
||||
static struct __res_state * ho_res_get(struct irs_ho *this);
|
||||
static void ho_res_set(struct irs_ho *this,
|
||||
struct __res_state *res,
|
||||
void (*free_res)(void *));
|
||||
static struct addrinfo * ho_addrinfo(struct irs_ho *this, const char *name,
|
||||
const struct addrinfo *pai);
|
||||
|
||||
static size_t ns_namelen(const char *);
|
||||
static int init(struct irs_ho *this);
|
||||
|
||||
/* Portability. */
|
||||
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0
|
||||
#endif
|
||||
|
||||
/* Public. */
|
||||
|
||||
struct irs_ho *
|
||||
irs_lcl_ho(struct irs_acc *this) {
|
||||
struct irs_ho *ho;
|
||||
struct pvt *pvt;
|
||||
|
||||
UNUSED(this);
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
if (!(ho = memget(sizeof *ho))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(ho, 0x5e, sizeof *ho);
|
||||
ho->private = pvt;
|
||||
ho->close = ho_close;
|
||||
ho->byname = ho_byname;
|
||||
ho->byname2 = ho_byname2;
|
||||
ho->byaddr = ho_byaddr;
|
||||
ho->next = ho_next;
|
||||
ho->rewind = ho_rewind;
|
||||
ho->minimize = ho_minimize;
|
||||
ho->res_get = ho_res_get;
|
||||
ho->res_set = ho_res_set;
|
||||
ho->addrinfo = ho_addrinfo;
|
||||
return (ho);
|
||||
}
|
||||
|
||||
/* Methods. */
|
||||
|
||||
static void
|
||||
ho_close(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
ho_minimize(this);
|
||||
if (pvt->fp)
|
||||
(void) fclose(pvt->fp);
|
||||
if (pvt->res && pvt->free_res)
|
||||
(*pvt->free_res)(pvt->res);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_byname(struct irs_ho *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct hostent *hp;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
if (pvt->res->options & RES_USE_INET6) {
|
||||
hp = ho_byname2(this, name, AF_INET6);
|
||||
if (hp)
|
||||
return (hp);
|
||||
}
|
||||
return (ho_byname2(this, name, AF_INET));
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_byname2(struct irs_ho *this, const char *name, int af) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct hostent *hp;
|
||||
char **hap;
|
||||
size_t n;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
ho_rewind(this);
|
||||
n = ns_namelen(name);
|
||||
while ((hp = ho_next(this)) != NULL) {
|
||||
size_t nn;
|
||||
|
||||
if (hp->h_addrtype != af)
|
||||
continue;
|
||||
nn = ns_namelen(hp->h_name);
|
||||
if (strncasecmp(hp->h_name, name, Max(n, nn)) == 0)
|
||||
goto found;
|
||||
for (hap = hp->h_aliases; *hap; hap++) {
|
||||
nn = ns_namelen(*hap);
|
||||
if (strncasecmp(*hap, name, Max(n, nn)) == 0)
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
found:
|
||||
if (!hp) {
|
||||
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
|
||||
return (NULL);
|
||||
}
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS);
|
||||
return (hp);
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
const u_char *uaddr = addr;
|
||||
struct hostent *hp;
|
||||
int size;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
if (af == AF_INET6 && len == IN6ADDRSZ &&
|
||||
(!memcmp(uaddr, mapped, sizeof mapped) ||
|
||||
!memcmp(uaddr, tunnelled, sizeof tunnelled))) {
|
||||
/* Unmap. */
|
||||
addr = (const u_char *)addr + sizeof mapped;
|
||||
uaddr += sizeof mapped;
|
||||
af = AF_INET;
|
||||
len = INADDRSZ;
|
||||
}
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
size = INADDRSZ;
|
||||
break;
|
||||
case AF_INET6:
|
||||
size = IN6ADDRSZ;
|
||||
break;
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
}
|
||||
if (size > len) {
|
||||
errno = EINVAL;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the search.
|
||||
*/
|
||||
ho_rewind(this);
|
||||
while ((hp = ho_next(this)) != NULL) {
|
||||
char **hap;
|
||||
|
||||
for (hap = hp->h_addr_list; *hap; hap++) {
|
||||
const u_char *taddr = (const u_char *)*hap;
|
||||
int taf = hp->h_addrtype;
|
||||
int tlen = hp->h_length;
|
||||
|
||||
if (taf == AF_INET6 && tlen == IN6ADDRSZ &&
|
||||
(!memcmp(taddr, mapped, sizeof mapped) ||
|
||||
!memcmp(taddr, tunnelled, sizeof tunnelled))) {
|
||||
/* Unmap. */
|
||||
taddr += sizeof mapped;
|
||||
taf = AF_INET;
|
||||
tlen = INADDRSZ;
|
||||
}
|
||||
if (taf == af && tlen == len &&
|
||||
!memcmp(taddr, uaddr, tlen))
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
found:
|
||||
if (!hp) {
|
||||
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
|
||||
return (NULL);
|
||||
}
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS);
|
||||
return (hp);
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_next(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char *cp, **q, *p;
|
||||
char *bufp, *ndbuf, *dbuf = NULL;
|
||||
int c, af, len, bufsiz, offset;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
if (!pvt->fp)
|
||||
ho_rewind(this);
|
||||
if (!pvt->fp) {
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
}
|
||||
bufp = pvt->hostbuf;
|
||||
bufsiz = sizeof pvt->hostbuf;
|
||||
offset = 0;
|
||||
again:
|
||||
if (!(p = fgets(bufp + offset, bufsiz - offset, pvt->fp))) {
|
||||
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
|
||||
if (dbuf)
|
||||
free(dbuf);
|
||||
return (NULL);
|
||||
}
|
||||
if (!strchr(p, '\n') && !feof(pvt->fp)) {
|
||||
#define GROWBUF 1024
|
||||
/* allocate space for longer line */
|
||||
if (dbuf == NULL) {
|
||||
if ((ndbuf = malloc(bufsiz + GROWBUF)) != NULL)
|
||||
strcpy(ndbuf, bufp);
|
||||
} else
|
||||
ndbuf = realloc(dbuf, bufsiz + GROWBUF);
|
||||
if (ndbuf) {
|
||||
dbuf = ndbuf;
|
||||
bufp = dbuf;
|
||||
bufsiz += GROWBUF;
|
||||
offset = strlen(dbuf);
|
||||
} else {
|
||||
/* allocation failed; skip this long line */
|
||||
while ((c = getc(pvt->fp)) != EOF)
|
||||
if (c == '\n')
|
||||
break;
|
||||
if (c != EOF)
|
||||
ungetc(c, pvt->fp);
|
||||
}
|
||||
goto again;
|
||||
}
|
||||
|
||||
p -= offset;
|
||||
offset = 0;
|
||||
|
||||
if (*p == '#')
|
||||
goto again;
|
||||
if ((cp = strpbrk(p, "#\n")) != NULL)
|
||||
*cp = '\0';
|
||||
if (!(cp = strpbrk(p, " \t")))
|
||||
goto again;
|
||||
*cp++ = '\0';
|
||||
if (inet_pton(AF_INET6, p, pvt->host_addr) > 0) {
|
||||
af = AF_INET6;
|
||||
len = IN6ADDRSZ;
|
||||
} else if (inet_aton(p, (struct in_addr *)pvt->host_addr) > 0) {
|
||||
if (pvt->res->options & RES_USE_INET6) {
|
||||
map_v4v6_address((char*)pvt->host_addr,
|
||||
(char*)pvt->host_addr);
|
||||
af = AF_INET6;
|
||||
len = IN6ADDRSZ;
|
||||
} else {
|
||||
af = AF_INET;
|
||||
len = INADDRSZ;
|
||||
}
|
||||
} else {
|
||||
goto again;
|
||||
}
|
||||
pvt->h_addr_ptrs[0] = (char *)pvt->host_addr;
|
||||
pvt->h_addr_ptrs[1] = NULL;
|
||||
pvt->host.h_addr_list = pvt->h_addr_ptrs;
|
||||
pvt->host.h_length = len;
|
||||
pvt->host.h_addrtype = af;
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
pvt->host.h_name = cp;
|
||||
q = pvt->host.h_aliases = pvt->host_aliases;
|
||||
if ((cp = strpbrk(cp, " \t")) != NULL)
|
||||
*cp++ = '\0';
|
||||
while (cp && *cp) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &pvt->host_aliases[MAXALIASES - 1])
|
||||
*q++ = cp;
|
||||
if ((cp = strpbrk(cp, " \t")) != NULL)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
*q = NULL;
|
||||
if (dbuf)
|
||||
free(dbuf);
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS);
|
||||
return (&pvt->host);
|
||||
}
|
||||
|
||||
static void
|
||||
ho_rewind(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->fp) {
|
||||
if (fseek(pvt->fp, 0L, SEEK_SET) == 0)
|
||||
return;
|
||||
(void)fclose(pvt->fp);
|
||||
}
|
||||
if (!(pvt->fp = fopen(_PATH_HOSTS, "r")))
|
||||
return;
|
||||
if (fcntl(fileno(pvt->fp), F_SETFD, 1) < 0) {
|
||||
(void)fclose(pvt->fp);
|
||||
pvt->fp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ho_minimize(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->fp != NULL) {
|
||||
(void)fclose(pvt->fp);
|
||||
pvt->fp = NULL;
|
||||
}
|
||||
if (pvt->res)
|
||||
res_nclose(pvt->res);
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
ho_res_get(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (!res) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
ho_res_set(this, res, free);
|
||||
}
|
||||
|
||||
return (pvt->res);
|
||||
}
|
||||
|
||||
static void
|
||||
ho_res_set(struct irs_ho *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->res && pvt->free_res) {
|
||||
res_nclose(pvt->res);
|
||||
(*pvt->free_res)(pvt->res);
|
||||
}
|
||||
|
||||
pvt->res = res;
|
||||
pvt->free_res = free_res;
|
||||
}
|
||||
|
||||
struct lcl_res_target {
|
||||
struct lcl_res_target *next;
|
||||
int family;
|
||||
};
|
||||
|
||||
/* XXX */
|
||||
extern struct addrinfo *hostent2addrinfo __P((struct hostent *,
|
||||
const struct addrinfo *pai));
|
||||
|
||||
static struct addrinfo *
|
||||
ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct hostent *hp;
|
||||
struct lcl_res_target q, q2, *p;
|
||||
struct addrinfo sentinel, *cur;
|
||||
|
||||
memset(&q, 0, sizeof(q2));
|
||||
memset(&q2, 0, sizeof(q2));
|
||||
memset(&sentinel, 0, sizeof(sentinel));
|
||||
cur = &sentinel;
|
||||
|
||||
switch(pai->ai_family) {
|
||||
case AF_UNSPEC: /* INET6 then INET4 */
|
||||
q.family = AF_INET6;
|
||||
q.next = &q2;
|
||||
q2.family = AF_INET;
|
||||
break;
|
||||
case AF_INET6:
|
||||
q.family = AF_INET6;
|
||||
break;
|
||||
case AF_INET:
|
||||
q.family = AF_INET;
|
||||
break;
|
||||
default:
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); /* ??? */
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
for (p = &q; p; p = p->next) {
|
||||
struct addrinfo *ai;
|
||||
|
||||
hp = (*this->byname2)(this, name, p->family);
|
||||
if (hp == NULL) {
|
||||
/* byname2 should've set an appropriate error */
|
||||
continue;
|
||||
}
|
||||
if ((hp->h_name == NULL) || (hp->h_name[0] == 0) ||
|
||||
(hp->h_addr_list[0] == NULL)) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
continue;
|
||||
}
|
||||
|
||||
ai = hostent2addrinfo(hp, pai);
|
||||
if (ai) {
|
||||
cur->ai_next = ai;
|
||||
while (cur && cur->ai_next)
|
||||
cur = cur->ai_next;
|
||||
}
|
||||
}
|
||||
|
||||
if (sentinel.ai_next == NULL)
|
||||
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
|
||||
|
||||
return(sentinel.ai_next);
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
static size_t
|
||||
ns_namelen(const char *s) {
|
||||
int i;
|
||||
|
||||
for (i = strlen(s); i > 0 && s[i-1] == '.'; i--)
|
||||
(void)NULL;
|
||||
return ((size_t) i);
|
||||
}
|
||||
|
||||
static int
|
||||
init(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res && !ho_res_get(this))
|
||||
return (-1);
|
||||
if (((pvt->res->options & RES_INIT) == 0) &&
|
||||
res_ninit(pvt->res) == -1)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
@@ -0,0 +1,444 @@
|
||||
/*
|
||||
* Copyright (c) 1996-1999 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.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: lcl_ng.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "lcl_p.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
#define NG_HOST 0 /* Host name */
|
||||
#define NG_USER 1 /* User name */
|
||||
#define NG_DOM 2 /* and Domain name */
|
||||
#define LINSIZ 1024 /* Length of netgroup file line */
|
||||
|
||||
/*
|
||||
* XXX Warning XXX
|
||||
* This code is a hack-and-slash special. It realy needs to be
|
||||
* rewritten with things like strdup, and realloc in mind.
|
||||
* More reasonable data structures would not be a bad thing.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Static Variables and functions used by setnetgrent(), getnetgrent() and
|
||||
* endnetgrent().
|
||||
* There are two linked lists:
|
||||
* - linelist is just used by setnetgrent() to parse the net group file via.
|
||||
* parse_netgrp()
|
||||
* - netgrp is the list of entries for the current netgroup
|
||||
*/
|
||||
struct linelist {
|
||||
struct linelist *l_next; /* Chain ptr. */
|
||||
int l_parsed; /* Flag for cycles */
|
||||
char * l_groupname; /* Name of netgroup */
|
||||
char * l_line; /* Netgroup entrie(s) to be parsed */
|
||||
};
|
||||
|
||||
struct ng_old_struct {
|
||||
struct ng_old_struct *ng_next; /* Chain ptr */
|
||||
char * ng_str[3]; /* Field pointers, see below */
|
||||
};
|
||||
|
||||
struct pvt {
|
||||
FILE *fp;
|
||||
struct linelist *linehead;
|
||||
struct ng_old_struct *nextgrp;
|
||||
struct {
|
||||
struct ng_old_struct *gr;
|
||||
char *grname;
|
||||
} grouphead;
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void ng_rewind(struct irs_ng *, const char*);
|
||||
static void ng_close(struct irs_ng *);
|
||||
static int ng_next(struct irs_ng *, const char **,
|
||||
const char **, const char **);
|
||||
static int ng_test(struct irs_ng *, const char *,
|
||||
const char *, const char *,
|
||||
const char *);
|
||||
static void ng_minimize(struct irs_ng *);
|
||||
|
||||
static int parse_netgrp(struct irs_ng *, const char*);
|
||||
static struct linelist *read_for_group(struct irs_ng *, const char *);
|
||||
static void freelists(struct irs_ng *);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_ng *
|
||||
irs_lcl_ng(struct irs_acc *this) {
|
||||
struct irs_ng *ng;
|
||||
struct pvt *pvt;
|
||||
|
||||
UNUSED(this);
|
||||
|
||||
if (!(ng = memget(sizeof *ng))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(ng, 0x5e, sizeof *ng);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(ng, sizeof *ng);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
ng->private = pvt;
|
||||
ng->close = ng_close;
|
||||
ng->next = ng_next;
|
||||
ng->test = ng_test;
|
||||
ng->rewind = ng_rewind;
|
||||
ng->minimize = ng_minimize;
|
||||
return (ng);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
ng_close(struct irs_ng *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->fp != NULL)
|
||||
fclose(pvt->fp);
|
||||
freelists(this);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the netgroup file looking for the netgroup and build the list
|
||||
* of netgrp structures. Let parse_netgrp() and read_for_group() do
|
||||
* most of the work.
|
||||
*/
|
||||
static void
|
||||
ng_rewind(struct irs_ng *this, const char *group) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->fp != NULL && fseek(pvt->fp, SEEK_CUR, 0L) == -1) {
|
||||
fclose(pvt->fp);
|
||||
pvt->fp = NULL;
|
||||
}
|
||||
|
||||
if (pvt->fp == NULL || pvt->grouphead.gr == NULL ||
|
||||
strcmp(group, pvt->grouphead.grname)) {
|
||||
freelists(this);
|
||||
if (pvt->fp != NULL)
|
||||
fclose(pvt->fp);
|
||||
pvt->fp = fopen(_PATH_NETGROUP, "r");
|
||||
if (pvt->fp != NULL) {
|
||||
if (parse_netgrp(this, group))
|
||||
freelists(this);
|
||||
if (!(pvt->grouphead.grname = strdup(group)))
|
||||
freelists(this);
|
||||
fclose(pvt->fp);
|
||||
pvt->fp = NULL;
|
||||
}
|
||||
}
|
||||
pvt->nextgrp = pvt->grouphead.gr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the next netgroup off the list.
|
||||
*/
|
||||
static int
|
||||
ng_next(struct irs_ng *this, const char **host, const char **user,
|
||||
const char **domain)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->nextgrp) {
|
||||
*host = pvt->nextgrp->ng_str[NG_HOST];
|
||||
*user = pvt->nextgrp->ng_str[NG_USER];
|
||||
*domain = pvt->nextgrp->ng_str[NG_DOM];
|
||||
pvt->nextgrp = pvt->nextgrp->ng_next;
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Search for a match in a netgroup.
|
||||
*/
|
||||
static int
|
||||
ng_test(struct irs_ng *this, const char *name,
|
||||
const char *host, const char *user, const char *domain)
|
||||
{
|
||||
const char *ng_host, *ng_user, *ng_domain;
|
||||
|
||||
ng_rewind(this, name);
|
||||
while (ng_next(this, &ng_host, &ng_user, &ng_domain))
|
||||
if ((host == NULL || ng_host == NULL ||
|
||||
!strcmp(host, ng_host)) &&
|
||||
(user == NULL || ng_user == NULL ||
|
||||
!strcmp(user, ng_user)) &&
|
||||
(domain == NULL || ng_domain == NULL ||
|
||||
!strcmp(domain, ng_domain))) {
|
||||
freelists(this);
|
||||
return (1);
|
||||
}
|
||||
freelists(this);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
ng_minimize(struct irs_ng *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->fp != NULL) {
|
||||
(void)fclose(pvt->fp);
|
||||
pvt->fp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
/*
|
||||
* endnetgrent() - cleanup
|
||||
*/
|
||||
static void
|
||||
freelists(struct irs_ng *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct linelist *lp, *olp;
|
||||
struct ng_old_struct *gp, *ogp;
|
||||
|
||||
lp = pvt->linehead;
|
||||
while (lp) {
|
||||
olp = lp;
|
||||
lp = lp->l_next;
|
||||
free(olp->l_groupname);
|
||||
free(olp->l_line);
|
||||
free((char *)olp);
|
||||
}
|
||||
pvt->linehead = NULL;
|
||||
if (pvt->grouphead.grname) {
|
||||
free(pvt->grouphead.grname);
|
||||
pvt->grouphead.grname = NULL;
|
||||
}
|
||||
gp = pvt->grouphead.gr;
|
||||
while (gp) {
|
||||
ogp = gp;
|
||||
gp = gp->ng_next;
|
||||
if (ogp->ng_str[NG_HOST])
|
||||
free(ogp->ng_str[NG_HOST]);
|
||||
if (ogp->ng_str[NG_USER])
|
||||
free(ogp->ng_str[NG_USER]);
|
||||
if (ogp->ng_str[NG_DOM])
|
||||
free(ogp->ng_str[NG_DOM]);
|
||||
free((char *)ogp);
|
||||
}
|
||||
pvt->grouphead.gr = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the netgroup file setting up the linked lists.
|
||||
*/
|
||||
static int
|
||||
parse_netgrp(struct irs_ng *this, const char *group) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char *spos, *epos;
|
||||
int len, strpos;
|
||||
char *pos, *gpos;
|
||||
struct ng_old_struct *grp;
|
||||
struct linelist *lp = pvt->linehead;
|
||||
|
||||
/*
|
||||
* First, see if the line has already been read in.
|
||||
*/
|
||||
while (lp) {
|
||||
if (!strcmp(group, lp->l_groupname))
|
||||
break;
|
||||
lp = lp->l_next;
|
||||
}
|
||||
if (lp == NULL &&
|
||||
(lp = read_for_group(this, group)) == NULL)
|
||||
return (1);
|
||||
if (lp->l_parsed) {
|
||||
/*fprintf(stderr, "Cycle in netgroup %s\n", lp->l_groupname);*/
|
||||
return (1);
|
||||
} else
|
||||
lp->l_parsed = 1;
|
||||
pos = lp->l_line;
|
||||
while (*pos != '\0') {
|
||||
if (*pos == '(') {
|
||||
if (!(grp = malloc(sizeof (struct ng_old_struct)))) {
|
||||
freelists(this);
|
||||
errno = ENOMEM;
|
||||
return (1);
|
||||
}
|
||||
memset(grp, 0, sizeof (struct ng_old_struct));
|
||||
grp->ng_next = pvt->grouphead.gr;
|
||||
pvt->grouphead.gr = grp;
|
||||
pos++;
|
||||
gpos = strsep(&pos, ")");
|
||||
for (strpos = 0; strpos < 3; strpos++) {
|
||||
if ((spos = strsep(&gpos, ","))) {
|
||||
while (*spos == ' ' || *spos == '\t')
|
||||
spos++;
|
||||
if ((epos = strpbrk(spos, " \t"))) {
|
||||
*epos = '\0';
|
||||
len = epos - spos;
|
||||
} else
|
||||
len = strlen(spos);
|
||||
if (len > 0) {
|
||||
if(!(grp->ng_str[strpos]
|
||||
= (char *)
|
||||
malloc(len + 1))) {
|
||||
freelists(this);
|
||||
return (1);
|
||||
}
|
||||
memcpy(grp->ng_str[strpos],
|
||||
spos,
|
||||
len + 1);
|
||||
}
|
||||
} else
|
||||
goto errout;
|
||||
}
|
||||
} else {
|
||||
spos = strsep(&pos, ", \t");
|
||||
if (spos != NULL && parse_netgrp(this, spos)) {
|
||||
freelists(this);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
if (pos == NULL)
|
||||
break;
|
||||
while (*pos == ' ' || *pos == ',' || *pos == '\t')
|
||||
pos++;
|
||||
}
|
||||
return (0);
|
||||
errout:
|
||||
/*fprintf(stderr, "Bad netgroup %s at ..%s\n", lp->l_groupname,
|
||||
spos);*/
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the netgroup file and save lines until the line for the netgroup
|
||||
* is found. Return 1 if eof is encountered.
|
||||
*/
|
||||
static struct linelist *
|
||||
read_for_group(struct irs_ng *this, const char *group) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char *pos, *spos, *linep = NULL, *olinep;
|
||||
int len, olen, cont;
|
||||
struct linelist *lp;
|
||||
char line[LINSIZ + 1];
|
||||
|
||||
while (fgets(line, LINSIZ, pvt->fp) != NULL) {
|
||||
pos = line;
|
||||
if (*pos == '#')
|
||||
continue;
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
spos = pos;
|
||||
while (*pos != ' ' && *pos != '\t' && *pos != '\n' &&
|
||||
*pos != '\0')
|
||||
pos++;
|
||||
len = pos - spos;
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
if (*pos != '\n' && *pos != '\0') {
|
||||
if (!(lp = malloc(sizeof (*lp)))) {
|
||||
freelists(this);
|
||||
return (NULL);
|
||||
}
|
||||
lp->l_parsed = 0;
|
||||
if (!(lp->l_groupname = malloc(len + 1))) {
|
||||
free(lp);
|
||||
freelists(this);
|
||||
return (NULL);
|
||||
}
|
||||
memcpy(lp->l_groupname, spos, len);
|
||||
*(lp->l_groupname + len) = '\0';
|
||||
len = strlen(pos);
|
||||
olen = 0;
|
||||
olinep = NULL;
|
||||
|
||||
/*
|
||||
* Loop around handling line continuations.
|
||||
*/
|
||||
do {
|
||||
if (*(pos + len - 1) == '\n')
|
||||
len--;
|
||||
if (*(pos + len - 1) == '\\') {
|
||||
len--;
|
||||
cont = 1;
|
||||
} else
|
||||
cont = 0;
|
||||
if (len > 0) {
|
||||
if (!(linep = malloc(olen + len + 1))){
|
||||
if (olen > 0)
|
||||
free(olinep);
|
||||
free(lp->l_groupname);
|
||||
free(lp);
|
||||
freelists(this);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
if (olen > 0) {
|
||||
memcpy(linep, olinep, olen);
|
||||
free(olinep);
|
||||
}
|
||||
memcpy(linep + olen, pos, len);
|
||||
olen += len;
|
||||
*(linep + olen) = '\0';
|
||||
olinep = linep;
|
||||
}
|
||||
if (cont) {
|
||||
if (fgets(line, LINSIZ, pvt->fp)) {
|
||||
pos = line;
|
||||
len = strlen(pos);
|
||||
} else
|
||||
cont = 0;
|
||||
}
|
||||
} while (cont);
|
||||
lp->l_line = linep;
|
||||
lp->l_next = pvt->linehead;
|
||||
pvt->linehead = lp;
|
||||
|
||||
/*
|
||||
* If this is the one we wanted, we are done.
|
||||
*/
|
||||
if (!strcmp(lp->l_groupname, group))
|
||||
return (lp);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
@@ -0,0 +1,371 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1993, 1995
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1996-1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: lcl_nw.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
/* from getgrent.c 8.2 (Berkeley) 3/21/94"; */
|
||||
/* from BSDI Id: getgrent.c,v 2.8 1996/05/28 18:15:14 bostic Exp $ */
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include <isc/misc.h>
|
||||
#include "irs_p.h"
|
||||
#include "lcl_p.h"
|
||||
|
||||
#define MAXALIASES 35
|
||||
#define MAXADDRSIZE 4
|
||||
|
||||
struct pvt {
|
||||
FILE * fp;
|
||||
char line[BUFSIZ+1];
|
||||
struct nwent net;
|
||||
char * aliases[MAXALIASES];
|
||||
char addr[MAXADDRSIZE];
|
||||
struct __res_state * res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void nw_close(struct irs_nw *);
|
||||
static struct nwent * nw_byname(struct irs_nw *, const char *, int);
|
||||
static struct nwent * nw_byaddr(struct irs_nw *, void *, int, int);
|
||||
static struct nwent * nw_next(struct irs_nw *);
|
||||
static void nw_rewind(struct irs_nw *);
|
||||
static void nw_minimize(struct irs_nw *);
|
||||
static struct __res_state * nw_res_get(struct irs_nw *this);
|
||||
static void nw_res_set(struct irs_nw *this,
|
||||
struct __res_state *res,
|
||||
void (*free_res)(void *));
|
||||
|
||||
static int init(struct irs_nw *this);
|
||||
|
||||
/* Portability. */
|
||||
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0
|
||||
#endif
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_nw *
|
||||
irs_lcl_nw(struct irs_acc *this) {
|
||||
struct irs_nw *nw;
|
||||
struct pvt *pvt;
|
||||
|
||||
UNUSED(this);
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
if (!(nw = memget(sizeof *nw))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(nw, 0x5e, sizeof *nw);
|
||||
nw->private = pvt;
|
||||
nw->close = nw_close;
|
||||
nw->byname = nw_byname;
|
||||
nw->byaddr = nw_byaddr;
|
||||
nw->next = nw_next;
|
||||
nw->rewind = nw_rewind;
|
||||
nw->minimize = nw_minimize;
|
||||
nw->res_get = nw_res_get;
|
||||
nw->res_set = nw_res_set;
|
||||
return (nw);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
nw_close(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
nw_minimize(this);
|
||||
if (pvt->res && pvt->free_res)
|
||||
(*pvt->free_res)(pvt->res);
|
||||
if (pvt->fp)
|
||||
(void)fclose(pvt->fp);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
nw_byaddr(struct irs_nw *this, void *net, int length, int type) {
|
||||
struct nwent *p;
|
||||
|
||||
if (init(this) == -1)
|
||||
return(NULL);
|
||||
|
||||
nw_rewind(this);
|
||||
while ((p = nw_next(this)) != NULL)
|
||||
if (p->n_addrtype == type && p->n_length == length)
|
||||
if (bitncmp(p->n_addr, net, length) == 0)
|
||||
break;
|
||||
return (p);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
nw_byname(struct irs_nw *this, const char *name, int type) {
|
||||
struct nwent *p;
|
||||
char **ap;
|
||||
|
||||
if (init(this) == -1)
|
||||
return(NULL);
|
||||
|
||||
nw_rewind(this);
|
||||
while ((p = nw_next(this)) != NULL) {
|
||||
if (ns_samename(p->n_name, name) == 1 &&
|
||||
p->n_addrtype == type)
|
||||
break;
|
||||
for (ap = p->n_aliases; *ap; ap++)
|
||||
if ((ns_samename(*ap, name) == 1) &&
|
||||
(p->n_addrtype == type))
|
||||
goto found;
|
||||
}
|
||||
found:
|
||||
return (p);
|
||||
}
|
||||
|
||||
static void
|
||||
nw_rewind(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->fp) {
|
||||
if (fseek(pvt->fp, 0L, SEEK_SET) == 0)
|
||||
return;
|
||||
(void)fclose(pvt->fp);
|
||||
}
|
||||
if (!(pvt->fp = fopen(_PATH_NETWORKS, "r")))
|
||||
return;
|
||||
if (fcntl(fileno(pvt->fp), F_SETFD, 1) < 0) {
|
||||
(void)fclose(pvt->fp);
|
||||
pvt->fp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
nw_next(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct nwent *ret = NULL;
|
||||
char *p, *cp, **q;
|
||||
char *bufp, *ndbuf, *dbuf = NULL;
|
||||
int c, bufsiz, offset = 0;
|
||||
|
||||
if (init(this) == -1)
|
||||
return(NULL);
|
||||
|
||||
if (pvt->fp == NULL)
|
||||
nw_rewind(this);
|
||||
if (pvt->fp == NULL) {
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
}
|
||||
bufp = pvt->line;
|
||||
bufsiz = sizeof(pvt->line);
|
||||
|
||||
again:
|
||||
p = fgets(bufp + offset, bufsiz - offset, pvt->fp);
|
||||
if (p == NULL)
|
||||
goto cleanup;
|
||||
if (!strchr(p, '\n') && !feof(pvt->fp)) {
|
||||
#define GROWBUF 1024
|
||||
/* allocate space for longer line */
|
||||
if (dbuf == NULL) {
|
||||
if ((ndbuf = malloc(bufsiz + GROWBUF)) != NULL)
|
||||
strcpy(ndbuf, bufp);
|
||||
} else
|
||||
ndbuf = realloc(dbuf, bufsiz + GROWBUF);
|
||||
if (ndbuf) {
|
||||
dbuf = ndbuf;
|
||||
bufp = dbuf;
|
||||
bufsiz += GROWBUF;
|
||||
offset = strlen(dbuf);
|
||||
} else {
|
||||
/* allocation failed; skip this long line */
|
||||
while ((c = getc(pvt->fp)) != EOF)
|
||||
if (c == '\n')
|
||||
break;
|
||||
if (c != EOF)
|
||||
ungetc(c, pvt->fp);
|
||||
}
|
||||
goto again;
|
||||
}
|
||||
|
||||
p -= offset;
|
||||
offset = 0;
|
||||
|
||||
if (*p == '#')
|
||||
goto again;
|
||||
|
||||
cp = strpbrk(p, "#\n");
|
||||
if (cp != NULL)
|
||||
*cp = '\0';
|
||||
pvt->net.n_name = p;
|
||||
cp = strpbrk(p, " \t");
|
||||
if (cp == NULL)
|
||||
goto again;
|
||||
*cp++ = '\0';
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
p = strpbrk(cp, " \t");
|
||||
if (p != NULL)
|
||||
*p++ = '\0';
|
||||
pvt->net.n_length = inet_net_pton(AF_INET, cp, pvt->addr,
|
||||
sizeof pvt->addr);
|
||||
if (pvt->net.n_length < 0)
|
||||
goto again;
|
||||
pvt->net.n_addrtype = AF_INET;
|
||||
pvt->net.n_addr = pvt->addr;
|
||||
q = pvt->net.n_aliases = pvt->aliases;
|
||||
if (p != NULL) {
|
||||
cp = p;
|
||||
while (cp && *cp) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &pvt->aliases[MAXALIASES - 1])
|
||||
*q++ = cp;
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
}
|
||||
*q = NULL;
|
||||
ret = &pvt->net;
|
||||
|
||||
cleanup:
|
||||
if (dbuf)
|
||||
free(dbuf);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static void
|
||||
nw_minimize(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->res)
|
||||
res_nclose(pvt->res);
|
||||
if (pvt->fp != NULL) {
|
||||
(void)fclose(pvt->fp);
|
||||
pvt->fp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
nw_res_get(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (!res) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
nw_res_set(this, res, free);
|
||||
}
|
||||
|
||||
return (pvt->res);
|
||||
}
|
||||
|
||||
static void
|
||||
nw_res_set(struct irs_nw *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->res && pvt->free_res) {
|
||||
res_nclose(pvt->res);
|
||||
(*pvt->free_res)(pvt->res);
|
||||
}
|
||||
|
||||
pvt->res = res;
|
||||
pvt->free_res = free_res;
|
||||
}
|
||||
|
||||
static int
|
||||
init(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res && !nw_res_get(this))
|
||||
return (-1);
|
||||
if (((pvt->res->options & RES_INIT) == 0) &&
|
||||
res_ninit(pvt->res) == -1)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: lcl_p.h,v 1.1 2004/04/15 16:03:29 wkornew Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* lcl_p.h - private include file for the local accessor functions.
|
||||
*/
|
||||
|
||||
#ifndef _LCL_P_H_INCLUDED
|
||||
#define _LCL_P_H_INCLUDED
|
||||
|
||||
/*
|
||||
* Object state.
|
||||
*/
|
||||
struct lcl_p {
|
||||
struct __res_state * res;
|
||||
void (*free_res) __P((void *));
|
||||
};
|
||||
|
||||
/*
|
||||
* Externs.
|
||||
*/
|
||||
|
||||
extern struct irs_acc * irs_lcl_acc __P((const char *));
|
||||
extern struct irs_gr * irs_lcl_gr __P((struct irs_acc *));
|
||||
extern struct irs_pw * irs_lcl_pw __P((struct irs_acc *));
|
||||
extern struct irs_sv * irs_lcl_sv __P((struct irs_acc *));
|
||||
extern struct irs_pr * irs_lcl_pr __P((struct irs_acc *));
|
||||
extern struct irs_ho * irs_lcl_ho __P((struct irs_acc *));
|
||||
extern struct irs_nw * irs_lcl_nw __P((struct irs_acc *));
|
||||
extern struct irs_ng * irs_lcl_ng __P((struct irs_acc *));
|
||||
|
||||
#endif /*_LCL_P_H_INCLUDED*/
|
||||
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1993, 1995
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: lcl_pr.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* extern */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "lcl_p.h"
|
||||
|
||||
#ifndef _PATH_PROTOCOLS
|
||||
#define _PATH_PROTOCOLS "/etc/protocols"
|
||||
#endif
|
||||
#define MAXALIASES 35
|
||||
|
||||
/* Types */
|
||||
|
||||
struct pvt {
|
||||
FILE * fp;
|
||||
char line[BUFSIZ+1];
|
||||
struct protoent proto;
|
||||
char * proto_aliases[MAXALIASES];
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void pr_close(struct irs_pr *);
|
||||
static struct protoent * pr_next(struct irs_pr *);
|
||||
static struct protoent * pr_byname(struct irs_pr *, const char *);
|
||||
static struct protoent * pr_bynumber(struct irs_pr *, int);
|
||||
static void pr_rewind(struct irs_pr *);
|
||||
static void pr_minimize(struct irs_pr *);
|
||||
|
||||
/* Portability. */
|
||||
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0
|
||||
#endif
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_pr *
|
||||
irs_lcl_pr(struct irs_acc *this) {
|
||||
struct irs_pr *pr;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(pr = memget(sizeof *pr))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(pr, sizeof *this);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pr->private = pvt;
|
||||
pr->close = pr_close;
|
||||
pr->byname = pr_byname;
|
||||
pr->bynumber = pr_bynumber;
|
||||
pr->next = pr_next;
|
||||
pr->rewind = pr_rewind;
|
||||
pr->minimize = pr_minimize;
|
||||
pr->res_get = NULL;
|
||||
pr->res_set = NULL;
|
||||
return (pr);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
pr_close(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->fp)
|
||||
(void) fclose(pvt->fp);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct protoent *
|
||||
pr_byname(struct irs_pr *this, const char *name) {
|
||||
|
||||
struct protoent *p;
|
||||
char **cp;
|
||||
|
||||
pr_rewind(this);
|
||||
while ((p = pr_next(this))) {
|
||||
if (!strcmp(p->p_name, name))
|
||||
goto found;
|
||||
for (cp = p->p_aliases; *cp; cp++)
|
||||
if (!strcmp(*cp, name))
|
||||
goto found;
|
||||
}
|
||||
found:
|
||||
return (p);
|
||||
}
|
||||
|
||||
static struct protoent *
|
||||
pr_bynumber(struct irs_pr *this, int proto) {
|
||||
struct protoent *p;
|
||||
|
||||
pr_rewind(this);
|
||||
while ((p = pr_next(this)))
|
||||
if (p->p_proto == proto)
|
||||
break;
|
||||
return (p);
|
||||
}
|
||||
|
||||
static void
|
||||
pr_rewind(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->fp) {
|
||||
if (fseek(pvt->fp, 0L, SEEK_SET) == 0)
|
||||
return;
|
||||
(void)fclose(pvt->fp);
|
||||
}
|
||||
if (!(pvt->fp = fopen(_PATH_PROTOCOLS, "r" )))
|
||||
return;
|
||||
if (fcntl(fileno(pvt->fp), F_SETFD, 1) < 0) {
|
||||
(void)fclose(pvt->fp);
|
||||
pvt->fp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct protoent *
|
||||
pr_next(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char *p, *cp, **q;
|
||||
char *bufp, *ndbuf, *dbuf = NULL;
|
||||
int c, bufsiz, offset;
|
||||
|
||||
if (!pvt->fp)
|
||||
pr_rewind(this);
|
||||
if (!pvt->fp)
|
||||
return (NULL);
|
||||
bufp = pvt->line;
|
||||
bufsiz = BUFSIZ;
|
||||
offset = 0;
|
||||
again:
|
||||
if ((p = fgets(bufp + offset, bufsiz - offset, pvt->fp)) == NULL) {
|
||||
if (dbuf)
|
||||
free(dbuf);
|
||||
return (NULL);
|
||||
}
|
||||
if (!strchr(p, '\n') && !feof(pvt->fp)) {
|
||||
#define GROWBUF 1024
|
||||
/* allocate space for longer line */
|
||||
if (dbuf == NULL) {
|
||||
if ((ndbuf = malloc(bufsiz + GROWBUF)) != NULL)
|
||||
strcpy(ndbuf, bufp);
|
||||
} else
|
||||
ndbuf = realloc(dbuf, bufsiz + GROWBUF);
|
||||
if (ndbuf) {
|
||||
dbuf = ndbuf;
|
||||
bufp = dbuf;
|
||||
bufsiz += GROWBUF;
|
||||
offset = strlen(dbuf);
|
||||
} else {
|
||||
/* allocation failed; skip this long line */
|
||||
while ((c = getc(pvt->fp)) != EOF)
|
||||
if (c == '\n')
|
||||
break;
|
||||
if (c != EOF)
|
||||
ungetc(c, pvt->fp);
|
||||
}
|
||||
goto again;
|
||||
}
|
||||
|
||||
p -= offset;
|
||||
offset = 0;
|
||||
|
||||
if (*p == '#')
|
||||
goto again;
|
||||
cp = strpbrk(p, "#\n");
|
||||
if (cp != NULL)
|
||||
*cp = '\0';
|
||||
pvt->proto.p_name = p;
|
||||
cp = strpbrk(p, " \t");
|
||||
if (cp == NULL)
|
||||
goto again;
|
||||
*cp++ = '\0';
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
p = strpbrk(cp, " \t");
|
||||
if (p != NULL)
|
||||
*p++ = '\0';
|
||||
pvt->proto.p_proto = atoi(cp);
|
||||
q = pvt->proto.p_aliases = pvt->proto_aliases;
|
||||
if (p != NULL) {
|
||||
cp = p;
|
||||
while (cp && *cp) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &pvt->proto_aliases[MAXALIASES - 1])
|
||||
*q++ = cp;
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
}
|
||||
*q = NULL;
|
||||
return (&pvt->proto);
|
||||
}
|
||||
|
||||
static void
|
||||
pr_minimize(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->fp != NULL) {
|
||||
(void)fclose(pvt->fp);
|
||||
pvt->fp = NULL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1993, 1995
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: lcl_pw.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Extern */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_PW
|
||||
static int __bind_irs_pw_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <db.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <utmp.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "lcl_p.h"
|
||||
|
||||
/*
|
||||
* The lookup techniques and data extraction code here must be kept
|
||||
* in sync with that in `pwd_mkdb'.
|
||||
*/
|
||||
|
||||
|
||||
/* Types */
|
||||
|
||||
struct pvt {
|
||||
struct passwd passwd; /* password structure */
|
||||
DB *pw_db; /* password database */
|
||||
int pw_keynum; /* key counter */
|
||||
int warned;
|
||||
u_int max;
|
||||
char * line;
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void pw_close(struct irs_pw *);
|
||||
static struct passwd * pw_next(struct irs_pw *);
|
||||
static struct passwd * pw_byname(struct irs_pw *, const char *);
|
||||
static struct passwd * pw_byuid(struct irs_pw *, uid_t);
|
||||
static void pw_rewind(struct irs_pw *);
|
||||
static void pw_minimize(struct irs_pw *);
|
||||
|
||||
static int initdb(struct pvt *);
|
||||
static int hashpw(struct irs_pw *, DBT *);
|
||||
|
||||
/* Public */
|
||||
struct irs_pw *
|
||||
irs_lcl_pw(struct irs_acc *this) {
|
||||
struct irs_pw *pw;
|
||||
struct pvt *pvt;
|
||||
|
||||
UNUSED(this);
|
||||
|
||||
if (!(pw = memget(sizeof *pw))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pw, 0x5e, sizeof *pw);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
free(pw);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pw->private = pvt;
|
||||
pw->close = pw_close;
|
||||
pw->next = pw_next;
|
||||
pw->byname = pw_byname;
|
||||
pw->byuid = pw_byuid;
|
||||
pw->rewind = pw_rewind;
|
||||
pw->minimize = pw_minimize;
|
||||
pw->res_get = NULL;
|
||||
pw->res_set = NULL;
|
||||
return (pw);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
pw_close(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->pw_db) {
|
||||
(void)(pvt->pw_db->close)(pvt->pw_db);
|
||||
pvt->pw_db = NULL;
|
||||
}
|
||||
if (pvt->line)
|
||||
memput(pvt->line, pvt->max);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
pw_next(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
DBT key;
|
||||
char bf[sizeof(pvt->pw_keynum) + 1];
|
||||
|
||||
if (!initdb(pvt))
|
||||
return (NULL);
|
||||
|
||||
++pvt->pw_keynum;
|
||||
bf[0] = _PW_KEYBYNUM;
|
||||
memcpy(bf + 1, (char *)&pvt->pw_keynum, sizeof(pvt->pw_keynum));
|
||||
key.data = (u_char *)bf;
|
||||
key.size = sizeof(pvt->pw_keynum) + 1;
|
||||
return (hashpw(this, &key) ? &pvt->passwd : NULL);
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
pw_byname(struct irs_pw *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
DBT key;
|
||||
int len, rval;
|
||||
char bf[UT_NAMESIZE + 1];
|
||||
|
||||
if (!initdb(pvt))
|
||||
return (NULL);
|
||||
|
||||
bf[0] = _PW_KEYBYNAME;
|
||||
len = strlen(name);
|
||||
memcpy(bf + 1, name, MIN(len, UT_NAMESIZE));
|
||||
key.data = (u_char *)bf;
|
||||
key.size = len + 1;
|
||||
rval = hashpw(this, &key);
|
||||
|
||||
return (rval ? &pvt->passwd : NULL);
|
||||
}
|
||||
|
||||
|
||||
static struct passwd *
|
||||
pw_byuid(struct irs_pw *this, uid_t uid) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
DBT key;
|
||||
int keyuid, rval;
|
||||
char bf[sizeof(keyuid) + 1];
|
||||
|
||||
if (!initdb(pvt))
|
||||
return (NULL);
|
||||
|
||||
bf[0] = _PW_KEYBYUID;
|
||||
keyuid = uid;
|
||||
memcpy(bf + 1, &keyuid, sizeof(keyuid));
|
||||
key.data = (u_char *)bf;
|
||||
key.size = sizeof(keyuid) + 1;
|
||||
rval = hashpw(this, &key);
|
||||
|
||||
return (rval ? &pvt->passwd : NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
pw_rewind(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
pvt->pw_keynum = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pw_minimize(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->pw_db != NULL) {
|
||||
(void) (*pvt->pw_db->close)(pvt->pw_db);
|
||||
pvt->pw_db = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
static int
|
||||
initdb(struct pvt *pvt) {
|
||||
const char *p;
|
||||
|
||||
if (pvt->pw_db) {
|
||||
if (lseek((*pvt->pw_db->fd)(pvt->pw_db), 0L, SEEK_CUR) >= 0L)
|
||||
return (1);
|
||||
else
|
||||
(void) (*pvt->pw_db->close)(pvt->pw_db);
|
||||
}
|
||||
pvt->pw_db = dbopen((p = _PATH_SMP_DB), O_RDONLY, 0, DB_HASH, NULL);
|
||||
if (!pvt->pw_db)
|
||||
pvt->pw_db = dbopen((p =_PATH_MP_DB), O_RDONLY,
|
||||
0, DB_HASH, NULL);
|
||||
if (pvt->pw_db)
|
||||
return (1);
|
||||
if (!pvt->warned) {
|
||||
syslog(LOG_ERR, "%s: %m", p);
|
||||
pvt->warned++;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
hashpw(struct irs_pw *this, DBT *key) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char *p, *t, *l;
|
||||
DBT data;
|
||||
|
||||
if ((pvt->pw_db->get)(pvt->pw_db, key, &data, 0))
|
||||
return (0);
|
||||
p = (char *)data.data;
|
||||
if (data.size > pvt->max) {
|
||||
size_t newlen = pvt->max + 1024;
|
||||
char *p = memget(newlen);
|
||||
if (p == NULL) {
|
||||
return (0);
|
||||
}
|
||||
if (pvt->line != NULL) {
|
||||
memcpy(p, pvt->line, pvt->max);
|
||||
memput(pvt->line, pvt->max);
|
||||
}
|
||||
pvt->max = newlen;
|
||||
pvt->line = p;
|
||||
}
|
||||
|
||||
/* THIS CODE MUST MATCH THAT IN pwd_mkdb. */
|
||||
t = pvt->line;
|
||||
l = pvt->line + pvt->max;
|
||||
#define EXPAND(e) if ((e = t) == NULL) return (0); else \
|
||||
do if (t >= l) return (0); while ((*t++ = *p++) != '\0')
|
||||
#define SCALAR(v) if (t + sizeof v >= l) return (0); else \
|
||||
(memmove(&(v), p, sizeof v), p += sizeof v)
|
||||
EXPAND(pvt->passwd.pw_name);
|
||||
EXPAND(pvt->passwd.pw_passwd);
|
||||
SCALAR(pvt->passwd.pw_uid);
|
||||
SCALAR(pvt->passwd.pw_gid);
|
||||
SCALAR(pvt->passwd.pw_change);
|
||||
EXPAND(pvt->passwd.pw_class);
|
||||
EXPAND(pvt->passwd.pw_gecos);
|
||||
EXPAND(pvt->passwd.pw_dir);
|
||||
EXPAND(pvt->passwd.pw_shell);
|
||||
SCALAR(pvt->passwd.pw_expire);
|
||||
return (1);
|
||||
}
|
||||
|
||||
#endif /* WANT_IRS_PW */
|
||||
@@ -0,0 +1,431 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1993, 1995
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1996-1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: lcl_sv.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* extern */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#ifdef IRS_LCL_SV_DB
|
||||
#include <db.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "lcl_p.h"
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) ((size_t)sprintf x)
|
||||
#endif
|
||||
|
||||
/* Types */
|
||||
|
||||
struct pvt {
|
||||
#ifdef IRS_LCL_SV_DB
|
||||
DB * dbh;
|
||||
int dbf;
|
||||
#endif
|
||||
struct lcl_sv sv;
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void sv_close(struct irs_sv*);
|
||||
static struct servent * sv_next(struct irs_sv *);
|
||||
static struct servent * sv_byname(struct irs_sv *, const char *,
|
||||
const char *);
|
||||
static struct servent * sv_byport(struct irs_sv *, int, const char *);
|
||||
static void sv_rewind(struct irs_sv *);
|
||||
static void sv_minimize(struct irs_sv *);
|
||||
/*global*/ struct servent * irs_lclsv_fnxt(struct lcl_sv *);
|
||||
#ifdef IRS_LCL_SV_DB
|
||||
static struct servent * sv_db_rec(struct lcl_sv *, DBT *, DBT *);
|
||||
#endif
|
||||
|
||||
/* Portability */
|
||||
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0
|
||||
#endif
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_sv *
|
||||
irs_lcl_sv(struct irs_acc *this) {
|
||||
struct irs_sv *sv;
|
||||
struct pvt *pvt;
|
||||
|
||||
UNUSED(this);
|
||||
|
||||
if ((sv = memget(sizeof *sv)) == NULL) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(sv, 0x5e, sizeof *sv);
|
||||
if ((pvt = memget(sizeof *pvt)) == NULL) {
|
||||
memput(sv, sizeof *sv);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
sv->private = pvt;
|
||||
sv->close = sv_close;
|
||||
sv->next = sv_next;
|
||||
sv->byname = sv_byname;
|
||||
sv->byport = sv_byport;
|
||||
sv->rewind = sv_rewind;
|
||||
sv->minimize = sv_minimize;
|
||||
sv->res_get = NULL;
|
||||
sv->res_set = NULL;
|
||||
#ifdef IRS_LCL_SV_DB
|
||||
pvt->dbf = R_FIRST;
|
||||
#endif
|
||||
return (sv);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
sv_close(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
#ifdef IRS_LCL_SV_DB
|
||||
if (pvt->dbh != NULL)
|
||||
(*pvt->dbh->close)(pvt->dbh);
|
||||
#endif
|
||||
if (pvt->sv.fp)
|
||||
fclose(pvt->sv.fp);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct servent *
|
||||
sv_byname(struct irs_sv *this, const char *name, const char *proto) {
|
||||
#ifdef IRS_LCL_SV_DB
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
#endif
|
||||
struct servent *p;
|
||||
char **cp;
|
||||
|
||||
sv_rewind(this);
|
||||
#ifdef IRS_LCL_SV_DB
|
||||
if (pvt->dbh != NULL) {
|
||||
DBT key, data;
|
||||
|
||||
/* Note that (sizeof "/") == 2. */
|
||||
if ((strlen(name) + sizeof "/" + proto ? strlen(proto) : 0)
|
||||
> sizeof pvt->sv.line)
|
||||
goto try_local;
|
||||
key.data = pvt->sv.line;
|
||||
key.size = SPRINTF((pvt->sv.line, "%s/%s", name,
|
||||
proto ? proto : "")) + 1;
|
||||
if (proto != NULL) {
|
||||
if ((*pvt->dbh->get)(pvt->dbh, &key, &data, 0) != 0)
|
||||
return (NULL);
|
||||
} else if ((*pvt->dbh->seq)(pvt->dbh, &key, &data, R_CURSOR)
|
||||
!= 0)
|
||||
return (NULL);
|
||||
return (sv_db_rec(&pvt->sv, &key, &data));
|
||||
}
|
||||
try_local:
|
||||
#endif
|
||||
|
||||
while ((p = sv_next(this))) {
|
||||
if (strcmp(name, p->s_name) == 0)
|
||||
goto gotname;
|
||||
for (cp = p->s_aliases; *cp; cp++)
|
||||
if (strcmp(name, *cp) == 0)
|
||||
goto gotname;
|
||||
continue;
|
||||
gotname:
|
||||
if (proto == NULL || strcmp(p->s_proto, proto) == 0)
|
||||
break;
|
||||
}
|
||||
return (p);
|
||||
}
|
||||
|
||||
static struct servent *
|
||||
sv_byport(struct irs_sv *this, int port, const char *proto) {
|
||||
#ifdef IRS_LCL_SV_DB
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
#endif
|
||||
struct servent *p;
|
||||
|
||||
sv_rewind(this);
|
||||
#ifdef IRS_LCL_SV_DB
|
||||
if (pvt->dbh != NULL) {
|
||||
DBT key, data;
|
||||
u_short *ports;
|
||||
|
||||
ports = (u_short *)pvt->sv.line;
|
||||
ports[0] = 0;
|
||||
ports[1] = port;
|
||||
key.data = ports;
|
||||
key.size = sizeof(u_short) * 2;
|
||||
if (proto && *proto) {
|
||||
strncpy((char *)ports + key.size, proto,
|
||||
BUFSIZ - key.size);
|
||||
key.size += strlen((char *)ports + key.size) + 1;
|
||||
if ((*pvt->dbh->get)(pvt->dbh, &key, &data, 0) != 0)
|
||||
return (NULL);
|
||||
} else {
|
||||
if ((*pvt->dbh->seq)(pvt->dbh, &key, &data, R_CURSOR)
|
||||
!= 0)
|
||||
return (NULL);
|
||||
}
|
||||
return (sv_db_rec(&pvt->sv, &key, &data));
|
||||
}
|
||||
#endif
|
||||
while ((p = sv_next(this))) {
|
||||
if (p->s_port != port)
|
||||
continue;
|
||||
if (proto == NULL || strcmp(p->s_proto, proto) == 0)
|
||||
break;
|
||||
}
|
||||
return (p);
|
||||
}
|
||||
|
||||
static void
|
||||
sv_rewind(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->sv.fp) {
|
||||
if (fseek(pvt->sv.fp, 0L, SEEK_SET) == 0)
|
||||
return;
|
||||
(void)fclose(pvt->sv.fp);
|
||||
pvt->sv.fp = NULL;
|
||||
}
|
||||
#ifdef IRS_LCL_SV_DB
|
||||
pvt->dbf = R_FIRST;
|
||||
if (pvt->dbh != NULL)
|
||||
return;
|
||||
pvt->dbh = dbopen(_PATH_SERVICES_DB, O_RDONLY,O_RDONLY,DB_BTREE, NULL);
|
||||
if (pvt->dbh != NULL) {
|
||||
if (fcntl((*pvt->dbh->fd)(pvt->dbh), F_SETFD, 1) < 0) {
|
||||
(*pvt->dbh->close)(pvt->dbh);
|
||||
pvt->dbh = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if ((pvt->sv.fp = fopen(_PATH_SERVICES, "r")) == NULL)
|
||||
return;
|
||||
if (fcntl(fileno(pvt->sv.fp), F_SETFD, 1) < 0) {
|
||||
(void)fclose(pvt->sv.fp);
|
||||
pvt->sv.fp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct servent *
|
||||
sv_next(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
#ifdef IRS_LCL_SV_DB
|
||||
if (pvt->dbh == NULL && pvt->sv.fp == NULL)
|
||||
#else
|
||||
if (pvt->sv.fp == NULL)
|
||||
#endif
|
||||
sv_rewind(this);
|
||||
|
||||
#ifdef IRS_LCL_SV_DB
|
||||
if (pvt->dbh != NULL) {
|
||||
DBT key, data;
|
||||
|
||||
while ((*pvt->dbh->seq)(pvt->dbh, &key, &data, pvt->dbf) == 0){
|
||||
pvt->dbf = R_NEXT;
|
||||
if (((char *)key.data)[0])
|
||||
continue;
|
||||
return (sv_db_rec(&pvt->sv, &key, &data));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pvt->sv.fp == NULL)
|
||||
return (NULL);
|
||||
return (irs_lclsv_fnxt(&pvt->sv));
|
||||
}
|
||||
|
||||
static void
|
||||
sv_minimize(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
#ifdef IRS_LCL_SV_DB
|
||||
if (pvt->dbh != NULL) {
|
||||
(*pvt->dbh->close)(pvt->dbh);
|
||||
pvt->dbh = NULL;
|
||||
}
|
||||
#endif
|
||||
if (pvt->sv.fp != NULL) {
|
||||
(void)fclose(pvt->sv.fp);
|
||||
pvt->sv.fp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Quasipublic. */
|
||||
|
||||
struct servent *
|
||||
irs_lclsv_fnxt(struct lcl_sv *sv) {
|
||||
char *p, *cp, **q;
|
||||
|
||||
again:
|
||||
if ((p = fgets(sv->line, BUFSIZ, sv->fp)) == NULL)
|
||||
return (NULL);
|
||||
if (*p == '#')
|
||||
goto again;
|
||||
sv->serv.s_name = p;
|
||||
while (*p && *p != '\n' && *p != ' ' && *p != '\t' && *p != '#')
|
||||
++p;
|
||||
if (*p == '\0' || *p == '#' || *p == '\n')
|
||||
goto again;
|
||||
*p++ = '\0';
|
||||
while (*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
if (*p == '\0' || *p == '#' || *p == '\n')
|
||||
goto again;
|
||||
sv->serv.s_port = htons((u_short)strtol(p, &cp, 10));
|
||||
if (cp == p || (*cp != '/' && *cp != ','))
|
||||
goto again;
|
||||
p = cp + 1;
|
||||
sv->serv.s_proto = p;
|
||||
|
||||
q = sv->serv.s_aliases = sv->serv_aliases;
|
||||
|
||||
while (*p && *p != '\n' && *p != ' ' && *p != '\t' && *p != '#')
|
||||
++p;
|
||||
|
||||
while (*p == ' ' || *p == '\t') {
|
||||
*p++ = '\0';
|
||||
while (*p == ' ' || *p == '\t')
|
||||
++p;
|
||||
if (*p == '\0' || *p == '#' || *p == '\n')
|
||||
break;
|
||||
if (q < &sv->serv_aliases[IRS_SV_MAXALIASES - 1])
|
||||
*q++ = p;
|
||||
while (*p && *p != '\n' && *p != ' ' && *p != '\t' && *p != '#')
|
||||
++p;
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
*q = NULL;
|
||||
return (&sv->serv);
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
#ifdef IRS_LCL_SV_DB
|
||||
static struct servent *
|
||||
sv_db_rec(struct lcl_sv *sv, DBT *key, DBT *data) {
|
||||
char *p, **q;
|
||||
int n;
|
||||
|
||||
p = data->data;
|
||||
p[data->size - 1] = '\0'; /* should be, but we depend on it */
|
||||
|
||||
if (((char *)key->data)[0] == '\0') {
|
||||
if (key->size < sizeof(u_short)*2 || data->size < 2)
|
||||
return (NULL);
|
||||
sv->serv.s_port = ((u_short *)key->data)[1];
|
||||
n = strlen(p) + 1;
|
||||
if ((size_t)n > sizeof(sv->line)) {
|
||||
n = sizeof(sv->line);
|
||||
}
|
||||
memcpy(sv->line, p, n);
|
||||
sv->serv.s_name = sv->line;
|
||||
if ((sv->serv.s_proto = strchr(sv->line, '/')) != NULL)
|
||||
*(sv->serv.s_proto)++ = '\0';
|
||||
p += n;
|
||||
data->size -= n;
|
||||
} else {
|
||||
if (data->size < sizeof(u_short) + 1)
|
||||
return (NULL);
|
||||
if (key->size > sizeof(sv->line))
|
||||
key->size = sizeof(sv->line);
|
||||
((char *)key->data)[key->size - 1] = '\0';
|
||||
memcpy(sv->line, key->data, key->size);
|
||||
sv->serv.s_name = sv->line;
|
||||
if ((sv->serv.s_proto = strchr(sv->line, '/')) != NULL)
|
||||
*(sv->serv.s_proto)++ = '\0';
|
||||
sv->serv.s_port = *(u_short *)data->data;
|
||||
p += sizeof(u_short);
|
||||
data->size -= sizeof(u_short);
|
||||
}
|
||||
q = sv->serv.s_aliases = sv->serv_aliases;
|
||||
while (data->size > 0 && q < &sv->serv_aliases[IRS_SV_MAXALIASES - 1]) {
|
||||
|
||||
*q++ = p;
|
||||
n = strlen(p) + 1;
|
||||
data->size -= n;
|
||||
p += n;
|
||||
}
|
||||
*q = NULL;
|
||||
return (&sv->serv);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (c) 1996-1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: nis.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifdef WANT_IRS_NIS
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "hesiod.h"
|
||||
#include "nis_p.h"
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void nis_close(struct irs_acc *);
|
||||
static struct __res_state * nis_res_get(struct irs_acc *);
|
||||
static void nis_res_set(struct irs_acc *, struct __res_state *,
|
||||
void (*)(void *));
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_acc *
|
||||
irs_nis_acc(const char *options) {
|
||||
struct nis_p *nis;
|
||||
struct irs_acc *acc;
|
||||
char *domain;
|
||||
|
||||
UNUSED(options);
|
||||
|
||||
if (yp_get_default_domain(&domain) != 0)
|
||||
return (NULL);
|
||||
if (!(nis = memget(sizeof *nis))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(nis, 0, sizeof *nis);
|
||||
if (!(acc = memget(sizeof *acc))) {
|
||||
memput(nis, sizeof *nis);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(acc, 0x5e, sizeof *acc);
|
||||
acc->private = nis;
|
||||
nis->domain = strdup(domain);
|
||||
#ifdef WANT_IRS_GR
|
||||
acc->gr_map = irs_nis_gr;
|
||||
#else
|
||||
acc->gr_map = NULL;
|
||||
#endif
|
||||
#ifdef WANT_IRS_PW
|
||||
acc->pw_map = irs_nis_pw;
|
||||
#else
|
||||
acc->pw_map = NULL;
|
||||
#endif
|
||||
acc->sv_map = irs_nis_sv;
|
||||
acc->pr_map = irs_nis_pr;
|
||||
acc->ho_map = irs_nis_ho;
|
||||
acc->nw_map = irs_nis_nw;
|
||||
acc->ng_map = irs_nis_ng;
|
||||
acc->res_get = nis_res_get;
|
||||
acc->res_set = nis_res_set;
|
||||
acc->close = nis_close;
|
||||
return (acc);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static struct __res_state *
|
||||
nis_res_get(struct irs_acc *this) {
|
||||
struct nis_p *nis = (struct nis_p *)this->private;
|
||||
|
||||
if (nis->res == NULL) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (res == NULL)
|
||||
return (NULL);
|
||||
memset(res, 0, sizeof *res);
|
||||
nis_res_set(this, res, free);
|
||||
}
|
||||
|
||||
if ((nis->res->options & RES_INIT) == 0 &&
|
||||
res_ninit(nis->res) < 0)
|
||||
return (NULL);
|
||||
|
||||
return (nis->res);
|
||||
}
|
||||
|
||||
static void
|
||||
nis_res_set(struct irs_acc *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct nis_p *nis = (struct nis_p *)this->private;
|
||||
|
||||
if (nis->res && nis->free_res) {
|
||||
res_nclose(nis->res);
|
||||
(*nis->free_res)(nis->res);
|
||||
}
|
||||
|
||||
nis->res = res;
|
||||
nis->free_res = free_res;
|
||||
}
|
||||
|
||||
static void
|
||||
nis_close(struct irs_acc *this) {
|
||||
struct nis_p *nis = (struct nis_p *)this->private;
|
||||
|
||||
if (nis->res && nis->free_res)
|
||||
(*nis->free_res)(nis->res);
|
||||
free(nis->domain);
|
||||
memput(nis, sizeof *nis);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
#endif /*WANT_IRS_NIS*/
|
||||
@@ -0,0 +1,353 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1993, 1995
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1996-1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: nis_gr.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
/* from getgrent.c 8.2 (Berkeley) 3/21/94"; */
|
||||
/* from BSDI Id: getgrent.c,v 2.8 1996/05/28 18:15:14 bostic Exp $ */
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#if !defined(WANT_IRS_GR) || !defined(WANT_IRS_NIS)
|
||||
static int __bind_irs_gr_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "nis_p.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
struct pvt {
|
||||
int needrewind;
|
||||
char * nis_domain;
|
||||
char * curkey_data;
|
||||
int curkey_len;
|
||||
char * curval_data;
|
||||
int curval_len;
|
||||
/*
|
||||
* Need space to store the entries read from the group file.
|
||||
* The members list also needs space per member, and the
|
||||
* strings making up the user names must be allocated
|
||||
* somewhere. Rather than doing lots of small allocations,
|
||||
* we keep one buffer and resize it as needed.
|
||||
*/
|
||||
struct group group;
|
||||
size_t nmemb; /* Malloc'd max index of gr_mem[]. */
|
||||
char * membuf;
|
||||
size_t membufsize;
|
||||
};
|
||||
|
||||
enum do_what { do_none = 0x0, do_key = 0x1, do_val = 0x2, do_all = 0x3 };
|
||||
|
||||
static /*const*/ char group_bygid[] = "group.bygid";
|
||||
static /*const*/ char group_byname[] = "group.byname";
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void gr_close(struct irs_gr *);
|
||||
static struct group * gr_next(struct irs_gr *);
|
||||
static struct group * gr_byname(struct irs_gr *, const char *);
|
||||
static struct group * gr_bygid(struct irs_gr *, gid_t);
|
||||
static void gr_rewind(struct irs_gr *);
|
||||
static void gr_minimize(struct irs_gr *);
|
||||
|
||||
static struct group * makegroupent(struct irs_gr *);
|
||||
static void nisfree(struct pvt *, enum do_what);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_gr *
|
||||
irs_nis_gr(struct irs_acc *this) {
|
||||
struct irs_gr *gr;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(gr = memget(sizeof *gr))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(gr, 0x5e, sizeof *gr);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(gr, sizeof *gr);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->needrewind = 1;
|
||||
pvt->nis_domain = ((struct nis_p *)this->private)->domain;
|
||||
gr->private = pvt;
|
||||
gr->close = gr_close;
|
||||
gr->next = gr_next;
|
||||
gr->byname = gr_byname;
|
||||
gr->bygid = gr_bygid;
|
||||
gr->rewind = gr_rewind;
|
||||
gr->list = make_group_list;
|
||||
gr->minimize = gr_minimize;
|
||||
gr->res_get = NULL;
|
||||
gr->res_set = NULL;
|
||||
return (gr);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
gr_close(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->group.gr_mem)
|
||||
free(pvt->group.gr_mem);
|
||||
if (pvt->membuf)
|
||||
free(pvt->membuf);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_next(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct group *rval;
|
||||
int r;
|
||||
|
||||
do {
|
||||
if (pvt->needrewind) {
|
||||
nisfree(pvt, do_all);
|
||||
r = yp_first(pvt->nis_domain, group_byname,
|
||||
&pvt->curkey_data, &pvt->curkey_len,
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
pvt->needrewind = 0;
|
||||
} else {
|
||||
char *newkey_data;
|
||||
int newkey_len;
|
||||
|
||||
nisfree(pvt, do_val);
|
||||
r = yp_next(pvt->nis_domain, group_byname,
|
||||
pvt->curkey_data, pvt->curkey_len,
|
||||
&newkey_data, &newkey_len,
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
nisfree(pvt, do_key);
|
||||
pvt->curkey_data = newkey_data;
|
||||
pvt->curkey_len = newkey_len;
|
||||
}
|
||||
if (r != 0) {
|
||||
errno = ENOENT;
|
||||
return (NULL);
|
||||
}
|
||||
rval = makegroupent(this);
|
||||
} while (rval == NULL);
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_byname(struct irs_gr *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
int r;
|
||||
|
||||
nisfree(pvt, do_val);
|
||||
r = yp_match(pvt->nis_domain, group_byname, name, strlen(name),
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
if (r != 0) {
|
||||
errno = ENOENT;
|
||||
return (NULL);
|
||||
}
|
||||
return (makegroupent(this));
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_bygid(struct irs_gr *this, gid_t gid) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char tmp[sizeof "4294967295"];
|
||||
int r;
|
||||
|
||||
nisfree(pvt, do_val);
|
||||
(void) sprintf(tmp, "%u", (unsigned int)gid);
|
||||
r = yp_match(pvt->nis_domain, group_bygid, tmp, strlen(tmp),
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
if (r != 0) {
|
||||
errno = ENOENT;
|
||||
return (NULL);
|
||||
}
|
||||
return (makegroupent(this));
|
||||
}
|
||||
|
||||
static void
|
||||
gr_rewind(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
pvt->needrewind = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
gr_minimize(struct irs_gr *this) {
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static struct group *
|
||||
makegroupent(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
unsigned int num_members = 0;
|
||||
char *cp, **new;
|
||||
u_long t;
|
||||
|
||||
if (pvt->group.gr_mem) {
|
||||
free(pvt->group.gr_mem);
|
||||
pvt->group.gr_mem = NULL;
|
||||
pvt->nmemb = 0;
|
||||
}
|
||||
if (pvt->membuf)
|
||||
free(pvt->membuf);
|
||||
pvt->membuf = pvt->curval_data;
|
||||
pvt->curval_data = NULL;
|
||||
|
||||
cp = pvt->membuf;
|
||||
pvt->group.gr_name = cp;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
pvt->group.gr_passwd = cp;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
errno = 0;
|
||||
t = strtoul(cp, NULL, 10);
|
||||
if (errno == ERANGE)
|
||||
goto cleanup;
|
||||
pvt->group.gr_gid = (gid_t) t;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
cp++;
|
||||
|
||||
if (*cp && cp[strlen(cp)-1] == '\n')
|
||||
cp[strlen(cp)-1] = '\0';
|
||||
|
||||
/*
|
||||
* Parse the members out.
|
||||
*/
|
||||
while (*cp) {
|
||||
if (num_members+1 >= pvt->nmemb || pvt->group.gr_mem == NULL) {
|
||||
pvt->nmemb += 10;
|
||||
new = realloc(pvt->group.gr_mem,
|
||||
pvt->nmemb * sizeof(char *));
|
||||
if (new == NULL)
|
||||
goto cleanup;
|
||||
pvt->group.gr_mem = new;
|
||||
}
|
||||
pvt->group.gr_mem[num_members++] = cp;
|
||||
if (!(cp = strchr(cp, ',')))
|
||||
break;
|
||||
*cp++ = '\0';
|
||||
}
|
||||
if (pvt->group.gr_mem == NULL) {
|
||||
pvt->group.gr_mem = malloc(sizeof(char*));
|
||||
if (!pvt->group.gr_mem)
|
||||
goto cleanup;
|
||||
pvt->nmemb = 1;
|
||||
}
|
||||
pvt->group.gr_mem[num_members] = NULL;
|
||||
|
||||
return (&pvt->group);
|
||||
|
||||
cleanup:
|
||||
if (pvt->group.gr_mem) {
|
||||
free(pvt->group.gr_mem);
|
||||
pvt->group.gr_mem = NULL;
|
||||
pvt->nmemb = 0;
|
||||
}
|
||||
if (pvt->membuf) {
|
||||
free(pvt->membuf);
|
||||
pvt->membuf = NULL;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
nisfree(struct pvt *pvt, enum do_what do_what) {
|
||||
if ((do_what & do_key) && pvt->curkey_data) {
|
||||
free(pvt->curkey_data);
|
||||
pvt->curkey_data = NULL;
|
||||
}
|
||||
if ((do_what & do_val) && pvt->curval_data) {
|
||||
free(pvt->curval_data);
|
||||
pvt->curval_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* WANT_IRS_GR && WANT_IRS_NIS */
|
||||
@@ -0,0 +1,530 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: nis_ho.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_NIS
|
||||
static int __bind_irs_nis_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "nis_p.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
#define MAXALIASES 35
|
||||
#define MAXADDRS 35
|
||||
|
||||
#if PACKETSZ > 1024
|
||||
#define MAXPACKET PACKETSZ
|
||||
#else
|
||||
#define MAXPACKET 1024
|
||||
#endif
|
||||
|
||||
struct pvt {
|
||||
int needrewind;
|
||||
char * nis_domain;
|
||||
char * curkey_data;
|
||||
int curkey_len;
|
||||
char * curval_data;
|
||||
int curval_len;
|
||||
struct hostent host;
|
||||
char * h_addr_ptrs[MAXADDRS + 1];
|
||||
char * host_aliases[MAXALIASES + 1];
|
||||
char hostbuf[8*1024];
|
||||
u_char host_addr[16]; /* IPv4 or IPv6 */
|
||||
struct __res_state *res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
enum do_what { do_none = 0x0, do_key = 0x1, do_val = 0x2, do_all = 0x3 };
|
||||
|
||||
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 };
|
||||
static /*const*/ char hosts_byname[] = "hosts.byname";
|
||||
static /*const*/ char hosts_byaddr[] = "hosts.byaddr";
|
||||
static /*const*/ char ipnode_byname[] = "ipnode.byname";
|
||||
static /*const*/ char ipnode_byaddr[] = "ipnode.byaddr";
|
||||
static /*const*/ char yp_multi[] = "YP_MULTI_";
|
||||
|
||||
/* Forwards */
|
||||
|
||||
static void ho_close(struct irs_ho *this);
|
||||
static struct hostent * ho_byname(struct irs_ho *this, const char *name);
|
||||
static struct hostent * ho_byname2(struct irs_ho *this, const char *name,
|
||||
int af);
|
||||
static struct hostent * ho_byaddr(struct irs_ho *this, const void *addr,
|
||||
int len, int af);
|
||||
static struct hostent * ho_next(struct irs_ho *this);
|
||||
static void ho_rewind(struct irs_ho *this);
|
||||
static void ho_minimize(struct irs_ho *this);
|
||||
static struct __res_state * ho_res_get(struct irs_ho *this);
|
||||
static void ho_res_set(struct irs_ho *this,
|
||||
struct __res_state *res,
|
||||
void (*free_res)(void *));
|
||||
static struct addrinfo * ho_addrinfo(struct irs_ho *this, const char *name,
|
||||
const struct addrinfo *pai);
|
||||
|
||||
static struct hostent * makehostent(struct irs_ho *this);
|
||||
static void nisfree(struct pvt *, enum do_what);
|
||||
static int init(struct irs_ho *this);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_ho *
|
||||
irs_nis_ho(struct irs_acc *this) {
|
||||
struct irs_ho *ho;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
if (!(ho = memget(sizeof *ho))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(ho, 0x5e, sizeof *ho);
|
||||
pvt->needrewind = 1;
|
||||
pvt->nis_domain = ((struct nis_p *)this->private)->domain;
|
||||
ho->private = pvt;
|
||||
ho->close = ho_close;
|
||||
ho->byname = ho_byname;
|
||||
ho->byname2 = ho_byname2;
|
||||
ho->byaddr = ho_byaddr;
|
||||
ho->next = ho_next;
|
||||
ho->rewind = ho_rewind;
|
||||
ho->minimize = ho_minimize;
|
||||
ho->res_set = ho_res_set;
|
||||
ho->res_get = ho_res_get;
|
||||
ho->addrinfo = ho_addrinfo;
|
||||
return (ho);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
ho_close(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
ho_minimize(this);
|
||||
nisfree(pvt, do_all);
|
||||
if (pvt->res && pvt->free_res)
|
||||
(*pvt->free_res)(pvt->res);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_byname(struct irs_ho *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct hostent *hp;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
if (pvt->res->options & RES_USE_INET6) {
|
||||
hp = ho_byname2(this, name, AF_INET6);
|
||||
if (hp)
|
||||
return (hp);
|
||||
}
|
||||
return (ho_byname2(this, name, AF_INET));
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_byname2(struct irs_ho *this, const char *name, int af) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
int r;
|
||||
char *tmp;
|
||||
|
||||
UNUSED(af);
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
nisfree(pvt, do_val);
|
||||
|
||||
strcpy(pvt->hostbuf, yp_multi);
|
||||
strncat(pvt->hostbuf, name, sizeof(pvt->hostbuf) - sizeof(yp_multi));
|
||||
pvt->hostbuf[sizeof(pvt->hostbuf) - 1] = '\0';
|
||||
for (r = sizeof(yp_multi) - 1; pvt->hostbuf[r] != '\0'; r++)
|
||||
if (isupper((unsigned char)pvt->hostbuf[r]))
|
||||
tolower(pvt->hostbuf[r]);
|
||||
|
||||
tmp = pvt->hostbuf;
|
||||
r = yp_match(pvt->nis_domain, ipnode_byname, tmp,
|
||||
strlen(tmp), &pvt->curval_data, &pvt->curval_len);
|
||||
if (r != 0) {
|
||||
tmp = pvt->hostbuf + sizeof(yp_multi) - 1;
|
||||
r = yp_match(pvt->nis_domain, ipnode_byname, tmp,
|
||||
strlen(tmp), &pvt->curval_data, &pvt->curval_len);
|
||||
}
|
||||
if (r != 0) {
|
||||
tmp = pvt->hostbuf;
|
||||
r = yp_match(pvt->nis_domain, hosts_byname, tmp,
|
||||
strlen(tmp), &pvt->curval_data, &pvt->curval_len);
|
||||
}
|
||||
if (r != 0) {
|
||||
tmp = pvt->hostbuf + sizeof(yp_multi) - 1;
|
||||
r = yp_match(pvt->nis_domain, hosts_byname, tmp,
|
||||
strlen(tmp), &pvt->curval_data, &pvt->curval_len);
|
||||
}
|
||||
if (r != 0) {
|
||||
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
|
||||
return (NULL);
|
||||
}
|
||||
return (makehostent(this));
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
|
||||
const u_char *uaddr = addr;
|
||||
int r;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
if (af == AF_INET6 && len == IN6ADDRSZ &&
|
||||
(!memcmp(uaddr, mapped, sizeof mapped) ||
|
||||
!memcmp(uaddr, tunnelled, sizeof tunnelled))) {
|
||||
/* Unmap. */
|
||||
addr = (const u_char *)addr + sizeof mapped;
|
||||
uaddr += sizeof mapped;
|
||||
af = AF_INET;
|
||||
len = INADDRSZ;
|
||||
}
|
||||
if (inet_ntop(af, uaddr, tmp, sizeof tmp) == NULL) {
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
}
|
||||
nisfree(pvt, do_val);
|
||||
r = yp_match(pvt->nis_domain, ipnode_byaddr, tmp, strlen(tmp),
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
if (r != 0)
|
||||
r = yp_match(pvt->nis_domain, hosts_byaddr, tmp, strlen(tmp),
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
if (r != 0) {
|
||||
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
|
||||
return (NULL);
|
||||
}
|
||||
return (makehostent(this));
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_next(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct hostent *rval;
|
||||
int r;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
do {
|
||||
if (pvt->needrewind) {
|
||||
nisfree(pvt, do_all);
|
||||
r = yp_first(pvt->nis_domain, hosts_byaddr,
|
||||
&pvt->curkey_data, &pvt->curkey_len,
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
pvt->needrewind = 0;
|
||||
} else {
|
||||
char *newkey_data;
|
||||
int newkey_len;
|
||||
|
||||
nisfree(pvt, do_val);
|
||||
r = yp_next(pvt->nis_domain, hosts_byaddr,
|
||||
pvt->curkey_data, pvt->curkey_len,
|
||||
&newkey_data, &newkey_len,
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
nisfree(pvt, do_key);
|
||||
pvt->curkey_data = newkey_data;
|
||||
pvt->curkey_len = newkey_len;
|
||||
}
|
||||
if (r != 0) {
|
||||
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
|
||||
return (NULL);
|
||||
}
|
||||
rval = makehostent(this);
|
||||
} while (rval == NULL);
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static void
|
||||
ho_rewind(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
pvt->needrewind = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
ho_minimize(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->res)
|
||||
res_nclose(pvt->res);
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
ho_res_get(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (!res) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
ho_res_set(this, res, free);
|
||||
}
|
||||
|
||||
return (pvt->res);
|
||||
}
|
||||
|
||||
static void
|
||||
ho_res_set(struct irs_ho *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->res && pvt->free_res) {
|
||||
res_nclose(pvt->res);
|
||||
(*pvt->free_res)(pvt->res);
|
||||
}
|
||||
|
||||
pvt->res = res;
|
||||
pvt->free_res = free_res;
|
||||
}
|
||||
|
||||
struct nis_res_target {
|
||||
struct nis_res_target *next;
|
||||
int family;
|
||||
};
|
||||
|
||||
/* XXX */
|
||||
extern struct addrinfo *hostent2addrinfo __P((struct hostent *,
|
||||
const struct addrinfo *pai));
|
||||
|
||||
static struct addrinfo *
|
||||
ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct hostent *hp;
|
||||
struct nis_res_target q, q2, *p;
|
||||
struct addrinfo sentinel, *cur;
|
||||
|
||||
memset(&q, 0, sizeof(q2));
|
||||
memset(&q2, 0, sizeof(q2));
|
||||
memset(&sentinel, 0, sizeof(sentinel));
|
||||
cur = &sentinel;
|
||||
|
||||
switch(pai->ai_family) {
|
||||
case AF_UNSPEC: /* INET6 then INET4 */
|
||||
q.family = AF_INET6;
|
||||
q.next = &q2;
|
||||
q2.family = AF_INET;
|
||||
break;
|
||||
case AF_INET6:
|
||||
q.family = AF_INET6;
|
||||
break;
|
||||
case AF_INET:
|
||||
q.family = AF_INET;
|
||||
break;
|
||||
default:
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); /* ??? */
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
for (p = &q; p; p = p->next) {
|
||||
struct addrinfo *ai;
|
||||
|
||||
hp = (*this->byname2)(this, name, p->family);
|
||||
if (hp == NULL) {
|
||||
/* byname2 should've set an appropriate error */
|
||||
continue;
|
||||
}
|
||||
if ((hp->h_name == NULL) || (hp->h_name[0] == 0) ||
|
||||
(hp->h_addr_list[0] == NULL)) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
continue;
|
||||
}
|
||||
ai = hostent2addrinfo(hp, pai);
|
||||
if (ai) {
|
||||
cur->ai_next = ai;
|
||||
while (cur && cur->ai_next)
|
||||
cur = cur->ai_next;
|
||||
}
|
||||
}
|
||||
|
||||
if (sentinel.ai_next == NULL)
|
||||
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
|
||||
|
||||
return(sentinel.ai_next);
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
/*
|
||||
ipnodes:
|
||||
::1 localhost
|
||||
127.0.0.1 localhost
|
||||
1.2.3.4 FOO bar
|
||||
1.2.6.4 FOO bar
|
||||
1.2.6.5 host
|
||||
|
||||
ipnodes.byname:
|
||||
YP_MULTI_localhost ::1,127.0.0.1 localhost
|
||||
YP_MULTI_foo 1.2.3.4,1.2.6.4 FOO bar
|
||||
YP_MULTI_bar 1.2.3.4,1.2.6.4 FOO bar
|
||||
host 1.2.6.5 host
|
||||
|
||||
hosts.byname:
|
||||
localhost 127.0.0.1 localhost
|
||||
host 1.2.6.5 host
|
||||
YP_MULTI_foo 1.2.3.4,1.2.6.4 FOO bar
|
||||
YP_MULTI_bar 1.2.3.4,1.2.6.4 FOO bar
|
||||
*/
|
||||
|
||||
static struct hostent *
|
||||
makehostent(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
static const char spaces[] = " \t";
|
||||
char *cp, **q, *p, *comma, *ap;
|
||||
int af = 0, len = 0;
|
||||
int multi = 0;
|
||||
int addr = 0;
|
||||
|
||||
p = pvt->curval_data;
|
||||
if ((cp = strpbrk(p, "#\n")) != NULL)
|
||||
*cp = '\0';
|
||||
if (!(cp = strpbrk(p, spaces)))
|
||||
return (NULL);
|
||||
*cp++ = '\0';
|
||||
ap = pvt->hostbuf;
|
||||
do {
|
||||
if ((comma = strchr(p, ',')) != NULL) {
|
||||
*comma++ = '\0';
|
||||
multi = 1;
|
||||
}
|
||||
if ((ap + IN6ADDRSZ) > (pvt->hostbuf + sizeof(pvt->hostbuf)))
|
||||
break;
|
||||
if ((pvt->res->options & RES_USE_INET6) &&
|
||||
inet_pton(AF_INET6, p, ap) > 0) {
|
||||
af = AF_INET6;
|
||||
len = IN6ADDRSZ;
|
||||
} else if (inet_pton(AF_INET, p, pvt->host_addr) > 0) {
|
||||
if (pvt->res->options & RES_USE_INET6) {
|
||||
map_v4v6_address((char*)pvt->host_addr, ap);
|
||||
af = AF_INET6;
|
||||
len = IN6ADDRSZ;
|
||||
} else {
|
||||
af = AF_INET;
|
||||
len = INADDRSZ;
|
||||
}
|
||||
} else {
|
||||
if (!multi)
|
||||
return (NULL);
|
||||
continue;
|
||||
}
|
||||
if (addr < MAXADDRS) {
|
||||
pvt->h_addr_ptrs[addr++] = ap;
|
||||
pvt->h_addr_ptrs[addr] = NULL;
|
||||
ap += len;
|
||||
}
|
||||
} while ((p = comma) != NULL);
|
||||
if (ap == pvt->hostbuf)
|
||||
return (NULL);
|
||||
pvt->host.h_addr_list = pvt->h_addr_ptrs;
|
||||
pvt->host.h_length = len;
|
||||
pvt->host.h_addrtype = af;
|
||||
cp += strspn(cp, spaces);
|
||||
pvt->host.h_name = cp;
|
||||
q = pvt->host.h_aliases = pvt->host_aliases;
|
||||
if ((cp = strpbrk(cp, spaces)) != NULL)
|
||||
*cp++ = '\0';
|
||||
while (cp && *cp) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &pvt->host_aliases[MAXALIASES])
|
||||
*q++ = cp;
|
||||
if ((cp = strpbrk(cp, spaces)) != NULL)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
*q = NULL;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS);
|
||||
return (&pvt->host);
|
||||
}
|
||||
|
||||
static void
|
||||
nisfree(struct pvt *pvt, enum do_what do_what) {
|
||||
if ((do_what & do_key) && pvt->curkey_data) {
|
||||
free(pvt->curkey_data);
|
||||
pvt->curkey_data = NULL;
|
||||
}
|
||||
if ((do_what & do_val) && pvt->curval_data) {
|
||||
free(pvt->curval_data);
|
||||
pvt->curval_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
init(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res && !ho_res_get(this))
|
||||
return (-1);
|
||||
if (((pvt->res->options & RES_INIT) == 0) &&
|
||||
res_ninit(pvt->res) == -1)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
#endif /*WANT_IRS_NIS*/
|
||||
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: nis_ng.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_NIS
|
||||
static int __bind_irs_nis_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include <isc/assertions.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "nis_p.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
struct tmpgrp {
|
||||
const char * name;
|
||||
const char * host;
|
||||
const char * user;
|
||||
const char * domain;
|
||||
struct tmpgrp * next;
|
||||
};
|
||||
|
||||
struct pvt {
|
||||
char * nis_domain;
|
||||
struct tmpgrp * tmp;
|
||||
struct tmpgrp * cur;
|
||||
char * tmpgroup;
|
||||
};
|
||||
|
||||
enum do_what { do_none = 0x0, do_key = 0x1, do_val = 0x2, do_all = 0x3 };
|
||||
|
||||
static /*const*/ char netgroup_map[] = "netgroup";
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void ng_close(struct irs_ng *);
|
||||
static int ng_next(struct irs_ng *, const char **,
|
||||
const char **, const char **);
|
||||
static int ng_test(struct irs_ng *,
|
||||
const char *, const char *,
|
||||
const char *, const char *);
|
||||
static void ng_rewind(struct irs_ng *, const char *);
|
||||
static void ng_minimize(struct irs_ng *);
|
||||
|
||||
static void add_group_to_list(struct pvt *, const char *, int);
|
||||
static void add_tuple_to_list(struct pvt *, const char *, char *);
|
||||
static void tmpfree(struct pvt *);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_ng *
|
||||
irs_nis_ng(struct irs_acc *this) {
|
||||
struct irs_ng *ng;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(ng = memget(sizeof *ng))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(ng, 0x5e, sizeof *ng);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(ng, sizeof *ng);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->nis_domain = ((struct nis_p *)this->private)->domain;
|
||||
ng->private = pvt;
|
||||
ng->close = ng_close;
|
||||
ng->next = ng_next;
|
||||
ng->test = ng_test;
|
||||
ng->rewind = ng_rewind;
|
||||
ng->minimize = ng_minimize;
|
||||
return (ng);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
ng_close(struct irs_ng *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
tmpfree(pvt);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static int
|
||||
ng_next(struct irs_ng *this, const char **host, const char **user, const char **domain) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->cur)
|
||||
return (0);
|
||||
*host = pvt->cur->host;
|
||||
*user = pvt->cur->user;
|
||||
*domain = pvt->cur->domain;
|
||||
pvt->cur = pvt->cur->next;
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
ng_test(struct irs_ng *this, const char *name,
|
||||
const char *host, const char *user, const char *domain)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct tmpgrp *cur;
|
||||
|
||||
tmpfree(pvt);
|
||||
add_group_to_list(pvt, name, strlen(name));
|
||||
for (cur = pvt->tmp; cur; cur = cur->next) {
|
||||
if ((!host || !cur->host || !strcmp(host, cur->host)) &&
|
||||
(!user || !cur->user || !strcmp(user, cur->user)) &&
|
||||
(!domain || !cur->domain || !strcmp(domain, cur->domain)))
|
||||
break;
|
||||
}
|
||||
tmpfree(pvt);
|
||||
return ((cur == NULL) ? 0 : 1);
|
||||
}
|
||||
|
||||
static void
|
||||
ng_rewind(struct irs_ng *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
/* Either hand back or free the existing list. */
|
||||
if (pvt->tmpgroup) {
|
||||
if (pvt->tmp && !strcmp(pvt->tmpgroup, name))
|
||||
goto reset;
|
||||
tmpfree(pvt);
|
||||
}
|
||||
pvt->tmpgroup = strdup(name);
|
||||
add_group_to_list(pvt, name, strlen(name));
|
||||
reset:
|
||||
pvt->cur = pvt->tmp;
|
||||
}
|
||||
|
||||
static void
|
||||
ng_minimize(struct irs_ng *this) {
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static void
|
||||
add_group_to_list(struct pvt *pvt, const char *name, int len) {
|
||||
char *vdata, *cp, *np;
|
||||
struct tmpgrp *tmp;
|
||||
int vlen, r;
|
||||
char *nametmp;
|
||||
|
||||
/* Don't add the same group to the list more than once. */
|
||||
for (tmp = pvt->tmp; tmp; tmp = tmp->next)
|
||||
if (!strcmp(tmp->name, name))
|
||||
return;
|
||||
|
||||
DE_CONST(name, nametmp);
|
||||
r = yp_match(pvt->nis_domain, netgroup_map, nametmp, len,
|
||||
&vdata, &vlen);
|
||||
if (r == 0) {
|
||||
cp = vdata;
|
||||
if (*cp && cp[strlen(cp)-1] == '\n')
|
||||
cp[strlen(cp)-1] = '\0';
|
||||
for ( ; cp; cp = np) {
|
||||
np = strchr(cp, ' ');
|
||||
if (np)
|
||||
*np++ = '\0';
|
||||
if (*cp == '(')
|
||||
add_tuple_to_list(pvt, name, cp);
|
||||
else
|
||||
add_group_to_list(pvt, cp, strlen(cp));
|
||||
}
|
||||
free(vdata);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_tuple_to_list(struct pvt *pvt, const char *name, char *cp) {
|
||||
struct tmpgrp *tmp;
|
||||
char *tp, *np;
|
||||
|
||||
INSIST(*cp++ == '(');
|
||||
|
||||
tmp = malloc(sizeof *tmp + strlen(name) + sizeof '\0' +
|
||||
strlen(cp) - sizeof ')');
|
||||
if (!tmp)
|
||||
return;
|
||||
memset(tmp, 0, sizeof *tmp);
|
||||
tp = ((char *)tmp) + sizeof *tmp;
|
||||
|
||||
/* Name */
|
||||
strcpy(tp, name);
|
||||
tmp->name = tp;
|
||||
tp += strlen(tp) + 1;
|
||||
|
||||
/* Host */
|
||||
if (!(np = strchr(cp, ',')))
|
||||
goto cleanup;
|
||||
*np++ = '\0';
|
||||
strcpy(tp, cp);
|
||||
tmp->host = tp;
|
||||
tp += strlen(tp) + 1;
|
||||
cp = np;
|
||||
|
||||
/* User */
|
||||
if (!(np = strchr(cp, ',')))
|
||||
goto cleanup;
|
||||
*np++ = '\0';
|
||||
strcpy(tp, cp);
|
||||
tmp->user = tp;
|
||||
tp += strlen(tp) + 1;
|
||||
cp = np;
|
||||
|
||||
/* Domain */
|
||||
if (!(np = strchr(cp, ')')))
|
||||
goto cleanup;
|
||||
*np++ = '\0';
|
||||
strcpy(tp, cp);
|
||||
tmp->domain = tp;
|
||||
|
||||
/*
|
||||
* Empty string in file means wildcard, but
|
||||
* NULL string in return value means wildcard.
|
||||
*/
|
||||
if (!*tmp->host)
|
||||
tmp->host = NULL;
|
||||
if (!*tmp->user)
|
||||
tmp->user = NULL;
|
||||
if (!*tmp->domain)
|
||||
tmp->domain = NULL;
|
||||
|
||||
/* Add to list (LIFO). */
|
||||
tmp->next = pvt->tmp;
|
||||
pvt->tmp = tmp;
|
||||
return;
|
||||
|
||||
cleanup:
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
static void
|
||||
tmpfree(struct pvt *pvt) {
|
||||
struct tmpgrp *cur, *next;
|
||||
|
||||
if (pvt->tmpgroup) {
|
||||
free(pvt->tmpgroup);
|
||||
pvt->tmpgroup = NULL;
|
||||
}
|
||||
for (cur = pvt->tmp; cur; cur = next) {
|
||||
next = cur->next;
|
||||
free(cur);
|
||||
}
|
||||
pvt->tmp = NULL;
|
||||
}
|
||||
|
||||
#endif /*WANT_IRS_NIS*/
|
||||
@@ -0,0 +1,381 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: nis_nw.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_NIS
|
||||
static int __bind_irs_nis_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "nis_p.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
#define MAXALIASES 35
|
||||
#define MAXADDRSIZE 4
|
||||
|
||||
struct pvt {
|
||||
int needrewind;
|
||||
char * nis_domain;
|
||||
char * curkey_data;
|
||||
int curkey_len;
|
||||
char * curval_data;
|
||||
int curval_len;
|
||||
|
||||
struct nwent nwent;
|
||||
char * nwbuf;
|
||||
|
||||
char * aliases[MAXALIASES + 1];
|
||||
u_char addr[MAXADDRSIZE];
|
||||
|
||||
struct __res_state * res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
enum do_what { do_none = 0x0, do_key = 0x1, do_val = 0x2, do_all = 0x3 };
|
||||
|
||||
static /*const*/ char networks_byname[] = "networks.byname";
|
||||
static /*const*/ char networks_byaddr[] = "networks.byaddr";
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void nw_close(struct irs_nw *);
|
||||
static struct nwent * nw_byname(struct irs_nw *, const char *, int);
|
||||
static struct nwent * nw_byaddr(struct irs_nw *, void *, int, int);
|
||||
static struct nwent * nw_next(struct irs_nw *);
|
||||
static void nw_rewind(struct irs_nw *);
|
||||
static void nw_minimize(struct irs_nw *);
|
||||
static struct __res_state * nw_res_get(struct irs_nw *this);
|
||||
static void nw_res_set(struct irs_nw *this,
|
||||
struct __res_state *res,
|
||||
void (*free_res)(void *));
|
||||
|
||||
static struct nwent * makenwent(struct irs_nw *this);
|
||||
static void nisfree(struct pvt *, enum do_what);
|
||||
static int init(struct irs_nw *this);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_nw *
|
||||
irs_nis_nw(struct irs_acc *this) {
|
||||
struct irs_nw *nw;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
if (!(nw = memget(sizeof *nw))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(nw, 0x5e, sizeof *nw);
|
||||
pvt->needrewind = 1;
|
||||
pvt->nis_domain = ((struct nis_p *)this->private)->domain;
|
||||
nw->private = pvt;
|
||||
nw->close = nw_close;
|
||||
nw->byname = nw_byname;
|
||||
nw->byaddr = nw_byaddr;
|
||||
nw->next = nw_next;
|
||||
nw->rewind = nw_rewind;
|
||||
nw->minimize = nw_minimize;
|
||||
nw->res_get = nw_res_get;
|
||||
nw->res_set = nw_res_set;
|
||||
return (nw);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
nw_close(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
nw_minimize(this);
|
||||
if (pvt->res && pvt->free_res)
|
||||
(*pvt->free_res)(pvt->res);
|
||||
if (pvt->nwbuf)
|
||||
free(pvt->nwbuf);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
nw_byaddr(struct irs_nw *this, void *net, int length, int af) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char tmp[sizeof "255.255.255.255/32"], *t;
|
||||
int r;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
if (af != AF_INET) {
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
errno = EAFNOSUPPORT;
|
||||
return (NULL);
|
||||
}
|
||||
nisfree(pvt, do_val);
|
||||
/* Try it with /CIDR first. */
|
||||
if (inet_net_ntop(AF_INET, net, length, tmp, sizeof tmp) == NULL) {
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
}
|
||||
r = yp_match(pvt->nis_domain, networks_byaddr, tmp, strlen(tmp),
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
if (r != 0) {
|
||||
/* Give it a shot without the /CIDR. */
|
||||
if ((t = strchr(tmp, '/')) != NULL) {
|
||||
*t = '\0';
|
||||
r = yp_match(pvt->nis_domain, networks_byaddr,
|
||||
tmp, strlen(tmp),
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
}
|
||||
if (r != 0) {
|
||||
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
return (makenwent(this));
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
nw_byname(struct irs_nw *this, const char *name, int af) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
int r;
|
||||
char *tmp;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
if (af != AF_INET) {
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
errno = EAFNOSUPPORT;
|
||||
return (NULL);
|
||||
}
|
||||
nisfree(pvt, do_val);
|
||||
DE_CONST(name, tmp);
|
||||
r = yp_match(pvt->nis_domain, networks_byname, tmp,
|
||||
strlen(tmp), &pvt->curval_data, &pvt->curval_len);
|
||||
if (r != 0) {
|
||||
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
|
||||
return (NULL);
|
||||
}
|
||||
return (makenwent(this));
|
||||
}
|
||||
|
||||
static void
|
||||
nw_rewind(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
pvt->needrewind = 1;
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
nw_next(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct nwent *rval;
|
||||
int r;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
do {
|
||||
if (pvt->needrewind) {
|
||||
nisfree(pvt, do_all);
|
||||
r = yp_first(pvt->nis_domain, networks_byaddr,
|
||||
&pvt->curkey_data, &pvt->curkey_len,
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
pvt->needrewind = 0;
|
||||
} else {
|
||||
char *newkey_data;
|
||||
int newkey_len;
|
||||
|
||||
nisfree(pvt, do_val);
|
||||
r = yp_next(pvt->nis_domain, networks_byaddr,
|
||||
pvt->curkey_data, pvt->curkey_len,
|
||||
&newkey_data, &newkey_len,
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
nisfree(pvt, do_key);
|
||||
pvt->curkey_data = newkey_data;
|
||||
pvt->curkey_len = newkey_len;
|
||||
}
|
||||
if (r != 0) {
|
||||
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
|
||||
return (NULL);
|
||||
}
|
||||
rval = makenwent(this);
|
||||
} while (rval == NULL);
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static void
|
||||
nw_minimize(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->res)
|
||||
res_nclose(pvt->res);
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
nw_res_get(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (!res) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
nw_res_set(this, res, free);
|
||||
}
|
||||
|
||||
return (pvt->res);
|
||||
}
|
||||
|
||||
static void
|
||||
nw_res_set(struct irs_nw *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->res && pvt->free_res) {
|
||||
res_nclose(pvt->res);
|
||||
(*pvt->free_res)(pvt->res);
|
||||
}
|
||||
|
||||
pvt->res = res;
|
||||
pvt->free_res = free_res;
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static struct nwent *
|
||||
makenwent(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
static const char spaces[] = " \t";
|
||||
char *t, *cp, **ap;
|
||||
|
||||
if (pvt->nwbuf)
|
||||
free(pvt->nwbuf);
|
||||
pvt->nwbuf = pvt->curval_data;
|
||||
pvt->curval_data = NULL;
|
||||
|
||||
if ((cp = strpbrk(pvt->nwbuf, "#\n")) != NULL)
|
||||
*cp = '\0';
|
||||
cp = pvt->nwbuf;
|
||||
|
||||
/* Name */
|
||||
pvt->nwent.n_name = cp;
|
||||
cp += strcspn(cp, spaces);
|
||||
if (!*cp)
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
cp += strspn(cp, spaces);
|
||||
|
||||
/* Network */
|
||||
pvt->nwent.n_addrtype = AF_INET;
|
||||
t = cp + strcspn(cp, spaces);
|
||||
if (*t)
|
||||
*t++ = '\0';
|
||||
pvt->nwent.n_length = inet_net_pton(AF_INET, cp,
|
||||
pvt->addr, sizeof pvt->addr);
|
||||
if (pvt->nwent.n_length < 0)
|
||||
goto cleanup;
|
||||
pvt->nwent.n_addr = pvt->addr;
|
||||
cp = t;
|
||||
|
||||
/* Aliases */
|
||||
ap = pvt->nwent.n_aliases = pvt->aliases;
|
||||
while (*cp) {
|
||||
if (ap >= &pvt->aliases[MAXALIASES])
|
||||
break;
|
||||
*ap++ = cp;
|
||||
cp += strcspn(cp, spaces);
|
||||
if (!*cp)
|
||||
break;
|
||||
*cp++ = '\0';
|
||||
cp += strspn(cp, spaces);
|
||||
}
|
||||
*ap = NULL;
|
||||
|
||||
return (&pvt->nwent);
|
||||
|
||||
cleanup:
|
||||
if (pvt->nwbuf) {
|
||||
free(pvt->nwbuf);
|
||||
pvt->nwbuf = NULL;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
nisfree(struct pvt *pvt, enum do_what do_what) {
|
||||
if ((do_what & do_key) && pvt->curkey_data) {
|
||||
free(pvt->curkey_data);
|
||||
pvt->curkey_data = NULL;
|
||||
}
|
||||
if ((do_what & do_val) && pvt->curval_data) {
|
||||
free(pvt->curval_data);
|
||||
pvt->curval_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
init(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res && !nw_res_get(this))
|
||||
return (-1);
|
||||
if (((pvt->res->options & RES_INIT) == 0) &&
|
||||
res_ninit(pvt->res) == -1)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif /*WANT_IRS_NIS*/
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: nis_p.h,v 1.1 2004/04/15 16:03:29 wkornew Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* nis_p.h - private include file for the NIS functions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Object state.
|
||||
*/
|
||||
struct nis_p {
|
||||
char * domain;
|
||||
struct __res_state * res;
|
||||
void (*free_res) __P((void *));
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Methods.
|
||||
*/
|
||||
|
||||
extern struct irs_gr * irs_nis_gr __P((struct irs_acc *));
|
||||
extern struct irs_pw * irs_nis_pw __P((struct irs_acc *));
|
||||
extern struct irs_sv * irs_nis_sv __P((struct irs_acc *));
|
||||
extern struct irs_pr * irs_nis_pr __P((struct irs_acc *));
|
||||
extern struct irs_ho * irs_nis_ho __P((struct irs_acc *));
|
||||
extern struct irs_nw * irs_nis_nw __P((struct irs_acc *));
|
||||
extern struct irs_ng * irs_nis_ng __P((struct irs_acc *));
|
||||
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: nis_pr.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_NIS
|
||||
static int __bind_irs_nis_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "nis_p.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
struct pvt {
|
||||
int needrewind;
|
||||
char * nis_domain;
|
||||
char * curkey_data;
|
||||
int curkey_len;
|
||||
char * curval_data;
|
||||
int curval_len;
|
||||
struct protoent proto;
|
||||
char * prbuf;
|
||||
};
|
||||
|
||||
enum do_what { do_none = 0x0, do_key = 0x1, do_val = 0x2, do_all = 0x3 };
|
||||
|
||||
static /*const*/ char protocols_byname[] = "protocols.byname";
|
||||
static /*const*/ char protocols_bynumber[] = "protocols.bynumber";
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void pr_close(struct irs_pr *);
|
||||
static struct protoent * pr_byname(struct irs_pr *, const char *);
|
||||
static struct protoent * pr_bynumber(struct irs_pr *, int);
|
||||
static struct protoent * pr_next(struct irs_pr *);
|
||||
static void pr_rewind(struct irs_pr *);
|
||||
static void pr_minimize(struct irs_pr *);
|
||||
|
||||
static struct protoent * makeprotoent(struct irs_pr *this);
|
||||
static void nisfree(struct pvt *, enum do_what);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_pr *
|
||||
irs_nis_pr(struct irs_acc *this) {
|
||||
struct irs_pr *pr;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(pr = memget(sizeof *pr))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pr, 0x5e, sizeof *pr);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(pr, sizeof *pr);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->needrewind = 1;
|
||||
pvt->nis_domain = ((struct nis_p *)this->private)->domain;
|
||||
pr->private = pvt;
|
||||
pr->byname = pr_byname;
|
||||
pr->bynumber = pr_bynumber;
|
||||
pr->next = pr_next;
|
||||
pr->rewind = pr_rewind;
|
||||
pr->close = pr_close;
|
||||
pr->minimize = pr_minimize;
|
||||
pr->res_get = NULL;
|
||||
pr->res_set = NULL;
|
||||
return (pr);
|
||||
}
|
||||
|
||||
/* Methods. */
|
||||
|
||||
static void
|
||||
pr_close(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
nisfree(pvt, do_all);
|
||||
if (pvt->proto.p_aliases)
|
||||
free(pvt->proto.p_aliases);
|
||||
if (pvt->prbuf)
|
||||
free(pvt->prbuf);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct protoent *
|
||||
pr_byname(struct irs_pr *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
int r;
|
||||
char *tmp;
|
||||
|
||||
nisfree(pvt, do_val);
|
||||
DE_CONST(name, tmp);
|
||||
r = yp_match(pvt->nis_domain, protocols_byname, tmp,
|
||||
strlen(tmp), &pvt->curval_data, &pvt->curval_len);
|
||||
if (r != 0) {
|
||||
errno = ENOENT;
|
||||
return (NULL);
|
||||
}
|
||||
return (makeprotoent(this));
|
||||
}
|
||||
|
||||
static struct protoent *
|
||||
pr_bynumber(struct irs_pr *this, int num) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char tmp[sizeof "-4294967295"];
|
||||
int r;
|
||||
|
||||
nisfree(pvt, do_val);
|
||||
(void) sprintf(tmp, "%d", num);
|
||||
r = yp_match(pvt->nis_domain, protocols_bynumber, tmp, strlen(tmp),
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
if (r != 0) {
|
||||
errno = ENOENT;
|
||||
return (NULL);
|
||||
}
|
||||
return (makeprotoent(this));
|
||||
}
|
||||
|
||||
static struct protoent *
|
||||
pr_next(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct protoent *rval;
|
||||
int r;
|
||||
|
||||
do {
|
||||
if (pvt->needrewind) {
|
||||
nisfree(pvt, do_all);
|
||||
r = yp_first(pvt->nis_domain, protocols_bynumber,
|
||||
&pvt->curkey_data, &pvt->curkey_len,
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
pvt->needrewind = 0;
|
||||
} else {
|
||||
char *newkey_data;
|
||||
int newkey_len;
|
||||
|
||||
nisfree(pvt, do_val);
|
||||
r = yp_next(pvt->nis_domain, protocols_bynumber,
|
||||
pvt->curkey_data, pvt->curkey_len,
|
||||
&newkey_data, &newkey_len,
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
nisfree(pvt, do_key);
|
||||
pvt->curkey_data = newkey_data;
|
||||
pvt->curkey_len = newkey_len;
|
||||
}
|
||||
if (r != 0) {
|
||||
errno = ENOENT;
|
||||
return (NULL);
|
||||
}
|
||||
rval = makeprotoent(this);
|
||||
} while (rval == NULL);
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static void
|
||||
pr_rewind(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
pvt->needrewind = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
pr_minimize(struct irs_pr *this) {
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static struct protoent *
|
||||
makeprotoent(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char *p, **t;
|
||||
int n, m;
|
||||
|
||||
if (pvt->prbuf)
|
||||
free(pvt->prbuf);
|
||||
pvt->prbuf = pvt->curval_data;
|
||||
pvt->curval_data = NULL;
|
||||
|
||||
for (p = pvt->prbuf; *p && *p != '#';)
|
||||
p++;
|
||||
while (p > pvt->prbuf && isspace((unsigned char)(p[-1])))
|
||||
p--;
|
||||
*p = '\0';
|
||||
|
||||
p = pvt->prbuf;
|
||||
n = m = 0;
|
||||
|
||||
pvt->proto.p_name = p;
|
||||
while (*p && !isspace((unsigned char)*p))
|
||||
p++;
|
||||
if (!*p)
|
||||
return (NULL);
|
||||
*p++ = '\0';
|
||||
|
||||
while (*p && isspace((unsigned char)*p))
|
||||
p++;
|
||||
pvt->proto.p_proto = atoi(p);
|
||||
while (*p && !isspace((unsigned char)*p))
|
||||
p++;
|
||||
*p++ = '\0';
|
||||
|
||||
while (*p) {
|
||||
if ((n + 1) >= m || !pvt->proto.p_aliases) {
|
||||
m += 10;
|
||||
t = realloc(pvt->proto.p_aliases,
|
||||
m * sizeof(char *));
|
||||
if (!t) {
|
||||
errno = ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
pvt->proto.p_aliases = t;
|
||||
}
|
||||
pvt->proto.p_aliases[n++] = p;
|
||||
while (*p && !isspace((unsigned char)*p))
|
||||
p++;
|
||||
if (*p)
|
||||
*p++ = '\0';
|
||||
}
|
||||
if (!pvt->proto.p_aliases)
|
||||
pvt->proto.p_aliases = malloc(sizeof(char *));
|
||||
if (!pvt->proto.p_aliases)
|
||||
goto cleanup;
|
||||
pvt->proto.p_aliases[n] = NULL;
|
||||
return (&pvt->proto);
|
||||
|
||||
cleanup:
|
||||
if (pvt->proto.p_aliases) {
|
||||
free(pvt->proto.p_aliases);
|
||||
pvt->proto.p_aliases = NULL;
|
||||
}
|
||||
if (pvt->prbuf) {
|
||||
free(pvt->prbuf);
|
||||
pvt->prbuf = NULL;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
nisfree(struct pvt *pvt, enum do_what do_what) {
|
||||
if ((do_what & do_key) && pvt->curkey_data) {
|
||||
free(pvt->curkey_data);
|
||||
pvt->curkey_data = NULL;
|
||||
}
|
||||
if ((do_what & do_val) && pvt->curval_data) {
|
||||
free(pvt->curval_data);
|
||||
pvt->curval_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*WANT_IRS_NIS*/
|
||||
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: nis_pw.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#if !defined(WANT_IRS_PW) || !defined(WANT_IRS_NIS)
|
||||
static int __bind_irs_pw_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
#include <isc/memcluster.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "nis_p.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
struct pvt {
|
||||
int needrewind;
|
||||
char * nis_domain;
|
||||
char * curkey_data;
|
||||
int curkey_len;
|
||||
char * curval_data;
|
||||
int curval_len;
|
||||
struct passwd passwd;
|
||||
char * pwbuf;
|
||||
};
|
||||
|
||||
enum do_what { do_none = 0x0, do_key = 0x1, do_val = 0x2, do_all = 0x3 };
|
||||
|
||||
static /*const*/ char passwd_byname[] = "passwd.byname";
|
||||
static /*const*/ char passwd_byuid[] = "passwd.byuid";
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void pw_close(struct irs_pw *);
|
||||
static struct passwd * pw_next(struct irs_pw *);
|
||||
static struct passwd * pw_byname(struct irs_pw *, const char *);
|
||||
static struct passwd * pw_byuid(struct irs_pw *, uid_t);
|
||||
static void pw_rewind(struct irs_pw *);
|
||||
static void pw_minimize(struct irs_pw *);
|
||||
|
||||
static struct passwd * makepasswdent(struct irs_pw *);
|
||||
static void nisfree(struct pvt *, enum do_what);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_pw *
|
||||
irs_nis_pw(struct irs_acc *this) {
|
||||
struct irs_pw *pw;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(pw = memget(sizeof *pw))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pw, 0x5e, sizeof *pw);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(pw, sizeof *pw);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->needrewind = 1;
|
||||
pvt->nis_domain = ((struct nis_p *)this->private)->domain;
|
||||
pw->private = pvt;
|
||||
pw->close = pw_close;
|
||||
pw->next = pw_next;
|
||||
pw->byname = pw_byname;
|
||||
pw->byuid = pw_byuid;
|
||||
pw->rewind = pw_rewind;
|
||||
pw->minimize = pw_minimize;
|
||||
pw->res_get = NULL;
|
||||
pw->res_set = NULL;
|
||||
return (pw);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
pw_close(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->pwbuf)
|
||||
free(pvt->pwbuf);
|
||||
nisfree(pvt, do_all);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
pw_next(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct passwd *rval;
|
||||
int r;
|
||||
|
||||
do {
|
||||
if (pvt->needrewind) {
|
||||
nisfree(pvt, do_all);
|
||||
r = yp_first(pvt->nis_domain, passwd_byname,
|
||||
&pvt->curkey_data, &pvt->curkey_len,
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
pvt->needrewind = 0;
|
||||
} else {
|
||||
char *newkey_data;
|
||||
int newkey_len;
|
||||
|
||||
nisfree(pvt, do_val);
|
||||
r = yp_next(pvt->nis_domain, passwd_byname,
|
||||
pvt->curkey_data, pvt->curkey_len,
|
||||
&newkey_data, &newkey_len,
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
nisfree(pvt, do_key);
|
||||
pvt->curkey_data = newkey_data;
|
||||
pvt->curkey_len = newkey_len;
|
||||
}
|
||||
if (r != 0) {
|
||||
errno = ENOENT;
|
||||
return (NULL);
|
||||
}
|
||||
rval = makepasswdent(this);
|
||||
} while (rval == NULL);
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
pw_byname(struct irs_pw *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
int r;
|
||||
char *tmp;
|
||||
|
||||
nisfree(pvt, do_val);
|
||||
DE_CONST(name, tmp);
|
||||
r = yp_match(pvt->nis_domain, passwd_byname, tmp, strlen(tmp),
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
if (r != 0) {
|
||||
errno = ENOENT;
|
||||
return (NULL);
|
||||
}
|
||||
return (makepasswdent(this));
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
pw_byuid(struct irs_pw *this, uid_t uid) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char tmp[sizeof "4294967295"];
|
||||
int r;
|
||||
|
||||
nisfree(pvt, do_val);
|
||||
(void) sprintf(tmp, "%u", (unsigned int)uid);
|
||||
r = yp_match(pvt->nis_domain, passwd_byuid, tmp, strlen(tmp),
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
if (r != 0) {
|
||||
errno = ENOENT;
|
||||
return (NULL);
|
||||
}
|
||||
return (makepasswdent(this));
|
||||
}
|
||||
|
||||
static void
|
||||
pw_rewind(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
pvt->needrewind = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
pw_minimize(struct irs_pw *this) {
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static struct passwd *
|
||||
makepasswdent(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char *cp;
|
||||
|
||||
memset(&pvt->passwd, 0, sizeof pvt->passwd);
|
||||
if (pvt->pwbuf)
|
||||
free(pvt->pwbuf);
|
||||
pvt->pwbuf = pvt->curval_data;
|
||||
pvt->curval_data = NULL;
|
||||
|
||||
cp = pvt->pwbuf;
|
||||
pvt->passwd.pw_name = cp;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
#ifdef HAS_PW_CLASS
|
||||
pvt->passwd.pw_class = cp; /* Needs to point at a \0. */
|
||||
#endif
|
||||
*cp++ = '\0';
|
||||
|
||||
pvt->passwd.pw_passwd = cp;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
pvt->passwd.pw_uid = atoi(cp);
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
pvt->passwd.pw_gid = atoi(cp);
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
pvt->passwd.pw_gecos = cp;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
pvt->passwd.pw_dir = cp;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
pvt->passwd.pw_shell = cp;
|
||||
|
||||
if ((cp = strchr(cp, '\n')) != NULL)
|
||||
*cp = '\0';
|
||||
|
||||
return (&pvt->passwd);
|
||||
|
||||
cleanup:
|
||||
free(pvt->pwbuf);
|
||||
pvt->pwbuf = NULL;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
nisfree(struct pvt *pvt, enum do_what do_what) {
|
||||
if ((do_what & do_key) && pvt->curkey_data) {
|
||||
free(pvt->curkey_data);
|
||||
pvt->curkey_data = NULL;
|
||||
}
|
||||
if ((do_what & do_val) && pvt->curval_data) {
|
||||
free(pvt->curval_data);
|
||||
pvt->curval_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* WANT_IRS_PW && WANT_IRS_NIS */
|
||||
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: nis_sv.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_NIS
|
||||
static int __bind_irs_nis_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
#include <sys/socket.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "nis_p.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
struct pvt {
|
||||
int needrewind;
|
||||
char * nis_domain;
|
||||
char * curkey_data;
|
||||
int curkey_len;
|
||||
char * curval_data;
|
||||
int curval_len;
|
||||
char line[BUFSIZ+1];
|
||||
struct servent serv;
|
||||
char * svbuf;
|
||||
};
|
||||
|
||||
enum do_what { do_none = 0x0, do_key = 0x1, do_val = 0x2, do_all = 0x3 };
|
||||
|
||||
static /*const*/ char services_byname[] = "services.byname";
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void sv_close(struct irs_sv*);
|
||||
static struct servent * sv_next(struct irs_sv *);
|
||||
static struct servent * sv_byname(struct irs_sv *, const char *,
|
||||
const char *);
|
||||
static struct servent * sv_byport(struct irs_sv *, int, const char *);
|
||||
static void sv_rewind(struct irs_sv *);
|
||||
static void sv_minimize(struct irs_sv *);
|
||||
|
||||
static struct servent * makeservent(struct irs_sv *this);
|
||||
static void nisfree(struct pvt *, enum do_what);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_sv *
|
||||
irs_nis_sv(struct irs_acc *this) {
|
||||
struct irs_sv *sv;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(sv = memget(sizeof *sv))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(sv, 0x5e, sizeof *sv);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(sv, sizeof *sv);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->needrewind = 1;
|
||||
pvt->nis_domain = ((struct nis_p *)this->private)->domain;
|
||||
sv->private = pvt;
|
||||
sv->close = sv_close;
|
||||
sv->next = sv_next;
|
||||
sv->byname = sv_byname;
|
||||
sv->byport = sv_byport;
|
||||
sv->rewind = sv_rewind;
|
||||
sv->minimize = sv_minimize;
|
||||
sv->res_get = NULL;
|
||||
sv->res_set = NULL;
|
||||
return (sv);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
sv_close(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
nisfree(pvt, do_all);
|
||||
if (pvt->serv.s_aliases)
|
||||
free(pvt->serv.s_aliases);
|
||||
if (pvt->svbuf)
|
||||
free(pvt->svbuf);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct servent *
|
||||
sv_byname(struct irs_sv *this, const char *name, const char *proto) {
|
||||
struct servent *serv;
|
||||
char **sap;
|
||||
|
||||
sv_rewind(this);
|
||||
while ((serv = sv_next(this)) != NULL) {
|
||||
if (proto != NULL && strcmp(proto, serv->s_proto))
|
||||
continue;
|
||||
if (!strcmp(name, serv->s_name))
|
||||
break;
|
||||
for (sap = serv->s_aliases; sap && *sap; sap++)
|
||||
if (!strcmp(name, *sap))
|
||||
break;
|
||||
}
|
||||
return (serv);
|
||||
}
|
||||
|
||||
static struct servent *
|
||||
sv_byport(struct irs_sv *this, int port, const char *proto) {
|
||||
struct servent *serv;
|
||||
|
||||
sv_rewind(this);
|
||||
while ((serv = sv_next(this)) != NULL) {
|
||||
if (proto != NULL && strcmp(proto, serv->s_proto))
|
||||
continue;
|
||||
if (serv->s_port == port)
|
||||
break;
|
||||
}
|
||||
return (serv);
|
||||
}
|
||||
|
||||
static void
|
||||
sv_rewind(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
pvt->needrewind = 1;
|
||||
}
|
||||
|
||||
static struct servent *
|
||||
sv_next(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct servent *rval;
|
||||
int r;
|
||||
|
||||
do {
|
||||
if (pvt->needrewind) {
|
||||
nisfree(pvt, do_all);
|
||||
r = yp_first(pvt->nis_domain, services_byname,
|
||||
&pvt->curkey_data, &pvt->curkey_len,
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
pvt->needrewind = 0;
|
||||
} else {
|
||||
char *newkey_data;
|
||||
int newkey_len;
|
||||
|
||||
nisfree(pvt, do_val);
|
||||
r = yp_next(pvt->nis_domain, services_byname,
|
||||
pvt->curkey_data, pvt->curkey_len,
|
||||
&newkey_data, &newkey_len,
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
nisfree(pvt, do_key);
|
||||
pvt->curkey_data = newkey_data;
|
||||
pvt->curkey_len = newkey_len;
|
||||
}
|
||||
if (r != 0) {
|
||||
errno = ENOENT;
|
||||
return (NULL);
|
||||
}
|
||||
rval = makeservent(this);
|
||||
} while (rval == NULL);
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static void
|
||||
sv_minimize(struct irs_sv *this) {
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static struct servent *
|
||||
makeservent(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
static const char spaces[] = " \t";
|
||||
char *p, **t;
|
||||
int n, m;
|
||||
|
||||
if (pvt->svbuf)
|
||||
free(pvt->svbuf);
|
||||
pvt->svbuf = pvt->curval_data;
|
||||
pvt->curval_data = NULL;
|
||||
|
||||
if (pvt->serv.s_aliases) {
|
||||
free(pvt->serv.s_aliases);
|
||||
pvt->serv.s_aliases = NULL;
|
||||
}
|
||||
|
||||
if ((p = strpbrk(pvt->svbuf, "#\n")))
|
||||
*p = '\0';
|
||||
|
||||
p = pvt->svbuf;
|
||||
|
||||
pvt->serv.s_name = p;
|
||||
p += strcspn(p, spaces);
|
||||
if (!*p)
|
||||
goto cleanup;
|
||||
*p++ = '\0';
|
||||
p += strspn(p, spaces);
|
||||
|
||||
pvt->serv.s_port = htons((u_short) atoi(p));
|
||||
pvt->serv.s_proto = NULL;
|
||||
|
||||
while (*p && !isspace((unsigned char)*p))
|
||||
if (*p++ == '/')
|
||||
pvt->serv.s_proto = p;
|
||||
if (!pvt->serv.s_proto)
|
||||
goto cleanup;
|
||||
if (*p) {
|
||||
*p++ = '\0';
|
||||
p += strspn(p, spaces);
|
||||
}
|
||||
|
||||
n = m = 0;
|
||||
while (*p) {
|
||||
if ((n + 1) >= m || !pvt->serv.s_aliases) {
|
||||
m += 10;
|
||||
t = realloc(pvt->serv.s_aliases, m * sizeof(char *));
|
||||
if (!t) {
|
||||
errno = ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
pvt->serv.s_aliases = t;
|
||||
}
|
||||
pvt->serv.s_aliases[n++] = p;
|
||||
p += strcspn(p, spaces);
|
||||
if (!*p)
|
||||
break;
|
||||
*p++ = '\0';
|
||||
p += strspn(p, spaces);
|
||||
}
|
||||
if (!pvt->serv.s_aliases)
|
||||
pvt->serv.s_aliases = malloc(sizeof(char *));
|
||||
if (!pvt->serv.s_aliases)
|
||||
goto cleanup;
|
||||
pvt->serv.s_aliases[n] = NULL;
|
||||
return (&pvt->serv);
|
||||
|
||||
cleanup:
|
||||
if (pvt->serv.s_aliases) {
|
||||
free(pvt->serv.s_aliases);
|
||||
pvt->serv.s_aliases = NULL;
|
||||
}
|
||||
if (pvt->svbuf) {
|
||||
free(pvt->svbuf);
|
||||
pvt->svbuf = NULL;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
nisfree(struct pvt *pvt, enum do_what do_what) {
|
||||
if ((do_what & do_key) && pvt->curkey_data) {
|
||||
free(pvt->curkey_data);
|
||||
pvt->curkey_data = NULL;
|
||||
}
|
||||
if ((do_what & do_val) && pvt->curval_data) {
|
||||
free(pvt->curval_data);
|
||||
pvt->curval_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*WANT_IRS_NIS*/
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: nul_ng.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* nul_ng.c - the netgroup accessor null map
|
||||
*/
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "hesiod.h"
|
||||
#include "dns_p.h"
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static void ng_close(struct irs_ng *);
|
||||
static int ng_next(struct irs_ng *, const char **,
|
||||
const char **, const char **);
|
||||
static int ng_test(struct irs_ng *,
|
||||
const char *, const char *,
|
||||
const char *, const char *);
|
||||
static void ng_rewind(struct irs_ng *, const char *);
|
||||
static void ng_minimize(struct irs_ng *);
|
||||
|
||||
/* Public. */
|
||||
|
||||
struct irs_ng *
|
||||
irs_nul_ng(struct irs_acc *this) {
|
||||
struct irs_ng *ng;
|
||||
|
||||
UNUSED(this);
|
||||
|
||||
if (!(ng = memget(sizeof *ng))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(ng, 0x5e, sizeof *ng);
|
||||
ng->private = NULL;
|
||||
ng->close = ng_close;
|
||||
ng->next = ng_next;
|
||||
ng->test = ng_test;
|
||||
ng->rewind = ng_rewind;
|
||||
ng->minimize = ng_minimize;
|
||||
return (ng);
|
||||
}
|
||||
|
||||
/* Methods. */
|
||||
|
||||
static void
|
||||
ng_close(struct irs_ng *this) {
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
ng_next(struct irs_ng *this, const char **host, const char **user,
|
||||
const char **domain)
|
||||
{
|
||||
UNUSED(this);
|
||||
UNUSED(host);
|
||||
UNUSED(user);
|
||||
UNUSED(domain);
|
||||
errno = ENOENT;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
ng_test(struct irs_ng *this, const char *name,
|
||||
const char *user, const char *host, const char *domain)
|
||||
{
|
||||
UNUSED(this);
|
||||
UNUSED(name);
|
||||
UNUSED(user);
|
||||
UNUSED(host);
|
||||
UNUSED(domain);
|
||||
errno = ENODEV;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static void
|
||||
ng_rewind(struct irs_ng *this, const char *netgroup) {
|
||||
UNUSED(this);
|
||||
UNUSED(netgroup);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
static void
|
||||
ng_minimize(struct irs_ng *this) {
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: pathnames.h,v 1.1 2004/04/15 16:03:29 wkornew Exp $
|
||||
*/
|
||||
|
||||
#ifndef _PATH_IRS_CONF
|
||||
#define _PATH_IRS_CONF "/etc/irs.conf"
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_NETWORKS
|
||||
#define _PATH_NETWORKS "/etc/networks"
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_GROUP
|
||||
#define _PATH_GROUP "/etc/group"
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_NETGROUP
|
||||
#define _PATH_NETGROUP "/etc/netgroup"
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_SERVICES
|
||||
#define _PATH_SERVICES "/etc/services"
|
||||
#endif
|
||||
|
||||
#ifdef IRS_LCL_SV_DB
|
||||
#ifndef _PATH_SERVICES_DB
|
||||
#define _PATH_SERVICES_DB _PATH_SERVICES ".db"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_HESIOD_CONF
|
||||
#define _PATH_HESIOD_CONF "/etc/hesiod.conf"
|
||||
#endif
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 1996,1999 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: util.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) sprintf x
|
||||
#endif
|
||||
|
||||
void
|
||||
map_v4v6_address(const char *src, char *dst) {
|
||||
u_char *p = (u_char *)dst;
|
||||
char tmp[NS_INADDRSZ];
|
||||
int i;
|
||||
|
||||
/* Stash a temporary copy so our caller can update in place. */
|
||||
memcpy(tmp, src, NS_INADDRSZ);
|
||||
/* Mark this ipv6 addr as a mapped ipv4. */
|
||||
for (i = 0; i < 10; i++)
|
||||
*p++ = 0x00;
|
||||
*p++ = 0xff;
|
||||
*p++ = 0xff;
|
||||
/* Retrieve the saved copy and we're done. */
|
||||
memcpy((void*)p, tmp, NS_INADDRSZ);
|
||||
}
|
||||
|
||||
int
|
||||
make_group_list(struct irs_gr *this, const char *name,
|
||||
gid_t basegid, gid_t *groups, int *ngroups)
|
||||
{
|
||||
struct group *grp;
|
||||
int i, ng;
|
||||
int ret, maxgroups;
|
||||
|
||||
ret = -1;
|
||||
ng = 0;
|
||||
maxgroups = *ngroups;
|
||||
/*
|
||||
* When installing primary group, duplicate it;
|
||||
* the first element of groups is the effective gid
|
||||
* and will be overwritten when a setgid file is executed.
|
||||
*/
|
||||
if (ng >= maxgroups)
|
||||
goto done;
|
||||
groups[ng++] = basegid;
|
||||
if (ng >= maxgroups)
|
||||
goto done;
|
||||
groups[ng++] = basegid;
|
||||
/*
|
||||
* Scan the group file to find additional groups.
|
||||
*/
|
||||
(*this->rewind)(this);
|
||||
while ((grp = (*this->next)(this)) != NULL) {
|
||||
if ((gid_t)grp->gr_gid == basegid)
|
||||
continue;
|
||||
for (i = 0; grp->gr_mem[i]; i++) {
|
||||
if (!strcmp(grp->gr_mem[i], name)) {
|
||||
if (ng >= maxgroups)
|
||||
goto done;
|
||||
groups[ng++] = grp->gr_gid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
done:
|
||||
*ngroups = ng;
|
||||
return (ret);
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 1997,1999 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.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: assertions.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/assertions.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
/*
|
||||
* Forward.
|
||||
*/
|
||||
|
||||
static void default_assertion_failed(const char *, int, assertion_type,
|
||||
const char *, int);
|
||||
|
||||
/*
|
||||
* Public.
|
||||
*/
|
||||
|
||||
assertion_failure_callback __assertion_failed = default_assertion_failed;
|
||||
|
||||
void
|
||||
set_assertion_failure_callback(assertion_failure_callback f) {
|
||||
if (f == NULL)
|
||||
__assertion_failed = default_assertion_failed;
|
||||
else
|
||||
__assertion_failed = f;
|
||||
}
|
||||
|
||||
const char *
|
||||
assertion_type_to_text(assertion_type type) {
|
||||
const char *result;
|
||||
|
||||
switch (type) {
|
||||
case assert_require:
|
||||
result = "REQUIRE";
|
||||
break;
|
||||
case assert_ensure:
|
||||
result = "ENSURE";
|
||||
break;
|
||||
case assert_insist:
|
||||
result = "INSIST";
|
||||
break;
|
||||
case assert_invariant:
|
||||
result = "INVARIANT";
|
||||
break;
|
||||
default:
|
||||
result = NULL;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Private.
|
||||
*/
|
||||
|
||||
static void
|
||||
default_assertion_failed(const char *file, int line, assertion_type type,
|
||||
const char *cond, int print_errno)
|
||||
{
|
||||
fprintf(stderr, "%s:%d: %s(%s)%s%s failed.\n",
|
||||
file, line, assertion_type_to_text(type), cond,
|
||||
(print_errno) ? ": " : "",
|
||||
(print_errno) ? strerror(errno) : "");
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
@@ -0,0 +1,320 @@
|
||||
/*
|
||||
* Copyright (c) 1996-1999 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1995 by International Business Machines, Inc.
|
||||
*
|
||||
* International Business Machines, Inc. (hereinafter called IBM) grants
|
||||
* permission under its copyrights to use, copy, modify, and distribute this
|
||||
* Software with or without fee, provided that the above copyright notice and
|
||||
* all paragraphs of this notice appear in all copies, and that the name of IBM
|
||||
* not be used in connection with the marketing of any product incorporating
|
||||
* the Software or modifications thereof, without specific, written prior
|
||||
* permission.
|
||||
*
|
||||
* To the extent it has a right to do so, IBM grants an immunity from suit
|
||||
* under its patents, if any, for the use, sale or manufacture of products to
|
||||
* the extent that such products are used for performing Domain Name System
|
||||
* dynamic updates in TCP/IP networks by means of the Software. No immunity is
|
||||
* granted for any product per se or for any other function of any product.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
|
||||
* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
|
||||
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: base64.c,v 1.1 2004/04/15 16:03:29 wkornew Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#define Assert(Cond) if (!(Cond)) abort()
|
||||
|
||||
static const char Base64[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
static const char Pad64 = '=';
|
||||
|
||||
/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
|
||||
The following encoding technique is taken from RFC 1521 by Borenstein
|
||||
and Freed. It is reproduced here in a slightly edited form for
|
||||
convenience.
|
||||
|
||||
A 65-character subset of US-ASCII is used, enabling 6 bits to be
|
||||
represented per printable character. (The extra 65th character, "=",
|
||||
is used to signify a special processing function.)
|
||||
|
||||
The encoding process represents 24-bit groups of input bits as output
|
||||
strings of 4 encoded characters. Proceeding from left to right, a
|
||||
24-bit input group is formed by concatenating 3 8-bit input groups.
|
||||
These 24 bits are then treated as 4 concatenated 6-bit groups, each
|
||||
of which is translated into a single digit in the base64 alphabet.
|
||||
|
||||
Each 6-bit group is used as an index into an array of 64 printable
|
||||
characters. The character referenced by the index is placed in the
|
||||
output string.
|
||||
|
||||
Table 1: The Base64 Alphabet
|
||||
|
||||
Value Encoding Value Encoding Value Encoding Value Encoding
|
||||
0 A 17 R 34 i 51 z
|
||||
1 B 18 S 35 j 52 0
|
||||
2 C 19 T 36 k 53 1
|
||||
3 D 20 U 37 l 54 2
|
||||
4 E 21 V 38 m 55 3
|
||||
5 F 22 W 39 n 56 4
|
||||
6 G 23 X 40 o 57 5
|
||||
7 H 24 Y 41 p 58 6
|
||||
8 I 25 Z 42 q 59 7
|
||||
9 J 26 a 43 r 60 8
|
||||
10 K 27 b 44 s 61 9
|
||||
11 L 28 c 45 t 62 +
|
||||
12 M 29 d 46 u 63 /
|
||||
13 N 30 e 47 v
|
||||
14 O 31 f 48 w (pad) =
|
||||
15 P 32 g 49 x
|
||||
16 Q 33 h 50 y
|
||||
|
||||
Special processing is performed if fewer than 24 bits are available
|
||||
at the end of the data being encoded. A full encoding quantum is
|
||||
always completed at the end of a quantity. When fewer than 24 input
|
||||
bits are available in an input group, zero bits are added (on the
|
||||
right) to form an integral number of 6-bit groups. Padding at the
|
||||
end of the data is performed using the '=' character.
|
||||
|
||||
Since all base64 input is an integral number of octets, only the
|
||||
-------------------------------------------------
|
||||
following cases can arise:
|
||||
|
||||
(1) the final quantum of encoding input is an integral
|
||||
multiple of 24 bits; here, the final unit of encoded
|
||||
output will be an integral multiple of 4 characters
|
||||
with no "=" padding,
|
||||
(2) the final quantum of encoding input is exactly 8 bits;
|
||||
here, the final unit of encoded output will be two
|
||||
characters followed by two "=" padding characters, or
|
||||
(3) the final quantum of encoding input is exactly 16 bits;
|
||||
here, the final unit of encoded output will be three
|
||||
characters followed by one "=" padding character.
|
||||
*/
|
||||
|
||||
int
|
||||
b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) {
|
||||
size_t datalength = 0;
|
||||
u_char input[3];
|
||||
u_char output[4];
|
||||
size_t i;
|
||||
|
||||
while (2 < srclength) {
|
||||
input[0] = *src++;
|
||||
input[1] = *src++;
|
||||
input[2] = *src++;
|
||||
srclength -= 3;
|
||||
|
||||
output[0] = input[0] >> 2;
|
||||
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
|
||||
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
|
||||
output[3] = input[2] & 0x3f;
|
||||
Assert(output[0] < 64);
|
||||
Assert(output[1] < 64);
|
||||
Assert(output[2] < 64);
|
||||
Assert(output[3] < 64);
|
||||
|
||||
if (datalength + 4 > targsize)
|
||||
return (-1);
|
||||
target[datalength++] = Base64[output[0]];
|
||||
target[datalength++] = Base64[output[1]];
|
||||
target[datalength++] = Base64[output[2]];
|
||||
target[datalength++] = Base64[output[3]];
|
||||
}
|
||||
|
||||
/* Now we worry about padding. */
|
||||
if (0 != srclength) {
|
||||
/* Get what's left. */
|
||||
input[0] = input[1] = input[2] = '\0';
|
||||
for (i = 0; i < srclength; i++)
|
||||
input[i] = *src++;
|
||||
|
||||
output[0] = input[0] >> 2;
|
||||
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
|
||||
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
|
||||
Assert(output[0] < 64);
|
||||
Assert(output[1] < 64);
|
||||
Assert(output[2] < 64);
|
||||
|
||||
if (datalength + 4 > targsize)
|
||||
return (-1);
|
||||
target[datalength++] = Base64[output[0]];
|
||||
target[datalength++] = Base64[output[1]];
|
||||
if (srclength == 1)
|
||||
target[datalength++] = Pad64;
|
||||
else
|
||||
target[datalength++] = Base64[output[2]];
|
||||
target[datalength++] = Pad64;
|
||||
}
|
||||
if (datalength >= targsize)
|
||||
return (-1);
|
||||
target[datalength] = '\0'; /* Returned value doesn't count \0. */
|
||||
return (datalength);
|
||||
}
|
||||
|
||||
/* skips all whitespace anywhere.
|
||||
converts characters, four at a time, starting at (or after)
|
||||
src from base - 64 numbers into three 8 bit bytes in the target area.
|
||||
it returns the number of data bytes stored at the target, or -1 on error.
|
||||
*/
|
||||
|
||||
int
|
||||
b64_pton(src, target, targsize)
|
||||
char const *src;
|
||||
u_char *target;
|
||||
size_t targsize;
|
||||
{
|
||||
int tarindex, state, ch;
|
||||
char *pos;
|
||||
|
||||
state = 0;
|
||||
tarindex = 0;
|
||||
|
||||
while ((ch = *src++) != '\0') {
|
||||
if (isspace(ch)) /* Skip whitespace anywhere. */
|
||||
continue;
|
||||
|
||||
if (ch == Pad64)
|
||||
break;
|
||||
|
||||
pos = strchr(Base64, ch);
|
||||
if (pos == 0) /* A non-base64 character. */
|
||||
return (-1);
|
||||
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (target) {
|
||||
if ((size_t)tarindex >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] = (pos - Base64) << 2;
|
||||
}
|
||||
state = 1;
|
||||
break;
|
||||
case 1:
|
||||
if (target) {
|
||||
if ((size_t)tarindex + 1 >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] |= (pos - Base64) >> 4;
|
||||
target[tarindex+1] = ((pos - Base64) & 0x0f)
|
||||
<< 4 ;
|
||||
}
|
||||
tarindex++;
|
||||
state = 2;
|
||||
break;
|
||||
case 2:
|
||||
if (target) {
|
||||
if ((size_t)tarindex + 1 >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] |= (pos - Base64) >> 2;
|
||||
target[tarindex+1] = ((pos - Base64) & 0x03)
|
||||
<< 6;
|
||||
}
|
||||
tarindex++;
|
||||
state = 3;
|
||||
break;
|
||||
case 3:
|
||||
if (target) {
|
||||
if ((size_t)tarindex >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] |= (pos - Base64);
|
||||
}
|
||||
tarindex++;
|
||||
state = 0;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We are done decoding Base-64 chars. Let's see if we ended
|
||||
* on a byte boundary, and/or with erroneous trailing characters.
|
||||
*/
|
||||
|
||||
if (ch == Pad64) { /* We got a pad char. */
|
||||
ch = *src++; /* Skip it, get next. */
|
||||
switch (state) {
|
||||
case 0: /* Invalid = in first position */
|
||||
case 1: /* Invalid = in second position */
|
||||
return (-1);
|
||||
|
||||
case 2: /* Valid, means one byte of info */
|
||||
/* Skip any number of spaces. */
|
||||
for ((void)NULL; ch != '\0'; ch = *src++)
|
||||
if (!isspace(ch))
|
||||
break;
|
||||
/* Make sure there is another trailing = sign. */
|
||||
if (ch != Pad64)
|
||||
return (-1);
|
||||
ch = *src++; /* Skip the = */
|
||||
/* Fall through to "single trailing =" case. */
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 3: /* Valid, means two bytes of info */
|
||||
/*
|
||||
* We know this char is an =. Is there anything but
|
||||
* whitespace after it?
|
||||
*/
|
||||
for ((void)NULL; ch != '\0'; ch = *src++)
|
||||
if (!isspace(ch))
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* Now make sure for cases 2 and 3 that the "extra"
|
||||
* bits that slopped past the last full byte were
|
||||
* zeros. If we don't check them, they become a
|
||||
* subliminal channel.
|
||||
*/
|
||||
if (target && target[tarindex] != 0)
|
||||
return (-1);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* We ended by seeing the end of the string. Make sure we
|
||||
* have no partial bytes lying around.
|
||||
*/
|
||||
if (state != 0)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (tarindex);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user