From mb@fuchur.lan.attic.ch  Mon Jul 23 13:52:30 2001
Return-Path: <mb@fuchur.lan.attic.ch>
Received: from fuchur.lan.attic.ch (fuchur.lan.attic.ch [194.235.47.21])
	by hub.freebsd.org (Postfix) with ESMTP id 287A437B403
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 23 Jul 2001 13:52:28 -0700 (PDT)
	(envelope-from mb@fuchur.lan.attic.ch)
Received: (from mb@localhost)
	by fuchur.lan.attic.ch (8.11.4/8.11.4) id f6NKvMq01699;
	Mon, 23 Jul 2001 22:57:22 +0200 (CEST)
	(envelope-from mb)
Message-Id: <200107232057.f6NKvMq01699@fuchur.lan.attic.ch>
Date: Mon, 23 Jul 2001 22:57:22 +0200 (CEST)
From: Martin Blapp <mb@imp.ch>
Reply-To: Martin Blapp <mb@imp.ch>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [PATCH] keyserv and rpc.yppasswd
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         29171
>Category:       bin
>Synopsis:       [PATCH] keyserv and rpc.yppasswd
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jul 23 14:00:01 PDT 2001
>Closed-Date:    Sat Feb 9 12:41:27 PST 2002
>Last-Modified:  Sat Feb 09 12:41:57 PST 2002
>Originator:     Martin Blapp
>Release:        FreeBSD 5.0-CURRENT i386
>Organization:
Improware AG
>Environment:
System: FreeBSD fuchur.lan.attic.ch 5.0-CURRENT FreeBSD 5.0-CURRENT #0: Sat Jun 30 19:49:42 CEST 2001 root@fuchur.lan.attic.ch:/usr/obj/usr/src/sys/FUCHUR2 i386

>Description:

Local AF-LOCAL support is currently broken in CURRENT since 3 month. I post
the URL's here so the patches don't get lost.

>How-To-Repeat:

Use yppasswd as root to change a users password on the ypserver itself.
Normally you shouln't be asked for the old password. With these fixes, the
old behaviour works again.

>Fix:

Add my patches:

http://home.teleport.ch/freebsd/userland/keyserv.diff
http://home.teleport.ch/freebsd/userland/rpc.yppasswdd.diff

http://home.teleport.ch/freebsd/userland/local_transp_clnt_create.diff
http://home.teleport.ch/freebsd/userland/local_transp_compat.diff
http://home.teleport.ch/freebsd/userland/local_transp_getaddrinfo-fix.diff
>Release-Note:
>Audit-Trail:

From: Dima Dorfman <dima@unixfreak.org>
To: Martin Blapp <mb@imp.ch>
Cc: FreeBSD-gnats-submit@freebsd.org
Subject: Re: bin/29171: [PATCH] keyserv and rpc.yppasswd 
Date: Mon, 23 Jul 2001 22:34:47 -0700

 Martin Blapp <mb@imp.ch> writes:
 > >Description:
 > 
 > [...] I post
 > the URL's here so the patches don't get lost.
 
 It would be better if you also attached the actual patches to your PRs
 so that somebody looking at this PR in three years, after you've
 removed them from your web server or the latter is no longer
 available, would have access to them.  The PR database should be a
 self-contained as possible.
 
 Thanks.

From: Martin =?iso-8859-1?Q?Blapp=FC?= <mb@imp.ch>
To: freebsd-gnats-submit@FreeBSD.org, mb@imp.ch
Cc:  
Subject: Re: bin/29171: [PATCH] keyserv and rpc.yppasswd
Date: Thu, 04 Oct 2001 23:13:52 +0200

 Hi,
 
 I just updated my patches to the latest CURRENT.
 
 Unfortunatly this patchset is still outstanding and should be reviewed
 and comitted.
 
 Also the following patch should be comitted, cause it fixes a additional
 part:
 
 http://home.teleport.ch/freebsd/userland/local_transp_svc_vc.c.diff
 
 Everything is commented inside the patches ...
 
 Martin
 

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);
  }
 
State-Changed-From-To: open->closed 
State-Changed-By: mbr 
State-Changed-When: Sat Feb 9 12:41:27 PST 2002 
State-Changed-Why:  
Alfred comitted my fixes. Thanks 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=29171 
>Unformatted:
