Assign default group to newly created devices
[strongswan.git] / src / libimcv / imv / imv_policy_manager.c
index 12fa7d2..737929a 100644 (file)
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <time.h>
+
+/* The default policy group #1 is assumed to always exist */
+#define DEFAULT_GROUP_ID       1
 
 /**
  * global debug output variables
  */
-static int debug_level = 2;
+static int debug_level = 1;
 static bool stderr_quiet = FALSE;
 
 /**
@@ -50,15 +54,17 @@ static void stderr_dbg(debug_t group, level_t level, char *fmt, ...)
 bool policy_start(database_t *db, int session_id)
 {
        enumerator_t *e;
-       int id, gid, device_id, product_id, group_id = 0;
-       int type, rec_fail, rec_noresult;
+       int id, gid, device_id, product_id, group_id = 0, parent;
+       int type, file, dir, arg_int, rec_fail, rec_noresult;
+       u_int created;
        char *argument;
 
        /* get session data */
        e = db->query(db,
-                       "SELECT device, product FROM sessions WHERE id = ? ",
-                        DB_INT, session_id, DB_INT, DB_INT);
-       if (!e || !e->enumerate(e, &device_id, &product_id))
+                       "SELECT s.device, s.product, d.created FROM sessions AS s "
+                       "LEFT JOIN devices AS d ON s.device = d.id WHERE s.id = ?",
+                        DB_INT, session_id, DB_INT, DB_INT, DB_UINT);
+       if (!e || !e->enumerate(e, &device_id, &product_id, &created))
        {
                DESTROY_IF(e);
                fprintf(stderr, "session %d not found\n", session_id);
@@ -70,7 +76,7 @@ bool policy_start(database_t *db, int session_id)
        if (device_id)
        {
                e = db->query(db,
-                               "SELECT group_id FROM group_members WHERE device = ?",
+                               "SELECT group_id FROM groups_members WHERE device_id = ?",
                                 DB_INT, device_id, DB_INT);
                if (e)
                {
@@ -80,14 +86,26 @@ bool policy_start(database_t *db, int session_id)
                        }
                        e->destroy(e);
                }
+
+               /* set the creation date if hasn't been set yet */
+               if (!created)
+               {
+                       if (db->execute(db, NULL,
+                                       "UPDATE devices SET created = ? WHERE id = ?",
+                                       DB_UINT, time(NULL), DB_INT, device_id) != 1)
+                       {
+                               fprintf(stderr, "creation date of device could not be set\n");
+                               return FALSE;
+                       }
+               }
        }
 
        /* if no group membership found, try default product group */
        if (!group_id)
        {
                e = db->query(db,
-                               "SELECT group_id FROM default_product_groups WHERE product = ?",
-                                DB_INT, product_id, DB_INT);
+                               "SELECT group_id FROM groups_product_defaults "
+                               "WHERE product_id = ?", DB_INT, product_id, DB_INT);
                if (e)
                {
                        if (e->enumerate(e, &gid))
@@ -98,38 +116,80 @@ bool policy_start(database_t *db, int session_id)
                }
        }
 
-       /* if still no group membership found, leave */
-       if (!group_id)
+       /* assign a newly created device to a default group */
+       if (device_id && !created)
        {
-               fprintf(stderr, "no group membership found\n");
-               return TRUE;
+               db->execute(db, NULL,
+                       "INSERT INTO groups_members (device_id, group_id) "
+                       "VALUES (?, ?)", DB_INT, device_id,
+                       DB_INT, group_id ? group_id : DEFAULT_GROUP_ID);
        }
 
-       /* get enforcements for given group */
-       e = db->query(db,
-                       "SELECT e.id, p.type, p.argument, p.rec_fail, p.rec_noresult "
-                       "FROM enforcements AS e JOIN policies as p ON  e.policy = p.id "
-                       "WHERE e.group_id = ?",
-                        DB_INT, group_id, DB_INT, DB_INT, DB_TEXT, DB_INT, DB_INT);
-       if (!e)
-       {
-               return FALSE;
-       }
-       while (e->enumerate(e, &id, &type, &argument, &rec_fail, &rec_noresult))
+       /* get iteratively enforcements for given group */
+       while (group_id)
        {
-               /* insert a workitem */
-               if (db->execute(db, NULL,
-                               "INSERT INTO workitems (session, enforcement, type, argument, "
-                               "rec_fail, rec_noresult) VALUES (?, ?, ?, ?, ?, ?)",
+               e = db->query(db,
+                               "SELECT e.id, "
+                               "p.type, p.argument, p.file, p.dir, p.rec_fail, p.rec_noresult "
+                               "FROM enforcements AS e JOIN policies as p ON e.policy = p.id "
+                               "WHERE e.group_id = ?", DB_INT, group_id,
+                                DB_INT, DB_INT, DB_TEXT, DB_INT, DB_INT, DB_INT, DB_INT);
+               if (!e)
+               {
+                       return FALSE;
+               }
+               while (e->enumerate(e, &id, &type, &argument, &file, &dir,
+                                                          &rec_fail, &rec_noresult))
+               {
+                       /* determine arg_int */
+                       switch ((imv_workitem_type_t)type)
+                       {
+                               case IMV_WORKITEM_FILE_REF_MEAS:
+                               case IMV_WORKITEM_FILE_MEAS:
+                               case IMV_WORKITEM_FILE_META:
+                                       arg_int = file;
+                                       break;
+                               case IMV_WORKITEM_DIR_REF_MEAS:
+                               case IMV_WORKITEM_DIR_MEAS:
+                               case IMV_WORKITEM_DIR_META:
+                                       arg_int = dir;
+                                       break;
+                               default:
+                                       arg_int = 0;
+                       }
+
+                       /* insert a workitem */
+                       if (db->execute(db, NULL,
+                               "INSERT INTO workitems (session, enforcement, type, arg_str, "
+                               "arg_int, rec_fail, rec_noresult) VALUES (?, ?, ?, ?, ?, ?, ?)",
                                DB_INT, session_id, DB_INT, id, DB_INT, type, DB_TEXT, argument,
-                               DB_INT, rec_fail, DB_INT, rec_noresult) != 1)
+                               DB_INT, arg_int, DB_INT, rec_fail, DB_INT, rec_noresult) != 1)
+                       {
+                               e->destroy(e);
+                               fprintf(stderr, "could not insert workitem\n");
+                               return FALSE;
+                       }
+               }
+               e->destroy(e);
+
+               e = db->query(db,
+                               "SELECT parent FROM groups WHERE id = ?",
+                                DB_INT, group_id, DB_INT);
+               if (!e)
                {
-                       e->destroy(e);
-                       fprintf(stderr, "could not insert workitem\n");
                        return FALSE;
                }
+               if (e->enumerate(e, &parent))
+               {
+                       group_id = parent;
+               }
+               else
+               {
+                       fprintf(stderr, "group information not found\n");
+                       group_id = 0;
+               }
+               e->destroy(e);
        }
-       e->destroy(e);
 
        return TRUE;
 }
@@ -139,34 +199,26 @@ bool policy_stop(database_t *db, int session_id)
        enumerator_t *e;
        int rec, policy;
        char *result;
-       bool no_worklists = TRUE;
 
        e = db->query(db,
                        "SELECT w.rec_final, w.result, e.policy FROM workitems AS w "
-                       "JOIN enforcements AS e ON w.enforcement = e.id WHERE w.session = ?",
+                       "JOIN enforcements AS e ON w.enforcement = e.id "
+                       "WHERE w.session = ? AND w.result IS NOT NULL",
                         DB_INT, session_id, DB_INT, DB_TEXT, DB_INT);
        if (e)
        {
                while (e->enumerate(e, &rec, &result, &policy))
                {
-                       no_worklists = FALSE;
-
-                       /* insert result */
                        db->execute(db, NULL,
                                "INSERT INTO results (session, policy, rec, result) "
                                "VALUES (?, ?, ?, ?)", DB_INT, session_id, DB_INT, policy,
                                 DB_INT, rec, DB_TEXT, result);
                }
                e->destroy(e);
-
-               if (no_worklists)
-               {
-                       return TRUE;
-               }
        }
        return db->execute(db, NULL,
                                "DELETE FROM workitems WHERE session = ?",
-                               DB_UINT, session_id) > 0;
+                               DB_UINT, session_id) >= 0;
 }
 
 int main(int argc, char *argv[])
@@ -223,6 +275,12 @@ int main(int argc, char *argv[])
        
        /* attach IMV database */
        uri = lib->settings->get_str(lib->settings, "libimcv.database", NULL);
+       if (!uri)
+       {
+               fprintf(stderr, "database uri not defined.\n");
+               exit(SS_RC_INITIALIZATION_FAILED);
+       }
+
        db = lib->db->create(lib->db, uri);
        if (!db)
        {
@@ -245,4 +303,3 @@ int main(int argc, char *argv[])
 
        exit(EXIT_SUCCESS);
 }
-