DCI access control server side refactoring (access list stored in separate table...
authorVictor Kirhenshtein <victor@netxms.org>
Sun, 12 Nov 2017 16:10:41 +0000 (18:10 +0200)
committerVictor Kirhenshtein <victor@netxms.org>
Sun, 12 Nov 2017 16:10:41 +0000 (18:10 +0200)
sql/schema.in
src/server/core/datacoll.cpp
src/server/core/dcitem.cpp
src/server/core/dcobject.cpp
src/server/core/dctable.cpp
src/server/core/template.cpp
src/server/core/userdb_objects.cpp
src/server/include/nms_dcoll.h
src/server/include/nms_objects.h
src/server/tools/nxdbmgr/upgrade_v22.cpp
src/server/tools/nxdbmgr/upgrade_v30.cpp

index be2cb69..446b52f 100644 (file)
@@ -759,6 +759,16 @@ CREATE TABLE raw_dci_values
 CREATE INDEX idx_raw_dci_values_item_id ON raw_dci_values(item_id);
 #endif
 
+/**
+ * DCI level access control
+ */
+CREATE TABLE dci_access
+(
+   dci_id integer not null,
+   user_id integer not null,
+   PRIMARY KEY(dci_id,user_id);
+) TABLE_TYPE;
+
 /*
 ** Events configuration
 */
index 8f0acf9..ae014b6 100644 (file)
@@ -506,7 +506,7 @@ static THREAD_RESULT THREAD_CALL StatCollector(void *pArg)
 THREAD_RESULT THREAD_CALL CacheLoader(void *arg)
 {
    ThreadSetName("CacheLoader");
-   DbgPrintf(2, _T("DCI cache loader thread started"));
+   nxlog_debug_tag(_T("obj.dc.cache"), 2, _T("DCI cache loader thread started"));
    while(true)
    {
       DCObjectInfo *ref = (DCObjectInfo *)g_dciCacheLoaderQueue.getOrBlock();
@@ -528,7 +528,7 @@ THREAD_RESULT THREAD_CALL CacheLoader(void *arg)
       }
       delete ref;
    }
-   DbgPrintf(2, _T("DCI cache loader thread stopped"));
+   nxlog_debug_tag(_T("obj.dc.cache"), 2, _T("DCI cache loader thread stopped"));
    return THREAD_OK;
 }
 
index 27082d2..7416779 100644 (file)
@@ -101,7 +101,7 @@ DCItem::DCItem(const DCItem *pSrc) : DCObject(pSrc)
  *    delta_calculation,transformation,template_id,description,instance,
  *    template_item_id,flags,resource_id,proxy_node,base_units,unit_multiplier,
  *    custom_units_name,perftab_settings,system_tag,snmp_port,snmp_raw_value_type,
- *    instd_method,instd_data,instd_filter,samples,comments,guid,npe_name,visibility_rights
+ *    instd_method,instd_data,instd_filter,samples,comments,guid,npe_name
  */
 DCItem::DCItem(DB_HANDLE hdb, DB_RESULT hResult, int iRow, Template *pNode) : DCObject()
 {
@@ -148,16 +148,6 @@ DCItem::DCItem(DB_HANDLE hdb, DB_RESULT hResult, int iRow, Template *pNode) : DC
    m_comments = DBGetField(hResult, iRow, 27, NULL, 0);
    m_guid = DBGetFieldGUID(hResult, iRow, 28);
    DBGetField(hResult, iRow, 29, m_predictionEngine, MAX_NPE_NAME_LEN);
-   //set visibility rights
-   pszTmp = DBGetField(hResult, iRow, 30, NULL, 0);
-   StringList list;
-   list.splitAndAdd(pszTmp, _T(","));
-   for(int i = 0; i < list.size(); i++)
-   {
-      if (*(list.get(i)) != 0)
-         m_visibilityRights->add(_tcstol(list.get(i), NULL, 0));
-   }
-   free(pszTmp);
 
    // Load last raw value from database
        TCHAR szQuery[256];
@@ -175,6 +165,7 @@ DCItem::DCItem(DB_HANDLE hdb, DB_RESULT hResult, int iRow, Template *pNode) : DC
       DBFreeResult(hTempResult);
    }
 
+   loadAccessList(hdb);
        loadCustomSchedules(hdb);
 }
 
@@ -332,7 +323,7 @@ bool DCItem::saveToDatabase(DB_HANDLE hdb)
                           _T("unit_multiplier=?,custom_units_name=?,perftab_settings=?,")
                      _T("system_tag=?,snmp_port=?,snmp_raw_value_type=?,")
                                          _T("instd_method=?,instd_data=?,instd_filter=?,samples=?,")
-                                         _T("comments=?,guid=?,npe_name=?,visibility_rights=? WHERE item_id=?"));
+                                         _T("comments=?,guid=?,npe_name=? WHERE item_id=?"));
        }
    else
        {
@@ -342,8 +333,8 @@ bool DCItem::saveToDatabase(DB_HANDLE hdb)
                  _T("transformation,description,instance,template_item_id,flags,")
                  _T("resource_id,proxy_node,base_units,unit_multiplier,")
                           _T("custom_units_name,perftab_settings,system_tag,snmp_port,snmp_raw_value_type,")
-                                         _T("instd_method,instd_data,instd_filter,samples,comments,guid,npe_name,visibility_rights,item_id) VALUES ")
-                          _T("(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"));
+                                         _T("instd_method,instd_data,instd_filter,samples,comments,guid,npe_name,item_id) VALUES ")
+                          _T("(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"));
        }
        if (hStmt == NULL)
                return false;
@@ -380,16 +371,7 @@ bool DCItem::saveToDatabase(DB_HANDLE hdb)
    DBBind(hStmt, 28, DB_SQLTYPE_TEXT, m_comments, DB_BIND_STATIC);
    DBBind(hStmt, 29, DB_SQLTYPE_VARCHAR, m_guid);
    DBBind(hStmt, 30, DB_SQLTYPE_VARCHAR, m_predictionEngine, DB_BIND_STATIC);
-   String tmp;
-   int size = m_visibilityRights->size();
-   for(int i = 0; i < size; i++)
-   {
-      tmp.append(m_visibilityRights->get(i));
-      if(i != (size - 1))
-         tmp.append(_T(','));
-   }
-   DBBind(hStmt, 31, DB_SQLTYPE_VARCHAR, tmp, DB_BIND_STATIC);
-       DBBind(hStmt, 32, DB_SQLTYPE_INTEGER, m_id);
+       DBBind(hStmt, 31, DB_SQLTYPE_INTEGER, m_id);
 
    bool bResult = DBExecute(hStmt);
        DBFreeStatement(hStmt);
index 0730bd7..edf31c5 100644 (file)
@@ -70,7 +70,7 @@ DCObject::DCObject()
    m_instanceFilterSource = NULL;
    m_instanceFilter = NULL;
    m_instance[0] = 0;
-   m_visibilityRights = new IntegerArray<UINT32>();
+   m_accessList = new IntegerArray<UINT32>(0, 16);
 }
 
 /**
@@ -116,7 +116,7 @@ DCObject::DCObject(const DCObject *pSrc)
    m_instanceFilter = NULL;
    setInstanceFilter(pSrc->m_instanceFilterSource);
    _tcscpy(m_instance, pSrc->m_instance);
-   m_visibilityRights = new IntegerArray<UINT32>(pSrc->m_visibilityRights);
+   m_accessList = new IntegerArray<UINT32>(pSrc->m_accessList);
 }
 
 /**
@@ -162,7 +162,7 @@ DCObject::DCObject(UINT32 dwId, const TCHAR *szName, int iSource,
    m_instanceFilterSource = NULL;
    m_instanceFilter = NULL;
    m_instance[0] = 0;
-   m_visibilityRights = new IntegerArray<UINT32>();
+   m_accessList = new IntegerArray<UINT32>(0, 16);
 }
 
 /**
@@ -228,7 +228,7 @@ DCObject::DCObject(ConfigEntry *config, Template *owner)
    m_instanceFilter = NULL;
    setInstanceFilter(config->getSubEntryValue(_T("instanceFilter")));
    nx_strncpy(m_instance, config->getSubEntryValue(_T("instance"), 0, _T("")), MAX_DB_STRING);
-   m_visibilityRights = new IntegerArray<UINT32>();
+   m_accessList = new IntegerArray<UINT32>(0, 16);
 }
 
 /**
@@ -245,7 +245,33 @@ DCObject::~DCObject()
    free(m_instanceDiscoveryData);
    free(m_instanceFilterSource);
    delete m_instanceFilter;
-   delete m_visibilityRights;
+   delete m_accessList;
+}
+
+/**
+ * Load access list
+ */
+bool DCObject::loadAccessList(DB_HANDLE hdb)
+{
+   m_accessList->clear();
+
+   DB_STATEMENT hStmt = DBPrepare(hdb, _T("SELECT user_id FROM dci_access WHERE dci_id=?"));
+   if (hStmt == NULL)
+      return false;
+
+   DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, m_id);
+   DB_RESULT hResult = DBSelectPrepared(hStmt);
+   if (hResult != NULL)
+   {
+      int count = DBGetNumRows(hResult);
+      for(int i = 0; i < count; i++)
+      {
+         m_accessList->add(DBGetFieldULong(hResult, i, 0));
+      }
+      DBFreeResult(hResult);
+   }
+   DBFreeStatement(hStmt);
+   return hResult != NULL;
 }
 
 /**
@@ -257,10 +283,12 @@ bool DCObject::loadCustomSchedules(DB_HANDLE hdb)
    if (!(m_flags & DCF_ADVANCED_SCHEDULE))
                return true;
 
-       TCHAR query[256];
+   DB_STATEMENT hStmt = DBPrepare(hdb, _T("SELECT schedule FROM dci_schedules WHERE item_id=?"));
+   if (hStmt == NULL)
+      return false;
 
-   _sntprintf(query, 256, _T("SELECT schedule FROM dci_schedules WHERE item_id=%d"), m_id);
-   DB_RESULT hResult = DBSelect(hdb, query);
+   DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, m_id);
+   DB_RESULT hResult = DBSelectPrepared(hStmt);
    if (hResult != NULL)
    {
       int count = DBGetNumRows(hResult);
@@ -274,7 +302,7 @@ bool DCObject::loadCustomSchedules(DB_HANDLE hdb)
       }
       DBFreeResult(hResult);
    }
-
+   DBFreeStatement(hStmt);
        return hResult != NULL;
 }
 
@@ -697,7 +725,7 @@ void DCObject::createMessage(NXCPMessage *pMsg)
    if (m_instanceFilterSource != NULL)
       pMsg->setField(VID_INSTD_FILTER, m_instanceFilterSource);
    pMsg->setField(VID_INSTANCE, m_instance);
-   pMsg->setFieldFromInt32Array(VID_ACL, m_visibilityRights);
+   pMsg->setFieldFromInt32Array(VID_ACL, m_accessList);
    unlock();
 }
 
@@ -718,14 +746,17 @@ void DCObject::updateFromMessage(NXCPMessage *pMsg)
    setStatus(pMsg->getFieldAsUInt16(VID_DCI_STATUS), true);
        m_dwResourceId = pMsg->getFieldAsUInt32(VID_RESOURCE_ID);
        m_sourceNode = pMsg->getFieldAsUInt32(VID_AGENT_PROXY);
-       safe_free(m_pszPerfTabSettings);
+   m_snmpPort = pMsg->getFieldAsUInt16(VID_SNMP_PORT);
+
+       free(m_pszPerfTabSettings);
        m_pszPerfTabSettings = pMsg->getFieldAsString(VID_PERFTAB_SETTINGS);
-       m_snmpPort = pMsg->getFieldAsUInt16(VID_SNMP_PORT);
-   TCHAR *pszStr = pMsg->getFieldAsString(VID_TRANSFORMATION_SCRIPT);
-   safe_free_and_null(m_comments);
+
+       free(m_comments);
    m_comments = pMsg->getFieldAsString(VID_COMMENTS);
+
+   TCHAR *pszStr = pMsg->getFieldAsString(VID_TRANSFORMATION_SCRIPT);
    setTransformationScript(pszStr);
-   safe_free(pszStr);
+   free(pszStr);
 
    // Update schedules
    int count = pMsg->getFieldAsInt32(VID_NUM_SCHEDULES);
@@ -753,15 +784,16 @@ void DCObject::updateFromMessage(NXCPMessage *pMsg)
 
    m_instanceDiscoveryMethod = pMsg->getFieldAsUInt16(VID_INSTD_METHOD);
 
-   safe_free(m_instanceDiscoveryData);
+   free(m_instanceDiscoveryData);
    m_instanceDiscoveryData = pMsg->getFieldAsString(VID_INSTD_DATA);
 
    pszStr = pMsg->getFieldAsString(VID_INSTD_FILTER);
    setInstanceFilter(pszStr);
-   safe_free(pszStr);
+   free(pszStr);
    pMsg->getFieldAsString(VID_INSTANCE, m_instance, MAX_DB_STRING);
-   m_visibilityRights->clear();
-   pMsg->getFieldAsInt32Array(VID_ACL, m_visibilityRights);
+
+   m_accessList->clear();
+   pMsg->getFieldAsInt32Array(VID_ACL, m_accessList);
 
        unlock();
 }
@@ -776,17 +808,45 @@ bool DCObject::saveToDatabase(DB_HANDLE hdb)
        lock();
 
    // Save schedules
-   _sntprintf(query, 1024, _T("DELETE FROM dci_schedules WHERE item_id=%d"), (int)m_id);
-   bool success = DBQuery(hdb, query);
-       if (success && (m_schedules != NULL))
+   bool success = ExecuteQueryOnObject(hdb, m_id, _T("DELETE FROM dci_schedules WHERE item_id=?"));
+       if (success && (m_schedules != NULL) && !m_schedules->isEmpty())
    {
-      for(int i = 0; i < m_schedules->size(); i++)
+          DB_STATEMENT hStmt = DBPrepare(hdb, _T("INSERT INTO dci_schedules (item_id,schedule_id,schedule) VALUES (?,?,?)"));
+          if (hStmt != NULL)
+          {
+             DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, m_id);
+         for(int i = 0; (i < m_schedules->size()) && success; i++)
+         {
+            DBBind(hStmt, 2, DB_SQLTYPE_INTEGER, i + 1);
+            DBBind(hStmt, 3, DB_SQLTYPE_VARCHAR, m_schedules->get(i), DB_BIND_STATIC);
+            success = DBExecute(hStmt);
+         }
+         DBFreeStatement(hStmt);
+          }
+          else
+          {
+             success = false;
+          }
+   }
+
+   // Save access list
+   success = ExecuteQueryOnObject(hdb, m_id, _T("DELETE FROM dci_access WHERE dci_id=?"));
+   if (success && !m_accessList->isEmpty())
+   {
+      DB_STATEMENT hStmt = DBPrepare(hdb, _T("INSERT INTO dci_access (dci_id,user_id) VALUES (?,?)"));
+      if (hStmt != NULL)
+      {
+         DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, m_id);
+         for(int i = 0; (i < m_accessList->size()) && success; i++)
+         {
+            DBBind(hStmt, 2, DB_SQLTYPE_INTEGER, m_accessList->get(i));
+            success = DBExecute(hStmt);
+         }
+         DBFreeStatement(hStmt);
+      }
+      else
       {
-         _sntprintf(query, 1024, _T("INSERT INTO dci_schedules (item_id,schedule_id,schedule) VALUES (%d,%d,%s)"),
-                    m_id, i + 1, (const TCHAR *)DBPrepareString(hdb, m_schedules->get(i)));
-         success = DBQuery(hdb, query);
-                       if (!success)
-                               break;
+         success = false;
       }
    }
 
@@ -1261,24 +1321,23 @@ void DCObject::setInstanceFilter(const TCHAR *pszScript)
  */
 bool DCObject::hasAccess(UINT32 userId)
 {
-   if(m_visibilityRights->isEmpty())
+   if (m_accessList->isEmpty())
       return true;
 
    if(userId == 0)
       return true;
 
-   for(int i = 0; i < m_visibilityRights->size(); i++)
+   for(int i = 0; i < m_accessList->size(); i++)
    {
-      UINT32 id = m_visibilityRights->get(i);
-      if((id & GROUP_FLAG) != 0)
+      UINT32 id = m_accessList->get(i);
+      if (id & GROUP_FLAG)
       {
-         if(CheckUserMembership(userId, id))
+         if (CheckUserMembership(userId, id))
             return true;
       }
-      else
+      else if (id == userId)
       {
-         if(id == userId)
-            return true;
+         return true;
       }
    }
    return false;
@@ -1318,7 +1377,7 @@ json_t *DCObject::toJson()
    json_object_set_new(root, "instanceDiscoveryData", json_string_t(m_instanceDiscoveryData));
    json_object_set_new(root, "instanceFilter", json_string_t(m_instanceFilterSource));
    json_object_set_new(root, "instance", json_string_t(m_instance));
-   json_object_set_new(root, "visibility", m_visibilityRights->toJson());
+   json_object_set_new(root, "accessList", m_accessList->toJson());
    return root;
 }
 
index c3c07a2..a6ee881 100644 (file)
@@ -160,7 +160,8 @@ DCTable::DCTable(UINT32 id, const TCHAR *name, int source, int pollingInterval,
  *    item_id,template_id,template_item_id,name,
  *    description,flags,source,snmp_port,polling_interval,retention_time,
  *    status,system_tag,resource_id,proxy_node,perftab_settings,
- *    transformation_script,comments,guid,visibility_rights
+ *    transformation_script,comments,guid,instd_method,instd_data,
+ *    instd_filter,instance
  */
 DCTable::DCTable(DB_HANDLE hdb, DB_RESULT hResult, int iRow, Template *pNode) : DCObject()
 {
@@ -184,6 +185,14 @@ DCTable::DCTable(DB_HANDLE hdb, DB_RESULT hResult, int iRow, Template *pNode) :
    m_guid = DBGetFieldGUID(hResult, iRow, 17);
    setTransformationScript(pszTmp);
    free(pszTmp);
+   m_instanceDiscoveryMethod = (WORD)DBGetFieldLong(hResult, iRow, 18);
+   m_instanceDiscoveryData = DBGetField(hResult, iRow, 19, NULL, 0);
+   m_instanceFilterSource = NULL;
+   m_instanceFilter = NULL;
+   pszTmp = DBGetField(hResult, iRow, 20, NULL, 0);
+   setInstanceFilter(pszTmp);
+   free(pszTmp);
+   DBGetField(hResult, iRow, 21, m_instance, MAX_DB_STRING);
 
    m_owner = pNode;
        m_columns = new ObjectArray<DCTableColumn>(8, 8, true);
@@ -204,29 +213,11 @@ DCTable::DCTable(DB_HANDLE hdb, DB_RESULT hResult, int iRow, Template *pNode) :
                DBFreeStatement(hStmt);
        }
 
-       loadCustomSchedules(hdb);
+   loadAccessList(hdb);
+   loadCustomSchedules(hdb);
 
    m_thresholds = new ObjectArray<DCTableThreshold>(0, 4, true);
    loadThresholds(hdb);
-
-   m_instanceDiscoveryMethod = (WORD)DBGetFieldLong(hResult, iRow, 18);
-   m_instanceDiscoveryData = DBGetField(hResult, iRow, 19, NULL, 0);
-   m_instanceFilterSource = NULL;
-   m_instanceFilter = NULL;
-   pszTmp = DBGetField(hResult, iRow, 20, NULL, 0);
-   setInstanceFilter(pszTmp);
-   free(pszTmp);
-   DBGetField(hResult, iRow, 21, m_instance, MAX_DB_STRING);
-   //set visibility rights
-   pszTmp = DBGetField(hResult, iRow, 21, NULL, 0);
-   StringList list;
-   list.splitAndAdd(pszTmp, _T(","));
-   for(int i = 0; i < list.size(); i++)
-   {
-      if(*(list.get(i)) != 0)
-         m_visibilityRights->add(_tcstol(list.get(i), NULL, 0));
-   }
-   free(pszTmp);
 }
 
 /**
@@ -499,16 +490,16 @@ bool DCTable::saveToDatabase(DB_HANDLE hdb)
                                       _T("description=?,flags=?,source=?,snmp_port=?,polling_interval=?,")
                              _T("retention_time=?,status=?,system_tag=?,resource_id=?,proxy_node=?,")
                                                                          _T("perftab_settings=?,transformation_script=?,comments=?,guid=?,")
-                                                                         _T("instd_method=?,instd_data=?,instd_filter=?,instance=?,visibility_rights=? WHERE item_id=?"));
+                                                                         _T("instd_method=?,instd_data=?,instd_filter=?,instance=? WHERE item_id=?"));
        }
        else
        {
                hStmt = DBPrepare(hdb, _T("INSERT INTO dc_tables (node_id,template_id,template_item_id,name,")
                                       _T("description,flags,source,snmp_port,polling_interval,")
                                       _T("retention_time,status,system_tag,resource_id,proxy_node,perftab_settings,")
-                                                                         _T("transformation_script,comments,guid, ")
-                                                                         _T("instd_method,instd_data,instd_filter,instance,visibility_rights,item_id) ")
-                                                                         _T("VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"));
+                                                                         _T("transformation_script,comments,guid,")
+                                                                         _T("instd_method,instd_data,instd_filter,instance,item_id) ")
+                                                                         _T("VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"));
        }
        if (hStmt == NULL)
                return FALSE;
@@ -537,16 +528,7 @@ bool DCTable::saveToDatabase(DB_HANDLE hdb)
    DBBind(hStmt, 20, DB_SQLTYPE_VARCHAR, m_instanceDiscoveryData, DB_BIND_STATIC);
    DBBind(hStmt, 21, DB_SQLTYPE_TEXT, m_instanceFilterSource, DB_BIND_STATIC);
    DBBind(hStmt, 22, DB_SQLTYPE_VARCHAR, m_instance, DB_BIND_STATIC);
-   String tmp;
-   int size = m_visibilityRights->size();
-   for(int i = 0; i < size; i++)
-   {
-      tmp.append(m_visibilityRights->get(i));
-      if(i != (size - 1))
-         tmp.append(_T(','));
-   }
-   DBBind(hStmt, 23, DB_SQLTYPE_VARCHAR, tmp, DB_BIND_STATIC);
-   DBBind(hStmt, 24, DB_SQLTYPE_INTEGER, m_id);
+   DBBind(hStmt, 23, DB_SQLTYPE_INTEGER, m_id);
 
        bool result = DBExecute(hStmt);
        DBFreeStatement(hStmt);
index 363b49a..04e9b3f 100644 (file)
@@ -383,7 +383,7 @@ void Template::loadItemsFromDB(DB_HANDLE hdb)
               _T("instance,template_item_id,flags,resource_id,")
               _T("proxy_node,base_units,unit_multiplier,custom_units_name,")
                   _T("perftab_settings,system_tag,snmp_port,snmp_raw_value_type,")
-                                 _T("instd_method,instd_data,instd_filter,samples,comments,guid,npe_name,visibility_rights ")
+                                 _T("instd_method,instd_data,instd_filter,samples,comments,guid,npe_name ")
                                  _T("FROM items WHERE node_id=?"));
        if (hStmt != NULL)
        {
@@ -403,7 +403,8 @@ void Template::loadItemsFromDB(DB_HANDLE hdb)
                   _T("SELECT item_id,template_id,template_item_id,name,")
                                  _T("description,flags,source,snmp_port,polling_interval,retention_time,")
               _T("status,system_tag,resource_id,proxy_node,perftab_settings,")
-              _T("transformation_script,comments,guid,instd_method,instd_data,instd_filter,instance,visibility_rights FROM dc_tables WHERE node_id=?"));
+              _T("transformation_script,comments,guid,instd_method,instd_data,")
+              _T("instd_filter,instance FROM dc_tables WHERE node_id=?"));
        if (hStmt != NULL)
        {
                DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, m_id);
@@ -483,13 +484,15 @@ bool Template::deleteDCObject(UINT32 dcObjectId, bool needLock, UINT32 userId)
                   i = m_dcObjects->indexOf(object);
             }
             // Destroy item
-            DbgPrintf(7, _T("Template::DeleteDCObject: deleting DCObject %d from object %d"), (int)dcObjectId, (int)m_id);
+            nxlog_debug_tag(_T("obj.dc"), 7, _T("Template::DeleteDCObject: deleting DCObject [%u] from object %s [%u]"), dcObjectId, m_name, m_id);
             destroyItem(object, i);
             success = true;
-            DbgPrintf(7, _T("Template::DeleteDCObject: DCO deleted from object %d"), (int)m_id);
+            nxlog_debug_tag(_T("obj.dc"), 7, _T("Template::DeleteDCObject: DCObject deleted from object %s [%u]"), m_name, m_id);
          }
          else
-            DbgPrintf(3, _T("Template::DeleteDCObject: access denied DCO %d"), (int)m_id);
+         {
+            nxlog_debug_tag(_T("obj.dc"), 6, _T("Template::DeleteDCObject: denied access to DCObject %u for user %u"), dcObjectId, userId);
+         }
          break;
       }
        }
@@ -541,14 +544,14 @@ void Template::destroyItem(DCObject *object, int index)
    else
    {
       m_dcObjects->unlink(index);
-      DbgPrintf(7, _T("Template::DeleteItem: destruction of DCO %d delayed"), (int)object->getId());
+      nxlog_debug_tag(_T("obj.dc"), 7, _T("Template::DeleteItem: destruction of DCO %u delayed"), object->getId());
    }
 }
 
 /**
  * Modify data collection object from NXCP message
  */
-bool Template::updateDCObject(UINT32 dwItemId, NXCPMessage *pMsg, UINT32 *pdwNumMaps, UINT32 **ppdwMapIndex, UINT32 **ppdwMapId, UINT32 userID)
+bool Template::updateDCObject(UINT32 dwItemId, NXCPMessage *pMsg, UINT32 *pdwNumMaps, UINT32 **ppdwMapIndex, UINT32 **ppdwMapId, UINT32 userId)
 {
    bool success = false;
 
@@ -560,7 +563,7 @@ bool Template::updateDCObject(UINT32 dwItemId, NXCPMessage *pMsg, UINT32 *pdwNum
                DCObject *object = m_dcObjects->get(i);
       if (object->getId() == dwItemId)
       {
-         if(object->hasAccess(userID))
+         if (object->hasAccess(userId))
          {
             if (object->getType() == DCO_TYPE_ITEM)
             {
@@ -577,7 +580,9 @@ bool Template::updateDCObject(UINT32 dwItemId, NXCPMessage *pMsg, UINT32 *pdwNum
             success = true;
          }
          else
-            DbgPrintf(3, _T("Template::updateDCObject: access denied DCO %d"), (int)m_id);
+         {
+            nxlog_debug_tag(_T("obj.dc"), 6, _T("Template::updateDCObject: denied access to DCObject %u for user %u"), dwItemId, userId);
+         }
          break;
       }
        }
@@ -709,14 +714,17 @@ void Template::sendItemsToClient(ClientSession *pSession, UINT32 dwRqId)
    // Walk through items list
    for(int i = 0; i < m_dcObjects->size(); i++)
    {
-      if(m_dcObjects->get(i)->hasAccess(pSession->getUserId()))
+      DCObject *dco = m_dcObjects->get(i);
+      if (dco->hasAccess(pSession->getUserId()))
       {
-         m_dcObjects->get(i)->createMessage(&msg);
+         dco->createMessage(&msg);
          pSession->sendMessage(&msg);
          msg.deleteAllFields();
       }
       else
-         DbgPrintf(3, _T("Template::sendItemsToClient: access denied DCO %d"), (int)m_id);
+      {
+         nxlog_debug_tag(_T("obj.dc"), 6, _T("Template::sendItemsToClient: denied access to DCObject %u for user %u"), dco->getId(), pSession->getUserId());
+      }
    }
 
    unlockDciAccess();
@@ -729,7 +737,7 @@ void Template::sendItemsToClient(ClientSession *pSession, UINT32 dwRqId)
 /**
  * Get item by it's id
  */
-DCObject *Template::getDCObjectById(UINT32 itemId, UINT32 userID, bool lock)
+DCObject *Template::getDCObjectById(UINT32 itemId, UINT32 userId, bool lock)
 {
    DCObject *object = NULL;
 
@@ -741,10 +749,10 @@ DCObject *Template::getDCObjectById(UINT32 itemId, UINT32 userID, bool lock)
                DCObject *curr = m_dcObjects->get(i);
       if (curr->getId() == itemId)
                {
-         if(curr->hasAccess(userID))
+         if (curr->hasAccess(userId))
             object = curr;
          else
-            DbgPrintf(3, _T("Template::getDCObjectById: access denied DCO %d"), (int)m_id);
+            nxlog_debug_tag(_T("obj.dc"), 6, _T("Template::getDCObjectById: denied access to DCObject %u for user %u"), itemId, userId);
          break;
                }
        }
@@ -757,7 +765,7 @@ DCObject *Template::getDCObjectById(UINT32 itemId, UINT32 userID, bool lock)
 /**
  * Get item by template item id
  */
-DCObject *Template::getDCObjectByTemplateId(UINT32 tmplItemId, UINT32 userID)
+DCObject *Template::getDCObjectByTemplateId(UINT32 tmplItemId, UINT32 userId)
 {
    DCObject *object = NULL;
 
@@ -768,10 +776,10 @@ DCObject *Template::getDCObjectByTemplateId(UINT32 tmplItemId, UINT32 userID)
                DCObject *curr = m_dcObjects->get(i);
       if (curr->getTemplateItemId() == tmplItemId)
                {
-         if(object->hasAccess(userID))
+         if (object->hasAccess(userId))
             object = curr;
          else
-            DbgPrintf(3, _T("Template::getDCObjectByTemplateId: access denied DCO %d"), (int)m_id);
+            nxlog_debug_tag(_T("obj.dc"), 6, _T("Template::getDCObjectByTemplateId: denied access to DCObject %u for user %u"), object->getId(), userId);
          break;
                }
        }
@@ -783,7 +791,7 @@ DCObject *Template::getDCObjectByTemplateId(UINT32 tmplItemId, UINT32 userID)
 /**
  * Get item by it's name (case-insensetive)
  */
-DCObject *Template::getDCObjectByName(const TCHAR *name, UINT32 userID)
+DCObject *Template::getDCObjectByName(const TCHAR *name, UINT32 userId)
 {
    DCObject *object = NULL;
 
@@ -794,10 +802,10 @@ DCObject *Template::getDCObjectByName(const TCHAR *name, UINT32 userID)
                DCObject *curr = m_dcObjects->get(i);
       if (!_tcsicmp(curr->getName(), name))
                {
-         if(curr->hasAccess(userID))
+         if (curr->hasAccess(userId))
             object = curr;
          else
-            DbgPrintf(3, _T("Template::getDCObjectByName: access denied DCO %d"), (int)m_id);
+            nxlog_debug_tag(_T("obj.dc"), 6, _T("Template::getDCObjectByName: denied access to DCObject %u for user %u"), object->getId(), userId);
          break;
                }
        }
@@ -808,7 +816,7 @@ DCObject *Template::getDCObjectByName(const TCHAR *name, UINT32 userID)
 /**
  * Get item by it's description (case-insensetive)
  */
-DCObject *Template::getDCObjectByDescription(const TCHAR *description, UINT32 userID)
+DCObject *Template::getDCObjectByDescription(const TCHAR *description, UINT32 userId)
 {
    DCObject *object = NULL;
 
@@ -819,10 +827,10 @@ DCObject *Template::getDCObjectByDescription(const TCHAR *description, UINT32 us
                DCObject *curr = m_dcObjects->get(i);
       if (!_tcsicmp(curr->getDescription(), description))
                {
-         if(curr->hasAccess(userID))
+         if (curr->hasAccess(userId))
             object = curr;
          else
-            DbgPrintf(3, _T("Template::getDCObjectByDescription: access denied DCO %d"), (int)m_id);
+            nxlog_debug_tag(_T("obj.dc"), 6, _T("Template::getDCObjectByDescription: denied access to DCObject %u for user %u"), object->getId(), userId);
          break;
                }
        }
@@ -833,7 +841,7 @@ DCObject *Template::getDCObjectByDescription(const TCHAR *description, UINT32 us
 /**
  * Get item by GUID
  */
-DCObject *Template::getDCObjectByGUID(const uuid& guid, UINT32 userID, bool lock)
+DCObject *Template::getDCObjectByGUID(const uuid& guid, UINT32 userId, bool lock)
 {
    DCObject *object = NULL;
 
@@ -846,10 +854,10 @@ DCObject *Template::getDCObjectByGUID(const uuid& guid, UINT32 userID, bool lock
       DCObject *curr = m_dcObjects->get(i);
       if (guid.equals(curr->getGuid()))
       {
-         if(curr->hasAccess(userID))
+         if (curr->hasAccess(userId))
             object = curr;
          else
-            DbgPrintf(3, _T("Template::getDCObjectByGUID: access denied DCO %d"), (int)m_id);
+            nxlog_debug_tag(_T("obj.dc"), 6, _T("Template::getDCObjectByGUID: denied access to DCObject %u for user %u"), object->getId(), userId);
          break;
       }
    }
@@ -963,8 +971,8 @@ BOOL Template::applyToTarget(DataCollectionTarget *target)
    }
 
    pdwItemList = (UINT32 *)malloc(sizeof(UINT32) * m_dcObjects->size());
-   DbgPrintf(2, _T("Apply %d items from template \"%s\" to target \"%s\""),
-             m_dcObjects->size(), m_name, target->getName());
+   nxlog_debug_tag(_T("obj.dc"), 2, _T("Apply %d items from template \"%s\" to target \"%s\""),
+                   m_dcObjects->size(), m_name, target->getName());
 
    // Copy items
    for(int i = 0; i < m_dcObjects->size(); i++)
index bc8245b..ae0ad80 100644 (file)
@@ -605,6 +605,11 @@ bool User::deleteFromDatabase(DB_HANDLE hdb)
    }
 
    if (success)
+   {
+      success = ExecuteQueryOnObject(hdb, m_id, _T("DELETE FROM dci_access WHERE user_id=?"));
+   }
+
+   if (success)
       DBCommit(hdb);
    else
       DBRollback(hdb);
@@ -939,6 +944,11 @@ bool Group::deleteFromDatabase(DB_HANDLE hdb)
    }
 
    if (success)
+   {
+      success = ExecuteQueryOnObject(hdb, m_id, _T("DELETE FROM dci_access WHERE user_id=?"));
+   }
+
+   if (success)
       DBCommit(hdb);
    else
       DBRollback(hdb);
index 81cafd8..ab0d43e 100644 (file)
@@ -217,12 +217,13 @@ protected:
    TCHAR *m_instanceFilterSource;
    NXSL_Program *m_instanceFilter;
    TCHAR m_instance[MAX_DB_STRING];
-   IntegerArray<UINT32> *m_visibilityRights;
+   IntegerArray<UINT32> *m_accessList;
 
    void lock() { MutexLock(m_hMutex); }
    bool tryLock() { return MutexTryLock(m_hMutex); }
    void unlock() { MutexUnlock(m_hMutex); }
 
+   bool loadAccessList(DB_HANDLE hdb);
        bool loadCustomSchedules(DB_HANDLE hdb);
    bool matchSchedule(const TCHAR *schedule, bool *withSeconds, struct tm *currLocalTime, time_t currTimestamp);
 
index f071314..f5129a1 100644 (file)
@@ -792,15 +792,15 @@ public:
 
    int getItemCount() { return m_dcObjects->size(); }
    bool addDCObject(DCObject *object, bool alreadyLocked = false);
-   bool updateDCObject(UINT32 dwItemId, NXCPMessage *pMsg, UINT32 *pdwNumMaps, UINT32 **ppdwMapIndex, UINT32 **ppdwMapId, UINT32 userID);
-   bool deleteDCObject(UINT32 dcObjectId, bool needLock, UINT32 userID);
+   bool updateDCObject(UINT32 dwItemId, NXCPMessage *pMsg, UINT32 *pdwNumMaps, UINT32 **ppdwMapIndex, UINT32 **ppdwMapId, UINT32 userId);
+   bool deleteDCObject(UINT32 dcObjectId, bool needLock, UINT32 userId);
    bool setItemStatus(UINT32 dwNumItems, UINT32 *pdwItemList, int iStatus);
-   DCObject *getDCObjectById(UINT32 itemId, UINT32 userID, bool lock = true);
-   DCObject *getDCObjectByGUID(const uuid& guid, UINT32 userID, bool lock = true);
-   DCObject *getDCObjectByTemplateId(UINT32 tmplItemId, UINT32 userID);
-   DCObject *getDCObjectByName(const TCHAR *name, UINT32 userID);
-   DCObject *getDCObjectByDescription(const TCHAR *description, UINT32 userID);
-   NXSL_Value *getAllDCObjectsForNXSL(const TCHAR *name, const TCHAR *description, UINT32 userID);
+   DCObject *getDCObjectById(UINT32 itemId, UINT32 userId, bool lock = true);
+   DCObject *getDCObjectByGUID(const uuid& guid, UINT32 userId, bool lock = true);
+   DCObject *getDCObjectByTemplateId(UINT32 tmplItemId, UINT32 userId);
+   DCObject *getDCObjectByName(const TCHAR *name, UINT32 userId);
+   DCObject *getDCObjectByDescription(const TCHAR *description, UINT32 userId);
+   NXSL_Value *getAllDCObjectsForNXSL(const TCHAR *name, const TCHAR *description, UINT32 userId);
    bool lockDCIList(int sessionId, const TCHAR *pszNewOwner, TCHAR *pszCurrOwner);
    bool unlockDCIList(int sessionId);
    void setDCIModificationFlag() { m_dciListModified = true; }
index 1061953..83e1be8 100644 (file)
@@ -36,11 +36,11 @@ static bool H_UpgradeFromV3()
  */
 static bool H_UpgradeFromV2()
 {
-   static const TCHAR *batch =
-            _T("ALTER TABLE dc_tables ADD visibility_rights varchar(2000)\n")
-            _T("ALTER TABLE items ADD visibility_rights varchar(2000)\n")
-            _T("<END>");
-   CHK_EXEC(SQLBatch(batch));
+   CHK_EXEC(CreateTable(
+         _T("CREATE TABLE dci_access (")
+         _T("   dci_id integer not null,")
+         _T("   user_id integer not null,")
+         _T("   PRIMARY KEY(dci_id,user_id))")));
    CHK_EXEC(SetMinorSchemaVersion(3));
    return true;
 }
index d3e1f35..9ff4247 100644 (file)
@@ -29,11 +29,11 @@ static bool H_UpgradeFromV11()
 {
    if (GetSchemaLevelForMajorVersion(22) < 3)
    {
-      static const TCHAR *batch =
-               _T("ALTER TABLE dc_tables ADD visibility_rights varchar(2000)\n")
-               _T("ALTER TABLE items ADD visibility_rights varchar(2000)\n")
-               _T("<END>");
-      CHK_EXEC(SQLBatch(batch));
+      CHK_EXEC(CreateTable(
+            _T("CREATE TABLE dci_access (")
+            _T("   dci_id integer not null,")
+            _T("   user_id integer not null,")
+            _T("   PRIMARY KEY(dci_id,user_id))")));
       CHK_EXEC(SetSchemaLevelForMajorVersion(22, 3));
       CHK_EXEC(SetMinorSchemaVersion(12));
    }