Fixed incorrect data type constants usage; confusing DT_xxx and DTYPE_xxx constants...
[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
VK
31
32//
2d5c8ac8
VK
33// Fill CSCP message with user data
34//
35
36static void FillUserInfoMessage(CSCPMessage *pMsg, NMS_USER *pUser)
37{
38 pMsg->SetVariable(VID_USER_ID, pUser->dwId);
39 pMsg->SetVariable(VID_USER_NAME, pUser->szName);
40 pMsg->SetVariable(VID_USER_FLAGS, pUser->wFlags);
41 pMsg->SetVariable(VID_USER_SYS_RIGHTS, pUser->wSystemRights);
42 pMsg->SetVariable(VID_USER_FULL_NAME, pUser->szFullName);
43 pMsg->SetVariable(VID_USER_DESCRIPTION, pUser->szDescription);
44}
45
46
47//
48// Fill CSCP message with user group data
49//
50
51static void FillGroupInfoMessage(CSCPMessage *pMsg, NMS_USER_GROUP *pGroup)
52{
53 DWORD i, dwId;
54
55 pMsg->SetVariable(VID_USER_ID, pGroup->dwId);
56 pMsg->SetVariable(VID_USER_NAME, pGroup->szName);
57 pMsg->SetVariable(VID_USER_FLAGS, pGroup->wFlags);
58 pMsg->SetVariable(VID_USER_SYS_RIGHTS, pGroup->wSystemRights);
59 pMsg->SetVariable(VID_USER_DESCRIPTION, pGroup->szDescription);
60 pMsg->SetVariable(VID_NUM_MEMBERS, pGroup->dwNumMembers);
61 for(i = 0, dwId = VID_GROUP_MEMBER_BASE; i < pGroup->dwNumMembers; i++, dwId++)
62 pMsg->SetVariable(dwId, pGroup->pMembers[i]);
63}
64
65
66//
21e4b6f0
VK
67// Client session class constructor
68//
69
b54b2b11 70ClientSession::ClientSession(SOCKET hSocket, DWORD dwHostAddr)
21e4b6f0
VK
71{
72 m_pSendQueue = new Queue;
73 m_pMessageQueue = new Queue;
62f5857f 74 m_pUpdateQueue = new Queue;
21e4b6f0
VK
75 m_hSocket = hSocket;
76 m_dwIndex = INVALID_INDEX;
77 m_iState = STATE_CONNECTED;
78 m_pMsgBuffer = (CSCP_BUFFER *)malloc(sizeof(CSCP_BUFFER));
8f7e2482
VK
79 m_mutexWriteThreadRunning = MutexCreate();
80 m_mutexProcessingThreadRunning = MutexCreate();
81 m_mutexUpdateThreadRunning = MutexCreate();
03482383
VK
82 m_mutexSendEvents = MutexCreate();
83 m_mutexSendObjects = MutexCreate();
84 m_mutexSendAlarms = MutexCreate();
b54b2b11
VK
85 m_dwFlags = 0;
86 m_dwHostAddr = dwHostAddr;
87 strcpy(m_szUserName, "<not logged in>");
984542f8 88 m_dwUserId = INVALID_INDEX;
338493a0
VK
89 m_dwOpenDCIListSize = 0;
90 m_pOpenDCIList = NULL;
8f7e2482 91 m_ppEPPRuleList = NULL;
21e4b6f0
VK
92}
93
94
95//
96// Destructor
97//
98
99ClientSession::~ClientSession()
100{
101 shutdown(m_hSocket, 2);
102 closesocket(m_hSocket);
103 delete m_pSendQueue;
104 delete m_pMessageQueue;
62f5857f 105 delete m_pUpdateQueue;
338493a0 106 safe_free(m_pMsgBuffer);
8f7e2482
VK
107 MutexDestroy(m_mutexWriteThreadRunning);
108 MutexDestroy(m_mutexProcessingThreadRunning);
109 MutexDestroy(m_mutexUpdateThreadRunning);
03482383
VK
110 MutexDestroy(m_mutexSendEvents);
111 MutexDestroy(m_mutexSendObjects);
112 MutexDestroy(m_mutexSendAlarms);
338493a0 113 safe_free(m_pOpenDCIList);
8f7e2482
VK
114 if (m_ppEPPRuleList != NULL)
115 {
116 DWORD i;
117
118 if (m_dwFlags & CSF_EPP_UPLOAD) // Aborted in the middle of EPP transfer
119 for(i = 0; i < m_dwRecordsUploaded; i++)
120 delete m_ppEPPRuleList[i];
121 free(m_ppEPPRuleList);
122 }
21e4b6f0
VK
123}
124
125
126//
127// Print debug information
128//
129
130void ClientSession::DebugPrintf(char *szFormat, ...)
131{
132 if ((g_dwFlags & AF_STANDALONE) && (g_dwFlags & AF_DEBUG_CSCP))
133 {
134 va_list args;
135
136 printf("*CSCP(%d)* ", m_dwIndex);
137 va_start(args, szFormat);
138 vprintf(szFormat, args);
139 va_end(args);
140 }
141}
142
143
144//
21e4b6f0
VK
145// ReadThread()
146//
147
148void ClientSession::ReadThread(void)
149{
150 CSCP_MESSAGE *pRawMsg;
151 CSCPMessage *pMsg;
152 int iErr;
338493a0
VK
153 DWORD i;
154 NetObj *pObject;
21e4b6f0
VK
155
156 // Initialize raw message receiving function
a933a2bf 157 RecvCSCPMessage(0, NULL, m_pMsgBuffer, 0);
21e4b6f0
VK
158
159 pRawMsg = (CSCP_MESSAGE *)malloc(65536);
160 while(1)
161 {
a933a2bf 162 if ((iErr = RecvCSCPMessage(m_hSocket, pRawMsg, m_pMsgBuffer, 65536)) <= 0)
21e4b6f0
VK
163 break;
164
a933a2bf
VK
165 // Check if message is too large
166 if (iErr == 1)
167 continue;
168
21e4b6f0 169 // Check that actual received packet size is equal to encoded in packet
6159a875 170 if ((int)ntohl(pRawMsg->dwSize) != iErr)
21e4b6f0 171 {
6159a875 172 DebugPrintf("Actual message size doesn't match wSize value (%d,%d)\n", iErr, ntohl(pRawMsg->dwSize));
21e4b6f0
VK
173 continue; // Bad packet, wait for next
174 }
175
176 // Create message object from raw message
177 pMsg = new CSCPMessage(pRawMsg);
178 m_pMessageQueue->Put(pMsg);
179 }
180 if (iErr < 0)
181 WriteLog(MSG_SESSION_CLOSED, EVENTLOG_WARNING_TYPE, "e", WSAGetLastError());
182 free(pRawMsg);
183
184 // Notify other threads to exit
ecb7e1ee
VK
185 m_pSendQueue->Put(INVALID_POINTER_VALUE);
186 m_pMessageQueue->Put(INVALID_POINTER_VALUE);
8f7e2482 187 m_pUpdateQueue->Put(INVALID_POINTER_VALUE);
ecb7e1ee
VK
188
189 // Wait for other threads to finish
8f7e2482
VK
190 MutexLock(m_mutexWriteThreadRunning, INFINITE);
191 MutexUnlock(m_mutexWriteThreadRunning);
192
193 MutexLock(m_mutexProcessingThreadRunning, INFINITE);
194 MutexUnlock(m_mutexProcessingThreadRunning);
195
196 MutexLock(m_mutexUpdateThreadRunning, INFINITE);
197 MutexUnlock(m_mutexUpdateThreadRunning);
54abbe0e
VK
198
199 // Remove all locks created by this session
200 RemoveAllSessionLocks(m_dwIndex);
338493a0
VK
201 for(i = 0; i < m_dwOpenDCIListSize; i++)
202 {
203 pObject = FindObjectById(m_pOpenDCIList[i]);
204 if (pObject != NULL)
205 if (pObject->Type() == OBJECT_NODE)
206 ((Node *)pObject)->UnlockDCIList(m_dwIndex);
207 }
8f7e2482
VK
208
209 DebugPrintf("Session closed\n");
21e4b6f0
VK
210}
211
212
213//
214// WriteThread()
215//
216
217void ClientSession::WriteThread(void)
218{
219 CSCP_MESSAGE *pMsg;
7ac0c0a8 220 char szBuffer[128];
21e4b6f0 221
8f7e2482 222 MutexLock(m_mutexWriteThreadRunning, INFINITE);
21e4b6f0
VK
223 while(1)
224 {
225 pMsg = (CSCP_MESSAGE *)m_pSendQueue->GetOrBlock();
ecb7e1ee 226 if (pMsg == INVALID_POINTER_VALUE) // Session termination indicator
21e4b6f0
VK
227 break;
228
6159a875
VK
229 DebugPrintf("Sending message %s\n", CSCPMessageCodeName(ntohs(pMsg->wCode), szBuffer));
230 if (send(m_hSocket, (const char *)pMsg, ntohl(pMsg->dwSize), 0) <= 0)
21e4b6f0 231 {
9d72bde1 232 safe_free(pMsg);
21e4b6f0
VK
233 break;
234 }
9d72bde1 235 safe_free(pMsg);
21e4b6f0 236 }
8f7e2482
VK
237 MutexUnlock(m_mutexWriteThreadRunning);
238}
239
240
241//
242// Update processing thread
243//
244
245void ClientSession::UpdateThread(void)
246{
247 UPDATE_INFO *pUpdate;
248 CSCPMessage msg;
249
250 MutexLock(m_mutexUpdateThreadRunning, INFINITE);
251 while(1)
252 {
253 pUpdate = (UPDATE_INFO *)m_pUpdateQueue->GetOrBlock();
254 if (pUpdate == INVALID_POINTER_VALUE) // Session termination indicator
255 break;
256
257 switch(pUpdate->dwCategory)
258 {
259 case INFO_CAT_EVENT:
03482383 260 MutexLock(m_mutexSendEvents, INFINITE);
8f7e2482 261 m_pSendQueue->Put(CreateRawCSCPMessage(CMD_EVENT, 0, sizeof(NXC_EVENT), pUpdate->pData, NULL));
03482383 262 MutexUnlock(m_mutexSendEvents);
8f7e2482
VK
263 free(pUpdate->pData);
264 break;
265 case INFO_CAT_OBJECT_CHANGE:
03482383 266 MutexLock(m_mutexSendObjects, INFINITE);
8f7e2482 267 msg.SetCode(CMD_OBJECT_UPDATE);
03482383 268 msg.SetId(0);
8f7e2482
VK
269 ((NetObj *)pUpdate->pData)->CreateMessage(&msg);
270 SendMessage(&msg);
03482383 271 MutexUnlock(m_mutexSendObjects);
8f7e2482
VK
272 msg.DeleteAllVariables();
273 ((NetObj *)pUpdate->pData)->DecRefCount();
274 break;
03482383
VK
275 case INFO_CAT_ALARM:
276 MutexLock(m_mutexSendAlarms, INFINITE);
277 msg.SetCode(CMD_ALARM_UPDATE);
278 msg.SetId(0);
279 msg.SetVariable(VID_NOTIFICATION_CODE, ((ALARM_UPDATE *)pUpdate->pData)->dwCode);
280 msg.SetVariable(VID_ALARM_ID, ((ALARM_UPDATE *)pUpdate->pData)->alarm.dwAlarmId);
eb484131 281 if (((ALARM_UPDATE *)pUpdate->pData)->dwCode == NX_NOTIFY_NEW_ALARM)
03482383 282 FillAlarmInfoMessage(&msg, &((ALARM_UPDATE *)pUpdate->pData)->alarm);
49dde062 283 SendMessage(&msg);
03482383
VK
284 MutexUnlock(m_mutexSendAlarms);
285 msg.DeleteAllVariables();
286 break;
8f7e2482
VK
287 default:
288 break;
289 }
290
291 free(pUpdate);
292 }
293 MutexUnlock(m_mutexUpdateThreadRunning);
21e4b6f0
VK
294}
295
296
297//
298// Message processing thread
299//
300
301void ClientSession::ProcessingThread(void)
302{
3421c063 303 CSCPMessage *pMsg;
74a5aa17 304 char szBuffer[128];
21e4b6f0 305
8f7e2482 306 MutexLock(m_mutexProcessingThreadRunning, INFINITE);
21e4b6f0
VK
307 while(1)
308 {
309 pMsg = (CSCPMessage *)m_pMessageQueue->GetOrBlock();
ecb7e1ee 310 if (pMsg == INVALID_POINTER_VALUE) // Session termination indicator
21e4b6f0
VK
311 break;
312
74a5aa17 313 DebugPrintf("Received message %s\n", CSCPMessageCodeName(pMsg->GetCode(), szBuffer));
21e4b6f0
VK
314 if ((m_iState != STATE_AUTHENTICATED) && (pMsg->GetCode() != CMD_LOGIN))
315 {
316 delete pMsg;
317 continue;
318 }
319
320 switch(pMsg->GetCode())
321 {
322 case CMD_LOGIN:
e100f091 323 Login(pMsg);
21e4b6f0
VK
324 break;
325 case CMD_GET_OBJECTS:
e100f091 326 SendAllObjects(pMsg->GetId());
21e4b6f0
VK
327 break;
328 case CMD_GET_EVENTS:
74a5aa17 329 SendAllEvents(pMsg->GetId());
21e4b6f0
VK
330 break;
331 case CMD_GET_CONFIG_VARLIST:
332 SendAllConfigVars();
333 break;
b54b2b11
VK
334 case CMD_OPEN_EVENT_DB:
335 SendEventDB(pMsg->GetId());
336 break;
337 case CMD_CLOSE_EVENT_DB:
3421c063 338 CloseEventDB(pMsg->GetId());
b54b2b11 339 break;
605d2931
VK
340 case CMD_SET_EVENT_INFO:
341 SetEventInfo(pMsg);
342 break;
24156e90
VK
343 case CMD_MODIFY_OBJECT:
344 ModifyObject(pMsg);
345 break;
c1c39152
VK
346 case CMD_SET_OBJECT_MGMT_STATUS:
347 ChangeObjectMgmtStatus(pMsg);
348 break;
23a32988
VK
349 case CMD_LOAD_USER_DB:
350 SendUserDB(pMsg->GetId());
351 break;
ff550544
VK
352 case CMD_CREATE_USER:
353 CreateUser(pMsg);
354 break;
355 case CMD_UPDATE_USER:
356 UpdateUser(pMsg);
357 break;
358 case CMD_DELETE_USER:
359 DeleteUser(pMsg);
360 break;
361 case CMD_LOCK_USER_DB:
362 LockUserDB(pMsg->GetId(), TRUE);
363 break;
364 case CMD_UNLOCK_USER_DB:
365 LockUserDB(pMsg->GetId(), FALSE);
366 break;
017e1e13
VK
367 case CMD_SET_PASSWORD:
368 SetPassword(pMsg);
369 break;
7257eb7d
VK
370 case CMD_GET_NODE_DCI_LIST:
371 OpenNodeDCIList(pMsg);
372 break;
373 case CMD_UNLOCK_NODE_DCI_LIST:
374 CloseNodeDCIList(pMsg);
375 break;
9ed4eaff
VK
376 case CMD_CREATE_NEW_DCI:
377 case CMD_MODIFY_NODE_DCI:
378 case CMD_DELETE_NODE_DCI:
379 ModifyNodeDCI(pMsg);
380 break;
ebebc8ea
VK
381 case CMD_GET_DCI_DATA:
382 GetCollectedData(pMsg);
383 break;
06e7be2f
VK
384 case CMD_OPEN_EPP:
385 OpenEPP(pMsg->GetId());
386 break;
387 case CMD_CLOSE_EPP:
388 CloseEPP(pMsg->GetId());
389 break;
390 case CMD_SAVE_EPP:
391 SaveEPP(pMsg);
392 break;
8f7e2482
VK
393 case CMD_EPP_RECORD:
394 ProcessEPPRecord(pMsg);
06e7be2f
VK
395 break;
396 case CMD_GET_MIB_LIST:
397 SendMIBList(pMsg->GetId());
398 break;
399 case CMD_GET_MIB:
400 SendMIB(pMsg);
401 break;
ef44d5ea
VK
402 case CMD_CREATE_OBJECT:
403 CreateObject(pMsg);
404 break;
e6b958c4
VK
405 case CMD_BIND_OBJECT:
406 ChangeObjectBinding(pMsg, TRUE);
407 break;
408 case CMD_UNBIND_OBJECT:
409 ChangeObjectBinding(pMsg, FALSE);
410 break;
3421c063
VK
411 case CMD_GET_EVENT_NAMES:
412 SendEventNames(pMsg->GetId());
413 break;
f70fc197 414 case CMD_GET_IMAGE_LIST:
aa3743b2 415 SendImageCatalogue(this, pMsg->GetId(), pMsg->GetVariableShort(VID_IMAGE_FORMAT));
f70fc197
VK
416 break;
417 case CMD_LOAD_IMAGE_FILE:
aa3743b2
VK
418 SendImageFile(this, pMsg->GetId(), pMsg->GetVariableLong(VID_IMAGE_ID),
419 pMsg->GetVariableShort(VID_IMAGE_FORMAT));
8bff53f6
VK
420 break;
421 case CMD_GET_DEFAULT_IMAGE_LIST:
422 SendDefaultImageList(this, pMsg->GetId());
f70fc197 423 break;
03482383
VK
424 case CMD_GET_ALL_ALARMS:
425 SendAllAlarms(pMsg->GetId(), pMsg->GetVariableShort(VID_IS_ACK));
426 break;
427 case CMD_GET_ALARM:
428 break;
429 case CMD_ACK_ALARM:
ee20e615
VK
430 AcknowlegeAlarm(pMsg);
431 break;
432 case CMD_DELETE_ALARM:
03482383 433 break;
21e4b6f0
VK
434 default:
435 break;
436 }
437 delete pMsg;
438 }
8f7e2482 439 MutexUnlock(m_mutexProcessingThreadRunning);
21e4b6f0
VK
440}
441
442
443//
e100f091
VK
444// Authenticate client
445//
446
447void ClientSession::Login(CSCPMessage *pRequest)
448{
449 CSCPMessage msg;
6528a4d7 450 BYTE szPassword[SHA1_DIGEST_SIZE];
e100f091
VK
451 char szLogin[MAX_USER_NAME], szBuffer[32];
452
453 // Prepare responce message
454 msg.SetCode(CMD_LOGIN_RESP);
455 msg.SetId(pRequest->GetId());
456
457 if (m_iState != STATE_AUTHENTICATED)
458 {
459
460 pRequest->GetVariableStr(VID_LOGIN_NAME, szLogin, MAX_USER_NAME);
6528a4d7 461 pRequest->GetVariableBinary(VID_PASSWORD, szPassword, SHA1_DIGEST_SIZE);
e100f091
VK
462
463 if (AuthenticateUser(szLogin, szPassword, &m_dwUserId, &m_dwSystemAccess))
464 {
465 m_iState = STATE_AUTHENTICATED;
466 sprintf(m_szUserName, "%s@%s", szLogin, IpToStr(m_dwHostAddr, szBuffer));
467 msg.SetVariable(VID_RCC, RCC_SUCCESS);
468 DebugPrintf("User %s authenticated\n", m_szUserName);
469 }
470 else
471 {
472 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
473 }
474 }
475 else
476 {
477 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
478 }
479
480 // Send responce
481 SendMessage(&msg);
482}
483
484
485//
b54b2b11
VK
486// Send event configuration to client
487//
488
489void ClientSession::SendEventDB(DWORD dwRqId)
490{
491 DB_ASYNC_RESULT hResult;
492 CSCPMessage msg;
493 char szBuffer[1024];
494
495 // Prepare responce message
3a5042fd 496 msg.SetCode(CMD_REQUEST_COMPLETED);
b54b2b11
VK
497 msg.SetId(dwRqId);
498
b8bad201
VK
499 if (!CheckSysAccessRights(SYSTEM_ACCESS_VIEW_EVENT_DB))
500 {
501 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
502 SendMessage(&msg);
503 }
504 else if (!LockComponent(CID_EVENT_DB, m_dwIndex, m_szUserName, NULL, szBuffer))
b54b2b11
VK
505 {
506 msg.SetVariable(VID_RCC, RCC_COMPONENT_LOCKED);
507 msg.SetVariable(VID_LOCKED_BY, szBuffer);
508 SendMessage(&msg);
509 }
510 else
511 {
512 m_dwFlags |= CSF_EVENT_DB_LOCKED;
b8bad201 513 m_dwFlags &= ~CSF_EVENT_DB_MODIFIED;
b54b2b11
VK
514
515 msg.SetVariable(VID_RCC, RCC_SUCCESS);
516 SendMessage(&msg);
517 msg.DeleteAllVariables();
518
519 // Prepare data message
520 msg.SetCode(CMD_EVENT_DB_RECORD);
521 msg.SetId(dwRqId);
522
eafa21c7 523 hResult = DBAsyncSelect(g_hCoreDB, "SELECT event_id,name,severity,flags,message,description FROM events");
ebebc8ea 524 if (hResult != NULL)
b54b2b11 525 {
ebebc8ea
VK
526 while(DBFetch(hResult))
527 {
528 msg.SetVariable(VID_EVENT_ID, DBGetFieldAsyncULong(hResult, 0));
529 msg.SetVariable(VID_NAME, DBGetFieldAsync(hResult, 1, szBuffer, 1024));
530 msg.SetVariable(VID_SEVERITY, DBGetFieldAsyncULong(hResult, 2));
531 msg.SetVariable(VID_FLAGS, DBGetFieldAsyncULong(hResult, 3));
8f7e2482
VK
532
533 DBGetFieldAsync(hResult, 4, szBuffer, 1024);
534 DecodeSQLString(szBuffer);
535 msg.SetVariable(VID_MESSAGE, szBuffer);
536
537 DBGetFieldAsync(hResult, 5, szBuffer, 1024);
538 DecodeSQLString(szBuffer);
539 msg.SetVariable(VID_DESCRIPTION, szBuffer);
540
ebebc8ea
VK
541 SendMessage(&msg);
542 msg.DeleteAllVariables();
543 }
544 DBFreeAsyncResult(hResult);
b54b2b11 545 }
3a5042fd
VK
546
547 // Send end-of-list indicator
548 msg.SetCode(CMD_EVENT_DB_EOF);
549 SendMessage(&msg);
b54b2b11
VK
550 }
551}
552
553
554//
3421c063
VK
555// Close event configuration database
556//
557
558void ClientSession::CloseEventDB(DWORD dwRqId)
559{
560 CSCPMessage msg;
561
562 msg.SetCode(CMD_REQUEST_COMPLETED);
563 msg.SetId(dwRqId);
564
565 if (m_dwFlags & CSF_EVENT_DB_LOCKED)
566 {
567 // Check if event configuration DB has been modified
568 if (m_dwFlags & CSF_EVENT_DB_MODIFIED)
569 {
570 ReloadEvents();
571
572 // Notify clients on event database change
573 EnumerateClientSessions(NotifyClient, (void *)NX_NOTIFY_EVENTDB_CHANGED);
574 }
575 UnlockComponent(CID_EVENT_DB);
576 m_dwFlags &= ~CSF_EVENT_DB_LOCKED;
577 msg.SetVariable(VID_RCC, RCC_SUCCESS);
578 }
579 else
580 {
581 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
582 }
583 SendMessage(&msg);
584}
585
586
587//
21e4b6f0
VK
588// Send all objects to client
589//
590
e100f091 591void ClientSession::SendAllObjects(DWORD dwRqId)
21e4b6f0
VK
592{
593 DWORD i;
594 CSCPMessage msg;
595
e100f091
VK
596 // Send confirmation message
597 msg.SetCode(CMD_REQUEST_COMPLETED);
598 msg.SetId(dwRqId);
599 msg.SetVariable(VID_RCC, RCC_SUCCESS);
600 SendMessage(&msg);
601 msg.DeleteAllVariables();
602
03482383 603 MutexLock(m_mutexSendObjects, INFINITE);
53512272 604
21e4b6f0
VK
605 // Prepare message
606 msg.SetCode(CMD_OBJECT);
607
608 // Send objects, one per message
609 ObjectsGlobalLock();
610 for(i = 0; i < g_dwIdIndexSize; i++)
24156e90
VK
611 if (g_pIndexById[i].pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
612 {
613 g_pIndexById[i].pObject->CreateMessage(&msg);
614 SendMessage(&msg);
615 msg.DeleteAllVariables();
616 }
21e4b6f0
VK
617 ObjectsGlobalUnlock();
618
619 // Send end of list notification
620 msg.SetCode(CMD_OBJECT_LIST_END);
621 SendMessage(&msg);
53512272 622
03482383 623 MutexUnlock(m_mutexSendObjects);
21e4b6f0
VK
624}
625
626
627//
628// Send all events to client
629//
630
74a5aa17 631void ClientSession::SendAllEvents(DWORD dwRqId)
21e4b6f0 632{
21e4b6f0 633 CSCPMessage msg;
20177e8e 634 DB_ASYNC_RESULT hResult;
9c36ef66 635 NXC_EVENT event;
21e4b6f0 636
74a5aa17
VK
637 // Send confirmation message
638 msg.SetCode(CMD_REQUEST_COMPLETED);
639 msg.SetId(dwRqId);
640 msg.SetVariable(VID_RCC, RCC_SUCCESS);
641 SendMessage(&msg);
642 msg.DeleteAllVariables();
643
03482383 644 MutexLock(m_mutexSendEvents, INFINITE);
62f5857f 645
21e4b6f0 646 // Retrieve events from database
fa1d3757 647 hResult = DBAsyncSelect(g_hCoreDB, "SELECT event_id,timestamp,source,severity,message FROM event_log ORDER BY timestamp");
21e4b6f0
VK
648 if (hResult != NULL)
649 {
650 // Send events, one per message
20177e8e 651 while(DBFetch(hResult))
21e4b6f0 652 {
20177e8e
VK
653 event.dwEventId = htonl(DBGetFieldAsyncULong(hResult, 0));
654 event.dwTimeStamp = htonl(DBGetFieldAsyncULong(hResult, 1));
655 event.dwSourceId = htonl(DBGetFieldAsyncULong(hResult, 2));
656 event.dwSeverity = htonl(DBGetFieldAsyncULong(hResult, 3));
657 DBGetFieldAsync(hResult, 4, event.szMessage, MAX_EVENT_MSG_LENGTH);
8f7e2482 658 DecodeSQLString(event.szMessage);
74a5aa17 659 m_pSendQueue->Put(CreateRawCSCPMessage(CMD_EVENT, dwRqId, sizeof(NXC_EVENT), &event, NULL));
9c36ef66 660 }
20177e8e 661 DBFreeAsyncResult(hResult);
21e4b6f0
VK
662 }
663
664 // Send end of list notification
665 msg.SetCode(CMD_EVENT_LIST_END);
666 SendMessage(&msg);
62f5857f 667
03482383 668 MutexUnlock(m_mutexSendEvents);
21e4b6f0
VK
669}
670
671
672//
673// Send all configuration variables to client
674//
675
676void ClientSession::SendAllConfigVars(void)
677{
678 DWORD i, dwNumRecords;
679 CSCPMessage msg;
680 DB_RESULT hResult;
681
682 // Check user rights
683 if ((m_dwUserId != 0) && ((m_dwSystemAccess & SYSTEM_ACCESS_VIEW_CONFIG) == 0))
684 {
685 // Access denied
686 msg.SetCode(CMD_CONFIG_VARLIST_END);
a5f8dbb8 687 msg.SetVariable(VID_ERROR, (DWORD)1);
21e4b6f0
VK
688 SendMessage(&msg);
689 }
690 else
691 {
692 // Prepare message
693 msg.SetCode(CMD_CONFIG_VARIABLE);
694
695 // Retrieve configuration variables from database
696 hResult = DBSelect(g_hCoreDB, "SELECT name,value FROM config");
697 if (hResult != NULL)
698 {
699 // Send events, one per message
700 dwNumRecords = DBGetNumRows(hResult);
701 for(i = 0; i < dwNumRecords; i++)
702 {
a5f8dbb8
VK
703 msg.SetVariable(VID_NAME, DBGetField(hResult, i, 0));
704 msg.SetVariable(VID_VALUE, DBGetField(hResult, i, 1));
21e4b6f0
VK
705 SendMessage(&msg);
706 msg.DeleteAllVariables();
707 }
20177e8e 708 DBFreeResult(hResult);
21e4b6f0
VK
709 }
710
711 // Send end of list notification
712 msg.SetCode(CMD_CONFIG_VARLIST_END);
a5f8dbb8 713 msg.SetVariable(VID_ERROR, (DWORD)0);
21e4b6f0
VK
714 SendMessage(&msg);
715 }
716}
20177e8e
VK
717
718
719//
720// Close session forcibly
721//
722
723void ClientSession::Kill(void)
724{
725 // We shutdown socket connection, which will cause
726 // read thread to stop, and other threads will follow
727 shutdown(m_hSocket, 2);
728}
62f5857f
VK
729
730
731//
732// Handler for new events
733//
734
735void ClientSession::OnNewEvent(Event *pEvent)
736{
737 UPDATE_INFO *pUpdate;
738
984542f8
VK
739 if (m_iState == STATE_AUTHENTICATED)
740 {
741 pUpdate = (UPDATE_INFO *)malloc(sizeof(UPDATE_INFO));
742 pUpdate->dwCategory = INFO_CAT_EVENT;
743 pUpdate->pData = malloc(sizeof(NXC_EVENT));
744 pEvent->PrepareMessage((NXC_EVENT *)pUpdate->pData);
745 m_pUpdateQueue->Put(pUpdate);
746 }
62f5857f
VK
747}
748
749
750//
751// Handler for object changes
752//
753
53512272 754void ClientSession::OnObjectChange(NetObj *pObject)
62f5857f 755{
53512272
VK
756 UPDATE_INFO *pUpdate;
757
984542f8
VK
758 if (m_iState == STATE_AUTHENTICATED)
759 if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
760 {
761 pUpdate = (UPDATE_INFO *)malloc(sizeof(UPDATE_INFO));
762 pUpdate->dwCategory = INFO_CAT_OBJECT_CHANGE;
763 pUpdate->pData = pObject;
764 m_pUpdateQueue->Put(pUpdate);
765 pObject->IncRefCount();
766 }
62f5857f
VK
767}
768
769
770//
83f0529c
VK
771// Send notification message to server
772//
773
4de204a3 774void ClientSession::Notify(DWORD dwCode, DWORD dwData)
83f0529c
VK
775{
776 CSCPMessage msg;
777
778 msg.SetCode(CMD_NOTIFY);
779 msg.SetVariable(VID_NOTIFICATION_CODE, dwCode);
4de204a3 780 msg.SetVariable(VID_NOTIFICATION_DATA, dwData);
83f0529c
VK
781 SendMessage(&msg);
782}
605d2931
VK
783
784
785//
786// Update event template
787//
788
789void ClientSession::SetEventInfo(CSCPMessage *pRequest)
790{
791 CSCPMessage msg;
792
793 // Prepare reply message
794 msg.SetCode(CMD_REQUEST_COMPLETED);
795 msg.SetId(pRequest->GetId());
796
797 // Check if we have event configuration database opened
798 if (!(m_dwFlags & CSF_EVENT_DB_LOCKED))
799 {
800 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
801 }
802 else
803 {
804 // Check access rights
805 if (CheckSysAccessRights(SYSTEM_ACCESS_EDIT_EVENT_DB))
806 {
8f7e2482 807 char szQuery[4096], szName[MAX_EVENT_NAME];
605d2931
VK
808 DWORD dwEventId;
809 BOOL bEventExist = FALSE;
810 DB_RESULT hResult;
811
812 // Check if event with specific id exists
813 dwEventId = pRequest->GetVariableLong(VID_EVENT_ID);
814 sprintf(szQuery, "SELECT event_id FROM events WHERE event_id=%ld", dwEventId);
815 hResult = DBSelect(g_hCoreDB, szQuery);
816 if (hResult != NULL)
817 {
818 if (DBGetNumRows(hResult) > 0)
819 bEventExist = TRUE;
820 DBFreeResult(hResult);
821 }
822
b8bad201 823 // Prepare and execute SQL query
8f7e2482
VK
824 pRequest->GetVariableStr(VID_NAME, szName, MAX_EVENT_NAME);
825 if (IsValidObjectName(szName))
b8bad201 826 {
8f7e2482
VK
827 char szMessage[MAX_DB_STRING], *pszDescription, *pszEscMsg, *pszEscDescr;
828
829 pRequest->GetVariableStr(VID_MESSAGE, szMessage, MAX_DB_STRING);
830 pszEscMsg = EncodeSQLString(szMessage);
831
832 pszDescription = pRequest->GetVariableStr(VID_DESCRIPTION);
833 pszEscDescr = EncodeSQLString(pszDescription);
9d72bde1 834 safe_free(pszDescription);
8f7e2482
VK
835
836 if (bEventExist)
837 {
838 sprintf(szQuery, "UPDATE events SET name='%s',severity=%ld,flags=%ld,message='%s',description='%s' WHERE event_id=%ld",
839 szName, pRequest->GetVariableLong(VID_SEVERITY), pRequest->GetVariableLong(VID_FLAGS),
840 pszEscMsg, pszEscDescr, dwEventId);
841 }
842 else
843 {
844 sprintf(szQuery, "INSERT INTO events SET event_id,name,severity,flags,message,description VALUES (%ld,'%s',%ld,%ld,'%s','%s')",
845 dwEventId, szName, pRequest->GetVariableLong(VID_SEVERITY),
846 pRequest->GetVariableLong(VID_FLAGS), pszEscMsg, pszEscDescr);
847 }
848
849 free(pszEscMsg);
850 free(pszEscDescr);
851
852 if (DBQuery(g_hCoreDB, szQuery))
853 {
854 msg.SetVariable(VID_RCC, RCC_SUCCESS);
855 m_dwFlags |= CSF_EVENT_DB_MODIFIED;
856 }
857 else
858 {
859 msg.SetVariable(VID_RCC, RCC_DB_FAILURE);
860 }
b8bad201 861 }
605d2931 862 else
b8bad201 863 {
8f7e2482 864 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_NAME);
b8bad201 865 }
605d2931
VK
866 }
867 else
868 {
869 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
870 }
871 }
872
873 // Send responce
874 SendMessage(&msg);
875}
24156e90
VK
876
877
878//
879// Modify object
880//
881
882void ClientSession::ModifyObject(CSCPMessage *pRequest)
883{
ff550544 884 DWORD dwObjectId, dwResult = RCC_SUCCESS;
24156e90
VK
885 NetObj *pObject;
886 CSCPMessage msg;
887
888 // Prepare reply message
889 msg.SetCode(CMD_REQUEST_COMPLETED);
890 msg.SetId(pRequest->GetId());
891
892 dwObjectId = pRequest->GetVariableLong(VID_OBJECT_ID);
893 pObject = FindObjectById(dwObjectId);
894 if (pObject != NULL)
895 {
896 if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_MODIFY))
897 {
ff550544
VK
898 // If user attempts to change object's ACL, check
899 // if he has OBJECT_ACCESS_CONTROL permission
900 if (pRequest->IsVariableExist(VID_ACL_SIZE))
901 if (!pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_CONTROL))
902 dwResult = RCC_ACCESS_DENIED;
903
904 // If allowed, change object and set completion code
905 if (dwResult != RCC_ACCESS_DENIED)
906 dwResult = pObject->ModifyFromMessage(pRequest);
24156e90
VK
907 msg.SetVariable(VID_RCC, dwResult);
908 }
909 else
910 {
911 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
912 }
913 }
914 else
915 {
916 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
917 }
918
919 // Send responce
920 SendMessage(&msg);
921}
23a32988
VK
922
923
924//
925// Send users database to client
926//
927
928void ClientSession::SendUserDB(DWORD dwRqId)
929{
930 CSCPMessage msg;
2d5c8ac8 931 DWORD i;
23a32988
VK
932
933 // Prepare responce message
934 msg.SetCode(CMD_REQUEST_COMPLETED);
935 msg.SetId(dwRqId);
936 msg.SetVariable(VID_RCC, RCC_SUCCESS);
937 SendMessage(&msg);
938
939 // Send users
940 msg.SetCode(CMD_USER_DATA);
941 for(i = 0; i < g_dwNumUsers; i++)
942 {
2d5c8ac8 943 FillUserInfoMessage(&msg, &g_pUserList[i]);
23a32988
VK
944 SendMessage(&msg);
945 msg.DeleteAllVariables();
946 }
947
948 // Send groups
949 msg.SetCode(CMD_GROUP_DATA);
950 for(i = 0; i < g_dwNumGroups; i++)
951 {
2d5c8ac8 952 FillGroupInfoMessage(&msg, &g_pGroupList[i]);
23a32988
VK
953 SendMessage(&msg);
954 msg.DeleteAllVariables();
955 }
956
957 // Send end-of-database notification
958 msg.SetCode(CMD_USER_DB_EOF);
959 SendMessage(&msg);
960}
ff550544
VK
961
962
963//
964// Create new user
965//
966
967void ClientSession::CreateUser(CSCPMessage *pRequest)
968{
969 CSCPMessage msg;
970
971 // Prepare responce message
972 msg.SetCode(CMD_REQUEST_COMPLETED);
973 msg.SetId(pRequest->GetId());
974
975 // Check user rights
976 if (!(m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_USERS))
977 {
978 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
979 }
980 else if (!(m_dwFlags & CSF_USER_DB_LOCKED))
981 {
982 // User database have to be locked before any
983 // changes to user database can be made
984 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
985 }
986 else
987 {
984542f8 988 DWORD dwResult, dwUserId;
ff550544
VK
989 BOOL bIsGroup;
990 char szUserName[MAX_USER_NAME];
991
992 pRequest->GetVariableStr(VID_USER_NAME, szUserName, MAX_USER_NAME);
8f7e2482
VK
993 if (IsValidObjectName(szUserName))
994 {
995 bIsGroup = pRequest->GetVariableShort(VID_IS_GROUP);
996 dwResult = CreateNewUser(szUserName, bIsGroup, &dwUserId);
997 msg.SetVariable(VID_RCC, dwResult);
998 if (dwResult == RCC_SUCCESS)
999 msg.SetVariable(VID_USER_ID, dwUserId); // Send id of new user to client
1000 }
1001 else
1002 {
1003 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_NAME);
1004 }
ff550544
VK
1005 }
1006
1007 // Send responce
1008 SendMessage(&msg);
1009}
1010
1011
1012//
1013// Update existing user's data
1014//
1015
1016void ClientSession::UpdateUser(CSCPMessage *pRequest)
1017{
612d43dc
VK
1018 CSCPMessage msg;
1019
1020 // Prepare responce message
1021 msg.SetCode(CMD_REQUEST_COMPLETED);
1022 msg.SetId(pRequest->GetId());
1023
1024 // Check user rights
1025 if (!(m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_USERS))
1026 {
1027 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1028 }
1029 else if (!(m_dwFlags & CSF_USER_DB_LOCKED))
1030 {
1031 // User database have to be locked before any
1032 // changes to user database can be made
1033 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
1034 }
1035 else
1036 {
86f31e8f 1037 DWORD dwUserId, dwResult;
612d43dc
VK
1038
1039 dwUserId = pRequest->GetVariableLong(VID_USER_ID);
1040 if (dwUserId & GROUP_FLAG)
1041 {
1042 NMS_USER_GROUP group;
2d5c8ac8 1043 DWORD i, dwId;
86f31e8f
VK
1044
1045 group.dwId = dwUserId;
2d5c8ac8
VK
1046 pRequest->GetVariableStr(VID_USER_DESCRIPTION, group.szDescription, MAX_USER_DESCR);
1047 pRequest->GetVariableStr(VID_USER_NAME, group.szName, MAX_USER_NAME);
1048 group.wFlags = pRequest->GetVariableShort(VID_USER_FLAGS);
1049 group.wSystemRights = pRequest->GetVariableShort(VID_USER_SYS_RIGHTS);
1050 group.dwNumMembers = pRequest->GetVariableLong(VID_NUM_MEMBERS);
1051 group.pMembers = (DWORD *)malloc(sizeof(DWORD) * group.dwNumMembers);
1052 for(i = 0, dwId = VID_GROUP_MEMBER_BASE; i < group.dwNumMembers; i++, dwId++)
1053 group.pMembers[i] = pRequest->GetVariableLong(dwId);
86f31e8f 1054 dwResult = ModifyGroup(&group);
2d5c8ac8 1055 safe_free(group.pMembers);
612d43dc
VK
1056 }
1057 else
1058 {
1059 NMS_USER user;
1060
1061 user.dwId = dwUserId;
1062 pRequest->GetVariableStr(VID_USER_DESCRIPTION, user.szDescription, MAX_USER_DESCR);
1063 pRequest->GetVariableStr(VID_USER_FULL_NAME, user.szFullName, MAX_USER_FULLNAME);
1064 pRequest->GetVariableStr(VID_USER_NAME, user.szName, MAX_USER_NAME);
1065 user.wFlags = pRequest->GetVariableShort(VID_USER_FLAGS);
86f31e8f
VK
1066 user.wSystemRights = pRequest->GetVariableShort(VID_USER_SYS_RIGHTS);
1067 dwResult = ModifyUser(&user);
612d43dc 1068 }
86f31e8f 1069 msg.SetVariable(VID_RCC, dwResult);
612d43dc
VK
1070 }
1071
1072 // Send responce
1073 SendMessage(&msg);
ff550544
VK
1074}
1075
1076
1077//
1078// Delete user
1079//
1080
1081void ClientSession::DeleteUser(CSCPMessage *pRequest)
1082{
1083 CSCPMessage msg;
1084 DWORD dwUserId;
1085
1086 // Prepare responce message
1087 msg.SetCode(CMD_REQUEST_COMPLETED);
1088 msg.SetId(pRequest->GetId());
1089
612d43dc
VK
1090 // Check user rights
1091 if (!(m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_USERS))
ff550544 1092 {
612d43dc
VK
1093 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1094 }
1095 else if (!(m_dwFlags & CSF_USER_DB_LOCKED))
1096 {
1097 // User database have to be locked before any
1098 // changes to user database can be made
1099 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
1100 }
1101 else
1102 {
1103 // Get Id of user to be deleted
1104 dwUserId = pRequest->GetVariableLong(VID_USER_ID);
1105
1106 if (dwUserId != 0)
ff550544 1107 {
612d43dc
VK
1108 if (!(m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_USERS))
1109 {
1110 // Current user has no rights for user account management
1111 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1112 }
1113 else if (!(m_dwFlags & CSF_USER_DB_LOCKED))
1114 {
1115 // User database have to be locked before any
1116 // changes to user database can be made
1117 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
1118 }
1119 else
1120 {
1121 DWORD dwResult;
1122
1123 dwResult = DeleteUserFromDB(dwUserId);
1124 msg.SetVariable(VID_RCC, dwResult);
1125 }
ff550544
VK
1126 }
1127 else
1128 {
612d43dc
VK
1129 // Nobody can delete system administrator account
1130 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
ff550544
VK
1131 }
1132 }
ff550544
VK
1133
1134 // Send responce
1135 SendMessage(&msg);
1136}
1137
1138
1139//
1140// Lock/unlock user database
1141//
1142
1143void ClientSession::LockUserDB(DWORD dwRqId, BOOL bLock)
1144{
1145 CSCPMessage msg;
1146 char szBuffer[256];
1147
1148 // Prepare responce message
1149 msg.SetCode(CMD_REQUEST_COMPLETED);
1150 msg.SetId(dwRqId);
1151
1152 if (m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_USERS)
1153 {
1154 if (bLock)
1155 {
1156 if (!LockComponent(CID_USER_DB, m_dwIndex, m_szUserName, NULL, szBuffer))
1157 {
1158 msg.SetVariable(VID_RCC, RCC_COMPONENT_LOCKED);
1159 msg.SetVariable(VID_LOCKED_BY, szBuffer);
1160 }
1161 else
1162 {
1163 m_dwFlags |= CSF_USER_DB_LOCKED;
1164 msg.SetVariable(VID_RCC, RCC_SUCCESS);
1165 }
1166 }
1167 else
1168 {
1169 if (m_dwFlags & CSF_USER_DB_LOCKED)
1170 {
1171 UnlockComponent(CID_USER_DB);
1172 m_dwFlags &= ~CSF_USER_DB_LOCKED;
1173 }
1174 msg.SetVariable(VID_RCC, RCC_SUCCESS);
1175 }
1176 }
1177 else
1178 {
1179 // Current user has no rights for user account management
1180 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1181 }
1182
1183 // Send responce
1184 SendMessage(&msg);
1185}
984542f8
VK
1186
1187
1188//
1189// Notify client on user database update
1190//
1191
1192void ClientSession::OnUserDBUpdate(int iCode, DWORD dwUserId, NMS_USER *pUser, NMS_USER_GROUP *pGroup)
1193{
1194 CSCPMessage msg;
1195
1196 if (m_iState == STATE_AUTHENTICATED)
1197 {
1198 msg.SetCode(CMD_USER_DB_UPDATE);
1199 msg.SetId(0);
1200 msg.SetVariable(VID_UPDATE_TYPE, (WORD)iCode);
984542f8
VK
1201
1202 switch(iCode)
1203 {
1204 case USER_DB_CREATE:
2d5c8ac8 1205 msg.SetVariable(VID_USER_ID, dwUserId);
984542f8 1206 if (dwUserId & GROUP_FLAG)
984542f8 1207 msg.SetVariable(VID_USER_NAME, pGroup->szName);
984542f8 1208 else
984542f8 1209 msg.SetVariable(VID_USER_NAME, pUser->szName);
2d5c8ac8
VK
1210 break;
1211 case USER_DB_MODIFY:
1212 if (dwUserId & GROUP_FLAG)
1213 FillGroupInfoMessage(&msg, pGroup);
1214 else
1215 FillUserInfoMessage(&msg, pUser);
984542f8
VK
1216 break;
1217 default:
2d5c8ac8 1218 msg.SetVariable(VID_USER_ID, dwUserId);
984542f8
VK
1219 break;
1220 }
1221
1222 SendMessage(&msg);
1223 }
1224}
017e1e13
VK
1225
1226
9ed4eaff
VK
1227//
1228// Change management status for the object
1229//
1230
1231void ClientSession::ChangeObjectMgmtStatus(CSCPMessage *pRequest)
1232{
1233 CSCPMessage msg;
1234 DWORD dwObjectId;
1235 NetObj *pObject;
1236
1237 // Prepare responce message
1238 msg.SetCode(CMD_REQUEST_COMPLETED);
1239 msg.SetId(pRequest->GetId());
1240
1241 // Get object id and check access rights
1242 dwObjectId = pRequest->GetVariableLong(VID_OBJECT_ID);
1243 pObject = FindObjectById(dwObjectId);
1244 if (pObject != NULL)
1245 {
1246 if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_MODIFY))
1247 {
1248 BOOL bIsManaged;
1249
1250 bIsManaged = (BOOL)pRequest->GetVariableShort(VID_MGMT_STATUS);
1251 pObject->SetMgmtStatus(bIsManaged);
1252 msg.SetVariable(VID_RCC, RCC_SUCCESS);
1253 }
1254 else
1255 {
1256 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1257 }
1258 }
1259 else
1260 {
1261 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
1262 }
1263
1264 // Send responce
1265 SendMessage(&msg);
1266}
1267
1268
017e1e13
VK
1269//
1270// Set user's password
1271//
1272
1273void ClientSession::SetPassword(CSCPMessage *pRequest)
1274{
1275 CSCPMessage msg;
1276 DWORD dwUserId;
1277
1278 // Prepare responce message
1279 msg.SetCode(CMD_REQUEST_COMPLETED);
1280 msg.SetId(pRequest->GetId());
1281
1282 dwUserId = pRequest->GetVariableLong(VID_USER_ID);
1283
1284 if (((m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_USERS) &&
1285 !((dwUserId == 0) && (m_dwUserId != 0))) || // Only administrator can change password for UID 0
1286 (dwUserId == m_dwUserId)) // User can change password for itself
1287 {
1288 DWORD dwResult;
6528a4d7 1289 BYTE szPassword[SHA1_DIGEST_SIZE];
017e1e13 1290
6528a4d7 1291 pRequest->GetVariableBinary(VID_PASSWORD, szPassword, SHA1_DIGEST_SIZE);
017e1e13
VK
1292 dwResult = SetUserPassword(dwUserId, szPassword);
1293 msg.SetVariable(VID_RCC, dwResult);
1294 }
1295 else
1296 {
1297 // Current user has no rights to change password for specific user
1298 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1299 }
1300
1301 // Send responce
1302 SendMessage(&msg);
1303}
7257eb7d
VK
1304
1305
1306//
1307// Send node's DCIs to client and lock data collection settings
1308//
1309
1310void ClientSession::OpenNodeDCIList(CSCPMessage *pRequest)
1311{
1312 CSCPMessage msg;
3c55b85d
VK
1313 DWORD dwObjectId;
1314 NetObj *pObject;
1315 BOOL bSuccess = FALSE;
7257eb7d
VK
1316
1317 // Prepare responce message
1318 msg.SetCode(CMD_REQUEST_COMPLETED);
1319 msg.SetId(pRequest->GetId());
1320
3c55b85d
VK
1321 // Get node id and check object class and access rights
1322 dwObjectId = pRequest->GetVariableLong(VID_OBJECT_ID);
1323 pObject = FindObjectById(dwObjectId);
1324 if (pObject != NULL)
1325 {
1326 if (pObject->Type() == OBJECT_NODE)
1327 {
1328 if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
1329 {
1330 // Try to lock DCI list
1331 bSuccess = ((Node *)pObject)->LockDCIList(m_dwIndex);
1332 msg.SetVariable(VID_RCC, bSuccess ? RCC_SUCCESS : RCC_COMPONENT_LOCKED);
338493a0
VK
1333
1334 // Modify list of open nodes DCI lists
1335 if (bSuccess)
1336 {
1337 m_pOpenDCIList = (DWORD *)realloc(m_pOpenDCIList, sizeof(DWORD) * (m_dwOpenDCIListSize + 1));
1338 m_pOpenDCIList[m_dwOpenDCIListSize] = dwObjectId;
1339 m_dwOpenDCIListSize++;
1340 }
3c55b85d
VK
1341 }
1342 else
1343 {
1344 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1345 }
1346 }
1347 else
1348 {
1349 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
1350 }
1351 }
1352 else
1353 {
1354 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
1355 }
7257eb7d
VK
1356
1357 // Send responce
1358 SendMessage(&msg);
3c55b85d
VK
1359
1360 // If DCI list was successfully locked, send it to client
1361 if (bSuccess)
1362 ((Node *)pObject)->SendItemsToClient(this, pRequest->GetId());
7257eb7d
VK
1363}
1364
1365
1366//
1367// Unlock node's data collection settings
1368//
1369
1370void ClientSession::CloseNodeDCIList(CSCPMessage *pRequest)
1371{
1372 CSCPMessage msg;
3c55b85d
VK
1373 DWORD dwObjectId;
1374 NetObj *pObject;
7257eb7d
VK
1375
1376 // Prepare responce message
1377 msg.SetCode(CMD_REQUEST_COMPLETED);
1378 msg.SetId(pRequest->GetId());
1379
3c55b85d
VK
1380 // Get node id and check object class and access rights
1381 dwObjectId = pRequest->GetVariableLong(VID_OBJECT_ID);
1382 pObject = FindObjectById(dwObjectId);
1383 if (pObject != NULL)
1384 {
1385 if (pObject->Type() == OBJECT_NODE)
1386 {
1387 if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
1388 {
1389 BOOL bSuccess;
1390
1391 // Try to unlock DCI list
1392 bSuccess = ((Node *)pObject)->UnlockDCIList(m_dwIndex);
1393 msg.SetVariable(VID_RCC, bSuccess ? RCC_SUCCESS : RCC_OUT_OF_STATE_REQUEST);
338493a0
VK
1394
1395 // Modify list of open nodes DCI lists
1396 if (bSuccess)
1397 {
1398 DWORD i;
1399
1400 for(i = 0; i < m_dwOpenDCIListSize; i++)
1401 if (m_pOpenDCIList[i] == dwObjectId)
1402 {
1403 m_dwOpenDCIListSize--;
1404 memmove(&m_pOpenDCIList[i], &m_pOpenDCIList[i + 1],
1405 sizeof(DWORD) * (m_dwOpenDCIListSize - i));
1406 break;
1407 }
1408 }
3c55b85d
VK
1409 }
1410 else
1411 {
1412 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1413 }
1414 }
1415 else
1416 {
1417 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
1418 }
1419 }
1420 else
1421 {
1422 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
1423 }
1424
7257eb7d
VK
1425 // Send responce
1426 SendMessage(&msg);
1427}
c1c39152
VK
1428
1429
1430//
9ed4eaff 1431// Create, modify, or delete data collection item for node
c1c39152
VK
1432//
1433
9ed4eaff 1434void ClientSession::ModifyNodeDCI(CSCPMessage *pRequest)
c1c39152
VK
1435{
1436 CSCPMessage msg;
1437 DWORD dwObjectId;
1438 NetObj *pObject;
1439
1440 // Prepare responce message
1441 msg.SetCode(CMD_REQUEST_COMPLETED);
1442 msg.SetId(pRequest->GetId());
1443
9ed4eaff 1444 // Get node id and check object class and access rights
c1c39152
VK
1445 dwObjectId = pRequest->GetVariableLong(VID_OBJECT_ID);
1446 pObject = FindObjectById(dwObjectId);
1447 if (pObject != NULL)
1448 {
9ed4eaff 1449 if (pObject->Type() == OBJECT_NODE)
c1c39152 1450 {
9ed4eaff
VK
1451 if (((Node *)pObject)->IsLockedBySession(m_dwIndex))
1452 {
1453 if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_MODIFY))
1454 {
07a45e04 1455 DWORD i, dwItemId, dwNumMaps, *pdwMapId, *pdwMapIndex;
9ed4eaff
VK
1456 DCItem *pItem;
1457 BOOL bSuccess;
1458
1459 switch(pRequest->GetCode())
1460 {
1461 case CMD_CREATE_NEW_DCI:
1462 // Create dummy DCI
1463 pItem = new DCItem(CreateUniqueId(IDG_ITEM), "no name", DS_INTERNAL,
42d7ed00 1464 DCI_DT_INTEGER, 60, 30, (Node *)pObject);
9ed4eaff
VK
1465 pItem->SetStatus(ITEM_STATUS_DISABLED);
1466 if (((Node *)pObject)->AddItem(pItem))
1467 {
1468 msg.SetVariable(VID_RCC, RCC_SUCCESS);
1469 // Return new item id to client
1470 msg.SetVariable(VID_DCI_ID, pItem->Id());
1471 }
1472 else // Unable to add item to node
1473 {
1474 delete pItem;
1475 msg.SetVariable(VID_RCC, RCC_DUPLICATE_DCI);
1476 }
1477 break;
1478 case CMD_MODIFY_NODE_DCI:
1479 dwItemId = pRequest->GetVariableLong(VID_DCI_ID);
07a45e04
VK
1480 bSuccess = ((Node *)pObject)->UpdateItem(dwItemId, pRequest, &dwNumMaps,
1481 &pdwMapIndex, &pdwMapId);
1482 if (bSuccess)
1483 {
1484 msg.SetVariable(VID_RCC, RCC_SUCCESS);
1485
1486 // Send index to id mapping for newly created thresholds to client
1487 msg.SetVariable(VID_DCI_NUM_MAPS, dwNumMaps);
1488 for(i = 0; i < dwNumMaps; i++)
1489 {
1490 pdwMapId[i] = htonl(pdwMapId[i]);
1491 pdwMapIndex[i] = htonl(pdwMapIndex[i]);
1492 }
1493 msg.SetVariable(VID_DCI_MAP_IDS, (BYTE *)pdwMapId, sizeof(DWORD) * dwNumMaps);
1494 msg.SetVariable(VID_DCI_MAP_INDEXES, (BYTE *)pdwMapIndex, sizeof(DWORD) * dwNumMaps);
7247842d
VK
1495 safe_free(pdwMapId);
1496 safe_free(pdwMapIndex);
07a45e04
VK
1497 }
1498 else
1499 {
1500 msg.SetVariable(VID_RCC, RCC_INVALID_DCI_ID);
1501 }
9ed4eaff
VK
1502 break;
1503 case CMD_DELETE_NODE_DCI:
1504 dwItemId = pRequest->GetVariableLong(VID_DCI_ID);
1505 bSuccess = ((Node *)pObject)->DeleteItem(dwItemId);
1506 msg.SetVariable(VID_RCC, bSuccess ? RCC_SUCCESS : RCC_INVALID_DCI_ID);
1507 break;
1508 }
1509 }
1510 else // User doesn't have MODIFY rights on object
1511 {
1512 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1513 }
1514 }
1515 else // Nodes DCI list not locked by this session
1516 {
1517 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
1518 }
c1c39152 1519 }
9ed4eaff 1520 else // Object is not a node
c1c39152 1521 {
9ed4eaff 1522 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
c1c39152
VK
1523 }
1524 }
9ed4eaff 1525 else // No object with given ID
c1c39152
VK
1526 {
1527 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
1528 }
1529
1530 // Send responce
1531 SendMessage(&msg);
1532}
ebebc8ea
VK
1533
1534
1535//
1536// Get collected data
1537//
1538
1539void ClientSession::GetCollectedData(CSCPMessage *pRequest)
1540{
1541 CSCPMessage msg;
1542 DWORD dwObjectId;
1543 NetObj *pObject;
6159a875
VK
1544 BOOL bSuccess = FALSE;
1545 static DWORD m_dwRowSize[] = { 8, 12, 260, 12 };
ebebc8ea
VK
1546
1547 // Prepare responce message
1548 msg.SetCode(CMD_REQUEST_COMPLETED);
1549 msg.SetId(pRequest->GetId());
1550
1551 // Get node id and check object class and access rights
1552 dwObjectId = pRequest->GetVariableLong(VID_OBJECT_ID);
1553 pObject = FindObjectById(dwObjectId);
1554 if (pObject != NULL)
1555 {
1556 if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
1557 {
1558 DB_ASYNC_RESULT hResult;
1559 DWORD dwItemId, dwMaxRows, dwTimeFrom, dwTimeTo;
6159a875 1560 DWORD dwAllocatedRows = 100, dwNumRows = 0;
bdce7422
VK
1561 char szQuery[512], szCond[256];
1562 int iPos = 0, iType;
1563 DCI_DATA_HEADER *pData = NULL;
6159a875 1564 DCI_DATA_ROW *pCurr;
bdce7422
VK
1565
1566 // Send CMD_REQUEST_COMPLETED message
1567 msg.SetVariable(VID_RCC, RCC_SUCCESS);
1568 SendMessage(&msg);
ebebc8ea
VK
1569
1570 // Get request parameters
1571 dwItemId = pRequest->GetVariableLong(VID_DCI_ID);
1572 dwMaxRows = pRequest->GetVariableLong(VID_MAX_ROWS);
1573 dwTimeFrom = pRequest->GetVariableLong(VID_TIME_FROM);
1574 dwTimeTo = pRequest->GetVariableLong(VID_TIME_TO);
1575
9f20696e 1576 szCond[0] = 0;
bdce7422
VK
1577 if (dwTimeFrom != 0)
1578 {
1579 sprintf(szCond, " AND timestamp>=%d", dwTimeFrom);
1580 iPos = strlen(szCond);
1581 }
1582 if (dwTimeTo != 0)
1583 {
1584 sprintf(&szCond[iPos], " AND timestamp<=%d", dwTimeTo);
1585 }
1586
1587 sprintf(szQuery, "SELECT timestamp,value FROM idata_%d WHERE item_id=%d%s ORDER BY timestamp DESC",
1588 dwObjectId, dwItemId, szCond);
ebebc8ea
VK
1589 hResult = DBAsyncSelect(g_hCoreDB, szQuery);
1590 if (hResult != NULL)
1591 {
6159a875 1592 // Get item's data type to determine actual row size
bdce7422
VK
1593 iType = ((Node *)pObject)->GetItemType(dwItemId);
1594
6159a875
VK
1595 // Allocate initial memory block and prepare data header
1596 pData = (DCI_DATA_HEADER *)malloc(dwAllocatedRows * m_dwRowSize[iType] + sizeof(DCI_DATA_HEADER));
1597 pData->dwDataType = htonl((DWORD)iType);
1598 pData->dwItemId = htonl(dwItemId);
1599
1600 // Fill memory block with records
1601 pCurr = (DCI_DATA_ROW *)(((char *)pData) + sizeof(DCI_DATA_HEADER));
ebebc8ea
VK
1602 while(DBFetch(hResult))
1603 {
6159a875 1604 if ((dwMaxRows > 0) && (dwNumRows >= dwMaxRows))
bdce7422 1605 break;
6159a875
VK
1606
1607 // Extend buffer if we are at the end
1608 if (dwNumRows == dwAllocatedRows)
1609 {
1610 dwAllocatedRows += 50;
1611 pData = (DCI_DATA_HEADER *)realloc(pData,
1612 dwAllocatedRows * m_dwRowSize[iType] + sizeof(DCI_DATA_HEADER));
1613 pCurr = (DCI_DATA_ROW *)(((char *)pData) + sizeof(DCI_DATA_HEADER) + m_dwRowSize[iType] * dwNumRows);
1614 }
1615
1616 dwNumRows++;
1617
1618 pCurr->dwTimeStamp = htonl(DBGetFieldAsyncULong(hResult, 0));
1619 switch(iType)
1620 {
42d7ed00 1621 case DCI_DT_INTEGER:
9f20696e
VK
1622 pCurr->value.dwInteger = htonl(DBGetFieldAsyncULong(hResult, 1));
1623 break;
42d7ed00 1624 case DCI_DT_FLOAT:
9f20696e 1625 pCurr->value.dFloat = htond(DBGetFieldAsyncDouble(hResult, 1));
6159a875 1626 break;
42d7ed00 1627 case DCI_DT_STRING:
6159a875
VK
1628 DBGetFieldAsync(hResult, 1, pCurr->value.szString, MAX_DCI_STRING_VALUE);
1629 break;
1630 }
1631 pCurr = (DCI_DATA_ROW *)(((char *)pCurr) + m_dwRowSize[iType]);
ebebc8ea
VK
1632 }
1633 DBFreeAsyncResult(hResult);
9f20696e 1634 pData->dwNumRows = htonl(dwNumRows);
6159a875
VK
1635
1636 // Prepare and send raw message with fetched data
1637 m_pSendQueue->Put(
1638 CreateRawCSCPMessage(CMD_DCI_DATA, pRequest->GetId(),
1639 dwNumRows * m_dwRowSize[iType] + sizeof(DCI_DATA_HEADER),
1640 pData, NULL));
1641 free(pData);
1642 bSuccess = TRUE;
ebebc8ea
VK
1643 }
1644 }
1645 else
1646 {
1647 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1648 }
1649 }
1650 else // No object with given ID
1651 {
1652 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
1653 }
1654
1655 // Send responce
6159a875
VK
1656 if (!bSuccess)
1657 SendMessage(&msg);
ebebc8ea 1658}
06e7be2f
VK
1659
1660
1661//
1662// Open event processing policy
1663//
1664
1665void ClientSession::OpenEPP(DWORD dwRqId)
1666{
1667 CSCPMessage msg;
1668 char szBuffer[256];
1669 BOOL bSuccess = FALSE;
1670
1671 // Prepare responce message
1672 msg.SetCode(CMD_REQUEST_COMPLETED);
1673 msg.SetId(dwRqId);
1674
1675 if (m_dwSystemAccess & SYSTEM_ACCESS_EPP)
1676 {
1677 if (!LockComponent(CID_EPP, m_dwIndex, m_szUserName, NULL, szBuffer))
1678 {
1679 msg.SetVariable(VID_RCC, RCC_COMPONENT_LOCKED);
1680 msg.SetVariable(VID_LOCKED_BY, szBuffer);
1681 }
1682 else
1683 {
1684 m_dwFlags |= CSF_EPP_LOCKED;
1685 msg.SetVariable(VID_RCC, RCC_SUCCESS);
1686 msg.SetVariable(VID_NUM_RULES, g_pEventPolicy->NumRules());
1687 bSuccess = TRUE;
1688 }
1689 }
1690 else
1691 {
1692 // Current user has no rights for event policy management
1693 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1694 }
1695
1696 // Send responce
1697 SendMessage(&msg);
1698
1699 // Send policy to client
1700 if (bSuccess)
1701 g_pEventPolicy->SendToClient(this, dwRqId);
1702}
1703
1704
1705//
1706// Close event processing policy
1707//
1708
1709void ClientSession::CloseEPP(DWORD dwRqId)
1710{
1711 CSCPMessage msg;
1712
1713 // Prepare responce message
1714 msg.SetCode(CMD_REQUEST_COMPLETED);
1715 msg.SetId(dwRqId);
1716
1717 if (m_dwSystemAccess & SYSTEM_ACCESS_EPP)
1718 {
1719 if (m_dwFlags & CSF_EPP_LOCKED)
1720 {
1721 UnlockComponent(CID_EPP);
1722 m_dwFlags &= ~CSF_EPP_LOCKED;
1723 }
1724 msg.SetVariable(VID_RCC, RCC_SUCCESS);
1725 }
1726 else
1727 {
1728 // Current user has no rights for event policy management
1729 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1730 }
1731
1732 // Send responce
1733 SendMessage(&msg);
1734}
1735
1736
1737//
1738// Save event processing policy
1739//
1740
8f7e2482 1741void ClientSession::SaveEPP(CSCPMessage *pRequest)
06e7be2f 1742{
8f7e2482
VK
1743 CSCPMessage msg;
1744
1745 // Prepare responce message
1746 msg.SetCode(CMD_REQUEST_COMPLETED);
1747 msg.SetId(pRequest->GetId());
1748
1749 if (m_dwSystemAccess & SYSTEM_ACCESS_EPP)
1750 {
1751 if (m_dwFlags & CSF_EPP_LOCKED)
1752 {
1753 msg.SetVariable(VID_RCC, RCC_SUCCESS);
8f7e2482
VK
1754 m_dwNumRecordsToUpload = pRequest->GetVariableLong(VID_NUM_RULES);
1755 m_dwRecordsUploaded = 0;
043fe1ec
VK
1756 if (m_dwNumRecordsToUpload == 0)
1757 {
1758 g_pEventPolicy->ReplacePolicy(0, NULL);
1759 g_pEventPolicy->SaveToDB();
1760 }
1761 else
1762 {
1763 m_dwFlags |= CSF_EPP_UPLOAD;
1764 m_ppEPPRuleList = (EPRule **)malloc(sizeof(EPRule *) * m_dwNumRecordsToUpload);
1765 memset(m_ppEPPRuleList, 0, sizeof(EPRule *) * m_dwNumRecordsToUpload);
1766 }
8f7e2482
VK
1767 DebugPrintf("Accepted EPP upload request for %d rules\n", m_dwNumRecordsToUpload);
1768 }
1769 else
1770 {
1771 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
1772 }
1773 }
1774 else
1775 {
1776 // Current user has no rights for event policy management
1777 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
1778 }
1779
1780 // Send responce
1781 SendMessage(&msg);
06e7be2f
VK
1782}
1783
1784
1785//
8f7e2482 1786// Process EPP rule received from client
06e7be2f
VK
1787//
1788
8f7e2482 1789void ClientSession::ProcessEPPRecord(CSCPMessage *pRequest)
06e7be2f 1790{
8f7e2482
VK
1791 if (!(m_dwFlags & CSF_EPP_LOCKED))
1792 {
1793 CSCPMessage msg;
1794
1795 msg.SetCode(CMD_REQUEST_COMPLETED);
1796 msg.SetId(pRequest->GetId());
1797 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
1798 SendMessage(&msg);
1799 }
1800 else
1801 {
1802 if (m_dwRecordsUploaded < m_dwNumRecordsToUpload)
1803 {
1804 m_ppEPPRuleList[m_dwRecordsUploaded] = new EPRule(pRequest);
1805 m_dwRecordsUploaded++;
1806 if (m_dwRecordsUploaded == m_dwNumRecordsToUpload)
1807 {
1808 CSCPMessage msg;
1809
1810 // All records received, replace event policy...
1811 DebugPrintf("Replacing event processing policy with a new one at %p (%d rules)\n",
1812 m_ppEPPRuleList, m_dwNumRecordsToUpload);
1813 g_pEventPolicy->ReplacePolicy(m_dwNumRecordsToUpload, m_ppEPPRuleList);
043fe1ec 1814 g_pEventPolicy->SaveToDB();
8f7e2482
VK
1815 m_ppEPPRuleList = NULL;
1816
1817 // ... and send final confirmation
1818 msg.SetCode(CMD_REQUEST_COMPLETED);
1819 msg.SetId(pRequest->GetId());
1820 msg.SetVariable(VID_RCC, RCC_SUCCESS);
1821 SendMessage(&msg);
1822
1823 m_dwFlags &= ~CSF_EPP_UPLOAD;
1824 }
1825 }
1826 }
06e7be2f
VK
1827}
1828
1829
1830//
1831// Send list of available MIB files to client
1832//
1833
1834void ClientSession::SendMIBList(DWORD dwRqId)
1835{
1836 CSCPMessage msg;
1837 DWORD dwId1, dwId2, dwNumFiles;
1838 DIR *dir;
1839 int iBufPos;
c9ccd685 1840#ifdef _WIN32
06e7be2f 1841 struct direct *dptr;
c9ccd685
AK
1842#else
1843 struct dirent *dptr;
1844#endif
06e7be2f
VK
1845 char szBuffer[MAX_PATH];
1846 BYTE md5Hash[MD5_DIGEST_SIZE];
1847
1848 // Prepare responce message
1849 msg.SetCode(CMD_MIB_LIST);
1850 msg.SetId(dwRqId);
1851
1852 // Read directory
1853 dwNumFiles = 0;
1854 strcpy(szBuffer, g_szDataDir);
1855 strcat(szBuffer, DDIR_MIBS);
1856 dir = opendir(szBuffer);
1857 if (dir != NULL)
1858 {
1859#ifdef _WIN32
1860 strcat(szBuffer, "\\");
1861#else
1862 strcat(szBuffer, "/");
1863#endif
1864 iBufPos = strlen(szBuffer);
1865 dwId1 = VID_MIB_NAME_BASE;
1866 dwId2 = VID_MIB_HASH_BASE;
1867 while((dptr = readdir(dir)) != NULL)
1868 {
1869 strcpy(&szBuffer[iBufPos], dptr->d_name);
1870 if (CalculateFileMD5Hash(szBuffer, md5Hash))
1871 {
1872 msg.SetVariable(dwId1++, dptr->d_name);
1873 msg.SetVariable(dwId2++, md5Hash, MD5_DIGEST_SIZE);
1874 dwNumFiles++;
1875 }
1876 }
1877 closedir(dir);
1878 }
1879
1880 msg.SetVariable(VID_NUM_MIBS, dwNumFiles);
1881
1882 // Send responce
1883 SendMessage(&msg);
1884}
1885
1886
1887//
1888// Send requested MIB file to client
1889//
1890
1891void ClientSession::SendMIB(CSCPMessage *pRequest)
1892{
1893 CSCPMessage msg;
1894 BYTE *pFile;
1895 DWORD dwFileSize;
1896 char szBuffer[MAX_PATH], szMIB[MAX_PATH];
1897
1898 // Prepare responce message
1899 msg.SetCode(CMD_MIB);
1900 msg.SetId(pRequest->GetId());
1901
1902 // Get name of the requested file
1903 pRequest->GetVariableStr(VID_MIB_NAME, szMIB, MAX_PATH);
1904
1905 // Load file into memory
1906 strcpy(szBuffer, g_szDataDir);
1907 strcat(szBuffer, DDIR_MIBS);
1908#ifdef _WIN32
1909 strcat(szBuffer, "\\");
1910#else
1911 strcat(szBuffer, "/");
1912#endif
1913 strcat(szBuffer, szMIB);
1914 pFile = LoadFile(szBuffer, &dwFileSize);
1915 if (pFile != NULL)
1916 {
1917 msg.SetVariable(VID_RCC, RCC_SUCCESS);
1918 msg.SetVariable(VID_MIB_FILE_SIZE, dwFileSize);
1919 msg.SetVariable(VID_MIB_FILE, pFile, dwFileSize);
1920 free(pFile);
1921 }
1922 else
1923 {
1924 msg.SetVariable(VID_RCC, RCC_SYSTEM_FAILURE);
1925 }
1926
1927 // Send responce
1928 SendMessage(&msg);
1929}
ef44d5ea
VK
1930
1931
1932//
3421c063
VK
1933// Send list of event name/identifier pairs
1934//
1935
1936void ClientSession::SendEventNames(DWORD dwRqId)
1937{
1938 CSCPMessage msg;
1939 DB_RESULT hResult;
1940
1941 msg.SetCode(CMD_EVENT_NAME_LIST);
1942 msg.SetId(dwRqId);
936eeedf 1943 hResult = DBSelect(g_hCoreDB, "SELECT event_id,name,severity FROM events");
3421c063
VK
1944 if (hResult != NULL)
1945 {
1946 DWORD i, dwNumEvents;
1947 NXC_EVENT_NAME *pList;
1948
1949 dwNumEvents = DBGetNumRows(hResult);
1950 msg.SetVariable(VID_NUM_EVENTS, dwNumEvents);
1951 if (dwNumEvents > 0)
1952 {
1953 pList = (NXC_EVENT_NAME *)malloc(sizeof(NXC_EVENT_NAME) * dwNumEvents);
1954 for(i = 0; i < dwNumEvents; i++)
1955 {
1956 pList[i].dwEventId = htonl(DBGetFieldULong(hResult, i, 0));
936eeedf 1957 pList[i].dwSeverity = htonl(DBGetFieldLong(hResult, i, 2));
3421c063
VK
1958 strcpy(pList[i].szName, DBGetField(hResult, i, 1));
1959 }
1960 msg.SetVariable(VID_EVENT_NAME_TABLE, (BYTE *)pList, sizeof(NXC_EVENT_NAME) * dwNumEvents);
1961 free(pList);
1962 }
1963 DBFreeResult(hResult);
1964 msg.SetVariable(VID_RCC, RCC_SUCCESS);
1965 }
1966 else
1967 {
1968 msg.SetVariable(VID_RCC, RCC_DB_FAILURE);
1969 }
1970 SendMessage(&msg);
1971}
1972
1973
1974//
ef44d5ea
VK
1975// Create new object
1976//
1977
1978void ClientSession::CreateObject(CSCPMessage *pRequest)
1979{
e6b958c4
VK
1980 CSCPMessage msg;
1981 NetObj *pObject, *pParent;
1982 int iClass;
917aa2e6 1983 char *pDescription, szObjectName[MAX_OBJECT_NAME];
e6b958c4
VK
1984
1985 // Prepare responce message
1986 msg.SetCode(CMD_REQUEST_COMPLETED);
1987 msg.SetId(pRequest->GetId());
1988
1989 // Find parent object
1990 pParent = FindObjectById(pRequest->GetVariableLong(VID_PARENT_ID));
1991 if (pParent != NULL)
1992 {
1993 // User should have create access to parent object
1994 if (pParent->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_CREATE))
1995 {
1996 // Parent object should be container or service root
1997 if ((pParent->Type() == OBJECT_CONTAINER) ||
1998 (pParent->Type() == OBJECT_SERVICEROOT))
1999 {
2000 iClass = pRequest->GetVariableShort(VID_OBJECT_CLASS);
2001 pRequest->GetVariableStr(VID_OBJECT_NAME, szObjectName, MAX_OBJECT_NAME);
8f7e2482 2002 if (IsValidObjectName(szObjectName))
e6b958c4 2003 {
8f7e2482 2004 if ((iClass == OBJECT_NODE) || (iClass == OBJECT_CONTAINER))
e6b958c4 2005 {
8f7e2482
VK
2006 // Create new object
2007 switch(iClass)
2008 {
2009 case OBJECT_NODE:
2010 pObject = PollNewNode(pRequest->GetVariableLong(VID_IP_ADDRESS),
2011 pRequest->GetVariableLong(VID_IP_NETMASK),
2012 DF_DEFAULT);
2013 break;
2014 case OBJECT_CONTAINER:
2015 pDescription = pRequest->GetVariableStr(VID_DESCRIPTION);
2016 pObject = new Container(szObjectName,
2017 pRequest->GetVariableLong(VID_CATEGORY),
2018 pDescription);
9d72bde1 2019 safe_free(pDescription);
8f7e2482
VK
2020 NetObjInsert(pObject, TRUE);
2021 break;
2022 }
917aa2e6 2023
8f7e2482
VK
2024 // If creation was successful do binding
2025 if (pObject != NULL)
2026 {
2027 pParent->AddChild(pObject);
2028 pObject->AddParent(pParent);
2029 msg.SetVariable(VID_RCC, RCC_SUCCESS);
2030 msg.SetVariable(VID_OBJECT_ID, pObject->Id());
2031 }
2032 else
2033 {
2034 msg.SetVariable(VID_RCC, RCC_OBJECT_CREATION_FAILED);
2035 }
917aa2e6
VK
2036 }
2037 else
2038 {
8f7e2482 2039 msg.SetVariable(VID_RCC, RCC_INCOMPATIBLE_OPERATION);
917aa2e6 2040 }
e6b958c4
VK
2041 }
2042 else
2043 {
8f7e2482 2044 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_NAME);
e6b958c4
VK
2045 }
2046 }
2047 else
2048 {
2049 msg.SetVariable(VID_RCC, RCC_INCOMPATIBLE_OPERATION);
2050 }
2051 }
2052 else
2053 {
2054 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
2055 }
2056 }
2057 else
2058 {
2059 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
2060 }
2061
2062 // Send responce
2063 SendMessage(&msg);
2064}
2065
2066
2067//
2068// Bind/unbind object
2069//
2070
2071void ClientSession::ChangeObjectBinding(CSCPMessage *pRequest, BOOL bBind)
2072{
2073 CSCPMessage msg;
2074 NetObj *pParent, *pChild;
2075
2076 // Prepare responce message
2077 msg.SetCode(CMD_REQUEST_COMPLETED);
2078 msg.SetId(pRequest->GetId());
2079
2080 // Get parent and child objects
2081 pParent = FindObjectById(pRequest->GetVariableLong(VID_PARENT_ID));
2082 pChild = FindObjectById(pRequest->GetVariableLong(VID_CHILD_ID));
2083
2084 // Check access rights and change binding
2085 if ((pParent != NULL) && (pChild != NULL))
2086 {
2087 // User should have modify access to both objects
2088 if ((pParent->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_MODIFY)) &&
2089 (pChild->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_MODIFY)))
2090 {
2091 // Parent object should be container or service root
2092 if ((pParent->Type() == OBJECT_CONTAINER) ||
2093 (pParent->Type() == OBJECT_SERVICEROOT))
2094 {
2095 if (bBind)
2096 {
917aa2e6
VK
2097 // Prevent loops
2098 if (!pChild->IsChild(pParent->Id()))
2099 {
2100 pParent->AddChild(pChild);
2101 pChild->AddParent(pParent);
2102 msg.SetVariable(VID_RCC, RCC_SUCCESS);
2103 }
2104 else
2105 {
2106 msg.SetVariable(VID_RCC, RCC_OBJECT_LOOP);
2107 }
e6b958c4
VK
2108 }
2109 else
2110 {
2111 pParent->DeleteChild(pChild);
2112 pChild->DeleteParent(pParent);
917aa2e6 2113 msg.SetVariable(VID_RCC, RCC_SUCCESS);
e6b958c4 2114 }
e6b958c4
VK
2115 }
2116 else
2117 {
2118 msg.SetVariable(VID_RCC, RCC_INCOMPATIBLE_OPERATION);
2119 }
2120 }
2121 else
2122 {
2123 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
2124 }
2125 }
2126 else
2127 {
2128 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
2129 }
2130
2131 // Send responce
2132 SendMessage(&msg);
ef44d5ea 2133}
03482383
VK
2134
2135
2136//
2137// Process changes in alarms
2138//
2139
2140void ClientSession::OnAlarmUpdate(DWORD dwCode, NXC_ALARM *pAlarm)
2141{
2142 UPDATE_INFO *pUpdate;
2143 NetObj *pObject;
2144
2145 if (m_iState == STATE_AUTHENTICATED)
2146 {
2147 pObject = FindObjectById(pAlarm->dwSourceObject);
2148 if (pObject != NULL)
2149 if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_READ_ALARMS))
2150 {
2151 pUpdate = (UPDATE_INFO *)malloc(sizeof(UPDATE_INFO));
2152 pUpdate->dwCategory = INFO_CAT_ALARM;
2153 pUpdate->pData = malloc(sizeof(ALARM_UPDATE));
2154 ((ALARM_UPDATE *)pUpdate->pData)->dwCode = dwCode;
2155 memcpy(&((ALARM_UPDATE *)pUpdate->pData)->alarm, pAlarm, sizeof(NXC_ALARM));
2156 m_pUpdateQueue->Put(pUpdate);
2157 }
2158 }
2159}
2160
2161
2162//
2163// Send all alarms to client
2164//
2165
2166void ClientSession::SendAllAlarms(DWORD dwRqId, BOOL bIncludeAck)
2167{
2168 MutexLock(m_mutexSendAlarms, INFINITE);
2169 g_alarmMgr.SendAlarmsToClient(dwRqId, bIncludeAck, this);
2170 MutexUnlock(m_mutexSendAlarms);
2171}
ee20e615
VK
2172
2173
2174//
2175// Acknowlege alarm
2176//
2177
2178void ClientSession::AcknowlegeAlarm(CSCPMessage *pRequest)
2179{
2180 CSCPMessage msg;
2181 NetObj *pObject;
2182 DWORD dwAlarmId;
2183
2184 // Prepare responce message
2185 msg.SetCode(CMD_REQUEST_COMPLETED);
2186 msg.SetId(pRequest->GetId());
2187
2188 // Get alarm id and it's source object
2189 dwAlarmId = pRequest->GetVariableLong(VID_ALARM_ID);
2190 pObject = g_alarmMgr.GetAlarmSourceObject(dwAlarmId);
2191 if (pObject != NULL)
2192 {
2193 // User should have "acknowlege alarm" right to the object
2194 if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_ACK_ALARMS))
2195 {
2196 g_alarmMgr.AckById(dwAlarmId, m_dwUserId);
2197 msg.SetVariable(VID_RCC, RCC_SUCCESS);
2198 }
2199 else
2200 {
2201 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
2202 }
2203 }
2204 else
2205 {
2206 // Normally, for existing alarms pObject will not be NULL,
2207 // so we assume that alarm id is invalid
2208 msg.SetVariable(VID_RCC, RCC_INVALID_ALARM_ID);
2209 }
2210
2211 // Send responce
2212 SendMessage(&msg);
2213}