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
2f7aab1c26
commit
4ed6d63483
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=74627
@ -110,12 +110,6 @@ struct ct_data {
|
|||||||
XDR ct_xdrs; /* XDR stream */
|
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
|
* This machinery implements per-fd locks for MT-safety. It is not
|
||||||
* sufficient to do per-CLIENT handle locks for MT-safety because a
|
* 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);
|
t->tv_usec <= -1 || t->tv_usec > 1000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
__msgread(sock, buf, cnt)
|
__msgread(sock, buf, cnt)
|
||||||
int sock;
|
int sock;
|
||||||
void *buf;
|
void *buf;
|
||||||
@ -808,7 +803,7 @@ __msgread(sock, buf, cnt)
|
|||||||
|
|
||||||
return(_recvmsg(sock, &msg, 0));
|
return(_recvmsg(sock, &msg, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
__msgwrite(sock, buf, cnt)
|
__msgwrite(sock, buf, cnt)
|
||||||
int sock;
|
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_rendezvous_ops __P((SVCXPRT *));
|
||||||
static void svc_vc_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 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 __msgwrite(int, void *, size_t);
|
||||||
static int __msgread(int, void *, size_t);
|
|
||||||
|
|
||||||
struct cf_rendezvous { /* kept in xprt->xp_p1 for rendezvouser */
|
struct cf_rendezvous { /* kept in xprt->xp_p1 for rendezvouser */
|
||||||
u_int sendsize;
|
u_int sendsize;
|
||||||
@ -100,12 +100,6 @@ struct cf_conn { /* kept in xprt->xp_p1 for actual connection */
|
|||||||
char verf_body[MAX_AUTH_BYTES];
|
char verf_body[MAX_AUTH_BYTES];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cmessage {
|
|
||||||
struct cmsghdr cmsg;
|
|
||||||
struct cmsgcred cmcred;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Usage:
|
* Usage:
|
||||||
* xprt = svc_vc_create(sock, send_buf_size, recv_buf_size);
|
* xprt = svc_vc_create(sock, send_buf_size, recv_buf_size);
|
||||||
@ -421,17 +415,18 @@ read_vc(xprtp, buf, len)
|
|||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
/*FALLTHROUGH*/
|
/*FALLTHROUGH*/
|
||||||
case 0:
|
case 0:
|
||||||
goto fatal_err;
|
goto fatal_err;
|
||||||
default:
|
|
||||||
break;
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} while ((pollfd.revents & POLLIN) == 0);
|
} while ((pollfd.revents & POLLIN) == 0);
|
||||||
|
|
||||||
sa = (struct sockaddr *)xprt->xp_rtaddr.buf;
|
sa = (struct sockaddr *)xprt->xp_rtaddr.buf;
|
||||||
if (sa->sa_family == AF_LOCAL) {
|
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;
|
cmp = &cm->cmsg;
|
||||||
sc = (struct sockcred *)(void *)CMSG_DATA(cmp);
|
sc = (struct sockcred *)(void *)CMSG_DATA(cmp);
|
||||||
xprt->xp_p2 = sc;
|
xprt->xp_p2 = sc;
|
||||||
@ -632,17 +627,17 @@ svc_vc_rendezvous_ops(xprt)
|
|||||||
mutex_unlock(&ops_lock);
|
mutex_unlock(&ops_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
__msgread(sock, buf, cnt)
|
__msgread_withcred(sock, buf, cnt, cmp)
|
||||||
int sock;
|
int sock;
|
||||||
void *buf;
|
void *buf;
|
||||||
size_t cnt;
|
size_t cnt;
|
||||||
|
struct cmessage *cmp;
|
||||||
{
|
{
|
||||||
struct iovec iov[1];
|
struct iovec iov[1];
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
struct cmessage cm;
|
|
||||||
|
|
||||||
bzero((char *)&cm, sizeof(cm));
|
bzero(cmp, sizeof(*cmp));
|
||||||
iov[0].iov_base = buf;
|
iov[0].iov_base = buf;
|
||||||
iov[0].iov_len = cnt;
|
iov[0].iov_len = cnt;
|
||||||
|
|
||||||
@ -650,13 +645,13 @@ __msgread(sock, buf, cnt)
|
|||||||
msg.msg_iovlen = 1;
|
msg.msg_iovlen = 1;
|
||||||
msg.msg_name = NULL;
|
msg.msg_name = NULL;
|
||||||
msg.msg_namelen = 0;
|
msg.msg_namelen = 0;
|
||||||
msg.msg_control = (caddr_t)&cm;
|
msg.msg_control = cmp;
|
||||||
msg.msg_controllen = sizeof(struct cmessage);
|
msg.msg_controllen = sizeof(struct cmessage);
|
||||||
msg.msg_flags = 0;
|
msg.msg_flags = 0;
|
||||||
|
|
||||||
return(_recvmsg(sock, &msg, 0));
|
return(_recvmsg(sock, &msg, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
__msgwrite(sock, buf, cnt)
|
__msgwrite(sock, buf, cnt)
|
||||||
int sock;
|
int sock;
|
||||||
@ -685,3 +680,19 @@ __msgwrite(sock, buf, cnt)
|
|||||||
|
|
||||||
return(_sendmsg(sock, &msg, 0));
|
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 */
|
gid_t cmcred_groups[CMGROUP_MAX]; /* groups */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct cmessage {
|
||||||
|
struct cmsghdr cmsg;
|
||||||
|
struct cmsgcred cmcred;
|
||||||
|
};
|
||||||
|
|
||||||
/* given pointer to struct cmsghdr, return pointer to data */
|
/* given pointer to struct cmsghdr, return pointer to data */
|
||||||
#define CMSG_DATA(cmsg) ((u_char *)(cmsg) + \
|
#define CMSG_DATA(cmsg) ((u_char *)(cmsg) + \
|
||||||
_ALIGN(sizeof(struct cmsghdr)))
|
_ALIGN(sizeof(struct cmsghdr)))
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
|
|
||||||
PROG= keyserv
|
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.
|
CFLAGS+= -DKEYSERV_RANDOM -DBROKEN_DES -I.
|
||||||
.if $(OBJFORMAT) == elf
|
.if $(OBJFORMAT) == elf
|
||||||
|
@ -741,7 +741,7 @@ root_auth(trans, rqstp)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__rpc_get_local_uid(&uid, trans) < 0) {
|
if (__rpc_get_local_uid(trans, &uid) < 0) {
|
||||||
if (debugging)
|
if (debugging)
|
||||||
fprintf(stderr, "__rpc_get_local_uid failed\n");
|
fprintf(stderr, "__rpc_get_local_uid failed\n");
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
/*
|
||||||
|
* $FreeBSD$
|
||||||
|
*/
|
||||||
extern void setmodulus __P((char *modx));
|
extern void setmodulus __P((char *modx));
|
||||||
|
|
||||||
extern keystatus pk_setkey __P(( uid_t, keybuf ));;
|
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 keystatus pk_get_conv_key __P(( uid_t, keybuf, cryptkeyres * ));
|
||||||
extern void pk_nodefaultkeys __P(( void ));
|
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 crypt_prog_1 __P(( struct svc_req *, register SVCXPRT * ));
|
||||||
extern void load_des __P(( int, char * ));
|
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;
|
RPCB rpcbreg;
|
||||||
long ans;
|
long ans;
|
||||||
struct sockaddr_in *who;
|
struct sockaddr_in *who;
|
||||||
struct cmsgcred *cmcred;
|
uid_t uid;
|
||||||
char uidbuf[32];
|
char uidbuf[32];
|
||||||
|
|
||||||
#ifdef RPCBIND_DEBUG
|
#ifdef RPCBIND_DEBUG
|
||||||
@ -194,19 +194,18 @@ pmapproc_change(struct svc_req *rqstp, SVCXPRT *xprt, unsigned long op)
|
|||||||
}
|
}
|
||||||
|
|
||||||
who = svc_getcaller(xprt);
|
who = svc_getcaller(xprt);
|
||||||
cmcred = __svc_getcallercreds(xprt);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Can't use getpwnam here. We might end up calling ourselves
|
* Can't use getpwnam here. We might end up calling ourselves
|
||||||
* and looping.
|
* and looping.
|
||||||
*/
|
*/
|
||||||
if (cmcred == NULL)
|
if (__rpc_get_local_uid(xprt, &uid) < 0)
|
||||||
rpcbreg.r_owner = "unknown";
|
rpcbreg.r_owner = "unknown";
|
||||||
else if (cmcred->cmcred_uid == 0)
|
else if (uid == 0)
|
||||||
rpcbreg.r_owner = "superuser";
|
rpcbreg.r_owner = "superuser";
|
||||||
else {
|
else {
|
||||||
/* r_owner will be strdup-ed later */
|
/* 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;
|
rpcbreg.r_owner = uidbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1348,15 +1348,14 @@ find_service(rpcprog_t prog, rpcvers_t vers, char *netid)
|
|||||||
static char *
|
static char *
|
||||||
getowner(SVCXPRT *transp, char *owner, size_t ownersize)
|
getowner(SVCXPRT *transp, char *owner, size_t ownersize)
|
||||||
{
|
{
|
||||||
struct cmsgcred *cmcred;
|
uid_t uid;
|
||||||
|
|
||||||
cmcred = __svc_getcallercreds(transp);
|
if (__rpc_get_local_uid(transp, &uid) < 0)
|
||||||
if (cmcred == NULL)
|
strlcpy(owner, "unknown", ownersize);
|
||||||
strlcpy(owner, "unknown", ownersize);
|
else if (uid == 0)
|
||||||
else if (cmcred->cmcred_uid == 0)
|
|
||||||
strlcpy(owner, "superuser", ownersize);
|
strlcpy(owner, "superuser", ownersize);
|
||||||
else
|
else
|
||||||
snprintf(owner, ownersize, "%d", cmcred->cmcred_uid);
|
snprintf(owner, ownersize, "%d", uid);
|
||||||
|
|
||||||
return owner;
|
return owner;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user