Fixed bug in DCI loading from database
[public/netxms.git] / src / server / core / session.cpp
CommitLineData
21e4b6f0
VK
1/*
2** NetXMS - Network Management System
3** Copyright (C) 2003, 2004 Victor Kirhenshtein
4**
5** This program is free software; you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation; either version 2 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program; if not, write to the Free Software
17** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18**
19** $module: session.cpp
20**
21**/
22
23#include "nms_core.h"
24
06e7be2f 25#ifdef _WIN32
c9ccd685
AK
26# include <direct.h>
27#else
28# include <dirent.h>
06e7be2f
VK
29#endif
30
21e4b6f0 31
ccdbbb52
VK
32//
33// Externals
34//
35
36void UnregisterSession(DWORD dwIndex);
37
38
d966d18a
VK
39//
40// Node poller start data
41//
42
43typedef struct
44{
45 ClientSession *pSession;
46 Node *pNode;
47 int iPollType;
48 DWORD dwRqId;
49} POLLER_START_DATA;
50
51
2d5c8ac8
VK
52//
53// Fill CSCP message with user data
54//
55
56static void FillUserInfoMessage(CSCPMessage *pMsg, NMS_USER *pUser)
57{
58 pMsg->SetVariable(VID_USER_ID, pUser->dwId);
59 pMsg->SetVariable(VID_USER_NAME, pUser->szName);
60 pMsg->SetVariable(VID_USER_FLAGS, pUser->wFlags);
61 pMsg->SetVariable(VID_USER_SYS_RIGHTS, pUser->wSystemRights);
62 pMsg->SetVariable(VID_USER_FULL_NAME, pUser->szFullName);
63 pMsg->SetVariable(VID_USER_DESCRIPTION, pUser->szDescription);
64}
65
66
67//
68// Fill CSCP message with user group data
69//
70
71static void FillGroupInfoMessage(CSCPMessage *pMsg, NMS_USER_GROUP *pGroup)
72{
73 DWORD i, dwId;
74
75 pMsg->SetVariable(VID_USER_ID, pGroup->dwId);
76 pMsg->SetVariable(VID_USER_NAME, pGroup->szName);
77 pMsg->SetVariable(VID_USER_FLAGS, pGroup->wFlags);
78 pMsg->SetVariable(VID_USER_SYS_RIGHTS, pGroup->wSystemRights);
79 pMsg->SetVariable(VID_USER_DESCRIPTION, pGroup->szDescription);
80 pMsg->SetVariable(VID_NUM_MEMBERS, pGroup->dwNumMembers);
81 for(i = 0, dwId = VID_GROUP_MEMBER_BASE; i < pGroup->dwNumMembers; i++, dwId++)
82 pMsg->SetVariable(dwId, pGroup->pMembers[i]);
83}
84
85
ccdbbb52
VK
86//
87// Client communication read thread starter
88//
89
90THREAD_RESULT THREAD_CALL ClientSession::ReadThreadStarter(void *pArg)
91{
92 ((ClientSession *)pArg)->ReadThread();
93
94 // When ClientSession::ReadThread exits, all other session
95 // threads are already stopped, so we can safely destroy
96 // session object
97 UnregisterSession(((ClientSession *)pArg)->GetIndex());
98 delete (ClientSession *)pArg;
99 return THREAD_OK;
100}
101
102
103//
104// Client communication write thread starter
105//
106
107THREAD_RESULT THREAD_CALL ClientSession::WriteThreadStarter(void *pArg)
108{
109 ((ClientSession *)pArg)->WriteThread();
110 return THREAD_OK;
111}
112
113
114//
115// Received message processing thread starter
116//
117
118THREAD_RESULT THREAD_CALL ClientSession::ProcessingThreadStarter(void *pArg)
119{
120 ((ClientSession *)pArg)->ProcessingThread();
121 return THREAD_OK;
122}
123
124
125//
126// Information update processing thread starter
127//
128
129THREAD_RESULT THREAD_CALL ClientSession::UpdateThreadStarter(void *pArg)
130{
131 ((ClientSession *)pArg)->UpdateThread();
132 return THREAD_OK;
133}
134
135
d966d18a
VK
136//
137// Forced node poll thread starter
138//
139
140THREAD_RESULT THREAD_CALL ClientSession::PollerThreadStarter(void *pArg)
141{
142 ((POLLER_START_DATA *)pArg)->pSession->PollerThread(
143 ((POLLER_START_DATA *)pArg)->pNode,
144 ((POLLER_START_DATA *)pArg)->iPollType,
145 ((POLLER_START_DATA *)pArg)->dwRqId);
146 free(pArg);
147 return THREAD_OK;
148}
149
150
21e4b6f0
VK
151//
152// Client session class constructor
153//
154
b54b2b11 155ClientSession::ClientSession(SOCKET hSocket, DWORD dwHostAddr)
21e4b6f0
VK
156{
157 m_pSendQueue = new Queue;
158 m_pMessageQueue = new Queue;
62f5857f 159 m_pUpdateQueue = new Queue;
21e4b6f0
VK
160 m_hSocket = hSocket;
161 m_dwIndex = INVALID_INDEX;
162 m_iState = STATE_CONNECTED;
163 m_pMsgBuffer = (CSCP_BUFFER *)malloc(sizeof(CSCP_BUFFER));
ccdbbb52
VK
164 m_hWriteThread = INVALID_THREAD_HANDLE;
165 m_hProcessingThread = INVALID_THREAD_HANDLE;
166 m_hUpdateThread = INVALID_THREAD_HANDLE;
03482383
VK
167 m_mutexSendEvents = MutexCreate();
168 m_mutexSendObjects = MutexCreate();
169 m_mutexSendAlarms = MutexCreate();
c9363772 170 m_mutexSendActions = MutexCreate();
d966d18a 171 m_mutexPollerInit = MutexCreate();
b54b2b11
VK
172 m_dwFlags = 0;
173 m_dwHostAddr = dwHostAddr;
174 strcpy(m_szUserName, "<not logged in>");
984542f8 175 m_dwUserId = INVALID_INDEX;
338493a0
VK
176 m_dwOpenDCIListSize = 0;
177 m_pOpenDCIList = NULL;
8f7e2482 178 m_ppEPPRuleList = NULL;
21e4b6f0
VK
179}
180
181
182//
183// Destructor
184//
185
186ClientSession::~ClientSession()
187{
188 shutdown(m_hSocket, 2);
189 closesocket(m_hSocket);
190 delete m_pSendQueue;
191 delete m_pMessageQueue;
62f5857f 192 delete m_pUpdateQueue;
338493a0 193 safe_free(m_pMsgBuffer);
03482383
VK
194 MutexDestroy(m_mutexSendEvents);
195 MutexDestroy(m_mutexSendObjects);
196 MutexDestroy(m_mutexSendAlarms);
c9363772 197 MutexDestroy(m_mutexSendActions);
d966d18a 198 MutexDestroy(m_mutexPollerInit);
338493a0 199 safe_free(m_pOpenDCIList);
8f7e2482
VK
200 if (m_ppEPPRuleList != NULL)
201 {
202 DWORD i;
203
204 if (m_dwFlags & CSF_EPP_UPLOAD) // Aborted in the middle of EPP transfer
205 for(i = 0; i < m_dwRecordsUploaded; i++)
206 delete m_ppEPPRuleList[i];
207 free(m_ppEPPRuleList);
208 }
21e4b6f0
VK
209}
210
211
ccdbbb52
VK
212//
213// Start all threads
214//
215
216void ClientSession::Run(void)
217{
218 m_hWriteThread = ThreadCreateEx(WriteThreadStarter, 0, this);
219 m_hProcessingThread = ThreadCreateEx(ProcessingThreadStarter, 0, this);
220 m_hUpdateThread = ThreadCreateEx(UpdateThreadStarter, 0, this);
221 ThreadCreate(ReadThreadStarter, 0, this);
222}
223
224
21e4b6f0
VK
225//
226// Print debug information
227//
228
229void ClientSession::DebugPrintf(char *szFormat, ...)
230{
231 if ((g_dwFlags & AF_STANDALONE) && (g_dwFlags & AF_DEBUG_CSCP))
232 {
233 va_list args;
234
235 printf("*CSCP(%d)* ", m_dwIndex);
236 va_start(args, szFormat);
237 vprintf(szFormat, args);
238 va_end(args);
239 }
240}
241
242
21e4b6f0
VK
243//
244// ReadThread()
245//
246
247void ClientSession::ReadThread(void)
248{
249 CSCP_MESSAGE *pRawMsg;
250 CSCPMessage *pMsg;
251 int iErr;
338493a0
VK
252 DWORD i;
253 NetObj *pObject;
21e4b6f0
VK
254
255 // Initialize raw message receiving function
a933a2bf 256 RecvCSCPMessage(0, NULL, m_pMsgBuffer, 0);
21e4b6f0
VK
257
258 pRawMsg = (CSCP_MESSAGE *)malloc(65536);
259 while(1)
260 {
a933a2bf 261 if ((iErr = RecvCSCPMessage(m_hSocket, pRawMsg, m_pMsgBuffer, 65536)) <= 0)
21e4b6f0
VK
262 break;
263
a933a2bf
VK
264 // Check if message is too large
265 if (iErr == 1)
266 continue;
267
21e4b6f0 268 // Check that actual received packet size is equal to encoded in packet
6159a875 269 if ((int)ntohl(pRawMsg->dwSize) != iErr)
21e4b6f0 270 {
6159a875 271 DebugPrintf("Actual message size doesn't match wSize value (%d,%d)\n", iErr, ntohl(pRawMsg->dwSize));
21e4b6f0
VK
272 continue; // Bad packet, wait for next
273 }
274
275 // Create message object from raw message
276 pMsg = new CSCPMessage(pRawMsg);
277 m_pMessageQueue->Put(pMsg);
278 }
279 if (iErr < 0)
280 WriteLog(MSG_SESSION_CLOSED, EVENTLOG_WARNING_TYPE, "e", WSAGetLastError());
281 free(pRawMsg);
282
283 // Notify other threads to exit
d09b1909 284 m_pSendQueue->Clear();
ecb7e1ee 285 m_pSendQueue->Put(INVALID_POINTER_VALUE);
d09b1909 286 m_pMessageQueue->Clear();
ecb7e1ee 287 m_pMessageQueue->Put(INVALID_POINTER_VALUE);
d09b1909 288 m_pUpdateQueue->Clear();
8f7e2482 289 m_pUpdateQueue->Put(INVALID_POINTER_VALUE);
ecb7e1ee
VK
290
291 // Wait for other threads to finish
ccdbbb52
VK
292 ThreadJoin(m_hWriteThread);
293 ThreadJoin(m_hProcessingThread);
294 ThreadJoin(m_hUpdateThread);
54abbe0e
VK
295
296 // Remove all locks created by this session
297 RemoveAllSessionLocks(m_dwIndex);
338493a0
VK
298 for(i = 0; i < m_dwOpenDCIListSize; i++)
299 {
300 pObject = FindObjectById(m_pOpenDCIList[i]);
301 if (pObject != NULL)
302 if (pObject->Type() == OBJECT_NODE)
303 ((Node *)pObject)->UnlockDCIList(m_dwIndex);
304 }
8f7e2482
VK
305
306 DebugPrintf("Session closed\n");
21e4b6f0
VK
307}
308
309
310//
311// WriteThread()
312//
313
314void ClientSession::WriteThread(void)
315{
316 CSCP_MESSAGE *pMsg;
7ac0c0a8 317 char szBuffer[128];
21e4b6f0
VK
318
319 while(1)
320 {
321 pMsg = (CSCP_MESSAGE *)m_pSendQueue->GetOrBlock();
ecb7e1ee 322 if (pMsg == INVALID_POINTER_VALUE) // Session termination indicator
21e4b6f0
VK
323 break;
324
6159a875
VK
325 DebugPrintf("Sending message %s\n", CSCPMessageCodeName(ntohs(pMsg->wCode), szBuffer));
326 if (send(m_hSocket, (const char *)pMsg, ntohl(pMsg->dwSize), 0) <= 0)
21e4b6f0 327 {
9d72bde1 328 safe_free(pMsg);
21e4b6f0
VK
329 break;
330 }
9d72bde1 331 safe_free(pMsg);
21e4b6f0 332 }
8f7e2482
VK
333}
334
335
336//
337// Update processing thread
338//
339
340void ClientSession::UpdateThread(void)
341{
342 UPDATE_INFO *pUpdate;
343 CSCPMessage msg;
344
8f7e2482
VK
345 while(1)
346 {
347 pUpdate = (UPDATE_INFO *)m_pUpdateQueue->GetOrBlock();
348 if (pUpdate == INVALID_POINTER_VALUE) // Session termination indicator
349 break;
350
351 switch(pUpdate->dwCategory)
352 {
353 case INFO_CAT_EVENT:
03482383 354 MutexLock(m_mutexSendEvents, INFINITE);
8f7e2482 355 m_pSendQueue->Put(CreateRawCSCPMessage(CMD_EVENT, 0, sizeof(NXC_EVENT), pUpdate->pData, NULL));
03482383 356 MutexUnlock(m_mutexSendEvents);
8f7e2482
VK
357 free(pUpdate->pData);
358 break;
359 case INFO_CAT_OBJECT_CHANGE:
03482383 360 MutexLock(m_mutexSendObjects, INFINITE);
8f7e2482 361 msg.SetCode(CMD_OBJECT_UPDATE);
03482383 362 msg.SetId(0);
8f7e2482
VK
363 ((NetObj *)pUpdate->pData)->CreateMessage(&msg);
364 SendMessage(&msg);
03482383 365 MutexUnlock(m_mutexSendObjects);
8f7e2482
VK
366 msg.DeleteAllVariables();
367 ((NetObj *)pUpdate->pData)->DecRefCount();
368 break;
03482383
VK
369 case INFO_CAT_ALARM:
370 MutexLock(m_mutexSendAlarms, INFINITE);
371 msg.SetCode(CMD_ALARM_UPDATE);
372 msg.SetId(0);
c9363772 373 msg.SetVariable(VID_NOTIFICATION_CODE, pUpdate->dwCode);
b900a78b 374 FillAlarmInfoMessage(&msg, (NXC_ALARM *)pUpdate->pData);
49dde062 375 SendMessage(&msg);
03482383
VK
376 MutexUnlock(m_mutexSendAlarms);
377 msg.DeleteAllVariables();
c9363772
VK
378 free(pUpdate->pData);
379 break;
380 case INFO_CAT_ACTION:
381 MutexLock(m_mutexSendActions, INFINITE);
382 msg.SetCode(CMD_ACTION_DB_UPDATE);
383 msg.SetId(0);
384 msg.SetVariable(VID_NOTIFICATION_CODE, pUpdate->dwCode);
385 msg.SetVariable(VID_ACTION_ID, ((NXC_ACTION *)pUpdate->pData)->dwId);
e91cb822
VK
386 if (pUpdate->dwCode != NX_NOTIFY_ACTION_DELETED)
387 FillActionInfoMessage(&msg, (NXC_ACTION *)pUpdate->pData);
c9363772
VK
388 SendMessage(&msg);
389 MutexUnlock(m_mutexSendActions);
390 msg.DeleteAllVariables();
391 free(pUpdate->pData);
03482383 392 break;
8f7e2482
VK
393 default:
394 break;
395 }
396
397 free(pUpdate);
398 }
21e4b6f0
VK
399}
400
401
402//
403// Message processing thread
404//
405
406void ClientSession::ProcessingThread(void)
407{
3421c063 408 CSCPMessage *pMsg;
74a5aa17 409 char szBuffer[128];
21e4b6f0
VK
410
411 while(1)
412 {
413 pMsg = (CSCPMessage *)m_pMessageQueue->GetOrBlock();
ecb7e1ee 414 if (pMsg == INVALID_POINTER_VALUE) // Session termination indicator
21e4b6f0
VK
415 break;
416
74a5aa17 417 DebugPrintf("Received message %s\n", CSCPMessageCodeName(pMsg->GetCode(), szBuffer));
21e4b6f0
VK
418 if ((m_iState != STATE_AUTHENTICATED) && (pMsg->GetCode() != CMD_LOGIN))
419 {
420 delete pMsg;
421 continue;
422 }
423
424 switch(pMsg->GetCode())
425 {
426 case CMD_LOGIN:
e100f091 427 Login(pMsg);
21e4b6f0
VK
428 break;
429 case CMD_GET_OBJECTS:
e100f091 430 SendAllObjects(pMsg->GetId());
21e4b6f0
VK
431 break;
432 case CMD_GET_EVENTS:
74a5aa17 433 SendAllEvents(pMsg->GetId());
21e4b6f0
VK
434 break;
435 case CMD_GET_CONFIG_VARLIST:
436 SendAllConfigVars();
437 break;
b54b2b11
VK
438 case CMD_OPEN_EVENT_DB:
439 SendEventDB(pMsg->GetId());
440 break;
441 case CMD_CLOSE_EVENT_DB:
3421c063 442 CloseEventDB(pMsg->GetId());
b54b2b11 443 break;
605d2931
VK
444 case CMD_SET_EVENT_INFO:
445 SetEventInfo(pMsg);
446 break;
24156e90
VK
447 case CMD_MODIFY_OBJECT:
448 ModifyObject(pMsg);
449 break;
c1c39152
VK
450 case CMD_SET_OBJECT_MGMT_STATUS:
451 ChangeObjectMgmtStatus(pMsg);
452 break;
23a32988
VK
453 case CMD_LOAD_USER_DB:
454 SendUserDB(pMsg->GetId());
455 break;
ff550544
VK
456 case CMD_CREATE_USER:
457 CreateUser(pMsg);
458 break;
459 case CMD_UPDATE_USER:
460 UpdateUser(pMsg);
461 break;
462 case CMD_DELETE_USER:
463 DeleteUser(pMsg);
464 break;
465 case CMD_LOCK_USER_DB:
466 LockUserDB(pMsg->GetId(), TRUE);
467 break;
468 case CMD_UNLOCK_USER_DB:
469 LockUserDB(pMsg->GetId(), FALSE);
470 break;
017e1e13
VK
471 case CMD_SET_PASSWORD:
472 SetPassword(pMsg);
473 break;
7257eb7d
VK
474 case CMD_GET_NODE_DCI_LIST:
475 OpenNodeDCIList(pMsg);
476 break;
477 case CMD_UNLOCK_NODE_DCI_LIST:
478 CloseNodeDCIList(pMsg);
479 break;
9ed4eaff
VK
480 case CMD_CREATE_NEW_DCI:
481 case CMD_MODIFY_NODE_DCI:
482 case CMD_DELETE_NODE_DCI:
483 ModifyNodeDCI(pMsg);
484 break;
ebebc8ea
VK
485 case CMD_GET_DCI_DATA:
486 GetCollectedData(pMsg);
487 break;
06e7be2f
VK
488 case CMD_OPEN_EPP:
489 OpenEPP(pMsg->GetId());
490 break;
491 case CMD_CLOSE_EPP:
492 CloseEPP(pMsg->GetId());
493 break;
494 case CMD_SAVE_EPP:
495 SaveEPP(pMsg);
496 break;
8f7e2482
VK
497 case CMD_EPP_RECORD:
498 ProcessEPPRecord(pMsg);
06e7be2f
VK
499 break;
500 case CMD_GET_MIB_LIST:
501 SendMIBList(pMsg->GetId());
502 break;
503 case CMD_GET_MIB:
504 SendMIB(pMsg);
505 break;
ef44d5ea
VK
506 case CMD_CREATE_OBJECT:
507 CreateObject(pMsg);
508 break;
e6b958c4
VK
509 case CMD_BIND_OBJECT:
510 ChangeObjectBinding(pMsg, TRUE);
511 break;
512 case CMD_UNBIND_OBJECT:
513 ChangeObjectBinding(pMsg, FALSE);
514 break;
3421c063
VK
515 case CMD_GET_EVENT_NAMES:
516 SendEventNames(pMsg->GetId());
517 break;
f70fc197 518 case CMD_GET_IMAGE_LIST:
aa3743b2 519 SendImageCatalogue(this, pMsg->GetId(), pMsg->GetVariableShort(VID_IMAGE_FORMAT));
f70fc197
VK
520 break;
521 case CMD_LOAD_IMAGE_FILE:
aa3743b2
VK
522 SendImageFile(this, pMsg->GetId(), pMsg->GetVariableLong(VID_IMAGE_ID),
523 pMsg->GetVariableShort(VID_IMAGE_FORMAT));
8bff53f6
VK
524 break;
525 case CMD_GET_DEFAULT_IMAGE_LIST:
526 SendDefaultImageList(this, pMsg->GetId());
f70fc197 527 break;
03482383
VK
528 case CMD_GET_ALL_ALARMS:
529 SendAllAlarms(pMsg->GetId(), pMsg->GetVariableShort(VID_IS_ACK));
530 break;
531 case CMD_GET_ALARM:
532 break;
533 case CMD_ACK_ALARM:
ee20e615
VK
534 AcknowlegeAlarm(pMsg);
535 break;
536 case CMD_DELETE_ALARM:
03482383 537 break;
c9363772
VK
538 case CMD_LOCK_ACTION_DB:
539 LockActionDB(pMsg->GetId(), TRUE);
540 break;
541 case CMD_UNLOCK_ACTION_DB:
542 LockActionDB(pMsg->GetId(), FALSE);
543 break;
544 case CMD_CREATE_ACTION:
545 CreateAction(pMsg);
546 break;
547 case CMD_MODIFY_ACTION:
548 UpdateAction(pMsg);
549 break;
550 case CMD_DELETE_ACTION:
551 DeleteAction(pMsg);
552 break;
e91cb822
VK
553 case CMD_LOAD_ACTIONS:
554 SendAllActions(pMsg->GetId());
555 break;
6849d9be
VK
556 case CMD_GET_CONTAINER_CAT_LIST:
557 SendContainerCategories(pMsg->GetId());
558 break;
88039e6c
VK
559 case CMD_DELETE_OBJECT:
560 DeleteObject(pMsg);
561 break;
0b89f5fb
VK
562 case CMD_POLL_NODE:
563 ForcedNodePoll(pMsg);
564 break;
21e4b6f0
VK
565 default:
566 break;
567 }
568 delete pMsg;
569 }
570}
571
572
e100f091
VK
573//
574// Authenticate client
575//
576
577void ClientSession::Login(CSCPMessage *pRequest)
578{
579 CSCPMessage msg;
6528a4d7 580 BYTE szPassword[SHA1_DIGEST_SIZE];
e100f091
VK
581 char szLogin[MAX_USER_NAME], szBuffer[32];
582
583 // Prepare responce message
584 msg.SetCode(CMD_LOGIN_RESP);
585 msg.SetId(pRequest->GetId());
586
587 if (m_iState != STATE_AUTHENTICATED)
588 {
589
590 pRequest->GetVariableStr(VID_LOGIN_NAME, szLogin, MAX_USER_NAME);
6528a4d7 591 pRequest->GetVariableBinary(VID_PASSWORD, szPassword, SHA1_DIGEST_SIZE);
e100f091
VK
592
593 if (AuthenticateUser(szLogin, szPassword, &m_dwUserId, &m_dwSystemAccess))
594 {
595 m_iState = STATE_AUTHENTICATED;
596 sprintf(m_szUserName, "%s@%s", szLogin, IpToStr(m_dwHostAddr, szBuffer));
597 msg.SetVariable(VID_RCC, RCC_SUCCESS);
598 DebugPrintf("User %s authenticated\n", m_szUserName);
599 }
600 else
601 {
602 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
603 }
604 }
605 else
606 {
607 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
608 }
609
610 // Send responce
611 SendMessage(&msg);
612}
613
614
b54b2b11
VK
615//
616// Send event configuration to client
617//
618
619void ClientSession::SendEventDB(DWORD dwRqId)
620{
621 DB_ASYNC_RESULT hResult;
622 CSCPMessage msg;
623 char szBuffer[1024];
624
625 // Prepare responce message
3a5042fd 626 msg.SetCode(CMD_REQUEST_COMPLETED);
b54b2b11
VK
627 msg.SetId(dwRqId);
628
b8bad201
VK
629 if (!CheckSysAccessRights(SYSTEM_ACCESS_VIEW_EVENT_DB))
630 {
631 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
632 SendMessage(&msg);
633 }
634 else if (!LockComponent(CID_EVENT_DB, m_dwIndex, m_szUserName, NULL, szBuffer))
b54b2b11
VK
635 {
636 msg.SetVariable(VID_RCC, RCC_COMPONENT_LOCKED);
637 msg.SetVariable(VID_LOCKED_BY, szBuffer);
638 SendMessage(&msg);
639 }
640 else
641 {
642 m_dwFlags |= CSF_EVENT_DB_LOCKED;
b8bad201 643 m_dwFlags &= ~CSF_EVENT_DB_MODIFIED;
b54b2b11
VK
644
645 msg.SetVariable(VID_RCC, RCC_SUCCESS);
646 SendMessage(&msg);
647 msg.DeleteAllVariables();
648
649 // Prepare data message
650 msg.SetCode(CMD_EVENT_DB_RECORD);
651 msg.SetId(dwRqId);
652
eafa21c7 653 hResult = DBAsyncSelect(g_hCoreDB, "SELECT event_id,name,severity,flags,message,description FROM events");
ebebc8ea 654 if (hResult != NULL)
b54b2b11 655 {
ebebc8ea
VK
656 while(DBFetch(hResult))
657 {
658 msg.SetVariable(VID_EVENT_ID, DBGetFieldAsyncULong(hResult, 0));
659 msg.SetVariable(VID_NAME, DBGetFieldAsync(hResult, 1, szBuffer, 1024));
660 msg.SetVariable(VID_SEVERITY, DBGetFieldAsyncULong(hResult, 2));
661 msg.SetVariable(VID_FLAGS, DBGetFieldAsyncULong(hResult, 3));
8f7e2482
VK
662
663 DBGetFieldAsync(hResult, 4, szBuffer, 1024);
664 DecodeSQLString(szBuffer);
665 msg.SetVariable(VID_MESSAGE, szBuffer);
666
667 DBGetFieldAsync(hResult, 5, szBuffer, 1024);
668 DecodeSQLString(szBuffer);
669 msg.SetVariable(VID_DESCRIPTION, szBuffer);
670
ebebc8ea
VK
671 SendMessage(&msg);
672 msg.DeleteAllVariables();
673 }
674 DBFreeAsyncResult(hResult);
b54b2b11 675 }
3a5042fd
VK
676
677 // Send end-of-list indicator
678 msg.SetCode(CMD_EVENT_DB_EOF);
679 SendMessage(&msg);
b54b2b11
VK
680 }
681}
682
683
3421c063
VK
684//
685// Close event configuration database
686//
687
688void ClientSession::CloseEventDB(DWORD dwRqId)
689{
690 CSCPMessage msg;
691
692 msg.SetCode(CMD_REQUEST_COMPLETED);
693 msg.SetId(dwRqId);
694
695 if (m_dwFlags & CSF_EVENT_DB_LOCKED)
696 {
697 // Check if event configuration DB has been modified
698 if (m_dwFlags & CSF_EVENT_DB_MODIFIED)
699 {
700 ReloadEvents();
701
702 // Notify clients on event database change
703 EnumerateClientSessions(NotifyClient, (void *)NX_NOTIFY_EVENTDB_CHANGED);
704 }
705 UnlockComponent(CID_EVENT_DB);
706 m_dwFlags &= ~CSF_EVENT_DB_LOCKED;
707 msg.SetVariable(VID_RCC, RCC_SUCCESS);
708 }
709 else
710 {
711 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
712 }
713 SendMessage(&msg);
714}
715
716
21e4b6f0
VK
717//
718// Send all objects to client
719//
720
e100f091 721void ClientSession::SendAllObjects(DWORD dwRqId)
21e4b6f0
VK
722{
723 DWORD i;
724 CSCPMessage msg;
725
e100f091
VK
726 // Send confirmation message
727 msg.SetCode(CMD_REQUEST_COMPLETED);
728 msg.SetId(dwRqId);
729 msg.SetVariable(VID_RCC, RCC_SUCCESS);
730 SendMessage(&msg);
731 msg.DeleteAllVariables();
732
03482383 733 MutexLock(m_mutexSendObjects, INFINITE);
53512272 734
21e4b6f0
VK
735 // Prepare message
736 msg.SetCode(CMD_OBJECT);
737
738 // Send objects, one per message
739 ObjectsGlobalLock();
740 for(i = 0; i < g_dwIdIndexSize; i++)
24156e90
VK
741 if (g_pIndexById[i].pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
742 {
743 g_pIndexById[i].pObject->CreateMessage(&msg);
744 SendMessage(&msg);
745 msg.DeleteAllVariables();
746 }
21e4b6f0
VK
747 ObjectsGlobalUnlock();
748
749 // Send end of list notification
750 msg.SetCode(CMD_OBJECT_LIST_END);
751 SendMessage(&msg);
53512272 752
03482383 753 MutexUnlock(m_mutexSendObjects);
21e4b6f0
VK
754}
755
756
757//
758// Send all events to client
759//
760
74a5aa17 761void ClientSession::SendAllEvents(DWORD dwRqId)
21e4b6f0 762{
21e4b6f0 763 CSCPMessage msg;
20177e8e 764 DB_ASYNC_RESULT hResult;
9c36ef66 765 NXC_EVENT event;
21e4b6f0 766
74a5aa17
VK
767 // Send confirmation message
768 msg.SetCode(CMD_REQUEST_COMPLETED);
769 msg.SetId(dwRqId);
770 msg.SetVariable(VID_RCC, RCC_SUCCESS);
771 SendMessage(&msg);
772 msg.DeleteAllVariables();
773
03482383 774 MutexLock(m_mutexSendEvents, INFINITE);
62f5857f 775
21e4b6f0 776 // Retrieve events from database
31115ff9
VK
777 hResult = DBAsyncSelect(g_hCoreDB, "SELECT event_id,event_timestamp,event_source,"
778 "event_severity,event_message FROM event_log "
779 "ORDER BY event_timestamp");
21e4b6f0
VK
780 if (hResult != NULL)
781 {
782 // Send events, one per message
20177e8e 783 while(DBFetch(hResult))
21e4b6f0 784 {
20177e8e
VK
785 event.dwEventId = htonl(DBGetFieldAsyncULong(hResult, 0));
786 event.dwTimeStamp = htonl(DBGetFieldAsyncULong(hResult, 1));
787 event.dwSourceId = htonl(DBGetFieldAsyncULong(hResult, 2));
788 event.dwSeverity = htonl(DBGetFieldAsyncULong(hResult, 3));
789 DBGetFieldAsync(hResult, 4, event.szMessage, MAX_EVENT_MSG_LENGTH);
8f7e2482 790 DecodeSQLString(event.szMessage);
74a5aa17 791 m_pSendQueue->Put(CreateRawCSCPMessage(CMD_EVENT, dwRqId, sizeof(NXC_EVENT), &event, NULL));
9c36ef66 792 }
20177e8e 793 DBFreeAsyncResult(hResult);
21e4b6f0
VK
794 }
795
796 // Send end of list notification
797 msg.SetCode(CMD_EVENT_LIST_END);
798 SendMessage(&msg);
62f5857f 799
03482383 800 MutexUnlock(m_mutexSendEvents);
21e4b6f0
VK
801}
802
803
804//
805// Send all configuration variables to client
806//
807
808void ClientSession::SendAllConfigVars(void)
809{
810 DWORD i, dwNumRecords;
811 CSCPMessage msg;
812 DB_RESULT hResult;
813
814 // Check user rights
815 if ((m_dwUserId != 0) && ((m_dwSystemAccess & SYSTEM_ACCESS_VIEW_CONFIG) == 0))
816 {
817 // Access denied
818 msg.SetCode(CMD_CONFIG_VARLIST_END);
a5f8dbb8 819 msg.SetVariable(VID_ERROR, (DWORD)1);
21e4b6f0
VK
820 SendMessage(&msg);
821 }
822 else
823 {
824 // Prepare message
825 msg.SetCode(CMD_CONFIG_VARIABLE);
826
827 // Retrieve configuration variables from database
31115ff9 828 hResult = DBSelect(g_hCoreDB, "SELECT var_name,var_value FROM config");
21e4b6f0
VK
829 if (hResult != NULL)
830 {
831 // Send events, one per message
832 dwNumRecords = DBGetNumRows(hResult);
833 for(i = 0; i < dwNumRecords; i++)
834 {
a5f8dbb8
VK
835 msg.SetVariable(VID_NAME, DBGetField(hResult, i, 0));
836 msg.SetVariable(VID_VALUE, DBGetField(hResult, i, 1));
21e4b6f0
VK
837 SendMessage(&msg);
838 msg.DeleteAllVariables();
839 }
20177e8e 840 DBFreeResult(hResult);
21e4b6f0
VK
841 }
842
843 // Send end of list notification
844 msg.SetCode(CMD_CONFIG_VARLIST_END);
a5f8dbb8 845 msg.SetVariable(VID_ERROR, (DWORD)0);
21e4b6f0
VK
846 SendMessage(&msg);
847 }
848}
20177e8e
VK
849
850
851//
852// Close session forcibly
853//
854
855void ClientSession::Kill(void)
856{
857 // We shutdown socket connection, which will cause
858 // read thread to stop, and other threads will follow
859 shutdown(m_hSocket, 2);
860}
62f5857f
VK
861
862
863//
864// Handler for new events
865//
866
867void ClientSession::OnNewEvent(Event *pEvent)
868{
869 UPDATE_INFO *pUpdate;
870
984542f8
VK
871 if (m_iState == STATE_AUTHENTICATED)
872 {
873 pUpdate = (UPDATE_INFO *)malloc(sizeof(UPDATE_INFO));
874 pUpdate->dwCategory = INFO_CAT_EVENT;
875 pUpdate->pData = malloc(sizeof(NXC_EVENT));
876 pEvent->PrepareMessage((NXC_EVENT *)pUpdate->pData);
877 m_pUpdateQueue->Put(pUpdate);
878 }
62f5857f
VK
879}
880
881
882//
883// Handler for object changes
884//
885
53512272 886void ClientSession::OnObjectChange(NetObj *pObject)
62f5857f 887{
53512272
VK
888 UPDATE_INFO *pUpdate;
889
984542f8
VK
890 if (m_iState == STATE_AUTHENTICATED)
891 if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
892 {
893 pUpdate = (UPDATE_INFO *)malloc(sizeof(UPDATE_INFO));
894 pUpdate->dwCategory = INFO_CAT_OBJECT_CHANGE;
895 pUpdate->pData = pObject;
984542f8 896 pObject->IncRefCount();
333ece94 897 m_pUpdateQueue->Put(pUpdate);
984542f8 898 }
62f5857f
VK
899}
900
901
83f0529c
VK
902//
903// Send notification message to server
904//
905
4de204a3 906void ClientSession::Notify(DWORD dwCode, DWORD dwData)
83f0529c
VK
907{
908 CSCPMessage msg;
909
910 msg.SetCode(CMD_NOTIFY);
911 msg.SetVariable(VID_NOTIFICATION_CODE, dwCode);
4de204a3 912 msg.SetVariable(VID_NOTIFICATION_DATA, dwData);
83f0529c
VK
913 SendMessage(&msg);
914}
605d2931
VK
915
916
917//
918// Update event template
919//
920
921void ClientSession::SetEventInfo(CSCPMessage *pRequest)
922{
923 CSCPMessage msg;
924
925 // Prepare reply message
926 msg.SetCode(CMD_REQUEST_COMPLETED);
927 msg.SetId(pRequest->GetId());
928
929 // Check if we have event configuration database opened
930 if (!(m_dwFlags & CSF_EVENT_DB_LOCKED))
931 {
932 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
933 }
934 else
935 {
936 // Check access rights
937 if (CheckSysAccessRights(SYSTEM_ACCESS_EDIT_EVENT_DB))
938 {
8f7e2482 939 char szQuery[4096], szName[MAX_EVENT_NAME];
605d2931
VK
940 DWORD dwEventId;
941 BOOL bEventExist = FALSE;
942 DB_RESULT hResult;
943
944 // Check if event with specific id exists
945 dwEventId = pRequest->GetVariableLong(VID_EVENT_ID);
946 sprintf(szQuery, "SELECT event_id FROM events WHERE event_id=%ld", dwEventId);
947 hResult = DBSelect(g_hCoreDB, szQuery);
948 if (hResult != NULL)
949 {
950 if (DBGetNumRows(hResult) > 0)
951 bEventExist = TRUE;
952 DBFreeResult(hResult);
953 }
954
b8bad201 955 // Prepare and execute SQL query
8f7e2482
VK
956 pRequest->GetVariableStr(VID_NAME, szName, MAX_EVENT_NAME);
957 if (IsValidObjectName(szName))
b8bad201 958 {
8f7e2482
VK
959 char szMessage[MAX_DB_STRING], *pszDescription, *pszEscMsg, *pszEscDescr;
960
961 pRequest->GetVariableStr(VID_MESSAGE, szMessage, MAX_DB_STRING);
962 pszEscMsg = EncodeSQLString(szMessage);
963
964 pszDescription = pRequest->GetVariableStr(VID_DESCRIPTION);
965 pszEscDescr = EncodeSQLString(pszDescription);
9d72bde1 966 safe_free(pszDescription);
8f7e2482
VK
967
968 if (bEventExist)
969 {
970 sprintf(szQuery, "UPDATE events SET name='%s',severity=%ld,flags=%ld,message='%s',description='%s' WHERE event_id=%ld",
971 szName, pRequest->GetVariableLong(VID_SEVERITY), pRequest->GetVariableLong(VID_FLAGS),
972 pszEscMsg, pszEscDescr, dwEventId);
973 }
974 else
975 {
976 sprintf(szQuery, "INSERT INTO events SET event_id,name,severity,flags,message,description VALUES (%ld,'%s',%ld,%ld,'%s','%s')",
977 dwEventId, szName, pRequest->GetVariableLong(VID_SEVERITY),
978 pRequest->GetVariableLong(VID_FLAGS), pszEscMsg, pszEscDescr);
979 }
980
981 free(pszEscMsg);
982 free(pszEscDescr);
983
984 if (DBQuery(g_hCoreDB, szQuery))
985 {
986 msg.SetVariable(VID_RCC, RCC_SUCCESS);
987 m_dwFlags |= CSF_EVENT_DB_MODIFIED;
988 }
989 else
990 {
991 msg.SetVariable(VID_RCC, RCC_DB_FAILURE);
992 }
b8bad201 993 }
605d2931 994 else
b8bad201 995 {
8f7e2482 996 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_NAME);
b8bad201 997 }
605d2931
VK
998 }
999 else
1000 {
1001 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1002 }
1003 }
1004
1005 // Send responce
1006 SendMessage(&msg);
1007}
24156e90
VK
1008
1009
1010//
1011// Modify object
1012//
1013
1014void ClientSession::ModifyObject(CSCPMessage *pRequest)
1015{
ff550544 1016 DWORD dwObjectId, dwResult = RCC_SUCCESS;
24156e90
VK
1017 NetObj *pObject;
1018 CSCPMessage msg;
1019
1020 // Prepare reply message
1021 msg.SetCode(CMD_REQUEST_COMPLETED);
1022 msg.SetId(pRequest->GetId());
1023
1024 dwObjectId = pRequest->GetVariableLong(VID_OBJECT_ID);
1025 pObject = FindObjectById(dwObjectId);
1026 if (pObject != NULL)
1027 {
1028 if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_MODIFY))
1029 {
ff550544
VK
1030 // If user attempts to change object's ACL, check
1031 // if he has OBJECT_ACCESS_CONTROL permission
1032 if (pRequest->IsVariableExist(VID_ACL_SIZE))
1033 if (!pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_CONTROL))
1034 dwResult = RCC_ACCESS_DENIED;
1035
1036 // If allowed, change object and set completion code
1037 if (dwResult != RCC_ACCESS_DENIED)
1038 dwResult = pObject->ModifyFromMessage(pRequest);
24156e90
VK
1039 msg.SetVariable(VID_RCC, dwResult);
1040 }
1041 else
1042 {
1043 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1044 }
1045 }
1046 else
1047 {
1048 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
1049 }
1050
1051 // Send responce
1052 SendMessage(&msg);
1053}
23a32988
VK
1054
1055
1056//
1057// Send users database to client
1058//
1059
1060void ClientSession::SendUserDB(DWORD dwRqId)
1061{
1062 CSCPMessage msg;
2d5c8ac8 1063 DWORD i;
23a32988
VK
1064
1065 // Prepare responce message
1066 msg.SetCode(CMD_REQUEST_COMPLETED);
1067 msg.SetId(dwRqId);
1068 msg.SetVariable(VID_RCC, RCC_SUCCESS);
1069 SendMessage(&msg);
1070
1071 // Send users
1072 msg.SetCode(CMD_USER_DATA);
1073 for(i = 0; i < g_dwNumUsers; i++)
1074 {
2d5c8ac8 1075 FillUserInfoMessage(&msg, &g_pUserList[i]);
23a32988
VK
1076 SendMessage(&msg);
1077 msg.DeleteAllVariables();
1078 }
1079
1080 // Send groups
1081 msg.SetCode(CMD_GROUP_DATA);
1082 for(i = 0; i < g_dwNumGroups; i++)
1083 {
2d5c8ac8 1084 FillGroupInfoMessage(&msg, &g_pGroupList[i]);
23a32988
VK
1085 SendMessage(&msg);
1086 msg.DeleteAllVariables();
1087 }
1088
1089 // Send end-of-database notification
1090 msg.SetCode(CMD_USER_DB_EOF);
1091 SendMessage(&msg);
1092}
ff550544
VK
1093
1094
1095//
1096// Create new user
1097//
1098
1099void ClientSession::CreateUser(CSCPMessage *pRequest)
1100{
1101 CSCPMessage msg;
1102
1103 // Prepare responce message
1104 msg.SetCode(CMD_REQUEST_COMPLETED);
1105 msg.SetId(pRequest->GetId());
1106
1107 // Check user rights
1108 if (!(m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_USERS))
1109 {
1110 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1111 }
1112 else if (!(m_dwFlags & CSF_USER_DB_LOCKED))
1113 {
1114 // User database have to be locked before any
1115 // changes to user database can be made
1116 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
1117 }
1118 else
1119 {
984542f8 1120 DWORD dwResult, dwUserId;
ff550544
VK
1121 BOOL bIsGroup;
1122 char szUserName[MAX_USER_NAME];
1123
1124 pRequest->GetVariableStr(VID_USER_NAME, szUserName, MAX_USER_NAME);
8f7e2482
VK
1125 if (IsValidObjectName(szUserName))
1126 {
1127 bIsGroup = pRequest->GetVariableShort(VID_IS_GROUP);
1128 dwResult = CreateNewUser(szUserName, bIsGroup, &dwUserId);
1129 msg.SetVariable(VID_RCC, dwResult);
1130 if (dwResult == RCC_SUCCESS)
1131 msg.SetVariable(VID_USER_ID, dwUserId); // Send id of new user to client
1132 }
1133 else
1134 {
1135 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_NAME);
1136 }
ff550544
VK
1137 }
1138
1139 // Send responce
1140 SendMessage(&msg);
1141}
1142
1143
1144//
1145// Update existing user's data
1146//
1147
1148void ClientSession::UpdateUser(CSCPMessage *pRequest)
1149{
612d43dc
VK
1150 CSCPMessage msg;
1151
1152 // Prepare responce message
1153 msg.SetCode(CMD_REQUEST_COMPLETED);
1154 msg.SetId(pRequest->GetId());
1155
1156 // Check user rights
1157 if (!(m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_USERS))
1158 {
1159 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1160 }
1161 else if (!(m_dwFlags & CSF_USER_DB_LOCKED))
1162 {
1163 // User database have to be locked before any
1164 // changes to user database can be made
1165 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
1166 }
1167 else
1168 {
86f31e8f 1169 DWORD dwUserId, dwResult;
612d43dc
VK
1170
1171 dwUserId = pRequest->GetVariableLong(VID_USER_ID);
1172 if (dwUserId & GROUP_FLAG)
1173 {
1174 NMS_USER_GROUP group;
2d5c8ac8 1175 DWORD i, dwId;
86f31e8f
VK
1176
1177 group.dwId = dwUserId;
2d5c8ac8
VK
1178 pRequest->GetVariableStr(VID_USER_DESCRIPTION, group.szDescription, MAX_USER_DESCR);
1179 pRequest->GetVariableStr(VID_USER_NAME, group.szName, MAX_USER_NAME);
1180 group.wFlags = pRequest->GetVariableShort(VID_USER_FLAGS);
1181 group.wSystemRights = pRequest->GetVariableShort(VID_USER_SYS_RIGHTS);
1182 group.dwNumMembers = pRequest->GetVariableLong(VID_NUM_MEMBERS);
1183 group.pMembers = (DWORD *)malloc(sizeof(DWORD) * group.dwNumMembers);
1184 for(i = 0, dwId = VID_GROUP_MEMBER_BASE; i < group.dwNumMembers; i++, dwId++)
1185 group.pMembers[i] = pRequest->GetVariableLong(dwId);
86f31e8f 1186 dwResult = ModifyGroup(&group);
2d5c8ac8 1187 safe_free(group.pMembers);
612d43dc
VK
1188 }
1189 else
1190 {
1191 NMS_USER user;
1192
1193 user.dwId = dwUserId;
1194 pRequest->GetVariableStr(VID_USER_DESCRIPTION, user.szDescription, MAX_USER_DESCR);
1195 pRequest->GetVariableStr(VID_USER_FULL_NAME, user.szFullName, MAX_USER_FULLNAME);
1196 pRequest->GetVariableStr(VID_USER_NAME, user.szName, MAX_USER_NAME);
1197 user.wFlags = pRequest->GetVariableShort(VID_USER_FLAGS);
86f31e8f
VK
1198 user.wSystemRights = pRequest->GetVariableShort(VID_USER_SYS_RIGHTS);
1199 dwResult = ModifyUser(&user);
612d43dc 1200 }
86f31e8f 1201 msg.SetVariable(VID_RCC, dwResult);
612d43dc
VK
1202 }
1203
1204 // Send responce
1205 SendMessage(&msg);
ff550544
VK
1206}
1207
1208
1209//
1210// Delete user
1211//
1212
1213void ClientSession::DeleteUser(CSCPMessage *pRequest)
1214{
1215 CSCPMessage msg;
1216 DWORD dwUserId;
1217
1218 // Prepare responce message
1219 msg.SetCode(CMD_REQUEST_COMPLETED);
1220 msg.SetId(pRequest->GetId());
1221
612d43dc
VK
1222 // Check user rights
1223 if (!(m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_USERS))
ff550544 1224 {
612d43dc
VK
1225 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1226 }
1227 else if (!(m_dwFlags & CSF_USER_DB_LOCKED))
1228 {
1229 // User database have to be locked before any
1230 // changes to user database can be made
1231 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
1232 }
1233 else
1234 {
1235 // Get Id of user to be deleted
1236 dwUserId = pRequest->GetVariableLong(VID_USER_ID);
1237
1238 if (dwUserId != 0)
ff550544 1239 {
c9363772 1240 DWORD dwResult;
612d43dc 1241
c9363772
VK
1242 dwResult = DeleteUserFromDB(dwUserId);
1243 msg.SetVariable(VID_RCC, dwResult);
ff550544
VK
1244 }
1245 else
1246 {
612d43dc
VK
1247 // Nobody can delete system administrator account
1248 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
ff550544
VK
1249 }
1250 }
ff550544
VK
1251
1252 // Send responce
1253 SendMessage(&msg);
1254}
1255
1256
1257//
1258// Lock/unlock user database
1259//
1260
1261void ClientSession::LockUserDB(DWORD dwRqId, BOOL bLock)
1262{
1263 CSCPMessage msg;
1264 char szBuffer[256];
1265
1266 // Prepare responce message
1267 msg.SetCode(CMD_REQUEST_COMPLETED);
1268 msg.SetId(dwRqId);
1269
1270 if (m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_USERS)
1271 {
1272 if (bLock)
1273 {
1274 if (!LockComponent(CID_USER_DB, m_dwIndex, m_szUserName, NULL, szBuffer))
1275 {
1276 msg.SetVariable(VID_RCC, RCC_COMPONENT_LOCKED);
1277 msg.SetVariable(VID_LOCKED_BY, szBuffer);
1278 }
1279 else
1280 {
1281 m_dwFlags |= CSF_USER_DB_LOCKED;
1282 msg.SetVariable(VID_RCC, RCC_SUCCESS);
1283 }
1284 }
1285 else
1286 {
1287 if (m_dwFlags & CSF_USER_DB_LOCKED)
1288 {
1289 UnlockComponent(CID_USER_DB);
1290 m_dwFlags &= ~CSF_USER_DB_LOCKED;
1291 }
1292 msg.SetVariable(VID_RCC, RCC_SUCCESS);
1293 }
1294 }
1295 else
1296 {
1297 // Current user has no rights for user account management
1298 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1299 }
1300
1301 // Send responce
1302 SendMessage(&msg);
1303}
984542f8
VK
1304
1305
1306//
1307// Notify client on user database update
1308//
1309
1310void ClientSession::OnUserDBUpdate(int iCode, DWORD dwUserId, NMS_USER *pUser, NMS_USER_GROUP *pGroup)
1311{
1312 CSCPMessage msg;
1313
1314 if (m_iState == STATE_AUTHENTICATED)
1315 {
1316 msg.SetCode(CMD_USER_DB_UPDATE);
1317 msg.SetId(0);
1318 msg.SetVariable(VID_UPDATE_TYPE, (WORD)iCode);
984542f8
VK
1319
1320 switch(iCode)
1321 {
1322 case USER_DB_CREATE:
2d5c8ac8 1323 msg.SetVariable(VID_USER_ID, dwUserId);
984542f8 1324 if (dwUserId & GROUP_FLAG)
984542f8 1325 msg.SetVariable(VID_USER_NAME, pGroup->szName);
984542f8 1326 else
984542f8 1327 msg.SetVariable(VID_USER_NAME, pUser->szName);
2d5c8ac8
VK
1328 break;
1329 case USER_DB_MODIFY:
1330 if (dwUserId & GROUP_FLAG)
1331 FillGroupInfoMessage(&msg, pGroup);
1332 else
1333 FillUserInfoMessage(&msg, pUser);
984542f8
VK
1334 break;
1335 default:
2d5c8ac8 1336 msg.SetVariable(VID_USER_ID, dwUserId);
984542f8
VK
1337 break;
1338 }
1339
1340 SendMessage(&msg);
1341 }
1342}
017e1e13
VK
1343
1344
9ed4eaff
VK
1345//
1346// Change management status for the object
1347//
1348
1349void ClientSession::ChangeObjectMgmtStatus(CSCPMessage *pRequest)
1350{
1351 CSCPMessage msg;
1352 DWORD dwObjectId;
1353 NetObj *pObject;
1354
1355 // Prepare responce message
1356 msg.SetCode(CMD_REQUEST_COMPLETED);
1357 msg.SetId(pRequest->GetId());
1358
1359 // Get object id and check access rights
1360 dwObjectId = pRequest->GetVariableLong(VID_OBJECT_ID);
1361 pObject = FindObjectById(dwObjectId);
1362 if (pObject != NULL)
1363 {
1364 if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_MODIFY))
1365 {
1366 BOOL bIsManaged;
1367
1368 bIsManaged = (BOOL)pRequest->GetVariableShort(VID_MGMT_STATUS);
1369 pObject->SetMgmtStatus(bIsManaged);
1370 msg.SetVariable(VID_RCC, RCC_SUCCESS);
1371 }
1372 else
1373 {
1374 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1375 }
1376 }
1377 else
1378 {
1379 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
1380 }
1381
1382 // Send responce
1383 SendMessage(&msg);
1384}
1385
1386
017e1e13
VK
1387//
1388// Set user's password
1389//
1390
1391void ClientSession::SetPassword(CSCPMessage *pRequest)
1392{
1393 CSCPMessage msg;
1394 DWORD dwUserId;
1395
1396 // Prepare responce message
1397 msg.SetCode(CMD_REQUEST_COMPLETED);
1398 msg.SetId(pRequest->GetId());
1399
1400 dwUserId = pRequest->GetVariableLong(VID_USER_ID);
1401
1402 if (((m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_USERS) &&
1403 !((dwUserId == 0) && (m_dwUserId != 0))) || // Only administrator can change password for UID 0
1404 (dwUserId == m_dwUserId)) // User can change password for itself
1405 {
1406 DWORD dwResult;
6528a4d7 1407 BYTE szPassword[SHA1_DIGEST_SIZE];
017e1e13 1408
6528a4d7 1409 pRequest->GetVariableBinary(VID_PASSWORD, szPassword, SHA1_DIGEST_SIZE);
017e1e13
VK
1410 dwResult = SetUserPassword(dwUserId, szPassword);
1411 msg.SetVariable(VID_RCC, dwResult);
1412 }
1413 else
1414 {
1415 // Current user has no rights to change password for specific user
1416 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1417 }
1418
1419 // Send responce
1420 SendMessage(&msg);
1421}
7257eb7d
VK
1422
1423
1424//
1425// Send node's DCIs to client and lock data collection settings
1426//
1427
1428void ClientSession::OpenNodeDCIList(CSCPMessage *pRequest)
1429{
1430 CSCPMessage msg;
3c55b85d
VK
1431 DWORD dwObjectId;
1432 NetObj *pObject;
1433 BOOL bSuccess = FALSE;
7257eb7d
VK
1434
1435 // Prepare responce message
1436 msg.SetCode(CMD_REQUEST_COMPLETED);
1437 msg.SetId(pRequest->GetId());
1438
3c55b85d
VK
1439 // Get node id and check object class and access rights
1440 dwObjectId = pRequest->GetVariableLong(VID_OBJECT_ID);
1441 pObject = FindObjectById(dwObjectId);
1442 if (pObject != NULL)
1443 {
1444 if (pObject->Type() == OBJECT_NODE)
1445 {
1446 if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
1447 {
1448 // Try to lock DCI list
1449 bSuccess = ((Node *)pObject)->LockDCIList(m_dwIndex);
1450 msg.SetVariable(VID_RCC, bSuccess ? RCC_SUCCESS : RCC_COMPONENT_LOCKED);
338493a0
VK
1451
1452 // Modify list of open nodes DCI lists
1453 if (bSuccess)
1454 {
1455 m_pOpenDCIList = (DWORD *)realloc(m_pOpenDCIList, sizeof(DWORD) * (m_dwOpenDCIListSize + 1));
1456 m_pOpenDCIList[m_dwOpenDCIListSize] = dwObjectId;
1457 m_dwOpenDCIListSize++;
1458 }
3c55b85d
VK
1459 }
1460 else
1461 {
1462 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1463 }
1464 }
1465 else
1466 {
1467 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
1468 }
1469 }
1470 else
1471 {
1472 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
1473 }
7257eb7d
VK
1474
1475 // Send responce
1476 SendMessage(&msg);
3c55b85d
VK
1477
1478 // If DCI list was successfully locked, send it to client
1479 if (bSuccess)
1480 ((Node *)pObject)->SendItemsToClient(this, pRequest->GetId());
7257eb7d
VK
1481}
1482
1483
1484//
1485// Unlock node's data collection settings
1486//
1487
1488void ClientSession::CloseNodeDCIList(CSCPMessage *pRequest)
1489{
1490 CSCPMessage msg;
3c55b85d
VK
1491 DWORD dwObjectId;
1492 NetObj *pObject;
7257eb7d
VK
1493
1494 // Prepare responce message
1495 msg.SetCode(CMD_REQUEST_COMPLETED);
1496 msg.SetId(pRequest->GetId());
1497
3c55b85d
VK
1498 // Get node id and check object class and access rights
1499 dwObjectId = pRequest->GetVariableLong(VID_OBJECT_ID);
1500 pObject = FindObjectById(dwObjectId);
1501 if (pObject != NULL)
1502 {
1503 if (pObject->Type() == OBJECT_NODE)
1504 {
1505 if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
1506 {
1507 BOOL bSuccess;
1508
1509 // Try to unlock DCI list
1510 bSuccess = ((Node *)pObject)->UnlockDCIList(m_dwIndex);
1511 msg.SetVariable(VID_RCC, bSuccess ? RCC_SUCCESS : RCC_OUT_OF_STATE_REQUEST);
338493a0
VK
1512
1513 // Modify list of open nodes DCI lists
1514 if (bSuccess)
1515 {
1516 DWORD i;
1517
1518 for(i = 0; i < m_dwOpenDCIListSize; i++)
1519 if (m_pOpenDCIList[i] == dwObjectId)
1520 {
1521 m_dwOpenDCIListSize--;
1522 memmove(&m_pOpenDCIList[i], &m_pOpenDCIList[i + 1],
1523 sizeof(DWORD) * (m_dwOpenDCIListSize - i));
1524 break;
1525 }
1526 }
3c55b85d
VK
1527 }
1528 else
1529 {
1530 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1531 }
1532 }
1533 else
1534 {
1535 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
1536 }
1537 }
1538 else
1539 {
1540 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
1541 }
1542
7257eb7d
VK
1543 // Send responce
1544 SendMessage(&msg);
1545}
c1c39152
VK
1546
1547
1548//
9ed4eaff 1549// Create, modify, or delete data collection item for node
c1c39152
VK
1550//
1551
9ed4eaff 1552void ClientSession::ModifyNodeDCI(CSCPMessage *pRequest)
c1c39152
VK
1553{
1554 CSCPMessage msg;
1555 DWORD dwObjectId;
1556 NetObj *pObject;
1557
1558 // Prepare responce message
1559 msg.SetCode(CMD_REQUEST_COMPLETED);
1560 msg.SetId(pRequest->GetId());
1561
9ed4eaff 1562 // Get node id and check object class and access rights
c1c39152
VK
1563 dwObjectId = pRequest->GetVariableLong(VID_OBJECT_ID);
1564 pObject = FindObjectById(dwObjectId);
1565 if (pObject != NULL)
1566 {
9ed4eaff 1567 if (pObject->Type() == OBJECT_NODE)
c1c39152 1568 {
9ed4eaff
VK
1569 if (((Node *)pObject)->IsLockedBySession(m_dwIndex))
1570 {
1571 if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_MODIFY))
1572 {
07a45e04 1573 DWORD i, dwItemId, dwNumMaps, *pdwMapId, *pdwMapIndex;
9ed4eaff
VK
1574 DCItem *pItem;
1575 BOOL bSuccess;
1576
1577 switch(pRequest->GetCode())
1578 {
1579 case CMD_CREATE_NEW_DCI:
1580 // Create dummy DCI
1581 pItem = new DCItem(CreateUniqueId(IDG_ITEM), "no name", DS_INTERNAL,
0ae741b9 1582 DCI_DT_INT, 60, 30, (Node *)pObject);
9ed4eaff
VK
1583 pItem->SetStatus(ITEM_STATUS_DISABLED);
1584 if (((Node *)pObject)->AddItem(pItem))
1585 {
1586 msg.SetVariable(VID_RCC, RCC_SUCCESS);
1587 // Return new item id to client
1588 msg.SetVariable(VID_DCI_ID, pItem->Id());
1589 }
1590 else // Unable to add item to node
1591 {
1592 delete pItem;
1593 msg.SetVariable(VID_RCC, RCC_DUPLICATE_DCI);
1594 }
1595 break;
1596 case CMD_MODIFY_NODE_DCI:
1597 dwItemId = pRequest->GetVariableLong(VID_DCI_ID);
07a45e04
VK
1598 bSuccess = ((Node *)pObject)->UpdateItem(dwItemId, pRequest, &dwNumMaps,
1599 &pdwMapIndex, &pdwMapId);
1600 if (bSuccess)
1601 {
1602 msg.SetVariable(VID_RCC, RCC_SUCCESS);
1603
1604 // Send index to id mapping for newly created thresholds to client
1605 msg.SetVariable(VID_DCI_NUM_MAPS, dwNumMaps);
1606 for(i = 0; i < dwNumMaps; i++)
1607 {
1608 pdwMapId[i] = htonl(pdwMapId[i]);
1609 pdwMapIndex[i] = htonl(pdwMapIndex[i]);
1610 }
1611 msg.SetVariable(VID_DCI_MAP_IDS, (BYTE *)pdwMapId, sizeof(DWORD) * dwNumMaps);
1612 msg.SetVariable(VID_DCI_MAP_INDEXES, (BYTE *)pdwMapIndex, sizeof(DWORD) * dwNumMaps);
7247842d
VK
1613 safe_free(pdwMapId);
1614 safe_free(pdwMapIndex);
07a45e04
VK
1615 }
1616 else
1617 {
1618 msg.SetVariable(VID_RCC, RCC_INVALID_DCI_ID);
1619 }
9ed4eaff
VK
1620 break;
1621 case CMD_DELETE_NODE_DCI:
1622 dwItemId = pRequest->GetVariableLong(VID_DCI_ID);
1623 bSuccess = ((Node *)pObject)->DeleteItem(dwItemId);
1624 msg.SetVariable(VID_RCC, bSuccess ? RCC_SUCCESS : RCC_INVALID_DCI_ID);
1625 break;
1626 }
1627 }
1628 else // User doesn't have MODIFY rights on object
1629 {
1630 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1631 }
1632 }
1633 else // Nodes DCI list not locked by this session
1634 {
1635 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
1636 }
c1c39152 1637 }
9ed4eaff 1638 else // Object is not a node
c1c39152 1639 {
9ed4eaff 1640 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
c1c39152
VK
1641 }
1642 }
9ed4eaff 1643 else // No object with given ID
c1c39152
VK
1644 {
1645 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
1646 }
1647
1648 // Send responce
1649 SendMessage(&msg);
1650}
ebebc8ea
VK
1651
1652
1653//
1654// Get collected data
1655//
1656
1657void ClientSession::GetCollectedData(CSCPMessage *pRequest)
1658{
1659 CSCPMessage msg;
1660 DWORD dwObjectId;
1661 NetObj *pObject;
6159a875 1662 BOOL bSuccess = FALSE;
2b9c1c41 1663 static DWORD m_dwRowSize[] = { 8, 8, 12, 12, 260, 12 };
ebebc8ea
VK
1664
1665 // Prepare responce message
1666 msg.SetCode(CMD_REQUEST_COMPLETED);
1667 msg.SetId(pRequest->GetId());
1668
1669 // Get node id and check object class and access rights
1670 dwObjectId = pRequest->GetVariableLong(VID_OBJECT_ID);
1671 pObject = FindObjectById(dwObjectId);
1672 if (pObject != NULL)
1673 {
1674 if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
1675 {
1676 DB_ASYNC_RESULT hResult;
1677 DWORD dwItemId, dwMaxRows, dwTimeFrom, dwTimeTo;
6159a875 1678 DWORD dwAllocatedRows = 100, dwNumRows = 0;
bdce7422
VK
1679 char szQuery[512], szCond[256];
1680 int iPos = 0, iType;
1681 DCI_DATA_HEADER *pData = NULL;
6159a875 1682 DCI_DATA_ROW *pCurr;
bdce7422
VK
1683
1684 // Send CMD_REQUEST_COMPLETED message
1685 msg.SetVariable(VID_RCC, RCC_SUCCESS);
1686 SendMessage(&msg);
ebebc8ea
VK
1687
1688 // Get request parameters
1689 dwItemId = pRequest->GetVariableLong(VID_DCI_ID);
1690 dwMaxRows = pRequest->GetVariableLong(VID_MAX_ROWS);
1691 dwTimeFrom = pRequest->GetVariableLong(VID_TIME_FROM);
1692 dwTimeTo = pRequest->GetVariableLong(VID_TIME_TO);
1693
9f20696e 1694 szCond[0] = 0;
bdce7422
VK
1695 if (dwTimeFrom != 0)
1696 {
1dc90d86 1697 sprintf(szCond, " AND idata_timestamp>=%d", dwTimeFrom);
bdce7422
VK
1698 iPos = strlen(szCond);
1699 }
1700 if (dwTimeTo != 0)
1701 {
1dc90d86 1702 sprintf(&szCond[iPos], " AND idata_timestamp<=%d", dwTimeTo);
bdce7422
VK
1703 }
1704
31115ff9 1705 sprintf(szQuery, "SELECT idata_timestamp,idata_value FROM idata_%d WHERE item_id=%d%s ORDER BY idata_timestamp DESC",
bdce7422 1706 dwObjectId, dwItemId, szCond);
ebebc8ea
VK
1707 hResult = DBAsyncSelect(g_hCoreDB, szQuery);
1708 if (hResult != NULL)
1709 {
6159a875 1710 // Get item's data type to determine actual row size
bdce7422
VK
1711 iType = ((Node *)pObject)->GetItemType(dwItemId);
1712
6159a875
VK
1713 // Allocate initial memory block and prepare data header
1714 pData = (DCI_DATA_HEADER *)malloc(dwAllocatedRows * m_dwRowSize[iType] + sizeof(DCI_DATA_HEADER));
1715 pData->dwDataType = htonl((DWORD)iType);
1716 pData->dwItemId = htonl(dwItemId);
1717
1718 // Fill memory block with records
1719 pCurr = (DCI_DATA_ROW *)(((char *)pData) + sizeof(DCI_DATA_HEADER));
ebebc8ea
VK
1720 while(DBFetch(hResult))
1721 {
6159a875 1722 if ((dwMaxRows > 0) && (dwNumRows >= dwMaxRows))
bdce7422 1723 break;
6159a875
VK
1724
1725 // Extend buffer if we are at the end
1726 if (dwNumRows == dwAllocatedRows)
1727 {
1728 dwAllocatedRows += 50;
1729 pData = (DCI_DATA_HEADER *)realloc(pData,
1730 dwAllocatedRows * m_dwRowSize[iType] + sizeof(DCI_DATA_HEADER));
1731 pCurr = (DCI_DATA_ROW *)(((char *)pData) + sizeof(DCI_DATA_HEADER) + m_dwRowSize[iType] * dwNumRows);
1732 }
1733
1734 dwNumRows++;
1735
1736 pCurr->dwTimeStamp = htonl(DBGetFieldAsyncULong(hResult, 0));
1737 switch(iType)
1738 {
0ae741b9
VK
1739 case DCI_DT_INT:
1740 case DCI_DT_UINT:
9f20696e
VK
1741 pCurr->value.dwInteger = htonl(DBGetFieldAsyncULong(hResult, 1));
1742 break;
0ae741b9
VK
1743 case DCI_DT_INT64:
1744 case DCI_DT_UINT64:
1745 /* TODO: add 64-bit conversion */
1746 pCurr->value.qwInt64 = htonl(DBGetFieldAsyncULong(hResult, 1));
1747 break;
42d7ed00 1748 case DCI_DT_FLOAT:
9f20696e 1749 pCurr->value.dFloat = htond(DBGetFieldAsyncDouble(hResult, 1));
6159a875 1750 break;
42d7ed00 1751 case DCI_DT_STRING:
6159a875
VK
1752 DBGetFieldAsync(hResult, 1, pCurr->value.szString, MAX_DCI_STRING_VALUE);
1753 break;
1754 }
1755 pCurr = (DCI_DATA_ROW *)(((char *)pCurr) + m_dwRowSize[iType]);
ebebc8ea
VK
1756 }
1757 DBFreeAsyncResult(hResult);
9f20696e 1758 pData->dwNumRows = htonl(dwNumRows);
6159a875
VK
1759
1760 // Prepare and send raw message with fetched data
1761 m_pSendQueue->Put(
1762 CreateRawCSCPMessage(CMD_DCI_DATA, pRequest->GetId(),
1763 dwNumRows * m_dwRowSize[iType] + sizeof(DCI_DATA_HEADER),
1764 pData, NULL));
1765 free(pData);
1766 bSuccess = TRUE;
ebebc8ea
VK
1767 }
1768 }
1769 else
1770 {
1771 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1772 }
1773 }
1774 else // No object with given ID
1775 {
1776 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
1777 }
1778
1779 // Send responce
6159a875
VK
1780 if (!bSuccess)
1781 SendMessage(&msg);
ebebc8ea 1782}
06e7be2f
VK
1783
1784
1785//
1786// Open event processing policy
1787//
1788
1789void ClientSession::OpenEPP(DWORD dwRqId)
1790{
1791 CSCPMessage msg;
1792 char szBuffer[256];
1793 BOOL bSuccess = FALSE;
1794
1795 // Prepare responce message
1796 msg.SetCode(CMD_REQUEST_COMPLETED);
1797 msg.SetId(dwRqId);
1798
1799 if (m_dwSystemAccess & SYSTEM_ACCESS_EPP)
1800 {
1801 if (!LockComponent(CID_EPP, m_dwIndex, m_szUserName, NULL, szBuffer))
1802 {
1803 msg.SetVariable(VID_RCC, RCC_COMPONENT_LOCKED);
1804 msg.SetVariable(VID_LOCKED_BY, szBuffer);
1805 }
1806 else
1807 {
1808 m_dwFlags |= CSF_EPP_LOCKED;
1809 msg.SetVariable(VID_RCC, RCC_SUCCESS);
1810 msg.SetVariable(VID_NUM_RULES, g_pEventPolicy->NumRules());
1811 bSuccess = TRUE;
1812 }
1813 }
1814 else
1815 {
1816 // Current user has no rights for event policy management
1817 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1818 }
1819
1820 // Send responce
1821 SendMessage(&msg);
1822
1823 // Send policy to client
1824 if (bSuccess)
1825 g_pEventPolicy->SendToClient(this, dwRqId);
1826}
1827
1828
1829//
1830// Close event processing policy
1831//
1832
1833void ClientSession::CloseEPP(DWORD dwRqId)
1834{
1835 CSCPMessage msg;
1836
1837 // Prepare responce message
1838 msg.SetCode(CMD_REQUEST_COMPLETED);
1839 msg.SetId(dwRqId);
1840
1841 if (m_dwSystemAccess & SYSTEM_ACCESS_EPP)
1842 {
1843 if (m_dwFlags & CSF_EPP_LOCKED)
1844 {
1845 UnlockComponent(CID_EPP);
1846 m_dwFlags &= ~CSF_EPP_LOCKED;
1847 }
1848 msg.SetVariable(VID_RCC, RCC_SUCCESS);
1849 }
1850 else
1851 {
1852 // Current user has no rights for event policy management
1853 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1854 }
1855
1856 // Send responce
1857 SendMessage(&msg);
1858}
1859
1860
1861//
1862// Save event processing policy
1863//
1864
8f7e2482 1865void ClientSession::SaveEPP(CSCPMessage *pRequest)
06e7be2f 1866{
8f7e2482
VK
1867 CSCPMessage msg;
1868
1869 // Prepare responce message
1870 msg.SetCode(CMD_REQUEST_COMPLETED);
1871 msg.SetId(pRequest->GetId());
1872
1873 if (m_dwSystemAccess & SYSTEM_ACCESS_EPP)
1874 {
1875 if (m_dwFlags & CSF_EPP_LOCKED)
1876 {
1877 msg.SetVariable(VID_RCC, RCC_SUCCESS);
8f7e2482
VK
1878 m_dwNumRecordsToUpload = pRequest->GetVariableLong(VID_NUM_RULES);
1879 m_dwRecordsUploaded = 0;
043fe1ec
VK
1880 if (m_dwNumRecordsToUpload == 0)
1881 {
1882 g_pEventPolicy->ReplacePolicy(0, NULL);
1883 g_pEventPolicy->SaveToDB();
1884 }
1885 else
1886 {
1887 m_dwFlags |= CSF_EPP_UPLOAD;
1888 m_ppEPPRuleList = (EPRule **)malloc(sizeof(EPRule *) * m_dwNumRecordsToUpload);
1889 memset(m_ppEPPRuleList, 0, sizeof(EPRule *) * m_dwNumRecordsToUpload);
1890 }
8f7e2482
VK
1891 DebugPrintf("Accepted EPP upload request for %d rules\n", m_dwNumRecordsToUpload);
1892 }
1893 else
1894 {
1895 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
1896 }
1897 }
1898 else
1899 {
1900 // Current user has no rights for event policy management
1901 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1902 }
1903
1904 // Send responce
1905 SendMessage(&msg);
06e7be2f
VK
1906}
1907
1908
1909//
8f7e2482 1910// Process EPP rule received from client
06e7be2f
VK
1911//
1912
8f7e2482 1913void ClientSession::ProcessEPPRecord(CSCPMessage *pRequest)
06e7be2f 1914{
8f7e2482
VK
1915 if (!(m_dwFlags & CSF_EPP_LOCKED))
1916 {
1917 CSCPMessage msg;
1918
1919 msg.SetCode(CMD_REQUEST_COMPLETED);
1920 msg.SetId(pRequest->GetId());
1921 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
1922 SendMessage(&msg);
1923 }
1924 else
1925 {
1926 if (m_dwRecordsUploaded < m_dwNumRecordsToUpload)
1927 {
1928 m_ppEPPRuleList[m_dwRecordsUploaded] = new EPRule(pRequest);
1929 m_dwRecordsUploaded++;
1930 if (m_dwRecordsUploaded == m_dwNumRecordsToUpload)
1931 {
1932 CSCPMessage msg;
1933
1934 // All records received, replace event policy...
1935 DebugPrintf("Replacing event processing policy with a new one at %p (%d rules)\n",
1936 m_ppEPPRuleList, m_dwNumRecordsToUpload);
1937 g_pEventPolicy->ReplacePolicy(m_dwNumRecordsToUpload, m_ppEPPRuleList);
043fe1ec 1938 g_pEventPolicy->SaveToDB();
8f7e2482
VK
1939 m_ppEPPRuleList = NULL;
1940
1941 // ... and send final confirmation
1942 msg.SetCode(CMD_REQUEST_COMPLETED);
1943 msg.SetId(pRequest->GetId());
1944 msg.SetVariable(VID_RCC, RCC_SUCCESS);
1945 SendMessage(&msg);
1946
1947 m_dwFlags &= ~CSF_EPP_UPLOAD;
1948 }
1949 }
1950 }
06e7be2f
VK
1951}
1952
1953
1954//
1955// Send list of available MIB files to client
1956//
1957
1958void ClientSession::SendMIBList(DWORD dwRqId)
1959{
1960 CSCPMessage msg;
1961 DWORD dwId1, dwId2, dwNumFiles;
1962 DIR *dir;
1963 int iBufPos;
c9ccd685 1964#ifdef _WIN32
06e7be2f 1965 struct direct *dptr;
c9ccd685
AK
1966#else
1967 struct dirent *dptr;
1968#endif
06e7be2f
VK
1969 char szBuffer[MAX_PATH];
1970 BYTE md5Hash[MD5_DIGEST_SIZE];
1971
1972 // Prepare responce message
1973 msg.SetCode(CMD_MIB_LIST);
1974 msg.SetId(dwRqId);
1975
1976 // Read directory
1977 dwNumFiles = 0;
1978 strcpy(szBuffer, g_szDataDir);
1979 strcat(szBuffer, DDIR_MIBS);
1980 dir = opendir(szBuffer);
1981 if (dir != NULL)
1982 {
06f6e54c 1983 strcat(szBuffer, FS_PATH_SEPARATOR);
06e7be2f
VK
1984 iBufPos = strlen(szBuffer);
1985 dwId1 = VID_MIB_NAME_BASE;
1986 dwId2 = VID_MIB_HASH_BASE;
1987 while((dptr = readdir(dir)) != NULL)
1988 {
06f6e54c
VK
1989 if (dptr->d_name[0] == '.')
1990 continue;
1991
06e7be2f
VK
1992 strcpy(&szBuffer[iBufPos], dptr->d_name);
1993 if (CalculateFileMD5Hash(szBuffer, md5Hash))
1994 {
1995 msg.SetVariable(dwId1++, dptr->d_name);
1996 msg.SetVariable(dwId2++, md5Hash, MD5_DIGEST_SIZE);
1997 dwNumFiles++;
1998 }
1999 }
2000 closedir(dir);
2001 }
2002
2003 msg.SetVariable(VID_NUM_MIBS, dwNumFiles);
2004
2005 // Send responce
2006 SendMessage(&msg);
2007}
2008
2009
2010//
2011// Send requested MIB file to client
2012//
2013
2014void ClientSession::SendMIB(CSCPMessage *pRequest)
2015{
2016 CSCPMessage msg;
2017 BYTE *pFile;
2018 DWORD dwFileSize;
2019 char szBuffer[MAX_PATH], szMIB[MAX_PATH];
2020
2021 // Prepare responce message
2022 msg.SetCode(CMD_MIB);
2023 msg.SetId(pRequest->GetId());
2024
2025 // Get name of the requested file
2026 pRequest->GetVariableStr(VID_MIB_NAME, szMIB, MAX_PATH);
2027
2028 // Load file into memory
2029 strcpy(szBuffer, g_szDataDir);
2030 strcat(szBuffer, DDIR_MIBS);
2031#ifdef _WIN32
2032 strcat(szBuffer, "\\");
2033#else
2034 strcat(szBuffer, "/");
2035#endif
2036 strcat(szBuffer, szMIB);
2037 pFile = LoadFile(szBuffer, &dwFileSize);
2038 if (pFile != NULL)
2039 {
2040 msg.SetVariable(VID_RCC, RCC_SUCCESS);
2041 msg.SetVariable(VID_MIB_FILE_SIZE, dwFileSize);
2042 msg.SetVariable(VID_MIB_FILE, pFile, dwFileSize);
2043 free(pFile);
2044 }
2045 else
2046 {
2047 msg.SetVariable(VID_RCC, RCC_SYSTEM_FAILURE);
2048 }
2049
2050 // Send responce
2051 SendMessage(&msg);
2052}
ef44d5ea
VK
2053
2054
3421c063
VK
2055//
2056// Send list of event name/identifier pairs
2057//
2058
2059void ClientSession::SendEventNames(DWORD dwRqId)
2060{
2061 CSCPMessage msg;
2062 DB_RESULT hResult;
2063
2064 msg.SetCode(CMD_EVENT_NAME_LIST);
2065 msg.SetId(dwRqId);
936eeedf 2066 hResult = DBSelect(g_hCoreDB, "SELECT event_id,name,severity FROM events");
3421c063
VK
2067 if (hResult != NULL)
2068 {
2069 DWORD i, dwNumEvents;
2070 NXC_EVENT_NAME *pList;
2071
2072 dwNumEvents = DBGetNumRows(hResult);
2073 msg.SetVariable(VID_NUM_EVENTS, dwNumEvents);
2074 if (dwNumEvents > 0)
2075 {
2076 pList = (NXC_EVENT_NAME *)malloc(sizeof(NXC_EVENT_NAME) * dwNumEvents);
2077 for(i = 0; i < dwNumEvents; i++)
2078 {
2079 pList[i].dwEventId = htonl(DBGetFieldULong(hResult, i, 0));
936eeedf 2080 pList[i].dwSeverity = htonl(DBGetFieldLong(hResult, i, 2));
3421c063
VK
2081 strcpy(pList[i].szName, DBGetField(hResult, i, 1));
2082 }
2083 msg.SetVariable(VID_EVENT_NAME_TABLE, (BYTE *)pList, sizeof(NXC_EVENT_NAME) * dwNumEvents);
2084 free(pList);
2085 }
2086 DBFreeResult(hResult);
2087 msg.SetVariable(VID_RCC, RCC_SUCCESS);
2088 }
2089 else
2090 {
2091 msg.SetVariable(VID_RCC, RCC_DB_FAILURE);
2092 }
2093 SendMessage(&msg);
2094}
2095
2096
ef44d5ea
VK
2097//
2098// Create new object
2099//
2100
2101void ClientSession::CreateObject(CSCPMessage *pRequest)
2102{
e6b958c4
VK
2103 CSCPMessage msg;
2104 NetObj *pObject, *pParent;
2105 int iClass;
917aa2e6 2106 char *pDescription, szObjectName[MAX_OBJECT_NAME];
e6b958c4
VK
2107
2108 // Prepare responce message
2109 msg.SetCode(CMD_REQUEST_COMPLETED);
2110 msg.SetId(pRequest->GetId());
2111
2112 // Find parent object
2113 pParent = FindObjectById(pRequest->GetVariableLong(VID_PARENT_ID));
2114 if (pParent != NULL)
2115 {
2116 // User should have create access to parent object
2117 if (pParent->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_CREATE))
2118 {
2119 // Parent object should be container or service root
2120 if ((pParent->Type() == OBJECT_CONTAINER) ||
2121 (pParent->Type() == OBJECT_SERVICEROOT))
2122 {
2123 iClass = pRequest->GetVariableShort(VID_OBJECT_CLASS);
2124 pRequest->GetVariableStr(VID_OBJECT_NAME, szObjectName, MAX_OBJECT_NAME);
8f7e2482 2125 if (IsValidObjectName(szObjectName))
e6b958c4 2126 {
8f7e2482 2127 if ((iClass == OBJECT_NODE) || (iClass == OBJECT_CONTAINER))
e6b958c4 2128 {
8f7e2482
VK
2129 // Create new object
2130 switch(iClass)
2131 {
2132 case OBJECT_NODE:
2133 pObject = PollNewNode(pRequest->GetVariableLong(VID_IP_ADDRESS),
2134 pRequest->GetVariableLong(VID_IP_NETMASK),
b900a78b 2135 DF_DEFAULT, szObjectName);
8f7e2482
VK
2136 break;
2137 case OBJECT_CONTAINER:
2138 pDescription = pRequest->GetVariableStr(VID_DESCRIPTION);
2139 pObject = new Container(szObjectName,
2140 pRequest->GetVariableLong(VID_CATEGORY),
2141 pDescription);
9d72bde1 2142 safe_free(pDescription);
8f7e2482
VK
2143 NetObjInsert(pObject, TRUE);
2144 break;
2145 }
917aa2e6 2146
8f7e2482
VK
2147 // If creation was successful do binding
2148 if (pObject != NULL)
2149 {
2150 pParent->AddChild(pObject);
2151 pObject->AddParent(pParent);
2152 msg.SetVariable(VID_RCC, RCC_SUCCESS);
2153 msg.SetVariable(VID_OBJECT_ID, pObject->Id());
2154 }
2155 else
2156 {
2157 msg.SetVariable(VID_RCC, RCC_OBJECT_CREATION_FAILED);
2158 }
917aa2e6
VK
2159 }
2160 else
2161 {
8f7e2482 2162 msg.SetVariable(VID_RCC, RCC_INCOMPATIBLE_OPERATION);
917aa2e6 2163 }
e6b958c4
VK
2164 }
2165 else
2166 {
8f7e2482 2167 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_NAME);
e6b958c4
VK
2168 }
2169 }
2170 else
2171 {
2172 msg.SetVariable(VID_RCC, RCC_INCOMPATIBLE_OPERATION);
2173 }
2174 }
2175 else
2176 {
2177 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
2178 }
2179 }
2180 else
2181 {
2182 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
2183 }
2184
2185 // Send responce
2186 SendMessage(&msg);
2187}
2188
2189
2190//
2191// Bind/unbind object
2192//
2193
2194void ClientSession::ChangeObjectBinding(CSCPMessage *pRequest, BOOL bBind)
2195{
2196 CSCPMessage msg;
2197 NetObj *pParent, *pChild;
2198
2199 // Prepare responce message
2200 msg.SetCode(CMD_REQUEST_COMPLETED);
2201 msg.SetId(pRequest->GetId());
2202
2203 // Get parent and child objects
2204 pParent = FindObjectById(pRequest->GetVariableLong(VID_PARENT_ID));
2205 pChild = FindObjectById(pRequest->GetVariableLong(VID_CHILD_ID));
2206
2207 // Check access rights and change binding
2208 if ((pParent != NULL) && (pChild != NULL))
2209 {
2210 // User should have modify access to both objects
2211 if ((pParent->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_MODIFY)) &&
2212 (pChild->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_MODIFY)))
2213 {
2214 // Parent object should be container or service root
2215 if ((pParent->Type() == OBJECT_CONTAINER) ||
2216 (pParent->Type() == OBJECT_SERVICEROOT))
2217 {
2218 if (bBind)
2219 {
917aa2e6
VK
2220 // Prevent loops
2221 if (!pChild->IsChild(pParent->Id()))
2222 {
2223 pParent->AddChild(pChild);
2224 pChild->AddParent(pParent);
2225 msg.SetVariable(VID_RCC, RCC_SUCCESS);
2226 }
2227 else
2228 {
2229 msg.SetVariable(VID_RCC, RCC_OBJECT_LOOP);
2230 }
e6b958c4
VK
2231 }
2232 else
2233 {
2234 pParent->DeleteChild(pChild);
2235 pChild->DeleteParent(pParent);
917aa2e6 2236 msg.SetVariable(VID_RCC, RCC_SUCCESS);
e6b958c4 2237 }
e6b958c4
VK
2238 }
2239 else
2240 {
2241 msg.SetVariable(VID_RCC, RCC_INCOMPATIBLE_OPERATION);
2242 }
2243 }
2244 else
2245 {
2246 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
2247 }
2248 }
2249 else
2250 {
2251 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
2252 }
2253
2254 // Send responce
2255 SendMessage(&msg);
ef44d5ea 2256}
03482383
VK
2257
2258
88039e6c
VK
2259//
2260// Delete object
2261//
2262
2263void ClientSession::DeleteObject(CSCPMessage *pRequest)
2264{
2265 CSCPMessage msg;
2266 NetObj *pObject;
2267
2268 // Prepare responce message
2269 msg.SetCode(CMD_REQUEST_COMPLETED);
2270 msg.SetId(pRequest->GetId());
2271
2272 // Find object to be deleted
2273 pObject = FindObjectById(pRequest->GetVariableLong(VID_OBJECT_ID));
2274 if (pObject != NULL)
2275 {
2276 // Check if it is a built-in object, like "Entire Network"
2277 if (pObject->Id() >= 10)
2278 {
2279 // Check access rights
2280 if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_DELETE))
2281 {
2282 pObject->Delete();
2283 msg.SetVariable(VID_RCC, RCC_SUCCESS);
2284 }
2285 else
2286 {
2287 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
2288 }
2289 }
2290 else
2291 {
2292 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
2293 }
2294 }
2295 else
2296 {
2297 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
2298 }
2299
2300 // Send responce
2301 SendMessage(&msg);
2302}
2303
2304
03482383
VK
2305//
2306// Process changes in alarms
2307//
2308
2309void ClientSession::OnAlarmUpdate(DWORD dwCode, NXC_ALARM *pAlarm)
2310{
2311 UPDATE_INFO *pUpdate;
2312 NetObj *pObject;
2313
2314 if (m_iState == STATE_AUTHENTICATED)
2315 {
2316 pObject = FindObjectById(pAlarm->dwSourceObject);
2317 if (pObject != NULL)
2318 if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_READ_ALARMS))
2319 {
2320 pUpdate = (UPDATE_INFO *)malloc(sizeof(UPDATE_INFO));
2321 pUpdate->dwCategory = INFO_CAT_ALARM;
c9363772
VK
2322 pUpdate->dwCode = dwCode;
2323 pUpdate->pData = nx_memdup(pAlarm, sizeof(NXC_ALARM));
03482383
VK
2324 m_pUpdateQueue->Put(pUpdate);
2325 }
2326 }
2327}
2328
2329
2330//
2331// Send all alarms to client
2332//
2333
2334void ClientSession::SendAllAlarms(DWORD dwRqId, BOOL bIncludeAck)
2335{
2336 MutexLock(m_mutexSendAlarms, INFINITE);
2337 g_alarmMgr.SendAlarmsToClient(dwRqId, bIncludeAck, this);
2338 MutexUnlock(m_mutexSendAlarms);
2339}
ee20e615
VK
2340
2341
2342//
2343// Acknowlege alarm
2344//
2345
2346void ClientSession::AcknowlegeAlarm(CSCPMessage *pRequest)
2347{
2348 CSCPMessage msg;
2349 NetObj *pObject;
2350 DWORD dwAlarmId;
2351
2352 // Prepare responce message
2353 msg.SetCode(CMD_REQUEST_COMPLETED);
2354 msg.SetId(pRequest->GetId());
2355
2356 // Get alarm id and it's source object
2357 dwAlarmId = pRequest->GetVariableLong(VID_ALARM_ID);
2358 pObject = g_alarmMgr.GetAlarmSourceObject(dwAlarmId);
2359 if (pObject != NULL)
2360 {
2361 // User should have "acknowlege alarm" right to the object
2362 if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_ACK_ALARMS))
2363 {
2364 g_alarmMgr.AckById(dwAlarmId, m_dwUserId);
2365 msg.SetVariable(VID_RCC, RCC_SUCCESS);
2366 }
2367 else
2368 {
2369 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
2370 }
2371 }
2372 else
2373 {
2374 // Normally, for existing alarms pObject will not be NULL,
2375 // so we assume that alarm id is invalid
2376 msg.SetVariable(VID_RCC, RCC_INVALID_ALARM_ID);
2377 }
2378
2379 // Send responce
2380 SendMessage(&msg);
2381}
c9363772
VK
2382
2383
2384//
2385// Lock/unlock action configuration database
2386//
2387
2388void ClientSession::LockActionDB(DWORD dwRqId, BOOL bLock)
2389{
2390 CSCPMessage msg;
2391 char szBuffer[256];
2392
2393 // Prepare responce message
2394 msg.SetCode(CMD_REQUEST_COMPLETED);
2395 msg.SetId(dwRqId);
2396
2397 if (m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_ACTIONS)
2398 {
2399 if (bLock)
2400 {
2401 if (!LockComponent(CID_ACTION_DB, m_dwIndex, m_szUserName, NULL, szBuffer))
2402 {
2403 msg.SetVariable(VID_RCC, RCC_COMPONENT_LOCKED);
2404 msg.SetVariable(VID_LOCKED_BY, szBuffer);
2405 }
2406 else
2407 {
2408 m_dwFlags |= CSF_ACTION_DB_LOCKED;
2409 msg.SetVariable(VID_RCC, RCC_SUCCESS);
2410 }
2411 }
2412 else
2413 {
2414 if (m_dwFlags & CSF_ACTION_DB_LOCKED)
2415 {
2416 UnlockComponent(CID_ACTION_DB);
2417 m_dwFlags &= ~CSF_ACTION_DB_LOCKED;
2418 }
2419 msg.SetVariable(VID_RCC, RCC_SUCCESS);
2420 }
2421 }
2422 else
2423 {
2424 // Current user has no rights for action management
2425 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
2426 }
2427
2428 // Send responce
2429 SendMessage(&msg);
2430}
2431
2432
2433//
2434// Create new action
2435//
2436
2437void ClientSession::CreateAction(CSCPMessage *pRequest)
2438{
2439 CSCPMessage msg;
2440
2441 // Prepare responce message
2442 msg.SetCode(CMD_REQUEST_COMPLETED);
2443 msg.SetId(pRequest->GetId());
2444
2445 // Check user rights
2446 if (!(m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_ACTIONS))
2447 {
2448 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
2449 }
2450 else if (!(m_dwFlags & CSF_ACTION_DB_LOCKED))
2451 {
2452 // Action database have to be locked before any
2453 // changes can be made
2454 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
2455 }
2456 else
2457 {
2458 DWORD dwResult, dwActionId;
2459 char szActionName[MAX_USER_NAME];
2460
2461 pRequest->GetVariableStr(VID_ACTION_NAME, szActionName, MAX_OBJECT_NAME);
2462 if (IsValidObjectName(szActionName))
2463 {
2464 dwResult = CreateNewAction(szActionName, &dwActionId);
2465 msg.SetVariable(VID_RCC, dwResult);
2466 if (dwResult == RCC_SUCCESS)
2467 msg.SetVariable(VID_ACTION_ID, dwActionId); // Send id of new action to client
2468 }
2469 else
2470 {
2471 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_NAME);
2472 }
2473 }
2474
2475 // Send responce
2476 SendMessage(&msg);
2477}
2478
2479
2480//
2481// Update existing action's data
2482//
2483
2484void ClientSession::UpdateAction(CSCPMessage *pRequest)
2485{
2486 CSCPMessage msg;
2487
2488 // Prepare responce message
2489 msg.SetCode(CMD_REQUEST_COMPLETED);
2490 msg.SetId(pRequest->GetId());
2491
2492 // Check user rights
2493 if (!(m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_ACTIONS))
2494 {
2495 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
2496 }
2497 else if (!(m_dwFlags & CSF_ACTION_DB_LOCKED))
2498 {
2499 // Action database have to be locked before any
2500 // changes can be made
2501 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
2502 }
2503 else
2504 {
15b8d488 2505 msg.SetVariable(VID_RCC, ModifyActionFromMessage(pRequest));
c9363772
VK
2506 }
2507
2508 // Send responce
2509 SendMessage(&msg);
2510}
2511
2512
2513//
2514// Delete action
2515//
2516
2517void ClientSession::DeleteAction(CSCPMessage *pRequest)
2518{
2519 CSCPMessage msg;
2520 DWORD dwActionId;
2521
2522 // Prepare responce message
2523 msg.SetCode(CMD_REQUEST_COMPLETED);
2524 msg.SetId(pRequest->GetId());
2525
2526 // Check user rights
2527 if (!(m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_ACTIONS))
2528 {
2529 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
2530 }
2531 else if (!(m_dwFlags & CSF_ACTION_DB_LOCKED))
2532 {
2533 // Action database have to be locked before any
2534 // changes can be made
2535 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
2536 }
2537 else
2538 {
2539 // Get Id of action to be deleted
2540 dwActionId = pRequest->GetVariableLong(VID_ACTION_ID);
15b8d488 2541 msg.SetVariable(VID_RCC, DeleteActionFromDB(dwActionId));
c9363772
VK
2542 }
2543
2544 // Send responce
2545 SendMessage(&msg);
2546}
2547
2548
2549//
2550// Process changes in actions
2551//
2552
2553void ClientSession::OnActionDBUpdate(DWORD dwCode, NXC_ACTION *pAction)
2554{
2555 UPDATE_INFO *pUpdate;
2556
2557 if (m_iState == STATE_AUTHENTICATED)
2558 {
2559 if (m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_ACTIONS)
2560 {
2561 pUpdate = (UPDATE_INFO *)malloc(sizeof(UPDATE_INFO));
2562 pUpdate->dwCategory = INFO_CAT_ACTION;
2563 pUpdate->dwCode = dwCode;
2564 pUpdate->pData = nx_memdup(pAction, sizeof(NXC_ACTION));
2565 m_pUpdateQueue->Put(pUpdate);
2566 }
2567 }
2568}
e91cb822
VK
2569
2570
2571//
2572// Send all actions to client
2573//
2574
2575void ClientSession::SendAllActions(DWORD dwRqId)
2576{
2577 CSCPMessage msg;
2578
2579 // Prepare responce message
2580 msg.SetCode(CMD_REQUEST_COMPLETED);
2581 msg.SetId(dwRqId);
2582
2583 // Check user rights
2584 if ((m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_ACTIONS) ||
2585 (m_dwSystemAccess & SYSTEM_ACCESS_EPP))
2586 {
2587 msg.SetVariable(VID_RCC, RCC_SUCCESS);
2588 SendMessage(&msg);
2589 MutexLock(m_mutexSendActions, INFINITE);
2590 SendActionsToClient(this, dwRqId);
2591 MutexUnlock(m_mutexSendActions);
2592 }
2593 else
2594 {
2595 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
2596 SendMessage(&msg);
2597 }
2598}
6849d9be
VK
2599
2600
2601//
2602// Send list of configured container categories to client
2603//
2604
2605void ClientSession::SendContainerCategories(DWORD dwRqId)
2606{
2607 CSCPMessage msg;
2608 DWORD i;
2609
2610 // Prepare responce message
2611 msg.SetCode(CMD_CONTAINER_CAT_DATA);
2612 msg.SetId(dwRqId);
2613
2614 for(i = 0; i < g_dwNumCategories; i++)
2615 {
2616 msg.SetVariable(VID_CATEGORY_ID, g_pContainerCatList[i].dwCatId);
2617 msg.SetVariable(VID_CATEGORY_NAME, g_pContainerCatList[i].szName);
2618 msg.SetVariable(VID_IMAGE_ID, g_pContainerCatList[i].dwImageId);
2619 msg.SetVariable(VID_DESCRIPTION, g_pContainerCatList[i].pszDescription);
2620 SendMessage(&msg);
2621 msg.DeleteAllVariables();
2622 }
2623
2624 // Send end-of-list indicator
2625 msg.SetVariable(VID_CATEGORY_ID, (DWORD)0);
2626 SendMessage(&msg);
2627}
0b89f5fb
VK
2628
2629
2630//
2631// Perform a forced node poll
2632//
2633
2634void ClientSession::ForcedNodePoll(CSCPMessage *pRequest)
2635{
eb8b1960 2636 CSCPMessage msg;
d966d18a 2637 POLLER_START_DATA *pData;
eb8b1960 2638 NetObj *pObject;
d966d18a
VK
2639
2640 pData = (POLLER_START_DATA *)malloc(sizeof(POLLER_START_DATA));
0ba90743 2641 pData->pSession = this;
d966d18a 2642 MutexLock(m_mutexPollerInit, INFINITE);
eb8b1960
VK
2643
2644 // Prepare responce message
d966d18a 2645 pData->dwRqId = pRequest->GetId();
eb8b1960 2646 msg.SetCode(CMD_POLLING_INFO);
d966d18a 2647 msg.SetId(pData->dwRqId);
eb8b1960
VK
2648
2649 // Get polling type
d966d18a 2650 pData->iPollType = pRequest->GetVariableShort(VID_POLL_TYPE);
eb8b1960
VK
2651
2652 // Find object to be deleted
2653 pObject = FindObjectById(pRequest->GetVariableLong(VID_OBJECT_ID));
2654 if (pObject != NULL)
2655 {
2656 // We can do polls only for node objects
2657 if ((pObject->Type() == OBJECT_NODE) &&
d966d18a 2658 ((pData->iPollType == POLL_STATUS) || (pData->iPollType == POLL_CONFIGURATION)))
eb8b1960
VK
2659 {
2660 // Check access rights
2661 if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_MODIFY))
2662 {
2663 ((Node *)pObject)->IncRefCount();
2664
d966d18a
VK
2665 pData->pNode = (Node *)pObject;
2666 ThreadCreate(PollerThreadStarter, 0, pData);
2667 msg.SetVariable(VID_RCC, RCC_OPERATION_IN_PROGRESS);
2668 msg.SetVariable(VID_POLLER_MESSAGE, _T("Poll request accepted\r\n"));
eb8b1960
VK
2669 }
2670 else
2671 {
2672 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
2673 }
2674 }
2675 else
2676 {
2677 msg.SetVariable(VID_RCC, RCC_INCOMPATIBLE_OPERATION);
2678 }
2679 }
2680 else
2681 {
2682 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
2683 }
2684
2685 // Send responce
2686 SendMessage(&msg);
d966d18a 2687 MutexUnlock(m_mutexPollerInit);
eb8b1960
VK
2688}
2689
2690
2691//
2692// Send message fro poller to client
2693//
2694
d966d18a 2695void ClientSession::SendPollerMsg(DWORD dwRqId, TCHAR *pszMsg)
eb8b1960
VK
2696{
2697 CSCPMessage msg;
2698
2699 msg.SetCode(CMD_POLLING_INFO);
d966d18a 2700 msg.SetId(dwRqId);
eb8b1960
VK
2701 msg.SetVariable(VID_RCC, RCC_OPERATION_IN_PROGRESS);
2702 msg.SetVariable(VID_POLLER_MESSAGE, pszMsg);
2703 SendMessage(&msg);
0b89f5fb 2704}
d966d18a
VK
2705
2706
2707//
2708// Node poller thread
2709//
2710
2711void ClientSession::PollerThread(Node *pNode, int iPollType, DWORD dwRqId)
2712{
2713 CSCPMessage msg;
2714
2715 // Wait while parent thread finishes initialization
2716 MutexLock(m_mutexPollerInit, INFINITE);
2717 MutexUnlock(m_mutexPollerInit);
2718
0ba90743
VK
2719 switch(iPollType)
2720 {
2721 case POLL_STATUS:
2722 pNode->StatusPoll(this, dwRqId);
2723 break;
2724 case POLL_CONFIGURATION:
2725 pNode->ConfigurationPoll(this, dwRqId);
2726 break;
2727 default:
2728 SendPollerMsg(dwRqId, _T("Invalid poll type requested\r\n"));
2729 break;
2730 }
d966d18a
VK
2731 pNode->DecRefCount();
2732
2733 msg.SetCode(CMD_POLLING_INFO);
2734 msg.SetId(dwRqId);
2735 msg.SetVariable(VID_RCC, RCC_SUCCESS);
2736 SendMessage(&msg);
2737}