1 karl 1.61 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.13 //
|
3 karl 1.42 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
|
6 karl 1.32 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.42 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.45 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.61 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mike 1.13 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
15 mike 1.14 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
18 mike 1.13 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
|
20 venkat.puvvada 1.80 //
|
21 mike 1.14 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
22 mike 1.13 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
24 mike 1.14 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
27 mike 1.13 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 //%/////////////////////////////////////////////////////////////////////////////
33
34 #include "System.h"
35
|
36 mike 1.64 #include "Network.h"
|
37 mike 1.65 #include "Mutex.h"
|
38 mike 1.21 #include <fcntl.h>
|
39 mike 1.13 #include <sys/types.h>
40 #include <time.h>
41 #include <sys/timeb.h>
42 #include <io.h>
|
43 tony 1.33 #include <conio.h>
|
44 mike 1.13 #include <direct.h>
45 #include <sys/types.h>
|
46 mday 1.19 #include <windows.h>
|
47 kumpf 1.18 #include <process.h>
|
48 kumpf 1.38 #include <lm.h>
|
49 mreddy 1.76 #include <Pegasus/Common/Tracer.h>
|
50 mike 1.13
|
51 h.sterling 1.52 #define SECURITY_WIN32
52 #include <security.h>
|
53 h.sterling 1.50
|
54 kumpf 1.36 PEGASUS_NAMESPACE_BEGIN
55
|
56 se.gupta 1.41 #define PEGASUS_ACCESS_EXISTS 0
57 #define PEGASUS_ACCESS_WRITE 2
58 #define PEGASUS_ACCESS_READ 4
59 #define PEGASUS_ACCESS_READ_AND_WRITE 6
|
60 mike 1.13
|
61 tony 1.33 #define PW_BUFF_LEN 65
62
|
63 mike 1.13 void System::getCurrentTime(Uint32& seconds, Uint32& milliseconds)
64 {
65 FILETIME ft;
66 GetSystemTimeAsFileTime(&ft);
67 ULARGE_INTEGER largeInt = { ft.dwLowDateTime, ft.dwHighDateTime };
68 largeInt.QuadPart -= 0x19db1ded53e8000;
69 seconds = long(largeInt.QuadPart / (10000 * 1000));
70 milliseconds = long((largeInt.QuadPart % (10000 * 1000)) / 10);
|
71 karl 1.23 // This is a real hack. Added the following line after timevalue was
72 // corrected and this apparently wrong. ks 7 apri 2002
73 milliseconds = milliseconds / 1000;
|
74 mike 1.13 }
75
|
76 jim.wunderlich 1.60 void System::getCurrentTimeUsec(Uint32& seconds, Uint32& microseconds)
77 {
78 FILETIME ft;
79 GetSystemTimeAsFileTime(&ft);
80 ULARGE_INTEGER largeInt = { ft.dwLowDateTime, ft.dwHighDateTime };
81 largeInt.QuadPart -= 0x19db1ded53e8000;
82 seconds = long(largeInt.QuadPart / (10000 * 1000));
83 microseconds = long((largeInt.QuadPart % (10000 * 1000)) / 10);
84 }
85
|
86 mike 1.13 String System::getCurrentASCIITime()
87 {
88 char tmpbuf[128];
|
89 kumpf 1.28 _strdate( tmpbuf );
90 String date = tmpbuf;
|
91 mike 1.13 _strtime( tmpbuf );
|
92 kumpf 1.28 date.append("-");
93 date.append(tmpbuf);
94 return date;
|
95 mike 1.13 }
96
97 void System::sleep(Uint32 seconds)
98 {
99 Sleep(seconds * 1000);
100 }
101
102 Boolean System::exists(const char* path)
103 {
|
104 se.gupta 1.41 return _access(path, PEGASUS_ACCESS_EXISTS) == 0;
|
105 mike 1.13 }
106
107 Boolean System::canRead(const char* path)
108 {
|
109 se.gupta 1.41 return _access(path, PEGASUS_ACCESS_READ) == 0;
|
110 mike 1.13 }
111
112 Boolean System::canWrite(const char* path)
113 {
|
114 se.gupta 1.41 return _access(path, PEGASUS_ACCESS_WRITE) == 0;
|
115 mike 1.13 }
116
117 Boolean System::getCurrentDirectory(char* path, Uint32 size)
118 {
119 return GetCurrentDirectory(size, path) != 0;
120 }
121
122 Boolean System::isDirectory(const char* path)
123 {
124 struct stat st;
125
126 if (stat(path, &st) != 0)
|
127 david.dillard 1.49 return false;
|
128 mike 1.13
129 return (st.st_mode & _S_IFDIR) != 0;
130 }
131
132 Boolean System::changeDirectory(const char* path)
133 {
134 return chdir(path) == 0;
135 }
136
137 Boolean System::makeDirectory(const char* path)
138 {
139 return _mkdir(path) == 0;
140 }
141
142 Boolean System::getFileSize(const char* path, Uint32& size)
143 {
144 struct stat st;
145
146 if (stat(path, &st) != 0)
|
147 david.dillard 1.49 return false;
|
148 mike 1.13
149 size = st.st_size;
150 return true;
151 }
152
153 Boolean System::removeDirectory(const char* path)
154 {
|
155 david.dillard 1.49 return rmdir(path) == 0;
|
156 mike 1.13 }
157
158 Boolean System::removeFile(const char* path)
159 {
|
160 david.dillard 1.49 return unlink(path) == 0;
|
161 mike 1.13 }
162
163 Boolean System::renameFile(const char* oldPath, const char* newPath)
164 {
165 return rename(oldPath, newPath) == 0;
166 }
167
|
168 kumpf 1.22 String System::getSystemCreationClassName ()
169 {
|
170 karl 1.39 return "CIM_ComputerSystem";
|
171 kumpf 1.22 }
172
|
173 kumpf 1.16 Uint32 System::lookupPort(
174 const char * serviceName,
175 Uint32 defaultPort)
176 {
177 Uint32 localPort;
178
179 struct servent *serv;
180
181 //
|
182 david.dillard 1.48 // Get the port number.
|
183 kumpf 1.16 //
|
184 david.dillard 1.49 if ( (serv = getservbyname(serviceName, TCP)) != NULL )
|
185 kumpf 1.16 {
|
186 david.dillard 1.48 localPort = ntohs(serv->s_port);
|
187 kumpf 1.16 }
188 else
189 {
190 localPort = defaultPort;
191 }
192
193 return localPort;
|
194 mike 1.13 }
195
|
196 mike 1.14 String System::getPassword(const char* prompt)
197 {
|
198 david.dillard 1.49 char password[PW_BUFF_LEN] = {0};
199 int num_chars = 0;
200 int ch;
|
201 tony 1.33
|
202 david.dillard 1.49 fputs(prompt, stderr);
|
203 tony 1.33
|
204 david.dillard 1.49 while ((ch = _getch()) != '\r' &&
205 num_chars < PW_BUFF_LEN)
|
206 tony 1.33 {
|
207 david.dillard 1.49 // EOF
208 if (ch == EOF)
|
209 tony 1.33 {
|
210 david.dillard 1.49 fputs("[EOF]\n", stderr);
211 return String::EMPTY;
|
212 tony 1.33 }
|
213 david.dillard 1.49 // Backspace or Delete
214 else if ((ch == '\b' || ch == 127) &&
215 num_chars > 0)
|
216 tony 1.33 {
|
217 david.dillard 1.49 password[--num_chars] = '\0';
218 fputs("\b \b", stderr);
|
219 tony 1.33 }
|
220 david.dillard 1.49 // CTRL+C
221 else if (ch == 3)
|
222 tony 1.33 {
|
223 david.dillard 1.49 // _getch() does not catch CTRL+C
224 fputs("^C\n", stderr);
225 exit(-1);
|
226 tony 1.33 }
|
227 david.dillard 1.49 // CTRL+Z
228 else if (ch == 26)
|
229 tony 1.33 {
|
230 david.dillard 1.49 fputs("^Z\n", stderr);
231 return String::EMPTY;
|
232 tony 1.33 }
|
233 david.dillard 1.49 // Esc
234 else if (ch == 27)
|
235 tony 1.33 {
|
236 david.dillard 1.49 fputc('\n', stderr);
237 fputs(prompt, stderr);
238 num_chars = 0;
239 }
240 // Function keys (0 or E0) are a guards for a Function key codes
241 else if (ch == 0 || ch == 0xE0)
242 {
243 ch = (ch << 4) | _getch();
244 // Handle DELETE, left arrow, keypad DEL, and keypad left arrow
245 if ((ch == 0xE53 || ch == 0xE4B || ch == 0x053 || ch == 0x04b) &&
246 num_chars > 0)
|
247 tony 1.33 {
|
248 david.dillard 1.49 password[--num_chars] = '\0';
249 fputs("\b \b", stderr);
|
250 tony 1.33 }
|
251 david.dillard 1.49 else
|
252 tony 1.33 {
|
253 david.dillard 1.49 fputc('\a', stderr);
|
254 tony 1.33 }
255 }
|
256 david.dillard 1.49 else if ((num_chars < sizeof(password) - 1) &&
257 !iscntrl(((unsigned char)(ch))))
|
258 tony 1.33 {
|
259 david.dillard 1.49 password[num_chars++] = ch;
260 fputc('*', stderr);
|
261 tony 1.33 }
|
262 david.dillard 1.49 else
|
263 tony 1.33 {
|
264 david.dillard 1.49 fputc('\a', stderr);
|
265 tony 1.33 }
266 }
|
267 mike 1.14
|
268 david.dillard 1.49 fputc('\n', stderr);
269 password[num_chars] = '\0';
|
270 tony 1.33
|
271 david.dillard 1.49 return String(password);
|
272 mike 1.14 }
273
|
274 kumpf 1.24 String System::getEffectiveUserName()
|
275 mike 1.14 {
|
276 h.sterling 1.52 #if (_MSC_VER >= 1300) || defined(PEGASUS_WINDOWS_SDK_HOME)
277
|
278 kumpf 1.70 //Bug 3076 fix
279 wchar_t fullUserName[UNLEN+1];
280 DWORD userNameSize = sizeof(fullUserName)/sizeof(fullUserName[0]);
281 wchar_t computerName[MAX_COMPUTERNAME_LENGTH+1];
282 DWORD computerNameSize = sizeof(computerName)/sizeof(computerName[0]);
283 wchar_t userName[UNLEN+1];
|
284 h.sterling 1.57 wchar_t userDomain[UNLEN+1];
|
285 kumpf 1.70 String userId;
286
287 if (!GetUserNameExW(NameSamCompatible, fullUserName, &userNameSize))
288 {
289 return String();
290 }
|
291 h.sterling 1.50
|
292 kumpf 1.70 wchar_t* index = wcschr(fullUserName, '\\');
293 *index = 0;
294 wcscpy(userDomain, fullUserName);
295 wcscpy(userName, index + 1);
296
297 //The above function will return the system name as the domain if
298 //the user is not on a real domain. Strip this out so that the rest of
299 //our windows user functions work. What if the system name and the domain
300 //name are the same?
|
301 h.sterling 1.57 GetComputerNameW(computerName, &computerNameSize);
|
302 kumpf 1.70
303 if (wcscmp(computerName, userDomain) != 0)
304 {
|
305 h.sterling 1.57 //userId.append(userDomain);
|
306 a.dunfey 1.72 Uint32 n = (Uint32)wcslen(userDomain);
|
307 kumpf 1.70 for (unsigned long i = 0; i < n; i++)
|
308 h.sterling 1.57 {
309 userId.append(Char16(userDomain[i]));
310 }
|
311 kumpf 1.70 userId.append("\\");
312 //userId.append(userName);
|
313 a.dunfey 1.72 n = (Uint32)wcslen(userName);
|
314 kumpf 1.70 for (unsigned long i = 0; i < n; i++)
|
315 h.sterling 1.57 {
316 userId.append(Char16(userName[i]));
317 }
318
|
319 kumpf 1.70 }
320 else
321 {
322 //userId.append(userName);
|
323 a.dunfey 1.72 Uint32 n = (Uint32)wcslen(userName);
|
324 kumpf 1.70 for (unsigned long i = 0; i < n; i++)
|
325 h.sterling 1.57 {
326 userId.append(Char16(userName[i]));
327 }
328
|
329 kumpf 1.70 }
|
330 h.sterling 1.50
|
331 kumpf 1.70 return userId;
|
332 h.sterling 1.52
333 #else //original getEffectiveUserName function
|
334 kumpf 1.70
|
335 david.dillard 1.49 int retcode = 0;
|
336 tony 1.33
|
337 david.dillard 1.49 // UNLEN (256) is the limit, not including null
|
338 h.sterling 1.57 wchar_t pUserName[256+1] = {0};
|
339 h.sterling 1.59 DWORD nSize = sizeof(pUserName)/sizeof(pUserName[0]);
|
340 mike 1.14
|
341 h.sterling 1.57 retcode = GetUserNameW(pUserName, &nSize);
|
342 david.dillard 1.49 if (retcode == 0)
|
343 tony 1.33 {
|
344 david.dillard 1.49 // zero is failure
345 return String();
|
346 tony 1.33 }
|
347 h.sterling 1.58 String userId;
|
348 h.sterling 1.57 Uint32 n = wcslen(pUserName);
|
349 kumpf 1.70 for (unsigned long i = 0; i < n; i++)
|
350 h.sterling 1.57 {
351 userId.append(Char16(pUserName[i]));
352 }
353
354 return userId;
|
355 h.sterling 1.52 #endif
|
356 mike 1.14 }
357
358 String System::encryptPassword(const char* password, const char* salt)
359 {
|
360 david.dillard 1.49 BYTE pbBuffer[PW_BUFF_LEN] = {0};
361 DWORD dwByteCount;
362 char pcSalt[3] = {0};
363
364 strncpy(pcSalt, salt, 2);
|
365 a.dunfey 1.72 dwByteCount = (DWORD)strlen(password);
|
366 david.dillard 1.49 memcpy(pbBuffer, password, dwByteCount);
367 for (DWORD i=0; (i<dwByteCount) || (i>=PW_BUFF_LEN); i++)
368 (i%2 == 0) ? pbBuffer[i] ^= pcSalt[1] : pbBuffer[i] ^= pcSalt[0];
369
370 return String(pcSalt) + String((char *)pbBuffer);
|
371 mike 1.14 }
372
|
373 a.dunfey 1.62 String processUserName;
374 Mutex processUserNameMut;
375
|
376 kumpf 1.26 Boolean System::isSystemUser(const char* userName)
|
377 mike 1.14 {
|
378 kumpf 1.70 if (processUserName.size() == 0)
|
379 a.dunfey 1.62 {
380 // Lock and recheck the processUserName length in case two threads
381 // enter this block simultaneously
382 AutoMutex mut(processUserNameMut);
|
383 kumpf 1.70 if (processUserName.size() == 0)
|
384 a.dunfey 1.62 {
385 processUserName = getEffectiveUserName();
386 }
387 }
|
388 kumpf 1.70 if (processUserName == userName)
|
389 a.dunfey 1.62 {
390 return true;
391 }
392
|
393 h.sterling 1.46 Boolean isSystemUser = false;
394
395 char mUserName[UNLEN+1];
396 char mDomainName[UNLEN+1];
|
397 david.dillard 1.51 char tUserName[UNLEN+1];
|
398 h.sterling 1.46 wchar_t wUserName[UNLEN+1];
399 wchar_t wDomainName[UNLEN+1];
400 char* pbs;
401 bool usingDomain = false;
|
402 david.dillard 1.49
|
403 h.sterling 1.46 LPBYTE pComputerName=NULL;
404 DWORD dwLevel = 1;
405 LPUSER_INFO_1 pUserInfo = NULL;
406 NET_API_STATUS nStatus = NULL;
407
|
408 kumpf 1.70 // Make a copy of the specified username, it cannot be used directly
409 // because it's declared as const and strchr() may modify the string.
|
410 david.dillard 1.51 strncpy(tUserName, userName, sizeof(tUserName) - 1);
|
411 david.dillard 1.54 tUserName[sizeof(tUserName)- 1] = '\0';
|
412 david.dillard 1.51
|
413 david.dillard 1.49 //separate the domain and user name if both are present.
|
414 david.dillard 1.51 if (NULL != (pbs = strchr(tUserName, '\\')))
|
415 h.sterling 1.46 {
416 *pbs = '\0';
|
417 david.dillard 1.51 strcpy(mDomainName, tUserName);
|
418 h.sterling 1.46 strcpy(mUserName, pbs+1);
419 usingDomain = true;
420
|
421 kumpf 1.70 }
422 else if ((NULL != (pbs = (strchr(tUserName, '@')))) ||
423 (NULL != (pbs = (strchr(tUserName, '.')))))
|
424 h.sterling 1.46 {
425 *pbs = '\0';
426 strcpy(mDomainName, pbs+1);
|
427 david.dillard 1.51 strcpy(mUserName, tUserName);
|
428 h.sterling 1.46 usingDomain = true;
|
429 david.dillard 1.49
|
430 kumpf 1.70 }
431 else
|
432 h.sterling 1.46 {
433 strcpy(mDomainName, ".");
|
434 david.dillard 1.51 strcpy(mUserName, tUserName);
|
435 h.sterling 1.46 }
436
437 //convert domain name to unicode
|
438 kumpf 1.70 if (!MultiByteToWideChar(
|
439 a.dunfey 1.72 CP_ACP, 0, mDomainName, -1, wDomainName,
440 (int)(strlen(mDomainName) + 1)))
|
441 h.sterling 1.46 {
442 return false;
443 }
444
445 //convert username to unicode
|
446 kumpf 1.70 if (!MultiByteToWideChar(
|
447 a.dunfey 1.72 CP_ACP, 0, mUserName, -1, wUserName, (int)(strlen(mUserName) + 1)))
|
448 h.sterling 1.46 {
449 return false;
450 }
|
451 david.dillard 1.49
|
452 h.sterling 1.46 if (usingDomain)
453 {
454 //get domain controller
455 DWORD rc = NetGetDCName(NULL, wDomainName, &pComputerName);
|
456 david.dillard 1.49 if (rc == NERR_Success)
|
457 h.sterling 1.46 {
|
458 kumpf 1.70 // this is automatically prefixed with "\\"
459 wcscpy(wDomainName, (LPWSTR) pComputerName);
|
460 david.dillard 1.49 }
|
461 h.sterling 1.46 /*
462 else
463 {
464 // failover
|
465 kumpf 1.70 // ATTN: This is commented out until there is resolution on
466 // Bugzilla 2236. -hns 2/2005
|
467 h.sterling 1.46 // This needs to be more thoroughly tested when we uncomment it out.
|
468 david.dillard 1.49
|
469 h.sterling 1.46 PDOMAIN_CONTROLLER_INFO DomainControllerInfo = NULL;
470
471 //this function does not take wide strings
472 rc = DsGetDcName(NULL,
473 mDomainName,
474 NULL,
475 NULL,
|
476 kumpf 1.70 //not sure what flags we want here
477 DS_DIRECTORY_SERVICE_REQUIRED,
|
478 h.sterling 1.46 &DomainControllerInfo);
479
480 if (rc == ERROR_SUCCESS && DomainControllerInfo)
481 {
482 strcpy(mDomainName, DomainControllerInfo->DomainName);
483 NetApiBufferFree(DomainControllerInfo);
484
|
485 kumpf 1.70 if (!MultiByteToWideChar(
486 CP_ACP, 0, mDomainName, -1, wDomainName,
487 strlen(mDomainName) + 1))
|
488 h.sterling 1.46 {
489 return false;
490 }
491 }
492 }
493 */
494 }
495
496 //get user info
497 nStatus = NetUserGetInfo(wDomainName,
498 wUserName,
499 dwLevel,
500 (LPBYTE *)&pUserInfo);
501
502 if (nStatus == NERR_Success)
503 {
504 isSystemUser = true;
505 }
|
506 david.dillard 1.49
507 if (pComputerName != NULL)
|
508 h.sterling 1.46 {
509 NetApiBufferFree(pComputerName);
510 }
511
512 if (pUserInfo != NULL)
513 {
514 NetApiBufferFree(pUserInfo);
515 }
516
517 return isSystemUser;
|
518 mike 1.14 }
519
|
520 h.sterling 1.46
|
521 david.dillard 1.43 Boolean System::isPrivilegedUser(const String& userName)
|
522 mike 1.14 {
|
523 h.sterling 1.46 Boolean isPrivileged = false;
524
525 char mUserName[UNLEN+1];
526 char mDomainName[UNLEN+1];
527 wchar_t wUserName[UNLEN+1];
528 wchar_t wDomainName[UNLEN+1];
529 char* pbs;
530 char userStr[UNLEN+1];
531 bool usingDomain = false;
532
533 LPBYTE pComputerName=NULL;
534 DWORD dwLevel = 1;
535 LPUSER_INFO_1 pUserInfo = NULL;
536 NET_API_STATUS nStatus = NULL;
537
538 //get the username in the correct format
539 strcpy(userStr, (const char*)userName.getCString());
540
|
541 david.dillard 1.49 //separate the domain and user name if both are present.
|
542 h.sterling 1.46 if (NULL != (pbs = strchr(userStr, '\\')))
543 {
544 *pbs = '\0';
545 strcpy(mDomainName, userStr);
546 strcpy(mUserName, pbs+1);
547 usingDomain = true;
548
|
549 kumpf 1.70 }
550 else if ((NULL != (pbs = (strchr(userStr, '@')))) ||
551 (NULL != (pbs = (strchr(userStr, '.')))))
|
552 h.sterling 1.46 {
553 *pbs = '\0';
554 strcpy(mDomainName, pbs+1);
555 strcpy(mUserName, userStr);
556 usingDomain = true;
|
557 david.dillard 1.49
|
558 kumpf 1.70 }
559 else
|
560 h.sterling 1.46 {
561 strcpy(mDomainName, ".");
562 strcpy(mUserName, userStr);
563 }
564
565 //convert domain name to unicode
|
566 kumpf 1.70 if (!MultiByteToWideChar(
|
567 a.dunfey 1.72 CP_ACP, 0, mDomainName, -1, wDomainName,
568 (int)(strlen(mDomainName) + 1)))
|
569 h.sterling 1.46 {
570 return false;
571 }
572
573 //convert username to unicode
|
574 kumpf 1.70 if (!MultiByteToWideChar(
|
575 a.dunfey 1.72 CP_ACP, 0, mUserName, -1, wUserName, (int)(strlen(mUserName) + 1)))
|
576 h.sterling 1.46 {
577 return false;
578 }
579
580 if (usingDomain)
581 {
582 //get domain controller
583 DWORD rc = NetGetDCName(NULL, wDomainName, &pComputerName);
|
584 david.dillard 1.49 if (rc == NERR_Success)
|
585 h.sterling 1.46 {
|
586 kumpf 1.70 // this is automatically prefixed with "\\"
587 wcscpy(wDomainName, (LPWSTR) pComputerName);
|
588 david.dillard 1.49 }
|
589 h.sterling 1.46 /*
590 else
591 {
592 // failover
|
593 kumpf 1.70 // ATTN: This is commented out until there is resolution on
594 // Bugzilla 2236. -hns 2/2005
|
595 h.sterling 1.46 // This needs to be more thoroughly tested when we uncomment it out.
|
596 david.dillard 1.49
|
597 h.sterling 1.46 PDOMAIN_CONTROLLER_INFO DomainControllerInfo = NULL;
598
599 //this function does not take wide strings
600 rc = DsGetDcName(NULL,
601 mDomainName,
602 NULL,
603 NULL,
|
604 kumpf 1.70 // not sure what flags we want here
605 DS_DIRECTORY_SERVICE_REQUIRED,
|
606 h.sterling 1.46 &DomainControllerInfo);
607
608 if (rc == ERROR_SUCCESS && DomainControllerInfo)
609 {
610 strcpy(mDomainName, DomainControllerInfo->DomainName);
611 NetApiBufferFree(DomainControllerInfo);
612
|
613 kumpf 1.70 if (!MultiByteToWideChar(
614 CP_ACP, 0, mDomainName, -1, wDomainName,
615 strlen(mDomainName) + 1))
|
616 h.sterling 1.46 {
617 return false;
618 }
619 }
620 }
621 */
622 }
623
624 //get privileges
625 nStatus = NetUserGetInfo(wDomainName,
626 wUserName,
627 dwLevel,
628 (LPBYTE *)&pUserInfo);
629
|
630 david.dillard 1.49 if ((nStatus == NERR_Success) &&
|
631 h.sterling 1.46 (pUserInfo != NULL) &&
632 (pUserInfo->usri1_priv == USER_PRIV_ADMIN))
633 {
634 isPrivileged = true;
635 }
636
|
637 david.dillard 1.49 if (pComputerName != NULL)
|
638 h.sterling 1.46 {
639 NetApiBufferFree(pComputerName);
640 }
641
642 if (pUserInfo != NULL)
643 {
644 NetApiBufferFree(pUserInfo);
645 }
646
647 return isPrivileged;
|
648 mike 1.14 }
|
649 kumpf 1.20
650 String System::getPrivilegedUserName()
651 {
652 // ATTN-NB-03-20000304: Implement better way to get the privileged
653 // user on the system.
654
|
655 kumpf 1.70 return String("Administrator");
|
656 kumpf 1.20 }
|
657 kumpf 1.37
658 Boolean System::isGroupMember(const char* userName, const char* groupName)
659 {
|
660 david.dillard 1.49 Boolean retVal = false;
|
661 kumpf 1.38
|
662 david.dillard 1.49 LPLOCALGROUP_USERS_INFO_0 pBuf = NULL;
663 DWORD dwLevel = 0;
664 DWORD dwFlags = LG_INCLUDE_INDIRECT ;
665 DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH;
666 DWORD dwEntriesRead = 0;
667 DWORD dwTotalEntries = 0;
668 NET_API_STATUS nStatus;
|
669 ms.aruran 1.71 wchar_t wcUserName[UNLEN+1];
670 wchar_t wcGroupName[UNLEN+1];
|
671 david.dillard 1.49
|
672 ms.aruran 1.71 //Convert user name to unicode
|
673 venkat.puvvada 1.80 if (!MultiByteToWideChar(CP_ACP,0,userName, -1, wcUserName,
|
674 ms.aruran 1.71 strlen(userName)+1))
675 {
676 return false;
677 }
|
678 venkat.puvvada 1.80
|
679 ms.aruran 1.71 //Convert group name to unicode
|
680 venkat.puvvada 1.80 if (!MultiByteToWideChar(CP_ACP, 0, groupName, -1, wcGroupName,
|
681 ms.aruran 1.71 strlen(groupName)+1))
682 {
683 return false;
684 }
|
685 david.dillard 1.49
686 //
687 // Call the NetUserGetLocalGroups function
688 // specifying information level 0.
689 //
690 // The LG_INCLUDE_INDIRECT flag specifies that the
691 // function should also return the names of the local
692 // groups in which the user is indirectly a member.
693 //
|
694 ms.aruran 1.71 nStatus = NetUserGetLocalGroups(
|
695 venkat.puvvada 1.80 NULL,
|
696 ms.aruran 1.71 (LPCWSTR)wcUserName,
697 dwLevel,
698 dwFlags,
699 (LPBYTE *) &pBuf,
700 dwPrefMaxLen,
701 &dwEntriesRead,
702 &dwTotalEntries);
|
703 kumpf 1.38
|
704 david.dillard 1.49 //
705 // If the call succeeds,
706 //
707 if (nStatus == NERR_Success)
708 {
709 LPLOCALGROUP_USERS_INFO_0 pTmpBuf;
710 DWORD i;
711 DWORD dwTotalCount = 0;
712
713 if ((pTmpBuf = pBuf) != NULL)
714 {
|
715 kumpf 1.38 //
|
716 david.dillard 1.49 // Loop through the local groups that the user belongs
717 // and find the matching group name.
|
718 kumpf 1.38 //
|
719 david.dillard 1.49 for (i = 0; i < dwEntriesRead; i++)
|
720 kumpf 1.38 {
|
721 david.dillard 1.49 //
722 // Compare the user's group name to groupName.
723 //
|
724 ms.aruran 1.71
725 if (wcscmp(pTmpBuf->lgrui0_name, wcGroupName) == 0)
|
726 david.dillard 1.49 {
727 // User is a member of the group.
728 retVal = true;
729 break;
730 }
731
732 pTmpBuf++;
733 dwTotalCount++;
|
734 kumpf 1.38 }
|
735 david.dillard 1.49 }
736 }
|
737 kumpf 1.38
|
738 david.dillard 1.49 //
739 // Free the allocated memory.
740 //
741 if (pBuf != NULL)
742 NetApiBufferFree(pBuf);
743
744 //
745 // If the given user and group are not found in the local group
746 // then try on the global groups.
747 //
748 if (!retVal)
749 {
750 LPGROUP_USERS_INFO_0 pBuf = NULL;
751 dwLevel = 0;
752 dwPrefMaxLen = MAX_PREFERRED_LENGTH;
753 dwEntriesRead = 0;
754 dwTotalEntries = 0;
755
756 //
757 // Call the NetUserGetGroups function, specifying level 0.
758 //
|
759 ms.aruran 1.71 nStatus = NetUserGetGroups(
760 NULL,
761 (LPCWSTR)wcUserName,
762 dwLevel,
763 (LPBYTE*)&pBuf,
764 dwPrefMaxLen,
765 &dwEntriesRead,
|
766 venkat.puvvada 1.80 &dwTotalEntries);
|
767 ms.aruran 1.71
|
768 david.dillard 1.49 //
769 // If the call succeeds,
770 //
771 if (nStatus == NERR_Success)
772 {
773 LPGROUP_USERS_INFO_0 pTmpBuf;
774 DWORD i;
775 DWORD dwTotalCount = 0;
776
777 if ((pTmpBuf = pBuf) != NULL)
778 {
|
779 kumpf 1.38 //
|
780 david.dillard 1.49 // Loop through the global groups to which the user belongs
781 // and find the matching group name.
|
782 kumpf 1.38 //
|
783 david.dillard 1.49 for (i = 0; i < dwEntriesRead; i++)
|
784 kumpf 1.38 {
|
785 david.dillard 1.49 //
786 // Compare the user's group name to groupName.
787 //
|
788 ms.aruran 1.71 if (wcscmp(pTmpBuf->grui0_name, wcGroupName) == 0)
|
789 david.dillard 1.49 {
790 // User is a member of the group.
791 retVal = true;
792 break;
793 }
794
795 pTmpBuf++;
796 dwTotalCount++;
|
797 kumpf 1.38 }
|
798 david.dillard 1.49 }
799 }
|
800 kumpf 1.38
|
801 david.dillard 1.49 //
802 // Free the allocated buffer.
803 //
804 if (pBuf != NULL)
805 NetApiBufferFree(pBuf);
806 }
|
807 kumpf 1.38
|
808 david.dillard 1.49 return retVal;
|
809 kumpf 1.37 }
|
810 kumpf 1.44
|
811 kumpf 1.63 Boolean System::lookupUserId(
812 const char* userName,
813 PEGASUS_UID_T& uid,
814 PEGASUS_GID_T& gid)
815 {
816 // ATTN: Implement this method to look up the specified user
817 return false;
818 }
819
|
820 kumpf 1.75 Boolean System::changeUserContext_SingleThreaded(
821 const char* userName,
|
822 kumpf 1.63 const PEGASUS_UID_T& uid,
823 const PEGASUS_GID_T& gid)
|
824 kumpf 1.44 {
825 // ATTN: Implement this method to change the process user context to the
826 // specified user
827 return false;
828 }
829
|
830 kumpf 1.15 Uint32 System::getPID()
831 {
|
832 kumpf 1.18 return _getpid();
|
833 mike 1.21 }
834
835 Boolean System::truncateFile(
|
836 david.dillard 1.49 const char* path,
|
837 mike 1.21 size_t newSize)
838 {
|
839 david.dillard 1.49
840 Boolean rv = false;
|
841 mike 1.21 int fd = open(path, O_RDWR);
|
842 david.dillard 1.49 if (fd != -1)
843 {
|
844 a.dunfey 1.72 if (chsize(fd, (long)newSize) == 0)
|
845 david.dillard 1.49 {
846 rv = true;
847 }
|
848 mike 1.21
|
849 david.dillard 1.49 close(fd);
850 }
|
851 mike 1.21
|
852 david.dillard 1.49 return rv;
|
853 kumpf 1.15 }
854
|
855 tony 1.27 // Is absolute path?
856 Boolean System::is_absolute_path(const char *path)
857 {
|
858 david.dillard 1.49 char full[_MAX_PATH];
859 char path_slash[_MAX_PATH];
860 char *p;
861
862 strncpy(path_slash, path, _MAX_PATH);
863 path_slash[_MAX_PATH-1] = '\0';
864
|
865 kumpf 1.70 for (p = path_slash; p < path_slash + strlen(path_slash); p++)
|
866 david.dillard 1.49 if (*p == '/')
867 *p = '\\';
868
|
869 kumpf 1.70 return (strcasecmp(
870 _fullpath(full, path_slash, _MAX_PATH), path_slash) == 0);
|
871 kumpf 1.34 }
872
873 // Changes file permissions on the given file.
874 Boolean System::changeFilePermissions(const char* path, mode_t mode)
875 {
876 // ATTN: File permissions are not currently defined in Windows
877 return true;
|
878 tony 1.27 }
|
879 david 1.29
|
880 kumpf 1.44 Boolean System::verifyFileOwnership(const char* path)
881 {
882 // ATTN: Implement this to check that the owner of the specified file is
883 // the same as the effective user for this process.
884 return true;
885 }
886
|
887 kumpf 1.53 void System::syslog(const String& ident, Uint32 severity, const char* message)
|
888 david 1.29 {
|
889 kumpf 1.53 // Not implemented
|
890 david 1.29 }
891
|
892 marek 1.69 void System::openlog(const char *ident, int logopt, int facility)
893 {
894 // Not implemented
895 }
896
897 void System::closelog()
898 {
899 // Not implemented
900 }
901
902
903
|
904 david 1.29 // System ID constants for Logger::put and Logger::trace
905 const String System::CIMSERVER = "cimserver"; // Server system ID
|
906 tony 1.27
|
907 marek 1.68 // check if a given IP address is defined on the local network interfaces
908 Boolean System::isIpOnNetworkInterface(Uint32 inIP)
909 {
910 SOCKET sock;
911 int interfaces = 0;
912 int errcode;
913
914 if ( SOCKET_ERROR != ( sock = WSASocket(AF_INET,
915 SOCK_RAW, 0, NULL, 0, 0) ) )
916 {
917 unsigned long *bytes_returned=0;
918 char *output_buf = (char *)calloc(1, 256);
919 int buf_size = 256;
|
920 kumpf 1.70
|
921 marek 1.68 if ( 0 == (errcode = WSAIoctl(sock,
922 SIO_ADDRESS_LIST_QUERY,
923 NULL,
924 0,
925 output_buf,
926 256,
927 bytes_returned,
928 NULL,
929 NULL)) )
930 {
931 SOCKET_ADDRESS_LIST *addr_list;
932 SOCKET_ADDRESS *addr;
933 Uint32 ip;
934 struct sockaddr_in *sin;
|
935 kumpf 1.70
936 addr_list = (SOCKET_ADDRESS_LIST *)output_buf;
|
937 marek 1.68 addr = addr_list->Address;
|
938 kumpf 1.70
|
939 marek 1.68 sin = (struct sockaddr_in *)addr->lpSockaddr;
|
940 kumpf 1.70
941 for ( ; interfaces < addr_list->iAddressCount; interfaces++)
|
942 marek 1.68 {
943 ip = sin->sin_addr.s_addr;
944 addr++;
945 sin = (struct sockaddr_in *)addr->lpSockaddr;
946 if (ip == inIP)
947 {
948 free(output_buf);
949 closesocket(sock);
|
950 kumpf 1.70 return true;
|
951 marek 1.68 }
952 }
|
953 kumpf 1.70 }
954 else
955 {
|
956 marek 1.68 free(output_buf);
957 return false;
958 }
959 free(output_buf);
960 closesocket(sock);
961 }
962 return false;
963 }
964
|
965 venkat.puvvada 1.80 #ifdef PEGASUS_ENABLE_IPV6
966 void _getInterfaceAddrs(Array<String> &ips, int af)
967 {
968 SOCKET sock;
969
970 if (INVALID_SOCKET != (sock = WSASocket(af, SOCK_RAW,
971 0, NULL, 0, 0)))
972 {
973 DWORD bytesReturned;
974 char buf[2048];
975 int interfaces = 0;
976 char str[PEGASUS_INET6_ADDRSTR_LEN];
977 void *p;
978 if (0 == WSAIoctl(sock, SIO_ADDRESS_LIST_QUERY, NULL, 0,
979 buf, 2048, &bytesReturned, NULL,
980 NULL))
981 {
982
983 SOCKET_ADDRESS_LIST *addr_list;
984 SOCKET_ADDRESS *addr;
985 struct sockaddr *sin;
986 venkat.puvvada 1.80 addr_list = (SOCKET_ADDRESS_LIST *)buf;
987 addr = addr_list->Address;
988 for (sin = (struct sockaddr *) addr->lpSockaddr ;
989 interfaces < addr_list->iAddressCount;
990 interfaces++)
991 {
992 if (af == AF_INET)
993 {
994 p = &((struct sockaddr_in*)sin)->sin_addr;
995 }
996 else
997 {
998 p = &((struct sockaddr_in6*)sin)->sin6_addr;
999 }
1000 // Don't gather loopback addrs
1001 if (!System::isLoopBack(af, p))
1002 {
1003 HostAddress::convertBinaryToText(af, p, str, sizeof(str));
1004 ips.append(str);
1005 }
1006 addr++;
1007 venkat.puvvada 1.80 sin = (struct sockaddr*)addr->lpSockaddr;
1008 }
1009 }
1010 }
1011 }
1012 #endif
1013
1014 Array<String> System::getInterfaceAddrs()
1015 {
1016 Array<String> ips;
1017
1018 #ifdef PEGASUS_ENABLE_IPV6
1019 _getInterfaceAddrs(ips, AF_INET);
1020 _getInterfaceAddrs(ips, AF_INET6);
1021 #endif
1022
1023 return ips;
1024 }
|
1025 marek 1.68
|
1026 thilo.boehm 1.81 String System::getErrorMSG_NLS(int errorCode,int errorCode2)
1027 {
1028 LPVOID winErrorMsg = NULL;
1029
1030 if (FormatMessage(
1031 FORMAT_MESSAGE_ALLOCATE_BUFFER |
1032 FORMAT_MESSAGE_FROM_SYSTEM |
1033 FORMAT_MESSAGE_IGNORE_INSERTS,
1034 NULL,
1035 errorCode,
1036 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1037 (LPTSTR)&winErrorMsg,
1038 0,
1039 NULL))
1040 {
1041 MessageLoaderParms parms(
1042 "Common.System.ERROR_MESSAGE.STANDARD",
1043 "$0 (error code $1)",(char*)winErrorMsg,errorCode);
1044 LocalFree(winErrorMsg);
1045 return MessageLoader::getMessage(parms);
1046 }
1047 thilo.boehm 1.81
1048 MessageLoaderParms parms(
1049 "Common.System.ERROR_MESSAGE.STANDARD",
1050 "$0 (error code $1)","",errorCode);
1051 return MessageLoader::getMessage(parms);
1052
1053 }
1054
1055 String System::getErrorMSG(int errorCode,int errorCode2)
1056 {
1057
1058 String buffer;
1059 LPVOID winErrorMsg = NULL;
1060
1061 char strErrorCode[32];
1062 sprintf(strErrorCode, "%d", errorCode);
1063
1064 if (FormatMessage(
1065 FORMAT_MESSAGE_ALLOCATE_BUFFER |
1066 FORMAT_MESSAGE_FROM_SYSTEM |
1067 FORMAT_MESSAGE_IGNORE_INSERTS,
1068 thilo.boehm 1.81 NULL,
1069 errorCode,
1070 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1071 (LPTSTR)&winErrorMsg,
1072 0,
1073 NULL))
1074 {
1075 buffer.append((char*)winErrorMsg);
1076 LocalFree(winErrorMsg);
1077 }
1078
1079 buffer.append(" (error code ");
1080 buffer.append(strErrorCode);
1081 buffer.append(")");
1082
1083 return buffer;
1084 }
1085
|
1086 kumpf 1.67
1087 ///////////////////////////////////////////////////////////////////////////////
1088 // AutoFileLock class
1089 ///////////////////////////////////////////////////////////////////////////////
1090
1091 AutoFileLock::AutoFileLock(const char* fileName)
1092 {
|
1093 mreddy 1.76 // Repeat createFile, if there is a sharing violation.
1094 do
1095 {
1096 _hFile = CreateFile (fileName, GENERIC_READ | GENERIC_WRITE, 0, NULL,
1097 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1098 }while ((GetLastError() == ERROR_SHARING_VIOLATION));
1099
1100 // If this conditon succeeds, There is an error opening the file. Hence
1101 // returning from here as Lock can not be acquired.
1102 if((_hFile == INVALID_HANDLE_VALUE)
1103 && (GetLastError() != ERROR_ALREADY_EXISTS)
1104 && (GetLastError() != ERROR_SUCCESS))
1105 {
|
1106 mike 1.82.4.1 PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL1,
|
1107 mreddy 1.76 "AutoFileLock: Failed to open lock file '%s', error code %d.",
1108 fileName, GetLastError()));
1109 return;
1110 }
1111
1112 OVERLAPPED l={0,0,0,0,0};
1113 if(LockFileEx(_hFile,LOCKFILE_EXCLUSIVE_LOCK, 0, 0, 0, &l) == 0)
1114 {
|
1115 mike 1.82.4.1 PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL1,
|
1116 mreddy 1.76 "AutoFileLock: Failed to Acquire lock on file %s, error code %d.",
1117 fileName, GetLastError()));
1118 CloseHandle(_hFile);
1119 _hFile = INVALID_HANDLE_VALUE;
1120 }
|
1121 kumpf 1.67 }
1122
1123 AutoFileLock::~AutoFileLock()
1124 {
|
1125 mreddy 1.76 if(_hFile != INVALID_HANDLE_VALUE)
1126 {
1127 OVERLAPPED l={0,0,0,0,0};
1128 if(UnlockFileEx (_hFile, 0, 0, 0, &l) == 0)
1129 {
1130 PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL2,
1131 "AutoFileLock: Failed to unlock file, error code %d.",
1132 GetLastError()));
1133 }
1134 CloseHandle(_hFile);
1135 }
|
1136 kumpf 1.67 }
1137
|
1138 thilo.boehm 1.81
|
1139 mike 1.13 PEGASUS_NAMESPACE_END
|