Merge pull request #3329 from efuss/fix-3311
[collectd.git] / src / openldap.c
index 50757db..cd72cdb 100644 (file)
@@ -28,8 +28,8 @@
 
 #include "collectd.h"
 
-#include "common.h"
 #include "plugin.h"
+#include "utils/common/common.h"
 
 #if defined(__APPLE__)
 #pragma clang diagnostic push
@@ -47,22 +47,20 @@ struct cldap_s /* {{{ */
   char *password;
   char *cacert;
   char *host;
-  int state;
-  _Bool starttls;
+  bool starttls;
   int timeout;
   char *url;
-  _Bool verifyhost;
+  bool verifyhost;
   int version;
 
   LDAP *ld;
 };
 typedef struct cldap_s cldap_t; /* }}} */
 
-static cldap_t **databases = NULL;
-static size_t databases_num = 0;
-
-static void cldap_free(cldap_t *st) /* {{{ */
+static void cldap_free(void *arg) /* {{{ */
 {
+  cldap_t *st = arg;
+
   if (st == NULL)
     return;
 
@@ -73,32 +71,30 @@ static void cldap_free(cldap_t *st) /* {{{ */
   sfree(st->name);
   sfree(st->url);
   if (st->ld)
-    ldap_memfree(st->ld);
+    ldap_unbind_ext_s(st->ld, NULL, NULL);
+
   sfree(st);
 } /* }}} void cldap_free */
 
 /* initialize ldap for each host */
 static int cldap_init_host(cldap_t *st) /* {{{ */
 {
-  LDAP *ld;
   int rc;
 
-  if (st->state && st->ld) {
+  if (st->ld) {
     DEBUG("openldap plugin: Already connected to %s", st->url);
-    return (0);
+    return 0;
   }
 
-  rc = ldap_initialize(&ld, st->url);
+  rc = ldap_initialize(&st->ld, st->url);
   if (rc != LDAP_SUCCESS) {
     ERROR("openldap plugin: ldap_initialize failed: %s", ldap_err2string(rc));
-    st->state = 0;
-    if (ld != NULL)
-      ldap_unbind_ext_s(ld, NULL, NULL);
+    if (st->ld != NULL)
+      ldap_unbind_ext_s(st->ld, NULL, NULL);
+    st->ld = NULL;
     return (-1);
   }
 
-  st->ld = ld;
-
   ldap_set_option(st->ld, LDAP_OPT_PROTOCOL_VERSION, &st->version);
 
   ldap_set_option(st->ld, LDAP_OPT_TIMEOUT,
@@ -109,19 +105,18 @@ static int cldap_init_host(cldap_t *st) /* {{{ */
   if (st->cacert != NULL)
     ldap_set_option(st->ld, LDAP_OPT_X_TLS_CACERTFILE, st->cacert);
 
-  if (st->verifyhost == 0) {
+  if (st->verifyhost == false) {
     int never = LDAP_OPT_X_TLS_NEVER;
     ldap_set_option(st->ld, LDAP_OPT_X_TLS_REQUIRE_CERT, &never);
   }
 
-  if (st->starttls != 0) {
-    rc = ldap_start_tls_s(ld, NULL, NULL);
+  if (st->starttls) {
+    rc = ldap_start_tls_s(st->ld, NULL, NULL);
     if (rc != LDAP_SUCCESS) {
       ERROR("openldap plugin: Failed to start tls on %s: %s", st->url,
             ldap_err2string(rc));
-      st->state = 0;
-      if (st->ld != NULL)
-        ldap_unbind_ext_s(st->ld, NULL, NULL);
+      ldap_unbind_ext_s(st->ld, NULL, NULL);
+      st->ld = NULL;
       return (-1);
     }
   }
@@ -140,14 +135,12 @@ static int cldap_init_host(cldap_t *st) /* {{{ */
   if (rc != LDAP_SUCCESS) {
     ERROR("openldap plugin: Failed to bind to %s: %s", st->url,
           ldap_err2string(rc));
-    st->state = 0;
-    if (st->ld != NULL)
-      ldap_unbind_ext_s(st->ld, NULL, NULL);
+    ldap_unbind_ext_s(st->ld, NULL, NULL);
+    st->ld = NULL;
     return (-1);
   } else {
     DEBUG("openldap plugin: Successfully connected to %s", st->url);
-    st->state = 1;
-    return (0);
+    return 0;
   }
 } /* }}} static cldap_init_host */
 
@@ -200,14 +193,14 @@ static int cldap_read_host(user_data_t *ud) /* {{{ */
 
   if ((ud == NULL) || (ud->data == NULL)) {
     ERROR("openldap plugin: cldap_read_host: Invalid user data.");
-    return (-1);
+    return -1;
   }
 
   st = (cldap_t *)ud->data;
 
   status = cldap_init_host(st);
   if (status != 0)
-    return (-1);
+    return -1;
 
   rc = ldap_search_ext_s(st->ld, "cn=Monitor", LDAP_SCOPE_SUBTREE,
                          "(|(!(cn=* *))(cn=Database*))", attrs, 0, NULL, NULL,
@@ -216,9 +209,8 @@ static int cldap_read_host(user_data_t *ud) /* {{{ */
   if (rc != LDAP_SUCCESS) {
     ERROR("openldap plugin: Failed to execute search: %s", ldap_err2string(rc));
     ldap_msgfree(result);
-    st->state = 0;
-    if (st->ld != NULL)
-      ldap_unbind_ext_s(st->ld, NULL, NULL);
+    ldap_unbind_ext_s(st->ld, NULL, NULL);
+    st->ld = NULL;
     return (-1);
   }
 
@@ -376,7 +368,7 @@ static int cldap_read_host(user_data_t *ud) /* {{{ */
   }
 
   ldap_msgfree(result);
-  return (0);
+  return 0;
 } /* }}} int cldap_read_host */
 
 /* Configuration handling functions {{{
@@ -397,18 +389,18 @@ static int cldap_config_add(oconfig_item_t *ci) /* {{{ */
   st = calloc(1, sizeof(*st));
   if (st == NULL) {
     ERROR("openldap plugin: calloc failed.");
-    return (-1);
+    return -1;
   }
 
   status = cf_util_get_string(ci, &st->name);
   if (status != 0) {
     sfree(st);
-    return (status);
+    return status;
   }
 
-  st->starttls = 0;
+  st->starttls = false;
   st->timeout = (long)CDTIME_T_TO_TIME_T(plugin_get_interval());
-  st->verifyhost = 1;
+  st->verifyhost = true;
   st->version = LDAP_VERSION3;
 
   for (int i = 0; i < ci->children_num; i++) {
@@ -464,41 +456,25 @@ static int cldap_config_add(oconfig_item_t *ci) /* {{{ */
     ldap_free_urldesc(ludpp);
   }
 
-  if (status == 0) {
-    cldap_t **temp;
-
-    temp = (cldap_t **)realloc(databases,
-                               sizeof(*databases) * (databases_num + 1));
-
-    if (temp == NULL) {
-      ERROR("openldap plugin: realloc failed");
-      status = -1;
-    } else {
-      char callback_name[3 * DATA_MAX_NAME_LEN] = {0};
-
-      databases = temp;
-      databases[databases_num] = st;
-      databases_num++;
-
-      ssnprintf(callback_name, sizeof(callback_name), "openldap/%s/%s",
-                (st->host != NULL) ? st->host : hostname_g,
-                (st->name != NULL) ? st->name : "default");
-
-      status = plugin_register_complex_read(/* group = */ NULL,
-                                            /* name      = */ callback_name,
-                                            /* callback  = */ cldap_read_host,
-                                            /* interval  = */ 0, &(user_data_t){
-                                                                     .data = st,
-                                                                 });
-    }
-  }
-
   if (status != 0) {
     cldap_free(st);
-    return (-1);
+    return -1;
   }
 
-  return (0);
+  char callback_name[3 * DATA_MAX_NAME_LEN] = {0};
+
+  ssnprintf(callback_name, sizeof(callback_name), "openldap/%s/%s",
+            (st->host != NULL) ? st->host : hostname_g,
+            (st->name != NULL) ? st->name : "default");
+
+  return plugin_register_complex_read(/* group = */ NULL,
+                                      /* name      = */ callback_name,
+                                      /* callback  = */ cldap_read_host,
+                                      /* interval  = */ 0,
+                                      &(user_data_t){
+                                          .data = st,
+                                          .free_func = cldap_free,
+                                      });
 } /* }}} int cldap_config_add */
 
 static int cldap_config(oconfig_item_t *ci) /* {{{ */
@@ -518,7 +494,7 @@ static int cldap_config(oconfig_item_t *ci) /* {{{ */
               child->key);
   } /* for (ci->children) */
 
-  return (status);
+  return status;
 } /* }}} int cldap_config */
 
 /* }}} End of configuration handling functions */
@@ -529,25 +505,13 @@ static int cldap_init(void) /* {{{ */
    * ldap_initialize(3) */
   int debug_level;
   ldap_get_option(NULL, LDAP_OPT_DEBUG_LEVEL, &debug_level);
-  return (0);
+  return 0;
 } /* }}} int cldap_init */
 
-static int cldap_shutdown(void) /* {{{ */
-{
-  for (size_t i = 0; i < databases_num; i++)
-    if (databases[i]->ld != NULL)
-      ldap_unbind_ext_s(databases[i]->ld, NULL, NULL);
-  sfree(databases);
-  databases_num = 0;
-
-  return (0);
-} /* }}} int cldap_shutdown */
-
 void module_register(void) /* {{{ */
 {
   plugin_register_complex_config("openldap", cldap_config);
   plugin_register_init("openldap", cldap_init);
-  plugin_register_shutdown("openldap", cldap_shutdown);
 } /* }}} void module_register */
 
 #if defined(__APPLE__)