1 mike 1.2 //%2006////////////////////////////////////////////////////////////////////////
2 //
3 // 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 // IBM Corp.; EMC Corporation, The Open Group.
7 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
9 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
11 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // 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 // 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 r.kieninger 1.8 //
|
21 mike 1.2 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 // 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 // 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 // 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 kumpf 1.4 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
|
35 mike 1.2 # define _OPEN_SYS_EXT
36 # include <sys/ps.h>
|
37 r.kieninger 1.8 # include <sys/__messag.h>
|
38 mike 1.2 #elif defined(PEGASUS_OS_VMS)
|
39 carson.hovey 1.3 # include <descrip.h> // $DESCRIPTOR
40 # include <iodef.h> // IO$_SENSEMODE
41 # include <ttdef.h> // TT$M_NOBRDCST
42 # include <tt2def.h> // TT2$M_PASTHRU
|
43 mike 1.2 # include <starlet.h>
|
44 carson.hovey 1.35 # include <stsdef.h> // VMS_STATUS_SUCCESS
45 # include <prvdef> // PRV$M_SETPRV
|
46 mike 1.2 #endif
47
48 #include <unistd.h>
49 #include <dirent.h>
50 #include <pwd.h>
51 #include <grp.h>
52 #include <errno.h>
53
54 #if defined(PEGASUS_OS_SOLARIS)
55 # include <string.h>
56 #endif
57
|
58 carson.hovey 1.3 #if !defined(PEGASUS_OS_VMS) && \
59 !defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) && \
|
60 mike 1.16 !defined(PEGASUS_OS_DARWIN)
|
61 mike 1.2 # include <crypt.h>
62 #endif
63
64 #include "Network.h"
65
66 #if defined(PEGASUS_USE_SYSLOGS)
67 # include <syslog.h>
68 #endif
69
70 #include <sys/stat.h>
71 #include <sys/types.h>
72 #include <cstdio>
73 #include <time.h>
74 #include <sys/time.h>
75 #include "System.h"
|
76 ouyang.jian 1.39
77 #ifdef PEGASUS_OS_PASE
78 #include <ILEWrapper/ILEUtilities.h>
79 #endif
80
|
81 mike 1.48.2.1 #if defined(PEGASUS_PLATFORM_SOLARIS_IX86_CC)
82 # include <sys/sockio.h>
83 #endif
84
|
85 mike 1.2 #include <Pegasus/Common/Tracer.h>
86 #include <Pegasus/Common/InternalException.h>
87 #include <Pegasus/Common/Mutex.h>
88
|
89 marek 1.10 #include <net/if.h>
90
|
91 mike 1.2 #include "Once.h"
92
93 PEGASUS_NAMESPACE_BEGIN
94
95 //==============================================================================
96 //
97 // System
98 //
99 //==============================================================================
100
101 // System ID constants for Logger::put and Logger::trace
|
102 ouyang.jian 1.23 #if defined(PEGASUS_OS_ZOS)
|
103 marek 1.12 const String System::CIMSERVER = "CFZCIM"; // Server system ID
|
104 mike 1.2 #else
105 const String System::CIMSERVER = "cimserver"; // Server system ID
106 #endif
107
108 void System::getCurrentTime(Uint32& seconds, Uint32& milliseconds)
109 {
110 timeval tv;
111 gettimeofday(&tv, 0);
112 seconds = Uint32(tv.tv_sec);
113 milliseconds = Uint32(tv.tv_usec) / 1000;
114 }
115
116 void System::getCurrentTimeUsec(Uint32& seconds, Uint32& microseconds)
117 {
118 timeval tv;
119 gettimeofday(&tv, 0);
120 seconds = Uint32(tv.tv_sec);
121 microseconds = Uint32(tv.tv_usec);
122 }
123
124 String System::getCurrentASCIITime()
125 mike 1.2 {
126 char str[50];
127 time_t rawTime;
128 struct tm tmBuffer;
129
130 time(&rawTime);
131 strftime(str, 40,"%m/%d/%Y-%T", localtime_r(&rawTime, &tmBuffer));
132 return String(str);
133 }
134
135 static inline void _sleep_wrapper(Uint32 seconds)
136 {
137 sleep(seconds);
138 }
139
140 void System::sleep(Uint32 seconds)
141 {
142 _sleep_wrapper(seconds);
143 }
144
145 Boolean System::exists(const char* path)
146 mike 1.2 {
147 return access(path, F_OK) == 0;
148 }
149
150 Boolean System::canRead(const char* path)
151 {
152 return access(path, R_OK) == 0;
153 }
154
155 Boolean System::canWrite(const char* path)
156 {
157 return access(path, W_OK) == 0;
158 }
159
160 Boolean System::getCurrentDirectory(char* path, Uint32 size)
161 {
162 return getcwd(path, size) != NULL;
163 }
164
165 Boolean System::isDirectory(const char* path)
166 {
167 mike 1.2 struct stat st;
168 if (stat(path, &st) != 0)
169 return false;
|
170 ouyang.jian 1.23
|
171 mike 1.2 return S_ISDIR(st.st_mode);
172 }
173
174 Boolean System::changeDirectory(const char* path)
175 {
176 return chdir(path) == 0;
177 }
178
179 Boolean System::makeDirectory(const char* path)
180 {
181 return mkdir(path, 0777) == 0;
182 }
183
184 Boolean System::getFileSize(const char* path, Uint32& size)
185 {
186 struct stat st;
187 if (stat(path, &st) != 0)
188 return false;
189 size = st.st_size;
|
190 ouyang.jian 1.23
|
191 mike 1.2 return true;
192 }
193
194 Boolean System::removeDirectory(const char* path)
195 {
196 return rmdir(path) == 0;
197 }
198
199 Boolean System::removeFile(const char* path)
200 {
201 return unlink(path) == 0;
202 }
203
204 Boolean System::renameFile(const char* oldPath, const char* newPath)
205 {
|
206 ouyang.jian 1.23 #if defined(PEGASUS_OS_VMS)
|
207 carson.hovey 1.3 // Note: link() on OpenVMS has a different meaning so rename is used.
208 // unlink() is a synonym for remove() so it can be used.
|
209 mike 1.2 if (rename(oldPath, newPath) != 0)
210 return false;
211
212 return true;
213 #else
214 if (link(oldPath, newPath) != 0)
215 return false;
216
217 return unlink(oldPath) == 0;
218 #endif
219 }
220
221 String System::getSystemCreationClassName ()
222 {
223 //
224 // The value returned should match the value of the CreationClassName key
225 // property used in the instrumentation of the CIM_ComputerSystem class
226 // as determined by the provider for the CIM_ComputerSystem class
227 //
228 return "CIM_ComputerSystem";
229 }
230 mike 1.2
231 Uint32 System::lookupPort(
232 const char * serviceName,
233 Uint32 defaultPort)
234 {
235 Uint32 localPort;
236
237 struct servent *serv;
238
239 //
240 // Get wbem-local port from /etc/services
241 //
242
243 #if defined(PEGASUS_OS_SOLARIS)
244 # define SERV_BUFF_SIZE 1024
245 struct servent serv_result;
246 char buf[SERV_BUFF_SIZE];
247
248 if ( (serv = getservbyname_r(serviceName, TCP, &serv_result,
249 buf, SERV_BUFF_SIZE)) != NULL )
250 #else // PEGASUS_OS_SOLARIS
251 mike 1.2 if ( (serv = getservbyname(serviceName, TCP)) != NULL )
252 #endif // PEGASUS_OS_SOLARIS
253 {
254 localPort = htons((uint16_t)serv->s_port);
255 }
256 else
257 {
258 localPort = defaultPort;
259 }
260
261 return localPort;
262 }
263
264 String System::getPassword(const char* prompt)
265 {
266 #if defined(PEGASUS_OS_VMS)
267
268 struct
269 {
270 short int numbuf;
271 char frst_char;
272 mike 1.2 char rsv1;
273 long rsv2;
274 }
275 tahead;
276
277 typedef struct
|
278 r.kieninger 1.8 { // I/O status block
279 short i_cond; // Condition value
280 short i_xfer; // Transfer count
281 long i_info; // Device information
|
282 mike 1.2 }
283 iosb;
284
285 typedef struct
|
286 r.kieninger 1.8 { // Terminal characteristics
287 char t_class; // Terminal class
288 char t_type; // Terminal type
289 short t_width; // Terminal width in characters
290 long t_mandl; // Terminal's mode and length
291 long t_extend; // Extended terminal characteristics
|
292 mike 1.2 }
293 termb;
294
295 termb otermb;
296 termb ntermb;
297
|
298 r.kieninger 1.8 static long ichan; // Gets channel number for TT:
|
299 mike 1.2
300 register int errorcode;
|
301 r.kieninger 1.8 int kbdflgs; // saved keyboard fd flags
302 int kbdpoll; // in O_NDELAY mode
303 int kbdqp = false; // there is a char in kbdq
304 int psize; // size of the prompt
|
305 mike 1.2
306 const size_t MAX_PASS_LEN = 32;
307 static char buf[MAX_PASS_LEN];
|
308 r.kieninger 1.8 char kbdq; // char we've already read
|
309 mike 1.2
310 iosb iostatus;
311
|
312 r.kieninger 1.8 static long termset[2] = { 0, 0 }; // No terminator
|
313 mike 1.2
|
314 r.kieninger 1.8 $DESCRIPTOR(inpdev, "TT"); // Terminal to use for input
|
315 mike 1.2
316 // Get a channel for the terminal
317
318 buf[0] = 0;
319
|
320 r.kieninger 1.8 errorcode = sys$assign(&inpdev, // Device name
321 &ichan, // Channel assigned
322 0, // request KERNEL mode access
323 0); // No mailbox assigned
|
324 mike 1.2
325 if (errorcode != SS$_NORMAL)
326 {
327 return buf;
328 }
329
330 // Read current terminal settings
331
|
332 r.kieninger 1.8 errorcode = sys$qiow(0, // Wait on event flag zero
333 ichan, // Channel to input terminal
334 IO$_SENSEMODE, // Function - Sense Mode
335 &iostatus, // Status after operation
336 0, 0, // No AST service
337 &otermb, // [P1] Address of Char Buffer
338 sizeof (otermb), // [P2] Size of Char Buffer
339 0, 0, 0, 0); // [P3] - [P6]
|
340 mike 1.2
341 if (errorcode != SS$_NORMAL)
342 {
343 return buf;
344 }
345
|
346 r.kieninger 1.8 // setup new settings
|
347 mike 1.2
348 ntermb = otermb;
349
|
350 r.kieninger 1.8 // turn on passthru and nobroadcast
|
351 mike 1.2
352 ntermb.t_extend |= TT2$M_PASTHRU;
353 ntermb.t_mandl |= TT$M_NOBRDCST;
354
|
355 r.kieninger 1.8 // Write out new terminal settings
|
356 mike 1.2
|
357 r.kieninger 1.8 errorcode = sys$qiow(0, // Wait on event flag zero
358 ichan, // Channel to input terminal
359 IO$_SETMODE, // Function - Set Mode
360 &iostatus, // Status after operation
361 0, 0, // No AST service
362 &ntermb, // [P1] Address of Char Buffer
363 sizeof (ntermb), // [P2] Size of Char Buffer
364 0, 0, 0, 0); // [P3] - [P6]
|
365 mike 1.2
366 if (errorcode != SS$_NORMAL)
367 {
368 return buf;
369 }
370
371 // Write a prompt, read characters from the terminal, performing no
372 // editing
373 // and doing no echo at all.
374
375 psize = strlen(prompt);
376
|
377 r.kieninger 1.8 errorcode = sys$qiow(0, // Event flag
378 ichan, // Input channel
|
379 mike 1.2 IO$_READPROMPT | IO$M_NOECHO | IO$M_NOFILTR |
380 IO$M_TRMNOECHO,
381 // Read with prompt, no echo, no translate, no
382 // termination character echo
|
383 r.kieninger 1.8 &iostatus, // I/O status block
384 NULL, // AST block (none)
385 0, // AST parameter
386 &buf, // P1 - input buffer
387 MAX_PASS_LEN, // P2 - buffer length
388 0, // P3 - ignored (timeout)
389 0, // P4 - ignored (terminator char set)
390 prompt, // P5 - prompt buffer
391 psize); // P6 - prompt size
|
392 mike 1.2
393 if (errorcode != SS$_NORMAL)
394 {
395 return buf;
396 }
397
|
398 r.kieninger 1.8 // Write out old terminal settings
399 errorcode = sys$qiow(0, // Wait on event flag zero
400 ichan, // Channel to input terminal
401 IO$_SETMODE, // Function - Set Mode
402 &iostatus, // Status after operation
403 0, 0, // No AST service
404 &otermb, // [P1] Address of Char Buffer
405 sizeof (otermb), // [P2] Size of Char Buffer
406 0, 0, 0, 0); // [P3] - [P6]
|
407 mike 1.2
408 if (errorcode != SS$_NORMAL)
409 {
410 return buf;
411 }
412
413 // Start new line
|
414 r.kieninger 1.8
|
415 mike 1.2 const int CR = 0x0d;
416 const int LF = 0x0a;
417 fputc(CR, stdout);
418 fputc(LF, stdout);
419
420 // Remove the termination character
421 psize = strlen(buf);
422 buf[psize - 1] = 0;
423
424 return buf;
425
426 #else /* default */
427
428 return String(getpass(prompt));
429
430 #endif /* default */
431 }
432
433 String System::getEffectiveUserName()
434 {
|
435 kumpf 1.44 #if defined(PEGASUS_OS_ZOS)
436 char effective_username[9];
437 __getuserid(effective_username, 9);
438 __etoa_l(effective_username,9);
439 return String(effective_username);
440 #else
|
441 kumpf 1.20 String userName;
|
442 mike 1.2 struct passwd* pwd = NULL;
443 const unsigned int PWD_BUFF_SIZE = 1024;
|
444 kumpf 1.44 struct passwd local_pwd;
445 char buf[PWD_BUFF_SIZE];
|
446 mike 1.2
|
447 kumpf 1.13 if (getpwuid_r(geteuid(), &local_pwd, buf, PWD_BUFF_SIZE, &pwd) != 0)
|
448 mike 1.2 {
|
449 kumpf 1.44 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL2,
450 "getpwuid_r failure: %s", strerror(errno)));
|
451 mike 1.2 }
|
452 kumpf 1.44 else if (pwd == NULL)
|
453 mike 1.2 {
|
454 kumpf 1.44 PEG_TRACE_CSTRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2,
455 "getpwuid_r failure; user may have been removed");
|
456 mike 1.2 }
457 else
458 {
459 //
460 // get the user name
461 //
462 userName.assign(pwd->pw_name);
463 }
464
|
465 kumpf 1.13 return userName;
|
466 kumpf 1.44 #endif
|
467 mike 1.2 }
468
469 String System::encryptPassword(const char* password, const char* salt)
470 {
|
471 venkat.puvvada 1.43 #if defined(PEGASUS_OS_VMS)
|
472 mike 1.2 const size_t MAX_PASS_LEN = 1024;
473 char pbBuffer[MAX_PASS_LEN] = {0};
|
474 venkat.puvvada 1.43 Uint32 dwByteCount;
|
475 mike 1.2 char pcSalt[3] = {0};
476
477 strncpy(pcSalt, salt, 2);
478 dwByteCount = strlen(password);
479 memcpy(pbBuffer, password, dwByteCount);
480
|
481 venkat.puvvada 1.43 for (Uint32 i=0; (i<dwByteCount) || (i>=MAX_PASS_LEN); i++)
|
482 mike 1.2 {
483 (i%2 == 0) ? pbBuffer[i] ^= pcSalt[1] : pbBuffer[i] ^= pcSalt[0];
484 }
485
486 return String(pcSalt) + String((char *)pbBuffer);
|
487 venkat.puvvada 1.43 #else
488 return String(crypt(password, salt));
489 #endif
|
490 mike 1.2 }
491
492 Boolean System::isSystemUser(const char* userName)
493 {
494 const unsigned int PWD_BUFF_SIZE = 1024;
495 struct passwd pwd;
496 struct passwd *result;
497 char pwdBuffer[PWD_BUFF_SIZE];
498
499 if (getpwnam_r(userName, &pwd, pwdBuffer, PWD_BUFF_SIZE, &result) != 0)
500 {
|
501 kumpf 1.44 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL2,
502 "getpwnam_r failure: %s", strerror(errno)));
|
503 mike 1.2 }
504
|
505 kumpf 1.44 return (result != NULL);
|
506 mike 1.2 }
507
508 Boolean System::isPrivilegedUser(const String& userName)
509 {
|
510 dave.sudlik 1.36 #if defined(PEGASUS_OS_PASE)
511 CString user = userName.getCString();
512 // this function only can be found in PASE environment
513 return umeIsPrivilegedUser((const char *)user);
514
515 #elif defined(PEGASUS_OS_VMS)
516 static union prvdef old_priv_mask;
517 static union prvdef new_priv_mask;
518 char enbflg = 1; // 1 = enable
519 char prmflg = 0; // 0 = life time of image only.
520 int retStat;
521
522 old_priv_mask.prv$v_sysprv = false; // SYSPRV privilege.
523 new_priv_mask.prv$v_sysprv = true; // SYSPRV privilege.
524
525 retStat = sys$setprv(enbflg, &new_priv_mask, prmflg, &old_priv_mask);
526 if (!$VMS_STATUS_SUCCESS(retStat))
527 {
528 return false;
529 }
530
531 dave.sudlik 1.36 if (retStat == SS$_NOTALLPRIV)
532 {
533 return false;
534 }
535
536 return true;
537
538 #else
|
539 mike 1.2 struct passwd pwd;
540 struct passwd *result;
541 const unsigned int PWD_BUFF_SIZE = 1024;
542 char pwdBuffer[PWD_BUFF_SIZE];
543
544 if (getpwnam_r(
545 userName.getCString(), &pwd, pwdBuffer, PWD_BUFF_SIZE, &result) != 0)
546 {
547 String errorMsg = String("getpwnam_r failure : ") +
548 String(strerror(errno));
549 PEG_TRACE_STRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2, errorMsg);
550 // L10N TODO - This message needs to be added.
551 //Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::WARNING,
552 // errorMsg);
553 }
554
555 // Check if the requested entry was found. If not return false.
556 if ( result != NULL )
557 {
558 // Check if the uid is 0.
559 if ( pwd.pw_uid == 0 )
560 mike 1.2 {
561 return true;
562 }
563 }
564 return false;
|
565 dave.sudlik 1.36 #endif
|
566 mike 1.2 }
567
|
568 kumpf 1.44 static String _privilegedUserName;
569 static Once _privilegedUserNameOnce = PEGASUS_ONCE_INITIALIZER;
|
570 mike 1.2
571 static void _initPrivilegedUserName()
572 {
573 struct passwd* pwd = NULL;
574 const unsigned int PWD_BUFF_SIZE = 1024;
575 struct passwd local_pwd;
576 char buf[PWD_BUFF_SIZE];
|
577 carson.hovey 1.35 PEGASUS_UID_T uid;
|
578 mike 1.2
|
579 carson.hovey 1.35 #if defined(PEGASUS_OS_VMS)
580 // 65540 = 10004 hex = [1,4] the UIC for [SYSTEM] on OpenVMS
581 uid = 0x10004;
582 #else
583 uid = 0;
584 #endif
|
585 kumpf 1.44
|
586 carson.hovey 1.35 if (getpwuid_r(uid, &local_pwd, buf, PWD_BUFF_SIZE, &pwd) != 0)
|
587 mike 1.2 {
|
588 kumpf 1.44 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL2,
589 "getpwuid_r failure: %s", strerror(errno)));
|
590 mike 1.2 }
|
591 kumpf 1.44 else if (pwd == NULL)
|
592 mike 1.2 {
|
593 kumpf 1.44 PEG_TRACE_CSTRING(
594 TRC_OS_ABSTRACTION, Tracer::LEVEL4,
595 "getpwuid_r: Could not find entry.");
596 PEGASUS_ASSERT(0);
|
597 mike 1.2 }
598 else
599 {
|
600 kumpf 1.44 _privilegedUserName.assign(pwd->pw_name);
|
601 mike 1.2 }
602 }
603
604 String System::getPrivilegedUserName()
605 {
|
606 kumpf 1.44 once(&_privilegedUserNameOnce, _initPrivilegedUserName);
607 return _privilegedUserName;
|
608 mike 1.2 }
609
610 #if !defined(PEGASUS_OS_VMS) || defined(PEGASUS_ENABLE_USERGROUP_AUTHORIZATION)
611
612 Boolean System::isGroupMember(const char* userName, const char* groupName)
613 {
614 struct group grp;
615 char* member;
616 Boolean retVal = false;
617 const unsigned int PWD_BUFF_SIZE = 1024;
618 const unsigned int GRP_BUFF_SIZE = 1024;
619 struct passwd pwd;
620 struct passwd* result;
621 struct group* grpresult;
622 char pwdBuffer[PWD_BUFF_SIZE];
623 char grpBuffer[GRP_BUFF_SIZE];
624
625 // Search Primary group information.
626
627 // Find the entry that matches "userName"
628
629 mike 1.2 if (getpwnam_r(userName, &pwd, pwdBuffer, PWD_BUFF_SIZE, &result) != 0)
630 {
631 String errorMsg = String("getpwnam_r failure : ") +
632 String(strerror(errno));
|
633 yi.zhou 1.7 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
|
634 mike 1.2 errorMsg);
635 throw InternalSystemError();
636 }
637
638 if ( result != NULL )
639 {
640 // User found, check for group information.
641 gid_t group_id;
642 group_id = pwd.pw_gid;
643
644 // Get the group name using group_id and compare with group passed.
645 if ( getgrgid_r(group_id, &grp,
646 grpBuffer, GRP_BUFF_SIZE, &grpresult) != 0)
647 {
648 String errorMsg = String("getgrgid_r failure : ") +
649 String(strerror(errno));
|
650 kumpf 1.13 Logger::put(
651 Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
652 errorMsg);
|
653 mike 1.2 throw InternalSystemError();
654 }
655
656 // Compare the user's group name to groupName.
|
657 kumpf 1.13 if (strcmp(grp.gr_name, groupName) == 0)
|
658 mike 1.2 {
659 // User is a member of the group.
660 return true;
661 }
662 }
663
664 //
665 // Search supplemental groups.
666 // Get a user group entry
667 //
668 if (getgrnam_r((char *)groupName, &grp,
669 grpBuffer, GRP_BUFF_SIZE, &grpresult) != 0)
670 {
671 String errorMsg = String("getgrnam_r failure : ") +
672 String(strerror(errno));
673 Logger::put(
|
674 yi.zhou 1.7 Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING, errorMsg);
|
675 mike 1.2 throw InternalSystemError();
676 }
677
678 // Check if the requested group was found.
679 if (grpresult == NULL)
680 {
681 return false;
682 }
683
684 Uint32 j = 0;
685
686 //
687 // Get all the members of the group
688 //
689 member = grp.gr_mem[j++];
690
691 while (member)
692 {
693 //
694 // Check if the user is a member of the group
695 //
696 mike 1.2 if ( strcmp(userName, member) == 0 )
697 {
698 retVal = true;
699 break;
700 }
701 member = grp.gr_mem[j++];
702 }
703
704 return retVal;
705 }
706
707 #endif /* !PEGASUS_OS_VMS || PEGASUS_ENABLE_USERGROUP_AUTHORIZATION */
708
709 Boolean System::lookupUserId(
710 const char* userName,
711 PEGASUS_UID_T& uid,
712 PEGASUS_GID_T& gid)
713 {
|
714 ouyang.jian 1.46 #if defined(PEGASUS_OS_PASE)
715 if (!umeLookupUserProfile(userName))
716 {
717 PEG_TRACE_CSTRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2,
718 "umeLookupUserProfile failed.");
719 return false;
720 }
721 return true;
722 #else
|
723 mike 1.2 const unsigned int PWD_BUFF_SIZE = 1024;
724 struct passwd pwd;
725 struct passwd *result;
726 char pwdBuffer[PWD_BUFF_SIZE];
727
728 int rc = getpwnam_r(userName, &pwd, pwdBuffer, PWD_BUFF_SIZE, &result);
729
730 if (rc != 0)
731 {
732 PEG_TRACE_STRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2,
733 String("getpwnam_r failed: ") + String(strerror(errno)));
734 return false;
735 }
736
737 if (result == 0)
738 {
|
739 marek 1.19 PEG_TRACE_CSTRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2,
|
740 mike 1.2 "getpwnam_r failed.");
741 return false;
742 }
743
744 uid = pwd.pw_uid;
745 gid = pwd.pw_gid;
746
747 return true;
|
748 ouyang.jian 1.46 #endif
|
749 mike 1.2 }
750
|
751 kumpf 1.22 Boolean System::changeUserContext_SingleThreaded(
752 const char* userName,
|
753 mike 1.2 const PEGASUS_UID_T& uid,
754 const PEGASUS_GID_T& gid)
755 {
|
756 ouyang.jian 1.46 #if defined(PEGASUS_OS_PASE)
757 char required_ph[12];
758
759 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL4,
760 "Changing user context to: username = %s", userName));
761
762 if (!umeGetUserProfile(userName, required_ph))
763 return false;
764
765 if (!umeSwapUserProfile(required_ph))
766 return false;
767
768 umeReleaseUserProfile(required_ph);
769 return true;
770 #else
|
771 marek 1.19 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL4,
|
772 kumpf 1.22 "Changing user context to: username = %s, uid = %d, gid = %d",
773 userName, (int)uid, (int)gid));
|
774 mike 1.2
775 if (setgid(gid) != 0)
776 {
777 PEG_TRACE_STRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2,
778 String("setgid failed: ") + String(strerror(errno)));
779 return false;
780 }
781
|
782 ouyang.jian 1.46 # if !defined(PEGASUS_OS_VMS)
|
783 kumpf 1.22 // NOTE: initgroups() uses non-reentrant functions and should only be
784 // called from a single-threaded process.
785 if (initgroups(userName, gid) != 0)
786 {
787 PEG_TRACE_STRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2,
788 String("initgroups failed: ") + String(strerror(errno)));
789 return false;
790 }
|
791 ouyang.jian 1.46 # endif
|
792 kumpf 1.22
|
793 mike 1.2 if (setuid(uid) != 0)
794 {
795 PEG_TRACE_STRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2,
796 String("setuid failed: ") + String(strerror(errno)));
797 return false;
798 }
799
800 return true;
|
801 ouyang.jian 1.46 #endif
|
802 mike 1.2 }
803
804 Uint32 System::getPID()
805 {
806 return getpid();
807 }
808
809 Boolean System::truncateFile(
810 const char* path,
811 size_t newSize)
812 {
813 return (truncate(path, newSize) == 0);
814 }
815
816 Boolean System::is_absolute_path(const char *path)
817 {
818 if (path == NULL)
819 return false;
820
821 if (path[0] == '/')
822 return true;
823 mike 1.2
824 return false;
825 }
826
827 Boolean System::changeFilePermissions(const char* path, mode_t mode)
828 {
829 Sint32 ret = 0;
830 const char * tmp = path;
831
832 return chmod(tmp, mode) == 0 ? true : false;
833 }
834
835 Boolean System::verifyFileOwnership(const char* path)
836 {
837 struct stat st;
|
838 ouyang.jian 1.23
|
839 mike 1.2 if (lstat(path, &st) != 0)
840 return false;
841
842 return ((st.st_uid == geteuid()) && // Verify the file owner
843 S_ISREG(st.st_mode) && // Verify it is a regular file
844 (st.st_nlink == 1)); // Verify it is not a hard link
845 }
846
847 void System::syslog(const String& ident, Uint32 severity, const char* message)
848 {
|
849 kumpf 1.17 #if defined(PEGASUS_USE_SYSLOGS) && \
850 (defined(PEGASUS_OS_HPUX) || defined(PEGASUS_OS_LINUX))
|
851 mike 1.2
852 // Since the openlog(), syslog(), and closelog() function calls must be
853 // coordinated (see below), we need a thread control.
854
855 static Mutex logMutex;
856
857 AutoMutex loglock(logMutex);
858
859 // Get a const char* representation of the identifier string. Note: The
860 // character string passed to the openlog() function must persist until
861 // closelog() is called. The syslog() method uses this pointer directly
862 // rather than a copy of the string it refers to.
863
864 CString identCString = ident.getCString();
865 openlog(identCString, LOG_PID, LOG_DAEMON);
866
867 // Map from the Logger log level to the system log level.
868
869 Uint32 syslogLevel;
870 if (severity & Logger::FATAL)
871 {
872 mike 1.2 syslogLevel = LOG_CRIT;
873 }
874 else if (severity & Logger::SEVERE)
875 {
876 syslogLevel = LOG_ERR;
877 }
878 else if (severity & Logger::WARNING)
879 {
880 syslogLevel = LOG_WARNING;
881 }
882 else if (severity & Logger::INFORMATION)
883 {
884 syslogLevel = LOG_INFO;
885 }
886 else // if (severity & Logger::TRACE)
887 {
888 syslogLevel = LOG_DEBUG;
889 }
890
891 // Write the message to the system log.
892
893 mike 1.2 ::syslog(syslogLevel, "%s", message);
894
895 closelog();
896
|
897 thilo.boehm 1.11 #elif defined(PEGASUS_OS_ZOS) && defined(PEGASUS_USE_SYSLOGS)
|
898 marek 1.14 #define ZOS_MSGID_LENGTH 11
|
899 r.kieninger 1.8
|
900 marek 1.14 char* zosMessageString;
901 Uint32 messageLength = strlen(message);
902 Uint32 syslogLevel = LOG_DEBUG;
903 const char* zos_msgid;
|
904 r.kieninger 1.9
|
905 marek 1.14 // determine syslog level and create zos_msgid string
|
906 r.kieninger 1.9 if ((severity & Logger::SEVERE) || (severity & Logger::FATAL) )
907 {
908 syslogLevel = LOG_ERR;
909 zos_msgid = "CFZ00004E: ";
910 }
911 else if (severity & Logger::WARNING)
912 {
913 syslogLevel = LOG_WARNING;
914 zos_msgid = "CFZ00002W: ";
915 }
916 else if (severity & Logger::INFORMATION)
917 {
918 syslogLevel = LOG_INFO;
919 zos_msgid = "CFZ00001I: ";
920 }
921 else
922 {
923 syslogLevel = LOG_DEBUG;
924 zos_msgid = "CFZ00001I: ";
925 }
|
926 r.kieninger 1.8
|
927 marek 1.14 // we cut at 4000 characters
928 // leaving room for 11 additional message characters
929 //
930 if (messageLength > 4000)
931 messageLength = 4000;
932
933 // reserve memory for the message string, also prepend
934 // z/OS message id CFZ* if necessary
|
935 r.kieninger 1.47 if ((strncmp(message, "CFZ", 3) != 0) &&
936 (strncmp(message, "CEZ", 3) != 0) )
|
937 r.kieninger 1.8 {
|
938 marek 1.14 // reserve message + 11 char message prepend + 1 byte for \0 char
939 zosMessageString = (char*) malloc(messageLength+ZOS_MSGID_LENGTH+1);
940 memcpy(zosMessageString, zos_msgid, ZOS_MSGID_LENGTH);
941 memcpy(zosMessageString+ZOS_MSGID_LENGTH, message, messageLength);
942 messageLength+=ZOS_MSGID_LENGTH;
943 } else
|
944 marek 1.12 {
|
945 marek 1.14 zosMessageString = (char*) malloc(messageLength+1);
946 memcpy(zosMessageString, message, messageLength);
|
947 marek 1.12 }
|
948 marek 1.14 // terminate with a null character
949 zosMessageString[messageLength]='\0';
|
950 marek 1.12
|
951 marek 1.14 // write first to syslog, __console changes the content of
952 // message string
953 ::syslog(syslogLevel, "%s", zosMessageString);
954
|
955 marek 1.12 CString identCString = ident.getCString();
|
956 r.kieninger 1.8 // Issue important messages to the z/OS console
|
957 marek 1.14 // audit messages will go to a different syslog like place
|
958 kumpf 1.13 if (!(severity & Logger::TRACE) &&
|
959 marek 1.12 !(strcmp("cimserver audit",identCString) == 0))
|
960 r.kieninger 1.8 {
961 struct __cons_msg cons;
962 int concmd=0;
|
963 marek 1.14
|
964 r.kieninger 1.8 memset(&cons,0,sizeof(cons));
|
965 marek 1.14 cons.__format.__f1.__msg_length = messageLength;
966 cons.__format.__f1.__msg = zosMessageString;
967 __console(&cons, NULL, &concmd);
|
968 r.kieninger 1.8 }
|
969 marek 1.14 free(zosMessageString);
|
970 r.kieninger 1.8
|
971 mike 1.2 #else /* default */
972
973 // Not implemented!
974
975 #endif /* default */
976 }
977
|
978 marek 1.12 void System::openlog(const char *ident, int logopt, int facility)
979 {
980
|
981 kumpf 1.17 #if defined(PEGASUS_USE_SYSLOGS) && \
982 (defined(PEGASUS_OS_HPUX) || defined(PEGASUS_OS_LINUX) || \
983 defined(PEGASUS_OS_ZOS))
|
984 marek 1.12 ::openlog(ident, logopt, facility);
985 #else /* default */
986
987 // Not implemented!
988
989 #endif /* default */
990
991 }
992
993 void System::closelog()
994 {
995
|
996 kumpf 1.17 #if defined(PEGASUS_USE_SYSLOGS) && \
997 (defined(PEGASUS_OS_HPUX) || defined(PEGASUS_OS_LINUX) || \
998 defined(PEGASUS_OS_ZOS))
|
999 marek 1.12 ::closelog();
1000 #else /* default */
1001
1002 // Not implemented!
1003
1004 #endif /* default */
1005
1006 }
1007
1008
|
1009 marek 1.10 // check if a given IP address is defined on the local network interfaces
1010 Boolean System::isIpOnNetworkInterface(Uint32 inIP)
1011 {
1012 // Function compares all IP addresses defined on
1013 // local network interface with a given IP address
|
1014 kumpf 1.27 #define PEGASUS_MAX_NETWORK_INTERFACES 32
|
1015 marek 1.10 struct ifconf conf;
1016
|
1017 kumpf 1.13 conf.ifc_buf =
1018 (char *)calloc(PEGASUS_MAX_NETWORK_INTERFACES, sizeof(struct ifreq));
1019 conf.ifc_len = PEGASUS_MAX_NETWORK_INTERFACES * sizeof(struct ifreq);
1020
1021 if (-1 < ioctl(AF_INET, SIOCGIFCONF, &conf))
1022 {
1023 struct ifreq* r = conf.ifc_req;
|
1024 kumpf 1.15 sockaddr_in* addr;
1025 addr = reinterpret_cast<struct sockaddr_in*>(&r->ifr_addr);
|
1026 kumpf 1.13 while (addr->sin_addr.s_addr != 0)
1027 {
1028 Uint32 ip = addr->sin_addr.s_addr;
1029 if (ip == inIP)
1030 {
1031 free(conf.ifc_buf);
1032 return true;
1033 }
1034 // next interface
1035 r++;
|
1036 kumpf 1.15 addr = reinterpret_cast<struct sockaddr_in*>(&r->ifr_addr);
|
1037 kumpf 1.13 }
|
1038 marek 1.10 }
1039 free(conf.ifc_buf);
1040 return false;
1041 }
1042
|
1043 thilo.boehm 1.41 String System::getErrorMSG_NLS(int errorCode,int errorCode2)
1044 {
1045 #if defined(PEGASUS_OS_ZOS)
1046
1047 char buf[10];
1048
1049 sprintf(buf,"%08X",errorCode2);
1050
1051 MessageLoaderParms parms(
1052 "Common.System.ERROR_MESSAGE.PEGASUS_OS_ZOS",
1053 "$0 (error code $1, reason code 0x$2)",
1054 strerror(errorCode),errorCode,buf);
1055
1056 #else
1057 MessageLoaderParms parms(
1058 "Common.System.ERROR_MESSAGE.STANDARD",
1059 "$0 (error code $1)",strerror(errorCode),errorCode);
1060
1061 #endif
1062
1063 return MessageLoader::getMessage(parms);
1064 thilo.boehm 1.41
1065 }
1066
1067 String System::getErrorMSG(int errorCode,int errorCode2)
1068 {
1069
1070 String buffer;
1071
1072 char strErrorCode[32];
1073 sprintf(strErrorCode, "%d", errorCode);
1074
1075 buffer.append(strerror(errorCode));
1076 buffer.append(" (error code ");
1077 buffer.append(strErrorCode);
1078
1079 #if defined(PEGASUS_OS_ZOS)
1080 char strErrorCode2[10];
1081 sprintf(strErrorCode2,"%08X",errorCode2);
1082 buffer.append(", reason code 0x");
1083 buffer.append(strErrorCode2);
1084 #endif
1085 thilo.boehm 1.41
1086 buffer.append(")");
1087
1088 return buffer;
1089 }
1090
1091
|
1092 kumpf 1.6
1093 ///////////////////////////////////////////////////////////////////////////////
1094 // AutoFileLock class
1095 ///////////////////////////////////////////////////////////////////////////////
1096
1097 AutoFileLock::AutoFileLock(const char* fileName)
1098 {
1099 #ifdef PEGASUS_OS_TYPE_UNIX
1100 _fl.l_type = F_WRLCK;
1101 _fl.l_whence = SEEK_SET;
1102 _fl.l_start = 0;
1103 _fl.l_len = 0;
1104 _fl.l_pid = getpid();
1105
1106 do
1107 {
1108 _fd = open(fileName, O_WRONLY);
1109 } while ((_fd == -1) && (errno == EINTR));
1110
1111 if (_fd != -1)
1112 {
1113 kumpf 1.6 int rc;
1114
1115 do
1116 {
1117 rc = fcntl(_fd, F_SETLKW, &_fl);
1118 } while ((rc == -1) && (errno == EINTR));
1119
1120 if (rc == -1)
1121 {
|
1122 marek 1.19 PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL2,
|
1123 kumpf 1.6 "AutoFileLock: Failed to lock file '%s', error code %d.",
|
1124 marek 1.19 fileName, errno));
|
1125 kumpf 1.6 _fd = -1;
1126 }
1127 }
1128 else
1129 {
|
1130 marek 1.19 PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL2,
|
1131 kumpf 1.6 "AutoFileLock: Failed to open lock file '%s', error code %d.",
|
1132 marek 1.19 fileName, errno));
|
1133 kumpf 1.6 }
1134 #endif
1135 }
1136
1137 AutoFileLock::~AutoFileLock()
1138 {
1139 #ifdef PEGASUS_OS_TYPE_UNIX
1140 if (_fd != -1)
1141 {
1142 _fl.l_type = F_UNLCK;
1143 int rc = fcntl(_fd, F_SETLK, &_fl);
1144 if (rc == -1)
1145 {
|
1146 marek 1.19 PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL2,
|
1147 kumpf 1.6 "AutoFileLock: Failed to unlock file, error code %d.",
|
1148 marek 1.19 errno));
|
1149 kumpf 1.6 }
1150 close(_fd);
1151 }
1152 #endif
1153 }
1154
1155
|
1156 mike 1.2 //==============================================================================
1157 //
|
1158 ouyang.jian 1.29 // PEGASUS_OS_AIX & PEGASUS_OS_PASE
|
1159 mike 1.2 //
1160 //==============================================================================
1161
1162 // System Initializater for AIX
|
1163 ouyang.jian 1.30 #if defined(PEGASUS_OS_AIX) || defined(PEGASUS_OS_PASE)
|
1164 mike 1.2 # include <cstdlib>
1165
1166 class SystemInitializer
1167 {
1168
1169 public:
1170 /**
1171 *
1172 * Default constructor.
1173 *
1174 */
1175 SystemInitializer();
1176 };
1177
1178 SystemInitializer::SystemInitializer()
1179 {
1180 putenv("XPG_SUS_ENV=ON");
1181 }
1182
1183 static SystemInitializer initializer;
1184
1185 mike 1.2 #endif /* PEGASUS_OS_AIX */
1186
|
1187 venkat.puvvada 1.37 Array<String> System::getInterfaceAddrs()
1188 {
1189 Array<String> ips;
1190
1191 #ifdef PEGASUS_ENABLE_IPV6
1192
|
1193 venkat.puvvada 1.42 #if defined(PEGASUS_HAS_GETIFADDRS)
|
1194 venkat.puvvada 1.37 struct ifaddrs *array, *addrs;
1195 char buff[PEGASUS_INET6_ADDRSTR_LEN];
1196
1197 if (0 > getifaddrs(&array))
1198 {
1199 return ips;
1200 }
1201
1202 for( addrs = array; addrs != NULL; addrs = addrs->ifa_next)
1203 {
1204 switch(addrs->ifa_addr->sa_family)
1205 {
1206 case AF_INET :
1207 // Don't gather loop back addrs.
1208 if (System::isLoopBack(AF_INET,
1209 &((struct sockaddr_in *)addrs->ifa_addr)->sin_addr))
1210 {
1211 continue;
1212 }
1213 HostAddress::convertBinaryToText(AF_INET,
1214 &((struct sockaddr_in *)addrs->ifa_addr)->sin_addr,
1215 venkat.puvvada 1.37 buff, sizeof(buff));
1216 ips.append(buff);
1217 break;
1218 case AF_INET6 :
1219 if (System::isLoopBack(AF_INET6,
1220 &((struct sockaddr_in6 *)addrs->ifa_addr)->sin6_addr))
1221 {
1222 continue;
1223 }
1224 HostAddress::convertBinaryToText(AF_INET6,
1225 &((struct sockaddr_in6 *)addrs->ifa_addr)->sin6_addr,
1226 buff, sizeof(buff));
1227 ips.append(buff);
1228 break;
1229 }
1230 }
1231 if(array)
1232 {
1233 freeifaddrs(array);
1234 }
1235 #elif defined(PEGASUS_OS_AIX)
1236 venkat.puvvada 1.37 //ATTN: implement for AIX
1237 #elif defined(PEGASUS_OS_ZOS)
1238 //ATTN: implement for ZOS
1239 #elif defined(PEGASUS_OS_HPUX)
1240 //ATTN: implement for HPUX
1241 #elif defined(PEGASUS_OS_VMS)
1242 //ATTN: implement for VMS
1243 #else
1244 //ATTN: implement for rest of UNIX flavors.
1245 #endif
1246
1247 #endif // PEGASUS_ENABLE_IPV6
1248
1249 return ips;
1250 }
1251
|
1252 thilo.boehm 1.41
|
1253 mike 1.2 PEGASUS_NAMESPACE_END
|