Unfinished communication code for action management
authorVictor Kirhenshtein <victor@netxms.org>
Sun, 5 Sep 2004 08:01:04 +0000 (08:01 +0000)
committerVictor Kirhenshtein <victor@netxms.org>
Sun, 5 Sep 2004 08:01:04 +0000 (08:01 +0000)
13 files changed:
include/netxmsdb.h
include/nms_cscp.h
include/nxclapi.h
sql/schema.in
sql/setup.in
src/server/core/actions.cpp
src/server/core/main.cpp
src/server/core/messages.mc
src/server/core/nms_actions.h
src/server/core/nms_core.h
src/server/core/nms_locks.h
src/server/core/session.cpp
src/server/core/users.cpp

index 3185411..14d0524 100644 (file)
@@ -23,6 +23,6 @@
 #ifndef _netxms_db_h
 #define _netxms_db_h
 
-#define DB_FORMAT_VERSION      4
+#define DB_FORMAT_VERSION      5
 
 #endif
index e60411a..57629dd 100644 (file)
@@ -238,6 +238,13 @@ typedef struct
 #define CMD_ALARM_UPDATE            0x0049
 #define CMD_ALARM_DATA              0x004A
 #define CMD_DELETE_ALARM            0x004B
+#define CMD_LOCK_ACTION_DB          0x004C
+#define CMD_UNLOCK_ACTION_DB        0x004D
+#define CMD_LOAD_ACTIONS            0x004E
+#define CMD_ACTION_DB_UPDATE        0x004F
+#define CMD_MODIFY_ACTION           0x0050
+#define CMD_CREATE_ACTION           0x0051
+#define CMD_DELETE_ACTION           0x0052
 
 
 //
@@ -340,6 +347,7 @@ typedef struct
 #define VID_TIMESTAMP               ((DWORD)94)
 #define VID_ACK_BY_USER             ((DWORD)95)
 #define VID_IS_ACK                  ((DWORD)96)
+#define VID_ACTION_ID               ((DWORD)97)
 
 // Variable ranges for object's ACL
 #define VID_ACL_USER_BASE           ((DWORD)0x00001000)
index 99aa93f..0fc41b1 100644 (file)
@@ -181,6 +181,9 @@ typedef unsigned long HREQUEST;
 #define NX_NOTIFY_ALARM_DELETED     3
 #define NX_NOTIFY_NEW_ALARM         4
 #define NX_NOTIFY_ALARM_ACKNOWLEGED 5
+#define NX_NOTIFY_ACTION_CREATED    6
+#define NX_NOTIFY_ACTION_MODIFIED   7
+#define NX_NOTIFY_ACTION_DELETED    8
 
 
 //
@@ -367,6 +370,7 @@ typedef struct
 {
    DWORD dwId;
    int iType;
+   BOOL bIsDisabled;
    char szName[MAX_OBJECT_NAME];
    char szRcptAddr[MAX_RCPT_ADDR_LEN];
    char szEmailSubject[MAX_EMAIL_SUBJECT_LEN];
index 53ecdc1..928c3c6 100644 (file)
@@ -288,6 +288,7 @@ CREATE TABLE actions
        action_id integer not null,
        action_name varchar(63) not null,
        action_type integer not null,
+       is_disabled integer,
        // Field "rcpt_addr" holds e-mail address for e-mail actions,
        // phone number for sms actions, and remote host address for
        // remote execution actions
index b2da9fa..ff73b9e 100644 (file)
@@ -60,6 +60,8 @@ INSERT INTO locks (component_id,component_name,lock_status,owner_info)
    VALUES (CID_USER_DB,'User Database',-1,'');
 INSERT INTO locks (component_id,component_name,lock_status,owner_info)
    VALUES (CID_EVENT_DB,'Event Configuration Database',-1,'');
+INSERT INTO locks (component_id,component_name,lock_status,owner_info)
+   VALUES (CID_ACTION_DB,'Action Configuration Database',-1,'');
 
 
 /*
index 1f2778b..334e0d8 100644 (file)
 
 static DWORD m_dwNumActions = 0;
 static NXC_ACTION *m_pActionList = NULL;
+static RWLOCK m_rwlockActionListAccess;
+static DWORD m_dwUpdateCode;
+
+
+//
+// Send updates to all connected clients
+//
+
+static void SendActionDBUpdate(ClientSession *pSession, void *pArg)
+{
+   pSession->OnActionDBUpdate(m_dwUpdateCode, (NXC_ACTION *)pArg);
+}
 
 
 //
 // Destroy action list
 //
 
-void DestroyActionList(void)
+static void DestroyActionList(void)
 {
    DWORD i;
 
+   RWLockWriteLock(m_rwlockActionListAccess, INFINITE);
    if (m_pActionList != NULL)
    {
       for(i = 0; i < m_dwNumActions; i++)
-         if (m_pActionList[i].pszData != NULL)
-            free(m_pActionList[i].pszData);
+         safe_free(m_pActionList[i].pszData);
       free(m_pActionList);
       m_pActionList = NULL;
       m_dwNumActions = 0;
    }
+   RWLockUnlock(m_rwlockActionListAccess);
 }
 
 
@@ -55,7 +68,7 @@ void DestroyActionList(void)
 // Load actions list from database
 //
 
-BOOL LoadActions(void)
+static BOOL LoadActions(void)
 {
    DB_RESULT hResult;
    BOOL bResult = FALSE;
@@ -63,7 +76,7 @@ BOOL LoadActions(void)
    char *pStr;
 
    hResult = DBSelect(g_hCoreDB, "SELECT action_id,action_name,action_type,"
-                                 "rcpt_addr,email_subject,action_data "
+                                 "is_disabled,rcpt_addr,email_subject,action_data "
                                  "FROM actions ORDER BY action_id");
    if (hResult != NULL)
    {
@@ -75,16 +88,17 @@ BOOL LoadActions(void)
          m_pActionList[i].dwId = DBGetFieldULong(hResult, i, 0);
          strncpy(m_pActionList[i].szName, DBGetField(hResult, i, 1), MAX_OBJECT_NAME);
          m_pActionList[i].iType = DBGetFieldLong(hResult, i, 2);
+         m_pActionList[i].bIsDisabled = DBGetFieldLong(hResult, i, 3);
 
-         pStr = DBGetField(hResult, i, 3);
+         pStr = DBGetField(hResult, i, 4);
          strcpy(m_pActionList[i].szRcptAddr, CHECK_NULL(pStr));
          DecodeSQLString(m_pActionList[i].szRcptAddr);
 
-         pStr = DBGetField(hResult, i, 4);
+         pStr = DBGetField(hResult, i, 5);
          strcpy(m_pActionList[i].szEmailSubject, CHECK_NULL(pStr));
          DecodeSQLString(m_pActionList[i].szEmailSubject);
 
-         m_pActionList[i].pszData = strdup(DBGetField(hResult, i, 5));
+         m_pActionList[i].pszData = strdup(DBGetField(hResult, i, 6));
          DecodeSQLString(m_pActionList[i].pszData);
       }
       DBFreeResult(hResult);
@@ -99,6 +113,70 @@ BOOL LoadActions(void)
 
 
 //
+// Initialize action-related stuff
+//
+
+BOOL InitActions(void)
+{
+   BOOL bSuccess = FALSE;
+
+   m_rwlockActionListAccess = RWLockCreate();
+   if (m_rwlockActionListAccess != NULL)
+      bSuccess = LoadActions();
+   return bSuccess;
+}
+
+
+//
+// Cleanup action-related stuff
+//
+
+void CleanupActions(void)
+{
+   DestroyActionList();
+   RWLockDestroy(m_rwlockActionListAccess);
+}
+
+
+//
+// Save action record to database
+//
+
+static void SaveActionToDB(NXC_ACTION *pAction)
+{
+   DB_RESULT hResult;
+   BOOL bExist = FALSE;
+   char szQuery[4096];
+
+   // Check if action with given ID already exist in database
+   sprintf(szQuery, "SELECT action_id FROM actions WHERE action_id=%ld", pAction->dwId);
+   hResult = DBSelect(g_hCoreDB, szQuery);
+   if (hResult != NULL)
+   {
+      bExist = (DBGetNumRows(hResult) > 0);
+      DBFreeResult(hResult);
+   }
+
+   // Prepare and execute INSERT or UPDATE query
+   if (bExist)
+      sprintf(szQuery, "UPDATE actions SET action_name='%s',action_type=%d,is_disabled=%d,"
+                       "rcpt_addr='%s',email_subject='%s',action_data='%s'"
+                       "WHERE action_id=%ld",
+              pAction->szName, pAction->iType, pAction->bIsDisabled,
+              pAction->szRcptAddr, pAction->szEmailSubject,
+              (pAction->pszData == NULL ? "" : pAction->pszData), pAction->dwId);
+   else
+      sprintf(szQuery, "INSERT INTO actions (action_id,action_name,action_type,"
+                       "is_disabled,rcpt_addr,email_subject,action_data VALUES"
+                       " (%ld,'%s',%d,%d,'%s','%s','%s')",
+              pAction->dwId,pAction->szName, pAction->iType, pAction->bIsDisabled,
+              pAction->szRcptAddr, pAction->szEmailSubject,
+              (pAction->pszData == NULL ? "" : pAction->pszData));
+   DBQuery(g_hCoreDB, szQuery);
+}
+
+
+//
 // Compare action's id for bsearch()
 //
 
@@ -118,35 +196,88 @@ BOOL ExecuteAction(DWORD dwActionId, Event *pEvent)
    NXC_ACTION *pAction;
    BOOL bSuccess = FALSE;
 
+   RWLockReadLock(m_rwlockActionListAccess, INFINITE);
    pAction = (NXC_ACTION *)bsearch((void *)dwActionId, m_pActionList, 
                                    m_dwNumActions, sizeof(NXC_ACTION), CompareId);
    if (pAction != NULL)
    {
-      char *pszExpandedData;
-
-      pszExpandedData = pEvent->ExpandText(pAction->pszData);
-      switch(pAction->iType)
+      if (pAction->bIsDisabled)
       {
-         case ACTION_EXEC:
-            DbgPrintf(AF_DEBUG_ACTIONS, "*actions* Executing command \"%s\"\n", pszExpandedData);
-            ExecCommand(pszExpandedData);
-            break;
-         case ACTION_SEND_EMAIL:
-            DbgPrintf(AF_DEBUG_ACTIONS, "*actions* Sending mail to %s: \"%s\"\n", 
-                      pAction->szRcptAddr, pszExpandedData);
-            break;
-         case ACTION_SEND_SMS:
-            DbgPrintf(AF_DEBUG_ACTIONS, "*actions* Sending SMS to %s: \"%s\"\n", 
-                      pAction->szRcptAddr, pszExpandedData);
-            break;
-         case ACTION_REMOTE:
-            DbgPrintf(AF_DEBUG_ACTIONS, "*actions* Executing on \"%s\": \"%s\"\n", 
-                      pAction->szRcptAddr, pszExpandedData);
-            break;
-         default:
-            break;
+         DbgPrintf(AF_DEBUG_ACTIONS, "*actions* Action %d (%s) is disabled and will not be executed\n",
+                   dwActionId, pAction->szName);
+         bSuccess = TRUE;
+      }
+      else
+      {
+         char *pszExpandedData;
+
+         pszExpandedData = pEvent->ExpandText(pAction->pszData);
+         switch(pAction->iType)
+         {
+            case ACTION_EXEC:
+               DbgPrintf(AF_DEBUG_ACTIONS, "*actions* Executing command \"%s\"\n", pszExpandedData);
+               bSuccess = ExecCommand(pszExpandedData);
+               break;
+            case ACTION_SEND_EMAIL:
+               DbgPrintf(AF_DEBUG_ACTIONS, "*actions* Sending mail to %s: \"%s\"\n", 
+                         pAction->szRcptAddr, pszExpandedData);
+               break;
+            case ACTION_SEND_SMS:
+               DbgPrintf(AF_DEBUG_ACTIONS, "*actions* Sending SMS to %s: \"%s\"\n", 
+                         pAction->szRcptAddr, pszExpandedData);
+               break;
+            case ACTION_REMOTE:
+               DbgPrintf(AF_DEBUG_ACTIONS, "*actions* Executing on \"%s\": \"%s\"\n", 
+                         pAction->szRcptAddr, pszExpandedData);
+               break;
+            default:
+               break;
+         }
+         free(pszExpandedData);
       }
-      free(pszExpandedData);
    }
+   RWLockUnlock(m_rwlockActionListAccess);
    return bSuccess;
 }
+
+
+//
+// Create new action
+//
+
+DWORD CreateNewAction(char *pszName, DWORD *pdwId)
+{
+   DWORD i, dwResult = RCC_SUCCESS;
+
+   RWLockWriteLock(m_rwlockActionListAccess, INFINITE);
+
+   // Check for duplicate name
+   for(i = 0; i < m_dwNumActions; i++)
+      if (!stricmp(m_pActionList[i].szName, pszName))
+      {
+         dwResult = RCC_ALREADY_EXIST;
+         break;
+      }
+
+   // If not exist, create it
+   if (i == m_dwNumActions)
+   {
+      m_dwNumActions++;
+      m_pActionList = (NXC_ACTION *)realloc(m_pActionList, sizeof(NXC_ACTION) * m_dwNumActions);
+      m_pActionList[i].dwId = CreateUniqueId(IDG_ACTION);
+      strncpy(m_pActionList[i].szName, pszName, MAX_OBJECT_NAME);
+      m_pActionList[i].bIsDisabled = TRUE;
+      m_pActionList[i].iType = ACTION_EXEC;
+      m_pActionList[i].szEmailSubject[0] = 0;
+      m_pActionList[i].szRcptAddr[0] = 0;
+      m_pActionList[i].pszData = NULL;
+
+      SaveActionToDB(&m_pActionList[i]);
+      m_dwUpdateCode = NX_NOTIFY_ACTION_CREATED;
+      EnumerateClientSessions(SendActionDBUpdate, &m_pActionList[i]);
+      *pdwId = m_pActionList[i].dwId;
+   }
+
+   RWLockUnlock(m_rwlockActionListAccess);
+   return dwResult;
+}
index 587ee53..680ad6d 100644 (file)
@@ -235,9 +235,12 @@ BOOL Initialize(void)
    if (!LoadObjects())
       return FALSE;
 
-   // Load event actions
-   if (!LoadActions())
+   // Initialize and load event actions
+   if (!InitActions())
+   {
+      WriteLog(MSG_ACTION_INIT_ERROR, EVENTLOG_ERROR_TYPE, NULL);
       return FALSE;
+   }
 
    // Initialize event handling subsystem
    if (!InitEventSubsystem())
@@ -326,7 +329,7 @@ void Shutdown(void)
       DBDisconnect(g_hCoreDB);
    DBUnloadDriver();
 
-   DestroyActionList();
+   CleanupActions();
 
    CloseLog();
 }
index 4e587ea..c49f2a1 100644 (file)
@@ -374,4 +374,10 @@ Language=English
 Your database has format version %1, but server is compiled for version %2
 .
 
+MessageId=
+SymbolicName=MSG_ACTION_INIT_ERROR
+Language=English
+Unable to initialize actions
+.
+
 ;#endif
index d84bce2..712f544 100644 (file)
@@ -28,8 +28,9 @@
 // Functions
 //
 
-BOOL LoadActions(void);
+BOOL InitActions(void);
+void CleanupActions(void);
 BOOL ExecuteAction(DWORD dwActionId, Event *pEvent);
-void DestroyActionList(void);
+DWORD CreateNewAction(char *pszName, DWORD *pdwId);
 
 #endif   /* _nms_actions_ */
index 1abebdf..a22232c 100644 (file)
@@ -175,6 +175,7 @@ typedef void * HSNMPSESSION;
 #define CSF_EVENT_DB_MODIFIED    ((DWORD)0x0004)
 #define CSF_USER_DB_LOCKED       ((DWORD)0x0008)
 #define CSF_EPP_UPLOAD           ((DWORD)0x0010)
+#define CSF_ACTION_DB_LOCKED     ((DWORD)0x0020)
 
 
 //
@@ -184,6 +185,7 @@ typedef void * HSNMPSESSION;
 #define INFO_CAT_EVENT           1
 #define INFO_CAT_OBJECT_CHANGE   2
 #define INFO_CAT_ALARM           3
+#define INFO_CAT_ACTION          4
 
 
 //
@@ -202,22 +204,12 @@ typedef void * HSNMPSESSION;
 typedef struct
 {
    DWORD dwCategory;    // Data category - event, network object, etc.
+   DWORD dwCode;        // Data-specific update code
    void *pData;         // Pointer to data block
 } UPDATE_INFO;
 
 
 //
-// Alarm update structure
-//
-
-typedef struct
-{
-   DWORD dwCode;
-   NXC_ALARM alarm;
-} ALARM_UPDATE;
-
-
-//
 // Client session
 //
 
@@ -240,6 +232,7 @@ private:
    MUTEX m_mutexSendEvents;
    MUTEX m_mutexSendObjects;
    MUTEX m_mutexSendAlarms;
+   MUTEX m_mutexSendActions;
    DWORD m_dwHostAddr;        // IP address of connected host (network byte order)
    char m_szUserName[256];    // String in form login_name@host
    DWORD m_dwOpenDCIListSize; // Number of open DCI lists
@@ -286,6 +279,10 @@ private:
    void CreateObject(CSCPMessage *pRequest);
    void ChangeObjectBinding(CSCPMessage *pRequest, BOOL bBind);
    void AcknowlegeAlarm(CSCPMessage *pRequest);
+   void CreateAction(CSCPMessage *pRequest);
+   void UpdateAction(CSCPMessage *pRequest);
+   void DeleteAction(CSCPMessage *pRequest);
+   void LockActionDB(DWORD dwRqId, BOOL bLock);
 
 public:
    ClientSession(SOCKET hSocket, DWORD dwHostAddr);
@@ -311,6 +308,7 @@ public:
    void OnObjectChange(NetObj *pObject);
    void OnUserDBUpdate(int iCode, DWORD dwUserId, NMS_USER *pUser, NMS_USER_GROUP *pGroup);
    void OnAlarmUpdate(DWORD dwCode, NXC_ALARM *pAlarm);
+   void OnActionDBUpdate(DWORD dwCode, NXC_ACTION *pAction);
 };
 
 
index e9f0c1d..9bf5df7 100644 (file)
@@ -32,6 +32,7 @@
 #define CID_EPP               1
 #define CID_USER_DB           2
 #define CID_EVENT_DB          3
+#define CID_ACTION_DB         4
 
 
 //
index 0fd300f..6d2895d 100644 (file)
@@ -82,6 +82,7 @@ ClientSession::ClientSession(SOCKET hSocket, DWORD dwHostAddr)
    m_mutexSendEvents = MutexCreate();
    m_mutexSendObjects = MutexCreate();
    m_mutexSendAlarms = MutexCreate();
+   m_mutexSendActions = MutexCreate();
    m_dwFlags = 0;
    m_dwHostAddr = dwHostAddr;
    strcpy(m_szUserName, "<not logged in>");
@@ -110,6 +111,7 @@ ClientSession::~ClientSession()
    MutexDestroy(m_mutexSendEvents);
    MutexDestroy(m_mutexSendObjects);
    MutexDestroy(m_mutexSendAlarms);
+   MutexDestroy(m_mutexSendActions);
    safe_free(m_pOpenDCIList);
    if (m_ppEPPRuleList != NULL)
    {
@@ -276,13 +278,27 @@ void ClientSession::UpdateThread(void)
             MutexLock(m_mutexSendAlarms, INFINITE);
             msg.SetCode(CMD_ALARM_UPDATE);
             msg.SetId(0);
-            msg.SetVariable(VID_NOTIFICATION_CODE, ((ALARM_UPDATE *)pUpdate->pData)->dwCode);
-            msg.SetVariable(VID_ALARM_ID, ((ALARM_UPDATE *)pUpdate->pData)->alarm.dwAlarmId);
-            if (((ALARM_UPDATE *)pUpdate->pData)->dwCode == NX_NOTIFY_NEW_ALARM)
-               FillAlarmInfoMessage(&msg, &((ALARM_UPDATE *)pUpdate->pData)->alarm);
+            msg.SetVariable(VID_NOTIFICATION_CODE, pUpdate->dwCode);
+            msg.SetVariable(VID_ALARM_ID, ((NXC_ALARM *)pUpdate->pData)->dwAlarmId);
+            if (pUpdate->dwCode == NX_NOTIFY_NEW_ALARM)
+               FillAlarmInfoMessage(&msg, (NXC_ALARM *)pUpdate->pData);
             SendMessage(&msg);
             MutexUnlock(m_mutexSendAlarms);
             msg.DeleteAllVariables();
+            free(pUpdate->pData);
+            break;
+         case INFO_CAT_ACTION:
+            MutexLock(m_mutexSendActions, INFINITE);
+            msg.SetCode(CMD_ACTION_DB_UPDATE);
+            msg.SetId(0);
+            msg.SetVariable(VID_NOTIFICATION_CODE, pUpdate->dwCode);
+            msg.SetVariable(VID_ACTION_ID, ((NXC_ACTION *)pUpdate->pData)->dwId);
+//            if (pUpdate->dwCode != NX_NOTIFY_ACTION_DELETED)
+//               FillActionInfoMessage(&msg, (NXC_ACTION *)pUpdate->pData);
+            SendMessage(&msg);
+            MutexUnlock(m_mutexSendActions);
+            msg.DeleteAllVariables();
+            free(pUpdate->pData);
             break;
          default:
             break;
@@ -431,6 +447,21 @@ void ClientSession::ProcessingThread(void)
             break;
          case CMD_DELETE_ALARM:
             break;
+         case CMD_LOCK_ACTION_DB:
+            LockActionDB(pMsg->GetId(), TRUE);
+            break;
+         case CMD_UNLOCK_ACTION_DB:
+            LockActionDB(pMsg->GetId(), FALSE);
+            break;
+         case CMD_CREATE_ACTION:
+            CreateAction(pMsg);
+            break;
+         case CMD_MODIFY_ACTION:
+            UpdateAction(pMsg);
+            break;
+         case CMD_DELETE_ACTION:
+            DeleteAction(pMsg);
+            break;
          default:
             break;
       }
@@ -1105,24 +1136,10 @@ void ClientSession::DeleteUser(CSCPMessage *pRequest)
 
       if (dwUserId != 0)
       {
-         if (!(m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_USERS))
-         {
-            // Current user has no rights for user account management
-            msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
-         }
-         else if (!(m_dwFlags & CSF_USER_DB_LOCKED))
-         {
-            // User database have to be locked before any
-            // changes to user database can be made
-            msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
-         }
-         else
-         {
-            DWORD dwResult;
+         DWORD dwResult;
 
-            dwResult = DeleteUserFromDB(dwUserId);
-            msg.SetVariable(VID_RCC, dwResult);
-         }
+         dwResult = DeleteUserFromDB(dwUserId);
+         msg.SetVariable(VID_RCC, dwResult);
       }
       else
       {
@@ -2150,9 +2167,8 @@ void ClientSession::OnAlarmUpdate(DWORD dwCode, NXC_ALARM *pAlarm)
          {
             pUpdate = (UPDATE_INFO *)malloc(sizeof(UPDATE_INFO));
             pUpdate->dwCategory = INFO_CAT_ALARM;
-            pUpdate->pData = malloc(sizeof(ALARM_UPDATE));
-            ((ALARM_UPDATE *)pUpdate->pData)->dwCode = dwCode;
-            memcpy(&((ALARM_UPDATE *)pUpdate->pData)->alarm, pAlarm, sizeof(NXC_ALARM)); 
+            pUpdate->dwCode = dwCode;
+            pUpdate->pData = nx_memdup(pAlarm, sizeof(NXC_ALARM));
             m_pUpdateQueue->Put(pUpdate);
          }
    }
@@ -2211,3 +2227,200 @@ void ClientSession::AcknowlegeAlarm(CSCPMessage *pRequest)
    // Send responce
    SendMessage(&msg);
 }
+
+
+//
+// Lock/unlock action configuration database
+//
+
+void ClientSession::LockActionDB(DWORD dwRqId, BOOL bLock)
+{
+   CSCPMessage msg;
+   char szBuffer[256];
+
+   // Prepare responce message
+   msg.SetCode(CMD_REQUEST_COMPLETED);
+   msg.SetId(dwRqId);
+
+   if (m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_ACTIONS)
+   {
+      if (bLock)
+      {
+         if (!LockComponent(CID_ACTION_DB, m_dwIndex, m_szUserName, NULL, szBuffer))
+         {
+            msg.SetVariable(VID_RCC, RCC_COMPONENT_LOCKED);
+            msg.SetVariable(VID_LOCKED_BY, szBuffer);
+         }
+         else
+         {
+            m_dwFlags |= CSF_ACTION_DB_LOCKED;
+            msg.SetVariable(VID_RCC, RCC_SUCCESS);
+         }
+      }
+      else
+      {
+         if (m_dwFlags & CSF_ACTION_DB_LOCKED)
+         {
+            UnlockComponent(CID_ACTION_DB);
+            m_dwFlags &= ~CSF_ACTION_DB_LOCKED;
+         }
+         msg.SetVariable(VID_RCC, RCC_SUCCESS);
+      }
+   }
+   else
+   {
+      // Current user has no rights for action management
+      msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
+   }
+
+   // Send responce
+   SendMessage(&msg);
+}
+
+
+//
+// Create new action
+//
+
+void ClientSession::CreateAction(CSCPMessage *pRequest)
+{
+   CSCPMessage msg;
+
+   // Prepare responce message
+   msg.SetCode(CMD_REQUEST_COMPLETED);
+   msg.SetId(pRequest->GetId());
+
+   // Check user rights
+   if (!(m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_ACTIONS))
+   {
+      msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
+   }
+   else if (!(m_dwFlags & CSF_ACTION_DB_LOCKED))
+   {
+      // Action database have to be locked before any
+      // changes can be made
+      msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
+   }
+   else
+   {
+      DWORD dwResult, dwActionId;
+      char szActionName[MAX_USER_NAME];
+
+      pRequest->GetVariableStr(VID_ACTION_NAME, szActionName, MAX_OBJECT_NAME);
+      if (IsValidObjectName(szActionName))
+      {
+         dwResult = CreateNewAction(szActionName, &dwActionId);
+         msg.SetVariable(VID_RCC, dwResult);
+         if (dwResult == RCC_SUCCESS)
+            msg.SetVariable(VID_ACTION_ID, dwActionId);   // Send id of new action to client
+      }
+      else
+      {
+         msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_NAME);
+      }
+   }
+
+   // Send responce
+   SendMessage(&msg);
+}
+
+
+//
+// Update existing action's data
+//
+
+void ClientSession::UpdateAction(CSCPMessage *pRequest)
+{
+   CSCPMessage msg;
+
+   // Prepare responce message
+   msg.SetCode(CMD_REQUEST_COMPLETED);
+   msg.SetId(pRequest->GetId());
+
+   // Check user rights
+   if (!(m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_ACTIONS))
+   {
+      msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
+   }
+   else if (!(m_dwFlags & CSF_ACTION_DB_LOCKED))
+   {
+      // Action database have to be locked before any
+      // changes can be made
+      msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
+   }
+   else
+   {
+      DWORD dwActionId, dwResult = 0;
+
+      dwActionId = pRequest->GetVariableLong(VID_ACTION_ID);
+/*         user.dwId = dwUserId;
+         pRequest->GetVariableStr(VID_USER_DESCRIPTION, user.szDescription, MAX_USER_DESCR);
+         pRequest->GetVariableStr(VID_USER_FULL_NAME, user.szFullName, MAX_USER_FULLNAME);
+         pRequest->GetVariableStr(VID_USER_NAME, user.szName, MAX_USER_NAME);
+         user.wFlags = pRequest->GetVariableShort(VID_USER_FLAGS);
+         user.wSystemRights = pRequest->GetVariableShort(VID_USER_SYS_RIGHTS);
+         dwResult = ModifyUser(&user);*/
+      msg.SetVariable(VID_RCC, dwResult);
+   }
+
+   // Send responce
+   SendMessage(&msg);
+}
+
+
+//
+// Delete action
+//
+
+void ClientSession::DeleteAction(CSCPMessage *pRequest)
+{
+   CSCPMessage msg;
+   DWORD dwActionId;
+
+   // Prepare responce message
+   msg.SetCode(CMD_REQUEST_COMPLETED);
+   msg.SetId(pRequest->GetId());
+
+   // Check user rights
+   if (!(m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_ACTIONS))
+   {
+      msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
+   }
+   else if (!(m_dwFlags & CSF_ACTION_DB_LOCKED))
+   {
+      // Action database have to be locked before any
+      // changes can be made
+      msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
+   }
+   else
+   {
+      // Get Id of action to be deleted
+      dwActionId = pRequest->GetVariableLong(VID_ACTION_ID);
+
+   }
+
+   // Send responce
+   SendMessage(&msg);
+}
+
+
+//
+// Process changes in actions
+//
+
+void ClientSession::OnActionDBUpdate(DWORD dwCode, NXC_ACTION *pAction)
+{
+   UPDATE_INFO *pUpdate;
+
+   if (m_iState == STATE_AUTHENTICATED)
+   {
+      if (m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_ACTIONS)
+      {
+         pUpdate = (UPDATE_INFO *)malloc(sizeof(UPDATE_INFO));
+         pUpdate->dwCategory = INFO_CAT_ACTION;
+         pUpdate->dwCode = dwCode;
+         pUpdate->pData = nx_memdup(pAction, sizeof(NXC_ACTION));
+         m_pUpdateQueue->Put(pUpdate);
+      }
+   }
+}
index 3fbfe83..d7a906c 100644 (file)
@@ -508,7 +508,7 @@ DWORD CreateNewUser(char *pszName, BOOL bIsGroup, DWORD *pdwId)
          g_pGroupList[i].dwId = dwNewId = CreateUniqueId(IDG_USER_GROUP);
          g_pGroupList[i].dwNumMembers = 0;
          g_pGroupList[i].pMembers = NULL;
-         strcpy(g_pGroupList[i].szName, pszName);
+         strncpy(g_pGroupList[i].szName, pszName, MAX_USER_NAME);
          g_pGroupList[i].wFlags = UF_MODIFIED;
          g_pGroupList[i].wSystemRights = 0;
          g_pGroupList[i].szDescription[0] = 0;
@@ -537,7 +537,7 @@ DWORD CreateNewUser(char *pszName, BOOL bIsGroup, DWORD *pdwId)
          g_dwNumUsers++;
          g_pUserList = (NMS_USER *)realloc(g_pUserList, sizeof(NMS_USER) * g_dwNumUsers);
          g_pUserList[i].dwId = dwNewId = CreateUniqueId(IDG_USER);
-         strcpy(g_pUserList[i].szName, pszName);
+         strncpy(g_pUserList[i].szName, pszName, MAX_USER_NAME);
          g_pUserList[i].wFlags = UF_MODIFIED;
          g_pUserList[i].wSystemRights = 0;
          g_pUserList[i].szFullName[0] = 0;