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