Don't parse comma separated pool names in attr-sql
[strongswan.git] / src / libhydra / plugins / attr_sql / sql_attribute.c
index 7f7bb19..8055be7 100644 (file)
@@ -38,7 +38,7 @@ struct private_sql_attribute_t {
        database_t *db;
 
        /**
-        * wheter to record lease history in lease table
+        * whether to record lease history in lease table
         */
        bool history;
 };
@@ -232,12 +232,9 @@ static host_t* get_lease(private_sql_attribute_t *this, char *name,
        return NULL;
 }
 
-/**
- * Implementation of attribute_provider_t.acquire_address
- */
-static host_t* acquire_address(private_sql_attribute_t *this,
-                                                          char *names, identification_t *id,
-                                                          host_t *requested)
+METHOD(attribute_provider_t, acquire_address, host_t*,
+       private_sql_attribute_t *this, char *name, identification_t *id,
+       host_t *requested)
 {
        host_t *address = NULL;
        u_int identity, pool, timeout;
@@ -245,115 +242,60 @@ static host_t* acquire_address(private_sql_attribute_t *this,
        identity = get_identity(this, id);
        if (identity)
        {
-               /* check for a single pool first (no concatenation and enumeration) */
-               if (strchr(names, ',') == NULL)
-               {
-                       pool = get_pool(this, names, &timeout);
-                       if (pool)
-                       {
-                               /* check for an existing lease */
-                               address = check_lease(this, names, pool, identity);
-                               if (address == NULL)
-                               {
-                                       /* get an unallocated address or expired lease */
-                                       address = get_lease(this, names, pool, timeout, identity);
-                               }
-                       }
-               }
-               else
+               pool = get_pool(this, name, &timeout);
+               if (pool)
                {
-                       enumerator_t *enumerator;
-                       char *name;
-
-                       /* in a first step check for an existing lease over all pools */
-                       enumerator = enumerator_create_token(names, ",", " ");
-                       while (enumerator->enumerate(enumerator, &name))
+                       /* check for an existing lease */
+                       address = check_lease(this, name, pool, identity);
+                       if (address == NULL)
                        {
-                               pool = get_pool(this, name, &timeout);
-                               if (pool)
-                               {
-                                       address = check_lease(this, name, pool, identity);
-                                       if (address)
-                                       {
-                                               enumerator->destroy(enumerator);
-                                               return address;
-                                       }
-                               }
-                       }
-                       enumerator->destroy(enumerator);
-
-                       /* in a second step get an unallocated address or expired lease */
-                       enumerator = enumerator_create_token(names, ",", " ");
-                       while (enumerator->enumerate(enumerator, &name))
-                       {
-                               pool = get_pool(this, name, &timeout);
-                               if (pool)
-                               {
-                                       address = get_lease(this, name, pool, timeout, identity);
-                                       if (address)
-                                       {
-                                               break;
-                                       }
-                               }
+                               /* get an unallocated address or expired lease */
+                               address = get_lease(this, name, pool, timeout, identity);
                        }
-                       enumerator->destroy(enumerator);
                }
        }
        return address;
 }
 
-/**
- * Implementation of attribute_provider_t.release_address
- */
-static bool release_address(private_sql_attribute_t *this,
-                                                       char *name, host_t *address, identification_t *id)
+METHOD(attribute_provider_t, release_address, bool,
+       private_sql_attribute_t *this, char *name, host_t *address,
+       identification_t *id)
 {
-       enumerator_t *enumerator;
-       bool found = FALSE;
+       u_int pool, timeout;
        time_t now = time(NULL);
 
-       enumerator = enumerator_create_token(name, ",", " ");
-       while (enumerator->enumerate(enumerator, &name))
+       pool = get_pool(this, name, &timeout);
+       if (pool)
        {
-               u_int pool, timeout;
-
-               pool = get_pool(this, name, &timeout);
-               if (pool)
+               if (this->history)
                {
-                       if (this->history)
-                       {
-                               this->db->execute(this->db, NULL,
-                                       "INSERT INTO leases (address, identity, acquired, released)"
-                                       " SELECT id, identity, acquired, ? FROM addresses "
-                                       " WHERE pool = ? AND address = ?",
-                                       DB_UINT, now, DB_UINT, pool,
-                                       DB_BLOB, address->get_address(address));
-                       }
-                       if (this->db->execute(this->db, NULL,
-                                       "UPDATE addresses SET released = ? WHERE "
-                                       "pool = ? AND address = ?", DB_UINT, time(NULL),
-                                       DB_UINT, pool, DB_BLOB, address->get_address(address)) > 0)
-                       {
-                               found = TRUE;
-                               break;
-                       }
+                       this->db->execute(this->db, NULL,
+                               "INSERT INTO leases (address, identity, acquired, released)"
+                               " SELECT id, identity, acquired, ? FROM addresses "
+                               " WHERE pool = ? AND address = ?",
+                               DB_UINT, now, DB_UINT, pool,
+                               DB_BLOB, address->get_address(address));
+               }
+               if (this->db->execute(this->db, NULL,
+                               "UPDATE addresses SET released = ? WHERE "
+                               "pool = ? AND address = ?", DB_UINT, time(NULL),
+                               DB_UINT, pool, DB_BLOB, address->get_address(address)) > 0)
+               {
+                       return TRUE;
                }
        }
-       enumerator->destroy(enumerator);
-       return found;
+       return FALSE;
 }
 
-/**
- * Implementation of sql_attribute_t.create_attribute_enumerator
- */
-static enumerator_t* create_attribute_enumerator(private_sql_attribute_t *this,
-                                                               char *names, identification_t *id, host_t *vip)
+METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
+       private_sql_attribute_t *this, linked_list_t *pools, identification_t *id,
+       linked_list_t *vips)
 {
        enumerator_t *attr_enumerator = NULL;
 
-       if (vip)
+       if (vips->get_count(vips))
        {
-               enumerator_t *names_enumerator;
+               enumerator_t *pool_enumerator;
                u_int count;
                char *name;
 
@@ -364,8 +306,8 @@ static enumerator_t* create_attribute_enumerator(private_sql_attribute_t *this,
                {
                        u_int identity = get_identity(this, id);
 
-                       names_enumerator = enumerator_create_token(names, ",", " ");
-                       while (names_enumerator->enumerate(names_enumerator, &name))
+                       pool_enumerator = pools->create_enumerator(pools);
+                       while (pool_enumerator->enumerate(pool_enumerator, &name))
                        {
                                u_int attr_pool = get_attr_pool(this, name);
                                if (!attr_pool)
@@ -392,14 +334,14 @@ static enumerator_t* create_attribute_enumerator(private_sql_attribute_t *this,
                                DESTROY_IF(attr_enumerator);
                                attr_enumerator = NULL;
                        }
-                       names_enumerator->destroy(names_enumerator);
+                       pool_enumerator->destroy(pool_enumerator);
                }
 
                /* in a second step check for attributes that match name */
                if (!attr_enumerator)
                {
-                       names_enumerator = enumerator_create_token(names, ",", " ");
-                       while (names_enumerator->enumerate(names_enumerator, &name))
+                       pool_enumerator = pools->create_enumerator(pools);
+                       while (pool_enumerator->enumerate(pool_enumerator, &name))
                        {
                                u_int attr_pool = get_attr_pool(this, name);
                                if (!attr_pool)
@@ -426,7 +368,7 @@ static enumerator_t* create_attribute_enumerator(private_sql_attribute_t *this,
                                DESTROY_IF(attr_enumerator);
                                attr_enumerator = NULL;
                        }
-                       names_enumerator->destroy(names_enumerator);
+                       pool_enumerator->destroy(pool_enumerator);
                }
 
                this->db->execute(this->db, NULL, "END TRANSACTION");
@@ -444,10 +386,8 @@ static enumerator_t* create_attribute_enumerator(private_sql_attribute_t *this,
        return (attr_enumerator ? attr_enumerator : enumerator_create_empty());
 }
 
-/**
- * Implementation of sql_attribute_t.destroy
- */
-static void destroy(private_sql_attribute_t *this)
+METHOD(sql_attribute_t, destroy, void,
+       private_sql_attribute_t *this)
 {
        free(this);
 }
@@ -457,17 +397,22 @@ static void destroy(private_sql_attribute_t *this)
  */
 sql_attribute_t *sql_attribute_create(database_t *db)
 {
-       private_sql_attribute_t *this = malloc_thing(private_sql_attribute_t);
+       private_sql_attribute_t *this;
        time_t now = time(NULL);
 
-       this->public.provider.acquire_address = (host_t*(*)(attribute_provider_t *this, char*, identification_t *, host_t *))acquire_address;
-       this->public.provider.release_address = (bool(*)(attribute_provider_t *this, char*,host_t *, identification_t*))release_address;
-       this->public.provider.create_attribute_enumerator = (enumerator_t*(*)(attribute_provider_t*, char *names, identification_t *id, host_t *host))create_attribute_enumerator;
-       this->public.destroy = (void(*)(sql_attribute_t*))destroy;
-
-       this->db = db;
-       this->history = lib->settings->get_bool(lib->settings,
-                                               "libhydra.plugins.attr-sql.lease_history", TRUE);
+       INIT(this,
+               .public = {
+                       .provider = {
+                               .acquire_address = _acquire_address,
+                               .release_address = _release_address,
+                               .create_attribute_enumerator = _create_attribute_enumerator,
+                       },
+                       .destroy = _destroy,
+               },
+               .db = db,
+               .history = lib->settings->get_bool(lib->settings,
+                                                       "libhydra.plugins.attr-sql.lease_history", TRUE),
+       );
 
        /* close any "online" leases in the case we crashed */
        if (this->history)