As partially explained in the patch comments my setup is as follows:

* rrdcached running from upstart

This allows upstart to ensure rrdcached is restarted if it ever dies.
Currently upstart does not offer the facility to run daemons under
another uid.

* monitor programs also running from upstart

Again to ensure they never die

* Perl CGI scripts running from www-data as part of Apache

These generate graphs on demand. As the RRD graph tool needs to ensure
data is flushed to the RRD before graph generation occurs it needs to
communicate to rrdcached socket to do this.

I did consider another approach which was to drop privileges of
rrdcached after starting. However it seemed to be a more complex
solution to the problem and likely more fragile.

-- 
Alex, homepage: http://www.bennee.com/~alex/
http://www.half-llama.co.uk
From c7d72bc6f133f33475e1574a6896fd7335a9c276 Mon Sep 17 00:00:00 2001
From: Alex Bennee <a...@pitcairn.cambridgebroadband.com>
Date: Fri, 22 Jan 2010 15:53:17 +0000
Subject: [PATCH] Allow rrdached to set the group permissions of the Unix socket for to
 arbitrary groups.

Obviously this will only work if rrdcached is running as root which in
my case it has to be (as upstart can't currently monitor non-root
daemons). As you may have RRD data sources (data loggers) and RRD
consumers (e.g. CGI scripts) that both need to talk to the cache
daemon one solution is to set the group permissions of the socket.

This offer some flexibility over trying to get every RRD user/daemon
running under the same user context.
---
 src/rrd_daemon.c |   48 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 47 insertions(+), 1 deletions(-)

diff --git a/src/rrd_daemon.c b/src/rrd_daemon.c
index 4c84f19..d4cfa94 100644
--- a/src/rrd_daemon.c
+++ b/src/rrd_daemon.c
@@ -106,6 +106,7 @@
 #include <sys/time.h>
 #include <time.h>
 #include <libgen.h>
+#include <grp.h>
 
 #include <glib-2.0/glib.h>
 /* }}} */
@@ -220,6 +221,9 @@ static uid_t daemon_uid;
 static listen_socket_t *listen_fds = NULL;
 static size_t listen_fds_num = 0;
 
+static gboolean set_socket_group = FALSE;
+static gid_t socket_group;
+
 enum {
   RUNNING,		/* normal operation */
   FLUSHING,		/* flushing remaining values */
@@ -2326,6 +2330,16 @@ static int open_listen_socket_unix (const listen_socket_t *sock) /* {{{ */
     return (-1);
   }
 
+  /* tweak the sockets group ownership */
+  if (set_socket_group)
+  {
+    if ( (chown(path, getuid(), socket_group) != 0) ||
+	 (chmod(path, (S_IRUSR|S_IWUSR|S_IXUSR | S_IRGRP|S_IWGRP)) != 0) )
+    {
+      fprintf(stderr, "rrdcached: failed to set socket group permissions (%s)\n", strerror(errno));
+    }
+  }
+
   status = listen (fd, /* backlog = */ 10);
   if (status != 0)
   {
@@ -2746,7 +2760,7 @@ static int read_options (int argc, char **argv) /* {{{ */
   char **permissions = NULL;
   size_t permissions_len = 0;
 
-  while ((option = getopt(argc, argv, "gl:P:f:w:z:t:Bb:p:Fj:h?")) != -1)
+  while ((option = getopt(argc, argv, "gl:s:P:f:w:z:t:Bb:p:Fj:h?")) != -1)
   {
     switch (option)
     {
@@ -2811,6 +2825,37 @@ static int read_options (int argc, char **argv) /* {{{ */
       }
       break;
 
+      /* set socket group permissions */
+      case 's':
+      {
+	gid_t group_gid;
+	struct group *grp;
+
+	group_gid = strtoul(optarg, NULL, 10);
+	if (errno != EINVAL && group_gid>0)
+	{
+	  /* we were passed a number */
+	  grp = getgrgid(group_gid);
+	}
+	else
+	{
+	  grp = getgrnam(optarg);
+	}
+
+	if (grp)
+	{
+	  socket_group = grp->gr_gid;
+	  set_socket_group = TRUE;
+	}
+	else
+	{
+	  /* no idea what the user wanted... */
+	  fprintf (stderr, "read_options: couldn't map \"%s\" to a group, Sorry\n", optarg);
+	  return (5);
+	}
+      }
+      break;
+
       case 'P':
       {
         char *optcopy;
@@ -3024,6 +3069,7 @@ static int read_options (int argc, char **argv) /* {{{ */
             "  -g            Do not fork and run in the foreground.\n"
             "  -j <dir>      Directory in which to create the journal files.\n"
             "  -F            Always flush all updates at shutdown\n"
+            "  -s <id|name>  Make socket g+rw to named group\n"
             "\n"
             "For more information and a detailed description of all options "
             "please refer\n"
-- 
1.6.6

_______________________________________________
rrd-developers mailing list
rrd-developers@lists.oetiker.ch
https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers

Reply via email to