check and warn about capabilities misconfiguration
[collectd.git] / src / iptables.c
index 05e3e24..a2ed4c7 100644 (file)
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 #include "configfile.h"
 
+#ifdef HAVE_SYS_CAPABILITY_H
+# include <sys/capability.h>
+#endif
+
 #include <libiptc/libiptc.h>
 #include <libiptc/libip6tc.h>
 
@@ -111,7 +116,8 @@ static int iptables_config (const char *key, const char *value)
     else
         return (1);
 
-    ip_chain_t temp, *final, **list;
+    ip_chain_t  temp = { 0 };
+    ip_chain_t *final, **list;
     char *table;
     int   table_len;
     char *chain;
@@ -121,8 +127,6 @@ static int iptables_config (const char *key, const char *value)
     char *fields[4];
     int   fields_num;
 
-    memset (&temp, 0, sizeof (temp));
-
     value_copy = strdup (value);
     if (value_copy == NULL)
     {
@@ -204,7 +208,7 @@ static int iptables_config (const char *key, const char *value)
     table = NULL;
     chain = NULL;
 
-    list = (ip_chain_t **) realloc (chain_list, (chain_num + 1) * sizeof (ip_chain_t *));
+    list = realloc (chain_list, (chain_num + 1) * sizeof (ip_chain_t *));
     if (list == NULL)
     {
         char errbuf[1024];
@@ -215,7 +219,7 @@ static int iptables_config (const char *key, const char *value)
     }
 
     chain_list = list;
-    final = (ip_chain_t *) malloc( sizeof(temp) );
+    final = malloc(sizeof (*final));
     if (final == NULL)
     {
         char errbuf[1024];
@@ -420,12 +424,11 @@ static void submit_chain (iptc_handle_t *handle, ip_chain_t *chain)
 
 static int iptables_read (void)
 {
-    int i;
     int num_failures = 0;
     ip_chain_t *chain;
 
     /* Init the iptc handle structure and query the correct table */
-    for (i = 0; i < chain_num; i++)
+    for (int i = 0; i < chain_num; i++)
     {
         chain = chain_list[i];
 
@@ -489,9 +492,7 @@ static int iptables_read (void)
 
 static int iptables_shutdown (void)
 {
-    int i;
-
-    for (i = 0; i < chain_num; i++)
+    for (int i = 0; i < chain_num; i++)
     {
         if ((chain_list[i] != NULL) && (chain_list[i]->rule_type == RTYPE_COMMENT))
             sfree (chain_list[i]->rule.comment);
@@ -502,10 +503,30 @@ static int iptables_shutdown (void)
     return (0);
 } /* int iptables_shutdown */
 
+static int iptables_init (void)
+{
+#ifdef HAVE_SYS_CAPABILITY_H
+    if (check_capability (CAP_NET_ADMIN) != 0)
+    {
+        if (getuid () == 0)
+            WARNING ("iptables plugin: Running collectd as root, but the "
+                  "CAP_NET_ADMIN capability is missing. The plugin's read "
+                  "function will probably fail. Is your init system dropping "
+                  "capabilities ?");
+        else
+            WARNING ("iptables plugin: collectd doesn't have the CAP_NET_ADMIN "
+                  "capability. If you don't want to run collectd as root, try "
+                  "running \"setcap cap_net_admin=ep\" on the collectd binary.");
+    }
+#endif
+    return (0);
+} /* int iptables_init */
+
 void module_register (void)
 {
     plugin_register_config ("iptables", iptables_config,
                              config_keys, config_keys_num);
+    plugin_register_init ("iptables", iptables_init);
     plugin_register_read ("iptables", iptables_read);
     plugin_register_shutdown ("iptables", iptables_shutdown);
 } /* void module_register */