| Summary: | [PATCH] keyserv and rpc.yppasswd | ||
|---|---|---|---|
| Product: | Base System | Reporter: | mb <mb> |
| Component: | bin | Assignee: | freebsd-bugs (Nobody) <bugs> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 5.0-CURRENT | ||
| Hardware: | Any | ||
| OS: | Any | ||
|
Description
mb
2001-07-23 22:00:01 UTC
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. 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 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 Alfred comitted my fixes. Thanks |