B<rrdcached>
[B<-P>E<nbsp>I<permissions>]
[B<-l>E<nbsp>I<address>]
+[B<-s>E<nbsp>I<group>]
[B<-w>E<nbsp>I<timeout>]
[B<-z>E<nbsp>I<delay>]
[B<-f>E<nbsp>I<timeout>]
If the B<-l> option is not specified the default address,
C<unix:/tmp/rrdcached.sock>, will be used.
+=item B<-s> I<id>
+
+Set the group permissions of the UNIX domain socket. The option accepts either
+a numeric group id or group name. That group will then have both read and write
+permissions to the socket and therefore able to send commands to the daemon. This
+may be useful in cases where you cannot easily run all RRD processes with the same
+user privileges (e.g. graph generating CGI scripts that typically run in the
+permission context of the web server).
+
=item B<-P> I<command>[,I<command>[,...]]
Specifies the commands accepted via a network socket. This allows
#include <sys/time.h>
#include <time.h>
#include <libgen.h>
+#include <grp.h>
#include <glib-2.0/glib.h>
/* }}} */
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 */
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)
{
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)
{
}
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;
" -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"