diff --git a/warden3/warden_server/warden3.0-alpha.sql b/warden3/warden_server/warden3.0-alpha.sql
index ab668c7d0d836b39dadb310e59d28d07704b49ef..3afc10405707311dd74c5b6a6b901264701fb7d1 100644
--- a/warden3/warden_server/warden3.0-alpha.sql
+++ b/warden3/warden_server/warden3.0-alpha.sql
@@ -176,11 +176,11 @@ CREATE TABLE IF NOT EXISTS `event_tag_mapping` (
 
 CREATE TABLE IF NOT EXISTS `last_events` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
-  `service_id` int(11) NOT NULL,
+  `client_id` int(11) NOT NULL,
   `event_id` int(11) NOT NULL,
   `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
   PRIMARY KEY (`id`),
-  KEY `service_id` (`service_id`,`event_id`)
+  KEY `client_id` (`client_id`,`event_id`)
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
 
 -- --------------------------------------------------------
diff --git a/warden3/warden_server/warden_server.py b/warden3/warden_server/warden_server.py
index 4be435506b28d84c2b892e38c0558afe8775125f..d1701e572779f9b2b77503f3758b375d37a3ac97 100755
--- a/warden3/warden_server/warden_server.py
+++ b/warden3/warden_server/warden_server.py
@@ -193,32 +193,42 @@ class X509Authenticator(NoAuthenticator):
 
 
     def authorize(self, env, client, method, event, args):
-        logging.debug("authorize: Client: " + str(client))
-       
         # Authorize for debug
         if (method == 'getDebug'):
-            return client if client[0]['debug'] == 1 else None
-
-        cl = None
-        identity = event['Node'][0]['Name']
-        test = 'Test' in event['Category']        
-        
-        logging.debug("Event identity: " + identity)
+            if not client["debug"]:
+                logging.info("Auth failed: client does not have debug enabled")
+                return None
+            return client
 
-        for clx in client:
-            if clx['identity'] == identity:
-                cl = clx
-                break
+        try:
+            identity = event['Node'][0]['Name'].lower()
+        except KeyError:
+            # Event does not bear valid Node attribute
+            logging.info("Auth failed: event does not bear valid Node attribute")
+            return None
 
-        if cl is None:
+        try:
+            service = client["services"][identity]
+        except KeyError:
+            # We are unable to pair service in message to service in db
+            logging.info("Auth failed: '%s' from event not found in services for client %i" % (identity, client["id"]))
             return None
+
+        client["service"] = service
         
         # Authorize for sending events
-        if ((method == 'sendEvents' and cl['write'] == 1) or
-            (method == 'sendEvents' and cl['test'] == 1 and test)):
-            return cl
-
-        return None
+        if (method == "sendEvents"):
+            if not (service["write"] or service["test"]):
+                logging.info("Auth failed: service %i (%s) is not allowed to write or test" % (service["service_id"], identity))
+                return None
+
+            test = 'Test' in event.get('Category', [])
+            if not test:
+                logging.info("Auth failed: service %i (%s) does not send Test category in event" % (service["service_id"], identity))
+                return None
+        
+        return client
+        
 
 class NoValidator(Object):
 
@@ -280,10 +290,26 @@ class MySQL(Object):
     def get_client_by_name(self, name):
         format_strings = ','.join(['%s'] * len(name))
         self.crs.execute("SELECT cl.`id`, cl.`hostname`, s.`service`, s.`service_id`, s.`identity`, cl.`read`, s.`write`, s.`test`, cl.`debug` FROM `clients` cl LEFT JOIN `services` s ON cl.`id` = s.`client_id` WHERE cl.`valid` = 1 AND s.`valid` = 1 AND `hostname` IN (%s)" % format_strings, tuple(name))
-        row = self.crs.fetchall()
-        logging.debug("Client/service info: " + str(row))
-        
-        return row if row else None
+        rows = self.crs.fetchall()
+        logging.debug("Client/service info: " + str(rows))
+        if not rows:
+            return None
+
+        client = {}
+        for n in ["id", "hostname", "read", "debug"]:
+            client[n] = rows[0][n]
+
+        services = {}
+        for row in rows:
+            service = {}
+            for n in ["service", "service_id", "identity", "write", "test"]:
+                service[n] = row[n]
+            services[row["identity"]] = service
+
+        client["services"] = services
+
+        logging.debug("Client/service formatted info: " + str(client))
+        return client
 
 
     def get_debug(self):
@@ -331,12 +357,12 @@ class MySQL(Object):
         if cat is not None or nocat is not None:
             if cat is not None:
                 parent_cats = []
-                sqltemp['cat'] = generateDynamicQuery(self, "Category", "category_id IN (%s)", json.loads(cat), parent_cats)
+                sqltemp['cat'] = self.generateDynamicQuery("Category", "category_id IN (%s)", json.loads(cat), parent_cats)
                 for pcats in parent_cats:
                     sqltemp['cat'] += " %s category_id DIV %s = 1 " % (("OR" if sqltemp['cat'] else ""), pcats)
             if nocat is not None:
                 parent_cats = []
-                sqltemp['cat'] = generateDynamicQuery(self, "Category", "category_id NOT IN (%s)", json.loads(nocat), parent_cats)
+                sqltemp['cat'] = self.generateDynamicQuery("Category", "category_id NOT IN (%s)", json.loads(nocat), parent_cats)
                 for pcats in parent_cats:
                     sqltemp['cat'] += " %s category_id DIV %s = 1 " % (("OR" if sqltemp['cat'] else ""), pcats)
                 
@@ -348,9 +374,9 @@ class MySQL(Object):
 
         if tag is not None or notag is not None:
             if tag is not None:
-                sqltemp['tag'] = generateDynamicQuery(self, "Tag", "tag_id IN (%s)", json.loads(tag))
+                sqltemp['tag'] = self.generateDynamicQuery("Tag", "tag_id IN (%s)", json.loads(tag))
             if notag is not None:
-                sqltemp['tag'] = generateDynamicQuery(self, "Tag", "tag_id NOT IN (%s)", json.loads(notag))
+                sqltemp['tag'] = self.generateDynamicQuery("Tag", "tag_id NOT IN (%s)", json.loads(notag))
             
             sqlwhere.append("e.id IN (SELECT event_id FROM event_tag_mapping WHERE %s)" % sqltemp['tag'])
 
@@ -402,8 +428,8 @@ class MySQL(Object):
         
         for event in events:
             try:
-                # logging.debug("INSERT INTO events (detected,received,service_id,data) VALUES ('%s', NOW(), '%s', '%s')" % (event['DetectTime'], client['id'], self.con.escape_string(str(event))))
-                self.crs.execute("INSERT INTO events (detected,received,service_id,data) VALUES ('%s', NOW(), '%s', '%s')" % (event['DetectTime'], client['service_id'], self.con.escape_string(str(event))))
+                # logging.debug("INSERT INTO events (detected,received,service_id,data) VALUES ('%s', NOW(), '%s', '%s')" % (event['DetectTime'], client["service"]["service_id"], self.con.escape_string(str(event))))
+                self.crs.execute("INSERT INTO events (detected,received,service_id,data) VALUES ('%s', NOW(), '%s', '%s')" % (event['DetectTime'], client["service"]["service_id"], self.con.escape_string(str(event))))
                 lastid = self.crs.lastrowid
                 # logging.debug(str(lastid))
                 for cat in event['Category']:
@@ -427,8 +453,8 @@ class MySQL(Object):
         return errs
 
     def insertLastReceivedId(self, client, id):
-        logging.debug("INSERT INTO last_events(service_id, event_id, timestamp) VALUES(%s, %s, NOW())" % (str(client[0]['service_id']), id))
-        self.crs.execute("INSERT INTO last_events(service_id, event_id, timestamp) VALUES(%s, %s, NOW())" % (str(client[0]['service_id']), id))
+        logging.debug("INSERT INTO last_events(client_id, event_id, timestamp) VALUES(%s, %s, NOW())" % (str(client["id"]), id))
+        self.crs.execute("INSERT INTO last_events(client_id, event_id, timestamp) VALUES(%s, %s, NOW())" % (str(client["id"]), id))
 
     def getLastEventId(self):
         self.crs.execute("SELECT MAX(id) as id FROM events")
@@ -437,12 +463,11 @@ class MySQL(Object):
         return row['id'] if row['id'] is not None else 0
 
     def getLastReceivedId(self, client):
-        logging.debug("IN getLastReceivedId")
-        service_id = client[0]['service_id'] 
-        logging.debug("getLastReceivedId (service_id) = %s", str(service_id))
+        client_id = client["id"] 
+        logging.debug("getLastReceivedId (client_id) = %s", str(client_id))
 
-        logging.debug("SELECT MAX(event_id) as id FROM last_events WHERE service_id = %s" % (str(service_id)))
-        self.crs.execute("SELECT MAX(event_id) as id FROM last_events WHERE service_id = %s" % (str(service_id)))
+        logging.debug("SELECT MAX(event_id) as id FROM last_events WHERE client_id = %s" % (str(client_id)))
+        self.crs.execute("SELECT MAX(event_id) as id FROM last_events WHERE client_id = %s" % (str(client_id)))
         row = self.crs.fetchone()
 
         logging.debug("getLastReceivedId - %s" % str(row['id']))
@@ -532,22 +557,24 @@ class MySQL(Object):
             return 0 if strict else data[section]['Other']
 
 
-def generateDynamicQuery(self, section, query_string, variables, parent_cats = []):
-    variables_id = []
-    # parent_cats = []
-
-    for v in variables:
-        mapped_id = self.map_id(section, v, True)
-        if mapped_id % 100 != 0:
-            variables_id.append(mapped_id)
-        else:
-            parent_cats.append(mapped_id)
-
-    # variables_id = [self.map_id(section, v) for v in variables if self.map_id(section, v) % 100 != 0]
-    format_strings = ','.join(['\'%s\''] * len(variables_id))
-    temp_string = query_string % format_strings
+    def generateDynamicQuery(self, section, query_string, variables, parent_cats = []):
+        variables_id = []
+        # parent_cats = []
+    
+        for v in variables:
+            mapped_id = self.map_id(section, v, True)
+            if mapped_id % 100 != 0:
+                variables_id.append(mapped_id)
+            else:
+                parent_cats.append(mapped_id)
     
-    return temp_string % tuple(variables_id)
+        # variables_id = [self.map_id(section, v) for v in variables if self.map_id(section, v) % 100 != 0]
+        format_strings = ','.join(['\'%s\''] * len(variables_id))
+        temp_string = query_string % format_strings
+        
+        return temp_string % tuple(variables_id)
+    
+
 
 def expose(meth):
     meth.exposed = True