1 --- server/gam_channel.c.orig	Tue Aug  9 12:17:39 2005
2 +++ server/gam_channel.c	Fri Feb 10 01:22:46 2006
3 @@ -7,6 +7,7 @@
4  #include <sys/stat.h>
5  #include <sys/un.h>
6  #include <sys/uio.h>
7 +#include <string.h>
8  #include "gam_error.h"
9  #include "gam_connection.h"
10  #include "gam_channel.h"
11 @@ -30,10 +31,10 @@ gam_client_conn_send_cred(int fd)
12  {
13      char data[2] = { 0, 0 };
14      int written;
15 -#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS)
16 -    struct {
17 +#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
18 +    union {
19  	    struct cmsghdr hdr;
20 -	    struct cmsgcred cred;
21 +	    char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
22      } cmsg;
23      struct iovec iov;
24      struct msghdr msg;
25 @@ -45,16 +46,16 @@ gam_client_conn_send_cred(int fd)
26      msg.msg_iov = &iov;
27      msg.msg_iovlen = 1;
28 
29 -    msg.msg_control = &cmsg;
30 -    msg.msg_controllen = sizeof (cmsg);
31 +    msg.msg_control = (caddr_t) &cmsg;
32 +    msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
33      memset (&cmsg, 0, sizeof (cmsg));
34 -    cmsg.hdr.cmsg_len = sizeof (cmsg);
35 +    cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
36      cmsg.hdr.cmsg_level = SOL_SOCKET;
37      cmsg.hdr.cmsg_type = SCM_CREDS;
38  #endif
39 
40  retry:
41 -#if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS)
42 +#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
43      written = sendmsg(fd, &msg, 0);
44  #else
45      written = write(fd, &data[0], 1);
46 @@ -95,15 +96,16 @@ gam_client_conn_check_cred(GIOChannel *
47      gid_t c_gid;
48 
49  #ifdef HAVE_CMSGCRED
50 -    struct {
51 +    struct cmsgcred *cred;
52 +    union {
53  	    struct cmsghdr hdr;
54 -	    struct cmsgcred cred;
55 +	    char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
56      } cmsg;
57  #endif
58 
59      s_uid = getuid();
60 
61 -#if defined(LOCAL_CREDS) && defined(HAVE_CMSGCRED)
62 +#if defined(LOCAL_CREDS) && defined(HAVE_CMSGCRED) && !defined(__FreeBSD__)
63      /* Set the socket to receive credentials on the next message */
64      {
65          int on = 1;
66 @@ -124,8 +126,8 @@ gam_client_conn_check_cred(GIOChannel *
67 
68  #ifdef HAVE_CMSGCRED
69      memset(&cmsg, 0, sizeof(cmsg));
70 -    msg.msg_control = &cmsg;
71 -    msg.msg_controllen = sizeof(cmsg);
72 +    msg.msg_control = (caddr_t) &cmsg;
73 +    msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
74  #endif
75 
76    retry:
77 @@ -142,7 +144,7 @@ gam_client_conn_check_cred(GIOChannel *
78          goto failed;
79      }
80  #ifdef HAVE_CMSGCRED
81 -    if (cmsg.hdr.cmsg_len < sizeof(cmsg) || cmsg.hdr.cmsg_type != SCM_CREDS) {
82 +    if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred)) || cmsg.hdr.cmsg_type != SCM_CREDS) {
83          GAM_DEBUG(DEBUG_INFO,
84                    "Message from recvmsg() was not SCM_CREDS\n");
85          goto failed;
86 @@ -168,9 +170,10 @@ gam_client_conn_check_cred(GIOChannel *
87              goto failed;
88          }
89  #elif defined(HAVE_CMSGCRED)
90 -	c_pid = cmsg.cred.cmcred_pid;
91 -	c_uid = cmsg.cred.cmcred_euid;
92 -	c_gid = cmsg.cred.cmcred_groups[0];
93 +	cred = (struct cmsgcred *) CMSG_DATA (&cmsg);
94 +	c_pid = cred->cmcred_pid;
95 +	c_uid = cred->cmcred_euid;
96 +	c_gid = cred->cmcred_groups[0];
97  #else /* !SO_PEERCRED && !HAVE_CMSGCRED */
98          GAM_DEBUG(DEBUG_INFO,
99                    "Socket credentials not supported on this OS\n");
100 @@ -620,6 +621,7 @@ gam_listen_unix_socket(const char *path)
101  {
102      int fd;
103      struct sockaddr_un addr;
104 +    struct stat st;
105 
106      fd = socket(PF_UNIX, SOCK_STREAM, 0);
107      if (fd < 0) {
108 @@ -640,8 +642,18 @@ gam_listen_unix_socket(const char *path)
109       * some extra protection checks. Also make sure the socket is created
110       * with restricted mode
111       */
112 -    if (!gam_check_secure_path(path)) {
113 +    if (!gam_check_secure_dir()) {
114 +	close(fd);
115  	return (-1);
116 +    }
117 +
118 +    if (stat(path, &st) == 0) {
119 +        /* bind() will fail if the socket already exists */
120 +        if (unlink(path) < 0) {
121 +            GAM_DEBUG(DEBUG_INFO, "Failed to remove %s\n", path);
122 +            close(fd);
123 +            return (-1);
124 +        }
125      }
126      strncpy(&addr.sun_path[0], path, (sizeof(addr) - 4) - 1);
127      umask(0077);
128