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