Hopefully fix some of the bugs in passing credentials over UNIX domain sockets.

Make struct cmessage visible from socket.h (about 4 places were
defining it for themselves which wasn't good)

Make __rpc_get_local_uid() useable and give it prototype that's
visible.

Fix some issues with printing out usernames from rpcbind and keyserv.
This commit is contained in:
alfred 2001-03-22 04:31:30 +00:00
parent 8da2bcdcda
commit 1d6a205da2
9 changed files with 52 additions and 118 deletions

View File

@ -110,12 +110,6 @@ struct ct_data {
XDR ct_xdrs; /* XDR stream */
};
struct cmessage {
struct cmsghdr cmsg;
struct cmsgcred cmcred;
};
/*
* This machinery implements per-fd locks for MT-safety. It is not
* sufficient to do per-CLIENT handle locks for MT-safety because a
@ -785,6 +779,7 @@ time_not_ok(t)
t->tv_usec <= -1 || t->tv_usec > 1000000);
}
static int
__msgread(sock, buf, cnt)
int sock;
void *buf;
@ -808,7 +803,7 @@ __msgread(sock, buf, cnt)
return(_recvmsg(sock, &msg, 0));
}
static int
__msgwrite(sock, buf, cnt)
int sock;

View File

@ -85,8 +85,8 @@ static bool_t svc_vc_reply __P((SVCXPRT *, struct rpc_msg *));
static void svc_vc_rendezvous_ops __P((SVCXPRT *));
static void svc_vc_ops __P((SVCXPRT *));
static bool_t svc_vc_control __P((SVCXPRT *xprt, const u_int rq, void *in));
static int __msgread_withcred(int, void *, size_t, struct cmessage *);
static int __msgwrite(int, void *, size_t);
static int __msgread(int, void *, size_t);
struct cf_rendezvous { /* kept in xprt->xp_p1 for rendezvouser */
u_int sendsize;
@ -100,12 +100,6 @@ struct cf_conn { /* kept in xprt->xp_p1 for actual connection */
char verf_body[MAX_AUTH_BYTES];
};
struct cmessage {
struct cmsghdr cmsg;
struct cmsgcred cmcred;
};
/*
* Usage:
* xprt = svc_vc_create(sock, send_buf_size, recv_buf_size);
@ -421,17 +415,18 @@ read_vc(xprtp, buf, len)
if (errno == EINTR)
continue;
/*FALLTHROUGH*/
case 0:
goto fatal_err;
default:
break;
case 0:
goto fatal_err;
default:
break;
}
} while ((pollfd.revents & POLLIN) == 0);
sa = (struct sockaddr *)xprt->xp_rtaddr.buf;
if (sa->sa_family == AF_LOCAL) {
if ((len = __msgread(sock, buf, len)) > 0) {
cm = (struct cmessage *)xprt->xp_verf.oa_base;
cm = (struct cmessage *)xprt->xp_verf.oa_base;
if ((len = __msgread_withcred(sock, buf, len, cm)) > 0) {
cmp = &cm->cmsg;
sc = (struct sockcred *)(void *)CMSG_DATA(cmp);
xprt->xp_p2 = sc;
@ -632,17 +627,17 @@ svc_vc_rendezvous_ops(xprt)
mutex_unlock(&ops_lock);
}
static int
__msgread(sock, buf, cnt)
int
__msgread_withcred(sock, buf, cnt, cmp)
int sock;
void *buf;
size_t cnt;
struct cmessage *cmp;
{
struct iovec iov[1];
struct msghdr msg;
struct cmessage cm;
bzero((char *)&cm, sizeof(cm));
bzero(cmp, sizeof(*cmp));
iov[0].iov_base = buf;
iov[0].iov_len = cnt;
@ -650,13 +645,13 @@ __msgread(sock, buf, cnt)
msg.msg_iovlen = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = (caddr_t)&cm;
msg.msg_control = cmp;
msg.msg_controllen = sizeof(struct cmessage);
msg.msg_flags = 0;
return(_recvmsg(sock, &msg, 0));
}
static int
__msgwrite(sock, buf, cnt)
int sock;
@ -685,3 +680,19 @@ __msgwrite(sock, buf, cnt)
return(_sendmsg(sock, &msg, 0));
}
/*
* Get the effective UID of the sending process. Used by rpcbind and keyserv
* (AF_LOCAL).
*/
int
__rpc_get_local_uid(SVCXPRT *transp, uid_t *uid)
{
struct cmsgcred *cmcred;
cmcred = __svc_getcallercreds(transp);
if (cmcred == NULL)
return(-1);
*uid = cmcred->cmcred_euid;
return(0);
}

View File

@ -364,6 +364,11 @@ struct cmsgcred {
gid_t cmcred_groups[CMGROUP_MAX]; /* groups */
};
struct cmessage {
struct cmsghdr cmsg;
struct cmsgcred cmcred;
};
/* given pointer to struct cmsghdr, return pointer to data */
#define CMSG_DATA(cmsg) ((u_char *)(cmsg) + \
_ALIGN(sizeof(struct cmsghdr)))

View File

@ -1,7 +1,7 @@
# $FreeBSD$
PROG= keyserv
SRCS= keyserv.c setkey.c keyserv_uid.c crypt_svc.c crypt_server.c crypt.h
SRCS= keyserv.c setkey.c crypt_svc.c crypt_server.c crypt.h
CFLAGS+= -DKEYSERV_RANDOM -DBROKEN_DES -I.
.if $(OBJFORMAT) == elf

View File

@ -741,7 +741,7 @@ root_auth(trans, rqstp)
return (0);
}
if (__rpc_get_local_uid(&uid, trans) < 0) {
if (__rpc_get_local_uid(trans, &uid) < 0) {
if (debugging)
fprintf(stderr, "__rpc_get_local_uid failed\n");
return (0);

View File

@ -1,4 +1,6 @@
/*
* $FreeBSD$
*/
extern void setmodulus __P((char *modx));
extern keystatus pk_setkey __P(( uid_t, keybuf ));;
@ -9,7 +11,6 @@ extern keystatus pk_netget __P(( uid_t, key_netstarg * ));
extern keystatus pk_get_conv_key __P(( uid_t, keybuf, cryptkeyres * ));
extern void pk_nodefaultkeys __P(( void ));
extern int __rpc_get_local_uid __P(( uid_t * , SVCXPRT * ));
extern void crypt_prog_1 __P(( struct svc_req *, register SVCXPRT * ));
extern void load_des __P(( int, char * ));

View File

@ -1,76 +0,0 @@
/*
* 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.
*/
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <rpc/key_prot.h>
#include <rpc/des.h>
#include <sys/socket.h>
#include <sys/param.h>
#include "keyserv.h"
#ifndef lint
static const char rcsid[] =
"$FreeBSD$";
#endif
/*
* XXX should be declared somewhere
*/
struct cmessage {
struct cmsghdr cmsg;
struct cmsgcred cmcred;
};
int
__rpc_get_local_uid(uid, transp)
uid_t *uid;
SVCXPRT *transp;
{
struct cmessage *cm;
if (transp->xp_verf.oa_length < sizeof(struct cmessage) ||
transp->xp_verf.oa_base == NULL ||
transp->xp_verf.oa_flavor != AUTH_UNIX)
return(-1);
cm = (struct cmessage *)transp->xp_verf.oa_base;
if (cm->cmsg.cmsg_type != SCM_CREDS)
return(-1);
*uid = cm->cmcred.cmcred_euid;
return(0);
}

View File

@ -173,7 +173,7 @@ pmapproc_change(struct svc_req *rqstp, SVCXPRT *xprt, unsigned long op)
RPCB rpcbreg;
long ans;
struct sockaddr_in *who;
struct cmsgcred *cmcred;
uid_t uid;
char uidbuf[32];
#ifdef RPCBIND_DEBUG
@ -194,19 +194,18 @@ pmapproc_change(struct svc_req *rqstp, SVCXPRT *xprt, unsigned long op)
}
who = svc_getcaller(xprt);
cmcred = __svc_getcallercreds(xprt);
/*
* Can't use getpwnam here. We might end up calling ourselves
* and looping.
*/
if (cmcred == NULL)
if (__rpc_get_local_uid(xprt, &uid) < 0)
rpcbreg.r_owner = "unknown";
else if (cmcred->cmcred_uid == 0)
else if (uid == 0)
rpcbreg.r_owner = "superuser";
else {
/* r_owner will be strdup-ed later */
snprintf(uidbuf, sizeof uidbuf, "%d", cmcred->cmcred_uid);
snprintf(uidbuf, sizeof uidbuf, "%d", uid);
rpcbreg.r_owner = uidbuf;
}

View File

@ -1348,15 +1348,14 @@ find_service(rpcprog_t prog, rpcvers_t vers, char *netid)
static char *
getowner(SVCXPRT *transp, char *owner, size_t ownersize)
{
struct cmsgcred *cmcred;
cmcred = __svc_getcallercreds(transp);
if (cmcred == NULL)
strlcpy(owner, "unknown", ownersize);
else if (cmcred->cmcred_uid == 0)
uid_t uid;
if (__rpc_get_local_uid(transp, &uid) < 0)
strlcpy(owner, "unknown", ownersize);
else if (uid == 0)
strlcpy(owner, "superuser", ownersize);
else
snprintf(owner, ownersize, "%d", cmcred->cmcred_uid);
snprintf(owner, ownersize, "%d", uid);
return owner;
}