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