1 --- libgamin/gam_api.c.orig	2007-08-27 03:21:03.000000000 -0700
2 +++ libgamin/gam_api.c	2013-02-16 15:51:11.927100135 -0800
3 @@ -14,6 +14,7 @@
4  #include <sys/socket.h>
5  #include <sys/un.h>
6  #include <sys/uio.h>
7 +#include <string.h>
8  #include "fam.h"
9  #include "gam_protocol.h"
10  #include "gam_data.h"
11 @@ -117,7 +118,11 @@
12      if (user_name[0] != 0)
13          return (user_name);
14 
15 +#ifdef RUN_AS_EUID
16 +    pw = getpwuid(geteuid());
17 +#else
18      pw = getpwuid(getuid());
19 +#endif
20 
21      if (pw != NULL) {
22  	strncpy(user_name, pw->pw_name, 99);
23 @@ -224,7 +229,11 @@
24  	free(dir);
25  	return(0);
26      }
27 +#ifdef RUN_AS_EUID
28 +    if (st.st_uid != geteuid()) {
29 +#else
30      if (st.st_uid != getuid()) {
31 +#endif
32  	gam_error(DEBUG_INFO,
33  		  "Socket directory %s has different owner\n",
34  		  dir);
35 @@ -301,7 +310,11 @@
36      if (ret < 0)
37  	return(0);
38 
39 +#ifdef RUN_AS_EUID
40 +    if (st.st_uid != geteuid()) {
41 +#else
42      if (st.st_uid != getuid()) {
43 +#endif
44  	gam_error(DEBUG_INFO,
45  		  "Socket %s has different owner\n",
46  		  path);
47 @@ -428,10 +441,10 @@
48  {
49      char data[2] = { 0, 0 };
50      int written;
51 -#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS)
52 -    struct {
53 +#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
54 +    union {
55  	    struct cmsghdr hdr;
56 -	    struct cmsgcred cred;
57 +	    char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
58      } cmsg;
59      struct iovec iov;
60      struct msghdr msg;
61 @@ -443,16 +456,16 @@
62      msg.msg_iov = &iov;
63      msg.msg_iovlen = 1;
64 
65 -    msg.msg_control = &cmsg;
66 -    msg.msg_controllen = sizeof (cmsg);
67 +    msg.msg_control = (caddr_t) &cmsg;
68 +    msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
69      memset (&cmsg, 0, sizeof (cmsg));
70 -    cmsg.hdr.cmsg_len = sizeof (cmsg);
71 +    cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
72      cmsg.hdr.cmsg_level = SOL_SOCKET;
73      cmsg.hdr.cmsg_type = SCM_CREDS;
74  #endif
75 
76  retry:
77 -#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS)
78 +#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
79      written = sendmsg(fd, &msg, 0);
80  #else
81      written = write(fd, &data[0], 1);
82 @@ -654,15 +667,20 @@
83      gid_t c_gid;
84 
85  #ifdef HAVE_CMSGCRED
86 -    struct {
87 +    struct cmsgcred *cred;
88 +    union {
89  	    struct cmsghdr hdr;
90 -	    struct cmsgcred cred;
91 +	    char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
92      } cmsg;
93  #endif
94 
95 +#ifdef RUN_AS_EUID
96 +    s_uid = geteuid();
97 +#else
98      s_uid = getuid();
99 +#endif
100 
101 -#if defined(LOCAL_CREDS) && defined(HAVE_CMSGCRED)
102 +#if defined(LOCAL_CREDS) && defined(HAVE_CMSGCRED) && !defined(__FreeBSD__)
103      /* Set the socket to receive credentials on the next message */
104      {
105          int on = 1;
106 @@ -683,8 +701,8 @@
107 
108  #ifdef HAVE_CMSGCRED
109      memset(&cmsg, 0, sizeof(cmsg));
110 -    msg.msg_control = &cmsg;
111 -    msg.msg_controllen = sizeof(cmsg);
112 +    msg.msg_control = (caddr_t) &cmsg;
113 +    msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
114  #endif
115 
116  retry:
117 @@ -701,7 +719,7 @@
118          goto failed;
119      }
120  #ifdef HAVE_CMSGCRED
121 -    if (cmsg.hdr.cmsg_len < sizeof(cmsg) || cmsg.hdr.cmsg_type != SCM_CREDS) {
122 +    if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred)) || cmsg.hdr.cmsg_type != SCM_CREDS) {
123          GAM_DEBUG(DEBUG_INFO,
124                    "Message from recvmsg() was not SCM_CREDS\n");
125          goto failed;
126 @@ -727,9 +745,10 @@
127              goto failed;
128          }
129  #elif defined(HAVE_CMSGCRED)
130 -        c_pid = cmsg.cred.cmcred_pid;
131 -        c_uid = cmsg.cred.cmcred_euid;
132 -        c_gid = cmsg.cred.cmcred_groups[0];
133 +        cred = (struct cmsgcred *) CMSG_DATA (&cmsg);
134 +        c_pid = cred->cmcred_pid;
135 +        c_uid = cred->cmcred_euid;
136 +        c_gid = cred->cmcred_groups[0];
137  #else /* !SO_PEERCRED && !HAVE_CMSGCRED */
138          GAM_DEBUG(DEBUG_INFO,
139                    "Socket credentials not supported on this OS\n");
140 @@ -1288,14 +1307,17 @@
141 
142      // FIXME: drop and reacquire lock while blocked?
143      gamin_data_lock(conn);
144 -    if (!gamin_data_event_ready(conn)) {
145 +    while ((ret = gamin_data_event_ready(conn)) == 0) {
146          if (gamin_read_data(conn, fc->fd, 1) < 0) {
147  	    gamin_try_reconnect(conn, fc->fd);
148  	    FAMErrno = FAM_CONNECT;
149  	    return (-1);
150  	}
151      }
152 -    ret = gamin_data_read_event(conn, fe);
153 +
154 +    if (ret > 0)
155 +        ret = gamin_data_read_event(conn, fe);
156 +
157      gamin_data_unlock(conn);
158 
159      if (ret < 0) {
160