Now the biggest step: import the changes to the main RPC code.

Note: you'll need to rinstalkl all your includes before compiling libc
the next time you update your sources in order for all this to work.

Reviewed by:	Mark Murray
This commit is contained in:
Bill Paul 1997-05-28 05:00:11 +00:00
parent 7d0a5a3919
commit e8636dfd57
59 changed files with 6510 additions and 970 deletions

View File

@ -1,16 +1,38 @@
# @(#)Makefile 5.11 (Berkeley) 9/6/90
.PATH: ${.CURDIR}/rpc ${.CURDIR}/.
CFLAGS+=-I${.CURDIR} -I${.CURDIR}/rpc
.PATH: ${.CURDIR}/../libc/rpc ${.CURDIR}/.
SRCS+= auth_none.c auth_unix.c authunix_prot.c bindresvport.c \
clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c clnt_tcp.c \
clnt_udp.c rpc_dtablesize.c get_myaddress.c getrpcent.c getrpcport.c \
pmap_clnt.c pmap_getmaps.c pmap_getport.c pmap_prot.c \
pmap_prot2.c pmap_rmt.c rpc_prot.c rpc_commondata.c rpc_callmsg.c \
svc.c svc_auth.c svc_auth_unix.c svc_raw.c svc_run.c svc_simple.c \
svc_tcp.c svc_udp.c xdr.c xdr_array.c xdr_mem.c \
xdr_rec.c xdr_reference.c xdr_stdio.c
svc_tcp.c svc_udp.c
SRCS+= clnt_unix.c svc_unix.c
SRCS+= auth_des.c authdes_prot.c auth_time.c des_soft.c des_crypt.c \
key_call.c key_prot_xdr.c netname.c netnamer.c rpcdname.c rtime.c \
svc_auth_des.c crypt_clnt.c crypt_xdr.c crypt_client.c
CFLAGS+= -DBROKEN_DES
CLEANFILES= crypt_clnt.c crypt_xdr.c crypt.h
RPCDIR= ${DESTDIR}/usr/include/rpcsvc
RPCGEN= rpcgen -C
crypt_clnt.c: ${RPCDIR}/crypt.x crypt.h
${RPCGEN} -l -o ${.TARGET} ${RPCDIR}/crypt.x
crypt_xdr.c: ${RPCDIR}/crypt.x crypt.h
${RPCGEN} -c -o ${.TARGET} ${RPCDIR}/crypt.x
crypt.h: ${RPCDIR}/crypt.x
${RPCGEN} -h -o ${.TARGET} ${RPCDIR}/crypt.x
# Only build man pages with libc.
.if ${LIB} == "c"
#
# XXX -- rstat.1 and rstat_svc.8 shouldn't really be here
# but there's no rstat command, don't know why, so I'm
@ -18,22 +40,81 @@ SRCS+= auth_none.c auth_unix.c authunix_prot.c bindresvport.c \
# Paul.
#
MAN1+= rpc/rstat.1
MAN3+= rpc/bindresvport.3 rpc/getrpcent.3 rpc/getrpcport.3 rpc/rpc.3 rpc/xdr.3
# MAN1+= rpc/rstat.1
MAN3+= rpc/bindresvport.3 rpc/getrpcent.3 rpc/getrpcport.3 rpc/rpc.3
MAN5+= rpc/rpc.5
MAN8+= rpc/rstat_svc.8
MAN3+= rpc/rpc_secure.3 rpc/publickey.3 rpc/rtime.3 rpc/des_crypt.3
MAN5+= rpc/publickey.5
UNSUPPORTED+= xdr_float.c
MLINKS+= getrpcent.3 getrpcbyname.3 \
getrpcent.3 getrpcbynumber.3 \
getrpcent.3 endrpcent.3 \
getrpcent.3 setrpcent.3 \
rpc.3 auth_destroy.3 \
rpc.3 authnone_create.3 \
rpc.3 authunix_create.3 \
rpc.3 authunix_create_default.3 \
rpc.3 callrpc.3 \
rpc.3 clnt_broadcast.3 \
rpc.3 clnt_call.3 \
rpc.3 clnt_control.3 \
rpc.3 clnt_create.3 \
rpc.3 clnt_destroy.3 \
rpc.3 clnt_freeres.3 \
rpc.3 clnt_geterr.3 \
rpc.3 clnt_pcreateerror.3 \
rpc.3 clnt_perrno.3 \
rpc.3 clnt_perror.3 \
rpc.3 clnt_spcreateerror.3 \
rpc.3 clnt_sperrno.3 \
rpc.3 clnt_sperror.3 \
rpc.3 clntraw_create.3 \
rpc.3 clnttcp_create.3 \
rpc.3 clntudp_bufcreate.3 \
rpc.3 clntudp_create.3 \
rpc.3 get_myaddress.3 \
rpc.3 pmap_getmaps.3 \
rpc.3 pmap_getport.3 \
rpc.3 pmap_rmtcall.3 \
rpc.3 pmap_set.3 \
rpc.3 pmap_unset.3 \
rpc.3 regsterrpc.3 \
rpc.3 rpc_createerr.3 \
rpc.3 svc_destroy.3 \
rpc.3 svc_fds.3 \
rpc.3 svc_fdset.3 \
rpc.3 svc_getargs.3 \
rpc.3 svc_getcaller.3 \
rpc.3 svc_getreg.3 \
rpc.3 svc_getregset.3 \
rpc.3 svc_register.3 \
rpc.3 svc_run.3 \
rpc.3 svc_sendreply.3 \
rpc.3 svc_unregister.3 \
rpc.3 svcerr_auth.3 \
rpc.3 svcerr_decode.3 \
rpc.3 svcerr_noproc.3 \
rpc.3 svcerr_noprog.3 \
rpc.3 svcerr_progvers.3 \
rpc.3 svcerr_systemerr.3 \
rpc.3 svcerr_weakauth.3 \
rpc.3 svcfd_create.3 \
rpc.3 svcraw_create.3 \
rpc.3 svctcp_create.3 \
rpc.3 svcudp_bufcreate.3 \
rpc.3 xdr_accepted_reply.3 \
rpc.3 xdr_authunix_parms.3 \
rpc.3 xdr_callhdr.3 \
rpc.3 xdr_callmsg.3 \
rpc.3 xdr_opaque_auth.3 \
rpc.3 xdr_pmap.3 \
rpc.3 xdr_pmaplist.3 \
rpc.3 xdr_rejected_reply.3 \
rpc.3 xdr_replymsg.3 \
rpc.3 xprt_register.3 \
rpc.3 xprt_unregister.3 \
HDRS+= auth.h auth_unix.h clnt.h pmap_clnt.h \
pmap_prot.h pmap_rmt.h rpc.h rpc_msg.h svc.h svc_auth.h types.h xdr.h
beforeinstall: ${HDRS}
@-if [ ! -d ${DESTDIR}/usr/include/rpc ]; then \
mkdir ${DESTDIR}/usr/include/rpc; \
chown ${BINOWN}.${BINGRP} ${DESTDIR}/usr/include/rpc; \
chmod 755 ${DESTDIR}/usr/include/rpc; \
fi
cd ${.CURDIR}/rpc; install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${HDRS} \
${DESTDIR}/usr/include/rpc
MLINKS+=getrpcent.3 getrpcbyname.3 getrpcent.3 getrpcbynumber.3
.endif

554
lib/libc/rpc/auth_des.c Normal file
View File

@ -0,0 +1,554 @@
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1988 by Sun Microsystems, Inc.
*/
/*
* auth_des.c, client-side implementation of DES authentication
*/
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/cdefs.h>
#include <rpc/des_crypt.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
#include <rpc/auth_des.h>
#include <netinet/in.h> /* XXX: just to get htonl() and ntohl() */
#include <sys/socket.h>
#undef NIS
#include <rpcsvc/nis.h>
#if defined(LIBC_SCCS) && !defined(lint)
/* from: static char sccsid[] = "@(#)auth_des.c 2.2 88/07/29 4.0 RPCSRC; from 1.9 88/02/08 SMI"; */
static const char rcsid[] = "$Id$";
#endif
extern bool_t __rpc_get_time_offset __P(( struct timeval *, nis_server *,
char *, char **, struct sockaddr_in * ));
extern int rtime __P(( struct sockaddr_in *, struct timeval *, struct timeval *));
extern bool_t xdr_authdes_cred __P(( XDR *, struct authdes_cred * ));
extern bool_t xdr_authdes_verf __P(( XDR *, struct authdes_verf * ));
#define MILLION 1000000L
#define RTIME_TIMEOUT 5 /* seconds to wait for sync */
#define AUTH_PRIVATE(auth) (struct ad_private *) auth->ah_private
#define ALLOC(object_type) (object_type *) mem_alloc(sizeof(object_type))
#define FREE(ptr, size) mem_free((char *)(ptr), (int) size)
#define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE)
#define debug(msg) /*printf("%s\n", msg) */
/*
* DES authenticator operations vector
*/
static void authdes_nextverf();
static bool_t authdes_marshal();
static bool_t authdes_validate();
static bool_t authdes_refresh();
static void authdes_destroy();
static struct auth_ops authdes_ops = {
authdes_nextverf,
authdes_marshal,
authdes_validate,
authdes_refresh,
authdes_destroy
};
#ifdef foo
static bool_t synchronize __P(( struct sockaddr *, struct timeval *));
#endif
/*
* This struct is pointed to by the ah_private field of an "AUTH *"
*/
struct ad_private {
char *ad_fullname; /* client's full name */
u_int ad_fullnamelen; /* length of name, rounded up */
char *ad_servername; /* server's full name */
u_int ad_servernamelen; /* length of name, rounded up */
u_int ad_window; /* client specified window */
bool_t ad_dosync; /* synchronize? */
struct sockaddr ad_syncaddr; /* remote host to synch with */
char *ad_timehost; /* remote host to synch with */
struct timeval ad_timediff; /* server's time - client's time */
u_long ad_nickname; /* server's nickname for client */
struct authdes_cred ad_cred; /* storage for credential */
struct authdes_verf ad_verf; /* storage for verifier */
struct timeval ad_timestamp; /* timestamp sent */
des_block ad_xkey; /* encrypted conversation key */
u_char ad_pkey[1024]; /* Server's actual public key */
char *ad_netid; /* Timehost netid */
char *ad_uaddr; /* Timehost uaddr */
nis_server *ad_nis_srvr; /* NIS+ server struct */
};
/*
* Create the client des authentication object
*/
AUTH *
authdes_create(servername, window, syncaddr, ckey)
char *servername; /* network name of server */
u_int window; /* time to live */
struct sockaddr *syncaddr; /* optional addr of host to sync with */
des_block *ckey; /* optional conversation key to use*/
{
AUTH *auth;
struct ad_private *ad;
char namebuf[MAXNETNAMELEN+1];
u_char pkey_data[1024];
if (!getpublickey(servername, pkey_data))
return(NULL);
/*
* Allocate everything now
*/
auth = ALLOC(AUTH);
ad = ALLOC(struct ad_private);
(void) getnetname(namebuf);
ad->ad_fullnamelen = RNDUP(strlen(namebuf));
ad->ad_fullname = (char *)mem_alloc(ad->ad_fullnamelen + 1);
ad->ad_servernamelen = strlen(servername);
ad->ad_servername = (char *)mem_alloc(ad->ad_servernamelen + 1);
if (auth == NULL || ad == NULL || ad->ad_fullname == NULL ||
ad->ad_servername == NULL) {
debug("authdes_create: out of memory");
goto failed;
}
/*
* Set up private data
*/
bcopy(namebuf, ad->ad_fullname, ad->ad_fullnamelen + 1);
bcopy(servername, ad->ad_servername, ad->ad_servernamelen + 1);
bcopy(pkey_data, ad->ad_pkey, strlen(pkey_data) + 1);
if (syncaddr != NULL) {
ad->ad_syncaddr = *syncaddr;
ad->ad_dosync = TRUE;
} else {
ad->ad_dosync = FALSE;
}
ad->ad_window = window;
if (ckey == NULL) {
if (key_gendes(&auth->ah_key) < 0) {
debug("authdes_create: unable to gen conversation key");
return (NULL);
}
} else {
auth->ah_key = *ckey;
}
/*
* Set up auth handle
*/
auth->ah_cred.oa_flavor = AUTH_DES;
auth->ah_verf.oa_flavor = AUTH_DES;
auth->ah_ops = &authdes_ops;
auth->ah_private = (caddr_t)ad;
if (!authdes_refresh(auth)) {
goto failed;
}
return (auth);
failed:
if (auth != NULL)
FREE(auth, sizeof(AUTH));
if (ad != NULL)
FREE(ad, sizeof(struct ad_private));
if (ad->ad_fullname != NULL)
FREE(ad->ad_fullname, ad->ad_fullnamelen + 1);
if (ad->ad_servername != NULL)
FREE(ad->ad_servername, ad->ad_servernamelen + 1);
return (NULL);
}
/*
* Slightly modified version of authdes_create which takes the public key
* of the server principal as an argument. This spares us a call to
* getpublickey() which in the nameserver context can cause a deadlock.
*/
AUTH *
authdes_pk_create(servername, pkey, window, timehost, ckey, srvr)
char *servername; /* network name of server */
netobj *pkey; /* public key of server */
u_int window; /* time to live */
char *timehost; /* optional hostname to sync with */
des_block *ckey; /* optional conversation key to use */
nis_server *srvr; /* optional NIS+ server struct */
{
AUTH *auth;
struct ad_private *ad;
char namebuf[MAXNETNAMELEN+1];
/*
* Allocate everything now
*/
auth = ALLOC(AUTH);
if (auth == NULL) {
debug("authdes_pk_create: out of memory");
return (NULL);
}
ad = ALLOC(struct ad_private);
if (ad == NULL) {
debug("authdes_pk_create: out of memory");
goto failed;
}
ad->ad_fullname = ad->ad_servername = NULL; /* Sanity reasons */
ad->ad_timehost = NULL;
ad->ad_netid = NULL;
ad->ad_uaddr = NULL;
ad->ad_nis_srvr = NULL;
ad->ad_timediff.tv_sec = 0;
ad->ad_timediff.tv_usec = 0;
memcpy(ad->ad_pkey, pkey->n_bytes, pkey->n_len);
if (!getnetname(namebuf))
goto failed;
ad->ad_fullnamelen = RNDUP((u_int) strlen(namebuf));
ad->ad_fullname = (char *)mem_alloc(ad->ad_fullnamelen + 1);
ad->ad_servernamelen = strlen(servername);
ad->ad_servername = (char *)mem_alloc(ad->ad_servernamelen + 1);
if (ad->ad_fullname == NULL || ad->ad_servername == NULL) {
debug("authdes_pk_create: out of memory");
goto failed;
}
if (timehost != NULL) {
ad->ad_timehost = (char *)mem_alloc(strlen(timehost) + 1);
if (ad->ad_timehost == NULL) {
debug("authdes_pk_create: out of memory");
goto failed;
}
memcpy(ad->ad_timehost, timehost, strlen(timehost) + 1);
ad->ad_dosync = TRUE;
} else if (srvr != NULL) {
ad->ad_nis_srvr = srvr; /* transient */
ad->ad_dosync = TRUE;
} else {
ad->ad_dosync = FALSE;
}
memcpy(ad->ad_fullname, namebuf, ad->ad_fullnamelen + 1);
memcpy(ad->ad_servername, servername, ad->ad_servernamelen + 1);
ad->ad_window = window;
if (ckey == NULL) {
if (key_gendes(&auth->ah_key) < 0) {
debug("authdes_pk_create: unable to gen conversation key");
goto failed;
}
} else {
auth->ah_key = *ckey;
}
/*
* Set up auth handle
*/
auth->ah_cred.oa_flavor = AUTH_DES;
auth->ah_verf.oa_flavor = AUTH_DES;
auth->ah_ops = &authdes_ops;
auth->ah_private = (caddr_t)ad;
if (!authdes_refresh(auth)) {
goto failed;
}
ad->ad_nis_srvr = NULL; /* not needed any longer */
return (auth);
failed:
if (auth)
FREE(auth, sizeof (AUTH));
if (ad) {
if (ad->ad_fullname)
FREE(ad->ad_fullname, ad->ad_fullnamelen + 1);
if (ad->ad_servername)
FREE(ad->ad_servername, ad->ad_servernamelen + 1);
if (ad->ad_timehost)
FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1);
if (ad->ad_netid)
free(ad->ad_netid);
if (ad->ad_uaddr)
free(ad->ad_uaddr);
FREE(ad, sizeof (struct ad_private));
}
return (NULL);
}
/*
* Implement the five authentication operations
*/
/*
* 1. Next Verifier
*/
/*ARGSUSED*/
static void
authdes_nextverf(auth)
AUTH *auth;
{
/* what the heck am I supposed to do??? */
}
/*
* 2. Marshal
*/
static bool_t
authdes_marshal(auth, xdrs)
AUTH *auth;
XDR *xdrs;
{
struct ad_private *ad = AUTH_PRIVATE(auth);
struct authdes_cred *cred = &ad->ad_cred;
struct authdes_verf *verf = &ad->ad_verf;
des_block cryptbuf[2];
des_block ivec;
int status;
long len;
int32_t *ixdr;
/*
* Figure out the "time", accounting for any time difference
* with the server if necessary.
*/
(void) gettimeofday(&ad->ad_timestamp, (struct timezone *)NULL);
ad->ad_timestamp.tv_sec += ad->ad_timediff.tv_sec;
ad->ad_timestamp.tv_usec += ad->ad_timediff.tv_usec;
if (ad->ad_timestamp.tv_usec >= MILLION) {
ad->ad_timestamp.tv_usec -= MILLION;
ad->ad_timestamp.tv_sec += 1;
}
/*
* XDR the timestamp and possibly some other things, then
* encrypt them.
*/
ixdr = (int32_t *)cryptbuf;
IXDR_PUT_LONG(ixdr, ad->ad_timestamp.tv_sec);
IXDR_PUT_LONG(ixdr, ad->ad_timestamp.tv_usec);
if (ad->ad_cred.adc_namekind == ADN_FULLNAME) {
IXDR_PUT_U_LONG(ixdr, ad->ad_window);
IXDR_PUT_U_LONG(ixdr, ad->ad_window - 1);
ivec.key.high = ivec.key.low = 0;
status = cbc_crypt((char *)&auth->ah_key, (char *)cryptbuf,
2*sizeof(des_block), DES_ENCRYPT | DES_HW, (char *)&ivec);
} else {
status = ecb_crypt((char *)&auth->ah_key, (char *)cryptbuf,
sizeof(des_block), DES_ENCRYPT | DES_HW);
}
if (DES_FAILED(status)) {
debug("authdes_marshal: DES encryption failure");
return (FALSE);
}
ad->ad_verf.adv_xtimestamp = cryptbuf[0];
if (ad->ad_cred.adc_namekind == ADN_FULLNAME) {
ad->ad_cred.adc_fullname.window = cryptbuf[1].key.high;
ad->ad_verf.adv_winverf = cryptbuf[1].key.low;
} else {
ad->ad_cred.adc_nickname = ad->ad_nickname;
ad->ad_verf.adv_winverf = 0;
}
/*
* Serialize the credential and verifier into opaque
* authentication data.
*/
if (ad->ad_cred.adc_namekind == ADN_FULLNAME) {
len = ((1 + 1 + 2 + 1)*BYTES_PER_XDR_UNIT + ad->ad_fullnamelen);
} else {
len = (1 + 1)*BYTES_PER_XDR_UNIT;
}
if ((ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT))) {
IXDR_PUT_LONG(ixdr, AUTH_DES);
IXDR_PUT_LONG(ixdr, len);
} else {
ATTEMPT(xdr_putlong(xdrs, (long *)&auth->ah_cred.oa_flavor));
ATTEMPT(xdr_putlong(xdrs, &len));
}
ATTEMPT(xdr_authdes_cred(xdrs, cred));
len = (2 + 1)*BYTES_PER_XDR_UNIT;
if ((ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT))) {
IXDR_PUT_LONG(ixdr, AUTH_DES);
IXDR_PUT_LONG(ixdr, len);
} else {
ATTEMPT(xdr_putlong(xdrs, (long *)&auth->ah_verf.oa_flavor));
ATTEMPT(xdr_putlong(xdrs, &len));
}
ATTEMPT(xdr_authdes_verf(xdrs, verf));
return (TRUE);
}
/*
* 3. Validate
*/
static bool_t
authdes_validate(auth, rverf)
AUTH *auth;
struct opaque_auth *rverf;
{
struct ad_private *ad = AUTH_PRIVATE(auth);
struct authdes_verf verf;
int status;
register u_long *ixdr;
if (rverf->oa_length != (2 + 1) * BYTES_PER_XDR_UNIT) {
return (FALSE);
}
ixdr = (u_long *)rverf->oa_base;
verf.adv_xtimestamp.key.high = (u_long)*ixdr++;
verf.adv_xtimestamp.key.low = (u_long)*ixdr++;
verf.adv_int_u = (u_long)*ixdr++; /* nickname not XDR'd ! */
/*
* Decrypt the timestamp
*/
status = ecb_crypt((char *)&auth->ah_key, (char *)&verf.adv_xtimestamp,
sizeof(des_block), DES_DECRYPT | DES_HW);
if (DES_FAILED(status)) {
debug("authdes_validate: DES decryption failure");
return (FALSE);
}
/*
* xdr the decrypted timestamp
*/
ixdr = (u_long *)verf.adv_xtimestamp.c;
verf.adv_timestamp.tv_sec = IXDR_GET_LONG(ixdr) + 1;
verf.adv_timestamp.tv_usec = IXDR_GET_LONG(ixdr);
/*
* validate
*/
if (bcmp((char *)&ad->ad_timestamp, (char *)&verf.adv_timestamp,
sizeof(struct timeval)) != 0) {
debug("authdes_validate: verifier mismatch\n");
return (FALSE);
}
/*
* We have a nickname now, let's use it
*/
ad->ad_nickname = verf.adv_nickname;
ad->ad_cred.adc_namekind = ADN_NICKNAME;
return (TRUE);
}
/*
* 4. Refresh
*/
static bool_t
authdes_refresh(auth)
AUTH *auth;
{
struct ad_private *ad = AUTH_PRIVATE(auth);
struct authdes_cred *cred = &ad->ad_cred;
netobj pkey;
if (ad->ad_dosync &&
#ifdef old
!synchronize(&ad->ad_syncaddr, &ad->ad_timediff)) {
#else
!__rpc_get_time_offset(&ad->ad_timediff,ad->ad_nis_srvr,
ad->ad_timehost, &(ad->ad_uaddr),
(struct sockaddr_in *)&(ad->ad_syncaddr))) {
#endif
/*
* Hope the clocks are synced!
*/
ad->ad_timediff.tv_sec = ad->ad_timediff.tv_usec = 0;
ad->ad_dosync = 0;
debug("authdes_refresh: unable to synchronize with server");
}
ad->ad_xkey = auth->ah_key;
pkey.n_bytes = (char *)(ad->ad_pkey);
pkey.n_len = strlen((char *)ad->ad_pkey) + 1;
if (key_encryptsession_pk(ad->ad_servername, &pkey, &ad->ad_xkey) < 0) {
debug("authdes_create: unable to encrypt conversation key");
return (FALSE);
}
cred->adc_fullname.key = ad->ad_xkey;
cred->adc_namekind = ADN_FULLNAME;
cred->adc_fullname.name = ad->ad_fullname;
return (TRUE);
}
/*
* 5. Destroy
*/
static void
authdes_destroy(auth)
AUTH *auth;
{
struct ad_private *ad = AUTH_PRIVATE(auth);
FREE(ad->ad_fullname, ad->ad_fullnamelen + 1);
FREE(ad->ad_servername, ad->ad_servernamelen + 1);
FREE(ad, sizeof(struct ad_private));
FREE(auth, sizeof(AUTH));
}
#ifdef old
/*
* Synchronize with the server at the given address, that is,
* adjust timep to reflect the delta between our clocks
*/
static bool_t
synchronize(syncaddr, timep)
struct sockaddr *syncaddr;
struct timeval *timep;
{
struct timeval mytime;
struct timeval timeout;
timeout.tv_sec = RTIME_TIMEOUT;
timeout.tv_usec = 0;
if (rtime((struct sockaddr_in *)syncaddr, timep, NULL /*&timeout*/) < 0) {
return (FALSE);
}
(void) gettimeofday(&mytime, (struct timezone *)NULL);
timep->tv_sec -= mytime.tv_sec;
if (mytime.tv_usec > timep->tv_usec) {
timep->tv_sec -= 1;
timep->tv_usec += MILLION;
}
timep->tv_usec -= mytime.tv_usec;
return (TRUE);
}
#endif

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,17 +30,18 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)auth_none.c 2.1 88/07/29 4.0 RPCSRC";*/
static char *rcsid = "$Id: auth_none.c,v 1.1 1993/10/27 05:40:10 paul Exp $";
static char *rcsid = "$Id: auth_none.c,v 1.5 1996/12/30 14:13:30 peter Exp $";
#endif
/*
* auth_none.c
* Creates a client authentication handle for passing "null"
* credentials and verifiers to remote systems.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
* Creates a client authentication handle for passing "null"
* credentials and verifiers to remote systems.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*/
#include <stdlib.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
@ -110,7 +111,7 @@ authnone_marshal(client, xdrs)
ap->marshalled_client, ap->mcnt));
}
static void
static void
authnone_verf()
{
}

500
lib/libc/rpc/auth_time.c Normal file
View File

@ -0,0 +1,500 @@
#pragma ident "@(#)auth_time.c 1.4 92/11/10 SMI"
/*
* auth_time.c
*
* This module contains the private function __rpc_get_time_offset()
* which will return the difference in seconds between the local system's
* notion of time and a remote server's notion of time. This must be
* possible without calling any functions that may invoke the name
* service. (netdir_getbyxxx, getXbyY, etc). The function is used in the
* synchronize call of the authdes code to synchronize clocks between
* NIS+ clients and their servers.
*
* Note to minimize the amount of duplicate code, portions of the
* synchronize() function were folded into this code, and the synchronize
* call becomes simply a wrapper around this function. Further, if this
* function is called with a timehost it *DOES* recurse to the name
* server so don't use it in that mode if you are doing name service code.
*
* Copyright (c) 1992 Sun Microsystems Inc.
* All rights reserved.
*
* Side effects :
* When called a client handle to a RPCBIND process is created
* and destroyed. Two strings "netid" and "uaddr" are malloc'd
* and returned. The SIGALRM processing is modified only if
* needed to deal with TCP connections.
*
* NOTE: This code has had the crap beaten out it in order to convert
* it from TI-RPC back to TD-RPC for use on FreeBSD.
*/
#include <stdio.h>
#include <syslog.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/signal.h>
#include <sys/errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <rpc/rpc.h>
#include <rpc/rpc_com.h>
#undef NIS
#include <rpcsvc/nis.h>
/*
* FreeBSD currently uses RPC 4.0, which uses portmap rather than
* rpcbind. Consequently, we need to fake up these values here.
* Luckily, the RPCB_GETTIME procedure uses only base XDR data types
* so we don't need anything besides these magic numbers.
*/
#define RPCBPROG (u_long)100000
#define RPCBVERS (u_long)3
#define RPCBPROC_GETTIME (u_long)6
#ifdef TESTING
#define msg(x) printf("ERROR: %s\n", x)
/* #define msg(x) syslog(LOG_ERR, "%s", x) */
#else
#define msg(x)
#endif
static int saw_alarm = 0;
static void
alarm_hndler(s)
int s;
{
saw_alarm = 1;
return;
}
/*
* The internet time server defines the epoch to be Jan 1, 1900
* whereas UNIX defines it to be Jan 1, 1970. To adjust the result
* from internet time-service time, into UNIX time we subtract the
* following offset :
*/
#define NYEARS (1970 - 1900)
#define TOFFSET ((u_long)60*60*24*(365*NYEARS + (NYEARS/4)))
/*
* Stolen from rpc.nisd:
* Turn a 'universal address' into a struct sockaddr_in.
* Bletch.
*/
static int uaddr_to_sockaddr(uaddr, sin)
#ifdef foo
endpoint *endpt;
#endif
char *uaddr;
struct sockaddr_in *sin;
{
unsigned char p_bytes[2];
int i;
unsigned long a[6];
i = sscanf(uaddr, "%lu.%lu.%lu.%lu.%lu.%lu", &a[0], &a[1], &a[2],
&a[3], &a[4], &a[5]);
if (i < 6)
return(1);
for (i = 0; i < 4; i++)
sin->sin_addr.s_addr |= (a[i] & 0x000000FF) << (8 * i);
p_bytes[0] = (unsigned char)a[4] & 0x000000FF;
p_bytes[1] = (unsigned char)a[5] & 0x000000FF;
sin->sin_family = AF_INET; /* always */
bcopy((char *)&p_bytes, (char *)&sin->sin_port, 2);
return (0);
}
/*
* free_eps()
*
* Free the strings that were strduped into the eps structure.
*/
static void
free_eps(eps, num)
endpoint eps[];
int num;
{
int i;
for (i = 0; i < num; i++) {
free(eps[i].uaddr);
free(eps[i].proto);
free(eps[i].family);
}
return;
}
/*
* get_server()
*
* This function constructs a nis_server structure description for the
* indicated hostname.
*
* NOTE: There is a chance we may end up recursing here due to the
* fact that gethostbyname() could do an NIS search. Ideally, the
* NIS+ server will call __rpc_get_time_offset() with the nis_server
* structure already populated.
*/
static nis_server *
get_server(sin, host, srv, eps, maxep)
struct sockaddr_in *sin;
char *host; /* name of the time host */
nis_server *srv; /* nis_server struct to use. */
endpoint eps[]; /* array of endpoints */
int maxep; /* max array size */
{
char hname[256];
int num_ep = 0, i;
struct hostent *he;
struct hostent dummy;
char *ptr[2];
if (host == NULL && sin == NULL)
return (NULL);
if (sin == NULL) {
he = gethostbyname(host);
if (he == NULL)
return(NULL);
} else {
he = &dummy;
ptr[0] = (char *)&sin->sin_addr.s_addr;
ptr[1] = NULL;
dummy.h_addr_list = ptr;
}
/*
* This is lame. We go around once for TCP, then again
* for UDP.
*/
for (i = 0; (he->h_addr_list[i] != NULL) && (num_ep < maxep);
i++, num_ep++) {
struct in_addr *a;
a = (struct in_addr *)he->h_addr_list[i];
snprintf(hname, sizeof(hname), "%s.0.111", inet_ntoa(*a));
eps[num_ep].uaddr = strdup(hname);
eps[num_ep].family = strdup("inet");
eps[num_ep].proto = strdup("tcp");
}
for (i = 0; (he->h_addr_list[i] != NULL) && (num_ep < maxep);
i++, num_ep++) {
struct in_addr *a;
a = (struct in_addr *)he->h_addr_list[i];
snprintf(hname, sizeof(hname), "%s.0.111", inet_ntoa(*a));
eps[num_ep].uaddr = strdup(hname);
eps[num_ep].family = strdup("inet");
eps[num_ep].proto = strdup("udp");
}
srv->name = (nis_name) host;
srv->ep.ep_len = num_ep;
srv->ep.ep_val = eps;
srv->key_type = NIS_PK_NONE;
srv->pkey.n_bytes = NULL;
srv->pkey.n_len = 0;
return (srv);
}
/*
* __rpc_get_time_offset()
*
* This function uses a nis_server structure to contact the a remote
* machine (as named in that structure) and returns the offset in time
* between that machine and this one. This offset is returned in seconds
* and may be positive or negative.
*
* The first time through, a lot of fiddling is done with the netconfig
* stuff to find a suitable transport. The function is very aggressive
* about choosing UDP or at worst TCP if it can. This is because
* those transports support both the RCPBIND call and the internet
* time service.
*
* Once through, *uaddr is set to the universal address of
* the machine and *netid is set to the local netid for the transport
* that uaddr goes with. On the second call, the netconfig stuff
* is skipped and the uaddr/netid pair are used to fetch the netconfig
* structure and to then contact the machine for the time.
*
* td = "server" - "client"
*/
int
__rpc_get_time_offset(td, srv, thost, uaddr, netid)
struct timeval *td; /* Time difference */
nis_server *srv; /* NIS Server description */
char *thost; /* if no server, this is the timehost */
char **uaddr; /* known universal address */
struct sockaddr_in *netid; /* known network identifier */
{
CLIENT *clnt; /* Client handle */
endpoint *ep, /* useful endpoints */
*useep = NULL; /* endpoint of xp */
char *useua = NULL; /* uaddr of selected xp */
int epl, i; /* counters */
enum clnt_stat status; /* result of clnt_call */
u_long thetime, delta;
int needfree = 0;
struct timeval tv;
int time_valid;
int udp_ep = -1, tcp_ep = -1;
int a1, a2, a3, a4;
char ut[64], ipuaddr[64];
endpoint teps[32];
nis_server tsrv;
void (*oldsig)() = NULL; /* old alarm handler */
struct sockaddr_in sin;
int s = RPC_ANYSOCK, len;
int type = 0;
td->tv_sec = 0;
td->tv_usec = 0;
/*
* First check to see if we need to find and address for this
* server.
*/
if (*uaddr == NULL) {
if ((srv != NULL) && (thost != NULL)) {
msg("both timehost and srv pointer used!");
return (0);
}
if (! srv) {
srv = get_server(netid, thost, &tsrv, teps, 32);
if (srv == NULL) {
msg("unable to contruct server data.");
return (0);
}
needfree = 1; /* need to free data in endpoints */
}
ep = srv->ep.ep_val;
epl = srv->ep.ep_len;
/* Identify the TCP and UDP endpoints */
for (i = 0;
(i < epl) && ((udp_ep == -1) || (tcp_ep == -1)); i++) {
if (strcasecmp(ep[i].proto, "udp") == 0)
udp_ep = i;
if (strcasecmp(ep[i].proto, "tcp") == 0)
tcp_ep = i;
}
/* Check to see if it is UDP or TCP */
if (tcp_ep > -1) {
useep = &ep[tcp_ep];
useua = ep[tcp_ep].uaddr;
type = SOCK_STREAM;
} else if (udp_ep > -1) {
useep = &ep[udp_ep];
useua = ep[udp_ep].uaddr;
type = SOCK_DGRAM;
}
if (useep == NULL) {
msg("no acceptable transport endpoints.");
if (needfree)
free_eps(teps, tsrv.ep.ep_len);
return (0);
}
}
/*
* Create a sockaddr from the uaddr.
*/
if (*uaddr != NULL)
useua = *uaddr;
/* Fixup test for NIS+ */
sscanf(useua, "%d.%d.%d.%d.", &a1, &a2, &a3, &a4);
sprintf(ipuaddr, "%d.%d.%d.%d.0.111", a1, a2, a3, a4);
useua = &ipuaddr[0];
if (uaddr_to_sockaddr(useua, &sin)) {
msg("unable to translate uaddr to sockaddr.");
if (needfree)
free_eps(teps, tsrv.ep.ep_len);
return (0);
}
/*
* Create the client handle to rpcbind. Note we always try
* version 3 since that is the earliest version that supports
* the RPCB_GETTIME call. Also it is the version that comes
* standard with SVR4. Since most everyone supports TCP/IP
* we could consider trying the rtime call first.
*/
clnt = clnttcp_create(&sin, RPCBPROG, RPCBVERS, &s, 0, 0);
if (clnt == NULL) {
msg("unable to create client handle to rpcbind.");
if (needfree)
free_eps(teps, tsrv.ep.ep_len);
return (0);
}
tv.tv_sec = 5;
tv.tv_usec = 0;
time_valid = 0;
status = clnt_call(clnt, RPCBPROC_GETTIME, xdr_void, NULL,
xdr_u_long, (char *)&thetime, tv);
/*
* The only error we check for is anything but success. In
* fact we could have seen PROGMISMATCH if talking to a 4.1
* machine (pmap v2) or TIMEDOUT if the net was busy.
*/
if (status == RPC_SUCCESS)
time_valid = 1;
else {
int save;
/* Blow away possible stale CLNT handle. */
if (clnt != NULL) {
clnt_destroy(clnt);
clnt = NULL;
}
/*
* Convert PMAP address into timeservice address
* We take advantage of the fact that we "know" what
* the universal address looks like for inet transports.
*
* We also know that the internet timeservice is always
* listening on port 37.
*/
sscanf(useua, "%d.%d.%d.%d.", &a1, &a2, &a3, &a4);
sprintf(ut, "%d.%d.%d.%d.0.37", a1, a2, a3, a4);
if (uaddr_to_sockaddr(ut, &sin)) {
msg("cannot convert timeservice uaddr to sockaddr.");
goto error;
}
s = socket(AF_INET, type, 0);
if (s == -1) {
msg("unable to open fd to network.");
goto error;
}
/*
* Now depending on whether or not we're talking to
* UDP we set a timeout or not.
*/
if (type == SOCK_DGRAM) {
struct timeval timeout = { 20, 0 };
struct sockaddr_in from;
fd_set readfds;
int res;
if (sendto(s, &thetime, sizeof(thetime), 0,
(struct sockaddr *)&sin, sizeof(sin)) == -1) {
msg("udp : sendto failed.");
goto error;
}
do {
FD_ZERO(&readfds);
FD_SET(s, &readfds);
res = select(_rpc_dtablesize(), &readfds,
(fd_set *)NULL, (fd_set *)NULL, &timeout);
} while (res < 0 && errno == EINTR);
if (res <= 0)
goto error;
len = sizeof(from);
res = recvfrom(s, (char *)&thetime, sizeof(thetime), 0,
(struct sockaddr *)&from, &len);
if (res == -1) {
msg("recvfrom failed on udp transport.");
goto error;
}
time_valid = 1;
} else {
int res;
oldsig = (void (*)())signal(SIGALRM, alarm_hndler);
saw_alarm = 0; /* global tracking the alarm */
alarm(20); /* only wait 20 seconds */
res = connect(s, (struct sockaddr *)&sin, sizeof(sin));
if (res == -1) {
msg("failed to connect to tcp endpoint.");
goto error;
}
if (saw_alarm) {
msg("alarm caught it, must be unreachable.");
goto error;
}
res = read(s, (char *)&thetime, sizeof(thetime));
if (res != sizeof(thetime)) {
if (saw_alarm)
msg("timed out TCP call.");
else
msg("wrong size of results returned");
goto error;
}
time_valid = 1;
}
save = errno;
(void) close(s);
errno = save;
s = RPC_ANYSOCK;
if (time_valid) {
thetime = ntohl(thetime);
thetime = thetime - TOFFSET; /* adjust to UNIX time */
} else
thetime = 0;
}
gettimeofday(&tv, 0);
error:
/*
* clean up our allocated data structures.
*/
if (s != RPC_ANYSOCK)
(void) close(s);
if (clnt != NULL)
clnt_destroy(clnt);
alarm(0); /* reset that alarm if its outstanding */
if (oldsig) {
signal(SIGALRM, oldsig);
}
/*
* note, don't free uaddr strings until after we've made a
* copy of them.
*/
if (time_valid) {
if (*uaddr == NULL)
*uaddr = strdup(useua);
/* Round to the nearest second */
tv.tv_sec += (tv.tv_sec > 500000) ? 1 : 0;
delta = (thetime > tv.tv_sec) ? thetime - tv.tv_sec :
tv.tv_sec - thetime;
td->tv_sec = (thetime < tv.tv_sec) ? - delta : delta;
td->tv_usec = 0;
} else {
msg("unable to get the server's time.");
}
if (needfree)
free_eps(teps, tsrv.ep.ep_len);
return (time_valid);
}

View File

@ -5,11 +5,11 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
@ -17,11 +17,11 @@
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,12 +30,12 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC";*/
static char *rcsid = "$Id: auth_unix.c,v 1.1 1993/10/27 05:40:11 paul Exp $";
static char *rcsid = "$Id: auth_unix.c,v 1.7 1996/12/30 14:14:39 peter Exp $";
#endif
/*
* auth_unix.c, Implements UNIX style authentication parameters.
*
* auth_unix.c, Implements UNIX style authentication parameters.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*
* The system is very weak. The client uses no encryption for it's
@ -47,7 +47,10 @@ static char *rcsid = "$Id: auth_unix.c,v 1.1 1993/10/27 05:40:11 paul Exp $";
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/param.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
@ -82,8 +85,20 @@ struct audata {
};
#define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private)
static bool_t marshal_new_auth();
static void marshal_new_auth();
/*
* This goop is here because some servers refuse to accept a
* credential with more than some number (usually 8) supplementary
* groups. Blargh!
*/
static int authunix_maxgrouplist = 0;
void
set_rpc_maxgrouplist(int num)
{
authunix_maxgrouplist = num;
}
/*
* Create a unix style authenticator.
@ -134,14 +149,20 @@ authunix_create(machname, uid, gid, len, aup_gids)
aup.aup_machname = machname;
aup.aup_uid = uid;
aup.aup_gid = gid;
aup.aup_len = (u_int)len;
/* GW: continuation of max group list hack */
if(authunix_maxgrouplist != 0) {
aup.aup_len = ((len < authunix_maxgrouplist) ? len
: authunix_maxgrouplist);
} else {
aup.aup_len = (u_int)len;
}
aup.aup_gids = aup_gids;
/*
* Serialize the parameters into origcred
*/
xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE);
if (! xdr_authunix_parms(&xdrs, &aup))
if (! xdr_authunix_parms(&xdrs, &aup))
abort();
au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs);
au->au_origcred.oa_flavor = AUTH_UNIX;
@ -153,7 +174,7 @@ authunix_create(machname, uid, gid, len, aup_gids)
return (NULL);
}
#endif
bcopy(mymem, au->au_origcred.oa_base, (u_int)len);
memcpy(au->au_origcred.oa_base, mymem, (u_int)len);
/*
* set auth handle to reflect new cred.
@ -175,14 +196,20 @@ authunix_create_default()
register int uid;
register int gid;
int gids[NGRPS];
int i;
gid_t real_gids[NGROUPS];
if (gethostname(machname, MAX_MACHINE_NAME) == -1)
abort();
machname[MAX_MACHINE_NAME] = 0;
uid = geteuid();
gid = getegid();
if ((len = getgroups(NGRPS, gids)) < 0)
uid = (int)geteuid();
gid = (int)getegid();
if ((len = getgroups(NGROUPS, real_gids)) < 0)
abort();
if(len > NGRPS) len = NGRPS; /* GW: turn `gid_t's into `int's */
for(i = 0; i < len; i++) {
gids[i] = (int)real_gids[i];
}
return (authunix_create(machname, uid, gid, len, gids));
}
@ -259,7 +286,7 @@ authunix_refresh(auth)
xdrmem_create(&xdrs, au->au_origcred.oa_base,
au->au_origcred.oa_length, XDR_DECODE);
stat = xdr_authunix_parms(&xdrs, &aup);
if (! stat)
if (! stat)
goto done;
/* update the time and serialize in place */
@ -303,7 +330,7 @@ authunix_destroy(auth)
* Marshals (pre-serializes) an auth struct.
* sets private data, au_marshed and au_mpos
*/
static bool_t
static void
marshal_new_auth(auth)
register AUTH *auth;
{

View File

@ -0,0 +1,82 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)authdes_prot.c 2.1 88/07/29 4.0 RPCSRC; from 1.6 88/02/08 SMI";
#endif
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1988 by Sun Microsystems, Inc.
*/
/*
* authdes_prot.c, XDR routines for DES authentication
*/
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
#include <rpc/auth_des.h>
#define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE)
bool_t
xdr_authdes_cred(xdrs, cred)
XDR *xdrs;
struct authdes_cred *cred;
{
/*
* Unrolled xdr
*/
ATTEMPT(xdr_enum(xdrs, (enum_t *)&cred->adc_namekind));
switch (cred->adc_namekind) {
case ADN_FULLNAME:
ATTEMPT(xdr_string(xdrs, &cred->adc_fullname.name, MAXNETNAMELEN));
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_fullname.key, sizeof(des_block)));
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_fullname.window, sizeof(cred->adc_fullname.window)));
return (TRUE);
case ADN_NICKNAME:
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_nickname, sizeof(cred->adc_nickname)));
return (TRUE);
default:
return (FALSE);
}
}
bool_t
xdr_authdes_verf(xdrs, verf)
register XDR *xdrs;
register struct authdes_verf *verf;
{
/*
* Unrolled xdr
*/
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&verf->adv_xtimestamp, sizeof(des_block)));
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&verf->adv_int_u, sizeof(verf->adv_int_u)));
return (TRUE);
}

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,7 +30,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)authunix_prot.c 1.15 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)authunix_prot.c 2.1 88/07/29 4.0 RPCSRC";*/
static char *rcsid = "$Id: authunix_prot.c,v 1.1 1993/10/27 05:40:15 paul Exp $";
static char *rcsid = "$Id: authunix_prot.c,v 1.2 1995/05/30 05:41:12 rgrimes Exp $";
#endif
/*

View File

@ -1,27 +1,30 @@
.\" @(#)bindresvport.3n 2.2 88/08/02 4.0 RPCSRC; from 1.7 88/03/14 SMI
.TH BINDRESVPORT 3N "22 november 1987"
.SH NAME
bindresvport \- bind a socket to a privileged IP port
.SH SYNOPSIS
.nf
.B #include <sys/types.h>
.B #include <netinet/in.h>
.LP
.B int bindresvport(sd, sin)
.B int sd;
.B struct sockaddr_in \(**sin;
.fi
.SH DESCRIPTION
.LP
.B bindresvport(\|)
.Dd "22 november 1987"
.Dt BINDRESVPORT 3
.Os
.Sh NAME
.Nm bindresvport
.Ndbind a socket to a privileged IP port
.Sh SYNOPSIS
.Fd #include <sys/types.h>
.Fd #include <netinet/in.h>
.Ft int
.Fn bindresvport "int sd" "struct sockaddr_in **sin"
.Sh DESCRIPTION
.Nm Bindresvport
is used to bind a socket descriptor to a privileged
.SM IP
.Tn IP
port, that is, a
port number in the range 0-1023.
The routine returns 0 if it is successful,
otherwise \-1 is returned and
.B errno
otherwise -1 is returned and
.Va errno
set to reflect the cause of the error.
.LP
.Pp
Only root can bind to a privileged port; this call will fail for any
other users.
.Pp
If the value of sin->sin_port is non-zero
.Fn bindresvport
will attempt to use that specific port. If it fails, it chooses another
privileged port automatically.

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,55 +30,78 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)bindresvport.c 1.8 88/02/08 SMI";*/
/*static char *sccsid = "from: @(#)bindresvport.c 2.2 88/07/29 4.0 RPCSRC";*/
static char *rcsid = "$Id: bindresvport.c,v 1.1 1993/10/27 05:40:17 paul Exp $";
/*from: OpenBSD: bindresvport.c,v 1.7 1996/07/30 16:25:47 downsj Exp */
static char *rcsid = "$Id: bindresvport.c,v 1.6 1996/12/30 14:12:36 peter Exp $";
#endif
/*
* Copyright (c) 1987 by Sun Microsystems, Inc.
*
* Portions Copyright(C) 1996, Jason Downs. All rights reserved.
*/
#include <sys/types.h>
#include <sys/errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
/*
* Bind a socket to a privileged IP port
*/
int
bindresvport(sd, sin)
int sd;
struct sockaddr_in *sin;
{
int res;
static short port;
int on, old, error;
struct sockaddr_in myaddr;
extern int errno;
int i;
#define STARTPORT 600
#define ENDPORT (IPPORT_RESERVED - 1)
#define NPORTS (ENDPORT - STARTPORT + 1)
int sinlen = sizeof(struct sockaddr_in);
if (sin == (struct sockaddr_in *)0) {
sin = &myaddr;
bzero(sin, sizeof (*sin));
memset(sin, 0, sinlen);
sin->sin_len = sinlen;
sin->sin_family = AF_INET;
} else if (sin->sin_family != AF_INET) {
errno = EPFNOSUPPORT;
return (-1);
}
if (port == 0) {
port = (getpid() % NPORTS) + STARTPORT;
if (sin->sin_port == 0) {
int oldlen = sizeof(old);
error = getsockopt(sd, IPPROTO_IP, IP_PORTRANGE,
&old, &oldlen);
if (error < 0)
return(error);
on = IP_PORTRANGE_LOW;
error = setsockopt(sd, IPPROTO_IP, IP_PORTRANGE,
&on, sizeof(on));
if (error < 0)
return(error);
}
res = -1;
errno = EADDRINUSE;
for (i = 0; i < NPORTS && res < 0 && errno == EADDRINUSE; i++) {
sin->sin_port = htons(port++);
if (port > ENDPORT) {
port = STARTPORT;
error = bind(sd, (struct sockaddr *)sin, sinlen);
if (sin->sin_port == 0) {
int saved_errno = errno;
if (error) {
if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE,
&old, sizeof(old)) < 0)
errno = saved_errno;
return (error);
}
if (sin != &myaddr) {
/* Hmm, what did the kernel assign... */
if (getsockname(sd, (struct sockaddr *)sin,
&sinlen) < 0)
errno = saved_errno;
return (error);
}
res = bind(sd,
(struct sockaddr *)sin, sizeof(struct sockaddr_in));
}
return (res);
return (error);
}

View File

@ -5,11 +5,11 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
@ -17,11 +17,11 @@
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,7 +30,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)clnt_generic.c 1.4 87/08/11 (C) 1987 SMI";*/
/*static char *sccsid = "from: @(#)clnt_generic.c 2.2 88/08/01 4.0 RPCSRC";*/
static char *rcsid = "$Id: clnt_generic.c,v 1.1 1993/10/27 05:40:19 paul Exp $";
static char *rcsid = "$Id: clnt_generic.c,v 1.5 1996/12/30 14:17:20 peter Exp $";
#endif
/*
@ -40,10 +40,11 @@ static char *rcsid = "$Id: clnt_generic.c,v 1.1 1993/10/27 05:40:19 paul Exp $";
#include <sys/socket.h>
#include <sys/errno.h>
#include <netdb.h>
#include <string.h>
/*
* Generic client creation: takes (hostname, program-number, protocol) and
* returns client handle. Default options are set, which the user can
* returns client handle. Default options are set, which the user can
* change using the rpc equivalent of ioctl()'s.
*/
CLIENT *
@ -56,10 +57,27 @@ clnt_create(hostname, prog, vers, proto)
struct hostent *h;
struct protoent *p;
struct sockaddr_in sin;
struct sockaddr_un sun;
int sock;
struct timeval tv;
static struct timeval tv;
CLIENT *client;
if (!strcmp(proto, "unix")) {
bzero((char *)&sun, sizeof(sun));
sun.sun_family = AF_UNIX;
strcpy(sun.sun_path, hostname);
sun.sun_len = sizeof(sun.sun_len) + sizeof(sun.sun_family) +
strlen(sun.sun_path) + 1;
sock = RPC_ANYSOCK;
client = clntunix_create(&sun, prog, vers, &sock, 0, 0);
if (client == NULL)
return(NULL);
tv.tv_sec = 25;
tv.tv_usec = 0;
clnt_control(client, CLSET_TIMEOUT, &tv);
return(client);
}
h = gethostbyname(hostname);
if (h == NULL) {
rpc_createerr.cf_stat = RPC_UNKNOWNHOST;
@ -70,17 +88,18 @@ clnt_create(hostname, prog, vers, proto)
* Only support INET for now
*/
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = EAFNOSUPPORT;
rpc_createerr.cf_error.re_errno = EAFNOSUPPORT;
return (NULL);
}
memset(&sin, 0, sizeof(sin));
sin.sin_len = sizeof(struct sockaddr_in);
sin.sin_family = h->h_addrtype;
sin.sin_port = 0;
bzero(sin.sin_zero, sizeof(sin.sin_zero));
bcopy(h->h_addr, (char*)&sin.sin_addr, h->h_length);
memcpy((char*)&sin.sin_addr, h->h_addr, h->h_length);
p = getprotobyname(proto);
if (p == NULL) {
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
rpc_createerr.cf_error.re_errno = EPFNOSUPPORT;
rpc_createerr.cf_error.re_errno = EPFNOSUPPORT;
return (NULL);
}
sock = RPC_ANYSOCK;
@ -92,21 +111,26 @@ clnt_create(hostname, prog, vers, proto)
if (client == NULL) {
return (NULL);
}
#if 0 /* XXX do we need this? */
tv.tv_sec = 25;
tv.tv_usec = 0;
clnt_control(client, CLSET_TIMEOUT, &tv);
#endif
break;
case IPPROTO_TCP:
client = clnttcp_create(&sin, prog, vers, &sock, 0, 0);
if (client == NULL) {
return (NULL);
}
#if 0 /* XXX do we need this? */
tv.tv_sec = 25;
tv.tv_usec = 0;
clnt_control(client, CLSET_TIMEOUT, &tv);
#endif
break;
default:
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = EPFNOSUPPORT;
rpc_createerr.cf_error.re_errno = EPFNOSUPPORT;
return (NULL);
}
return (client);

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,7 +30,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)clnt_perror.c 2.1 88/07/29 4.0 RPCSRC";*/
static char *rcsid = "$Id: clnt_perror.c,v 1.1 1993/10/27 05:40:20 paul Exp $";
static char *rcsid = "$Id: clnt_perror.c,v 1.6 1996/12/30 14:19:34 peter Exp $";
#endif
/*
@ -40,6 +40,7 @@ static char *rcsid = "$Id: clnt_perror.c,v 1.1 1993/10/27 05:40:20 paul Exp $";
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rpc/rpc.h>
#include <rpc/types.h>
@ -47,6 +48,7 @@ static char *rcsid = "$Id: clnt_perror.c,v 1.1 1993/10/27 05:40:20 paul Exp $";
#include <rpc/clnt.h>
static char *auth_errmsg();
#define CLNT_PERROR_BUFLEN 256
static char *buf;
@ -55,7 +57,7 @@ _buf()
{
if (buf == 0)
buf = (char *)malloc(256);
buf = (char *)malloc(CLNT_PERROR_BUFLEN);
return (buf);
}
@ -68,7 +70,6 @@ clnt_sperror(rpch, s)
char *s;
{
struct rpc_err e;
void clnt_perrno();
char *err;
char *str = _buf();
char *strstart = str;
@ -77,17 +78,14 @@ clnt_sperror(rpch, s)
return (0);
CLNT_GETERR(rpch, &e);
(void) sprintf(str, "%s: ", s);
str += strlen(str);
(void) strcpy(str, clnt_sperrno(e.re_status));
(void) sprintf(str, "%s: %s", s, clnt_sperrno(e.re_status));
str += strlen(str);
switch (e.re_status) {
case RPC_SUCCESS:
case RPC_CANTENCODEARGS:
case RPC_CANTDECODERES:
case RPC_TIMEDOUT:
case RPC_TIMEDOUT:
case RPC_PROGUNAVAIL:
case RPC_PROCUNAVAIL:
case RPC_CANTDECODEARGS:
@ -101,16 +99,14 @@ clnt_sperror(rpch, s)
case RPC_CANTSEND:
case RPC_CANTRECV:
(void) sprintf(str, "; errno = %s",
strerror(e.re_errno));
str += strlen(str);
(void) snprintf(str, CLNT_PERROR_BUFLEN - (str - strstart),
"; errno = %s\n", strerror(e.re_errno));
break;
case RPC_VERSMISMATCH:
(void) sprintf(str,
"; low version = %lu, high version = %lu",
"; low version = %lu, high version = %lu\n",
e.re_vers.low, e.re_vers.high);
str += strlen(str);
break;
case RPC_AUTHERROR:
@ -118,30 +114,28 @@ clnt_sperror(rpch, s)
(void) sprintf(str,"; why = ");
str += strlen(str);
if (err != NULL) {
(void) sprintf(str, "%s",err);
(void) sprintf(str, "%s\n",err);
} else {
(void) sprintf(str,
"(unknown authentication error - %d)",
"(unknown authentication error - %d)\n",
(int) e.re_why);
}
str += strlen(str);
break;
case RPC_PROGVERSMISMATCH:
(void) sprintf(str,
"; low version = %lu, high version = %lu",
(void) sprintf(str,
"; low version = %lu, high version = %lu\n",
e.re_vers.low, e.re_vers.high);
str += strlen(str);
break;
default: /* unknown */
(void) sprintf(str,
"; s1 = %lu, s2 = %lu",
(void) sprintf(str,
"; s1 = %lu, s2 = %lu\n",
e.re_lb.s1, e.re_lb.s2);
str += strlen(str);
break;
}
(void) sprintf(str, "\n");
strstart[CLNT_PERROR_BUFLEN-2] = '\n';
strstart[CLNT_PERROR_BUFLEN-1] = '\0';
return(strstart) ;
}
@ -150,52 +144,29 @@ clnt_perror(rpch, s)
CLIENT *rpch;
char *s;
{
(void) fprintf(stderr,"%s",clnt_sperror(rpch,s));
(void) fprintf(stderr,"%s\n",clnt_sperror(rpch,s));
}
struct rpc_errtab {
enum clnt_stat status;
char *message;
};
static struct rpc_errtab rpc_errlist[] = {
{ RPC_SUCCESS,
"RPC: Success" },
{ RPC_CANTENCODEARGS,
"RPC: Can't encode arguments" },
{ RPC_CANTDECODERES,
"RPC: Can't decode result" },
{ RPC_CANTSEND,
"RPC: Unable to send" },
{ RPC_CANTRECV,
"RPC: Unable to receive" },
{ RPC_TIMEDOUT,
"RPC: Timed out" },
{ RPC_VERSMISMATCH,
"RPC: Incompatible versions of RPC" },
{ RPC_AUTHERROR,
"RPC: Authentication error" },
{ RPC_PROGUNAVAIL,
"RPC: Program unavailable" },
{ RPC_PROGVERSMISMATCH,
"RPC: Program/version mismatch" },
{ RPC_PROCUNAVAIL,
"RPC: Procedure unavailable" },
{ RPC_CANTDECODEARGS,
"RPC: Server can't decode arguments" },
{ RPC_SYSTEMERROR,
"RPC: Remote system error" },
{ RPC_UNKNOWNHOST,
"RPC: Unknown host" },
{ RPC_UNKNOWNPROTO,
"RPC: Unknown protocol" },
{ RPC_PMAPFAILURE,
"RPC: Port mapper failure" },
{ RPC_PROGNOTREGISTERED,
"RPC: Program not registered"},
{ RPC_FAILED,
"RPC: Failed (unspecified error)"}
static const char *const rpc_errlist[] = {
"RPC: Success", /* 0 - RPC_SUCCESS */
"RPC: Can't encode arguments", /* 1 - RPC_CANTENCODEARGS */
"RPC: Can't decode result", /* 2 - RPC_CANTDECODERES */
"RPC: Unable to send", /* 3 - RPC_CANTSEND */
"RPC: Unable to receive", /* 4 - RPC_CANTRECV */
"RPC: Timed out", /* 5 - RPC_TIMEDOUT */
"RPC: Incompatible versions of RPC", /* 6 - RPC_VERSMISMATCH */
"RPC: Authentication error", /* 7 - RPC_AUTHERROR */
"RPC: Program unavailable", /* 8 - RPC_PROGUNAVAIL */
"RPC: Program/version mismatch", /* 9 - RPC_PROGVERSMISMATCH */
"RPC: Procedure unavailable", /* 10 - RPC_PROCUNAVAIL */
"RPC: Server can't decode arguments", /* 11 - RPC_CANTDECODEARGS */
"RPC: Remote system error", /* 12 - RPC_SYSTEMERROR */
"RPC: Unknown host", /* 13 - RPC_UNKNOWNHOST */
"RPC: Port mapper failure", /* 14 - RPC_PMAPFAILURE */
"RPC: Program not registered", /* 15 - RPC_PROGNOTREGISTERED */
"RPC: Failed (unspecified error)", /* 16 - RPC_FAILED */
"RPC: Unknown protocol" /* 17 - RPC_UNKNOWNPROTO */
};
@ -206,13 +177,11 @@ char *
clnt_sperrno(stat)
enum clnt_stat stat;
{
int i;
unsigned int errnum = stat;
if (errnum < (sizeof(rpc_errlist)/sizeof(rpc_errlist[0])))
return (char *)rpc_errlist[errnum];
for (i = 0; i < sizeof(rpc_errlist)/sizeof(struct rpc_errtab); i++) {
if (rpc_errlist[i].status == stat) {
return (rpc_errlist[i].message);
}
}
return ("RPC: (unknown error code)");
}
@ -220,7 +189,7 @@ void
clnt_perrno(num)
enum clnt_stat num;
{
(void) fprintf(stderr,"%s",clnt_sperrno(num));
(void) fprintf(stderr,"%s\n",clnt_sperrno(num));
}
@ -228,32 +197,29 @@ char *
clnt_spcreateerror(s)
char *s;
{
extern int sys_nerr;
char *str = _buf();
if (str == 0)
return(0);
(void) sprintf(str, "%s: ", s);
(void) strcat(str, clnt_sperrno(rpc_createerr.cf_stat));
switch (rpc_createerr.cf_stat) {
case RPC_PMAPFAILURE:
(void) strcat(str, " - ");
(void) strcat(str,
(void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s,
clnt_sperrno(rpc_createerr.cf_stat),
clnt_sperrno(rpc_createerr.cf_error.re_status));
break;
case RPC_SYSTEMERROR:
(void) strcat(str, " - ");
if (rpc_createerr.cf_error.re_errno > 0
&& rpc_createerr.cf_error.re_errno < sys_nerr)
(void) strcat(str,
strerror(rpc_createerr.cf_error.re_errno));
else
(void) sprintf(&str[strlen(str)], "Error %d",
rpc_createerr.cf_error.re_errno);
(void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s,
clnt_sperrno(rpc_createerr.cf_stat),
strerror(rpc_createerr.cf_error.re_errno));
break;
default:
(void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s\n", s,
clnt_sperrno(rpc_createerr.cf_stat));
break;
}
(void) strcat(str, "\n");
str[CLNT_PERROR_BUFLEN-2] = '\n';
str[CLNT_PERROR_BUFLEN-1] = '\0';
return (str);
}
@ -261,43 +227,28 @@ void
clnt_pcreateerror(s)
char *s;
{
(void) fprintf(stderr,"%s",clnt_spcreateerror(s));
(void) fprintf(stderr,"%s\n",clnt_spcreateerror(s));
}
struct auth_errtab {
enum auth_stat status;
char *message;
};
static struct auth_errtab auth_errlist[] = {
{ AUTH_OK,
"Authentication OK" },
{ AUTH_BADCRED,
"Invalid client credential" },
{ AUTH_REJECTEDCRED,
"Server rejected credential" },
{ AUTH_BADVERF,
"Invalid client verifier" },
{ AUTH_REJECTEDVERF,
"Server rejected verifier" },
{ AUTH_TOOWEAK,
"Client credential too weak" },
{ AUTH_INVALIDRESP,
"Invalid server verifier" },
{ AUTH_FAILED,
"Failed (unspecified error)" },
static const char *const auth_errlist[] = {
"Authentication OK", /* 0 - AUTH_OK */
"Invalid client credential", /* 1 - AUTH_BADCRED */
"Server rejected credential", /* 2 - AUTH_REJECTEDCRED */
"Invalid client verifier", /* 3 - AUTH_BADVERF */
"Server rejected verifier", /* 4 - AUTH_REJECTEDVERF */
"Client credential too weak", /* 5 - AUTH_TOOWEAK */
"Invalid server verifier", /* 6 - AUTH_INVALIDRESP */
"Failed (unspecified error)" /* 7 - AUTH_FAILED */
};
static char *
auth_errmsg(stat)
enum auth_stat stat;
{
int i;
unsigned int errnum = stat;
if (errnum < (sizeof(auth_errlist)/sizeof(auth_errlist[0])))
return (char *)auth_errlist[errnum];
for (i = 0; i < sizeof(auth_errlist)/sizeof(struct auth_errtab); i++) {
if (auth_errlist[i].status == stat) {
return(auth_errlist[i].message);
}
}
return(NULL);
}

View File

@ -5,11 +5,11 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
@ -17,11 +17,11 @@
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,7 +30,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)clnt_raw.c 2.2 88/08/01 4.0 RPCSRC";*/
static char *rcsid = "$Id: clnt_raw.c,v 1.1 1993/10/27 05:40:22 paul Exp $";
static char *rcsid = "$Id: clnt_raw.c,v 1.6 1996/12/30 14:21:36 peter Exp $";
#endif
/*
@ -45,6 +45,8 @@ static char *rcsid = "$Id: clnt_raw.c,v 1.1 1993/10/27 05:40:22 paul Exp $";
*/
#include <rpc/rpc.h>
#include <stdlib.h>
#include <stdio.h>
#define MCALL_MSG_SIZE 24
@ -97,13 +99,13 @@ clntraw_create(prog, vers)
clntraw_private = clp;
}
/*
* pre-serialize the staic part of the call msg and stash it away
* pre-serialize the static part of the call msg and stash it away
*/
call_msg.rm_direction = CALL;
call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
call_msg.rm_call.cb_prog = prog;
call_msg.rm_call.cb_vers = vers;
xdrmem_create(xdrs, clp->mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE);
xdrmem_create(xdrs, clp->mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE);
if (! xdr_callhdr(xdrs, &call_msg)) {
perror("clnt_raw.c - Fatal header serialization error.");
}
@ -123,7 +125,7 @@ clntraw_create(prog, vers)
return (client);
}
static enum clnt_stat
static enum clnt_stat
clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
CLIENT *h;
u_long proc;

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,18 +30,20 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)clnt_simple.c 2.2 88/08/01 4.0 RPCSRC";*/
static char *rcsid = "$Id: clnt_simple.c,v 1.1 1993/10/27 05:40:23 paul Exp $";
static char *rcsid = "$Id: clnt_simple.c,v 1.6 1996/12/30 14:23:50 peter Exp $";
#endif
/*
/*
* clnt_simple.c
* Simplified front end to rpc.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*/
#include <sys/param.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <rpc/rpc.h>
#include <sys/socket.h>
@ -54,8 +56,10 @@ static struct callrpc_private {
char *oldhost;
} *callrpc_private;
int
callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
char *host;
int prognum, versnum, procnum;
xdrproc_t inproc, outproc;
char *in, *out;
{
@ -72,16 +76,17 @@ callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
callrpc_private = crp;
}
if (crp->oldhost == NULL) {
crp->oldhost = malloc(256);
crp->oldhost = malloc(MAXHOSTNAMELEN);
crp->oldhost[0] = 0;
crp->socket = RPC_ANYSOCK;
}
if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum
&& strcmp(crp->oldhost, host) == 0) {
/* reuse old client */
/* reuse old client */
} else {
crp->valid = 0;
(void)close(crp->socket);
if (crp->socket != -1)
(void)close(crp->socket);
crp->socket = RPC_ANYSOCK;
if (crp->client) {
clnt_destroy(crp->client);
@ -91,7 +96,9 @@ callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
return ((int) RPC_UNKNOWNHOST);
timeout.tv_usec = 0;
timeout.tv_sec = 5;
bcopy(hp->h_addr, (char *)&server_addr.sin_addr, hp->h_length);
memset(&server_addr, 0, sizeof(server_addr));
memcpy((char *)&server_addr.sin_addr, hp->h_addr, hp->h_length);
server_addr.sin_len = sizeof(struct sockaddr_in);
server_addr.sin_family = AF_INET;
server_addr.sin_port = 0;
if ((crp->client = clntudp_create(&server_addr, (u_long)prognum,
@ -106,7 +113,7 @@ callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
tottimeout.tv_usec = 0;
clnt_stat = clnt_call(crp->client, procnum, inproc, in,
outproc, out, tottimeout);
/*
/*
* if call failed, empty cache
*/
if (clnt_stat != RPC_SUCCESS)

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,9 +30,9 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC";*/
static char *rcsid = "$Id: clnt_tcp.c,v 1.1 1993/10/27 05:40:24 paul Exp $";
static char *rcsid = "$Id: clnt_tcp.c,v 1.7 1996/12/30 14:36:17 peter Exp $";
#endif
/*
* clnt_tcp.c, Implements a TCP/IP based, client side RPC.
*
@ -53,6 +53,9 @@ static char *rcsid = "$Id: clnt_tcp.c,v 1.1 1993/10/27 05:40:24 paul Exp $";
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <rpc/rpc.h>
#include <sys/socket.h>
#include <netdb.h>
@ -61,8 +64,6 @@ static char *rcsid = "$Id: clnt_tcp.c,v 1.1 1993/10/27 05:40:24 paul Exp $";
#define MCALL_MSG_SIZE 24
extern int errno;
static int readtcp();
static int writetcp();
@ -87,7 +88,7 @@ struct ct_data {
bool_t ct_closeit;
struct timeval ct_wait;
bool_t ct_waitset; /* wait set by clnt_control? */
struct sockaddr_in ct_addr;
struct sockaddr_in ct_addr;
struct rpc_err ct_error;
char ct_mcall[MCALL_MSG_SIZE]; /* marshalled callmsg */
u_int ct_mpos; /* pos after marshal */
@ -118,9 +119,13 @@ clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
u_int recvsz;
{
CLIENT *h;
register struct ct_data *ct;
register struct ct_data *ct = NULL;
struct timeval now;
struct rpc_msg call_msg;
static u_int32_t disrupt;
if (disrupt == 0)
disrupt = (u_int32_t)(long)raddr;
h = (CLIENT *)mem_alloc(sizeof(*h));
if (h == NULL) {
@ -161,7 +166,8 @@ clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
sizeof(*raddr)) < 0)) {
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
(void)close(*sockp);
if (*sockp != -1)
(void)close(*sockp);
goto fooy;
}
ct->ct_closeit = TRUE;
@ -181,14 +187,14 @@ clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
* Initialize call message
*/
(void)gettimeofday(&now, (struct timezone *)0);
call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec;
call_msg.rm_xid = (++disrupt) ^ getpid() ^ now.tv_sec ^ now.tv_usec;
call_msg.rm_direction = CALL;
call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
call_msg.rm_call.cb_prog = prog;
call_msg.rm_call.cb_vers = vers;
/*
* pre-serialize the staic part of the call msg and stash it away
* pre-serialize the static part of the call msg and stash it away
*/
xdrmem_create(&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE,
XDR_ENCODE);
@ -216,8 +222,10 @@ fooy:
/*
* Something goofed, free stuff and barf
*/
mem_free((caddr_t)ct, sizeof(struct ct_data));
mem_free((caddr_t)h, sizeof(CLIENT));
if (ct)
mem_free((caddr_t)ct, sizeof(struct ct_data));
if (h)
mem_free((caddr_t)h, sizeof(CLIENT));
return ((CLIENT *)NULL);
}
@ -235,7 +243,7 @@ clnttcp_call(h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
register XDR *xdrs = &(ct->ct_xdrs);
struct rpc_msg reply_msg;
u_long x_id;
u_long *msg_x_id = (u_long *)(ct->ct_mcall); /* yuk */
u_int32_t *msg_x_id = (u_int32_t *)(ct->ct_mcall); /* yuk */
register bool_t shipnow;
int refreshes = 2;
@ -347,6 +355,7 @@ clnttcp_abort()
{
}
static bool_t
clnttcp_control(cl, request, info)
CLIENT *cl;
@ -354,18 +363,102 @@ clnttcp_control(cl, request, info)
char *info;
{
register struct ct_data *ct = (struct ct_data *)cl->cl_private;
register struct timeval *tv;
int len;
switch (request) {
case CLSET_FD_CLOSE:
ct->ct_closeit = TRUE;
break;
case CLSET_FD_NCLOSE:
ct->ct_closeit = FALSE;
break;
case CLSET_TIMEOUT:
ct->ct_wait = *(struct timeval *)info;
if (info == NULL)
return(FALSE);
tv = (struct timeval *)info;
ct->ct_wait.tv_sec = tv->tv_sec;
ct->ct_wait.tv_usec = tv->tv_usec;
ct->ct_waitset = TRUE;
break;
case CLGET_TIMEOUT:
if (info == NULL)
return(FALSE);
*(struct timeval *)info = ct->ct_wait;
break;
case CLGET_SERVER_ADDR:
if (info == NULL)
return(FALSE);
*(struct sockaddr_in *)info = ct->ct_addr;
break;
case CLGET_FD:
if (info == NULL)
return(FALSE);
*(int *)info = ct->ct_sock;
break;
case CLGET_XID:
/*
* use the knowledge that xid is the
* first element in the call structure *.
* This will get the xid of the PREVIOUS call
*/
if (info == NULL)
return(FALSE);
*(u_long *)info = ntohl(*(u_long *)ct->ct_mcall);
break;
case CLSET_XID:
/* This will set the xid of the NEXT call */
if (info == NULL)
return(FALSE);
*(u_long *)ct->ct_mcall = htonl(*(u_long *)info - 1);
/* decrement by 1 as clnttcp_call() increments once */
case CLGET_VERS:
/*
* This RELIES on the information that, in the call body,
* the version number field is the fifth field from the
* begining of the RPC header. MUST be changed if the
* call_struct is changed
*/
if (info == NULL)
return(FALSE);
*(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall +
4 * BYTES_PER_XDR_UNIT));
break;
case CLSET_VERS:
if (info == NULL)
return(FALSE);
*(u_long *)(ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT)
= htonl(*(u_long *)info);
break;
case CLGET_PROG:
/*
* This RELIES on the information that, in the call body,
* the program number field is the field from the
* begining of the RPC header. MUST be changed if the
* call_struct is changed
*/
if (info == NULL)
return(FALSE);
*(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall +
3 * BYTES_PER_XDR_UNIT));
break;
case CLSET_PROG:
if (info == NULL)
return(FALSE);
*(u_long *)(ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT)
= htonl(*(u_long *)info);
break;
case CLGET_LOCAL_ADDR:
len = sizeof(struct sockaddr);
if (getsockname(ct->ct_sock, (struct sockaddr *)info, &len) <0)
return(FALSE);
break;
case CLGET_RETRY_TIMEOUT:
case CLSET_RETRY_TIMEOUT:
case CLGET_SVC_ADDR:
case CLSET_SVC_ADDR:
case CLSET_PUSH_TIMOD:
case CLSET_POP_TIMOD:
default:
return (FALSE);
}
@ -399,35 +492,54 @@ readtcp(ct, buf, len)
caddr_t buf;
register int len;
{
#ifdef FD_SETSIZE
fd_set mask;
fd_set readfds;
if (len == 0)
return (0);
FD_ZERO(&mask);
FD_SET(ct->ct_sock, &mask);
#else
register int mask = 1 << (ct->ct_sock);
int readfds;
fd_set *fds, readfds;
struct timeval start, after, duration, delta, tmp, tv;
int r, save_errno;
if (len == 0)
return (0);
#endif /* def FD_SETSIZE */
if (ct->ct_sock + 1 > FD_SETSIZE) {
int bytes = howmany(ct->ct_sock + 1, NFDBITS) * sizeof(fd_mask);
fds = (fd_set *)malloc(bytes);
if (fds == NULL)
return (-1);
memset(fds, 0, bytes);
} else {
fds = &readfds;
FD_ZERO(fds);
}
gettimeofday(&start, NULL);
delta = ct->ct_wait;
while (TRUE) {
readfds = mask;
switch (select(_rpc_dtablesize(), &readfds, (int*)NULL, (int*)NULL,
&(ct->ct_wait))) {
/* XXX we know the other bits are still clear */
FD_SET(ct->ct_sock, fds);
tv = delta; /* in case select writes back */
r = select(ct->ct_sock+1, fds, NULL, NULL, &tv);
save_errno = errno;
gettimeofday(&after, NULL);
timersub(&start, &after, &duration);
timersub(&delta, &duration, &tmp);
delta = tmp;
if (delta.tv_sec < 0 || !timerisset(&delta))
r = 0;
switch (r) {
case 0:
if (fds != &readfds)
free(fds);
ct->ct_error.re_status = RPC_TIMEDOUT;
return (-1);
case -1:
if (errno == EINTR)
continue;
if (fds != &readfds)
free(fds);
ct->ct_error.re_status = RPC_CANTRECV;
ct->ct_error.re_errno = errno;
ct->ct_error.re_errno = save_errno;
return (-1);
}
break;

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,7 +30,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)clnt_udp.c 2.2 88/08/01 4.0 RPCSRC";*/
static char *rcsid = "$Id: clnt_udp.c,v 1.1 1993/10/27 05:40:25 paul Exp $";
static char *rcsid = "$Id: clnt_udp.c,v 1.8 1996/12/30 14:40:34 peter Exp $";
#endif
/*
@ -40,6 +40,9 @@ static char *rcsid = "$Id: clnt_udp.c,v 1.1 1993/10/27 05:40:25 paul Exp $";
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <rpc/rpc.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
@ -47,8 +50,6 @@ static char *rcsid = "$Id: clnt_udp.c,v 1.1 1993/10/27 05:40:25 paul Exp $";
#include <errno.h>
#include <rpc/pmap_clnt.h>
extern int errno;
/*
* UDP bases client side rpc operations
*/
@ -68,7 +69,7 @@ static struct clnt_ops udp_ops = {
clntudp_control
};
/*
/*
* Private data kept per client handle
*/
struct cu_data {
@ -114,9 +115,13 @@ clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
u_int recvsz;
{
CLIENT *cl;
register struct cu_data *cu;
register struct cu_data *cu = NULL;
struct timeval now;
struct rpc_msg call_msg;
static u_int32_t disrupt;
if (disrupt == 0)
disrupt = (u_int32_t)(long)raddr;
cl = (CLIENT *)mem_alloc(sizeof(CLIENT));
if (cl == NULL) {
@ -154,7 +159,7 @@ clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
cu->cu_total.tv_usec = -1;
cu->cu_sendsz = sendsz;
cu->cu_recvsz = recvsz;
call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec;
call_msg.rm_xid = (++disrupt) ^ getpid() ^ now.tv_sec ^ now.tv_usec;
call_msg.rm_direction = CALL;
call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
call_msg.rm_call.cb_prog = program;
@ -174,7 +179,7 @@ clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
rpc_createerr.cf_error.re_errno = errno;
goto fooy;
}
/* attempt to bind to prov port */
/* attempt to bind to priv port */
(void)bindresvport(*sockp, (struct sockaddr_in *)0);
/* the sockets rpc controls are non-blocking */
(void)ioctl(*sockp, FIONBIO, (char *) &dontblock);
@ -206,7 +211,7 @@ clntudp_create(raddr, program, version, wait, sockp)
UDPMSGSIZE, UDPMSGSIZE));
}
static enum clnt_stat
static enum clnt_stat
clntudp_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
register CLIENT *cl; /* client handle */
u_long proc; /* procedure number */
@ -221,29 +226,33 @@ clntudp_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
register int outlen;
register int inlen;
int fromlen;
#ifdef FD_SETSIZE
fd_set readfds;
fd_set mask;
#else
int readfds;
register int mask;
#endif /* def FD_SETSIZE */
fd_set *fds, readfds;
struct sockaddr_in from;
struct rpc_msg reply_msg;
XDR reply_xdrs;
struct timeval time_waited;
struct timeval time_waited, start, after, tmp1, tmp2, tv;
bool_t ok;
int nrefreshes = 2; /* number of times to refresh cred */
struct timeval timeout;
if (cu->cu_total.tv_usec == -1) {
if (cu->cu_total.tv_usec == -1)
timeout = utimeout; /* use supplied timeout */
} else {
else
timeout = cu->cu_total; /* use default timeout */
if (cu->cu_sock + 1 > FD_SETSIZE) {
int bytes = howmany(cu->cu_sock + 1, NFDBITS) * sizeof(fd_mask);
fds = (fd_set *)malloc(bytes);
if (fds == NULL)
return (cu->cu_error.re_status = RPC_CANTSEND);
memset(fds, 0, bytes);
} else {
fds = &readfds;
FD_ZERO(fds);
}
time_waited.tv_sec = 0;
time_waited.tv_usec = 0;
timerclear(&time_waited);
call_again:
xdrs = &(cu->cu_outxdrs);
xdrs->x_op = XDR_ENCODE;
@ -254,22 +263,28 @@ call_again:
(*(u_short *)(cu->cu_outbuf))++;
if ((! XDR_PUTLONG(xdrs, (long *)&proc)) ||
(! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
(! (*xargs)(xdrs, argsp)))
(! (*xargs)(xdrs, argsp))) {
if (fds != &readfds)
free(fds);
return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
}
outlen = (int)XDR_GETPOS(xdrs);
send_again:
if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0,
(struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen)
!= outlen) {
(struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen) != outlen) {
cu->cu_error.re_errno = errno;
if (fds != &readfds)
free(fds);
return (cu->cu_error.re_status = RPC_CANTSEND);
}
/*
* Hack to provide rpc-based message passing
*/
if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
if (!timerisset(&timeout)) {
if (fds != &readfds)
free(fds);
return (cu->cu_error.re_status = RPC_TIMEDOUT);
}
/*
@ -280,57 +295,60 @@ send_again:
reply_msg.acpted_rply.ar_verf = _null_auth;
reply_msg.acpted_rply.ar_results.where = resultsp;
reply_msg.acpted_rply.ar_results.proc = xresults;
#ifdef FD_SETSIZE
FD_ZERO(&mask);
FD_SET(cu->cu_sock, &mask);
#else
mask = 1 << cu->cu_sock;
#endif /* def FD_SETSIZE */
gettimeofday(&start, NULL);
for (;;) {
readfds = mask;
switch (select(_rpc_dtablesize(), &readfds, (int *)NULL,
(int *)NULL, &(cu->cu_wait))) {
/* XXX we know the other bits are still clear */
FD_SET(cu->cu_sock, fds);
tv = cu->cu_wait;
switch (select(cu->cu_sock+1, fds, NULL, NULL, &tv)) {
case 0:
time_waited.tv_sec += cu->cu_wait.tv_sec;
time_waited.tv_usec += cu->cu_wait.tv_usec;
while (time_waited.tv_usec >= 1000000) {
time_waited.tv_sec++;
time_waited.tv_usec -= 1000000;
}
if ((time_waited.tv_sec < timeout.tv_sec) ||
((time_waited.tv_sec == timeout.tv_sec) &&
(time_waited.tv_usec < timeout.tv_usec)))
goto send_again;
timeradd(&time_waited, &cu->cu_wait, &tmp1);
time_waited = tmp1;
if (timercmp(&time_waited, &timeout, <))
goto send_again;
if (fds != &readfds)
free(fds);
return (cu->cu_error.re_status = RPC_TIMEDOUT);
/*
* buggy in other cases because time_waited is not being
* updated.
*/
case -1:
if (errno == EINTR)
continue;
if (errno == EINTR) {
gettimeofday(&after, NULL);
timersub(&after, &start, &tmp1);
timeradd(&time_waited, &tmp1, &tmp2);
time_waited = tmp2;
if (timercmp(&time_waited, &timeout, <))
continue;
if (fds != &readfds)
free(fds);
return (cu->cu_error.re_status = RPC_TIMEDOUT);
}
cu->cu_error.re_errno = errno;
if (fds != &readfds)
free(fds);
return (cu->cu_error.re_status = RPC_CANTRECV);
}
do {
fromlen = sizeof(struct sockaddr);
inlen = recvfrom(cu->cu_sock, cu->cu_inbuf,
inlen = recvfrom(cu->cu_sock, cu->cu_inbuf,
(int) cu->cu_recvsz, 0,
(struct sockaddr *)&from, &fromlen);
} while (inlen < 0 && errno == EINTR);
if (inlen < 0) {
if (errno == EWOULDBLOCK)
continue;
continue;
cu->cu_error.re_errno = errno;
if (fds != &readfds)
free(fds);
return (cu->cu_error.re_status = RPC_CANTRECV);
}
if (inlen < sizeof(u_long))
continue;
if (inlen < sizeof(u_int32_t))
continue;
/* see if reply transaction id matches sent id */
if (*((u_long *)(cu->cu_inbuf)) != *((u_long *)(cu->cu_outbuf)))
continue;
if (*((u_int32_t *)(cu->cu_inbuf)) != *((u_int32_t *)(cu->cu_outbuf)))
continue;
/* we now assume we have the proper reply */
break;
}
@ -353,7 +371,7 @@ send_again:
xdrs->x_op = XDR_FREE;
(void)xdr_opaque_auth(xdrs,
&(reply_msg.acpted_rply.ar_verf));
}
}
} /* end successful completion */
else {
/* maybe our credentials need to be refreshed ... */
@ -366,6 +384,8 @@ send_again:
else {
cu->cu_error.re_status = RPC_CANTDECODERES;
}
if (fds != &readfds)
free(fds);
return (cu->cu_error.re_status);
}
@ -393,12 +413,13 @@ clntudp_freeres(cl, xdr_res, res_ptr)
return ((*xdr_res)(xdrs, res_ptr));
}
static void
static void
clntudp_abort(/*h*/)
/*CLIENT *h;*/
{
}
static bool_t
clntudp_control(cl, request, info)
CLIENT *cl;
@ -406,29 +427,117 @@ clntudp_control(cl, request, info)
char *info;
{
register struct cu_data *cu = (struct cu_data *)cl->cl_private;
register struct timeval *tv;
int len;
switch (request) {
case CLSET_FD_CLOSE:
cu->cu_closeit = TRUE;
break;
case CLSET_FD_NCLOSE:
cu->cu_closeit = FALSE;
break;
case CLSET_TIMEOUT:
cu->cu_total = *(struct timeval *)info;
if (info == NULL)
return(FALSE);
tv = (struct timeval *)info;
cu->cu_total.tv_sec = tv->tv_sec;
cu->cu_total.tv_usec = tv->tv_usec;
break;
case CLGET_TIMEOUT:
if (info == NULL)
return(FALSE);
*(struct timeval *)info = cu->cu_total;
break;
case CLSET_RETRY_TIMEOUT:
cu->cu_wait = *(struct timeval *)info;
if (info == NULL)
return(FALSE);
tv = (struct timeval *)info;
cu->cu_wait.tv_sec = tv->tv_sec;
cu->cu_wait.tv_usec = tv->tv_usec;
break;
case CLGET_RETRY_TIMEOUT:
if (info == NULL)
return(FALSE);
*(struct timeval *)info = cu->cu_wait;
break;
case CLGET_SERVER_ADDR:
if (info == NULL)
return(FALSE);
*(struct sockaddr_in *)info = cu->cu_raddr;
break;
case CLGET_FD:
if (info == NULL)
return(FALSE);
*(int *)info = cu->cu_sock;
break;
case CLGET_XID:
/*
* use the knowledge that xid is the
* first element in the call structure *.
* This will get the xid of the PREVIOUS call
*/
if (info == NULL)
return(FALSE);
*(u_long *)info = ntohl(*(u_long *)cu->cu_outbuf);
break;
case CLSET_XID:
/* This will set the xid of the NEXT call */
if (info == NULL)
return(FALSE);
*(u_long *)cu->cu_outbuf = htonl(*(u_long *)info - 1);
/* decrement by 1 as clntudp_call() increments once */
case CLGET_VERS:
/*
* This RELIES on the information that, in the call body,
* the version number field is the fifth field from the
* begining of the RPC header. MUST be changed if the
* call_struct is changed
*/
if (info == NULL)
return(FALSE);
*(u_long *)info = ntohl(*(u_long *)(cu->cu_outbuf +
4 * BYTES_PER_XDR_UNIT));
break;
case CLSET_VERS:
if (info == NULL)
return(FALSE);
*(u_long *)(cu->cu_outbuf + 4 * BYTES_PER_XDR_UNIT)
= htonl(*(u_long *)info);
break;
case CLGET_PROG:
/*
* This RELIES on the information that, in the call body,
* the program number field is the field from the
* begining of the RPC header. MUST be changed if the
* call_struct is changed
*/
if (info == NULL)
return(FALSE);
*(u_long *)info = ntohl(*(u_long *)(cu->cu_outbuf +
3 * BYTES_PER_XDR_UNIT));
break;
case CLSET_PROG:
if (info == NULL)
return(FALSE);
*(u_long *)(cu->cu_outbuf + 3 * BYTES_PER_XDR_UNIT)
= htonl(*(u_long *)info);
break;
case CLGET_LOCAL_ADDR:
len = sizeof(struct sockaddr);
if (getsockname(cu->cu_sock, (struct sockaddr *)info, &len) <0)
return(FALSE);
break;
case CLGET_SVC_ADDR:
case CLSET_SVC_ADDR:
case CLSET_PUSH_TIMOD:
case CLSET_POP_TIMOD:
default:
return (FALSE);
}
return (TRUE);
}
static void
clntudp_destroy(cl)
CLIENT *cl;

635
lib/libc/rpc/clnt_unix.c Normal file
View File

@ -0,0 +1,635 @@
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)clnt_unix.c 1.37 87/10/05 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)clnt_unix.c 2.2 88/08/01 4.0 RPCSRC";*/
static char *rcsid = "$Id: clnt_unix.c,v 1.7 1996/12/30 14:36:17 peter Exp $";
#endif
/*
* clnt_unix.c, Implements a AF_UNIX based, client side RPC.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*
* AF_UNIX based RPC supports 'batched calls'.
* A sequence of calls may be batched-up in a send buffer. The rpc call
* return immediately to the client even though the call was not necessarily
* sent. The batching occurs if the results' xdr routine is NULL (0) AND
* the rpc timeout value is zero (see clnt.h, rpc).
*
* Clients should NOT casually batch calls that in fact return results; that is,
* the server side should be aware that a call is batched and not produce any
* return message. Batched calls that produce many result messages can
* deadlock (netlock) the client and the server....
*
* Now go hang yourself.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <rpc/rpc.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netdb.h>
#include <errno.h>
#include <rpc/pmap_clnt.h>
#define MCALL_MSG_SIZE 24
static int readunix();
static int writeunix();
static enum clnt_stat clntunix_call();
static void clntunix_abort();
static void clntunix_geterr();
static bool_t clntunix_freeres();
static bool_t clntunix_control();
static void clntunix_destroy();
static struct clnt_ops unix_ops = {
clntunix_call,
clntunix_abort,
clntunix_geterr,
clntunix_freeres,
clntunix_destroy,
clntunix_control
};
struct ct_data {
int ct_sock;
bool_t ct_closeit;
struct timeval ct_wait;
bool_t ct_waitset; /* wait set by clnt_control? */
struct sockaddr_un ct_addr;
struct rpc_err ct_error;
char ct_mcall[MCALL_MSG_SIZE]; /* marshalled callmsg */
u_int ct_mpos; /* pos after marshal */
XDR ct_xdrs;
};
/*
* Create a client handle for a unix/ip connection.
* If *sockp<0, *sockp is set to a newly created TCP socket and it is
* connected to raddr. If *sockp non-negative then
* raddr is ignored. The rpc/unix package does buffering
* similar to stdio, so the client must pick send and receive buffer sizes,];
* 0 => use the default.
* If raddr->sin_port is 0, then a binder on the remote machine is
* consulted for the right port number.
* NB: *sockp is copied into a private area.
* NB: It is the clients responsibility to close *sockp.
* NB: The rpch->cl_auth is set null authentication. Caller may wish to set this
* something more useful.
*/
CLIENT *
clntunix_create(raddr, prog, vers, sockp, sendsz, recvsz)
struct sockaddr_un *raddr;
u_long prog;
u_long vers;
register int *sockp;
u_int sendsz;
u_int recvsz;
{
CLIENT *h;
register struct ct_data *ct = NULL;
struct timeval now;
struct rpc_msg call_msg;
static u_int32_t disrupt;
int len;
if (disrupt == 0)
disrupt = (u_int32_t)(long)raddr;
h = (CLIENT *)mem_alloc(sizeof(*h));
if (h == NULL) {
(void)fprintf(stderr, "clntunix_create: out of memory\n");
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
goto fooy;
}
ct = (struct ct_data *)mem_alloc(sizeof(*ct));
if (ct == NULL) {
(void)fprintf(stderr, "clntunix_create: out of memory\n");
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
goto fooy;
}
/*
* If no socket given, open one
*/
if (*sockp < 0) {
*sockp = socket(AF_UNIX, SOCK_STREAM, 0);
len = strlen(raddr->sun_path) + sizeof(raddr->sun_family) +
sizeof(raddr->sun_len) + 1;
raddr->sun_len = len;
if ((*sockp < 0)
|| (connect(*sockp, (struct sockaddr *)raddr, len) < 0)) {
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
if (*sockp != -1)
(void)close(*sockp);
goto fooy;
}
ct->ct_closeit = TRUE;
} else {
ct->ct_closeit = FALSE;
}
/*
* Set up private data struct
*/
ct->ct_sock = *sockp;
ct->ct_wait.tv_usec = 0;
ct->ct_waitset = FALSE;
ct->ct_addr = *raddr;
/*
* Initialize call message
*/
(void)gettimeofday(&now, (struct timezone *)0);
call_msg.rm_xid = (++disrupt) ^ getpid() ^ now.tv_sec ^ now.tv_usec;
call_msg.rm_direction = CALL;
call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
call_msg.rm_call.cb_prog = prog;
call_msg.rm_call.cb_vers = vers;
/*
* pre-serialize the static part of the call msg and stash it away
*/
xdrmem_create(&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE,
XDR_ENCODE);
if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) {
if (ct->ct_closeit) {
(void)close(*sockp);
}
goto fooy;
}
ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs));
XDR_DESTROY(&(ct->ct_xdrs));
/*
* Create a client handle which uses xdrrec for serialization
* and authnone for authentication.
*/
xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz,
(caddr_t)ct, readunix, writeunix);
h->cl_ops = &unix_ops;
h->cl_private = (caddr_t) ct;
h->cl_auth = authnone_create();
return (h);
fooy:
/*
* Something goofed, free stuff and barf
*/
if (ct)
mem_free((caddr_t)ct, sizeof(struct ct_data));
if (h)
mem_free((caddr_t)h, sizeof(CLIENT));
return ((CLIENT *)NULL);
}
static enum clnt_stat
clntunix_call(h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
register CLIENT *h;
u_long proc;
xdrproc_t xdr_args;
caddr_t args_ptr;
xdrproc_t xdr_results;
caddr_t results_ptr;
struct timeval timeout;
{
register struct ct_data *ct = (struct ct_data *) h->cl_private;
register XDR *xdrs = &(ct->ct_xdrs);
struct rpc_msg reply_msg;
u_long x_id;
u_int32_t *msg_x_id = (u_int32_t *)(ct->ct_mcall); /* yuk */
register bool_t shipnow;
int refreshes = 2;
if (!ct->ct_waitset) {
ct->ct_wait = timeout;
}
shipnow =
(xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0
&& timeout.tv_usec == 0) ? FALSE : TRUE;
call_again:
xdrs->x_op = XDR_ENCODE;
ct->ct_error.re_status = RPC_SUCCESS;
x_id = ntohl(--(*msg_x_id));
if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) ||
(! XDR_PUTLONG(xdrs, (long *)&proc)) ||
(! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
(! (*xdr_args)(xdrs, args_ptr))) {
if (ct->ct_error.re_status == RPC_SUCCESS)
ct->ct_error.re_status = RPC_CANTENCODEARGS;
(void)xdrrec_endofrecord(xdrs, TRUE);
return (ct->ct_error.re_status);
}
if (! xdrrec_endofrecord(xdrs, shipnow))
return (ct->ct_error.re_status = RPC_CANTSEND);
if (! shipnow)
return (RPC_SUCCESS);
/*
* Hack to provide rpc-based message passing
*/
if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
return(ct->ct_error.re_status = RPC_TIMEDOUT);
}
/*
* Keep receiving until we get a valid transaction id
*/
xdrs->x_op = XDR_DECODE;
while (TRUE) {
reply_msg.acpted_rply.ar_verf = _null_auth;
reply_msg.acpted_rply.ar_results.where = NULL;
reply_msg.acpted_rply.ar_results.proc = xdr_void;
if (! xdrrec_skiprecord(xdrs))
return (ct->ct_error.re_status);
/* now decode and validate the response header */
if (! xdr_replymsg(xdrs, &reply_msg)) {
if (ct->ct_error.re_status == RPC_SUCCESS)
continue;
return (ct->ct_error.re_status);
}
if (reply_msg.rm_xid == x_id)
break;
}
/*
* process header
*/
_seterr_reply(&reply_msg, &(ct->ct_error));
if (ct->ct_error.re_status == RPC_SUCCESS) {
if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) {
ct->ct_error.re_status = RPC_AUTHERROR;
ct->ct_error.re_why = AUTH_INVALIDRESP;
} else if (! (*xdr_results)(xdrs, results_ptr)) {
if (ct->ct_error.re_status == RPC_SUCCESS)
ct->ct_error.re_status = RPC_CANTDECODERES;
}
/* free verifier ... */
if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
xdrs->x_op = XDR_FREE;
(void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf));
}
} /* end successful completion */
else {
/* maybe our credentials need to be refreshed ... */
if (refreshes-- && AUTH_REFRESH(h->cl_auth))
goto call_again;
} /* end of unsuccessful completion */
return (ct->ct_error.re_status);
}
static void
clntunix_geterr(h, errp)
CLIENT *h;
struct rpc_err *errp;
{
register struct ct_data *ct =
(struct ct_data *) h->cl_private;
*errp = ct->ct_error;
}
static bool_t
clntunix_freeres(cl, xdr_res, res_ptr)
CLIENT *cl;
xdrproc_t xdr_res;
caddr_t res_ptr;
{
register struct ct_data *ct = (struct ct_data *)cl->cl_private;
register XDR *xdrs = &(ct->ct_xdrs);
xdrs->x_op = XDR_FREE;
return ((*xdr_res)(xdrs, res_ptr));
}
static void
clntunix_abort()
{
}
static bool_t
clntunix_control(cl, request, info)
CLIENT *cl;
int request;
char *info;
{
register struct ct_data *ct = (struct ct_data *)cl->cl_private;
register struct timeval *tv;
int len;
switch (request) {
case CLSET_FD_CLOSE:
ct->ct_closeit = TRUE;
break;
case CLSET_FD_NCLOSE:
ct->ct_closeit = FALSE;
break;
case CLSET_TIMEOUT:
if (info == NULL)
return(FALSE);
tv = (struct timeval *)info;
ct->ct_wait.tv_sec = tv->tv_sec;
ct->ct_wait.tv_usec = tv->tv_usec;
ct->ct_waitset = TRUE;
break;
case CLGET_TIMEOUT:
if (info == NULL)
return(FALSE);
*(struct timeval *)info = ct->ct_wait;
break;
case CLGET_SERVER_ADDR:
if (info == NULL)
return(FALSE);
*(struct sockaddr_un *)info = ct->ct_addr;
break;
case CLGET_FD:
if (info == NULL)
return(FALSE);
*(int *)info = ct->ct_sock;
break;
case CLGET_XID:
/*
* use the knowledge that xid is the
* first element in the call structure *.
* This will get the xid of the PREVIOUS call
*/
if (info == NULL)
return(FALSE);
*(u_long *)info = ntohl(*(u_long *)ct->ct_mcall);
break;
case CLSET_XID:
/* This will set the xid of the NEXT call */
if (info == NULL)
return(FALSE);
*(u_long *)ct->ct_mcall = htonl(*(u_long *)info - 1);
/* decrement by 1 as clntunix_call() increments once */
case CLGET_VERS:
/*
* This RELIES on the information that, in the call body,
* the version number field is the fifth field from the
* begining of the RPC header. MUST be changed if the
* call_struct is changed
*/
if (info == NULL)
return(FALSE);
*(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall +
4 * BYTES_PER_XDR_UNIT));
break;
case CLSET_VERS:
if (info == NULL)
return(FALSE);
*(u_long *)(ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT)
= htonl(*(u_long *)info);
break;
case CLGET_PROG:
/*
* This RELIES on the information that, in the call body,
* the program number field is the field from the
* begining of the RPC header. MUST be changed if the
* call_struct is changed
*/
if (info == NULL)
return(FALSE);
*(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall +
3 * BYTES_PER_XDR_UNIT));
break;
case CLSET_PROG:
if (info == NULL)
return(FALSE);
*(u_long *)(ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT)
= htonl(*(u_long *)info);
break;
case CLGET_LOCAL_ADDR:
len = sizeof(struct sockaddr);
if (getsockname(ct->ct_sock, (struct sockaddr *)info, &len) <0)
return(FALSE);
break;
case CLGET_RETRY_TIMEOUT:
case CLSET_RETRY_TIMEOUT:
case CLGET_SVC_ADDR:
case CLSET_SVC_ADDR:
case CLSET_PUSH_TIMOD:
case CLSET_POP_TIMOD:
default:
return (FALSE);
}
return (TRUE);
}
static void
clntunix_destroy(h)
CLIENT *h;
{
register struct ct_data *ct =
(struct ct_data *) h->cl_private;
if (ct->ct_closeit) {
(void)close(ct->ct_sock);
}
XDR_DESTROY(&(ct->ct_xdrs));
mem_free((caddr_t)ct, sizeof(struct ct_data));
mem_free((caddr_t)h, sizeof(CLIENT));
}
/*
* read() and write() are replaced with recvmsg()/sendmsg() so that
* we can pass ancillary control data. In this case, the data constists
* of credential information which the kernel will fill in for us.
* XXX: This code is specific to FreeBSD and will not work on other
* platforms without the requisite kernel modifications.
*/
struct cmessage {
struct cmsghdr cmsg;
struct cmsgcred cmcred;
};
static int __msgread(sock, buf, cnt)
int sock;
void *buf;
size_t cnt;
{
struct iovec iov[1];
struct msghdr msg;
struct cmessage cm;
bzero((char *)&cm, sizeof(cm));
iov[0].iov_base = buf;
iov[0].iov_len = cnt;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = (caddr_t)&cm;
msg.msg_controllen = sizeof(struct cmessage);
msg.msg_flags = 0;
return(recvmsg(sock, &msg, 0));
}
static int __msgwrite(sock, buf, cnt)
int sock;
void *buf;
size_t cnt;
{
struct iovec iov[1];
struct msghdr msg;
struct cmessage cm;
bzero((char *)&cm, sizeof(cm));
iov[0].iov_base = buf;
iov[0].iov_len = cnt;
cm.cmsg.cmsg_type = SCM_CREDS;
cm.cmsg.cmsg_level = SOL_SOCKET;
cm.cmsg.cmsg_len = sizeof(struct cmessage);
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = (caddr_t)&cm;
msg.msg_controllen = sizeof(struct cmessage);
msg.msg_flags = 0;
return(sendmsg(sock, &msg, 0));
}
/*
* Interface between xdr serializer and unix connection.
* Behaves like the system calls, read & write, but keeps some error state
* around for the rpc level.
*/
static int
readunix(ct, buf, len)
register struct ct_data *ct;
caddr_t buf;
register int len;
{
fd_set *fds, readfds;
struct timeval start, after, duration, delta, tmp, tv;
int r, save_errno;
if (len == 0)
return (0);
if (ct->ct_sock + 1 > FD_SETSIZE) {
int bytes = howmany(ct->ct_sock + 1, NFDBITS) * sizeof(fd_mask);
fds = (fd_set *)malloc(bytes);
if (fds == NULL)
return (-1);
memset(fds, 0, bytes);
} else {
fds = &readfds;
FD_ZERO(fds);
}
gettimeofday(&start, NULL);
delta = ct->ct_wait;
while (TRUE) {
/* XXX we know the other bits are still clear */
FD_SET(ct->ct_sock, fds);
tv = delta; /* in case select writes back */
r = select(ct->ct_sock+1, fds, NULL, NULL, &tv);
save_errno = errno;
gettimeofday(&after, NULL);
timersub(&start, &after, &duration);
timersub(&delta, &duration, &tmp);
delta = tmp;
if (delta.tv_sec < 0 || !timerisset(&delta))
r = 0;
switch (r) {
case 0:
if (fds != &readfds)
free(fds);
ct->ct_error.re_status = RPC_TIMEDOUT;
return (-1);
case -1:
if (errno == EINTR)
continue;
if (fds != &readfds)
free(fds);
ct->ct_error.re_status = RPC_CANTRECV;
ct->ct_error.re_errno = save_errno;
return (-1);
}
break;
}
switch (len = __msgread(ct->ct_sock, buf, len)) {
case 0:
/* premature eof */
ct->ct_error.re_errno = ECONNRESET;
ct->ct_error.re_status = RPC_CANTRECV;
len = -1; /* it's really an error */
break;
case -1:
ct->ct_error.re_errno = errno;
ct->ct_error.re_status = RPC_CANTRECV;
break;
}
return (len);
}
static int
writeunix(ct, buf, len)
struct ct_data *ct;
caddr_t buf;
int len;
{
register int i, cnt;
for (cnt = len; cnt > 0; cnt -= i, buf += i) {
if ((i = __msgwrite(ct->ct_sock, buf, cnt)) == -1) {
ct->ct_error.re_errno = errno;
ct->ct_error.re_status = RPC_CANTSEND;
return (-1);
}
}
return (len);
}

View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 1996
* Bill Paul <wpaul@ctr.columbia.edu>. 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 Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul 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.
*
* $Id$
*/
#include <sys/types.h>
#include <rpc/des_crypt.h>
#include <rpc/des.h>
#include <string.h>
#include <rpcsvc/crypt.h>
#ifndef lint
static const char rcsid[] = "$Id$";
#endif
#ifndef KEYSERVSOCK
#define KEYSERVSOCK "/var/run/keyservsock"
#endif
int
_des_crypt_call(buf, len, dparms)
char *buf;
int len;
struct desparams *dparms;
{
CLIENT *clnt;
desresp *result_1;
desargs des_crypt_1_arg;
int stat;
clnt = clnt_create(KEYSERVSOCK, CRYPT_PROG, CRYPT_VERS, "unix");
if (clnt == (CLIENT *) NULL) {
return(DESERR_HWERROR);
}
des_crypt_1_arg.desbuf.desbuf_len = len;
des_crypt_1_arg.desbuf.desbuf_val = buf;
des_crypt_1_arg.des_dir = dparms->des_dir;
des_crypt_1_arg.des_mode = dparms->des_mode;
bcopy(dparms->des_ivec, des_crypt_1_arg.des_ivec, 8);
bcopy(dparms->des_key, des_crypt_1_arg.des_key, 8);
result_1 = des_crypt_1(&des_crypt_1_arg, clnt);
if (result_1 == (desresp *) NULL) {
return(DESERR_HWERROR);
}
stat = result_1->stat;
if (result_1->stat == DESERR_NONE ||
result_1->stat == DESERR_NOHWDEVICE) {
bcopy(result_1->desbuf.desbuf_val, buf, len);
bcopy(result_1->des_ivec, dparms->des_ivec, 8);
}
clnt_freeres(clnt, xdr_desresp, (char *)result_1);
clnt_destroy(clnt);
return(stat);
}

126
lib/libc/rpc/des_crypt.3 Normal file
View File

@ -0,0 +1,126 @@
.\" @(#)des_crypt.3 2.1 88/08/11 4.0 RPCSRC; from 1.16 88/03/02 SMI;
.TH DES_CRYPT 3 "6 October 1987"
.SH NAME
des_crypt, ecb_crypt, cbc_crypt, des_setparity \- fast DES encryption
.SH SYNOPSIS
.nf
.B #include <des_crypt.h>
.LP
.B int ecb_crypt(key, data, datalen, mode)
.B char *key;
.B char *data;
.B unsigned datalen;
.B unsigned mode;
.LP
.B int cbc_crypt(key, data, datalen, mode, ivec)
.B char *key;
.B char *data;
.B unsigned datalen;
.B unsigned mode;
.B char *ivec;
.LP
.B void des_setparity(key)
.B char *key;
.fi
.SH DESCRIPTION
.IX encryption cbc_crypt "" \fLcbc_crypt\fP
.IX "des encryption" cbc_crypt "DES encryption" \fLcbc_crypt\fP
.IX encryption des_setparity "" \fLdes_setparity\fP
.IX "des encryption" des_setparity "DES encryption" \fLdes_setparity\fP
.B ecb_crypt(\|)
and
.B cbc_crypt(\|)
implement the
.SM NBS
.SM DES
(Data Encryption Standard).
These routines are faster and more general purpose than
.BR crypt (3).
They also are able to utilize
.SM DES
hardware if it is available.
.B ecb_crypt(\|)
encrypts in
.SM ECB
(Electronic Code Book)
mode, which encrypts blocks of data independently.
.B cbc_crypt(\|)
encrypts in
.SM CBC
(Cipher Block Chaining)
mode, which chains together
successive blocks.
.SM CBC
mode protects against insertions, deletions and
substitutions of blocks. Also, regularities in the clear text will
not appear in the cipher text.
.LP
Here is how to use these routines. The first parameter,
.IR key ,
is the 8-byte encryption key with parity.
To set the key's parity, which for
.SM DES
is in the low bit of each byte, use
.IR des_setparity .
The second parameter,
.IR data ,
contains the data to be encrypted or decrypted. The
third parameter,
.IR datalen ,
is the length in bytes of
.IR data ,
which must be a multiple of 8. The fourth parameter,
.IR mode ,
is formed by
.SM OR\s0'ing
together some things. For the encryption direction 'or' in either
.SM DES_ENCRYPT
or
.SM DES_DECRYPT\s0.
For software versus hardware
encryption, 'or' in either
.SM DES_HW
or
.SM DES_SW\s0.
If
.SM DES_HW
is specified, and there is no hardware, then the encryption is performed
in software and the routine returns
.SM DESERR_NOHWDEVICE\s0.
For
.IR cbc_crypt ,
the parameter
.I ivec
is the the 8-byte initialization
vector for the chaining. It is updated to the next initialization
vector upon return.
.LP
.SH "SEE ALSO"
.BR des (1),
.BR crypt (3)
.SH DIAGNOSTICS
.PD 0
.TP 20
.SM DESERR_NONE
No error.
.TP
.SM DESERR_NOHWDEVICE
Encryption succeeded, but done in software instead of the requested hardware.
.TP
.SM DESERR_HWERR
An error occurred in the hardware or driver.
.TP
.SM DESERR_BADPARAM
Bad parameter to routine.
.PD
.LP
Given a result status
.IR stat ,
the macro
.SM DES_FAILED\c
.BR ( stat )
is false only for the first two statuses.
.SH RESTRICTIONS
These routines are not available in RPCSRC 4.0.
This information is provided to describe the DES interface expected by
Secure RPC.

153
lib/libc/rpc/des_crypt.c Normal file
View File

@ -0,0 +1,153 @@
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* des_crypt.c, DES encryption library routines
* Copyright (C) 1986, Sun Microsystems, Inc.
*/
#include <sys/types.h>
#include <rpc/des_crypt.h>
#include <rpc/des.h>
#ifndef lint
/* from: static char sccsid[] = "@(#)des_crypt.c 2.2 88/08/10 4.0 RPCSRC; from 1.13 88/02/08 SMI"; */
static const char rcsid[] = "$Id$";
#endif
static int common_crypt __P(( char *, char *, register unsigned, unsigned, struct desparams * ));
int (*__des_crypt_LOCAL)() = 0;
extern _des_crypt_call __P(( char *, int, struct desparams * ));
/*
* Copy 8 bytes
*/
#define COPY8(src, dst) { \
register char *a = (char *) dst; \
register char *b = (char *) src; \
*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
}
/*
* Copy multiple of 8 bytes
*/
#define DESCOPY(src, dst, len) { \
register char *a = (char *) dst; \
register char *b = (char *) src; \
register int i; \
for (i = (int) len; i > 0; i -= 8) { \
*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
} \
}
/*
* CBC mode encryption
*/
int
cbc_crypt(key, buf, len, mode, ivec)
char *key;
char *buf;
unsigned len;
unsigned mode;
char *ivec;
{
int err;
struct desparams dp;
#ifdef BROKEN_DES
dp.UDES.UDES_buf = buf;
dp.des_mode = ECB;
#else
dp.des_mode = CBC;
#endif
COPY8(ivec, dp.des_ivec);
err = common_crypt(key, buf, len, mode, &dp);
COPY8(dp.des_ivec, ivec);
return(err);
}
/*
* ECB mode encryption
*/
int
ecb_crypt(key, buf, len, mode)
char *key;
char *buf;
unsigned len;
unsigned mode;
{
struct desparams dp;
#ifdef BROKEN_DES
dp.UDES.UDES_buf = buf;
dp.des_mode = CBC;
#else
dp.des_mode = ECB;
#endif
return(common_crypt(key, buf, len, mode, &dp));
}
/*
* Common code to cbc_crypt() & ecb_crypt()
*/
static int
common_crypt(key, buf, len, mode, desp)
char *key;
char *buf;
register unsigned len;
unsigned mode;
register struct desparams *desp;
{
register int desdev;
if ((len % 8) != 0 || len > DES_MAXDATA) {
return(DESERR_BADPARAM);
}
desp->des_dir =
((mode & DES_DIRMASK) == DES_ENCRYPT) ? ENCRYPT : DECRYPT;
desdev = mode & DES_DEVMASK;
COPY8(key, desp->des_key);
/*
* software
*/
if (__des_crypt_LOCAL != NULL) {
if (!__des_crypt_LOCAL(buf, len, desp)) {
return (DESERR_HWERROR);
}
} else {
if (!_des_crypt_call(buf, len, desp)) {
return (DESERR_HWERROR);
}
}
return(desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE);
}

67
lib/libc/rpc/des_soft.c Normal file
View File

@ -0,0 +1,67 @@
#if !defined(lint) && defined(SCCSIDS)
static char sccsid[] = "@(#)des_soft.c 2.2 88/08/10 4.0 RPCSRC; from 1.13 88/02/08 SMI";
#endif
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Table giving odd parity in the low bit for ASCII characters
*/
static char partab[128] = {
0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x07, 0x07,
0x08, 0x08, 0x0b, 0x0b, 0x0d, 0x0d, 0x0e, 0x0e,
0x10, 0x10, 0x13, 0x13, 0x15, 0x15, 0x16, 0x16,
0x19, 0x19, 0x1a, 0x1a, 0x1c, 0x1c, 0x1f, 0x1f,
0x20, 0x20, 0x23, 0x23, 0x25, 0x25, 0x26, 0x26,
0x29, 0x29, 0x2a, 0x2a, 0x2c, 0x2c, 0x2f, 0x2f,
0x31, 0x31, 0x32, 0x32, 0x34, 0x34, 0x37, 0x37,
0x38, 0x38, 0x3b, 0x3b, 0x3d, 0x3d, 0x3e, 0x3e,
0x40, 0x40, 0x43, 0x43, 0x45, 0x45, 0x46, 0x46,
0x49, 0x49, 0x4a, 0x4a, 0x4c, 0x4c, 0x4f, 0x4f,
0x51, 0x51, 0x52, 0x52, 0x54, 0x54, 0x57, 0x57,
0x58, 0x58, 0x5b, 0x5b, 0x5d, 0x5d, 0x5e, 0x5e,
0x61, 0x61, 0x62, 0x62, 0x64, 0x64, 0x67, 0x67,
0x68, 0x68, 0x6b, 0x6b, 0x6d, 0x6d, 0x6e, 0x6e,
0x70, 0x70, 0x73, 0x73, 0x75, 0x75, 0x76, 0x76,
0x79, 0x79, 0x7a, 0x7a, 0x7c, 0x7c, 0x7f, 0x7f,
};
/*
* Add odd parity to low bit of 8 byte key
*/
void
des_setparity(p)
char *p;
{
int i;
for (i = 0; i < 8; i++) {
*p = partab[*p & 0x7f];
p++;
}
}

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,7 +30,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)get_myaddress.c 1.4 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)get_myaddress.c 2.1 88/07/29 4.0 RPCSRC";*/
static char *rcsid = "$Id: get_myaddress.c,v 1.1 1993/10/27 05:40:27 paul Exp $";
static char *rcsid = "$Id: get_myaddress.c,v 1.6 1996/12/30 14:26:28 peter Exp $";
#endif
/*
@ -45,55 +45,65 @@ static char *rcsid = "$Id: get_myaddress.c,v 1.1 1993/10/27 05:40:27 paul Exp $"
#include <rpc/pmap_prot.h>
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/*
/*
* don't use gethostbyname, which would invoke yellow pages
*
* Avoid loopback interfaces. We return information from a loopback
* interface only if there are no other possible interfaces.
*/
int
get_myaddress(addr)
struct sockaddr_in *addr;
{
int s;
char buf[BUFSIZ];
struct ifconf ifc;
struct ifreq ifreq, *ifr;
int len, slop;
struct ifreq ifreq, *ifr, *end;
int loopback = 0, gotit = 0;
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("get_myaddress: socket");
exit(1);
return(-1);
}
ifc.ifc_len = sizeof (buf);
ifc.ifc_buf = buf;
if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
perror("get_myaddress: ioctl (get interface configuration)");
exit(1);
close(s);
return(-1);
}
again:
ifr = ifc.ifc_req;
for (len = ifc.ifc_len; len; len -= sizeof ifreq) {
end = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
while (ifr < end) {
ifreq = *ifr;
if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
perror("get_myaddress: ioctl");
exit(1);
close(s);
return(-1);
}
if ((ifreq.ifr_flags & IFF_UP) &&
ifr->ifr_addr.sa_family == AF_INET) {
ifr->ifr_addr.sa_family == AF_INET &&
(loopback == 1 && (ifreq.ifr_flags & IFF_LOOPBACK))) {
*addr = *((struct sockaddr_in *)&ifr->ifr_addr);
addr->sin_port = htons(PMAPPORT);
gotit = 1;
break;
}
/*
* Deal with variable length addresses
*/
slop = ifr->ifr_addr.sa_len - sizeof (struct sockaddr);
if (slop) {
ifr = (struct ifreq *) ((caddr_t)ifr + slop);
len -= slop;
}
if (ifr->ifr_addr.sa_len)
ifr = (struct ifreq *) ((caddr_t) ifr +
ifr->ifr_addr.sa_len -
sizeof(struct sockaddr));
ifr++;
}
if (gotit == 0 && loopback == 0) {
loopback = 1;
goto again;
}
(void) close(s);
return (0);
}

View File

@ -1,108 +1,95 @@
.\" @(#)getrpcent.3n 2.2 88/08/02 4.0 RPCSRC; from 1.11 88/03/14 SMI
.TH GETRPCENT 3N "14 December 1987"
.SH NAME
getrpcent, getrpcbyname, getrpcbynumber \- get RPC entry
.SH SYNOPSIS
.nf
.ft B
#include <netdb.h>
.LP
.ft B
struct rpcent *getrpcent(\|)
.LP
.ft B
struct rpcent *getrpcbyname(name)
char *name;
.LP
.ft B
struct rpcent *getrpcbynumber(number)
int number;
.LP
.ft B
setrpcent (stayopen)
int stayopen
.LP
.ft B
endrpcent (\|)
.fi
.SH DESCRIPTION
.LP
.BR getrpcent(\|) ,
.BR getrpcbyname(\|) ,
.Dd "December 14, 1987"
.Dt GETRPCENT 3
.Os
.Sh NAME
.Nm getrpcent ,
.Nm getrpcbyname ,
.Nm getrpcbynumber ,
.Nm endrpcent ,
.Nm setrpcent
.Nd get RPC entry
.Sh SYNOPSIS
.Fd #include <netdb.h>
.Ft struct rpcent *
.Fn getrpcent void
.Ft struct rpcent *
.Fn getrpcbyname "char *name"
.Ft struct rpcent *
.Fn getrpcbynumber "int number"
.Ft void
.Fn setrpcent "int stayopen"
.Ft void
.Fn endrpcent void
.Sh DESCRIPTION
The
.Fn getrpcent ,
.Fn getrpcbyname ,
and
.B getrpcbynumber(\|)
each return a pointer to an object with the
.Fn getrpcbynumber
functions each return a pointer to an object with the
following structure
containing the broken-out
fields of a line in the rpc program number data base,
.BR /etc/rpc .
.RS
.LP
.nf
.ft B
.Pa /etc/rpc .
.Bd -literal
struct rpcent {
char *r_name; /* name of server for this rpc program */
char **r_aliases; /* alias list */
long r_number; /* rpc program number */
};
.ft R
.fi
.RE
.LP
.Ed
.Pp
The members of this structure are:
.RS
.PD 0
.TP 20
.B r_name
.Bl -tag -width r_aliasesxxx
.It Fa r_name
The name of the server for this rpc program.
.TP 20
.B r_aliases
.It Fa r_aliases
A zero terminated list of alternate names for the rpc program.
.TP 20
.B r_number
.It Fa r_number
The rpc program number for this service.
.PD
.RE
.LP
.B getrpcent(\|)
reads the next line of the file, opening the file if necessary.
.LP
.B getrpcent(\|)
opens and rewinds the file. If the
.I stayopen
.El
.Pp
The
.Fn getrpcent
function reads the next line of the file, opening the file if necessary.
The
.Nm getrpcent
function opens and rewinds the file. If the
.Fa stayopen
flag is non-zero,
the net data base will not be closed after each call to
.B getrpcent(\|)
.Fn getrpcent
(either directly, or indirectly through one of
the other \*(lqgetrpc\*(rq calls).
.LP
.B endrpcent
the other
.Fn getrpcent
function family.
.Pp
.Fn endrpcent
closes the file.
.LP
.B getrpcbyname(\|)
.Pp
.Fn getrpcbyname
and
.B getrpcbynumber(\|)
.Fn getrpcbynumber
sequentially search from the beginning
of the file until a matching rpc program name or
program number is found, or until end-of-file is encountered.
.SH FILES
.PD 0
.TP 20
.B /etc/rpc
.PD
.SH "SEE ALSO"
.BR rpc (5),
.BR rpcinfo (8C),
.BR ypserv (8)
.SH DIAGNOSTICS
.LP
.Sh FILES
.Bl -tag -width /etc/rpc -compact
.It Pa /etc/rpc
.El
.Sh "SEE ALSO"
.Xr rpc 5 ,
.Xr rpcinfo 8 ,
.Xr ypserv 8
.Sh DIAGNOSTICS
A
.SM NULL
.Dv NULL
pointer is returned on
.SM EOF
.Dv EOF
or error.
.SH BUGS
.LP
.Sh BUGS
All information
is contained in a static area
so it must be copied if it is

View File

@ -30,7 +30,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro";*/
static char *rcsid = "$Id: getrpcent.c,v 1.1 1993/10/27 05:40:29 paul Exp $";
static char *rcsid = "$Id: getrpcent.c,v 1.6 1996/12/30 14:42:31 peter Exp $";
#endif
/*
@ -38,6 +38,7 @@ static char *rcsid = "$Id: getrpcent.c,v 1.1 1993/10/27 05:40:29 paul Exp $";
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <rpc/rpc.h>
@ -65,6 +66,7 @@ struct rpcdata {
#ifdef YP
static int __yp_nomap = 0;
extern int _yp_check(char **);
#endif /* YP */
static struct rpcent *interpret();
@ -122,7 +124,7 @@ getrpcbynumber(number)
no_yp:
#endif /* YP */
setrpcent(0);
while (p = getrpcent()) {
while ((p = getrpcent())) {
if (p->r_number == number)
break;
}
@ -134,20 +136,21 @@ struct rpcent *
getrpcbyname(name)
char *name;
{
struct rpcent *rpc;
struct rpcent *rpc = NULL;
char **rp;
setrpcent(0);
while (rpc = getrpcent()) {
while ((rpc = getrpcent())) {
if (strcmp(rpc->r_name, name) == 0)
return (rpc);
goto done;
for (rp = rpc->r_aliases; *rp != NULL; rp++) {
if (strcmp(*rp, name) == 0)
return (rpc);
goto done;
}
}
done:
endrpcent();
return (NULL);
return (rpc);
}
void
@ -201,12 +204,12 @@ endrpcent()
struct rpcent *
getrpcent()
{
struct rpcent *hp;
int reason;
register struct rpcdata *d = _rpcdata();
#ifdef YP
char *key = NULL, *val = NULL;
int keylen, vallen;
struct rpcent *hp;
int reason;
char *val = NULL;
int vallen;
#endif
if (d == 0)
@ -243,7 +246,8 @@ no_yp:
#endif /* YP */
if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL)
return (NULL);
if (fgets(d->line, BUFSIZ, d->rpcf) == NULL)
/* -1 so there is room to append a \n below */
if (fgets(d->line, BUFSIZ - 1, d->rpcf) == NULL)
return (NULL);
return (interpret(d->line, strlen(d->line)));
}
@ -259,9 +263,10 @@ interpret(val, len)
if (d == 0)
return (0);
(void) strncpy(d->line, val, len);
(void) strncpy(d->line, val, BUFSIZ);
d->line[BUFSIZ] = '\0';
p = d->line;
d->line[len] = '\n';
p[len] = '\n';
if (*p == '#')
return (getrpcent());
cp = strpbrk(p, "#\n");
@ -279,7 +284,7 @@ interpret(val, len)
d->rpc.r_number = atoi(cp);
q = d->rpc.r_aliases = d->rpc_aliases;
cp = strpbrk(cp, " \t");
if (cp != NULL)
if (cp != NULL)
*cp++ = '\0';
while (cp && *cp) {
if (*cp == ' ' || *cp == '\t') {

View File

@ -1,31 +1,29 @@
.\" @(#)getrpcport.3r 2.2 88/08/02 4.0 RPCSRC; from 1.12 88/02/26 SMI
.TH GETRPCPORT 3R "6 October 1987"
.SH NAME
getrpcport \- get RPC port number
.SH SYNOPSIS
.ft B
.nf
int getrpcport(host, prognum, versnum, proto)
char *host;
int prognum, versnum, proto;
.fi
.SH DESCRIPTION
.IX getrpcport "" "\fLgetrpcport\fR \(em get RPC port number"
.B getrpcport(\|)
.Dd "October 6, 1987"
.Dt GETRPCPORT 3
.Os
.Sh NAME
.Nm getrpcport
.Nd get RPC port number
.Sh SYNOPSIS
.Ft int
.Fn getrpcport "char *host" "int prognum" "int versnum" "int proto"
.Sh DESCRIPTION
.Fn getrpcport
returns the port number for version
.I versnum
.Fa versnum
of the RPC program
.I prognum
.Fa prognum
running on
.I host
.Fa host
and using protocol
.IR proto .
.Fa proto .
It returns 0 if it cannot contact the portmapper, or if
.I prognum
.Fa prognum
is not registered. If
.I prognum
.Fa prognum
is registered but not with version
.IR versnum ,
.Fa versnum ,
it will still return a port number (for some version of the program)
indicating that the program is indeed registered.
The version mismatch will be detected upon the first call to the service.

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,7 +30,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)getrpcport.c 1.3 87/08/11 SMI";*/
/*static char *sccsid = "from: @(#)getrpcport.c 2.1 88/07/29 4.0 RPCSRC";*/
static char *rcsid = "$Id: getrpcport.c,v 1.1 1993/10/27 05:40:31 paul Exp $";
static char *rcsid = "$Id: getrpcport.c,v 1.6 1996/12/30 14:43:42 peter Exp $";
#endif
/*
@ -38,20 +38,26 @@ static char *rcsid = "$Id: getrpcport.c,v 1.1 1993/10/27 05:40:31 paul Exp $";
*/
#include <stdio.h>
#include <string.h>
#include <rpc/rpc.h>
#include <rpc/pmap_clnt.h>
#include <netdb.h>
#include <sys/socket.h>
int
getrpcport(host, prognum, versnum, proto)
char *host;
int prognum, versnum, proto;
{
struct sockaddr_in addr;
struct hostent *hp;
if ((hp = gethostbyname(host)) == NULL)
return (0);
bcopy(hp->h_addr, (char *) &addr.sin_addr, hp->h_length);
memset(&addr, 0, sizeof(addr));
addr.sin_len = sizeof(struct sockaddr_in);
addr.sin_family = AF_INET;
addr.sin_port = 0;
memcpy((char *)&addr.sin_addr, hp->h_addr, hp->h_length);
return (pmap_getport(&addr, prognum, versnum, proto));
}

425
lib/libc/rpc/key_call.c Normal file
View File

@ -0,0 +1,425 @@
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1986-1991 by Sun Microsystems Inc.
*/
#ident "@(#)key_call.c 1.25 94/04/24 SMI"
/*
* key_call.c, Interface to keyserver
*
* setsecretkey(key) - set your secret key
* encryptsessionkey(agent, deskey) - encrypt a session key to talk to agent
* decryptsessionkey(agent, deskey) - decrypt ditto
* gendeskey(deskey) - generate a secure des key
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <rpc/rpc.h>
#include <rpc/auth.h>
#include <rpc/auth_unix.h>
#include <rpc/key_prot.h>
#include <string.h>
#include <sys/utsname.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/fcntl.h>
#define KEY_TIMEOUT 5 /* per-try timeout in seconds */
#define KEY_NRETRY 12 /* number of retries */
#ifdef DEBUG
#define debug(msg) (void) fprintf(stderr, "%s\n", msg);
#else
#define debug(msg)
#endif /* DEBUG */
/*
* Hack to allow the keyserver to use AUTH_DES (for authenticated
* NIS+ calls, for example). The only functions that get called
* are key_encryptsession_pk, key_decryptsession_pk, and key_gendes.
*
* The approach is to have the keyserver fill in pointers to local
* implementations of these functions, and to call those in key_call().
*/
cryptkeyres *(*__key_encryptsession_pk_LOCAL)() = 0;
cryptkeyres *(*__key_decryptsession_pk_LOCAL)() = 0;
des_block *(*__key_gendes_LOCAL)() = 0;
static int key_call __P(( u_long, xdrproc_t, char *, xdrproc_t, char * ));
int
key_setsecret(secretkey)
const char *secretkey;
{
keystatus status;
if (!key_call((u_long) KEY_SET, xdr_keybuf, (char *) secretkey,
xdr_keystatus, (char *)&status)) {
return (-1);
}
if (status != KEY_SUCCESS) {
debug("set status is nonzero");
return (-1);
}
return (0);
}
/* key_secretkey_is_set() returns 1 if the keyserver has a secret key
* stored for the caller's effective uid; it returns 0 otherwise
*
* N.B.: The KEY_NET_GET key call is undocumented. Applications shouldn't
* be using it, because it allows them to get the user's secret key.
*/
int
key_secretkey_is_set(void)
{
struct key_netstres kres;
memset((void*)&kres, 0, sizeof (kres));
if (key_call((u_long) KEY_NET_GET, xdr_void, (char *)NULL,
xdr_key_netstres, (char *) &kres) &&
(kres.status == KEY_SUCCESS) &&
(kres.key_netstres_u.knet.st_priv_key[0] != 0)) {
/* avoid leaving secret key in memory */
memset(kres.key_netstres_u.knet.st_priv_key, 0, HEXKEYBYTES);
return (1);
}
return (0);
}
int
key_encryptsession_pk(remotename, remotekey, deskey)
char *remotename;
netobj *remotekey;
des_block *deskey;
{
cryptkeyarg2 arg;
cryptkeyres res;
arg.remotename = remotename;
arg.remotekey = *remotekey;
arg.deskey = *deskey;
if (!key_call((u_long)KEY_ENCRYPT_PK, xdr_cryptkeyarg2, (char *)&arg,
xdr_cryptkeyres, (char *)&res)) {
return (-1);
}
if (res.status != KEY_SUCCESS) {
debug("encrypt status is nonzero");
return (-1);
}
*deskey = res.cryptkeyres_u.deskey;
return (0);
}
int
key_decryptsession_pk(remotename, remotekey, deskey)
char *remotename;
netobj *remotekey;
des_block *deskey;
{
cryptkeyarg2 arg;
cryptkeyres res;
arg.remotename = remotename;
arg.remotekey = *remotekey;
arg.deskey = *deskey;
if (!key_call((u_long)KEY_DECRYPT_PK, xdr_cryptkeyarg2, (char *)&arg,
xdr_cryptkeyres, (char *)&res)) {
return (-1);
}
if (res.status != KEY_SUCCESS) {
debug("decrypt status is nonzero");
return (-1);
}
*deskey = res.cryptkeyres_u.deskey;
return (0);
}
int
key_encryptsession(remotename, deskey)
const char *remotename;
des_block *deskey;
{
cryptkeyarg arg;
cryptkeyres res;
arg.remotename = (char *) remotename;
arg.deskey = *deskey;
if (!key_call((u_long)KEY_ENCRYPT, xdr_cryptkeyarg, (char *)&arg,
xdr_cryptkeyres, (char *)&res)) {
return (-1);
}
if (res.status != KEY_SUCCESS) {
debug("encrypt status is nonzero");
return (-1);
}
*deskey = res.cryptkeyres_u.deskey;
return (0);
}
int
key_decryptsession(remotename, deskey)
const char *remotename;
des_block *deskey;
{
cryptkeyarg arg;
cryptkeyres res;
arg.remotename = (char *) remotename;
arg.deskey = *deskey;
if (!key_call((u_long)KEY_DECRYPT, xdr_cryptkeyarg, (char *)&arg,
xdr_cryptkeyres, (char *)&res)) {
return (-1);
}
if (res.status != KEY_SUCCESS) {
debug("decrypt status is nonzero");
return (-1);
}
*deskey = res.cryptkeyres_u.deskey;
return (0);
}
int
key_gendes(key)
des_block *key;
{
if (!key_call((u_long)KEY_GEN, xdr_void, (char *)NULL,
xdr_des_block, (char *)key)) {
return (-1);
}
return (0);
}
int
key_setnet(arg)
struct netstarg *arg;
{
keystatus status;
if (!key_call((u_long) KEY_NET_PUT, xdr_key_netstarg, (char *) arg,
xdr_keystatus, (char *) &status)){
return (-1);
}
if (status != KEY_SUCCESS) {
debug("key_setnet status is nonzero");
return (-1);
}
return (1);
}
int
key_get_conv(pkey, deskey)
char *pkey;
des_block *deskey;
{
cryptkeyres res;
if (!key_call((u_long) KEY_GET_CONV, xdr_keybuf, pkey,
xdr_cryptkeyres, (char *)&res)) {
return (-1);
}
if (res.status != KEY_SUCCESS) {
debug("get_conv status is nonzero");
return (-1);
}
*deskey = res.cryptkeyres_u.deskey;
return (0);
}
struct key_call_private {
CLIENT *client; /* Client handle */
pid_t pid; /* process-id at moment of creation */
uid_t uid; /* user-id at last authorization */
};
static struct key_call_private *key_call_private_main = NULL;
#ifdef foo
static void
key_call_destroy(void *vp)
{
register struct key_call_private *kcp = (struct key_call_private *)vp;
if (kcp) {
if (kcp->client)
clnt_destroy(kcp->client);
free(kcp);
}
}
#endif
/*
* Keep the handle cached. This call may be made quite often.
*/
static CLIENT *
getkeyserv_handle(vers)
int vers;
{
struct key_call_private *kcp = key_call_private_main;
struct timeval wait_time;
int fd;
struct sockaddr_un name;
int namelen = sizeof(struct sockaddr_un);
#define TOTAL_TIMEOUT 30 /* total timeout talking to keyserver */
#define TOTAL_TRIES 5 /* Number of tries */
if (kcp == (struct key_call_private *)NULL) {
kcp = (struct key_call_private *)malloc(sizeof (*kcp));
if (kcp == (struct key_call_private *)NULL) {
return ((CLIENT *) NULL);
}
key_call_private_main = kcp;
kcp->client = NULL;
}
/* if pid has changed, destroy client and rebuild */
if (kcp->client != NULL && kcp->pid != getpid()) {
clnt_destroy(kcp->client);
kcp->client = NULL;
}
if (kcp->client != NULL) {
/* if other side closed socket, build handle again */
clnt_control(kcp->client, CLGET_FD, (char *)&fd);
if (getpeername(fd,(struct sockaddr *)&name,&namelen) == -1) {
auth_destroy(kcp->client->cl_auth);
clnt_destroy(kcp->client);
kcp->client = NULL;
}
}
if (kcp->client != NULL) {
/* if uid has changed, build client handle again */
if (kcp->uid != geteuid()) {
kcp->uid = geteuid();
auth_destroy(kcp->client->cl_auth);
kcp->client->cl_auth =
authsys_create("", kcp->uid, 0, 0, NULL);
if (kcp->client->cl_auth == NULL) {
clnt_destroy(kcp->client);
kcp->client = NULL;
return ((CLIENT *) NULL);
}
}
/* Change the version number to the new one */
clnt_control(kcp->client, CLSET_VERS, (void *)&vers);
return (kcp->client);
}
if ((kcp->client == (CLIENT *) NULL))
/* Use the AF_UNIX transport */
kcp->client = clnt_create("/var/run/keyservsock", KEY_PROG,
vers, "unix");
if (kcp->client == (CLIENT *) NULL) {
return ((CLIENT *) NULL);
}
kcp->uid = geteuid();
kcp->pid = getpid();
kcp->client->cl_auth = authsys_create("", kcp->uid, 0, 0, NULL);
if (kcp->client->cl_auth == NULL) {
clnt_destroy(kcp->client);
kcp->client = NULL;
return ((CLIENT *) NULL);
}
wait_time.tv_sec = TOTAL_TIMEOUT/TOTAL_TRIES;
wait_time.tv_usec = 0;
(void) clnt_control(kcp->client, CLSET_RETRY_TIMEOUT,
(char *)&wait_time);
if (clnt_control(kcp->client, CLGET_FD, (char *)&fd))
fcntl(fd, F_SETFD, 1); /* make it "close on exec" */
return (kcp->client);
}
/* returns 0 on failure, 1 on success */
static int
key_call(proc, xdr_arg, arg, xdr_rslt, rslt)
u_long proc;
xdrproc_t xdr_arg;
char *arg;
xdrproc_t xdr_rslt;
char *rslt;
{
CLIENT *clnt;
struct timeval wait_time;
if (proc == KEY_ENCRYPT_PK && __key_encryptsession_pk_LOCAL) {
cryptkeyres *res;
res = (*__key_encryptsession_pk_LOCAL)(geteuid(), arg);
*(cryptkeyres*)rslt = *res;
return (1);
} else if (proc == KEY_DECRYPT_PK && __key_decryptsession_pk_LOCAL) {
cryptkeyres *res;
res = (*__key_decryptsession_pk_LOCAL)(geteuid(), arg);
*(cryptkeyres*)rslt = *res;
return (1);
} else if (proc == KEY_GEN && __key_gendes_LOCAL) {
des_block *res;
res = (*__key_gendes_LOCAL)(geteuid(), 0);
*(des_block*)rslt = *res;
return (1);
}
if ((proc == KEY_ENCRYPT_PK) || (proc == KEY_DECRYPT_PK) ||
(proc == KEY_NET_GET) || (proc == KEY_NET_PUT) ||
(proc == KEY_GET_CONV))
clnt = getkeyserv_handle(2); /* talk to version 2 */
else
clnt = getkeyserv_handle(1); /* talk to version 1 */
if (clnt == NULL) {
return (0);
}
wait_time.tv_sec = TOTAL_TIMEOUT;
wait_time.tv_usec = 0;
if (clnt_call(clnt, proc, xdr_arg, arg, xdr_rslt, rslt,
wait_time) == RPC_SUCCESS) {
return (1);
} else {
return (0);
}
}

166
lib/libc/rpc/key_prot_xdr.c Normal file
View File

@ -0,0 +1,166 @@
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
#include <rpc/key_prot.h>
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
#pragma ident "@(#)key_prot.x 1.7 94/04/29 SMI"
/* Copyright (c) 1990, 1991 Sun Microsystems, Inc. */
/*
* Compiled from key_prot.x using rpcgen.
* DO NOT EDIT THIS FILE!
* This is NOT source code!
*/
bool_t
xdr_keystatus(register XDR *xdrs, keystatus *objp)
{
if (!xdr_enum(xdrs, (enum_t *)objp))
return (FALSE);
return (TRUE);
}
bool_t
xdr_keybuf(register XDR *xdrs, keybuf objp)
{
if (!xdr_opaque(xdrs, objp, HEXKEYBYTES))
return (FALSE);
return (TRUE);
}
bool_t
xdr_netnamestr(register XDR *xdrs, netnamestr *objp)
{
if (!xdr_string(xdrs, objp, MAXNETNAMELEN))
return (FALSE);
return (TRUE);
}
bool_t
xdr_cryptkeyarg(register XDR *xdrs, cryptkeyarg *objp)
{
if (!xdr_netnamestr(xdrs, &objp->remotename))
return (FALSE);
if (!xdr_des_block(xdrs, &objp->deskey))
return (FALSE);
return (TRUE);
}
bool_t
xdr_cryptkeyarg2(register XDR *xdrs, cryptkeyarg2 *objp)
{
if (!xdr_netnamestr(xdrs, &objp->remotename))
return (FALSE);
if (!xdr_netobj(xdrs, &objp->remotekey))
return (FALSE);
if (!xdr_des_block(xdrs, &objp->deskey))
return (FALSE);
return (TRUE);
}
bool_t
xdr_cryptkeyres(register XDR *xdrs, cryptkeyres *objp)
{
if (!xdr_keystatus(xdrs, &objp->status))
return (FALSE);
switch (objp->status) {
case KEY_SUCCESS:
if (!xdr_des_block(xdrs, &objp->cryptkeyres_u.deskey))
return (FALSE);
break;
}
return (TRUE);
}
bool_t
xdr_unixcred(register XDR *xdrs, unixcred *objp)
{
if (!xdr_u_int(xdrs, &objp->uid))
return (FALSE);
if (!xdr_u_int(xdrs, &objp->gid))
return (FALSE);
if (!xdr_array(xdrs, (char **)&objp->gids.gids_val, (u_int *) &objp->gids.gids_len, MAXGIDS,
sizeof (u_int), (xdrproc_t) xdr_u_int))
return (FALSE);
return (TRUE);
}
bool_t
xdr_getcredres(register XDR *xdrs, getcredres *objp)
{
if (!xdr_keystatus(xdrs, &objp->status))
return (FALSE);
switch (objp->status) {
case KEY_SUCCESS:
if (!xdr_unixcred(xdrs, &objp->getcredres_u.cred))
return (FALSE);
break;
}
return (TRUE);
}
bool_t
xdr_key_netstarg(register XDR *xdrs, key_netstarg *objp)
{
if (!xdr_keybuf(xdrs, objp->st_priv_key))
return (FALSE);
if (!xdr_keybuf(xdrs, objp->st_pub_key))
return (FALSE);
if (!xdr_netnamestr(xdrs, &objp->st_netname))
return (FALSE);
return (TRUE);
}
bool_t
xdr_key_netstres(register XDR *xdrs, key_netstres *objp)
{
if (!xdr_keystatus(xdrs, &objp->status))
return (FALSE);
switch (objp->status) {
case KEY_SUCCESS:
if (!xdr_key_netstarg(xdrs, &objp->key_netstres_u.knet))
return (FALSE);
break;
}
return (TRUE);
}

136
lib/libc/rpc/netname.c Normal file
View File

@ -0,0 +1,136 @@
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user or with the express written consent of
* Sun Microsystems, Inc.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
#if !defined(lint) && defined(SCCSIDS)
static char sccsid[] = "@(#)netname.c 1.8 91/03/11 Copyr 1986 Sun Micro";
#endif
/*
* netname utility routines
* convert from unix names to network names and vice-versa
* This module is operating system dependent!
* What we define here will work with any unix system that has adopted
* the sun NIS domain architecture.
*/
#include <sys/param.h>
#include <rpc/rpc.h>
#include <rpc/rpc_com.h>
#ifdef YP
#include <rpcsvc/yp_prot.h>
#include <rpcsvc/ypclnt.h>
#endif
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 256
#endif
#ifndef NGROUPS
#define NGROUPS 16
#endif
static char *OPSYS = "unix";
/*
* Figure out my fully qualified network name
*/
int
getnetname(name)
char name[MAXNETNAMELEN+1];
{
uid_t uid;
uid = geteuid();
if (uid == 0) {
return (host2netname(name, (char *) NULL, (char *) NULL));
} else {
return (user2netname(name, uid, (char *) NULL));
}
}
/*
* Convert unix cred to network-name
*/
int
user2netname(netname, uid, domain)
char netname[MAXNETNAMELEN + 1];
uid_t uid;
char *domain;
{
char *dfltdom;
#define MAXIPRINT (11) /* max length of printed integer */
if (domain == NULL) {
if (_rpc_get_default_domain(&dfltdom) != 0) {
return (0);
}
domain = dfltdom;
}
if (strlen(domain) + 1 + MAXIPRINT > MAXNETNAMELEN) {
return (0);
}
(void) sprintf(netname, "%s.%ld@%s", OPSYS, uid, domain);
return (1);
}
/*
* Convert host to network-name
*/
int
host2netname(netname, host, domain)
char netname[MAXNETNAMELEN + 1];
char *host;
char *domain;
{
char *dfltdom;
char hostname[MAXHOSTNAMELEN+1];
if (domain == NULL) {
if (_rpc_get_default_domain(&dfltdom) != 0) {
return (0);
}
domain = dfltdom;
}
if (host == NULL) {
(void) gethostname(hostname, sizeof(hostname));
host = hostname;
}
if (strlen(domain) + 1 + strlen(host) > MAXNETNAMELEN) {
return (0);
}
(void) sprintf(netname, "%s.%s@%s", OPSYS, host, domain);
return (1);
}

326
lib/libc/rpc/netnamer.c Normal file
View File

@ -0,0 +1,326 @@
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user or with the express written consent of
* Sun Microsystems, Inc.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
#if !defined(lint) && defined(SCCSIDS)
static char sccsid[] = "@(#)netnamer.c 1.13 91/03/11 Copyr 1986 Sun Micro";
#endif
/*
* netname utility routines convert from unix names to network names and
* vice-versa This module is operating system dependent! What we define here
* will work with any unix system that has adopted the sun NIS domain
* architecture.
*/
#include <sys/param.h>
#include <rpc/rpc.h>
#include <rpc/rpc_com.h>
#ifdef YP
#include <rpcsvc/yp_prot.h>
#include <rpcsvc/ypclnt.h>
#endif
#include <ctype.h>
#include <stdio.h>
#include <grp.h>
#include <pwd.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
static char *OPSYS = "unix";
static char *NETID = "netid.byname";
static char *NETIDFILE = "/etc/netid";
static int getnetid __P(( char *, char * ));
static int _getgroups __P(( char *, gid_t * ));
#ifndef NGROUPS
#define NGROUPS 16
#endif
/*
* Convert network-name into unix credential
*/
int
netname2user(netname, uidp, gidp, gidlenp, gidlist)
char netname[MAXNETNAMELEN + 1];
uid_t *uidp;
gid_t *gidp;
int *gidlenp;
gid_t *gidlist;
{
char *p;
int gidlen;
uid_t uid;
struct passwd *pwd;
char val[1024];
char *val1, *val2;
char *domain;
int vallen;
int err;
if (getnetid(netname, val)) {
p = strtok(val, ":");
if (p == NULL)
return (0);
*uidp = (uid_t) atol(val);
p = strtok(NULL, "\n,");
*gidp = (gid_t) atol(p);
if (p == NULL) {
return (0);
}
gidlen = 0;
for (gidlen = 0; gidlen < NGROUPS; gidlen++) {
p = strtok(NULL, "\n,");
if (p == NULL)
break;
gidlist[gidlen] = (gid_t) atol(p);
}
*gidlenp = gidlen;
return (1);
}
val1 = strchr(netname, '.');
if (val1 == NULL)
return (0);
if (strncmp(netname, OPSYS, (val1-netname)))
return (0);
val1++;
val2 = strchr(val1, '@');
if (val2 == NULL)
return (0);
vallen = val2 - val1;
if (vallen > (1024 - 1))
vallen = 1024 - 1;
(void) strncpy(val, val1, 1024);
val[vallen] = 0;
err = _rpc_get_default_domain(&domain); /* change to rpc */
if (err)
return (0);
if (strcmp(val2 + 1, domain))
return (0); /* wrong domain */
/* XXX: uid_t have different sizes on different OS's. sigh! */
if (sizeof (uid_t) == sizeof (short)) {
if (sscanf(val, "%hd", (short *)&uid) != 1)
return (0);
} else {
if (sscanf(val, "%ld", &uid) != 1)
return (0);
}
/* use initgroups method */
pwd = getpwuid(uid);
if (pwd == NULL)
return (0);
*uidp = pwd->pw_uid;
*gidp = pwd->pw_gid;
*gidlenp = _getgroups(pwd->pw_name, gidlist);
return (1);
}
/*
* initgroups
*/
static int
_getgroups(uname, groups)
char *uname;
gid_t groups[NGROUPS];
{
gid_t ngroups = 0;
register struct group *grp;
register int i;
register int j;
int filter;
setgrent();
while ((grp = getgrent())) {
for (i = 0; grp->gr_mem[i]; i++)
if (!strcmp(grp->gr_mem[i], uname)) {
if (ngroups == NGROUPS) {
#ifdef DEBUG
fprintf(stderr,
"initgroups: %s is in too many groups\n", uname);
#endif
goto toomany;
}
/* filter out duplicate group entries */
filter = 0;
for (j = 0; j < ngroups; j++)
if (groups[j] == grp->gr_gid) {
filter++;
break;
}
if (!filter)
groups[ngroups++] = grp->gr_gid;
}
}
toomany:
endgrent();
return (ngroups);
}
/*
* Convert network-name to hostname
*/
int
netname2host(netname, hostname, hostlen)
char netname[MAXNETNAMELEN + 1];
char *hostname;
int hostlen;
{
int err;
char valbuf[1024];
char *val;
char *val2;
int vallen;
char *domain;
if (getnetid(netname, valbuf)) {
val = valbuf;
if ((*val == '0') && (val[1] == ':')) {
(void) strncpy(hostname, val + 2, hostlen);
return (1);
}
}
val = strchr(netname, '.');
if (val == NULL)
return (0);
if (strncmp(netname, OPSYS, (val - netname)))
return (0);
val++;
val2 = strchr(val, '@');
if (val2 == NULL)
return (0);
vallen = val2 - val;
if (vallen > (hostlen - 1))
vallen = hostlen - 1;
(void) strncpy(hostname, val, vallen);
hostname[vallen] = 0;
err = _rpc_get_default_domain(&domain); /* change to rpc */
if (err)
return (0);
if (strcmp(val2 + 1, domain))
return (0); /* wrong domain */
else
return (1);
}
/*
* reads the file /etc/netid looking for a + to optionally go to the
* network information service.
*/
int
getnetid(key, ret)
char *key, *ret;
{
char buf[1024]; /* big enough */
char *res;
char *mkey;
char *mval;
FILE *fd;
#ifdef YP
char *domain;
int err;
char *lookup;
int len;
#endif
fd = fopen(NETIDFILE, "r");
if (fd == (FILE *) 0) {
#ifdef YP
res = "+";
goto getnetidyp;
#else
return (0);
#endif
}
for (;;) {
if (fd == (FILE *) 0)
return (0); /* getnetidyp brings us here */
res = fgets(buf, 1024, fd);
if (res == 0) {
fclose(fd);
return (0);
}
if (res[0] == '#')
continue;
else if (res[0] == '+') {
#ifdef YP
getnetidyp:
err = yp_get_default_domain(&domain);
if (err) {
continue;
}
lookup = NULL;
err = yp_match(domain, NETID, key,
strlen(key), &lookup, &len);
if (err) {
#ifdef DEBUG
fprintf(stderr, "match failed error %d\n", err);
#endif
continue;
}
lookup[len] = 0;
strcpy(ret, lookup);
free(lookup);
fclose(fd);
return (2);
#else /* YP */
#ifdef DEBUG
fprintf(stderr,
"Bad record in %s '+' -- NIS not supported in this library copy\n",
NETIDFILE);
#endif
continue;
#endif /* YP */
} else {
mkey = strtok(buf, "\t ");
if (mkey == NULL) {
fprintf(stderr,
"Bad record in %s -- %s", NETIDFILE, buf);
continue;
}
mval = strtok(NULL, " \t#\n");
if (mval == NULL) {
fprintf(stderr,
"Bad record in %s val problem - %s", NETIDFILE, buf);
continue;
}
if (strcmp(mkey, key) == 0) {
strcpy(ret, mval);
fclose(fd);
return (1);
}
}
}
}

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,7 +30,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)pmap_clnt.c 2.2 88/08/01 4.0 RPCSRC";*/
static char *rcsid = "$Id: pmap_clnt.c,v 1.1 1993/10/27 05:40:32 paul Exp $";
static char *rcsid = "$Id: pmap_clnt.c,v 1.5 1996/12/30 14:46:33 peter Exp $";
#endif
/*
@ -40,15 +40,22 @@ static char *rcsid = "$Id: pmap_clnt.c,v 1.1 1993/10/27 05:40:32 paul Exp $";
* Copyright (C) 1984, Sun Microsystems, Inc.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <rpc/rpc.h>
#include <rpc/pmap_prot.h>
#include <rpc/pmap_clnt.h>
#include <netinet/in.h>
static struct timeval timeout = { 5, 0 };
static struct timeval tottimeout = { 60, 0 };
void clnt_perror();
#ifndef PORTMAPSOCK
#define PORTMAPSOCK "/var/run/portmapsock"
#endif
/*
* Set a mapping between program,version and port.
@ -66,10 +73,22 @@ pmap_set(program, version, protocol, port)
register CLIENT *client;
struct pmap parms;
bool_t rslt;
struct stat st;
/*
* Temporary hack for backwards compatibility. Eventually
* this test will go away and we'll use only the "unix" transport.
*/
if (stat(PORTMAPSOCK, &st) == 0 && st.st_mode & S_IFSOCK)
client = clnt_create(PORTMAPSOCK, PMAPPROG, PMAPVERS, "unix");
else {
if (get_myaddress(&myaddress) != 0)
return (FALSE);
myaddress.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
}
get_myaddress(&myaddress);
client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
if (client == (CLIENT *)NULL)
return (FALSE);
parms.pm_prog = program;
@ -82,7 +101,8 @@ pmap_set(program, version, protocol, port)
return (FALSE);
}
CLNT_DESTROY(client);
(void)close(socket);
if (socket != -1)
(void)close(socket);
return (rslt);
}
@ -100,10 +120,21 @@ pmap_unset(program, version)
register CLIENT *client;
struct pmap parms;
bool_t rslt;
struct stat st;
get_myaddress(&myaddress);
client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
/*
* Temporary hack for backwards compatibility. Eventually
* this test will go away and we'll use only the "unix" transport.
*/
if (stat(PORTMAPSOCK, &st) == 0 && st.st_mode & S_IFSOCK)
client = clnt_create(PORTMAPSOCK, PMAPPROG, PMAPVERS, "unix");
else {
if (get_myaddress(&myaddress) != 0)
return (FALSE);
myaddress.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
}
if (client == (CLIENT *)NULL)
return (FALSE);
parms.pm_prog = program;
@ -112,6 +143,7 @@ pmap_unset(program, version)
CLNT_CALL(client, PMAPPROC_UNSET, xdr_pmap, &parms, xdr_bool, &rslt,
tottimeout);
CLNT_DESTROY(client);
(void)close(socket);
if (socket != -1)
(void)close(socket);
return (rslt);
}

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,7 +30,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)pmap_getmaps.c 2.2 88/08/01 4.0 RPCSRC";*/
static char *rcsid = "$Id: pmap_getmaps.c,v 1.1 1993/10/27 05:40:35 paul Exp $";
static char *rcsid = "$Id: pmap_getmaps.c,v 1.5 1996/12/30 14:48:28 peter Exp $";
#endif
/*
@ -47,14 +47,13 @@ static char *rcsid = "$Id: pmap_getmaps.c,v 1.1 1993/10/27 05:40:35 paul Exp $";
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <net/if.h>
#include <sys/ioctl.h>
#define NAMELEN 255
#define MAX_BROADCAST_SIZE 1400
extern int errno;
/*
* Get a copy of the current port maps.
* Calls the pmap service remotely to do get the maps.
@ -80,7 +79,8 @@ pmap_getmaps(address)
}
CLNT_DESTROY(client);
}
(void)close(socket);
if (socket != -1)
(void)close(socket);
address->sin_port = 0;
return (head);
}

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,7 +30,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)pmap_getport.c 2.2 88/08/01 4.0 RPCSRC";*/
static char *rcsid = "$Id: pmap_getport.c,v 1.1 1993/10/27 05:40:36 paul Exp $";
static char *rcsid = "$Id: pmap_getport.c,v 1.4 1996/12/30 14:49:24 peter Exp $";
#endif
/*
@ -45,6 +45,7 @@ static char *rcsid = "$Id: pmap_getport.c,v 1.1 1993/10/27 05:40:36 paul Exp $";
#include <rpc/pmap_clnt.h>
#include <sys/socket.h>
#include <net/if.h>
#include <unistd.h>
static struct timeval timeout = { 5, 0 };
static struct timeval tottimeout = { 60, 0 };
@ -83,7 +84,8 @@ pmap_getport(address, program, version, protocol)
}
CLNT_DESTROY(client);
}
(void)close(socket);
if (socket != -1)
(void)close(socket);
address->sin_port = 0;
return (port);
}

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,7 +30,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)pmap_prot.c 2.1 88/07/29 4.0 RPCSRC";*/
static char *rcsid = "$Id: pmap_prot.c,v 1.1 1993/10/27 05:40:37 paul Exp $";
static char *rcsid = "$Id: pmap_prot.c,v 1.2 1995/05/30 05:41:25 rgrimes Exp $";
#endif
/*
@ -51,8 +51,8 @@ xdr_pmap(xdrs, regs)
struct pmap *regs;
{
if (xdr_u_long(xdrs, &regs->pm_prog) &&
xdr_u_long(xdrs, &regs->pm_vers) &&
if (xdr_u_long(xdrs, &regs->pm_prog) &&
xdr_u_long(xdrs, &regs->pm_vers) &&
xdr_u_long(xdrs, &regs->pm_prot))
return (xdr_u_long(xdrs, &regs->pm_port));
return (FALSE);

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,7 +30,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)pmap_prot2.c 2.1 88/07/29 4.0 RPCSRC";*/
static char *rcsid = "$Id: pmap_prot2.c,v 1.1 1993/10/27 05:40:39 paul Exp $";
static char *rcsid = "$Id: pmap_prot2.c,v 1.3 1996/06/10 20:13:05 jraynard Exp $";
#endif
/*
@ -45,7 +45,7 @@ static char *rcsid = "$Id: pmap_prot2.c,v 1.1 1993/10/27 05:40:39 paul Exp $";
#include <rpc/pmap_prot.h>
/*
/*
* What is going on with linked lists? (!)
* First recall the link list declaration from pmap_prot.h:
*
@ -54,11 +54,11 @@ static char *rcsid = "$Id: pmap_prot2.c,v 1.1 1993/10/27 05:40:39 paul Exp $";
* struct pmaplist *pml_map;
* };
*
* Compare that declaration with a corresponding xdr declaration that
* Compare that declaration with a corresponding xdr declaration that
* is (a) pointer-less, and (b) recursive:
*
* typedef union switch (bool_t) {
*
*
* case TRUE: struct {
* struct pmap;
* pmaplist_t foo;
@ -71,8 +71,8 @@ static char *rcsid = "$Id: pmap_prot2.c,v 1.1 1993/10/27 05:40:39 paul Exp $";
* the C declaration has no bool_t variable. The bool_t can be
* interpreted as ``more data follows me''; if FALSE then nothing
* follows this bool_t; if TRUE then the bool_t is followed by
* an actual struct pmap, and then (recursively) by the
* xdr union, pamplist_t.
* an actual struct pmap, and then (recursively) by the
* xdr union, pamplist_t.
*
* This could be implemented via the xdr_union primitive, though this
* would cause a one recursive call per element in the list. Rather than do
@ -95,7 +95,7 @@ xdr_pmaplist(xdrs, rp)
*/
bool_t more_elements;
register int freeing = (xdrs->x_op == XDR_FREE);
register struct pmaplist **next;
register struct pmaplist **next = NULL;
while (TRUE) {
more_elements = (bool_t)(*rp != NULL);
@ -109,7 +109,7 @@ xdr_pmaplist(xdrs, rp)
* before we free the current object ...
*/
if (freeing)
next = &((*rp)->pml_next);
next = &((*rp)->pml_next);
if (! xdr_reference(xdrs, (caddr_t *)rp,
(u_int)sizeof(struct pmaplist), xdr_pmap))
return (FALSE);

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,7 +30,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)pmap_rmt.c 2.2 88/08/01 4.0 RPCSRC";*/
static char *rcsid = "$Id: pmap_rmt.c,v 1.1 1993/10/27 05:40:40 paul Exp $";
static char *rcsid = "$Id: pmap_rmt.c,v 1.9 1996/12/30 14:53:20 peter Exp $";
#endif
/*
@ -47,16 +47,17 @@ static char *rcsid = "$Id: pmap_rmt.c,v 1.1 1993/10/27 05:40:40 paul Exp $";
#include <rpc/pmap_rmt.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#define MAX_BROADCAST_SIZE 1400
extern int errno;
static struct timeval timeout = { 3, 0 };
/*
* pmapper remote-call-service interface.
* This routine is used to call the pmapper remote call service
@ -96,7 +97,8 @@ pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_pt
} else {
stat = RPC_FAILED;
}
(void)close(socket);
if (socket != -1)
(void)close(socket);
addr->sin_port = 0;
return (stat);
}
@ -156,7 +158,7 @@ xdr_rmtcallres(xdrs, crp)
/*
* The following is kludged-up support for simple rpc broadcasts.
* Someday a large, complicated system will replace these trivial
* Someday a large, complicated system will replace these trivial
* routines which only support udp/ip .
*/
@ -167,10 +169,11 @@ getbroadcastnets(addrs, sock, buf)
char *buf; /* why allocxate more when we can use existing... */
{
struct ifconf ifc;
struct ifreq ifreq, *ifr;
struct ifreq ifreq, *ifr;
struct sockaddr_in *sin;
char *cp, *cplim;
int n, i = 0;
struct in_addr addr;
char *cp, *cplim;
int n, i = 0;
ifc.ifc_len = UDPMSGSIZE;
ifc.ifc_buf = buf;
@ -196,17 +199,24 @@ getbroadcastnets(addrs, sock, buf)
sin = (struct sockaddr_in *)&ifr->ifr_addr;
#ifdef SIOCGIFBRDADDR /* 4.3BSD */
if (ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
addrs[i++] =
addr =
inet_makeaddr(inet_netof(sin->sin_addr),
INADDR_ANY);
} else {
addrs[i++] = ((struct sockaddr_in*)
addr = ((struct sockaddr_in*)
&ifreq.ifr_addr)->sin_addr;
}
#else /* 4.2 BSD */
addrs[i++] = inet_makeaddr(inet_netof(sin->sin_addr),
addr = inet_makeaddr(inet_netof(sin->sin_addr),
INADDR_ANY);
#endif
for (n=i-1; n>=0; n--) {
if (addr.s_addr == addrs[n].s_addr)
break;
}
if (n<0) {
addrs[i++] = addr;
}
}
}
return (i);
@ -214,7 +224,7 @@ getbroadcastnets(addrs, sock, buf)
typedef bool_t (*resultproc_t)();
enum clnt_stat
enum clnt_stat
clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
u_long prog; /* program number */
u_long vers; /* version number */
@ -232,13 +242,7 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
int outlen, inlen, fromlen, nets;
register int sock;
int on = 1;
#ifdef FD_SETSIZE
fd_set mask;
fd_set readfds;
#else
int readfds;
register int mask;
#endif /* def FD_SETSIZE */
fd_set *fds, readfds;
register int i;
bool_t done = FALSE;
register u_long xid;
@ -248,8 +252,12 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
struct rmtcallargs a;
struct rmtcallres r;
struct rpc_msg msg;
struct timeval t;
struct timeval t, tv;
char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE];
static u_int32_t disrupt;
if (disrupt == 0)
disrupt = (u_int32_t)(long)resultsp;
/*
* initialization: create a socket, a broadcast address, and
@ -267,20 +275,27 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
goto done_broad;
}
#endif /* def SO_BROADCAST */
#ifdef FD_SETSIZE
FD_ZERO(&mask);
FD_SET(sock, &mask);
#else
mask = (1 << sock);
#endif /* def FD_SETSIZE */
if (sock + 1 > FD_SETSIZE) {
int bytes = howmany(sock + 1, NFDBITS) * sizeof(fd_mask);
fds = (fd_set *)malloc(bytes);
if (fds == NULL) {
stat = RPC_CANTSEND;
goto done_broad;
}
memset(fds, 0, bytes);
} else {
fds = &readfds;
FD_ZERO(fds);
}
nets = getbroadcastnets(addrs, sock, inbuf);
bzero((char *)&baddr, sizeof (baddr));
memset(&baddr, 0, sizeof (baddr));
baddr.sin_len = sizeof(struct sockaddr_in);
baddr.sin_family = AF_INET;
baddr.sin_port = htons(PMAPPORT);
baddr.sin_addr.s_addr = htonl(INADDR_ANY);
/* baddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); */
(void)gettimeofday(&t, (struct timezone *)0);
msg.rm_xid = xid = getpid() ^ t.tv_sec ^ t.tv_usec;
msg.rm_xid = xid = (++disrupt) ^ getpid() ^ t.tv_sec ^ t.tv_usec;
t.tv_usec = 0;
msg.rm_direction = CALL;
msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
@ -307,6 +322,12 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
/*
* Basic loop: broadcast a packet and wait a while for response(s).
* The response timeout grows larger per iteration.
*
* XXX This will loop about 5 times the stop. If there are
* lots of signals being received by the process it will quit
* send them all in one quick burst, not paying attention to
* the intended function of sending them slowly over half a
* minute or so
*/
for (t.tv_sec = 4; t.tv_sec <= 14; t.tv_sec += 2) {
for (i = 0; i < nets; i++) {
@ -326,10 +347,11 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
recv_again:
msg.acpted_rply.ar_verf = _null_auth;
msg.acpted_rply.ar_results.where = (caddr_t)&r;
msg.acpted_rply.ar_results.proc = xdr_rmtcallres;
readfds = mask;
switch (select(_rpc_dtablesize(), &readfds, (int *)NULL,
(int *)NULL, &t)) {
msg.acpted_rply.ar_results.proc = xdr_rmtcallres;
/* XXX we know the other bits are still clear */
FD_SET(sock, fds);
tv = t; /* for select() that copies back */
switch (select(sock + 1, fds, NULL, NULL, &tv)) {
case 0: /* timed out */
stat = RPC_TIMEDOUT;
@ -354,7 +376,7 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
stat = RPC_CANTRECV;
goto done_broad;
}
if (inlen < sizeof(u_long))
if (inlen < sizeof(u_int32_t))
goto recv_again;
/*
* see if reply transaction id matches sent id.
@ -369,13 +391,6 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
done = (*eachresult)(resultsp, &raddr);
}
/* otherwise, we just ignore the errors ... */
} else {
#ifdef notdef
/* some kind of deserialization problem ... */
if (msg.rm_xid == xid)
fprintf(stderr, "Broadcast deserialization problem");
/* otherwise, just random garbage */
#endif
}
xdrs->x_op = XDR_FREE;
msg.acpted_rply.ar_results.proc = xdr_void;
@ -390,7 +405,10 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
}
}
done_broad:
(void)close(sock);
if (fds != &readfds)
free(fds);
if (sock >= 0)
(void)close(sock);
AUTH_DESTROY(unix_auth);
return (stat);
}

44
lib/libc/rpc/publickey.3 Normal file
View File

@ -0,0 +1,44 @@
.\" @(#)publickey.3r 2.1 88/08/07 4.0 RPCSRC
.TH PUBLICKEY 3R "6 October 1987"
.SH NAME
publickey, getpublickey, getsecretkey \- get public or secret key
.SH SYNOPSIS
.nf
.B #include <rpc/rpc.h>
.B #include <rpc/key_prot.h>
.LP
.B getpublickey(netname, publickey)
.B char netname[\s-1MAXNETNAMELEN\s0+1];
.B char publickey[\s-1HEXKEYBYTES\s0+1];
.LP
.B getsecretkey(netname, secretkey, passwd)
.B char netname[\s-1MAXNETNAMELEN\s0+1];
.B char secretkey[\s-1HEXKEYBYTES\s0+1];
.B char *passwd;
.fi
.SH DESCRIPTION
.IX "getpublickey function" "" "\fLgetpublickey()\fP function"
.IX "getsecretkey function" "" "\fLgetsecretkey()\fP function"
These routines are used to get public and secret keys from the
.SM YP
database.
.B getsecretkey(\|)
has an extra argument,
.IR passwd ,
which is used to decrypt the encrypted secret key stored in the database.
Both routines return 1 if they are successful in finding the key, 0 otherwise.
The keys are returned as
.SM NULL\s0-terminated,
hexadecimal strings. If the password supplied to
.B getsecretkey(\|)
fails to decrypt the secret key, the routine will return 1 but the
.I secretkey
argument will be a
.SM NULL
string (``'').
.SH "SEE ALSO"
.BR publickey (5)
.LP
.I \s-1RPC\s0 Programmer's Manual
in
.TX NETP

37
lib/libc/rpc/publickey.5 Normal file
View File

@ -0,0 +1,37 @@
.\" @(#)publickey.5 2.1 88/08/07 4.0 RPCSRC; from 1.6 88/02/29 SMI;
.TH PUBLICKEY 5 "19 October 1987"
.SH NAME
publickey \- public key database
.SH SYNOPSIS
.B /etc/publickey
.SH DESCRIPTION
.LP
.B /etc/publickey
is the public key database used for secure
networking. Each entry in
the database consists of a network user
name (which may either refer to
a user or a hostname), followed by the user's
public key (in hex
notation), a colon, and then the user's
secret key encrypted with
its login password (also in hex notation).
.LP
This file is altered either by the user through the
.BR chkey (1)
command or by the system administrator through the
.BR newkey (8)
command.
The file
.B /etc/publickey
should only contain data on the Yellow
Pages master machine, where it
is converted into the
.SM YP
database
.BR publickey.byname .
.SH SEE ALSO
.BR chkey (1),
.BR publickey (3R),
.BR newkey (8),
.BR ypupdated (8C)

View File

@ -1,5 +1,5 @@
.\" @(#)rpc.3n 2.4 88/08/08 4.0 RPCSRC; from 1.19 88/06/24 SMI
.TH RPC 3N "16 February 1988"
.TH RPC 3 "16 February 1988"
.SH NAME
rpc \- library routines for remote procedure calls
.SH SYNOPSIS AND DESCRIPTION
@ -13,7 +13,7 @@ reply.
Finally, the procedure call returns to the client.
.LP
Routines that are used for Secure RPC (DES authentication) are described in
.BR rpc_secure (3N).
.BR rpc_secure (3).
Secure RPC can be used only if DES encryption is available.
.LP
.ft B
@ -646,7 +646,7 @@ client for the remote program
.IR prognum ,
version
.IR versnum ;
the client uses use
the client uses
.SM UDP/IP
as a transport. The remote program is located at Internet
address
@ -700,7 +700,7 @@ client for the remote program
.IR prognum ,
on
.IR versnum ;
the client uses use
the client uses
.SM UDP/IP
as a transport. The remote program is located at Internet
address
@ -725,7 +725,7 @@ out.
The total time for the call to time out is specified by
.BR clnt_call(\|) .
.IP
This allows the user to specify the maximun packet size for sending and receiving
This allows the user to specify the maximum packet size for sending and receiving
.SM UDP\s0-based
.SM RPC
messages.
@ -735,7 +735,7 @@ messages.
.ft B
.nf
.sp .5
void
int
get_myaddress(addr)
struct sockaddr_in *addr;
.fi
@ -749,6 +749,7 @@ without consulting the library routines that deal with
.BR /etc/hosts .
The port number is always set to
.BR htons(\s-1PMAPPORT\s0) .
Returns zero on success, non-zero on failure.
.br
.if t .ne 10
.LP
@ -808,7 +809,7 @@ A return value of zero means that the mapping does not exist
or that
the
.SM RPC
system failured to contact the remote
system failed to contact the remote
.B portmap
service. In the latter case, the global variable
.B rpc_createerr(\|)
@ -997,7 +998,7 @@ fd_set svc_fdset;
A global variable reflecting the
.SM RPC
service side's
read file descriptor bit mask; it is suitable as a parameter
read file descriptor bit mask; it is suitable as a template parameter
to the
.B select
system call. This is only of interest
@ -1010,6 +1011,13 @@ yet it may change after calls to
.B svc_getreqset(\|)
or any creation routines.
.br
As well, note that if the process has descriptor limits
which are extended beyond
.BR FD_SETSIZE ,
this variable will only be usable for the first
.BR FD_SETSIZE
descriptors.
.br
.if t .ne 6
.LP
.ft B
@ -1487,7 +1495,7 @@ This routine returns
.SM NULL
if it fails.
.IP
This allows the user to specify the maximun packet size for sending and
This allows the user to specify the maximum packet size for sending and
receiving
.SM UDP\s0-based
.SM RPC messages.
@ -1709,8 +1717,8 @@ This routine modifies the global variable
.BR svc_fds(\|) .
Service implementors usually do not need this routine.
.SH SEE ALSO
.BR rpc_secure (3N),
.BR xdr (3N)
.BR rpc_secure (3),
.BR xdr (3)
.br
The following manuals:
.RS

View File

@ -1,71 +1,34 @@
.\" @(#)rpc.5 2.2 88/08/03 4.0 RPCSRC; from 1.4 87/11/27 SMI;
.TH RPC 5 "26 September 1985"
.SH NAME
rpc \- rpc program number data base
.SH SYNOPSIS
.B /etc/rpc
.SH DESCRIPTION
.Dd "September 26, 1985"
.Dt RPC 5
.Sh NAME
.Nm rpc
.Nd rpc program number data base
.Sh SYNOPSIS
/etc/rpc
.Sh DESCRIPTION
The
.I rpc
.Pa /etc/rpc
file contains user readable names that
can be used in place of rpc program numbers.
Each line has the following information:
.HP 10
.Pp
.Bl -bullet -compact
.It
name of server for the rpc program
.br
.ns
.HP 10
.It
rpc program number
.br
.ns
.HP 10
.It
aliases
.LP
.El
.Pp
Items are separated by any number of blanks and/or
tab characters.
A ``#'' indicates the beginning of a comment; characters up to the end of
the line are not interpreted by routines which search the file.
.LP
Here is an example of the \fI/etc/rpc\fP file from the Sun RPC Source
distribution.
.nf
.ta 1.5i +0.5i +1.0i +1.0i
#
# rpc 88/08/01 4.0 RPCSRC; from 1.12 88/02/07 SMI
#
portmapper 100000 portmap sunrpc
rstatd 100001 rstat rstat_svc rup perfmeter
rusersd 100002 rusers
nfs 100003 nfsprog
ypserv 100004 ypprog
mountd 100005 mount showmount
ypbind 100007
walld 100008 rwall shutdown
yppasswdd 100009 yppasswd
etherstatd 100010 etherstat
rquotad 100011 rquotaprog quota rquota
sprayd 100012 spray
3270_mapper 100013
rje_mapper 100014
selection_svc 100015 selnsvc
database_svc 100016
rexd 100017 rex
alis 100018
sched 100019
llockmgr 100020
nlockmgr 100021
x25.inr 100022
statmon 100023
status 100024
bootparam 100026
ypupdated 100028 ypupdate
keyserv 100029 keyserver
tfsd 100037
nsed 100038
nsemntd 100039
.fi
.DT
.SH FILES
/etc/rpc
.SH "SEE ALSO"
getrpcent(3N)
.Sh FILES
.Bl -tag -compact -width /etc/rpc
.Pa /etc/rpc
.El
.Sh "SEE ALSO"
.Xr getrpcent 3

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,7 +30,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)rpc_callmsg.c 2.1 88/07/29 4.0 RPCSRC";*/
static char *rcsid = "$Id: rpc_callmsg.c,v 1.1 1993/10/27 05:40:46 paul Exp $";
static char *rcsid = "$Id: rpc_callmsg.c,v 1.5 1996/12/30 14:55:38 peter Exp $";
#endif
/*
@ -41,7 +41,8 @@ static char *rcsid = "$Id: rpc_callmsg.c,v 1.1 1993/10/27 05:40:46 paul Exp $";
*/
#include <sys/param.h>
#include <stdlib.h>
#include <string.h>
#include <rpc/rpc.h>
/*
@ -52,7 +53,7 @@ xdr_callmsg(xdrs, cmsg)
register XDR *xdrs;
register struct rpc_msg *cmsg;
{
register long *buf;
register int32_t *buf;
register struct opaque_auth *oa;
if (xdrs->x_op == XDR_ENCODE) {
@ -83,16 +84,16 @@ xdr_callmsg(xdrs, cmsg)
IXDR_PUT_ENUM(buf, oa->oa_flavor);
IXDR_PUT_LONG(buf, oa->oa_length);
if (oa->oa_length) {
bcopy(oa->oa_base, (caddr_t)buf, oa->oa_length);
buf += RNDUP(oa->oa_length) / sizeof (long);
memcpy((caddr_t)buf, oa->oa_base, oa->oa_length);
buf += RNDUP(oa->oa_length) / sizeof (int32_t);
}
oa = &cmsg->rm_call.cb_verf;
IXDR_PUT_ENUM(buf, oa->oa_flavor);
IXDR_PUT_LONG(buf, oa->oa_length);
if (oa->oa_length) {
bcopy(oa->oa_base, (caddr_t)buf, oa->oa_length);
memcpy((caddr_t)buf, oa->oa_base, oa->oa_length);
/* no real need....
buf += RNDUP(oa->oa_length) / sizeof (long);
buf += RNDUP(oa->oa_length) / sizeof (int32_t);
*/
}
return (TRUE);
@ -131,11 +132,11 @@ xdr_callmsg(xdrs, cmsg)
return (FALSE);
}
} else {
bcopy((caddr_t)buf, oa->oa_base,
memcpy(oa->oa_base, (caddr_t)buf,
oa->oa_length);
/* no real need....
buf += RNDUP(oa->oa_length) /
sizeof (long);
sizeof (int32_t);
*/
}
}
@ -165,11 +166,11 @@ xdr_callmsg(xdrs, cmsg)
return (FALSE);
}
} else {
bcopy((caddr_t)buf, oa->oa_base,
memcpy(oa->oa_base, (caddr_t)buf,
oa->oa_length);
/* no real need...
buf += RNDUP(oa->oa_length) /
sizeof (long);
sizeof (int32_t);
*/
}
}
@ -177,14 +178,14 @@ xdr_callmsg(xdrs, cmsg)
}
}
if (
xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
xdr_u_int32_t(xdrs, &(cmsg->rm_xid)) &&
xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
(cmsg->rm_direction == CALL) &&
xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
(cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) &&
xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) &&
xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)) &&
xdr_u_long(xdrs, &(cmsg->rm_call.cb_proc)) &&
xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_prog)) &&
xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers)) &&
xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_proc)) &&
xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred)) )
return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf)));
return (FALSE);

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -29,18 +29,15 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)rpc_commondata.c 2.1 88/07/29 4.0 RPCSRC";*/
static char *rcsid = "$Id: rpc_commondata.c,v 1.1 1993/10/27 05:40:47 paul Exp $";
static char *rcsid = "$Id: rpc_commondata.c,v 1.3 1996/12/30 14:57:33 peter Exp $";
#endif
#include <rpc/rpc.h>
/*
* This file should only contain common data (global data) that is exported
* by public interfaces
* by public interfaces
*/
struct opaque_auth _null_auth;
#ifdef FD_SETSIZE
fd_set svc_fdset;
#else
int svc_fds;
#endif /* def FD_SETSIZE */
int svc_maxfd = -1;
struct rpc_createerr rpc_createerr;

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,19 +30,32 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)rpc_dtablesize.c 1.2 87/08/11 Copyr 1987 Sun Micro";*/
/*static char *sccsid = "from: @(#)rpc_dtablesize.c 2.1 88/07/29 4.0 RPCSRC";*/
static char *rcsid = "$Id: rpc_dtablesize.c,v 1.1 1993/10/27 05:40:48 paul Exp $";
static char *rcsid = "$Id: rpc_dtablesize.c,v 1.6 1996/12/30 18:41:20 peter Exp $";
#endif
#include <sys/types.h>
#include <unistd.h>
/*
* Cache the result of getdtablesize(), so we don't have to do an
* expensive system call every time.
*/
_rpc_dtablesize()
/*
* XXX In FreeBSD 2.x, you can have the maximum number of open file
* descriptors be greater than FD_SETSIZE (which us 256 by default).
*
* Since old programs tend to use this call to determine the first arg
* for select(), having this return > FD_SETSIZE is a Bad Idea(TM)!
*/
int
_rpc_dtablesize(void)
{
static int size;
if (size == 0) {
size = getdtablesize();
if (size > FD_SETSIZE)
size = FD_SETSIZE;
}
return (size);
}

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,7 +30,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)rpc_prot.c 2.3 88/08/07 4.0 RPCSRC";*/
static char *rcsid = "$Id: rpc_prot.c,v 1.1 1993/10/27 05:40:50 paul Exp $";
static char *rcsid = "$Id: rpc_prot.c,v 1.4 1996/12/30 15:00:53 peter Exp $";
#endif
/*
@ -86,9 +86,9 @@ xdr_des_block(xdrs, blkp)
/*
* XDR the MSG_ACCEPTED part of a reply message union
*/
bool_t
bool_t
xdr_accepted_reply(xdrs, ar)
register XDR *xdrs;
register XDR *xdrs;
register struct accepted_reply *ar;
{
@ -103,9 +103,11 @@ xdr_accepted_reply(xdrs, ar)
return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where));
case PROG_MISMATCH:
if (! xdr_u_long(xdrs, &(ar->ar_vers.low)))
if (! xdr_u_int32_t(xdrs, &(ar->ar_vers.low)))
return (FALSE);
return (xdr_u_long(xdrs, &(ar->ar_vers.high)));
return (xdr_u_int32_t(xdrs, &(ar->ar_vers.high)));
default:
break;
}
return (TRUE); /* TRUE => open ended set of problems */
}
@ -113,7 +115,7 @@ xdr_accepted_reply(xdrs, ar)
/*
* XDR the MSG_DENIED part of a reply message union
*/
bool_t
bool_t
xdr_rejected_reply(xdrs, rr)
register XDR *xdrs;
register struct rejected_reply *rr;
@ -125,9 +127,9 @@ xdr_rejected_reply(xdrs, rr)
switch (rr->rj_stat) {
case RPC_MISMATCH:
if (! xdr_u_long(xdrs, &(rr->rj_vers.low)))
if (! xdr_u_int32_t(xdrs, &(rr->rj_vers.low)))
return (FALSE);
return (xdr_u_long(xdrs, &(rr->rj_vers.high)));
return (xdr_u_int32_t(xdrs, &(rr->rj_vers.high)));
case AUTH_ERROR:
return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why)));
@ -149,7 +151,7 @@ xdr_replymsg(xdrs, rmsg)
register struct rpc_msg *rmsg;
{
if (
xdr_u_long(xdrs, &(rmsg->rm_xid)) &&
xdr_u_int32_t(xdrs, &(rmsg->rm_xid)) &&
xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) &&
(rmsg->rm_direction == REPLY) )
return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat),
@ -173,11 +175,11 @@ xdr_callhdr(xdrs, cmsg)
cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
if (
(xdrs->x_op == XDR_ENCODE) &&
xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
xdr_u_int32_t(xdrs, &(cmsg->rm_xid)) &&
xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) )
return (xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)));
xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_prog)) )
return (xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers)));
return (FALSE);
}
@ -221,7 +223,7 @@ accepted(acpt_stat, error)
error->re_lb.s2 = (long)acpt_stat;
}
static void
static void
rejected(rjct_stat, error)
register enum reject_stat rjct_stat;
register struct rpc_err *error;
@ -236,6 +238,8 @@ rejected(rjct_stat, error)
case AUTH_ERROR:
error->re_status = RPC_AUTHERROR;
return;
default:
break;
}
/* something's wrong, but we don't know what ... */
error->re_status = RPC_FAILED;
@ -287,5 +291,7 @@ _seterr_reply(msg, error)
error->re_vers.low = msg->acpted_rply.ar_vers.low;
error->re_vers.high = msg->acpted_rply.ar_vers.high;
break;
default:
break;
}
}

330
lib/libc/rpc/rpc_secure.3 Normal file
View File

@ -0,0 +1,330 @@
.\" @(#)rpc_secure.3n 2.1 88/08/08 4.0 RPCSRC; from 1.19 88/06/24 SMI
.TH RPC 3N "16 February 1988"
.SH NAME
rpc_secure \- library routines for secure remote procedure calls
.SH SYNOPSIS AND DESCRIPTION
These routines are part of the RPC library. They implement DES
Authentication. See
.BR rpc (3N)
for further details about RPC.
.LP
.ft B
.nf
.sp .5
#include <rpc/rpc.h>
.fi
.ft R
.br
.if t .ne 22
.LP
.ft B
.nf
.sp .5
\s-1AUTH\s0 *
authdes_create(name, window, syncaddr, ckey)
char *name;
unsigned window;
struct sockaddr_in *addr;
des_block *ckey;
.fi
.ft R
.IP
.B authdes_create(\|)
is the first of two routines which interface to the
.SM RPC
secure authentication system, known as
.SM DES
authentication.
The second is
.BR authdes_getucred(\|) ,
below. Note: the keyserver daemon
.BR keyserv (8C)
must be running for the
.SM DES
authentication system to work.
.IP
.BR authdes_create(\|) ,
used on the client side, returns an authentication handle that
will enable the use of the secure authentication system.
The first parameter
.I name
is the network name, or
.IR netname ,
of the owner of the server process. This field usually
represents a
.I hostname
derived from the utility routine
.BR host2netname ,
but could also represent a user name using
.BR user2netname .
The second field is window on the validity of
the client credential, given in seconds. A small
window is more secure than a large one, but choosing
too small of a window will increase the frequency of
resynchronizations because of clock drift. The third
parameter
.I syncaddr
is optional. If it is
.SM NULL\s0,
then the authentication system will assume
that the local clock is always in sync with the server's
clock, and will not attempt resynchronizations. If an address
is supplied, however, then the system will use the address
for consulting the remote time service whenever
resynchronization
is required. This parameter is usually the
address of the
.SM RPC
server itself. The final parameter
.I ckey
is also optional. If it is
.SM NULL\s0,
then the authentication system will
generate a random
.SM DES
key to be used for the encryption of credentials.
If it is supplied, however, then it will be used instead.
.br
.if t .ne 13
.LP
.ft B
.nf
.sp .5
authdes_getucred(adc, uid, gid, grouplen, groups)
struct authdes_cred *adc;
short *uid;
short *gid;
short *grouplen;
int *groups;
.fi
.ft R
.IP
.BR authdes_getucred(\|) ,
the second of the two
.SM DES
authentication routines,
is used on the server side for converting a
.SM DES
credential, which is
operating system independent, into a
.UX
credential. This routine differs from utility routine
.B netname2user
in that
.B authdes_getucred(\|)
pulls its information from a cache, and does not have to do a
Yellow Pages lookup every time it is called to get its information.
.br
.ft .ne 8
.LP
.ft B
.nf
.sp .5
host2netname(name, host, domain)
char *name;
char *host;
char *domain;
.fi
.ft R
.IP
Convert from a domain-specific hostname to an
operating-system independent netname. Return
.SM TRUE
if it succeeds and
.SM FALSE
if it fails. Inverse of
.BR netname2host(\|) .
.br
.if t .ne 9
.LP
.ft B
.nf
.sp .5
key_decryptsession(remotename, deskey)
char *remotename;
des_block *deskey;
.fi
.ft R
.IP
.B key_decryptsession(\|)
is an interface to the keyserver daemon, which is associated
with
.SM RPC\s0's
secure authentication system (\s-1DES\s0
authentication).
User programs rarely need to call it, or its associated routines
.BR key_encryptsession(\|) ,
.B key_gendes(\|)
and
.BR key_setsecret(\|) .
System commands such as
.B login
and the
.SM RPC
library are the main clients of these four routines.
.IP
.B key_decryptsession(\|)
takes a server netname and a des key, and decrypts the key by
using the the public key of the the server and the secret key
associated with the effective uid of the calling process. It
is the inverse of
.BR key_encryptsession(\|) .
.br
.if t .ne 8
.LP
.ft B
.nf
.sp .5
key_encryptsession(remotename, deskey)
char *remotename;
des_block *deskey;
.fi
.ft R
.IP
.B key_encryptsession(\|)
is a keyserver interface routine. It
takes a server netname and a des key, and encrypts
it using the public key of the the server and the secret key
associated with the effective uid of the calling process. It
is the inverse of
.BR key_decryptsession(\|) .
.br
.if t .ne 7
.LP
.ft B
.nf
.sp .5
key_gendes(deskey)
des_block *deskey;
.fi
.ft R
.IP
.B key_gendes(\|)
is a keyserver interface routine. It
is used to ask the keyserver for a secure conversation key.
Choosing one at \(lqrandom\(rq is usually not good enough,
because
the common ways of choosing random numbers, such as using the
current time, are very easy to guess.
.br
.if t .ne 6
.LP
.ft B
.nf
.sp .5
key_setsecret(key)
char *key;
.fi
.ft R
.IP
.B key_setsecret(\|)
is a keyserver interface routine. It is used to set the key for
the effective
.I uid
of the calling process.
.br
.if t .ne 7
.LP
.ft B
.nf
.sp .5
getnetname(name)
char name[\s-1MAXNETNAMELEN\s0];
.fi
.ft R
.IP
.B getnetname(\|)
installs the unique, operating-system independent netname of
the
caller in the fixed-length array
.IR name .
Returns
.SM TRUE
if it succeeds and
.SM FALSE
if it fails.
.br
.if t .ne 6
.LP
.ft B
.nf
.sp .5
netname2host(name, host, hostlen)
char *name;
char *host;
int hostlen;
.fi
.ft R
.IP
Convert from an operating-system independent netname to a
domain-specific hostname. Returns
.SM TRUE
if it succeeds and
.SM FALSE
if it fails. Inverse of
.BR host2netname(\|) .
.br
.if t .ne 9
.LP
.ft B
.nf
.sp .5
netname2user(name, uidp, gidp, gidlenp, gidlist)
char *name;
int *uidp;
int *gidp;
int *gidlenp;
int *gidlist;
.fi
.ft R
.IP
Convert from an operating-system independent netname to a
domain-specific user
.SM ID.
Returns
.SM TRUE
if it succeeds and
.SM FALSE
if it fails. Inverse of
.BR user2netname(\|) .
.br
.if t .ne 8
.LP
.ft B
.nf
.sp .5
user2netname(name, uid, domain)
char *name;
int uid;
char *domain;
.fi
.ft R
.IP
Convert from a domain-specific username to an operating-system
independent netname. Returns
.SM TRUE
if it succeeds and
.SM FALSE
if it fails. Inverse of
.BR netname2user(\|) .
.br
.SH SEE ALSO
.BR xdr (3N),
.BR keyserv (8C),
.BR rpc (3N)
.br
The following manuals:
.RS
.ft I
Remote Procedure Calls: Protocol Specification
.br
Remote Procedure Call Programming Guide
.br
rpcgen Programming Guide
.br
.ft R
.RE
.IR "\s-1RPC\s0: Remote Procedure Call Protocol Specification" ,
.SM RFC1050, Sun Microsystems, Inc.,
.SM USC-ISI\s0.

77
lib/libc/rpc/rpcdname.c Normal file
View File

@ -0,0 +1,77 @@
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user or with the express written consent of
* Sun Microsystems, Inc.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
#if !defined(lint) && defined(SCCSIDS)
static char sccsid[] = "@(#)rpcdname.c 1.7 91/03/11 Copyr 1989 Sun Micro";
#endif
/*
* rpcdname.c
* Gets the default domain name
*/
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
static char *default_domain = 0;
static char *
get_default_domain()
{
char temp[256];
if (default_domain)
return (default_domain);
if (getdomainname(temp, sizeof(temp)) < 0)
return (0);
if ((int) strlen(temp) > 0) {
default_domain = (char *)malloc((strlen(temp)+(unsigned)1));
if (default_domain == 0)
return (0);
(void) strcpy(default_domain, temp);
return (default_domain);
}
return (0);
}
/*
* This is a wrapper for the system call getdomainname which returns a
* ypclnt.h error code in the failure case. It also checks to see that
* the domain name is non-null, knowing that the null string is going to
* get rejected elsewhere in the NIS client package.
*/
int
_rpc_get_default_domain(domain)
char **domain;
{
if ((*domain = get_default_domain()) != 0)
return (0);
return (-1);
}

View File

@ -17,7 +17,7 @@ The load average numbers give the number of jobs in the run queue
averaged over 1, 5 and 15 minutes.
.PP
The
.B rstat_svc(8c)
.B rstat_svc(8)
daemon must be running on the remote host for this command to
work.
.B rstat
@ -50,8 +50,8 @@ daemon has terminated on the remote host.
rstat: RPC: Port mapper failure - RPC: Timed out
.IP
The remote host is not running the portmapper (see
.BR portmap(8c) ),
and cannot accomodate any RPC-based services. The host may be down.
.BR portmap(8) ),
and cannot accommodate any RPC-based services. The host may be down.
.SH "SEE ALSO"
.BR portmap (8c),
.BR rstat_svc (8c)
.BR portmap (8),
.BR rstat_svc (8)

View File

@ -1,5 +1,5 @@
.\" @(#)rstat_svc.8c 2.2 88/08/03 4.0 RPCSRC; from 1.10 87/09/09 SMI
.TH RSTAT_SVC 8C "24 November 1987"
.TH RSTAT_SVC 8 "24 November 1987"
.SH NAME
rstat_svc \- kernel statistics server
.SH SYNOPSIS
@ -17,5 +17,5 @@ daemon is normally invoked at boot time through /etc/rc.local.
.PP
.B rstat_svc
uses an RPC protocol defined in /usr/include/rpcsvc/rstat.x.
.SH "SEE ALSO"
.BR rstat (1),
.\" .SH "SEE ALSO"
.\" .BR rstat (1),

43
lib/libc/rpc/rtime.3 Normal file
View File

@ -0,0 +1,43 @@
.\" @(#)rtime.3n 2.1 88/08/08 4.0 RPCSRC; from 1.5 88/02/08 SMI
.TH RTIME 3 "22 November 1987"
.SH NAME
rtime \- get remote time
.SH SYNOPSIS
.nf
.B #include <sys/types.h>
.B #include <sys/time.h>
.B #include <netinet/in.h>
.LP
.B int rtime(addrp, timep, timeout)
.B struct sockaddr_in \(**addrp;
.B struct timeval \(**timep;
.B struct timeval \(**timeout;
.fi
.SH DESCRIPTION
.B rtime(\|)
consults the Internet Time Server at the address pointed to by
.I addrp
and returns the remote time in the
.B timeval
struct pointed to by
.IR timep .
Normally, the
.SM UDP
protocol is used when consulting the Time Server. The
.I timeout
parameter specifies how long the
routine should wait before giving
up when waiting for a reply. If
.I timeout
is specified as
.SM NULL\s0,
however, the routine will instead use
.SM TCP
and block until a reply is received from the time server.
.LP
The routine returns 0 if it is successful. Otherwise,
it returns \-1 and
.B errno
is set to reflect the cause of the error.
.SH "SEE ALSO"
.BR timed (8c)

157
lib/libc/rpc/rtime.c Normal file
View File

@ -0,0 +1,157 @@
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1988 by Sun Microsystems, Inc.
*/
/*
* rtime - get time from remote machine
*
* gets time, obtaining value from host
* on the udp/time socket. Since timeserver returns
* with time of day in seconds since Jan 1, 1900, must
* subtract seconds before Jan 1, 1970 to get
* what unix uses.
*/
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <stdio.h>
#include <netdb.h>
#if defined(LIBC_SCCS) && !defined(lint)
/* from: static char sccsid[] = "@(#)rtime.c 2.2 88/08/10 4.0 RPCSRC; from 1.8 88/02/08 SMI"; */
static const char rcsid[] = "$Id$";
#endif
extern int _rpc_dtablesize __P(( void ));
#define NYEARS (unsigned long)(1970 - 1900)
#define TOFFSET (unsigned long)(60*60*24*(365*NYEARS + (NYEARS/4)))
static void do_close __P(( int ));
int
rtime(addrp, timep, timeout)
struct sockaddr_in *addrp;
struct timeval *timep;
struct timeval *timeout;
{
int s;
fd_set readfds;
int res;
unsigned long thetime;
struct sockaddr_in from;
int fromlen;
int type;
struct servent *serv;
if (timeout == NULL) {
type = SOCK_STREAM;
} else {
type = SOCK_DGRAM;
}
s = socket(AF_INET, type, 0);
if (s < 0) {
return(-1);
}
addrp->sin_family = AF_INET;
/* TCP and UDP port are the same in this case */
if ((serv = getservbyname("time", "tcp")) == NULL) {
return(-1);
}
addrp->sin_port = serv->s_port;
if (type == SOCK_DGRAM) {
res = sendto(s, (char *)&thetime, sizeof(thetime), 0,
(struct sockaddr *)addrp, sizeof(*addrp));
if (res < 0) {
do_close(s);
return(-1);
}
do {
FD_ZERO(&readfds);
FD_SET(s, &readfds);
res = select(_rpc_dtablesize(), &readfds,
(fd_set *)NULL, (fd_set *)NULL, timeout);
} while (res < 0 && errno == EINTR);
if (res <= 0) {
if (res == 0) {
errno = ETIMEDOUT;
}
do_close(s);
return(-1);
}
fromlen = sizeof(from);
res = recvfrom(s, (char *)&thetime, sizeof(thetime), 0,
(struct sockaddr *)&from, &fromlen);
do_close(s);
if (res < 0) {
return(-1);
}
} else {
if (connect(s, (struct sockaddr *)addrp, sizeof(*addrp)) < 0) {
do_close(s);
return(-1);
}
res = read(s, (char *)&thetime, sizeof(thetime));
do_close(s);
if (res < 0) {
return(-1);
}
}
if (res != sizeof(thetime)) {
errno = EIO;
return(-1);
}
thetime = ntohl(thetime);
timep->tv_sec = thetime - TOFFSET;
timep->tv_usec = 0;
return(0);
}
static void
do_close(s)
int s;
{
int save;
save = errno;
(void) close(s);
errno = save;
}

View File

@ -5,32 +5,32 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
#if defined(LIBC_SCCS) && !defined(lint)
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)svc.c 1.44 88/02/08 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)svc.c 2.4 88/08/11 4.0 RPCSRC";*/
static char *rcsid = "$Id: svc.c,v 1.1 1993/10/27 05:40:54 paul Exp $";
static char *rcsid = "$Id: svc.c,v 1.7 1996/12/30 15:07:33 peter Exp $";
#endif
/*
@ -43,23 +43,20 @@ static char *rcsid = "$Id: svc.c,v 1.1 1993/10/27 05:40:54 paul Exp $";
* Copyright (C) 1984, Sun Microsystems, Inc.
*/
#include <string.h>
#include <stdlib.h>
#include <sys/errno.h>
#include <rpc/rpc.h>
#include <rpc/pmap_clnt.h>
extern int errno;
#ifdef FD_SETSIZE
static SVCXPRT **xports;
#else
#define NOFILE 32
static SVCXPRT *xports[NOFILE];
#endif /* def FD_SETSIZE */
static int xportssize;
#define NULL_SVC ((struct svc_callout *)0)
#define RQCRED_SIZE 400 /* this size is excessive */
#define max(a, b) (a > b ? a : b)
/*
* The services list
* Each entry represents a set of procedures (an rpc program).
@ -75,6 +72,9 @@ static struct svc_callout {
static struct svc_callout *svc_find();
int __svc_fdsetsize;
fd_set *__svc_fdset;
/* *************** SVCXPRT related stuff **************** */
/*
@ -86,44 +86,68 @@ xprt_register(xprt)
{
register int sock = xprt->xp_sock;
#ifdef FD_SETSIZE
if (xports == NULL) {
xports = (SVCXPRT **)
mem_alloc(FD_SETSIZE * sizeof(SVCXPRT *));
}
if (sock < _rpc_dtablesize()) {
xports[sock] = xprt;
FD_SET(sock, &svc_fdset);
}
#else
if (sock < NOFILE) {
xports[sock] = xprt;
svc_fds |= (1 << sock);
}
#endif /* def FD_SETSIZE */
if (sock + 1 > __svc_fdsetsize) {
int bytes = howmany(sock + 1, NFDBITS) * sizeof(fd_mask);
fd_set *fds;
fds = (fd_set *)malloc(bytes);
memset(fds, 0, bytes);
if (__svc_fdset) {
memcpy(fds, __svc_fdset, howmany(__svc_fdsetsize,
NFDBITS) * sizeof(fd_mask));
free(__svc_fdset);
}
__svc_fdset = fds;
__svc_fdsetsize = howmany(sock+1, NFDBITS);
}
if (sock < FD_SETSIZE)
FD_SET(sock, &svc_fdset);
FD_SET(sock, __svc_fdset);
if (xports == NULL || sock + 1 > xportssize) {
SVCXPRT **xp;
int size = FD_SETSIZE;
if (sock + 1 > size)
size = sock + 1;
xp = (SVCXPRT **)mem_alloc(size * sizeof(SVCXPRT *));
memset(xp, 0, size * sizeof(SVCXPRT *));
if (xports) {
memcpy(xp, xports, xportssize * sizeof(SVCXPRT *));
free(xports);
}
xportssize = size;
xports = xp;
}
xports[sock] = xprt;
svc_maxfd = max(svc_maxfd, sock);
}
/*
* De-activate a transport handle.
* De-activate a transport handle.
*/
void
xprt_unregister(xprt)
xprt_unregister(xprt)
SVCXPRT *xprt;
{
{
register int sock = xprt->xp_sock;
#ifdef FD_SETSIZE
if ((sock < _rpc_dtablesize()) && (xports[sock] == xprt)) {
if (xports[sock] == xprt) {
xports[sock] = (SVCXPRT *)0;
FD_CLR(sock, &svc_fdset);
if (sock < FD_SETSIZE)
FD_CLR(sock, &svc_fdset);
FD_CLR(sock, __svc_fdset);
if (sock == svc_maxfd) {
for (svc_maxfd--; svc_maxfd >= 0; svc_maxfd--)
if (xports[svc_maxfd])
break;
}
/*
* XXX could use svc_maxfd as a hint to
* decrease the size of __svc_fdset
*/
}
#else
if ((sock < NOFILE) && (xports[sock] == xprt)) {
xports[sock] = (SVCXPRT *)0;
svc_fds &= ~(1 << sock);
}
#endif /* def FD_SETSIZE */
}
@ -225,15 +249,15 @@ svc_sendreply(xprt, xdr_results, xdr_location)
xdrproc_t xdr_results;
caddr_t xdr_location;
{
struct rpc_msg rply;
struct rpc_msg rply;
rply.rm_direction = REPLY;
rply.rm_reply.rp_stat = MSG_ACCEPTED;
rply.acpted_rply.ar_verf = xprt->xp_verf;
rply.rm_direction = REPLY;
rply.rm_reply.rp_stat = MSG_ACCEPTED;
rply.acpted_rply.ar_verf = xprt->xp_verf;
rply.acpted_rply.ar_stat = SUCCESS;
rply.acpted_rply.ar_results.where = xdr_location;
rply.acpted_rply.ar_results.proc = xdr_results;
return (SVC_REPLY(xprt, &rply));
return (SVC_REPLY(xprt, &rply));
}
/*
@ -259,13 +283,13 @@ void
svcerr_decode(xprt)
register SVCXPRT *xprt;
{
struct rpc_msg rply;
struct rpc_msg rply;
rply.rm_direction = REPLY;
rply.rm_reply.rp_stat = MSG_ACCEPTED;
rply.rm_direction = REPLY;
rply.rm_reply.rp_stat = MSG_ACCEPTED;
rply.acpted_rply.ar_verf = xprt->xp_verf;
rply.acpted_rply.ar_stat = GARBAGE_ARGS;
SVC_REPLY(xprt, &rply);
SVC_REPLY(xprt, &rply);
}
/*
@ -275,13 +299,13 @@ void
svcerr_systemerr(xprt)
register SVCXPRT *xprt;
{
struct rpc_msg rply;
struct rpc_msg rply;
rply.rm_direction = REPLY;
rply.rm_reply.rp_stat = MSG_ACCEPTED;
rply.rm_direction = REPLY;
rply.rm_reply.rp_stat = MSG_ACCEPTED;
rply.acpted_rply.ar_verf = xprt->xp_verf;
rply.acpted_rply.ar_stat = SYSTEM_ERR;
SVC_REPLY(xprt, &rply);
SVC_REPLY(xprt, &rply);
}
/*
@ -315,15 +339,15 @@ svcerr_weakauth(xprt)
/*
* Program unavailable error reply
*/
void
void
svcerr_noprog(xprt)
register SVCXPRT *xprt;
{
struct rpc_msg rply;
struct rpc_msg rply;
rply.rm_direction = REPLY;
rply.rm_reply.rp_stat = MSG_ACCEPTED;
rply.acpted_rply.ar_verf = xprt->xp_verf;
rply.rm_direction = REPLY;
rply.rm_reply.rp_stat = MSG_ACCEPTED;
rply.acpted_rply.ar_verf = xprt->xp_verf;
rply.acpted_rply.ar_stat = PROG_UNAVAIL;
SVC_REPLY(xprt, &rply);
}
@ -331,9 +355,9 @@ svcerr_noprog(xprt)
/*
* Program version mismatch error reply
*/
void
void
svcerr_progvers(xprt, low_vers, high_vers)
register SVCXPRT *xprt;
register SVCXPRT *xprt;
u_long low_vers;
u_long high_vers;
{
@ -358,9 +382,9 @@ svcerr_progvers(xprt, low_vers, high_vers)
* the "raw" parameters (msg.rm_call.cb_cred and msg.rm_call.cb_verf) and
* the "cooked" credentials (rqst->rq_clntcred).
* However, this function does not know the structure of the cooked
* credentials, so it make the following assumptions:
* credentials, so it make the following assumptions:
* a) the structure is contiguous (no pointers), and
* b) the cred structure size does not exceed RQCRED_SIZE bytes.
* b) the cred structure size does not exceed RQCRED_SIZE bytes.
* In all events, all three parameters are freed upon exit from this routine.
* The storage is trivially management on the call stack in user land, but
* is mallocated in kernel land.
@ -370,29 +394,25 @@ void
svc_getreq(rdfds)
int rdfds;
{
#ifdef FD_SETSIZE
fd_set readfds;
FD_ZERO(&readfds);
readfds.fds_bits[0] = rdfds;
svc_getreqset(&readfds);
#else
int readfds = rdfds & svc_fds;
svc_getreqset(&readfds);
#endif /* def FD_SETSIZE */
}
void
svc_getreqset(readfds)
#ifdef FD_SETSIZE
fd_set *readfds;
{
#else
int *readfds;
svc_getreqset2(readfds, FD_SETSIZE);
}
void
svc_getreqset2(readfds, width)
fd_set *readfds;
int width;
{
int readfds_local = *readfds;
#endif /* def FD_SETSIZE */
enum xprt_stat stat;
struct rpc_msg msg;
int prog_found;
@ -400,30 +420,23 @@ svc_getreqset(readfds)
u_long high_vers;
struct svc_req r;
register SVCXPRT *xprt;
register u_long mask;
register int bit;
register u_long *maskp;
register int setsize;
register int sock;
register fd_mask mask, *maskp;
char cred_area[2*MAX_AUTH_BYTES + RQCRED_SIZE];
msg.rm_call.cb_cred.oa_base = cred_area;
msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]);
r.rq_clntcred = &(cred_area[2*MAX_AUTH_BYTES]);
#ifdef FD_SETSIZE
setsize = _rpc_dtablesize();
maskp = (u_long *)readfds->fds_bits;
for (sock = 0; sock < setsize; sock += NFDBITS) {
for (mask = *maskp++; bit = ffs(mask); mask ^= (1 << (bit - 1))) {
maskp = readfds->fds_bits;
for (sock = 0; sock < width; sock += NFDBITS) {
for (mask = *maskp++; (bit = ffs(mask)); mask ^= (1 << (bit - 1))) {
/* sock has input waiting */
xprt = xports[sock + bit - 1];
#else
for (sock = 0; readfds_local != 0; sock++, readfds_local >>= 1) {
if ((readfds_local & 1) != 0) {
/* sock has input waiting */
xprt = xports[sock];
#endif /* def FD_SETSIZE */
if (xprt == NULL)
/* But do we control sock? */
continue;
/* now receive msgs from xprtprt (support batch calls) */
do {
if (SVC_RECV(xprt, &msg)) {
@ -444,7 +457,7 @@ svc_getreqset(readfds)
}
/* now match message with a registered service*/
prog_found = FALSE;
low_vers = 0 - 1;
low_vers = (u_long) - 1;
high_vers = 0;
for (s = svc_head; s != NULL_SVC; s = s->sc_next) {
if (s->sc_prog == r.rq_prog) {

View File

@ -13,63 +13,76 @@
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1986-1991 by Sun Microsystems Inc.
*/
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)svc_auth.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)svc_auth.c 2.1 88/08/07 4.0 RPCSRC";*/
static char *rcsid = "$Id: svc_auth.c,v 1.1 1993/10/27 05:40:56 paul Exp $";
#ident "@(#)svc_auth.c 1.16 94/04/24 SMI"
#if !defined(lint) && defined(SCCSIDS)
static char sccsid[] = "@(#)svc_auth.c 1.26 89/02/07 Copyr 1984 Sun Micro";
#endif
/*
* svc_auth_nodes.c, Server-side rpc authenticator interface,
* *WITHOUT* DES authentication.
* svc_auth.c, Server-side rpc authenticator interface.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*/
#ifdef KERNEL
#include <sys/param.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
#include <rpc/clnt.h>
#include <rpc/rpc_msg.h>
#include <rpc/svc.h>
#include <rpc/svc_auth.h>
#else
#include <stdlib.h>
#include <rpc/rpc.h>
#endif
#include <sys/types.h>
/*
* svcauthsw is the bdevsw of server side authentication.
*
* svcauthsw is the bdevsw of server side authentication.
*
* Server side authenticators are called from authenticate by
* using the client auth struct flavor field to index into svcauthsw.
* The server auth flavors must implement a routine that looks
* like:
*
* The server auth flavors must implement a routine that looks
* like:
*
* enum auth_stat
* flavorx_auth(rqst, msg)
* register struct svc_req *rqst;
* register struct svc_req *rqst;
* register struct rpc_msg *msg;
*
*/
enum auth_stat _svcauth_null(); /* no authentication */
enum auth_stat _svcauth_unix(); /* unix style (uid, gids) */
enum auth_stat _svcauth_null(); /* no authentication */
enum auth_stat _svcauth_unix(); /* (system) unix style (uid, gids) */
enum auth_stat _svcauth_short(); /* short hand unix style */
enum auth_stat _svcauth_des(); /* des style */
static struct {
enum auth_stat (*authenticator)();
} svcauthsw[] = {
_svcauth_null, /* AUTH_NULL */
_svcauth_unix, /* AUTH_UNIX */
_svcauth_short, /* AUTH_SHORT */
/* declarations to allow servers to specify new authentication flavors */
struct authsvc {
int flavor;
enum auth_stat (*handler)();
struct authsvc *next;
};
#define AUTH_MAX 2 /* HIGHEST AUTH NUMBER */
static struct authsvc *Auths = NULL;
/*
* The call rpc message, msg has been obtained from the wire. The msg contains
@ -95,23 +108,104 @@ _authenticate(rqst, msg)
struct rpc_msg *msg;
{
register int cred_flavor;
register struct authsvc *asp;
rqst->rq_cred = msg->rm_call.cb_cred;
rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
rqst->rq_xprt->xp_verf.oa_length = 0;
cred_flavor = rqst->rq_cred.oa_flavor;
if ((cred_flavor <= AUTH_MAX) && (cred_flavor >= AUTH_NULL)) {
return ((*(svcauthsw[cred_flavor].authenticator))(rqst, msg));
switch (cred_flavor) {
case AUTH_NULL:
return(_svcauth_null(rqst, msg));
case AUTH_UNIX:
return(_svcauth_unix(rqst, msg));
case AUTH_SHORT:
return(_svcauth_short(rqst, msg));
/*
* We leave AUTH_DES turned off by default because svcauth_des()
* needs getpublickey(), which is in librpcsvc, not libc. If we
* included AUTH_DES as a built-in flavor, programs that don't
* have -lrpcsvc in their Makefiles wouldn't link correctly, even
* though they don't use AUTH_DES. And I'm too lazy to go through
* the tree looking for all of them.
*/
#ifdef DES_BUILTIN
case AUTH_DES:
return(_svcauth_des(rqst, msg));
#endif
}
/* flavor doesn't match any of the builtin types, so try new ones */
for (asp = Auths; asp; asp = asp->next) {
if (asp->flavor == cred_flavor) {
enum auth_stat as;
as = (*asp->handler)(rqst, msg);
return (as);
}
}
return (AUTH_REJECTEDCRED);
}
/*ARGSUSED*/
enum auth_stat
_svcauth_null(/*rqst, msg*/)
/*struct svc_req *rqst;
struct rpc_msg *msg;*/
_svcauth_null(rqst, msg)
struct svc_req *rqst;
struct rpc_msg *msg;
{
return (AUTH_OK);
}
/*
* Allow the rpc service to register new authentication types that it is
* prepared to handle. When an authentication flavor is registered,
* the flavor is checked against already registered values. If not
* registered, then a new Auths entry is added on the list.
*
* There is no provision to delete a registration once registered.
*
* This routine returns:
* 0 if registration successful
* 1 if flavor already registered
* -1 if can't register (errno set)
*/
int
svc_auth_reg(cred_flavor, handler)
register int cred_flavor;
enum auth_stat (*handler)();
{
register struct authsvc *asp;
switch (cred_flavor) {
case AUTH_NULL:
case AUTH_UNIX:
case AUTH_SHORT:
#ifdef DES_BUILTIN
case AUTH_DES:
#endif
/* already registered */
return (1);
default:
for (asp = Auths; asp; asp = asp->next) {
if (asp->flavor == cred_flavor) {
/* already registered */
return (1);
}
}
/* this is a new one, so go ahead and register it */
asp = (struct authsvc *)mem_alloc(sizeof (*asp));
if (asp == NULL) {
return (-1);
}
asp->flavor = cred_flavor;
asp->handler = handler;
asp->next = Auths;
Auths = asp;
break;
}
return (0);
}

531
lib/libc/rpc/svc_auth_des.c Normal file
View File

@ -0,0 +1,531 @@
/*
* Copyright (c) 1988 by Sun Microsystems, Inc.
*/
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* svcauth_des.c, server-side des authentication
*
* We insure for the service the following:
* (1) The timestamp microseconds do not exceed 1 million.
* (2) The timestamp plus the window is less than the current time.
* (3) The timestamp is not less than the one previously
* seen in the current session.
*
* It is up to the server to determine if the window size is
* too small .
*
*/
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <rpc/des_crypt.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
#include <rpc/auth_des.h>
#include <rpc/svc.h>
#include <rpc/rpc_msg.h>
#include <rpc/svc_auth.h>
#if defined(LIBC_SCCS) && !defined(lint)
/* from: static char sccsid[] = "@(#)svcauth_des.c 2.3 89/07/11 4.0 RPCSRC; from 1.15 88/02/08 SMI"; */
static const char rcsid[] = "$Id$";
#endif
#define debug(msg) printf("svcauth_des: %s\n", msg)
#define USEC_PER_SEC ((u_long) 1000000L)
#define BEFORE(t1, t2) timercmp(t1, t2, <)
/*
* LRU cache of conversation keys and some other useful items.
*/
#define AUTHDES_CACHESZ 64
struct cache_entry {
des_block key; /* conversation key */
char *rname; /* client's name */
u_int window; /* credential lifetime window */
struct timeval laststamp; /* detect replays of creds */
char *localcred; /* generic local credential */
};
static struct cache_entry *authdes_cache/* [AUTHDES_CACHESZ] */;
static short *authdes_lru/* [AUTHDES_CACHESZ] */;
static void cache_init(); /* initialize the cache */
static short cache_spot(); /* find an entry in the cache */
static void cache_ref(/*short sid*/); /* note that sid was ref'd */
static void invalidate(); /* invalidate entry in cache */
/*
* cache statistics
*/
static struct {
u_long ncachehits; /* times cache hit, and is not replay */
u_long ncachereplays; /* times cache hit, and is replay */
u_long ncachemisses; /* times cache missed */
} svcauthdes_stats;
/*
* Service side authenticator for AUTH_DES
*/
enum auth_stat
_svcauth_des(rqst, msg)
register struct svc_req *rqst;
register struct rpc_msg *msg;
{
register long *ixdr;
des_block cryptbuf[2];
register struct authdes_cred *cred;
struct authdes_verf verf;
int status;
register struct cache_entry *entry;
short sid = 0;
des_block *sessionkey;
des_block ivec;
u_int window;
struct timeval timestamp;
u_long namelen;
struct area {
struct authdes_cred area_cred;
char area_netname[MAXNETNAMELEN+1];
} *area;
if (authdes_cache == NULL) {
cache_init();
}
area = (struct area *)rqst->rq_clntcred;
cred = (struct authdes_cred *)&area->area_cred;
/*
* Get the credential
*/
ixdr = (long *)msg->rm_call.cb_cred.oa_base;
cred->adc_namekind = IXDR_GET_ENUM(ixdr, enum authdes_namekind);
switch (cred->adc_namekind) {
case ADN_FULLNAME:
namelen = IXDR_GET_U_LONG(ixdr);
if (namelen > MAXNETNAMELEN) {
return (AUTH_BADCRED);
}
cred->adc_fullname.name = area->area_netname;
bcopy((char *)ixdr, cred->adc_fullname.name,
(u_int)namelen);
cred->adc_fullname.name[namelen] = 0;
ixdr += (RNDUP(namelen) / BYTES_PER_XDR_UNIT);
cred->adc_fullname.key.key.high = (u_long)*ixdr++;
cred->adc_fullname.key.key.low = (u_long)*ixdr++;
cred->adc_fullname.window = (u_long)*ixdr++;
break;
case ADN_NICKNAME:
cred->adc_nickname = (u_long)*ixdr++;
break;
default:
return (AUTH_BADCRED);
}
/*
* Get the verifier
*/
ixdr = (long *)msg->rm_call.cb_verf.oa_base;
verf.adv_xtimestamp.key.high = (u_long)*ixdr++;
verf.adv_xtimestamp.key.low = (u_long)*ixdr++;
verf.adv_int_u = (u_long)*ixdr++;
/*
* Get the conversation key
*/
if (cred->adc_namekind == ADN_FULLNAME) {
netobj pkey;
char pkey_data[1024];
sessionkey = &cred->adc_fullname.key;
if (! getpublickey(cred->adc_fullname.name, pkey_data)) {
debug("getpublickey");
return(AUTH_BADCRED);
}
pkey.n_bytes = pkey_data;
pkey.n_len = strlen(pkey_data) + 1;
if (key_decryptsession_pk(cred->adc_fullname.name, &pkey,
sessionkey) < 0) {
debug("decryptsessionkey");
return (AUTH_BADCRED); /* key not found */
}
} else { /* ADN_NICKNAME */
sid = (short)cred->adc_nickname;
if (sid >= AUTHDES_CACHESZ) {
debug("bad nickname");
return (AUTH_BADCRED); /* garbled credential */
}
sessionkey = &authdes_cache[sid].key;
}
/*
* Decrypt the timestamp
*/
cryptbuf[0] = verf.adv_xtimestamp;
if (cred->adc_namekind == ADN_FULLNAME) {
cryptbuf[1].key.high = cred->adc_fullname.window;
cryptbuf[1].key.low = verf.adv_winverf;
ivec.key.high = ivec.key.low = 0;
status = cbc_crypt((char *)sessionkey, (char *)cryptbuf,
2*sizeof(des_block), DES_DECRYPT | DES_HW,
(char *)&ivec);
} else {
status = ecb_crypt((char *)sessionkey, (char *)cryptbuf,
sizeof(des_block), DES_DECRYPT | DES_HW);
}
if (DES_FAILED(status)) {
debug("decryption failure");
return (AUTH_FAILED); /* system error */
}
/*
* XDR the decrypted timestamp
*/
ixdr = (long *)cryptbuf;
timestamp.tv_sec = IXDR_GET_LONG(ixdr);
timestamp.tv_usec = IXDR_GET_LONG(ixdr);
/*
* Check for valid credentials and verifiers.
* They could be invalid because the key was flushed
* out of the cache, and so a new session should begin.
* Be sure and send AUTH_REJECTED{CRED, VERF} if this is the case.
*/
{
struct timeval current;
int nick;
int winverf;
if (cred->adc_namekind == ADN_FULLNAME) {
window = IXDR_GET_U_LONG(ixdr);
winverf = IXDR_GET_U_LONG(ixdr);
if (winverf != window - 1) {
debug("window verifier mismatch");
return (AUTH_BADCRED); /* garbled credential */
}
sid = cache_spot(sessionkey, cred->adc_fullname.name,
&timestamp);
if (sid < 0) {
debug("replayed credential");
return (AUTH_REJECTEDCRED); /* replay */
}
nick = 0;
} else { /* ADN_NICKNAME */
window = authdes_cache[sid].window;
nick = 1;
}
if ((u_long)timestamp.tv_usec >= USEC_PER_SEC) {
debug("invalid usecs");
/* cached out (bad key), or garbled verifier */
return (nick ? AUTH_REJECTEDVERF : AUTH_BADVERF);
}
if (nick && BEFORE(&timestamp,
&authdes_cache[sid].laststamp)) {
debug("timestamp before last seen");
return (AUTH_REJECTEDVERF); /* replay */
}
(void) gettimeofday(&current, (struct timezone *)NULL);
current.tv_sec -= window; /* allow for expiration */
if (!BEFORE(&current, &timestamp)) {
debug("timestamp expired");
/* replay, or garbled credential */
return (nick ? AUTH_REJECTEDVERF : AUTH_BADCRED);
}
}
/*
* Set up the reply verifier
*/
verf.adv_nickname = (u_long)sid;
/*
* xdr the timestamp before encrypting
*/
ixdr = (long *)cryptbuf;
IXDR_PUT_LONG(ixdr, timestamp.tv_sec - 1);
IXDR_PUT_LONG(ixdr, timestamp.tv_usec);
/*
* encrypt the timestamp
*/
status = ecb_crypt((char *)sessionkey, (char *)cryptbuf,
sizeof(des_block), DES_ENCRYPT | DES_HW);
if (DES_FAILED(status)) {
debug("encryption failure");
return (AUTH_FAILED); /* system error */
}
verf.adv_xtimestamp = cryptbuf[0];
/*
* Serialize the reply verifier, and update rqst
*/
ixdr = (long *)msg->rm_call.cb_verf.oa_base;
*ixdr++ = (long)verf.adv_xtimestamp.key.high;
*ixdr++ = (long)verf.adv_xtimestamp.key.low;
*ixdr++ = (long)verf.adv_int_u;
rqst->rq_xprt->xp_verf.oa_flavor = AUTH_DES;
rqst->rq_xprt->xp_verf.oa_base = msg->rm_call.cb_verf.oa_base;
rqst->rq_xprt->xp_verf.oa_length =
(char *)ixdr - msg->rm_call.cb_verf.oa_base;
/*
* We succeeded, commit the data to the cache now and
* finish cooking the credential.
*/
entry = &authdes_cache[sid];
entry->laststamp = timestamp;
cache_ref(sid);
if (cred->adc_namekind == ADN_FULLNAME) {
cred->adc_fullname.window = window;
cred->adc_nickname = (u_long)sid; /* save nickname */
if (entry->rname != NULL) {
mem_free(entry->rname, strlen(entry->rname) + 1);
}
entry->rname = (char *)mem_alloc((u_int)strlen(cred->adc_fullname.name)
+ 1);
if (entry->rname != NULL) {
(void) strcpy(entry->rname, cred->adc_fullname.name);
} else {
debug("out of memory");
}
entry->key = *sessionkey;
entry->window = window;
invalidate(entry->localcred); /* mark any cached cred invalid */
} else { /* ADN_NICKNAME */
/*
* nicknames are cooked into fullnames
*/
cred->adc_namekind = ADN_FULLNAME;
cred->adc_fullname.name = entry->rname;
cred->adc_fullname.key = entry->key;
cred->adc_fullname.window = entry->window;
}
return (AUTH_OK); /* we made it!*/
}
/*
* Initialize the cache
*/
static void
cache_init()
{
register int i;
authdes_cache = (struct cache_entry *)
mem_alloc(sizeof(struct cache_entry) * AUTHDES_CACHESZ);
bzero((char *)authdes_cache,
sizeof(struct cache_entry) * AUTHDES_CACHESZ);
authdes_lru = (short *)mem_alloc(sizeof(short) * AUTHDES_CACHESZ);
/*
* Initialize the lru list
*/
for (i = 0; i < AUTHDES_CACHESZ; i++) {
authdes_lru[i] = i;
}
}
/*
* Find the lru victim
*/
static short
cache_victim()
{
return (authdes_lru[AUTHDES_CACHESZ-1]);
}
/*
* Note that sid was referenced
*/
static void
cache_ref(sid)
register short sid;
{
register int i;
register short curr;
register short prev;
prev = authdes_lru[0];
authdes_lru[0] = sid;
for (i = 1; prev != sid; i++) {
curr = authdes_lru[i];
authdes_lru[i] = prev;
prev = curr;
}
}
/*
* Find a spot in the cache for a credential containing
* the items given. Return -1 if a replay is detected, otherwise
* return the spot in the cache.
*/
static short
cache_spot(key, name, timestamp)
register des_block *key;
char *name;
struct timeval *timestamp;
{
register struct cache_entry *cp;
register int i;
register u_long hi;
hi = key->key.high;
for (cp = authdes_cache, i = 0; i < AUTHDES_CACHESZ; i++, cp++) {
if (cp->key.key.high == hi &&
cp->key.key.low == key->key.low &&
cp->rname != NULL &&
bcmp(cp->rname, name, strlen(name) + 1) == 0) {
if (BEFORE(timestamp, &cp->laststamp)) {
svcauthdes_stats.ncachereplays++;
return (-1); /* replay */
}
svcauthdes_stats.ncachehits++;
return (i); /* refresh */
}
}
svcauthdes_stats.ncachemisses++;
return (cache_victim()); /* new credential */
}
#if (defined(sun) || defined(vax) || defined(__FreeBSD__))
/*
* Local credential handling stuff.
* NOTE: bsd unix dependent.
* Other operating systems should put something else here.
*/
#define UNKNOWN -2 /* grouplen, if cached cred is unknown user */
#define INVALID -1 /* grouplen, if cache entry is invalid */
struct bsdcred {
short uid; /* cached uid */
short gid; /* cached gid */
short grouplen; /* length of cached groups */
short groups[NGROUPS]; /* cached groups */
};
/*
* Map a des credential into a unix cred.
* We cache the credential here so the application does
* not have to make an rpc call every time to interpret
* the credential.
*/
int
authdes_getucred(adc, uid, gid, grouplen, groups)
struct authdes_cred *adc;
uid_t *uid;
gid_t *gid;
int *grouplen;
register gid_t *groups;
{
unsigned sid;
register int i;
uid_t i_uid;
gid_t i_gid;
int i_grouplen;
struct bsdcred *cred;
sid = adc->adc_nickname;
if (sid >= AUTHDES_CACHESZ) {
debug("invalid nickname");
return (0);
}
cred = (struct bsdcred *)authdes_cache[sid].localcred;
if (cred == NULL) {
cred = (struct bsdcred *)mem_alloc(sizeof(struct bsdcred));
authdes_cache[sid].localcred = (char *)cred;
cred->grouplen = INVALID;
}
if (cred->grouplen == INVALID) {
/*
* not in cache: lookup
*/
if (!netname2user(adc->adc_fullname.name, &i_uid, &i_gid,
&i_grouplen, groups))
{
debug("unknown netname");
cred->grouplen = UNKNOWN; /* mark as lookup up, but not found */
return (0);
}
debug("missed ucred cache");
*uid = cred->uid = i_uid;
*gid = cred->gid = i_gid;
*grouplen = cred->grouplen = i_grouplen;
for (i = i_grouplen - 1; i >= 0; i--) {
cred->groups[i] = groups[i]; /* int to short */
}
return (1);
} else if (cred->grouplen == UNKNOWN) {
/*
* Already lookup up, but no match found
*/
return (0);
}
/*
* cached credentials
*/
*uid = cred->uid;
*gid = cred->gid;
*grouplen = cred->grouplen;
for (i = cred->grouplen - 1; i >= 0; i--) {
groups[i] = cred->groups[i]; /* short to int */
}
return (1);
}
static void
invalidate(cred)
char *cred;
{
if (cred == NULL) {
return;
}
((struct bsdcred *)cred)->grouplen = INVALID;
}
#endif

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,7 +30,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)svc_auth_unix.c 1.28 88/02/08 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)svc_auth_unix.c 2.3 88/08/01 4.0 RPCSRC";*/
static char *rcsid = "$Id: svc_auth_unix.c,v 1.1 1993/10/27 05:40:58 paul Exp $";
static char *rcsid = "$Id: svc_auth_unix.c,v 1.4 1996/12/30 15:10:14 peter Exp $";
#endif
/*
@ -45,6 +45,7 @@ static char *rcsid = "$Id: svc_auth_unix.c,v 1.1 1993/10/27 05:40:58 paul Exp $"
*/
#include <stdio.h>
#include <string.h>
#include <rpc/rpc.h>
/*
@ -58,7 +59,7 @@ _svcauth_unix(rqst, msg)
register enum auth_stat stat;
XDR xdrs;
register struct authunix_parms *aup;
register long *buf;
register int32_t *buf;
struct area {
struct authunix_parms area_aup;
char area_machname[MAX_MACHINE_NAME+1];
@ -82,10 +83,10 @@ _svcauth_unix(rqst, msg)
stat = AUTH_BADCRED;
goto done;
}
bcopy((caddr_t)buf, aup->aup_machname, (u_int)str_len);
memcpy(aup->aup_machname, (caddr_t)buf, (u_int)str_len);
aup->aup_machname[str_len] = 0;
str_len = RNDUP(str_len);
buf += str_len / sizeof (long);
buf += str_len / sizeof (int32_t);
aup->aup_uid = IXDR_GET_LONG(buf);
aup->aup_gid = IXDR_GET_LONG(buf);
gid_len = IXDR_GET_U_LONG(buf);
@ -113,8 +114,19 @@ _svcauth_unix(rqst, msg)
stat = AUTH_BADCRED;
goto done;
}
rqst->rq_xprt->xp_verf.oa_flavor = AUTH_NULL;
rqst->rq_xprt->xp_verf.oa_length = 0;
/* get the verifier */
if ((u_int)msg->rm_call.cb_verf.oa_length) {
rqst->rq_xprt->xp_verf.oa_flavor =
msg->rm_call.cb_verf.oa_flavor;
rqst->rq_xprt->xp_verf.oa_base =
msg->rm_call.cb_verf.oa_base;
rqst->rq_xprt->xp_verf.oa_length =
msg->rm_call.cb_verf.oa_length;
} else {
rqst->rq_xprt->xp_verf.oa_flavor = AUTH_NULL;
rqst->rq_xprt->xp_verf.oa_length = 0;
}
stat = AUTH_OK;
done:
XDR_DESTROY(&xdrs);
@ -127,7 +139,7 @@ done:
* Looks up longhand in a cache.
*/
/*ARGSUSED*/
enum auth_stat
enum auth_stat
_svcauth_short(rqst, msg)
struct svc_req *rqst;
struct rpc_msg *msg;

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,7 +30,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)svc_raw.c 1.15 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)svc_raw.c 2.1 88/07/29 4.0 RPCSRC";*/
static char *rcsid = "$Id: svc_raw.c,v 1.1 1993/10/27 05:40:59 paul Exp $";
static char *rcsid = "$Id: svc_raw.c,v 1.3 1995/10/22 14:51:36 phk Exp $";
#endif
/*
@ -43,7 +43,7 @@ static char *rcsid = "$Id: svc_raw.c,v 1.1 1993/10/27 05:40:59 paul Exp $";
*/
#include <rpc/rpc.h>
#include <stdlib.h>
/*
* This is the "network" that we will be moving data over
@ -151,7 +151,7 @@ svcraw_freeargs(xprt, xdr_args, args_ptr)
SVCXPRT *xprt;
xdrproc_t xdr_args;
caddr_t args_ptr;
{
{
register struct svcraw_private *srp = svcraw_private;
register XDR *xdrs;
@ -160,7 +160,7 @@ svcraw_freeargs(xprt, xdr_args, args_ptr)
xdrs = &srp->xdr_stream;
xdrs->x_op = XDR_FREE;
return ((*xdr_args)(xdrs, args_ptr));
}
}
static void
svcraw_destroy()

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,7 +30,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)svc_run.c 2.1 88/07/29 4.0 RPCSRC";*/
static char *rcsid = "$Id: svc_run.c,v 1.1 1993/10/27 05:41:00 paul Exp $";
static char *rcsid = "$Id: svc_run.c,v 1.4 1996/12/30 15:14:29 peter Exp $";
#endif
/*
@ -38,36 +38,50 @@ static char *rcsid = "$Id: svc_run.c,v 1.1 1993/10/27 05:41:00 paul Exp $";
* Wait for input, call server program.
*/
#include <rpc/rpc.h>
#include <stdio.h>
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
extern int __svc_fdsetsize;
extern fd_set *__svc_fdset;
void
svc_run()
{
#ifdef FD_SETSIZE
fd_set readfds;
#else
int readfds;
#endif /* def FD_SETSIZE */
extern int errno;
fd_set *fds;
for (;;) {
#ifdef FD_SETSIZE
readfds = svc_fdset;
#else
readfds = svc_fds;
#endif /* def FD_SETSIZE */
switch (select(_rpc_dtablesize(), &readfds, (int *)0, (int *)0,
(struct timeval *)0)) {
if (__svc_fdset) {
int bytes = howmany(__svc_fdsetsize, NFDBITS) *
sizeof(fd_mask);
fds = (fd_set *)malloc(bytes);
memcpy(fds, __svc_fdset, bytes);
} else
fds = NULL;
switch (select(svc_maxfd + 1, fds, NULL, NULL,
(struct timeval *)0)) {
case -1:
if (errno == EINTR) {
if (fds)
free(fds);
continue;
}
perror("svc_run: - select failed");
if (fds)
free(fds);
return;
case 0:
if (fds)
free(fds);
continue;
default:
svc_getreqset(&readfds);
/* XXX What the hell?? what if fds == NULL?? */
svc_getreqset2(fds, svc_maxfd + 1);
free(fds);
}
}
}

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,10 +30,10 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)svc_simple.c 1.18 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)svc_simple.c 2.2 88/08/01 4.0 RPCSRC";*/
static char *rcsid = "$Id: svc_simple.c,v 1.1 1993/10/27 05:41:01 paul Exp $";
static char *rcsid = "$Id: svc_simple.c,v 1.5 1996/12/30 15:16:22 peter Exp $";
#endif
/*
/*
* svc_simple.c
* Simplified front end to rpc.
*
@ -41,7 +41,10 @@ static char *rcsid = "$Id: svc_simple.c,v 1.1 1993/10/27 05:41:01 paul Exp $";
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rpc/rpc.h>
#include <rpc/pmap_clnt.h>
#include <sys/socket.h>
#include <netdb.h>
@ -56,14 +59,16 @@ static void universal();
static SVCXPRT *transp;
struct proglst *pl;
int
registerrpc(prognum, versnum, procnum, progname, inproc, outproc)
int prognum, versnum, procnum;
char *(*progname)();
xdrproc_t inproc, outproc;
{
if (procnum == NULLPROC) {
(void) fprintf(stderr,
"can't reassign procedure number %d\n", NULLPROC);
"can't reassign procedure number %ld\n", NULLPROC);
return (-1);
}
if (transp == 0) {
@ -74,7 +79,7 @@ registerrpc(prognum, versnum, procnum, progname, inproc, outproc)
}
}
(void) pmap_unset((u_long)prognum, (u_long)versnum);
if (!svc_register(transp, (u_long)prognum, (u_long)versnum,
if (!svc_register(transp, (u_long)prognum, (u_long)versnum,
universal, IPPROTO_UDP)) {
(void) fprintf(stderr, "couldn't register prog %d vers %d\n",
prognum, versnum);
@ -105,11 +110,11 @@ universal(rqstp, transp)
char xdrbuf[UDPMSGSIZE];
struct proglst *pl;
/*
/*
* enforce "procnum 0 is echo" convention
*/
if (rqstp->rq_proc == NULLPROC) {
if (svc_sendreply(transp, xdr_void, (char *)NULL) == FALSE) {
if (svc_sendreply(transp, xdr_void, NULL) == FALSE) {
(void) fprintf(stderr, "xxx\n");
exit(1);
}
@ -120,7 +125,7 @@ universal(rqstp, transp)
for (pl = proglst; pl != NULL; pl = pl->p_nxt)
if (pl->p_prognum == prog && pl->p_procnum == proc) {
/* decode arguments into a CLEAN buffer */
bzero(xdrbuf, sizeof(xdrbuf)); /* required ! */
memset(xdrbuf, 0, sizeof(xdrbuf)); /* required ! */
if (!svc_getargs(transp, pl->p_inproc, xdrbuf)) {
svcerr_decode(transp);
return;

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,11 +30,11 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC";*/
static char *rcsid = "$Id: svc_tcp.c,v 1.1 1993/10/27 05:41:02 paul Exp $";
static char *rcsid = "$Id: svc_tcp.c,v 1.8 1996/12/30 15:19:08 peter Exp $";
#endif
/*
* svc_tcp.c, Server side for TCP/IP based RPC.
* svc_tcp.c, Server side for TCP/IP based RPC.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*
@ -44,11 +44,12 @@ static char *rcsid = "$Id: svc_tcp.c,v 1.1 1993/10/27 05:41:02 paul Exp $";
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <rpc/rpc.h>
#include <sys/socket.h>
#include <errno.h>
extern bool_t abort();
extern errno;
/*
* Ops vector for TCP/IP based rpc service handle
@ -78,9 +79,9 @@ static enum xprt_stat rendezvous_stat();
static struct xp_ops svctcp_rendezvous_op = {
rendezvous_request,
rendezvous_stat,
abort,
abort,
abort,
(bool_t (*)())abort,
(bool_t (*)())abort,
(bool_t (*)())abort,
svctcp_destroy
};
@ -138,7 +139,8 @@ svctcp_create(sock, sendsize, recvsize)
}
madesock = TRUE;
}
bzero((char *)&addr, sizeof (addr));
memset(&addr, 0, sizeof (addr));
addr.sin_len = sizeof(struct sockaddr_in);
addr.sin_family = AF_INET;
if (bindresvport(sock, &addr)) {
addr.sin_port = 0;
@ -195,7 +197,7 @@ makefd_xprt(fd, sendsize, recvsize)
{
register SVCXPRT *xprt;
register struct tcp_conn *cd;
xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
if (xprt == (SVCXPRT *)NULL) {
(void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n");
@ -241,6 +243,14 @@ rendezvous_request(xprt)
goto again;
return (FALSE);
}
/*
* XXX careful for ftp bounce attacks. If discovered, close the
* socket and look for another connection.
*/
if (addr.sin_port == htons(20)) {
close(sock);
goto again;
}
/*
* make a new transporter (re-uses xprt)
*/
@ -294,35 +304,52 @@ readtcp(xprt, buf, len)
register int len;
{
register int sock = xprt->xp_sock;
#ifdef FD_SETSIZE
fd_set mask;
fd_set readfds;
struct timeval start, delta, tv;
struct timeval tmp1, tmp2;
fd_set *fds, readfds;
FD_ZERO(&mask);
FD_SET(sock, &mask);
#else
register int mask = 1 << sock;
int readfds;
#endif /* def FD_SETSIZE */
if (sock + 1 > FD_SETSIZE) {
int bytes = howmany(sock+1, NFDBITS) * sizeof(fd_mask);
fds = (fd_set *)malloc(bytes);
if (fds == NULL)
goto fatal_err;
memset(fds, 0, bytes);
} else {
fds = &readfds;
FD_ZERO(fds);
}
delta = wait_per_try;
gettimeofday(&start, NULL);
do {
readfds = mask;
if (select(_rpc_dtablesize(), &readfds, (int*)NULL, (int*)NULL,
&wait_per_try) <= 0) {
if (errno == EINTR) {
continue;
}
/* XXX we know the other bits are still clear */
FD_SET(sock, fds);
tv = delta; /* in case select() implements writeback */
switch (select(sock + 1, fds, NULL, NULL, &tv)) {
case -1:
if (errno != EINTR)
goto fatal_err;
gettimeofday(&tmp1, NULL);
timersub(&tmp1, &start, &tmp2);
timersub(&delta, &tmp2, &tmp1);
if (tmp1.tv_sec < 0 || !timerisset(&tmp1))
goto fatal_err;
delta = tmp1;
continue;
case 0:
goto fatal_err;
}
#ifdef FD_SETSIZE
} while (!FD_ISSET(sock, &readfds));
#else
} while (readfds != mask);
#endif /* def FD_SETSIZE */
} while (!FD_ISSET(sock, fds));
if ((len = read(sock, buf, len)) > 0) {
if (fds != &readfds)
free(fds);
return (len);
}
fatal_err:
((struct tcp_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED;
if (fds != &readfds)
free(fds);
return (-1);
}

View File

@ -5,23 +5,23 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
@ -30,7 +30,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)svc_udp.c 1.24 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)svc_udp.c 2.2 88/07/29 4.0 RPCSRC";*/
static char *rcsid = "$Id: svc_udp.c,v 1.1 1993/10/27 05:41:03 paul Exp $";
static char *rcsid = "$Id: svc_udp.c,v 1.7 1996/12/30 15:21:19 peter Exp $";
#endif
/*
@ -43,11 +43,12 @@ static char *rcsid = "$Id: svc_udp.c,v 1.1 1993/10/27 05:41:03 paul Exp $";
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <rpc/rpc.h>
#include <sys/socket.h>
#include <errno.h>
#define rpc_buffer(xprt) ((xprt)->xp_p1)
#define MAX(a, b) ((a > b) ? a : b)
@ -57,6 +58,8 @@ static enum xprt_stat svcudp_stat();
static bool_t svcudp_getargs();
static bool_t svcudp_freeargs();
static void svcudp_destroy();
static void cache_set __P((SVCXPRT *, u_long));
static int cache_get __P((SVCXPRT *, struct rpc_msg *, char **, u_long *));
static struct xp_ops svcudp_op = {
svcudp_recv,
@ -67,8 +70,6 @@ static struct xp_ops svcudp_op = {
svcudp_destroy
};
extern int errno;
/*
* kept in xprt->xp_p2
*/
@ -112,7 +113,8 @@ svcudp_bufcreate(sock, sendsz, recvsz)
}
madesock = TRUE;
}
bzero((char *)&addr, sizeof (addr));
memset((char *)&addr, 0, sizeof (addr));
addr.sin_len = sizeof(struct sockaddr_in);
addr.sin_family = AF_INET;
if (bindresvport(sock, &addr)) {
addr.sin_port = 0;
@ -164,7 +166,7 @@ svcudp_stat(xprt)
SVCXPRT *xprt;
{
return (XPRT_IDLE);
return (XPRT_IDLE);
}
static bool_t
@ -177,7 +179,6 @@ svcudp_recv(xprt, msg)
register int rlen;
char *reply;
u_long replylen;
static int cache_get();
again:
xprt->xp_addrlen = sizeof(struct sockaddr_in);
@ -185,7 +186,7 @@ svcudp_recv(xprt, msg)
0, (struct sockaddr *)&(xprt->xp_raddr), &(xprt->xp_addrlen));
if (rlen == -1 && errno == EINTR)
goto again;
if (rlen < 4*sizeof(u_long))
if (rlen == -1 || rlen < 4*sizeof(u_int32_t))
return (FALSE);
xdrs->x_op = XDR_DECODE;
XDR_SETPOS(xdrs, 0);
@ -204,14 +205,13 @@ svcudp_recv(xprt, msg)
static bool_t
svcudp_reply(xprt, msg)
register SVCXPRT *xprt;
struct rpc_msg *msg;
register SVCXPRT *xprt;
struct rpc_msg *msg;
{
register struct svcudp_data *su = su_data(xprt);
register XDR *xdrs = &(su->su_xdrs);
register int slen;
register bool_t stat = FALSE;
static void cache_set();
xdrs->x_op = XDR_ENCODE;
XDR_SETPOS(xdrs, 0);
@ -284,7 +284,7 @@ svcudp_destroy(xprt)
(type *) mem_alloc((unsigned) (sizeof(type) * (size)))
#define BZERO(addr, type, size) \
bzero((char *) addr, sizeof(type) * (int) (size))
memset((char *) addr, 0, sizeof(type) * (int) (size))
/*
* An entry in the cache
@ -307,7 +307,7 @@ struct cache_node {
/*
* Next node on the list, if there is a collision
*/
cache_ptr cache_next;
cache_ptr cache_next;
};
@ -331,14 +331,14 @@ struct udp_cache {
* the hashing function
*/
#define CACHE_LOC(transp, xid) \
(xid % (SPARSENESS*((struct udp_cache *) su_data(transp)->su_cache)->uc_size))
(xid % (SPARSENESS*((struct udp_cache *) su_data(transp)->su_cache)->uc_size))
/*
* Enable use of the cache.
* Enable use of the cache.
* Note: there is no disable.
*/
svcudp_enablecache(transp, size)
int svcudp_enablecache(transp, size)
SVCXPRT *transp;
u_long size;
{
@ -347,7 +347,7 @@ svcudp_enablecache(transp, size)
if (su->su_cache != NULL) {
CACHE_PERROR("enablecache: cache already enabled");
return(0);
return(0);
}
uc = ALLOC(struct udp_cache, 1);
if (uc == NULL) {
@ -379,9 +379,9 @@ svcudp_enablecache(transp, size)
static void
cache_set(xprt, replylen)
SVCXPRT *xprt;
u_long replylen;
u_long replylen;
{
register cache_ptr victim;
register cache_ptr victim;
register cache_ptr *vicp;
register struct svcudp_data *su = su_data(xprt);
struct udp_cache *uc = (struct udp_cache *) su->su_cache;
@ -395,9 +395,9 @@ cache_set(xprt, replylen)
victim = uc->uc_fifo[uc->uc_nextvictim];
if (victim != NULL) {
loc = CACHE_LOC(xprt, victim->cache_xid);
for (vicp = &uc->uc_entries[loc];
*vicp != NULL && *vicp != victim;
vicp = &(*vicp)->cache_next)
for (vicp = &uc->uc_entries[loc];
*vicp != NULL && *vicp != victim;
vicp = &(*vicp)->cache_next)
;
if (*vicp == NULL) {
CACHE_PERROR("cache_set: victim not found");
@ -431,7 +431,7 @@ cache_set(xprt, replylen)
victim->cache_prog = uc->uc_prog;
victim->cache_addr = uc->uc_addr;
loc = CACHE_LOC(xprt, victim->cache_xid);
victim->cache_next = uc->uc_entries[loc];
victim->cache_next = uc->uc_entries[loc];
uc->uc_entries[loc] = victim;
uc->uc_fifo[uc->uc_nextvictim++] = victim;
uc->uc_nextvictim %= uc->uc_size;
@ -441,7 +441,7 @@ cache_set(xprt, replylen)
* Try to get an entry from the cache
* return 1 if found, 0 if not found
*/
static
static int
cache_get(xprt, msg, replyp, replylenp)
SVCXPRT *xprt;
struct rpc_msg *msg;
@ -453,7 +453,7 @@ cache_get(xprt, msg, replyp, replylenp)
register struct svcudp_data *su = su_data(xprt);
register struct udp_cache *uc = (struct udp_cache *) su->su_cache;
# define EQADDR(a1, a2) (bcmp((char*)&a1, (char*)&a2, sizeof(a1)) == 0)
# define EQADDR(a1, a2) (memcmp(&a1, &a2, sizeof(a1)) == 0)
loc = CACHE_LOC(xprt, su->su_xid);
for (ent = uc->uc_entries[loc]; ent != NULL; ent = ent->cache_next) {

511
lib/libc/rpc/svc_unix.c Normal file
View File

@ -0,0 +1,511 @@
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)svc_unix.c 1.21 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)svc_unix.c 2.2 88/08/01 4.0 RPCSRC";*/
static char *rcsid = "$Id: svc_unix.c,v 1.8 1996/12/30 15:19:08 peter Exp $";
#endif
/*
* svc_unix.c, Server side for TCP/IP based RPC.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*
* Actually implements two flavors of transporter -
* a unix rendezvouser (a listner and connection establisher)
* and a record/unix stream.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <rpc/rpc.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/uio.h>
#include <errno.h>
/*
* Ops vector for AF_UNIX based rpc service handle
*/
static bool_t svcunix_recv();
static enum xprt_stat svcunix_stat();
static bool_t svcunix_getargs();
static bool_t svcunix_reply();
static bool_t svcunix_freeargs();
static void svcunix_destroy();
static struct xp_ops svcunix_op = {
svcunix_recv,
svcunix_stat,
svcunix_getargs,
svcunix_reply,
svcunix_freeargs,
svcunix_destroy
};
/*
* Ops vector for TCP/IP rendezvous handler
*/
static bool_t rendezvous_request();
static enum xprt_stat rendezvous_stat();
static struct xp_ops svcunix_rendezvous_op = {
rendezvous_request,
rendezvous_stat,
(bool_t (*)())abort,
(bool_t (*)())abort,
(bool_t (*)())abort,
svcunix_destroy
};
static int readunix(), writeunix();
static SVCXPRT *makefd_xprt();
struct unix_rendezvous { /* kept in xprt->xp_p1 */
u_int sendsize;
u_int recvsize;
};
struct unix_conn { /* kept in xprt->xp_p1 */
enum xprt_stat strm_stat;
u_long x_id;
XDR xdrs;
char verf_body[MAX_AUTH_BYTES];
};
struct cmessage {
struct cmsghdr cmsg;
struct cmsgcred cmcred;
};
static struct cmessage cm;
static int __msgread(sock, buf, cnt)
int sock;
void *buf;
size_t cnt;
{
struct iovec iov[1];
struct msghdr msg;
bzero((char *)&cm, sizeof(cm));
iov[0].iov_base = buf;
iov[0].iov_len = cnt;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = (caddr_t)&cm;
msg.msg_controllen = sizeof(struct cmessage);
msg.msg_flags = 0;
return(recvmsg(sock, &msg, 0));
}
static int __msgwrite(sock, buf, cnt)
int sock;
void *buf;
size_t cnt;
{
struct iovec iov[1];
struct msghdr msg;
bzero((char *)&cm, sizeof(cm));
iov[0].iov_base = buf;
iov[0].iov_len = cnt;
cm.cmsg.cmsg_type = SCM_CREDS;
cm.cmsg.cmsg_level = SOL_SOCKET;
cm.cmsg.cmsg_len = sizeof(struct cmessage);
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = (caddr_t)&cm;
msg.msg_controllen = sizeof(struct cmessage);
msg.msg_flags = 0;
return(sendmsg(sock, &msg, 0));
}
/*
* Usage:
* xprt = svcunix_create(sock, send_buf_size, recv_buf_size);
*
* Creates, registers, and returns a (rpc) unix based transporter.
* Once *xprt is initialized, it is registered as a transporter
* see (svc.h, xprt_register). This routine returns
* a NULL if a problem occurred.
*
* If sock<0 then a socket is created, else sock is used.
* If the socket, sock is not bound to a port then svcunix_create
* binds it to an arbitrary port. The routine then starts a unix
* listener on the socket's associated port. In any (successful) case,
* xprt->xp_sock is the registered socket number and xprt->xp_port is the
* associated port number.
*
* Since unix streams do buffered io similar to stdio, the caller can specify
* how big the send and receive buffers are via the second and third parms;
* 0 => use the system default.
*/
SVCXPRT *
svcunix_create(sock, sendsize, recvsize, path)
register int sock;
u_int sendsize;
u_int recvsize;
char *path;
{
bool_t madesock = FALSE;
register SVCXPRT *xprt;
register struct unix_rendezvous *r;
struct sockaddr_un addr;
int len = sizeof(struct sockaddr_un);
if (sock == RPC_ANYSOCK) {
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
perror("svc_unix.c - AF_UNIX socket creation problem");
return ((SVCXPRT *)NULL);
}
madesock = TRUE;
}
memset(&addr, 0, sizeof (addr));
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, path);
len = strlen(addr.sun_path) + sizeof(addr.sun_family) +
sizeof(addr.sun_len) + 1;
addr.sun_len = len;
bind(sock, (struct sockaddr *)&addr, len);
if ((getsockname(sock, (struct sockaddr *)&addr, &len) != 0) ||
(listen(sock, 2) != 0)) {
perror("svc_unix.c - cannot getsockname or listen");
if (madesock)
(void)close(sock);
return ((SVCXPRT *)NULL);
}
r = (struct unix_rendezvous *)mem_alloc(sizeof(*r));
if (r == NULL) {
(void) fprintf(stderr, "svcunix_create: out of memory\n");
return (NULL);
}
r->sendsize = sendsize;
r->recvsize = recvsize;
xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
if (xprt == NULL) {
(void) fprintf(stderr, "svcunix_create: out of memory\n");
return (NULL);
}
xprt->xp_p2 = NULL;
xprt->xp_p1 = (caddr_t)r;
xprt->xp_verf = _null_auth;
xprt->xp_ops = &svcunix_rendezvous_op;
xprt->xp_port = -1 /*ntohs(addr.sin_port)*/;
xprt->xp_sock = sock;
xprt_register(xprt);
return (xprt);
}
/*
* Like svunix_create(), except the routine takes any *open* UNIX file
* descriptor as its first input.
*/
SVCXPRT *
svcunixfd_create(fd, sendsize, recvsize)
int fd;
u_int sendsize;
u_int recvsize;
{
return (makefd_xprt(fd, sendsize, recvsize));
}
static SVCXPRT *
makefd_xprt(fd, sendsize, recvsize)
int fd;
u_int sendsize;
u_int recvsize;
{
register SVCXPRT *xprt;
register struct unix_conn *cd;
xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
if (xprt == (SVCXPRT *)NULL) {
(void) fprintf(stderr, "svc_unix: makefd_xprt: out of memory\n");
goto done;
}
cd = (struct unix_conn *)mem_alloc(sizeof(struct unix_conn));
if (cd == (struct unix_conn *)NULL) {
(void) fprintf(stderr, "svc_unix: makefd_xprt: out of memory\n");
mem_free((char *) xprt, sizeof(SVCXPRT));
xprt = (SVCXPRT *)NULL;
goto done;
}
cd->strm_stat = XPRT_IDLE;
xdrrec_create(&(cd->xdrs), sendsize, recvsize,
(caddr_t)xprt, readunix, writeunix);
xprt->xp_p2 = NULL;
xprt->xp_p1 = (caddr_t)cd;
xprt->xp_verf.oa_base = cd->verf_body;
xprt->xp_addrlen = 0;
xprt->xp_ops = &svcunix_op; /* truely deals with calls */
xprt->xp_port = 0; /* this is a connection, not a rendezvouser */
xprt->xp_sock = fd;
xprt_register(xprt);
done:
return (xprt);
}
static bool_t
rendezvous_request(xprt)
register SVCXPRT *xprt;
{
int sock;
struct unix_rendezvous *r;
struct sockaddr_un addr;
struct sockaddr_in in_addr;
int len;
r = (struct unix_rendezvous *)xprt->xp_p1;
again:
len = sizeof(struct sockaddr_in);
if ((sock = accept(xprt->xp_sock, (struct sockaddr *)&addr,
&len)) < 0) {
if (errno == EINTR)
goto again;
return (FALSE);
}
/*
* make a new transporter (re-uses xprt)
*/
bzero((char *)&in_addr, sizeof(in_addr));
in_addr.sin_family = AF_UNIX;
xprt = makefd_xprt(sock, r->sendsize, r->recvsize);
xprt->xp_raddr = in_addr;
xprt->xp_addrlen = len;
return (FALSE); /* there is never an rpc msg to be processed */
}
static enum xprt_stat
rendezvous_stat()
{
return (XPRT_IDLE);
}
static void
svcunix_destroy(xprt)
register SVCXPRT *xprt;
{
register struct unix_conn *cd = (struct unix_conn *)xprt->xp_p1;
xprt_unregister(xprt);
(void)close(xprt->xp_sock);
if (xprt->xp_port != 0) {
/* a rendezvouser socket */
xprt->xp_port = 0;
} else {
/* an actual connection socket */
XDR_DESTROY(&(cd->xdrs));
}
mem_free((caddr_t)cd, sizeof(struct unix_conn));
mem_free((caddr_t)xprt, sizeof(SVCXPRT));
}
/*
* All read operations timeout after 35 seconds.
* A timeout is fatal for the connection.
*/
static struct timeval wait_per_try = { 35, 0 };
/*
* reads data from the unix conection.
* any error is fatal and the connection is closed.
* (And a read of zero bytes is a half closed stream => error.)
*/
static int
readunix(xprt, buf, len)
register SVCXPRT *xprt;
caddr_t buf;
register int len;
{
register int sock = xprt->xp_sock;
struct timeval start, delta, tv;
struct timeval tmp1, tmp2;
fd_set *fds, readfds;
if (sock + 1 > FD_SETSIZE) {
int bytes = howmany(sock+1, NFDBITS) * sizeof(fd_mask);
fds = (fd_set *)malloc(bytes);
if (fds == NULL)
goto fatal_err;
memset(fds, 0, bytes);
} else {
fds = &readfds;
FD_ZERO(fds);
}
delta = wait_per_try;
gettimeofday(&start, NULL);
do {
/* XXX we know the other bits are still clear */
FD_SET(sock, fds);
tv = delta; /* in case select() implements writeback */
switch (select(sock + 1, fds, NULL, NULL, &tv)) {
case -1:
if (errno != EINTR)
goto fatal_err;
gettimeofday(&tmp1, NULL);
timersub(&tmp1, &start, &tmp2);
timersub(&delta, &tmp2, &tmp1);
if (tmp1.tv_sec < 0 || !timerisset(&tmp1))
goto fatal_err;
delta = tmp1;
continue;
case 0:
goto fatal_err;
}
} while (!FD_ISSET(sock, fds));
if ((len = __msgread(sock, buf, len)) > 0) {
if (fds != &readfds)
free(fds);
return (len);
}
fatal_err:
((struct unix_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED;
if (fds != &readfds)
free(fds);
return (-1);
}
/*
* writes data to the unix connection.
* Any error is fatal and the connection is closed.
*/
static int
writeunix(xprt, buf, len)
register SVCXPRT *xprt;
caddr_t buf;
int len;
{
register int i, cnt;
for (cnt = len; cnt > 0; cnt -= i, buf += i) {
if ((i = __msgwrite(xprt->xp_sock, buf, cnt)) < 0) {
((struct unix_conn *)(xprt->xp_p1))->strm_stat =
XPRT_DIED;
return (-1);
}
}
return (len);
}
static enum xprt_stat
svcunix_stat(xprt)
SVCXPRT *xprt;
{
register struct unix_conn *cd =
(struct unix_conn *)(xprt->xp_p1);
if (cd->strm_stat == XPRT_DIED)
return (XPRT_DIED);
if (! xdrrec_eof(&(cd->xdrs)))
return (XPRT_MOREREQS);
return (XPRT_IDLE);
}
static bool_t
svcunix_recv(xprt, msg)
SVCXPRT *xprt;
register struct rpc_msg *msg;
{
register struct unix_conn *cd =
(struct unix_conn *)(xprt->xp_p1);
register XDR *xdrs = &(cd->xdrs);
xdrs->x_op = XDR_DECODE;
(void)xdrrec_skiprecord(xdrs);
if (xdr_callmsg(xdrs, msg)) {
cd->x_id = msg->rm_xid;
/* set up verifiers */
msg->rm_call.cb_verf.oa_flavor = AUTH_UNIX;
msg->rm_call.cb_verf.oa_base = (caddr_t)&cm;
msg->rm_call.cb_verf.oa_length = sizeof(cm);
return (TRUE);
}
return (FALSE);
}
static bool_t
svcunix_getargs(xprt, xdr_args, args_ptr)
SVCXPRT *xprt;
xdrproc_t xdr_args;
caddr_t args_ptr;
{
return ((*xdr_args)(&(((struct unix_conn *)(xprt->xp_p1))->xdrs), args_ptr));
}
static bool_t
svcunix_freeargs(xprt, xdr_args, args_ptr)
SVCXPRT *xprt;
xdrproc_t xdr_args;
caddr_t args_ptr;
{
register XDR *xdrs =
&(((struct unix_conn *)(xprt->xp_p1))->xdrs);
xdrs->x_op = XDR_FREE;
return ((*xdr_args)(xdrs, args_ptr));
}
static bool_t
svcunix_reply(xprt, msg)
SVCXPRT *xprt;
register struct rpc_msg *msg;
{
register struct unix_conn *cd =
(struct unix_conn *)(xprt->xp_p1);
register XDR *xdrs = &(cd->xdrs);
register bool_t stat;
xdrs->x_op = XDR_ENCODE;
msg->rm_xid = cd->x_id;
stat = xdr_replymsg(xdrs, msg);
(void)xdrrec_endofrecord(xdrs, TRUE);
return (stat);
}