chiark / gitweb /
server: Set admin socket permissions to match user.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 20 Dec 2008 17:06:11 +0000 (17:06 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Mon, 29 Dec 2008 21:52:12 +0000 (21:52 +0000)
We create the socket before dropping privileges so that we can create it
somewhere we might not be able to write to later.  This change will make
it possible for other processes running with reduced privilege to
connect and issue administration requests.

server/admin.c
server/tripe.8.in
server/tripe.c
server/tripe.h

index c4433e45005e3e34c1375405af64723977da55d0..00288f3017264e9bdf477ac8dee2d8726341324c 100644 (file)
@@ -2153,13 +2153,15 @@ void a_daemon(void) { flags |= F_DAEMON; }
 /* --- @a_init@ --- *
  *
  * Arguments:  @const char *name@ = socket name to create
+ *             @uid_t u@ = user to own the socket
+ *             @gid_t g@ = group to own the socket
  *
  * Returns:    ---
  *
  * Use:                Creates the admin listening socket.
  */
 
-void a_init(const char *name)
+void a_init(const char *name, uid_t u, gid_t g)
 {
   int fd;
   int n = 5;
@@ -2215,6 +2217,11 @@ again:
     goto again;
   }
   chmod(sun.sun_path, 0600);
+  if (chown(sun.sun_path, u, g)) {
+    T( trace(T_ADMIN,
+            "admin: failed to give away socket: %s",
+            strerror(errno)); )
+  }
   fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
   if (listen(fd, 5))
     die(EXIT_FAILURE, "couldn't listen on socket: %s", strerror(errno));
index edf0ea58639219ae53d6cd2e7eb8e09ce1edd7c6..9c6aea80244737cc7011d3fb3a4dd2fe5788dbd3 100644 (file)
@@ -215,7 +215,8 @@ to
 .IR user 's
 primary group, unless overridden by a
 .B \-G
-option.
+option.  The selected user (and group) will also be the owner of the
+administration socket.
 .TP
 .BI "\-G, \-\-setgid=" group
 Set gid to that of
index ebd8efc7eda172cc9fbee5b919403da709bd5516..ba59dfea62451d7866cb8863071c6d8d12d3b0c2 100644 (file)
@@ -288,9 +288,9 @@ int main(int argc, char *argv[])
       af |= AF_FOREGROUND;
     a_create(STDIN_FILENO, STDOUT_FILENO, af);
   }
+  a_init(csock, u, g);
   u_setugid(u, g);
   km_init(kr_priv, kr_pub, tag_priv);
-  a_init(csock);
   if (f & f_daemon) {
     if (daemonize())
       die(EXIT_FAILURE, "couldn't become a daemon: %s", strerror(errno));
index d955c88ee20b63244ea5636cfb87d9d7556860e3..a3f04c731005d1f595a92345bb7f975818bdbb8e 100644 (file)
@@ -899,13 +899,15 @@ extern void a_daemon(void);
 /* --- @a_init@ --- *
  *
  * Arguments:  @const char *sock@ = socket name to create
+ *             @uid_t u@ = user to own the socket
+ *             @gid_t g@ = group to own the socket
  *
  * Returns:    ---
  *
  * Use:                Creates the admin listening socket.
  */
 
-extern void a_init(const char */*sock*/);
+extern void a_init(const char */*sock*/, uid_t /*u*/, gid_t /*g*/);
 
 /*----- Mapping with addresses as keys ------------------------------------*/