From a8c5ada654f0ff7b7c8bb9542fcae9c4a917f353 Mon Sep 17 00:00:00 2001 From: fredrik Date: Tue, 29 May 2007 15:01:40 +0000 Subject: [PATCH] Add Linux/BSD switch for Unix auth. git-svn-id: svn+ssh://svn.dolda2000.com/srv/svn/repos/src/doldaconnect@1046 959494ce-11ee-0310-bf91-de5d638817bd --- configure.in | 15 +++++++++++++++ daemon/auth-unix.c | 6 +++--- daemon/net.c | 21 +++++++++++++++++---- daemon/net.h | 6 +++++- lib/uilib.c | 4 ++++ 5 files changed, 44 insertions(+), 8 deletions(-) diff --git a/configure.in b/configure.in index 6d8ed05..691b9e2 100644 --- a/configure.in +++ b/configure.in @@ -216,6 +216,21 @@ AH_TEMPLATE(HAVE_KEYUTILS, [define if your system supports the Linux keyring fun AC_CHECK_LIB(keyutils, keyctl_search, [ AC_DEFINE(HAVE_KEYUTILS) LDFLAGS="$LDFLAGS -lkeyutils" ]) +# Unix credentials selector +AH_TEMPLATE(UNIX_AUTH_STYLE, [undefine for no Unix auth, 1 for Linux style, 2 for BSD style]) +AC_CHECK_MEMBER(struct ucred.pid, [ linuxcreds=y ], [ linuxcreds=n ], [#include ]) +AC_CHECK_FUNC(getpeereid, [ bsdcreds=y ], [ bsdcreds=n ]) +AC_MSG_CHECKING([for Unix auth style]) +if test $linuxcreds = y; then + AC_DEFINE(UNIX_AUTH_STYLE, 1) + AC_MSG_RESULT(linux) +elif test $bsdcreds = y; then + AC_DEFINE(UNIX_AUTH_STYLE, 2) + AC_MSG_RESULT(bsd) +else + AC_MSG_RESULT(none) +fi + AC_HEADER_STDC AC_HEADER_DIRENT AC_HEADER_SYS_WAIT diff --git a/daemon/auth-unix.c b/daemon/auth-unix.c index 9707bfd..47a1c24 100644 --- a/daemon/auth-unix.c +++ b/daemon/auth-unix.c @@ -63,12 +63,12 @@ static int unixauth(struct authhandle *auth, struct socket *sk, char *passdata) data = auth->mechdata; if((pwd = getpwnam(data->username)) == NULL) return(AUTH_ERR); - if(sk->ucred.pid == 0) { + if(sk->ucred.uid == -1) { errno = EBADE; return(AUTH_ERR); } if(pwd->pw_uid == sk->ucred.uid) { - flog(LOG_INFO, "process %i successfully authenticated as %s with Unix credentials (uid=%i, gid=%i)", sk->ucred.pid, data->username, sk->ucred.uid, sk->ucred.gid); + flog(LOG_INFO, "successful authentication as %s with Unix credentials (uid=%i, gid=%i)", data->username, sk->ucred.uid, sk->ucred.gid); return(AUTH_SUCCESS); } auth->text = swcsdup(L"Unix credentials do not match supplied user name"); @@ -77,7 +77,7 @@ static int unixauth(struct authhandle *auth, struct socket *sk, char *passdata) static int available(struct socket *sk) { - return((sk->family == PF_UNIX) && (sk->ucred.pid != 0)); + return((sk->family == PF_UNIX) && (sk->ucred.uid != -1)); } static struct authmech mechdesc = { diff --git a/daemon/net.c b/daemon/net.c index 0fc9e45..5471e45 100644 --- a/daemon/net.c +++ b/daemon/net.c @@ -183,7 +183,8 @@ static struct socket *newsock(int type) new->close = 0; new->remote = NULL; new->remotelen = 0; - memset(&new->ucred, 0, sizeof(new->ucred)); + new->ucred.uid = -1; + new->ucred.gid = -1; switch(type) { case SOCK_STREAM: @@ -350,18 +351,21 @@ void *sockgetinbuf(struct socket *sk, size_t *size) static void recvcmsg(struct socket *sk, struct msghdr *msg) { struct cmsghdr *cmsg; - struct ucred *cred; for(cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) { +#if UNIX_AUTH_STYLE == 1 if((cmsg->cmsg_level == SOL_SOCKET) && (cmsg->cmsg_type == SCM_CREDENTIALS)) { - if(sk->ucred.pid == 0) + struct ucred *cred; + if(sk->ucred.uid == -1) { cred = (struct ucred *)CMSG_DATA(cmsg); - memcpy(&sk->ucred, cred, sizeof(*cred)); + sk->ucred.uid = cred->uid; + sk->ucred.gid = cred->gid; } } +#endif } } @@ -819,8 +823,17 @@ static void acceptunix(struct socket *sk) int buf; buf = 1; +#if UNIX_AUTH_STYLE == 1 if(setsockopt(sk->fd, SOL_SOCKET, SO_PASSCRED, &buf, sizeof(buf)) < 0) flog(LOG_WARNING, "could not enable SO_PASSCRED on Unix socket %i: %s", sk->fd, strerror(errno)); +#elif UNIX_AUTH_STYLE == 2 + if(getpeereid(sk->fd, &sk->ucred.uid, &sk->ucred.gid) < 0) + { + flog(LOG_WARNING, "could not get peer creds on Unix socket %i: %s", sk->fd, strerror(errno)); + sk->ucred.uid = -1; + sk->ucred.gid = -1; + } +#endif } int pollsocks(int timeout) diff --git a/daemon/net.h b/daemon/net.h index f9b7a29..6457033 100644 --- a/daemon/net.h +++ b/daemon/net.h @@ -55,7 +55,11 @@ struct socket int close; struct sockaddr *remote; socklen_t remotelen; - struct ucred ucred; + struct + { + uid_t uid; + gid_t gid; + } ucred; union { struct diff --git a/lib/uilib.c b/lib/uilib.c index 303ed0c..973a2b3 100644 --- a/lib/uilib.c +++ b/lib/uilib.c @@ -762,6 +762,7 @@ int dc_handleread(void) return(0); } +#if UNIX_AUTH_STYLE == 1 static void mkcreds(struct msghdr *msg) { struct ucred *ucred; @@ -780,6 +781,7 @@ static void mkcreds(struct msghdr *msg) ucred->gid = getgid(); msg->msg_controllen = cmsg->cmsg_len; } +#endif int dc_handlewrite(void) { @@ -798,11 +800,13 @@ int dc_handlewrite(void) msg.msg_iovlen = 1; bufvec.iov_base = queue->buf; bufvec.iov_len = queue->buflen; +#if UNIX_AUTH_STYLE == 1 if((servinfo.family == PF_UNIX) && !servinfo.sentcreds) { mkcreds(&msg); servinfo.sentcreds = 1; } +#endif ret = sendmsg(fd, &msg, MSG_NOSIGNAL | MSG_DONTWAIT); if(ret < 0) { -- 2.11.0