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