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 <sys/socket.h>])
+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
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");
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 = {
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:
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
}
}
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)
int close;
struct sockaddr *remote;
socklen_t remotelen;
- struct ucred ucred;
+ struct
+ {
+ uid_t uid;
+ gid_t gid;
+ } ucred;
union
{
struct
return(0);
}
+#if UNIX_AUTH_STYLE == 1
static void mkcreds(struct msghdr *msg)
{
struct ucred *ucred;
ucred->gid = getgid();
msg->msg_controllen = cmsg->cmsg_len;
}
+#endif
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)
{