pkgsrc/sysutils/gamin/patches/patch-ae
wiz 0bbe40fee4 Fix build after G_CONST_RETURN has been deprecated.
Based on PR 46210 by Francis GUDIN.
2012-03-17 02:19:08 +00:00

306 lines
8.6 KiB
Text

$NetBSD: patch-ae,v 1.3 2012/03/17 02:19:08 wiz Exp $
--- libgamin/gam_api.c.orig 2007-08-27 10:21:03.000000000 +0000
+++ libgamin/gam_api.c
@@ -7,6 +7,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
+#include <sys/param.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
@@ -51,6 +52,37 @@ const char *FamErrlist[] = {
NULL
};
+#if defined(LOCAL_PEEREID)
+static int
+gam_nb_getpeereid(int fd, pid_t *pid, uid_t *uid, gid_t *gid)
+{
+ struct unpcbid cred;
+ socklen_t len = sizeof(cred);
+
+ if (getsockopt(fd, 0, LOCAL_PEEREID, &cred, &len) < 0)
+ return 0;
+ if (pid)
+ *pid = cred.unp_pid;
+ if (uid)
+ *uid = cred.unp_euid;
+ if (gid)
+ *gid = cred.unp_egid;
+ return 1;
+}
+#elif defined(SOCKCREDSIZE)
+#define BSDCRED struct sockcred
+#define CRED_DATASIZE (SOCKCREDSIZE(NGROUPS))
+#define credpid(c,p) (p)
+#define creduid(c) (c->sc_euid)
+#define credgid(c) (c->sc_egid)
+#elif defined(HAVE_CMSGCRED)
+#define BSDCRED struct cmsgcred
+#define CRED_DATASIZE (sizeof(struct cmsgcred))
+#define credpid(c,p) (c->cmcred_pid)
+#define creduid(c) (c->cmcred_euid)
+#define credgid(c) (c->cmcred_groups[0])
+#endif
+
#ifdef GAMIN_DEBUG_API
int FAMDebug(FAMConnection *fc, const char *filename, FAMRequest * fr,
void *userData);
@@ -314,12 +346,6 @@ gamin_check_secure_path(const char *path
goto cleanup;
}
#endif
- if (st.st_mode & (S_IRWXG|S_IRWXO)) {
- gam_error(DEBUG_INFO,
- "Socket %s has wrong permissions\n",
- path);
- goto cleanup;
- }
/*
* Looks good though binding may fail due to an existing server
*/
@@ -379,6 +405,18 @@ gamin_connect_unix_socket(const char *pa
}
strncpy(&addr.sun_path[0], path, (sizeof(addr) - 4) - 1);
#endif
+#if defined(BSDCRED) && defined(LOCAL_CREDS)
+ /* Set the socket to receive credentials. */
+ {
+ int on = 1;
+
+ if (setsockopt(fd, 0, LOCAL_CREDS, &on, sizeof(on)) < 0) {
+ gam_error(DEBUG_INFO,
+ "Unable to setsockopt() LOCAL_CREDS on %d\n", fd);
+ return(-1);
+ }
+ }
+#endif
if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
if (retries == 0) {
@@ -426,37 +464,35 @@ gamin_connect_unix_socket(const char *pa
static int
gamin_write_credential_byte(int fd)
{
- char data[2] = { 0, 0 };
- int written;
-#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS)
- struct {
- struct cmsghdr hdr;
- struct cmsgcred cred;
- } cmsg;
- struct iovec iov;
struct msghdr msg;
+ struct iovec iov;
+ pid_t pid = getpid();
+ int written;
- iov.iov_base = &data[0];
- iov.iov_len = 1;
+#if defined(BSDCRED) && !defined(LOCAL_CREDS)
+ struct cmsghdr *cmsg;
+ char cmsgbuf[CMSG_SPACE(CRED_DATASIZE)];
+#endif
+
+ iov.iov_base = &pid;
+ iov.iov_len = sizeof(pid_t);
- memset (&msg, 0, sizeof (msg));
+ memset (&msg, 0, sizeof(msg));
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
- msg.msg_control = &cmsg;
- msg.msg_controllen = sizeof (cmsg);
- memset (&cmsg, 0, sizeof (cmsg));
- cmsg.hdr.cmsg_len = sizeof (cmsg);
- cmsg.hdr.cmsg_level = SOL_SOCKET;
- cmsg.hdr.cmsg_type = SCM_CREDS;
+#if defined(BSDCRED) && !defined(LOCAL_CREDS)
+ memset(cmsgbuf, 0, sizeof(cmsgbuf));
+ msg.msg_control = (void *)cmsgbuf;
+ msg.msg_controllen = sizeof(cmsgbuf);
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_len = CMSG_LEN(CRED_DATASIZE);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_CREDS;
#endif
retry:
-#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS)
written = sendmsg(fd, &msg, 0);
-#else
- written = write(fd, &data[0], 1);
-#endif
if (written < 0) {
if (errno == EINTR)
goto retry;
@@ -464,7 +500,7 @@ retry:
"Failed to write credential bytes to socket %d\n", fd);
return (-1);
}
- if (written != 1) {
+ if (written != iov.iov_len) {
gam_error(DEBUG_INFO, "Wrote %d credential bytes to socket %d\n",
written, fd);
return (-1);
@@ -648,43 +684,26 @@ gamin_check_cred(GAMDataPtr conn, int fd
{
struct msghdr msg;
struct iovec iov;
- char buf;
- pid_t c_pid;
+ pid_t c_pid, pid;
uid_t c_uid, s_uid;
gid_t c_gid;
-#ifdef HAVE_CMSGCRED
- struct {
- struct cmsghdr hdr;
- struct cmsgcred cred;
- } cmsg;
+#if defined(BSDCRED)
+ struct cmsghdr *cmsg;
+ char cmsgbuf[CMSG_SPACE(CRED_DATASIZE)];
#endif
- s_uid = getuid();
-
-#if defined(LOCAL_CREDS) && defined(HAVE_CMSGCRED)
- /* Set the socket to receive credentials on the next message */
- {
- int on = 1;
-
- if (setsockopt(fd, 0, LOCAL_CREDS, &on, sizeof(on)) < 0) {
- gam_error(DEBUG_INFO, "Unable to set LOCAL_CREDS socket option\n");
- return(-1);
- }
- }
-#endif
-
- iov.iov_base = &buf;
- iov.iov_len = 1;
+ iov.iov_base = &pid;
+ iov.iov_len = sizeof(pid_t);
memset(&msg, 0, sizeof(msg));
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
-#ifdef HAVE_CMSGCRED
- memset(&cmsg, 0, sizeof(cmsg));
- msg.msg_control = &cmsg;
- msg.msg_controllen = sizeof(cmsg);
+#if defined(BSDCRED)
+ memset(cmsgbuf, 0, sizeof(cmsgbuf));
+ msg.msg_control = (void *)cmsgbuf;
+ msg.msg_controllen = sizeof(cmsgbuf);
#endif
retry:
@@ -692,26 +711,33 @@ retry:
if (errno == EINTR)
goto retry;
- GAM_DEBUG(DEBUG_INFO, "Failed to read credentials byte on %d\n", fd);
+ GAM_DEBUG(DEBUG_INFO, "Failed to read credential bytes on %d\n", fd);
goto failed;
}
-
- if (buf != '\0') {
- GAM_DEBUG(DEBUG_INFO, "Credentials byte was not nul on %d\n", fd);
+ GAM_DEBUG(DEBUG_INFO, "Read pid %d on %d\n", pid, fd);
+#if defined(BSDCRED)
+ if (msg.msg_controllen == 0) {
+ GAM_DEBUG(DEBUG_INFO,
+ "No control message received over recvmsg()\n");
+ goto failed;
+ }
+ if ((msg.msg_flags & MSG_CTRUNC) != 0) {
+ GAM_DEBUG(DEBUG_INFO,
+ "Lost control message data over recvmsg()\n");
goto failed;
}
-#ifdef HAVE_CMSGCRED
- if (cmsg.hdr.cmsg_len < sizeof(cmsg) || cmsg.hdr.cmsg_type != SCM_CREDS) {
+ cmsg = CMSG_FIRSTHDR(&msg);
+ if (cmsg->cmsg_type != SCM_CREDS) {
GAM_DEBUG(DEBUG_INFO,
"Message from recvmsg() was not SCM_CREDS\n");
goto failed;
}
#endif
- GAM_DEBUG(DEBUG_INFO, "read credentials byte\n");
+ GAM_DEBUG(DEBUG_INFO, "read credential bytes\n");
{
-#ifdef SO_PEERCRED
+#if defined(SO_PEERCRED)
struct ucred cr;
socklen_t cr_len = sizeof(cr);
@@ -726,23 +752,37 @@ retry:
fd, cr_len, (int) sizeof(cr));
goto failed;
}
-#elif defined(HAVE_CMSGCRED)
- c_pid = cmsg.cred.cmcred_pid;
- c_uid = cmsg.cred.cmcred_euid;
- c_gid = cmsg.cred.cmcred_groups[0];
-#else /* !SO_PEERCRED && !HAVE_CMSGCRED */
+#elif defined(LOCAL_PEEREID)
+ if (gam_nb_getpeereid(fd, &c_pid, &c_uid, &c_gid) == 0) {
+ GAM_DEBUG(DEBUG_INFO,
+ "Failed to gam_nb_getpeereid() credentials on %d\n", fd);
+ goto failed;
+ }
+#elif defined(BSDCRED)
+ BSDCRED *cr = (BSDCRED *)CMSG_DATA(cmsg);
+ c_pid = credpid(cr, pid);
+ c_uid = creduid(cr);
+ c_gid = credgid(cr);
+#else
GAM_DEBUG(DEBUG_INFO,
"Socket credentials not supported on this OS\n");
goto failed;
#endif
}
+ s_uid = getuid();
if (s_uid != c_uid) {
GAM_DEBUG(DEBUG_INFO,
"Credentials check failed: s_uid %d, c_uid %d\n",
(int) s_uid, (int) c_uid);
goto failed;
}
+ if (pid != c_pid) {
+ GAM_DEBUG(DEBUG_INFO,
+ "read credentials do not match: pid %d, c_pid %d\n",
+ (int) pid, (int) c_pid);
+ goto failed;
+ }
GAM_DEBUG(DEBUG_INFO,
"Credentials: s_uid %d, c_uid %d, c_gid %d, c_pid %d\n",
(int) s_uid, (int) c_uid, (int) c_gid, (int) c_pid);
@@ -1288,14 +1328,16 @@ FAMNextEvent(FAMConnection * fc, FAMEven
// FIXME: drop and reacquire lock while blocked?
gamin_data_lock(conn);
- if (!gamin_data_event_ready(conn)) {
+ while ((ret = gamin_data_event_ready(conn)) == 0) {
if (gamin_read_data(conn, fc->fd, 1) < 0) {
gamin_try_reconnect(conn, fc->fd);
FAMErrno = FAM_CONNECT;
return (-1);
}
}
- ret = gamin_data_read_event(conn, fe);
+ if (ret > 0)
+ ret = gamin_data_read_event(conn, fe);
+
gamin_data_unlock(conn);
if (ret < 0) {