- Added primary key to user_group_members table
[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
25
26//
27// Client session class constructor
28//
29
b54b2b11 30ClientSession::ClientSession(SOCKET hSocket, DWORD dwHostAddr)
21e4b6f0
VK
31{
32 m_pSendQueue = new Queue;
33 m_pMessageQueue = new Queue;
62f5857f 34 m_pUpdateQueue = new Queue;
21e4b6f0
VK
35 m_hSocket = hSocket;
36 m_dwIndex = INVALID_INDEX;
37 m_iState = STATE_CONNECTED;
38 m_pMsgBuffer = (CSCP_BUFFER *)malloc(sizeof(CSCP_BUFFER));
d16cf8a5
AK
39 m_hCondWriteThreadStopped = ConditionCreate(FALSE);
40 m_hCondProcessingThreadStopped = ConditionCreate(FALSE);
41 m_hCondUpdateThreadStopped = ConditionCreate(FALSE);
62f5857f 42 m_hMutexSendEvents = MutexCreate();
53512272 43 m_hMutexSendObjects = MutexCreate();
b54b2b11
VK
44 m_dwFlags = 0;
45 m_dwHostAddr = dwHostAddr;
46 strcpy(m_szUserName, "<not logged in>");
21e4b6f0
VK
47}
48
49
50//
51// Destructor
52//
53
54ClientSession::~ClientSession()
55{
56 shutdown(m_hSocket, 2);
57 closesocket(m_hSocket);
58 delete m_pSendQueue;
59 delete m_pMessageQueue;
62f5857f 60 delete m_pUpdateQueue;
21e4b6f0
VK
61 if (m_pMsgBuffer != NULL)
62 free(m_pMsgBuffer);
ecb7e1ee
VK
63 ConditionDestroy(m_hCondWriteThreadStopped);
64 ConditionDestroy(m_hCondProcessingThreadStopped);
62f5857f
VK
65 ConditionDestroy(m_hCondUpdateThreadStopped);
66 MutexDestroy(m_hMutexSendEvents);
53512272 67 MutexDestroy(m_hMutexSendObjects);
b54b2b11
VK
68
69 // Unlock locked components
70 if (m_dwFlags & CSF_EVENT_DB_LOCKED)
71 UnlockComponent(CID_EVENT_DB);
21e4b6f0
VK
72}
73
74
75//
76// Print debug information
77//
78
79void ClientSession::DebugPrintf(char *szFormat, ...)
80{
81 if ((g_dwFlags & AF_STANDALONE) && (g_dwFlags & AF_DEBUG_CSCP))
82 {
83 va_list args;
84
85 printf("*CSCP(%d)* ", m_dwIndex);
86 va_start(args, szFormat);
87 vprintf(szFormat, args);
88 va_end(args);
89 }
90}
91
92
93//
94// Post message to send queue
95//
96
97void ClientSession::SendMessage(CSCPMessage *pMsg)
98{
99 m_pSendQueue->Put(pMsg->CreateMessage());
100}
101
102
103//
104// ReadThread()
105//
106
107void ClientSession::ReadThread(void)
108{
109 CSCP_MESSAGE *pRawMsg;
110 CSCPMessage *pMsg;
111 int iErr;
112
113 // Initialize raw message receiving function
114 RecvCSCPMessage(0, NULL, m_pMsgBuffer);
115
116 pRawMsg = (CSCP_MESSAGE *)malloc(65536);
117 while(1)
118 {
119 if ((iErr = RecvCSCPMessage(m_hSocket, pRawMsg, m_pMsgBuffer)) <= 0)
120 break;
121
122 // Check that actual received packet size is equal to encoded in packet
123 if (ntohs(pRawMsg->wSize) != iErr)
124 {
125 DebugPrintf("Actual message size doesn't match wSize value (%d,%d)\n", iErr, ntohs(pRawMsg->wSize));
126 continue; // Bad packet, wait for next
127 }
128
129 // Create message object from raw message
130 pMsg = new CSCPMessage(pRawMsg);
131 m_pMessageQueue->Put(pMsg);
132 }
133 if (iErr < 0)
134 WriteLog(MSG_SESSION_CLOSED, EVENTLOG_WARNING_TYPE, "e", WSAGetLastError());
135 free(pRawMsg);
136
137 // Notify other threads to exit
ecb7e1ee
VK
138 m_pSendQueue->Put(INVALID_POINTER_VALUE);
139 m_pMessageQueue->Put(INVALID_POINTER_VALUE);
140
141 // Wait for other threads to finish
142 ConditionWait(m_hCondWriteThreadStopped, INFINITE);
143 ConditionWait(m_hCondProcessingThreadStopped, INFINITE);
21e4b6f0
VK
144}
145
146
147//
148// WriteThread()
149//
150
151void ClientSession::WriteThread(void)
152{
153 CSCP_MESSAGE *pMsg;
154
155 while(1)
156 {
157 pMsg = (CSCP_MESSAGE *)m_pSendQueue->GetOrBlock();
ecb7e1ee 158 if (pMsg == INVALID_POINTER_VALUE) // Session termination indicator
21e4b6f0
VK
159 break;
160
161 if (send(m_hSocket, (const char *)pMsg, ntohs(pMsg->wSize), 0) <= 0)
162 {
7968a52d 163 MemFree(pMsg);
21e4b6f0
VK
164 break;
165 }
7968a52d 166 MemFree(pMsg);
21e4b6f0 167 }
ecb7e1ee 168 ConditionSet(m_hCondWriteThreadStopped);
21e4b6f0
VK
169}
170
171
172//
173// Message processing thread
174//
175
176void ClientSession::ProcessingThread(void)
177{
178 CSCPMessage *pMsg, *pReply;
179
180 while(1)
181 {
182 pMsg = (CSCPMessage *)m_pMessageQueue->GetOrBlock();
ecb7e1ee 183 if (pMsg == INVALID_POINTER_VALUE) // Session termination indicator
21e4b6f0
VK
184 break;
185
186 DebugPrintf("Received message with code %d\n", pMsg->GetCode());
187 if ((m_iState != STATE_AUTHENTICATED) && (pMsg->GetCode() != CMD_LOGIN))
188 {
189 delete pMsg;
190 continue;
191 }
192
193 switch(pMsg->GetCode())
194 {
195 case CMD_LOGIN:
196 if (m_iState != STATE_AUTHENTICATED)
197 {
0fdc2761 198 BYTE szPassword[SHA_DIGEST_LENGTH];
b54b2b11 199 char *pszLogin, szBuffer[16];
0fdc2761
VK
200
201 pszLogin = pMsg->GetVariableStr(VID_LOGIN_NAME);
202 pMsg->GetVariableBinary(VID_PASSWORD, szPassword, SHA_DIGEST_LENGTH);
21e4b6f0 203
0fdc2761 204 if (AuthenticateUser(pszLogin, szPassword, &m_dwUserId, &m_dwSystemAccess))
21e4b6f0
VK
205 m_iState = STATE_AUTHENTICATED;
206
b54b2b11
VK
207 if (m_iState == STATE_AUTHENTICATED)
208 {
209 sprintf(m_szUserName, "%s@%s", pszLogin, IpToStr(m_dwHostAddr, szBuffer));
210 }
211
7968a52d 212 MemFree(pszLogin);
21e4b6f0
VK
213
214 // Send reply
215 pReply = new CSCPMessage;
216 pReply->SetCode(CMD_LOGIN_RESP);
217 pReply->SetId(pMsg->GetId());
a5f8dbb8 218 pReply->SetVariable(VID_LOGIN_RESULT, (DWORD)(m_iState == STATE_AUTHENTICATED));
21e4b6f0
VK
219 SendMessage(pReply);
220 delete pReply;
221 }
222 else
223 {
224 }
225 break;
226 case CMD_GET_OBJECTS:
227 SendAllObjects();
228 break;
229 case CMD_GET_EVENTS:
230 SendAllEvents();
231 break;
232 case CMD_GET_CONFIG_VARLIST:
233 SendAllConfigVars();
234 break;
b54b2b11
VK
235 case CMD_OPEN_EVENT_DB:
236 SendEventDB(pMsg->GetId());
237 break;
238 case CMD_CLOSE_EVENT_DB:
239 if (m_dwFlags & CSF_EVENT_DB_LOCKED)
240 {
b8bad201
VK
241 // Check if event configuration DB has been modified
242 if (m_dwFlags & CSF_EVENT_DB_MODIFIED)
4d5a05a0 243 ReloadEvents();
b54b2b11
VK
244 UnlockComponent(CID_EVENT_DB);
245 m_dwFlags &= ~CSF_EVENT_DB_LOCKED;
246 }
3a5042fd
VK
247 // Send reply
248 pReply = new CSCPMessage;
249 pReply->SetCode(CMD_REQUEST_COMPLETED);
250 pReply->SetId(pMsg->GetId());
251 pReply->SetVariable(VID_RCC, RCC_SUCCESS);
252 SendMessage(pReply);
253 delete pReply;
b54b2b11 254 break;
605d2931
VK
255 case CMD_SET_EVENT_INFO:
256 SetEventInfo(pMsg);
257 break;
24156e90
VK
258 case CMD_MODIFY_OBJECT:
259 ModifyObject(pMsg);
260 break;
23a32988
VK
261 case CMD_LOAD_USER_DB:
262 SendUserDB(pMsg->GetId());
263 break;
21e4b6f0
VK
264 default:
265 break;
266 }
267 delete pMsg;
268 }
ecb7e1ee 269 ConditionSet(m_hCondProcessingThreadStopped);
21e4b6f0
VK
270}
271
272
b54b2b11
VK
273//
274// Send event configuration to client
275//
276
277void ClientSession::SendEventDB(DWORD dwRqId)
278{
279 DB_ASYNC_RESULT hResult;
280 CSCPMessage msg;
281 char szBuffer[1024];
282
283 // Prepare responce message
3a5042fd 284 msg.SetCode(CMD_REQUEST_COMPLETED);
b54b2b11
VK
285 msg.SetId(dwRqId);
286
b8bad201
VK
287 if (!CheckSysAccessRights(SYSTEM_ACCESS_VIEW_EVENT_DB))
288 {
289 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
290 SendMessage(&msg);
291 }
292 else if (!LockComponent(CID_EVENT_DB, m_dwIndex, m_szUserName, NULL, szBuffer))
b54b2b11
VK
293 {
294 msg.SetVariable(VID_RCC, RCC_COMPONENT_LOCKED);
295 msg.SetVariable(VID_LOCKED_BY, szBuffer);
296 SendMessage(&msg);
297 }
298 else
299 {
300 m_dwFlags |= CSF_EVENT_DB_LOCKED;
b8bad201 301 m_dwFlags &= ~CSF_EVENT_DB_MODIFIED;
b54b2b11
VK
302
303 msg.SetVariable(VID_RCC, RCC_SUCCESS);
304 SendMessage(&msg);
305 msg.DeleteAllVariables();
306
307 // Prepare data message
308 msg.SetCode(CMD_EVENT_DB_RECORD);
309 msg.SetId(dwRqId);
310
eafa21c7 311 hResult = DBAsyncSelect(g_hCoreDB, "SELECT event_id,name,severity,flags,message,description FROM events");
b54b2b11
VK
312 while(DBFetch(hResult))
313 {
314 msg.SetVariable(VID_EVENT_ID, DBGetFieldAsyncULong(hResult, 0));
315 msg.SetVariable(VID_NAME, DBGetFieldAsync(hResult, 1, szBuffer, 1024));
316 msg.SetVariable(VID_SEVERITY, DBGetFieldAsyncULong(hResult, 2));
317 msg.SetVariable(VID_FLAGS, DBGetFieldAsyncULong(hResult, 3));
318 msg.SetVariable(VID_MESSAGE, DBGetFieldAsync(hResult, 4, szBuffer, 1024));
319 msg.SetVariable(VID_DESCRIPTION, DBGetFieldAsync(hResult, 5, szBuffer, 1024));
320 SendMessage(&msg);
321 msg.DeleteAllVariables();
322 }
323 DBFreeAsyncResult(hResult);
3a5042fd
VK
324
325 // Send end-of-list indicator
326 msg.SetCode(CMD_EVENT_DB_EOF);
327 SendMessage(&msg);
b54b2b11
VK
328 }
329}
330
331
21e4b6f0
VK
332//
333// Send all objects to client
334//
335
336void ClientSession::SendAllObjects(void)
337{
338 DWORD i;
339 CSCPMessage msg;
340
53512272
VK
341 MutexLock(m_hMutexSendObjects, INFINITE);
342
21e4b6f0
VK
343 // Prepare message
344 msg.SetCode(CMD_OBJECT);
345
346 // Send objects, one per message
347 ObjectsGlobalLock();
348 for(i = 0; i < g_dwIdIndexSize; i++)
24156e90
VK
349 if (g_pIndexById[i].pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
350 {
351 g_pIndexById[i].pObject->CreateMessage(&msg);
352 SendMessage(&msg);
353 msg.DeleteAllVariables();
354 }
21e4b6f0
VK
355 ObjectsGlobalUnlock();
356
357 // Send end of list notification
358 msg.SetCode(CMD_OBJECT_LIST_END);
359 SendMessage(&msg);
53512272
VK
360
361 MutexUnlock(m_hMutexSendObjects);
21e4b6f0
VK
362}
363
364
365//
366// Send all events to client
367//
368
369void ClientSession::SendAllEvents(void)
370{
21e4b6f0 371 CSCPMessage msg;
20177e8e 372 DB_ASYNC_RESULT hResult;
9c36ef66 373 NXC_EVENT event;
21e4b6f0 374
62f5857f
VK
375 MutexLock(m_hMutexSendEvents, INFINITE);
376
21e4b6f0 377 // Retrieve events from database
fa1d3757 378 hResult = DBAsyncSelect(g_hCoreDB, "SELECT event_id,timestamp,source,severity,message FROM event_log ORDER BY timestamp");
21e4b6f0
VK
379 if (hResult != NULL)
380 {
381 // Send events, one per message
20177e8e 382 while(DBFetch(hResult))
21e4b6f0 383 {
20177e8e
VK
384 event.dwEventId = htonl(DBGetFieldAsyncULong(hResult, 0));
385 event.dwTimeStamp = htonl(DBGetFieldAsyncULong(hResult, 1));
386 event.dwSourceId = htonl(DBGetFieldAsyncULong(hResult, 2));
387 event.dwSeverity = htonl(DBGetFieldAsyncULong(hResult, 3));
388 DBGetFieldAsync(hResult, 4, event.szMessage, MAX_EVENT_MSG_LENGTH);
9c36ef66
VK
389 m_pSendQueue->Put(CreateRawCSCPMessage(CMD_EVENT, 0, sizeof(NXC_EVENT), &event, NULL));
390 }
20177e8e 391 DBFreeAsyncResult(hResult);
21e4b6f0
VK
392 }
393
394 // Send end of list notification
395 msg.SetCode(CMD_EVENT_LIST_END);
396 SendMessage(&msg);
62f5857f
VK
397
398 MutexUnlock(m_hMutexSendEvents);
21e4b6f0
VK
399}
400
401
402//
403// Send all configuration variables to client
404//
405
406void ClientSession::SendAllConfigVars(void)
407{
408 DWORD i, dwNumRecords;
409 CSCPMessage msg;
410 DB_RESULT hResult;
411
412 // Check user rights
413 if ((m_dwUserId != 0) && ((m_dwSystemAccess & SYSTEM_ACCESS_VIEW_CONFIG) == 0))
414 {
415 // Access denied
416 msg.SetCode(CMD_CONFIG_VARLIST_END);
a5f8dbb8 417 msg.SetVariable(VID_ERROR, (DWORD)1);
21e4b6f0
VK
418 SendMessage(&msg);
419 }
420 else
421 {
422 // Prepare message
423 msg.SetCode(CMD_CONFIG_VARIABLE);
424
425 // Retrieve configuration variables from database
426 hResult = DBSelect(g_hCoreDB, "SELECT name,value FROM config");
427 if (hResult != NULL)
428 {
429 // Send events, one per message
430 dwNumRecords = DBGetNumRows(hResult);
431 for(i = 0; i < dwNumRecords; i++)
432 {
a5f8dbb8
VK
433 msg.SetVariable(VID_NAME, DBGetField(hResult, i, 0));
434 msg.SetVariable(VID_VALUE, DBGetField(hResult, i, 1));
21e4b6f0
VK
435 SendMessage(&msg);
436 msg.DeleteAllVariables();
437 }
20177e8e 438 DBFreeResult(hResult);
21e4b6f0
VK
439 }
440
441 // Send end of list notification
442 msg.SetCode(CMD_CONFIG_VARLIST_END);
a5f8dbb8 443 msg.SetVariable(VID_ERROR, (DWORD)0);
21e4b6f0
VK
444 SendMessage(&msg);
445 }
446}
20177e8e
VK
447
448
449//
450// Close session forcibly
451//
452
453void ClientSession::Kill(void)
454{
455 // We shutdown socket connection, which will cause
456 // read thread to stop, and other threads will follow
457 shutdown(m_hSocket, 2);
458}
62f5857f
VK
459
460
461//
462// Handler for new events
463//
464
465void ClientSession::OnNewEvent(Event *pEvent)
466{
467 UPDATE_INFO *pUpdate;
468
469 pUpdate = (UPDATE_INFO *)malloc(sizeof(UPDATE_INFO));
470 pUpdate->dwCategory = INFO_CAT_EVENT;
471 pUpdate->pData = malloc(sizeof(NXC_EVENT));
472 pEvent->PrepareMessage((NXC_EVENT *)pUpdate->pData);
473 m_pUpdateQueue->Put(pUpdate);
474}
475
476
477//
478// Handler for object changes
479//
480
53512272 481void ClientSession::OnObjectChange(NetObj *pObject)
62f5857f 482{
53512272
VK
483 UPDATE_INFO *pUpdate;
484
24156e90
VK
485 if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
486 {
487 pUpdate = (UPDATE_INFO *)malloc(sizeof(UPDATE_INFO));
488 pUpdate->dwCategory = INFO_CAT_OBJECT_CHANGE;
489 pUpdate->pData = pObject;
490 m_pUpdateQueue->Put(pUpdate);
491 pObject->IncRefCount();
492 }
62f5857f
VK
493}
494
495
496//
497// Update processing thread
498//
499
500void ClientSession::UpdateThread(void)
501{
502 UPDATE_INFO *pUpdate;
53512272 503 CSCPMessage msg;
62f5857f
VK
504
505 while(1)
506 {
507 pUpdate = (UPDATE_INFO *)m_pUpdateQueue->GetOrBlock();
508 if (pUpdate == INVALID_POINTER_VALUE) // Session termination indicator
509 break;
510
511 switch(pUpdate->dwCategory)
512 {
513 case INFO_CAT_EVENT:
514 MutexLock(m_hMutexSendEvents, INFINITE);
515 m_pSendQueue->Put(CreateRawCSCPMessage(CMD_EVENT, 0, sizeof(NXC_EVENT), pUpdate->pData, NULL));
516 MutexUnlock(m_hMutexSendEvents);
517 free(pUpdate->pData);
518 break;
53512272
VK
519 case INFO_CAT_OBJECT_CHANGE:
520 MutexLock(m_hMutexSendObjects, INFINITE);
521 msg.SetId(0);
522 msg.SetCode(CMD_OBJECT_UPDATE);
523 ((NetObj *)pUpdate->pData)->CreateMessage(&msg);
524 SendMessage(&msg);
525 MutexUnlock(m_hMutexSendObjects);
526 msg.DeleteAllVariables();
527 ((NetObj *)pUpdate->pData)->DecRefCount();
528 break;
62f5857f
VK
529 default:
530 break;
531 }
532
533 free(pUpdate);
534 }
535 ConditionSet(m_hCondUpdateThreadStopped);
536}
83f0529c
VK
537
538
539//
540// Send notification message to server
541//
542
543void ClientSession::Notify(DWORD dwCode)
544{
545 CSCPMessage msg;
546
547 msg.SetCode(CMD_NOTIFY);
548 msg.SetVariable(VID_NOTIFICATION_CODE, dwCode);
549 SendMessage(&msg);
550}
605d2931
VK
551
552
553//
554// Update event template
555//
556
557void ClientSession::SetEventInfo(CSCPMessage *pRequest)
558{
559 CSCPMessage msg;
560
561 // Prepare reply message
562 msg.SetCode(CMD_REQUEST_COMPLETED);
563 msg.SetId(pRequest->GetId());
564
565 // Check if we have event configuration database opened
566 if (!(m_dwFlags & CSF_EVENT_DB_LOCKED))
567 {
568 msg.SetVariable(VID_RCC, RCC_OUT_OF_STATE_REQUEST);
569 }
570 else
571 {
572 // Check access rights
573 if (CheckSysAccessRights(SYSTEM_ACCESS_EDIT_EVENT_DB))
574 {
575 char szQuery[4096], *pszName, *pszMessage, *pszDescription;
576 DWORD dwEventId;
577 BOOL bEventExist = FALSE;
578 DB_RESULT hResult;
579
580 // Check if event with specific id exists
581 dwEventId = pRequest->GetVariableLong(VID_EVENT_ID);
582 sprintf(szQuery, "SELECT event_id FROM events WHERE event_id=%ld", dwEventId);
583 hResult = DBSelect(g_hCoreDB, szQuery);
584 if (hResult != NULL)
585 {
586 if (DBGetNumRows(hResult) > 0)
587 bEventExist = TRUE;
588 DBFreeResult(hResult);
589 }
590
b8bad201 591 // Prepare and execute SQL query
eafa21c7
VK
592 pszName = pRequest->GetVariableStr(VID_NAME);
593 pszMessage = pRequest->GetVariableStr(VID_MESSAGE);
594 pszDescription = pRequest->GetVariableStr(VID_DESCRIPTION);
605d2931
VK
595 if (bEventExist)
596 sprintf(szQuery, "UPDATE events SET name='%s',severity=%ld,flags=%ld,message='%s',description='%s' WHERE event_id=%ld",
eafa21c7 597 pszName, pRequest->GetVariableLong(VID_SEVERITY), pRequest->GetVariableLong(VID_FLAGS),
b8bad201 598 pszMessage, pszDescription, dwEventId);
605d2931 599 else
b8bad201 600 sprintf(szQuery, "INSERT INTO events SET event_id,name,severity,flags,message,description VALUES (%ld,'%s',%ld,%ld,'%s','%s')",
eafa21c7
VK
601 dwEventId, pszName, pRequest->GetVariableLong(VID_SEVERITY),
602 pRequest->GetVariableLong(VID_FLAGS), pszMessage, pszDescription);
605d2931 603 if (DBQuery(g_hCoreDB, szQuery))
b8bad201 604 {
605d2931 605 msg.SetVariable(VID_RCC, RCC_SUCCESS);
b8bad201
VK
606 m_dwFlags |= CSF_EVENT_DB_MODIFIED;
607 }
605d2931 608 else
b8bad201 609 {
605d2931 610 msg.SetVariable(VID_RCC, RCC_DB_FAILURE);
b8bad201 611 }
605d2931
VK
612
613 MemFree(pszName);
614 MemFree(pszMessage);
615 MemFree(pszDescription);
616 }
617 else
618 {
619 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
620 }
621 }
622
623 // Send responce
624 SendMessage(&msg);
625}
24156e90
VK
626
627
628//
629// Modify object
630//
631
632void ClientSession::ModifyObject(CSCPMessage *pRequest)
633{
634 DWORD dwObjectId, dwResult;
635 NetObj *pObject;
636 CSCPMessage msg;
637
638 // Prepare reply message
639 msg.SetCode(CMD_REQUEST_COMPLETED);
640 msg.SetId(pRequest->GetId());
641
642 dwObjectId = pRequest->GetVariableLong(VID_OBJECT_ID);
643 pObject = FindObjectById(dwObjectId);
644 if (pObject != NULL)
645 {
646 if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_MODIFY))
647 {
648 dwResult = pObject->ModifyFromMessage(pRequest);
649 msg.SetVariable(VID_RCC, dwResult);
650 }
651 else
652 {
653 msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
654 }
655 }
656 else
657 {
658 msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
659 }
660
661 // Send responce
662 SendMessage(&msg);
663}
23a32988
VK
664
665
666//
667// Send users database to client
668//
669
670void ClientSession::SendUserDB(DWORD dwRqId)
671{
672 CSCPMessage msg;
673 DWORD i, j, dwId;
674
675 // Prepare responce message
676 msg.SetCode(CMD_REQUEST_COMPLETED);
677 msg.SetId(dwRqId);
678 msg.SetVariable(VID_RCC, RCC_SUCCESS);
679 SendMessage(&msg);
680
681 // Send users
682 msg.SetCode(CMD_USER_DATA);
683 for(i = 0; i < g_dwNumUsers; i++)
684 {
685 msg.SetVariable(VID_USER_ID, g_pUserList[i].dwId);
686 msg.SetVariable(VID_USER_NAME, g_pUserList[i].szName);
687 msg.SetVariable(VID_USER_FLAGS, g_pUserList[i].wFlags);
688 msg.SetVariable(VID_USER_SYS_RIGHTS, g_pUserList[i].wSystemRights);
689 SendMessage(&msg);
690 msg.DeleteAllVariables();
691 }
692
693 // Send groups
694 msg.SetCode(CMD_GROUP_DATA);
695 for(i = 0; i < g_dwNumGroups; i++)
696 {
697 msg.SetVariable(VID_USER_ID, g_pGroupList[i].dwId);
698 msg.SetVariable(VID_USER_NAME, g_pGroupList[i].szName);
699 msg.SetVariable(VID_USER_FLAGS, g_pGroupList[i].wFlags);
700 msg.SetVariable(VID_USER_SYS_RIGHTS, g_pGroupList[i].wSystemRights);
701 msg.SetVariable(VID_NUM_MEMBERS, g_pGroupList[i].dwNumMembers);
702 for(j = 0, dwId = VID_GROUP_MEMBER_BASE; j < g_pGroupList[i].dwNumMembers; j++, dwId++)
703 msg.SetVariable(dwId, g_pGroupList[i].pMembers[j]);
704 SendMessage(&msg);
705 msg.DeleteAllVariables();
706 }
707
708 // Send end-of-database notification
709 msg.SetCode(CMD_USER_DB_EOF);
710 SendMessage(&msg);
711}