Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 6 Oct 2001 17:40:01 -0700 (PDT)
From:      Martin Blapp <mb@imp.ch>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: bin/29171: [PATCH] keyserv and rpc.yppasswd
Message-ID:  <200110070040.f970e1P30686@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/29171; it has been noted by GNATS.

From: Martin Blapp <mb@imp.ch>
To: <freebsd-gnats-submit@FreeBSD.org>
Cc:  
Subject: Re: bin/29171: [PATCH] keyserv and rpc.yppasswd
Date: Sun, 7 Oct 2001 02:40:51 +0200 (CEST)

 One part:
 
 http://home.teleport.ch/freebsd/userland/local_transp_compat.diff
 
 has been comitted by Bill Paul. Thanks !
 
 Here are the other patches:
 
 usr.sbin/keyserv/keyserv.c
 
 Fix the breakage in keyserv, Readded the svc_create() and
 the registering of the "unix" transport, now it is fixed.
 
 --- usr.sbin/keyserv/keyserv.c  Thu Mar 22 05:31:29 2001
 +++ usr.sbin/keyserv/keyserv.c  Fri Apr  6 23:41:56 2001
 @@ -117,6 +117,8 @@
  	int sock = RPC_ANYSOCK;
  	int warn = 0;
  	char *path = NULL;
 +	void *localhandle;
 +	struct netconfig *nconf = NULL;
 
  	__key_encryptsession_pk_LOCAL = &key_encrypt_pk_2_svc_prog;
  	__key_decryptsession_pk_LOCAL = &key_decrypt_pk_2_svc_prog;
 @@ -155,12 +157,15 @@
  	/*
  	 * Initialize
  	 */
 -	(void) umask(066);	/* paranoia */
 +	(void) umask(S_IXUSR|S_IXGRP|S_IXOTH);
  	if (geteuid() != 0)
  		errx(1, "keyserv must be run as root");
  	setmodulus(HEXMODULUS);
  	getrootkey(&masterkey, nflag);
 
 +	rpcb_unset(KEY_PROG, KEY_VERS, NULL);
 +	rpcb_unset(KEY_PROG, KEY_VERS2, NULL);
 +
  	if (svc_create(keyprogram, KEY_PROG, KEY_VERS,
  		"netpath") == 0) {
  		(void) fprintf(stderr,
 @@ -174,6 +179,32 @@
  			"%s: unable to create service\n", argv[0]);
  		exit(1);
  	}
 +
 +	localhandle = setnetconfig();
 +	while ((nconf = getnetconfig(localhandle)) != NULL) {
 +		if (nconf->nc_protofmly != NULL &&
 +		    strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0)
 +			break;
 +	}
 +
 +	if (nconf == NULL)
 +		errx(1, "getnetconfig: %s", nc_sperror());
 +
 +	unlink(KEYSERVSOCK);
 +	rpcb_unset(CRYPT_PROG, CRYPT_VERS, nconf);
 +	transp = svcunix_create(RPC_ANYSOCK, 0, 0, KEYSERVSOCK);
 +	if (transp == NULL)
 +		errx(1, "cannot create AF_LOCAL service");
 +	if (!svc_reg(transp, KEY_PROG, KEY_VERS, keyprogram, nconf))
 +		errx(1, "unable to register (KEY_PROG, KEY_VERS, unix)");
 +	if (!svc_reg(transp, KEY_PROG, KEY_VERS2, keyprogram, nconf))
 +		errx(1, "unable to register (KEY_PROG, KEY_VERS2, unix)");
 +	if (!svc_reg(transp, CRYPT_PROG, CRYPT_VERS, crypt_prog_1, nconf))
 +		errx(1, "unable to register (CRYPT_PROG, CRYPT_VERS, unix)");
 +
 +	endnetconfig(localhandle);
 +
 +	(void) umask(066);	/* paranoia */
 
  	if (!debugging) {
  		daemon(0,0);
 
 usr.sbin/rpc.yppasswdd/yppasswdd_main.c
 usr.sbin/rpc.yppasswdd/yppasswdd_server.c
 
 Fix the breakage in rpc.yppasswd. Readded the svc_create() and
 the registering of the "unix" transport, now it is fixed.
 
 Everywhere, rq_cred is taken to look what authentification we have.
 We can not bu sure that transp>xp_verf.oa_flavor is also filled in.
 This seems to be the same for all sun source. they take the flavor
 of rq_cred, instead of transp.
 
 - transp>xp_verf.oa_flavor != AUTH_UNIX) {
 + rqstp->rq_cred.oa_flavor != AUTH_UNIX) {
 
 Please look at my other fix: local_transp_svc_vc.c.diff to have
 a better explanation.
 
 --- usr.sbin/rpc.yppasswdd/yppasswdd_main.c	Mon Mar 19 13:50:10 2001
 +++ usr.sbin/rpc.yppasswdd/yppasswdd_main.c	Thu Apr 19 13:55:29 2001
 @@ -100,8 +100,8 @@
  static void terminate(sig)
  	int sig;
  {
 -	svc_unregister(YPPASSWDPROG, YPPASSWDVERS);
 -	svc_unregister(MASTER_YPPASSWDPROG, MASTER_YPPASSWDVERS);
 +	rpcb_unset(YPPASSWDPROG, YPPASSWDVERS, NULL);
 +	rpcb_unset(MASTER_YPPASSWDPROG, MASTER_YPPASSWDVERS, NULL);
  	unlink(sockname);
  	exit(0);
  }
 @@ -156,13 +156,14 @@
  	char *argv[];
  {
  	register SVCXPRT *transp = NULL;
 -	int sock;
 -	int proto = 0;
  	struct sockaddr_in saddr;
  	int asize = sizeof (saddr);
 +	struct netconfig *nconf;
 +	void *localhandle;
  	int ch;
  	char *mastername;
  	char myname[MAXHOSTNAMELEN + 2];
 +
  	extern int debug;
 
  	debug = 1;
 @@ -246,78 +247,59 @@
 
  	if (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {
  		int ssize = sizeof (int);
 -
  		if (saddr.sin_family != AF_INET)
  			exit(1);
  		if (getsockopt(0, SOL_SOCKET, SO_TYPE,
 -				(char *)&_rpcfdtype, &ssize) == -1)
 +		    (char *)&_rpcfdtype, &ssize) == -1)
  			exit(1);
 -		sock = 0;
  		_rpcpmstart = 1;
 -		proto = 0;
 -		openlog("rpc.yppasswdd", LOG_PID, LOG_DAEMON);
 -	} else {
 -		if (!debug) {
 -			if (daemon(0,0)) {
 -				err(1,"cannot fork");
 -			}
 -		}
 -		openlog("rpc.yppasswdd", LOG_PID, LOG_DAEMON);
 -		sock = RPC_ANYSOCK;
 -		(void) pmap_unset(YPPASSWDPROG, YPPASSWDVERS);
 -		(void) pmap_unset(MASTER_YPPASSWDPROG, MASTER_YPPASSWDVERS);
 -		unlink(sockname);
 -	}
 -
 -	if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_DGRAM)) {
 -		transp = svcudp_create(sock);
 -		if (transp == NULL) {
 -			yp_error("cannot create udp service.");
 -			exit(1);
 -		}
 -		if (!_rpcpmstart)
 -			proto = IPPROTO_UDP;
 -		if (!svc_register(transp, YPPASSWDPROG, YPPASSWDVERS, yppasswdprog_1, proto)) {
 -			yp_error("unable to register (YPPASSWDPROG, YPPASSWDVERS, udp).");
 -			exit(1);
 -		}
  	}
 
 -	if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_STREAM)) {
 -		transp = svctcp_create(sock, 0, 0);
 -		if (transp == NULL) {
 -			yp_error("cannot create tcp service.");
 -			exit(1);
 -		}
 -		if (!_rpcpmstart)
 -			proto = IPPROTO_TCP;
 -		if (!svc_register(transp, YPPASSWDPROG, YPPASSWDVERS, yppasswdprog_1, proto)) {
 -			yp_error("unable to register (YPPASSWDPROG, YPPASSWDVERS, tcp).");
 -			exit(1);
 +	if (!debug && _rpcpmstart == 0) {
 +		if (daemon(0,0)) {
 +			err(1,"cannot fork");
  		}
  	}
 +	openlog("rpc.yppasswdd", LOG_PID, LOG_DAEMON);
 
 -	unlink(sockname);
 -        if (svc_create(yppasswdprog_1, YPPASSWDPROG, YPPASSWDVERS,
 -	    "netpath") == 0) {
 -                (void) fprintf(stderr,
 -                        "%s: unable to create service\n", argv[0]);
 -                exit(1);
 -        }
 -        if (svc_create(master_yppasswdprog_1, MASTER_YPPASSWDPROG,
 +	rpcb_unset(YPPASSWDPROG, YPPASSWDVERS, NULL);
 +	rpcb_unset(MASTER_YPPASSWDPROG, MASTER_YPPASSWDVERS, NULL);
 +
 +	if (svc_create(yppasswdprog_1, YPPASSWDPROG, YPPASSWDVERS, "netpath") == 0) {
 +		yp_error("cannot create yppasswd service.");
 +		exit(1);
 +	}
 +	if (svc_create(master_yppasswdprog_1, MASTER_YPPASSWDPROG,
  	    MASTER_YPPASSWDVERS, "netpath") == 0) {
 -                (void) fprintf(stderr,
 -                        "%s: unable to create service\n", argv[0]);
 -                exit(1);
 -        }
 +		yp_error("cannot create master_yppasswd service.");
 +		exit(1);
 +	}
 +
 +	nconf = NULL;
 +	localhandle = setnetconfig();
 +	while ((nconf = getnetconfig(localhandle)) != NULL) {
 +		if (nconf->nc_protofmly != NULL &&
 +		    strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0)
 +			break;
 +	}
 +	if (nconf == NULL) {
 +		yp_error("getnetconfigent unix: %s", nc_sperror());
 +		exit(1);
 +	}
 +	unlink(sockname);
 +	transp = svcunix_create(RPC_ANYSOCK, 0, 0, sockname);
  	if (transp == NULL) {
  		yp_error("cannot create AF_LOCAL service.");
  		exit(1);
  	}
 -	if (!svc_register(transp, MASTER_YPPASSWDPROG, MASTER_YPPASSWDVERS, master_yppasswdprog_1, 0)) {
 -		yp_error("unable to register (MASTER_YPPASSWDPROG, MASTER_YPPASSWDVERS, unix).");
 +	if (!svc_reg(transp, MASTER_YPPASSWDPROG, MASTER_YPPASSWDVERS,
 +	    master_yppasswdprog_1, nconf)) {
 +		yp_error("unable to register (MASTER_YPPASSWDPROG,
 +		    MASTER_YPPASSWDVERS, unix).");
  		exit(1);
  	}
 +	endnetconfig(localhandle);
 +
  	/* Only root may connect() to the AF_UNIX link. */
  	if (chmod(sockname, 0))
  		err(1, "chmod of %s failed", sockname);
 --- usr.sbin/rpc.yppasswdd/yppasswdd_server.c	Thu Mar 22 21:43:13 2001
 +++ usr.sbin/rpc.yppasswdd/yppasswdd_server.c	Wed Apr 18 18:54:22 2001
 @@ -62,11 +62,6 @@
  #include "yppasswd.h"
  #include "yppasswd_private.h"
 
 -struct cmessage {
 -        struct cmsghdr cmsg;
 -        struct cmsgcred cmcred;
 -};
 -
  char *tempname;
 
  void reaper(sig)
 @@ -705,47 +700,43 @@
  	static int result;
  	int pfd, tfd;
  	int pid;
 +	uid_t uid;
  	int rval = 0;
  	DBT key, data;
  	char *passfile_hold;
  	char passfile_buf[MAXPATHLEN + 2];
  	struct sockaddr_in *rqhost;
 -	struct cmessage			*cm;
 -	SVCXPRT				*transp;
 +	SVCXPRT	*transp;
 
  	result = 1;
 +	transp = rqstp->rq_xprt;
 
  	/*
  	 * NO AF_INET CONNETCIONS ALLOWED!
  	 */
 -	rqhost = svc_getcaller(rqstp->rq_xprt);
 +	rqhost = svc_getcaller(transp);
  	if (rqhost->sin_family != AF_UNIX) {
  		yp_error("Alert! %s/%d attempted to use superuser-only \
  procedure!\n", inet_ntoa(rqhost->sin_addr), rqhost->sin_port);
 -		svcerr_auth(rqstp->rq_xprt, AUTH_BADCRED);
 +		svcerr_auth(transp, AUTH_BADCRED);
  		return(&result);
  	}
 
 -	transp = rqstp->rq_xprt;
 -
 -	if (transp->xp_verf.oa_length < sizeof(struct cmessage) ||
 -		transp->xp_verf.oa_base == NULL ||
 -		transp->xp_verf.oa_flavor != AUTH_UNIX) {
 +	if (rqstp->rq_cred.oa_flavor != AUTH_SYS) {
  		yp_error("caller didn't send proper credentials");
 -		svcerr_auth(rqstp->rq_xprt, AUTH_BADCRED);
 +		svcerr_auth(transp, AUTH_BADCRED);
  		return(&result);
  	}
 
 -	cm = (struct cmessage *)transp->xp_verf.oa_base;
 -	if (cm->cmsg.cmsg_type != SCM_CREDS) {
 +	if (__rpc_get_local_uid(transp, &uid) < 0) {
  		yp_error("caller didn't send proper credentials");
 -		svcerr_auth(rqstp->rq_xprt, AUTH_BADCRED);
 +		svcerr_auth(transp, AUTH_BADCRED);
  		return(&result);
  	}
 -
 - 	if (cm->cmcred.cmcred_euid) {
 +
 +	if (uid) {
  		yp_error("caller euid is %d, expecting 0 -- rejecting request",
 -				cm->cmcred.cmcred_euid);
 +		    uid);
  		svcerr_auth(rqstp->rq_xprt, AUTH_BADCRED);
  		return(&result);
  	}
 
 Last modified:
 
 2001-10-06 02:00
 
 Changed files:
 
 usr.bin/chpass/pw_yp.c
 usr.bin/passwd/yp_passwd.c
 lib/libc/rpc/crypt_client.c
 usr.bin/rpcinfo/rpcinfo.c
 
 Commment:
 
 The clnt_create(KEYSERVSOCK, CRYPT_PROG, CRYPT_VERS, "unix") hacks were
 removed and replaced them with clnt_tp_create, now the af_local support is fixed.
 I also removed the hack how rpcinfo contacted rpcbind, now we can
 relay on clnt_tp_create create the client-handle for us.  Only rpcbind itself
 needs a hardcoded socket-path.
 
 Index: lib/libc/rpc/crypt_client.c
 ===================================================================
 RCS file: /usr/home/ncvs/src/lib/libc/rpc/crypt_client.c,v
 retrieving revision 1.5
 diff -u -r1.5 crypt_client.c
 --- lib/libc/rpc/crypt_client.c	19 Mar 2001 12:49:50 -0000	1.5
 +++ lib/libc/rpc/crypt_client.c	5 Oct 2001 23:47:51 -0000
 @@ -42,10 +42,6 @@
  static const char rcsid[] = "$FreeBSD: src/lib/libc/rpc/crypt_client.c,v 1.5 2001/03/19 12:49:50 alfred Exp $";
  #endif
 
 -#ifndef KEYSERVSOCK
 -#define KEYSERVSOCK "/var/run/keyservsock"
 -#endif
 -
  int
  _des_crypt_call(buf, len, dparms)
  	char *buf;
 @@ -55,12 +51,27 @@
  	CLIENT *clnt;
  	desresp  *result_1;
  	desargs  des_crypt_1_arg;
 -	int	stat;
 +	struct netconfig *nconf;
 +	void *localhandle;
 +	int stat;
 
 -	clnt = clnt_create(KEYSERVSOCK, CRYPT_PROG, CRYPT_VERS, "unix");
 +	nconf = NULL;
 +	localhandle = setnetconfig();
 +	while ((nconf = getnetconfig(localhandle)) != NULL) {
 +		if (nconf->nc_protofmly != NULL &&
 +		     strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0)
 +			break;
 +	}
 +	if (nconf == NULL) {
 +		warnx("getnetconfig: %s", nc_sperror());
 +		return(DESERR_HWERROR);
 +	}
 +	clnt = clnt_tp_create(NULL, CRYPT_PROG, CRYPT_VERS, nconf);
  	if (clnt == (CLIENT *) NULL) {
 +		endnetconfig(localhandle);
  		return(DESERR_HWERROR);
  	}
 +	endnetconfig(localhandle);
 
  	des_crypt_1_arg.desbuf.desbuf_len = len;
  	des_crypt_1_arg.desbuf.desbuf_val = buf;
 Index: usr.bin/chpass/pw_yp.c
 ===================================================================
 RCS file: /usr/home/ncvs/src/usr.bin/chpass/pw_yp.c,v
 retrieving revision 1.16
 diff -u -r1.16 pw_yp.c
 --- usr.bin/chpass/pw_yp.c	20 Oct 1999 15:20:00 -0000	1.16
 +++ usr.bin/chpass/pw_yp.c	5 Oct 2001 23:47:51 -0000
 @@ -354,7 +354,6 @@
  	char *mastername;
  	int rval, localport;
  	struct stat st;
 -	char			*sockname = YP_SOCKNAME;
 
  	/*
  	 * Sometimes we are called just to probe for rpc.yppasswdd and
 @@ -407,7 +406,7 @@
  	/* See if _we_ are the master server. */
  	if (!force_old && !getuid() && (localport = getrpcport("localhost",
  		YPPASSWDPROG, YPPASSWDPROC_UPDATE, IPPROTO_UDP)) != 0) {
 -		if (localport == rval && stat(sockname, &st) != -1) {
 +		if (localport == rval) {
  			suser_override = 1;
  			mastername = "localhost";
  		}
 @@ -433,12 +432,14 @@
  {
  	struct yppasswd yppasswd;
  	struct master_yppasswd master_yppasswd;
 +	struct netconfig *nconf;
 +	void *localhandle;
  	CLIENT *clnt;
  	char *master, *password;
  	int *status = NULL;
  	struct rpc_err err;
 -	char			*sockname = YP_SOCKNAME;
 
 +	nconf = NULL;
  	_use_yp = 1;
 
  	/* Get NIS master server name */
 @@ -490,13 +491,26 @@
 
  	if (suser_override) {
  		/* Talk to server via AF_UNIX socket. */
 -		clnt = clnt_create(sockname, MASTER_YPPASSWDPROG,
 -					MASTER_YPPASSWDVERS, "unix");
 +		localhandle = setnetconfig();
 +		while ((nconf = getnetconfig(localhandle)) != NULL) {
 +			if (nconf->nc_protofmly != NULL &&
 +			    strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0)
 +				break;
 +		}
 +		if (nconf == NULL) {
 +			warnx("getnetconfig: %s", nc_sperror());
 +			pw_error(tempname, 0, 1);
 +		}
 +
 +		clnt = clnt_tp_create(NULL, MASTER_YPPASSWDPROG,
 +		   MASTER_YPPASSWDVERS, nconf);
  		if (clnt == NULL) {
  			warnx("failed to contact rpc.yppasswdd: %s",
  				clnt_spcreateerror(master));
 +			endnetconfig(localhandle);
  			pw_error(tempname, 0, 1);
  		}
 +		endnetconfig(localhandle);
  	} else {
  		/* Create a handle to yppasswdd. */
 
 Index: usr.bin/passwd/yp_passwd.c
 ===================================================================
 RCS file: /usr/home/ncvs/src/usr.bin/passwd/yp_passwd.c,v
 retrieving revision 1.15
 diff -u -r1.15 yp_passwd.c
 --- usr.bin/passwd/yp_passwd.c	28 Sep 1997 08:51:02 -0000	1.15
 +++ usr.bin/passwd/yp_passwd.c	5 Oct 2001 23:47:51 -0000
 @@ -55,14 +55,16 @@
  {
  	struct yppasswd yppasswd;
  	struct master_yppasswd master_yppasswd;
 +	struct netconfig *nconf;
 +	void *localhandle;
  	struct passwd *pw;
  	CLIENT *clnt;
  	struct rpc_err err;
  	char   *master;
  	int    *status = NULL;
  	uid_t	uid;
 -	char			*sockname = YP_SOCKNAME;
 
 +	nconf = NULL;
  	_use_yp = 1;
 
  	uid = getuid();
 @@ -144,12 +146,24 @@
  	}
 
  	if (suser_override) {
 -		if ((clnt = clnt_create(sockname, MASTER_YPPASSWDPROG,
 -				MASTER_YPPASSWDVERS, "unix")) == NULL) {
 +		localhandle = setnetconfig();
 +		while ((nconf = getnetconfig(localhandle)) != NULL) {
 +			if (nconf->nc_protofmly != NULL &&
 +			    strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0)
 +				break;
 +		}
 +		if (nconf == NULL) {
 +			warnx("getnetconfig: %s", nc_sperror());
 +			return(1);
 +		}
 +		if ((clnt = clnt_tp_create(NULL, MASTER_YPPASSWDPROG,
 +		    MASTER_YPPASSWDVERS, nconf)) == NULL) {
  			warnx("failed to contact rpc.yppasswdd on host %s: %s",
  				master, clnt_spcreateerror(""));
 +			endnetconfig(localhandle);
  			return(1);
  		}
 +		endnetconfig(localhandle);
  	} else {
  		if ((clnt = clnt_create(master, YPPASSWDPROG,
  				YPPASSWDVERS, "udp")) == NULL) {
 Index: usr.bin/rpcinfo/rpcinfo.c
 ===================================================================
 RCS file: /usr/home/ncvs/src/usr.bin/rpcinfo/rpcinfo.c,v
 retrieving revision 1.11
 diff -u -r1.11 rpcinfo.c
 --- usr.bin/rpcinfo/rpcinfo.c	19 Mar 2001 12:50:04 -0000	1.11
 +++ usr.bin/rpcinfo/rpcinfo.c	5 Oct 2001 23:47:51 -0000
 @@ -321,22 +321,24 @@
  static CLIENT *
  local_rpcb(u_long prog, u_long vers)
  {
 -	struct netbuf nbuf;
 -	struct sockaddr_un sun;
 -	int sock;
 +	void *localhandle;
 +	struct netconfig *nconf;
 +	CLIENT *clnt;
 
 -	memset(&sun, 0, sizeof sun);
 -	sock = socket(AF_LOCAL, SOCK_STREAM, 0);
 -	if (sock < 0)
 -		return NULL;
 +	localhandle = setnetconfig();
 +	while ((nconf = getnetconfig(localhandle)) != NULL) {
 +		if (nconf->nc_protofmly != NULL &&
 +		    strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0)
 +			break;
 +	}
 +	if (nconf == NULL) {
 +		warnx("getnetconfig: %s", nc_sperror());
 +		return (NULL);
 +	}
 
 -	sun.sun_family = AF_LOCAL;
 -	strcpy(sun.sun_path, _PATH_RPCBINDSOCK);
 -	nbuf.len = sun.sun_len = SUN_LEN(&sun);
 -	nbuf.maxlen = sizeof (struct sockaddr_un);
 -	nbuf.buf = &sun;
 -
 -	return clnt_vc_create(sock, &nbuf, prog, vers, 0, 0);
 +	clnt = clnt_tp_create(NULL, prog, vers, nconf);
 +	endnetconfig(localhandle);
 +	return clnt;
  }
 
  #ifdef PORTMAP
 
 Do not call addrinfo on local transport adresses, if returning a
 server handle (for reuse or whatever). We just return now a handle
 connected to the local rpcbind.
 
 Do not try to call checkcache, if host = NULL;
 
 For the local transport, fill in the adress of rpcbind.
 
 --- lib/libc/rpc/rpcb_clnt.c	Mon Apr  2 23:41:43 2001
 +++ lib/libc/rpc/rpcb_clnt.c	Sat Apr 21 12:54:25 2001
 @@ -300,7 +300,9 @@
  	/* Get the address of the rpcbind.  Check cache first */
  	addr_to_delete.len = 0;
  	rwlock_rdlock(&rpcbaddr_cache_lock);
 -	ad_cache = check_cache(host, nconf->nc_netid);
 +	ad_cache = NULL;
 +	if (host != NULL)
 +		ad_cache = check_cache(host, nconf->nc_netid);
  	if (ad_cache != NULL) {
  		addr = ad_cache->ac_taddr;
  		client = clnt_tli_create(RPC_ANYFD, nconf, addr,
 @@ -345,9 +347,26 @@
  	    nconf->nc_netid, si.si_af, si.si_proto, si.si_socktype);
  #endif
 
 -	if (getaddrinfo(host, "sunrpc", &hints, &res) != 0) {
 -		rpc_createerr.cf_stat = RPC_UNKNOWNHOST;
 -		return NULL;
 +	if (nconf->nc_protofmly != NULL && strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) {
 +		client = local_rpcb();
 +		if (! client) {
 +#ifdef ND_DEBUG
 +			clnt_pcreateerror("rpcbind clnt interface");
 +#endif
 +			return (NULL);
 +		} else {
 +			struct sockaddr_un sun;
 +
 +			*targaddr = malloc(sizeof(sun.sun_path));
 +			strncpy(*targaddr, _PATH_RPCBINDSOCK,
 +			    sizeof(sun.sun_path));
 +			return (client);
 +		}
 +	} else {
 +		if (getaddrinfo(host, "sunrpc", &hints, &res) != 0) {
 +			rpc_createerr.cf_stat = RPC_UNKNOWNHOST;
 +			return NULL;
 +		}
  	}
 
  	for (tres = res; tres != NULL; tres = tres->ai_next) {
 @@ -392,7 +411,8 @@
  			break;
  		}
  	}
 -	freeaddrinfo(res);
 +	if (res)
 +		freeaddrinfo(res);
  	return (client);
  }
 
 lib/libc/rpc/svc_vc.c
 
 Finally fix the credential stuff. I had to look at the code a long long
 time before I've seen what exactly was the breakage.
 
 In NetBSD, Solaris, xprt->xp_p2 pointed directly to the credentials,
 in FreeBSD xprt->xp_verf.oa_base was a pointer to a struct cmessage,
 which is defined as follow:
 
 struct cmessage {
         struct cmsghdr cmsg;
         struct cmsgcred cmcred;
 };
 
 The credentials were submitted the right way and xprt->xp_p2 pointed to them.
 But cb_verf.oa_flavor was still empty. There was an assignment missing
 in svc_recv() in svc_vc.c:
 
 msg->rm_call.cb_verf.oa_flavor = AUTH_UNIX;
 
 Also
 
 +       if (addr.ss_family == AF_LOCAL) {
 +               xprt->xp_raddr = *(struct sockaddr_in *)xprt->xp_rtaddr.buf;
 +               xprt->xp_addrlen = sizeof (struct sockaddr_in);
 +       }
 
 was missing. But the first seems not to be needed:
 
 I guess in rpc.yppasswdd there was a typo:
 
 - transp>xp_verf.oa_flavor != AUTH_UNIX) {
 + rqstp->rq_cred.oa_flavor != AUTH_UNIX) {
 
 This little fix does fix the breakage in rpc.yppasswdd :-)
 
 +       if (msg.msg_controllen == 0 ||
 +           (msg.msg_flags & MSG_CTRUNC) != 0)
 +               return (-1);
 
 We cannot set the cb_verf.oa_length in svc_recv() of svc_vc.c, the credentials
 get overwritten then, and that's bad.
 
 diff -ruN lib/libc/rpc/svc_vc.c lib/libc/rpc/svc_vc.c
 --- lib/libc/rpc/svc_vc.c.orig	Thu Oct  4 15:11:41 2001
 +++ lib/libc/rpc/svc_vc.c	Thu Oct  4 20:55:17 2001
 @@ -313,6 +313,10 @@
  		return (FALSE);
  	memcpy(xprt->xp_rtaddr.buf, &addr, len);
  	xprt->xp_rtaddr.len = len;
 +	if (addr.ss_family == AF_LOCAL) {
 +		xprt->xp_raddr = *(struct sockaddr_in *)xprt->xp_rtaddr.buf;
 +		xprt->xp_addrlen = sizeof (struct sockaddr_in);
 +	}
  #ifdef PORTMAP
  	if (addr.ss_family == AF_INET) {
  		xprt->xp_raddr = *(struct sockaddr_in *)xprt->xp_rtaddr.buf;
 @@ -423,13 +427,15 @@
  		}
  	} while ((pollfd.revents & POLLIN) == 0);
 
 +	cm = NULL;
  	sa = (struct sockaddr *)xprt->xp_rtaddr.buf;
  	if (sa->sa_family == AF_LOCAL) {
  		cm = (struct cmessage *)xprt->xp_verf.oa_base;
  		if ((len = __msgread_withcred(sock, buf, len, cm)) > 0) {
  			xprt->xp_p2 = &cm->cmcred;
  			return (len);
 -		}
 +		} else
 +			goto fatal_err;
  	} else {
  		if ((len = _read(sock, buf, (size_t)len)) > 0)
  			return (len);
 @@ -656,7 +663,12 @@
  	ret = _recvmsg(sock, &msg, 0);
  	bcopy(&cm.cmsg, &cmp->cmsg, sizeof(cmp->cmsg));
  	bcopy(CMSG_DATA(&cm), &cmp->cmcred, sizeof(cmp->cmcred));
 -	return ret;
 +
 +	if (msg.msg_controllen == 0 ||
 +	   (msg.msg_flags & MSG_CTRUNC) != 0)
 +		return (-1);
 +
 +	return (ret);
  }
 
  static int
 @@ -696,10 +708,21 @@
  __rpc_get_local_uid(SVCXPRT *transp, uid_t *uid)
  {
  	struct cmsgcred *cmcred;
 +	struct cmessage *cm;
 +	struct cmsghdr *cmp;
 +
 +	cm = (struct cmessage *)transp->xp_verf.oa_base;
 +
 +	if (cm == NULL)
 +		return (-1);
 +	cmp = &cm->cmsg;
 +	if (cmp == NULL || cmp->cmsg_level != SOL_SOCKET ||
 +	   cmp->cmsg_type != SCM_CREDS)
 +		return (-1);
 
  	cmcred = __svc_getcallercreds(transp);
  	if (cmcred == NULL)
 -		return(-1);
 +		return (-1);
  	*uid = cmcred->cmcred_euid;
 -	return(0);
 +	return (0);
  }
 

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200110070040.f970e1P30686>