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:
parent
8da2bcdcda
commit
1d6a205da2
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)))
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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 * ));
|
||||
|
||||
|
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user