Implemented seperate access rights for reading Agent data, SNMP data and taking scree...
authorEriks Jenkevics <eriks@netxms.org>
Tue, 3 Oct 2017 14:19:17 +0000 (17:19 +0300)
committerEriks Jenkevics <eriks@netxms.org>
Wed, 4 Oct 2017 12:43:17 +0000 (15:43 +0300)
include/netxmsdb.h
include/nxcldefs.h
sql/setup.in
src/client/java/netxms-client/src/main/java/org/netxms/client/constants/UserAccessRights.java
src/java/netxms-eclipse/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/AccessControl.java
src/server/core/node.cpp
src/server/core/session.cpp
src/server/include/nms_objects.h
src/server/tools/nxdbmgr/upgrade.cpp
webui/webapp/ObjectManager/src/org/netxms/ui/eclipse/objectmanager/propertypages/AccessControl.java

index a7c0e18..afb1e1f 100644 (file)
@@ -23,6 +23,6 @@
 #ifndef _netxmsdb_h
 #define _netxmsdb_h
 
-#define DB_FORMAT_VERSION   505
+#define DB_FORMAT_VERSION   506
 
 #endif
index bf15548..736f106 100644 (file)
@@ -726,6 +726,9 @@ enum SessionState
 #define OBJECT_ACCESS_UPLOAD        0x00002000
 #define OBJECT_ACCESS_MANAGE_FILES  0x00004000
 #define OBJECT_ACCESS_MAINTENANCE   0x00008000
+#define OBJECT_ACCESS_READ_AGENT    0x00010000
+#define OBJECT_ACCESS_READ_SNMP     0x00020000
+#define OBJECT_ACCESS_SCREENSHOT    0x00040000
 
 /**
  * Object sync flags
index 6c909ed..0490405 100644 (file)
@@ -281,15 +281,15 @@ INSERT INTO user_groups (id,name,system_access,flags,description,guid,created)
 
 INSERT INTO user_group_members (group_id,user_id) VALUES (-2147483647,1);
 
-INSERT INTO acl (object_id,user_id,access_rights) VALUES (1,-2147483647,65535);
-INSERT INTO acl (object_id,user_id,access_rights) VALUES (2,-2147483647,65535);
-INSERT INTO acl (object_id,user_id,access_rights) VALUES (3,-2147483647,65535);
-INSERT INTO acl (object_id,user_id,access_rights) VALUES (4,-2147483647,65535);
-INSERT INTO acl (object_id,user_id,access_rights) VALUES (5,-2147483647,65535);
-INSERT INTO acl (object_id,user_id,access_rights) VALUES (6,-2147483647,65535);
-INSERT INTO acl (object_id,user_id,access_rights) VALUES (7,-2147483647,65535);
-INSERT INTO acl (object_id,user_id,access_rights) VALUES (8,-2147483647,65535);
-INSERT INTO acl (object_id,user_id,access_rights) VALUES (9,-2147483647,65535);
+INSERT INTO acl (object_id,user_id,access_rights) VALUES (1,-2147483647,524287);
+INSERT INTO acl (object_id,user_id,access_rights) VALUES (2,-2147483647,524287);
+INSERT INTO acl (object_id,user_id,access_rights) VALUES (3,-2147483647,524287);
+INSERT INTO acl (object_id,user_id,access_rights) VALUES (4,-2147483647,524287);
+INSERT INTO acl (object_id,user_id,access_rights) VALUES (5,-2147483647,524287);
+INSERT INTO acl (object_id,user_id,access_rights) VALUES (6,-2147483647,524287);
+INSERT INTO acl (object_id,user_id,access_rights) VALUES (7,-2147483647,524287);
+INSERT INTO acl (object_id,user_id,access_rights) VALUES (8,-2147483647,524287);
+INSERT INTO acl (object_id,user_id,access_rights) VALUES (9,-2147483647,524287);
 
 /*
 ** Default event groups
index b640dab..3ec4cdd 100644 (file)
@@ -68,5 +68,8 @@ public class UserAccessRights
    public static final int OBJECT_ACCESS_UPLOAD        = 0x00002000;
    public static final int OBJECT_ACCESS_MANAGE_FILES  = 0x00004000;
    public static final int OBJECT_ACCESS_MAINTENANCE   = 0x00008000;
+   public static final int OBJECT_ACCESS_READ_AGENT    = 0x00010000;
+   public static final int OBJECT_ACCESS_READ_SNMP     = 0x00020000;
+   public static final int OBJECT_ACCESS_SCREENSHOT    = 0x00040000;
    
 }
index c834450..2aa5c79 100644 (file)
@@ -184,6 +184,8 @@ public class AccessControl extends PropertyPage
       rights.setLayoutData(gd);
       
       createAccessCheck(rights, Messages.get().AccessControl_AccessRead, UserAccessRights.OBJECT_ACCESS_READ);
+      createAccessCheck(rights, "Read agent data", UserAccessRights.OBJECT_ACCESS_READ_AGENT);
+      createAccessCheck(rights, "Read SNMP data", UserAccessRights.OBJECT_ACCESS_READ_SNMP);
       createAccessCheck(rights, Messages.get().AccessControl_AccessModify, UserAccessRights.OBJECT_ACCESS_MODIFY);
       createAccessCheck(rights, Messages.get().AccessControl_AccessCreate, UserAccessRights.OBJECT_ACCESS_CREATE);
       createAccessCheck(rights, Messages.get().AccessControl_AccessDelete, UserAccessRights.OBJECT_ACCESS_DELETE);
@@ -199,6 +201,7 @@ public class AccessControl extends PropertyPage
       createAccessCheck(rights, Messages.get().AccessControl_UploadFiles, UserAccessRights.OBJECT_ACCESS_UPLOAD);
       createAccessCheck(rights, Messages.get().AccessControl_ManageFiles, UserAccessRights.OBJECT_ACCESS_MANAGE_FILES);
       createAccessCheck(rights, "Control maintenance mode", UserAccessRights.OBJECT_ACCESS_MAINTENANCE);
+      createAccessCheck(rights, "Take screenshot", UserAccessRights.OBJECT_ACCESS_SCREENSHOT);
       
       userList.addSelectionChangedListener(new ISelectionChangedListener() {
                        @Override
@@ -210,7 +213,8 @@ public class AccessControl extends PropertyPage
                                        enableAllChecks(true);
                                        AccessListElement element = (AccessListElement)sel.getFirstElement();
                                        int rights = element.getAccessRights();
-                                       for(int i = 0, mask = 1; i < 16; i++, mask <<= 1)
+
+                                       for(int i = 0, mask = 1; i < accessChecks.size(); i++, mask <<= 1)
                                        {
                                                Button check = accessChecks.get(mask);
                                                if (check != null)
index 6aade38..10fdd1c 100644 (file)
@@ -4665,24 +4665,28 @@ static UINT32 RCCFromDCIError(UINT32 error)
 /**
  * Get item's value for client
  */
-UINT32 Node::getItemForClient(int iOrigin, const TCHAR *pszParam, TCHAR *pszBuffer, UINT32 dwBufSize)
+UINT32 Node::getItemForClient(int iOrigin, UINT32 userId, const TCHAR *pszParam, TCHAR *pszBuffer, UINT32 dwBufSize)
 {
-   UINT32 dwResult = 0, dwRetCode;
+   UINT32 dwResult = RCC_ACCESS_DENIED, dwRetCode;
 
    // Get data from node
    switch(iOrigin)
    {
       case DS_INTERNAL:
-         dwRetCode = getInternalItem(pszParam, dwBufSize, pszBuffer);
+         if (checkAccessRights(userId, OBJECT_ACCESS_READ))
+            dwRetCode = getInternalItem(pszParam, dwBufSize, pszBuffer);
          break;
       case DS_NATIVE_AGENT:
-         dwRetCode = getItemFromAgent(pszParam, dwBufSize, pszBuffer);
+         if (checkAccessRights(userId, OBJECT_ACCESS_READ_AGENT))
+            dwRetCode = getItemFromAgent(pszParam, dwBufSize, pszBuffer);
          break;
       case DS_SNMP_AGENT:
-         dwRetCode = getItemFromSNMP(0, pszParam, dwBufSize, pszBuffer, SNMP_RAWTYPE_NONE);
+         if (checkAccessRights(userId, OBJECT_ACCESS_READ_SNMP))
+            dwRetCode = getItemFromSNMP(0, pszParam, dwBufSize, pszBuffer, SNMP_RAWTYPE_NONE);
          break;
       case DS_CHECKPOINT_AGENT:
-         dwRetCode = getItemFromCheckPointSNMP(pszParam, dwBufSize, pszBuffer);
+         if (checkAccessRights(userId, OBJECT_ACCESS_READ_SNMP))
+            dwRetCode = getItemFromCheckPointSNMP(pszParam, dwBufSize, pszBuffer);
          break;
       default:
          dwResult = RCC_INVALID_ARGUMENT;
@@ -4690,7 +4694,7 @@ UINT32 Node::getItemForClient(int iOrigin, const TCHAR *pszParam, TCHAR *pszBuff
    }
 
    // Translate return code to RCC
-   if (dwResult != RCC_INVALID_ARGUMENT)
+   if (dwResult != RCC_INVALID_ARGUMENT && dwResult != RCC_ACCESS_DENIED)
       dwResult = RCCFromDCIError(dwRetCode);
 
    return dwResult;
index ac49a79..b95a060 100644 (file)
@@ -6321,22 +6321,15 @@ void ClientSession::queryParameter(NXCPMessage *pRequest)
    {
       if (object->getObjectClass() == OBJECT_NODE)
       {
-         if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
-         {
-            UINT32 dwResult;
-            TCHAR szBuffer[256], szName[MAX_PARAM_NAME];
+         UINT32 dwResult;
+         TCHAR szBuffer[256], szName[MAX_PARAM_NAME];
 
-            pRequest->getFieldAsString(VID_NAME, szName, MAX_PARAM_NAME);
-            dwResult = ((Node *)object)->getItemForClient(pRequest->getFieldAsUInt16(VID_DCI_SOURCE_TYPE),
-                                                           szName, szBuffer, 256);
-            msg.setField(VID_RCC, dwResult);
-            if (dwResult == RCC_SUCCESS)
-               msg.setField(VID_VALUE, szBuffer);
-         }
-         else
-         {
-            msg.setField(VID_RCC, RCC_ACCESS_DENIED);
-         }
+         pRequest->getFieldAsString(VID_NAME, szName, MAX_PARAM_NAME);
+         dwResult = ((Node *)object)->getItemForClient(pRequest->getFieldAsUInt16(VID_DCI_SOURCE_TYPE),
+                                                        m_dwUserId, szName, szBuffer, 256);
+         msg.setField(VID_RCC, dwResult);
+         if (dwResult == RCC_SUCCESS)
+            msg.setField(VID_VALUE, szBuffer);
       }
       else
       {
@@ -6369,7 +6362,7 @@ void ClientSession::queryAgentTable(NXCPMessage *pRequest)
    {
       if (object->getObjectClass() == OBJECT_NODE)
       {
-         if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
+         if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ_AGENT))
          {
                                TCHAR name[MAX_PARAM_NAME];
                                pRequest->getFieldAsString(VID_NAME, name, MAX_PARAM_NAME);
@@ -7485,7 +7478,7 @@ void ClientSession::getAgentConfig(NXCPMessage *pRequest)
    {
       if (object->getObjectClass() == OBJECT_NODE)
       {
-         if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
+         if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ_AGENT))
          {
             AgentConnection *pConn;
 
@@ -8364,7 +8357,7 @@ void ClientSession::StartSnmpWalk(NXCPMessage *pRequest)
    {
       if (object->getObjectClass() == OBJECT_NODE)
       {
-         if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
+         if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ_SNMP))
          {
             msg.setField(VID_RCC, RCC_SUCCESS);
 
@@ -13296,7 +13289,7 @@ void ClientSession::getSwitchForwardingDatabase(NXCPMessage *request)
 }
 
 /**
- * Get switch forwarding database
+ * Get routing table
  */
 void ClientSession::getRoutingTable(NXCPMessage *request)
 {
@@ -13334,7 +13327,7 @@ void ClientSession::getRoutingTable(NXCPMessage *request)
                }
                id += 4;
             }
-                       DestroyRoutingTable(rt);
+            DestroyRoutingTable(rt);
          }
          else
          {
@@ -13423,7 +13416,7 @@ void ClientSession::getLocationHistory(NXCPMessage *request)
 }
 
 /**
- * Get location history for object
+ * Get screenshot of object
  */
 void ClientSession::getScreenshot(NXCPMessage *request)
 {
@@ -13437,7 +13430,7 @@ void ClientSession::getScreenshot(NXCPMessage *request)
 
        if (object != NULL)
        {
-               if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
+               if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_SCREENSHOT))
                {
                        if (object->getObjectClass() == OBJECT_NODE)
                        {
@@ -13541,7 +13534,7 @@ void ClientSession::cleanAgentDciConfiguration(NXCPMessage *request)
 
        if (object != NULL)
        {
-      if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
+      if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_CONTROL))
                {
                        if (object->getObjectClass() == OBJECT_NODE)
                        {
@@ -13590,7 +13583,7 @@ void ClientSession::resyncAgentDciConfiguration(NXCPMessage *request)
 
    if (object != NULL)
        {
-      if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
+      if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_CONTROL))
                {
                        if (object->getObjectClass() == OBJECT_NODE)
                        {
index fb162d4..ca9c44b 100644 (file)
@@ -1950,7 +1950,7 @@ public:
    UINT32 getItemFromAgent(const TCHAR *szParam, UINT32 dwBufSize, TCHAR *szBuffer);
        UINT32 getTableFromAgent(const TCHAR *name, Table **table);
        UINT32 getListFromAgent(const TCHAR *name, StringList **list);
-   UINT32 getItemForClient(int iOrigin, const TCHAR *pszParam, TCHAR *pszBuffer, UINT32 dwBufSize);
+   UINT32 getItemForClient(int iOrigin, UINT32 userId, const TCHAR *pszParam, TCHAR *pszBuffer, UINT32 dwBufSize);
    UINT32 getTableForClient(const TCHAR *name, Table **table);
    UINT32 getItemFromSMCLP(const TCHAR *param, UINT32 bufSize, TCHAR *buffer);
 
index 6c0bcc2..b1c82e2 100644 (file)
@@ -645,6 +645,53 @@ BOOL moveFlagsFromOldTables(const TCHAR *tableName)
 }
 
 /**
+ * Upgrade from V505 to V506 included in stable as 461
+ */
+static BOOL H_UpgradeFromV505(int currVersion, int newVersion)
+{
+   DB_RESULT hResult = DBSelect(g_hCoreDB, _T("SELECT access_rights,object_id FROM acl WHERE user_id=-2147483647")); // Get group Admins object acl
+   if (hResult != NULL)
+   {
+      DB_STATEMENT hStmt = DBPrepare(g_hCoreDB, _T("UPDATE acl SET access_rights=? WHERE user_id=-2147483647 AND object_id=? "));
+      if (hStmt != NULL)
+      {
+         int nRows = DBGetNumRows(hResult);
+         UINT32 rights;
+         for(int i = 0; i < nRows; i++)
+         {
+            rights = DBGetFieldULong(hResult, i, 0);
+            if (rights & OBJECT_ACCESS_READ)
+            {
+               rights |= (OBJECT_ACCESS_READ_AGENT | OBJECT_ACCESS_READ_SNMP | OBJECT_ACCESS_SCREENSHOT);
+               DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, rights);
+               DBBind(hStmt, 2, DB_SQLTYPE_INTEGER, DBGetFieldULong(hResult, i, 1));
+
+               if (!SQLExecute(hStmt))
+               {
+                  if (!g_bIgnoreErrors)
+                  {
+                     DBFreeStatement(hStmt);
+                     DBFreeResult(hResult);
+                     return FALSE;
+                  }
+               }
+            }
+         }
+
+         DBFreeStatement(hStmt);
+      }
+      else if (!g_bIgnoreErrors)
+         return FALSE;
+      DBFreeResult(hResult);
+   }
+   else if (!g_bIgnoreErrors)
+      return FALSE;
+
+   CHK_EXEC(SetSchemaVersion(506));
+   return TRUE;
+}
+
+/**
  * Upgrade from V504 to V505 included in stable as 460
  */
 static BOOL H_UpgradeFromV504(int currVersion, int newVersion)
@@ -12295,6 +12342,7 @@ static struct
    { 502, 503, H_UpgradeFromV502 },
    { 503, 504, H_UpgradeFromV503 },
    { 504, 505, H_UpgradeFromV504 },
+   { 505, 506, H_UpgradeFromV505 },
    { 0, 0, NULL }
 };
 
index c834450..2aa5c79 100644 (file)
@@ -184,6 +184,8 @@ public class AccessControl extends PropertyPage
       rights.setLayoutData(gd);
       
       createAccessCheck(rights, Messages.get().AccessControl_AccessRead, UserAccessRights.OBJECT_ACCESS_READ);
+      createAccessCheck(rights, "Read agent data", UserAccessRights.OBJECT_ACCESS_READ_AGENT);
+      createAccessCheck(rights, "Read SNMP data", UserAccessRights.OBJECT_ACCESS_READ_SNMP);
       createAccessCheck(rights, Messages.get().AccessControl_AccessModify, UserAccessRights.OBJECT_ACCESS_MODIFY);
       createAccessCheck(rights, Messages.get().AccessControl_AccessCreate, UserAccessRights.OBJECT_ACCESS_CREATE);
       createAccessCheck(rights, Messages.get().AccessControl_AccessDelete, UserAccessRights.OBJECT_ACCESS_DELETE);
@@ -199,6 +201,7 @@ public class AccessControl extends PropertyPage
       createAccessCheck(rights, Messages.get().AccessControl_UploadFiles, UserAccessRights.OBJECT_ACCESS_UPLOAD);
       createAccessCheck(rights, Messages.get().AccessControl_ManageFiles, UserAccessRights.OBJECT_ACCESS_MANAGE_FILES);
       createAccessCheck(rights, "Control maintenance mode", UserAccessRights.OBJECT_ACCESS_MAINTENANCE);
+      createAccessCheck(rights, "Take screenshot", UserAccessRights.OBJECT_ACCESS_SCREENSHOT);
       
       userList.addSelectionChangedListener(new ISelectionChangedListener() {
                        @Override
@@ -210,7 +213,8 @@ public class AccessControl extends PropertyPage
                                        enableAllChecks(true);
                                        AccessListElement element = (AccessListElement)sel.getFirstElement();
                                        int rights = element.getAccessRights();
-                                       for(int i = 0, mask = 1; i < 16; i++, mask <<= 1)
+
+                                       for(int i = 0, mask = 1; i < accessChecks.size(); i++, mask <<= 1)
                                        {
                                                Button check = accessChecks.get(mask);
                                                if (check != null)