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