Patch to 2.0.15 attached. This fixes the fchmod() issue and should
give the correct permissions.
The "-g" option was a bit more tricky to fix. I ended up having to
go back to chown() and that seems to work ok. No matter where I put
fchown(), it just didn't work.
If you can give it some testing, I would appreciate it. I'll shoot
for an early (perhaps 3/27) release of 2.0.16 with this fix.
Ted.
diff --git a/sock.c b/sock.c
index bd7c32d..dd69e3d 100644
--- a/sock.c
+++ b/sock.c
@@ -111,20 +111,13 @@ open_sock()
/* ??? Move CLOEXEC and NONBLOCK settings below up to here? */
} else {
/* create our own socket */
- fd = ud_create_socket(socketfile);
+ fd = ud_create_socket(socketfile, socketmode);
if (fd < 0) {
acpid_log(LOG_ERR, "can't open socket %s: %s",
socketfile, strerror(errno));
exit(EXIT_FAILURE);
}
- if (fchmod(fd, socketmode) < 0) {
- close(fd);
- acpid_log(LOG_ERR, "chmod() on socket %s: %s",
- socketfile, strerror(errno));
- return;
- }
-
/* if we need to change the socket's group, do so */
if (socketgroup) {
struct group *gr;
@@ -140,7 +133,11 @@ open_sock()
socketfile, strerror(errno));
exit(EXIT_FAILURE);
}
- if (fchown(fd, buf.st_uid, gr->gr_gid) < 0) {
+ /* ??? I've tried using fchown(), however it doesn't
work here.
+ * It also doesn't work before bind(). The GNU
docs seem to
+ * indicate it isn't supposed to work with sockets.
*/
+ /* if (fchown(fd, buf.st_uid, gr->gr_gid) < 0) { */
+ if (chown(socketfile, buf.st_uid, gr->gr_gid) < 0) {
acpid_log(LOG_ERR, "can't chown %s: %s",
socketfile, strerror(errno));
exit(EXIT_FAILURE);
diff --git a/ud_socket.c b/ud_socket.c
index c3eb337..d9ab565 100644
--- a/ud_socket.c
+++ b/ud_socket.c
@@ -23,7 +23,7 @@
#include "ud_socket.h"
int
-ud_create_socket(const char *name)
+ud_create_socket(const char *name, mode_t socketmode)
{
int fd;
int r;
@@ -46,6 +46,16 @@ ud_create_socket(const char *name)
return fd;
}
+ /* Clear the umask to guarantee predictable results from fchmod(). */
+ umask(0);
+
+ if (fchmod(fd, socketmode) < 0) {
+ close(fd);
+ acpid_log(LOG_ERR, "fchmod() on socket %s: %s",
+ name, strerror(errno));
+ return -1;
+ }
+
/* setup address struct */
memset(&uds_addr, 0, sizeof(uds_addr));
uds_addr.sun_family = AF_UNIX;
diff --git a/ud_socket.h b/ud_socket.h
index a59db95..46a2189 100644
--- a/ud_socket.h
+++ b/ud_socket.h
@@ -8,7 +8,7 @@
#include <sys/socket.h>
#include <sys/un.h>
-int ud_create_socket(const char *name);
+int ud_create_socket(const char *name, mode_t socketmode);
int ud_accept(int sock, struct ucred *cred);
int ud_connect(const char *name);
int ud_get_peercred(int fd, struct ucred *cred);