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 //
21 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 mike 1.2 // 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 #elif defined(PEGASUS_PLATFORM_OS400_ISERIES_IBM)
38 # include <fcntl.h>
39 # include <qycmutilu2.H>
40 # include <unistd.cleinc>
41 # include "qycmmsgclsMessage.H" // ycmMessage class
42 # include "OS400SystemState.h" // OS400LoadDynamicLibrary, etc
43 # include "EBCDIC_OS400.h"
44 #elif defined(PEGASUS_OS_VMS)
|
45 carson.hovey 1.3 # include <descrip.h> // $DESCRIPTOR
46 # include <iodef.h> // IO$_SENSEMODE
47 # include <ttdef.h> // TT$M_NOBRDCST
48 # include <tt2def.h> // TT2$M_PASTHRU
|
49 mike 1.2 # include <starlet.h>
50 #endif
51
52 #include <unistd.h>
53 #include <dirent.h>
54 #include <pwd.h>
55 #include <grp.h>
56 #include <errno.h>
57
58 #if defined(PEGASUS_OS_SOLARIS)
59 # include <string.h>
60 #endif
61
|
62 carson.hovey 1.3 #if !defined(PEGASUS_OS_VMS) && \
63 !defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) && \
|
64 mike 1.2 !defined(PEGASUS_PLATFORM_OS400_ISERIES_IBM) && \
65 !defined(PEGASUS_PLATFORM_DARWIN_PPC_GNU)
66 # include <crypt.h>
67 #endif
68
69 #include "Network.h"
70
71 #if defined(PEGASUS_USE_SYSLOGS)
72 # include <syslog.h>
73 #endif
74
75 #include <sys/stat.h>
76 #include <sys/types.h>
77 #include <cstdio>
78 #include <time.h>
79 #include <sys/time.h>
80 #include "System.h"
81 #include <Pegasus/Common/Tracer.h>
82 #include <Pegasus/Common/InternalException.h>
83 #include <Pegasus/Common/Mutex.h>
84
85 mike 1.2 #if defined(PEGASUS_OS_LSB)
86 # include <termios.h>
87 # include <stdio.h>
88 # include <stdlib.h>
89 #endif
90
91 #include "Once.h"
92
93 PEGASUS_NAMESPACE_BEGIN
94
95 //==============================================================================
96 //
97 // QlgPath (PEGASUS_OS_OS400 only)
98 //
99 //==============================================================================
100
101 #ifdef PEGASUS_OS_OS400
102
103 struct QlgPath
104 {
105 QlgPath(const char* path);
106 mike 1.2 operator Qlg_Path_Name_T*() { return &qlg_struct; }
107 Qlg_Path_Name_T qlg_struct;
108 const char* pn;
109 };
110
111 QlgPath::QlgPath(const char* path) : pn(path)
112 {
113 memset((void*)&qlg_struct, 0, sizeof(Qlg_Path_Name_T));
114 qlg_struct.CCSID = 1208;
115 #pragma convert(37)
116 memcpy(qlg_struct.Country_ID,"US",2);
117 memcpy(qlg_struct.Language_ID,"ENU",3);
118 #pragma convert(0)
119 qlg_struct.Path_Type = QLG_PTR_SINGLE;
120 qlg_struct.Path_Length = strlen(path);
121 qlg_struct.Path_Name_Delimiter[0] = '/';
122 }
123
124 #endif /* PEGASUS_OS_OS400 */
125
126 //==============================================================================
127 mike 1.2 //
128 // System
129 //
130 //==============================================================================
131
132 // System ID constants for Logger::put and Logger::trace
133 #if defined(PEGASUS_PLATFORM_OS400_ISERIES_IBM)
134 const String System::CIMSERVER = "qycmcimom"; // Server system ID
135 #else
136 const String System::CIMSERVER = "cimserver"; // Server system ID
137 #endif
138
139 void System::getCurrentTime(Uint32& seconds, Uint32& milliseconds)
140 {
141 timeval tv;
142 gettimeofday(&tv, 0);
143 seconds = Uint32(tv.tv_sec);
144 milliseconds = Uint32(tv.tv_usec) / 1000;
145 }
146
147 void System::getCurrentTimeUsec(Uint32& seconds, Uint32& microseconds)
148 mike 1.2 {
149 timeval tv;
150 gettimeofday(&tv, 0);
151 seconds = Uint32(tv.tv_sec);
152 microseconds = Uint32(tv.tv_usec);
153 }
154
155 String System::getCurrentASCIITime()
156 {
157 char str[50];
158 time_t rawTime;
159 struct tm tmBuffer;
160
161 time(&rawTime);
162 strftime(str, 40,"%m/%d/%Y-%T", localtime_r(&rawTime, &tmBuffer));
163 return String(str);
164 }
165
166 static inline void _sleep_wrapper(Uint32 seconds)
167 {
168 sleep(seconds);
169 mike 1.2 }
170
171 void System::sleep(Uint32 seconds)
172 {
173 _sleep_wrapper(seconds);
174 }
175
176 Boolean System::exists(const char* path)
177 {
178 #if defined(PEGASUS_OS_OS400)
179 return QlgAccess(QlgPath(path), F_OK) == 0;
180 #else
181 return access(path, F_OK) == 0;
182 #endif
183 }
184
185 Boolean System::canRead(const char* path)
186 {
187 #if defined(PEGASUS_OS_OS400)
188 return QlgAccess(QlgPath(path), R_OK) == 0;
189 #else
190 mike 1.2 return access(path, R_OK) == 0;
191 #endif
192 }
193
194 Boolean System::canWrite(const char* path)
195 {
196 #if defined(PEGASUS_OS_OS400)
197 return QlgAccess(QlgPath(path), W_OK) == 0;
198 #else
199 return access(path, W_OK) == 0;
200 #endif
201 }
202
203 Boolean System::getCurrentDirectory(char* path, Uint32 size)
204 {
205 #if defined(PEGASUS_OS_OS400)
206 return QlgGetcwd(QlgPath(path), size) == 0;
207 #else
208 return getcwd(path, size) != NULL;
209 #endif
210 }
211 mike 1.2
212 Boolean System::isDirectory(const char* path)
213 {
214 struct stat st;
215
216 #if defined(PEGASUS_OS_OS400)
217 if (QlgStat(QlgPath(path), &st) != 0)
218 return false;
219 #else
220 if (stat(path, &st) != 0)
221 return false;
222 #endif
223 return S_ISDIR(st.st_mode);
224 }
225
226 Boolean System::changeDirectory(const char* path)
227 {
228 #if defined(PEGASUS_OS_OS400)
229 return QlgChdir(QlgPath(path)) == 0;
230 #else
231 return chdir(path) == 0;
232 mike 1.2 #endif
233 }
234
235 Boolean System::makeDirectory(const char* path)
236 {
237 #if defined(PEGASUS_OS_OS400)
238 return QlgMkdir(QlgPath(path), 0777) == 0;
239 #else
240 return mkdir(path, 0777) == 0;
241 #endif
242
243 }
244
245 Boolean System::getFileSize(const char* path, Uint32& size)
246 {
247 struct stat st;
248
249 #if defined(PEGASUS_OS_OS400)
250 if (QlgStat(QlgPath(path), &st) != 0)
251 return false;
252 #else
253 mike 1.2 if (stat(path, &st) != 0)
254 return false;
255 #endif
256
257 size = st.st_size;
258 return true;
259 }
260
261 Boolean System::removeDirectory(const char* path)
262 {
263 #if defined(PEGASUS_OS_OS400)
264 return QlgRmdir(QlgPath(path)) == 0;
265 #else
266 return rmdir(path) == 0;
267 #endif
268 }
269
270 Boolean System::removeFile(const char* path)
271 {
272 #if defined(PEGASUS_OS_OS400)
273 return QlgUnlink(QlgPath(path)) == 0;
274 mike 1.2 #else
275 return unlink(path) == 0;
276 #endif
277 }
278
279 Boolean System::renameFile(const char* oldPath, const char* newPath)
280 {
281 #if defined(PEGASUS_OS_OS400)
282 if (QlgLink(QlgPath(oldPath), QlgPath(newPath)) != 0)
283 return false;
284
285 return QlgUnlink(QlgPath(oldPath)) == 0;
|
286 carson.hovey 1.5 #elif defined(PEGASUS_OS_VMS)
|
287 carson.hovey 1.3 // Note: link() on OpenVMS has a different meaning so rename is used.
288 // unlink() is a synonym for remove() so it can be used.
|
289 mike 1.2 if (rename(oldPath, newPath) != 0)
290 return false;
291
292 return true;
293 #else
294 if (link(oldPath, newPath) != 0)
295 return false;
296
297 return unlink(oldPath) == 0;
298 #endif
299 }
300
301 String System::getHostName()
302 {
303 static char _hostname[PEGASUS_MAXHOSTNAMELEN + 1];
304 static MutexType _mutex = PEGASUS_MUTEX_INITIALIZER;
305
306 // Use double-checked locking pattern to avoid overhead of
307 // mutex on subsequenct calls.
308
309 if (_hostname[0] == '\0')
310 mike 1.2 {
311 mutex_lock(&_mutex);
312
313 if (_hostname[0] == '\0')
314 {
315 gethostname(_hostname, sizeof(_hostname));
316 _hostname[sizeof(_hostname)-1] = 0;
317 #if defined(PEGASUS_OS_OS400)
318 EtoA(_hostname);
319 #endif
320 }
321
322 mutex_unlock(&_mutex);
323 }
324
325 return _hostname;
326 }
327
328 static int _getHostByName(
329 const char* hostName,
330 char* hostNameOut,
331 mike 1.2 size_t hostNameOutSize)
332 {
333 struct hostent *hostEntry;
334
335 #if defined(PEGASUS_OS_LINUX)
336
337 char hostEntryBuffer[8192];
338 struct hostent hostEntryStruct;
339 int hostEntryErrno;
340
341 gethostbyname_r(
342 hostName,
343 &hostEntryStruct,
344 hostEntryBuffer,
345 sizeof(hostEntryBuffer),
346 &hostEntry,
347 &hostEntryErrno);
348
349 #elif defined(PEGASUS_OS_SOLARIS)
350
351 char hostEntryBuffer[8192];
352 mike 1.2 struct hostent hostEntryStruct;
353 int hostEntryErrno;
354
355 hostEntry = gethostbyname_r(
356 hostName,
357 &hostEntryStruct,
358 hostEntryBuffer,
359 sizeof(hostEntryBuffer),
360 &hostEntryErrno);
361
362 #else /* default */
363
364 hostEntry = gethostbyname(hostName);
365
366 #endif
367
368 if (hostEntry)
369 {
370 strncpy(hostNameOut, hostEntry->h_name, hostNameOutSize - 1);
371 return 0;
372 }
373 mike 1.2
374 return -1;
375 }
376
377 String System::getFullyQualifiedHostName ()
378 {
379 #if defined(PEGASUS_OS_ZOS)
380
381 char hostName[PEGASUS_MAXHOSTNAMELEN + 1];
382 String fqName;
383 struct addrinfo *resolv;
384 struct addrinfo hint;
385 struct hostent *he;
386 // receive short name of the local host
387 if (gethostname(hostName, PEGASUS_MAXHOSTNAMELEN) != 0)
388 {
389 return String::EMPTY;
390 }
391 resolv = new struct addrinfo;
392 hint.ai_flags = AI_CANONNAME;
393 hint.ai_family = AF_UNSPEC; // any family
394 mike 1.2 hint.ai_socktype = 0; // any socket type
395 hint.ai_protocol = 0; // any protocol
396 int success = getaddrinfo(hostName,
397 NULL,
398 &hint,
399 &resolv);
400 if (success==0)
401 {
402 // assign fully qualified hostname
403 fqName.assign(resolv->ai_canonname);
404 } else
405 {
406 if ((he = gethostbyname(hostName)))
407 {
408 strcpy (hostName, he->h_name);
409 }
410 // assign hostName
411 // if gethostbyname was successful assign that result
412 // else assign unqualified hostname
413 fqName.assign(hostName);
414 }
415 mike 1.2 freeaddrinfo(resolv);
416 delete resolv;
417
418 return fqName;
419
420 #else /* !PEGASUS_OS_ZOS */
421
422 char hostName[PEGASUS_MAXHOSTNAMELEN + 1];
423
424 if (gethostname(hostName, sizeof(hostName)) != 0)
425 return String::EMPTY;
426
427 hostName[sizeof(hostName)-1] = 0;
428
429 _getHostByName(hostName, hostName, sizeof(hostName));
430
431 # if defined(PEGASUS_OS_OS400)
432 EtoA(hostName);
433 # endif
434
435 return String(hostName);
436 mike 1.2
437 #endif /* !PEGASUS_OS_ZOS */
438 }
439
440 String System::getSystemCreationClassName ()
441 {
442 //
443 // The value returned should match the value of the CreationClassName key
444 // property used in the instrumentation of the CIM_ComputerSystem class
445 // as determined by the provider for the CIM_ComputerSystem class
446 //
447 return "CIM_ComputerSystem";
448 }
449
450 Uint32 System::lookupPort(
451 const char * serviceName,
452 Uint32 defaultPort)
453 {
454 Uint32 localPort;
455
456 struct servent *serv;
457 mike 1.2
458 //
459 // Get wbem-local port from /etc/services
460 //
461
462 #if defined(PEGASUS_OS_SOLARIS)
463 # define SERV_BUFF_SIZE 1024
464 struct servent serv_result;
465 char buf[SERV_BUFF_SIZE];
466
467 if ( (serv = getservbyname_r(serviceName, TCP, &serv_result,
468 buf, SERV_BUFF_SIZE)) != NULL )
469 #elif defined(PEGASUS_OS_OS400)
470 struct servent serv_result;
471 serv = &serv_result;
472 struct servent_data buf;
473 memset(&buf, 0x00, sizeof(struct servent_data));
474
475 char srvnameEbcdic[256];
476 strcpy(srvnameEbcdic, serviceName);
477 AtoE(srvnameEbcdic);
478 mike 1.2
479 char tcpEbcdic[64];
480 strcpy(tcpEbcdic, TCP);
481 AtoE(tcpEbcdic);
482
483 if ( (getservbyname_r(srvnameEbcdic, tcpEbcdic, &serv_result,
484 &buf)) == 0 )
485 #else // PEGASUS_OS_SOLARIS
486 if ( (serv = getservbyname(serviceName, TCP)) != NULL )
487 #endif // PEGASUS_OS_SOLARIS
488 {
489 localPort = htons((uint16_t)serv->s_port);
490 }
491 else
492 {
493 localPort = defaultPort;
494 }
495
496 return localPort;
497 }
498
499 mike 1.2 #if defined(PEGASUS_OS_LSB)
500
501 /*
502 getpass equivalent.
503 Adapted from example implementation described in GLIBC documentation
504 (http://www.dusek.ch/manual/glibc/libc_32.html) and
505 "Advanced Programming in the UNIX Environment" by Richard Stevens,
506 pg. 350.
507
508 */
509 char *getpassword(const char *prompt)
510 {
511 const size_t MAX_PASS_LEN = 1024;
512 static char buf[MAX_PASS_LEN];
513 struct termios old, new_val;
514 char *ptr;
515 int c;
516
517 buf[0] = 0;
518
519 /* Turn echoing off and fail if we can't. */
520 mike 1.2 if (tcgetattr (fileno (stdin), &old) != 0)
521 return buf;
522 new_val = old;
523 new_val.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
524 if (tcsetattr (fileno (stdin), TCSAFLUSH, &new_val) != 0)
525 return buf;
526
527 /* Read the password. */
528 fputs (prompt, stdin);
529 ptr = buf;
530 while ( (c = getc(stdin)) != EOF && c != '\n') {
531 if (ptr < &buf[MAX_PASS_LEN])
532 *ptr++ = c;
533 }
534 *ptr = 0;
535 putc('\n', stdin);
536
537 /* Restore terminal. */
538 (void) tcsetattr (fileno (stdin), TCSAFLUSH, &old);
539 fclose(stdin);
540 return buf;
541 mike 1.2 }
542
543 #endif /* PEGASUS_OS_LSB */
544
545 String System::getPassword(const char* prompt)
546 {
547 #if defined(PEGASUS_OS_VMS)
548
549 struct
550 {
551 short int numbuf;
552 char frst_char;
553 char rsv1;
554 long rsv2;
555 }
556 tahead;
557
558 typedef struct
559 { // I/O status block
560 short i_cond; // Condition value
561 short i_xfer; // Transfer count
562 mike 1.2 long i_info; // Device information
563 }
564 iosb;
565
566 typedef struct
567 { // Terminal characteristics
568 char t_class; // Terminal class
569 char t_type; // Terminal type
570 short t_width; // Terminal width in characters
571 long t_mandl; // Terminal's mode and length
572 long t_extend; // Extended terminal characteristics
573 }
574 termb;
575
576 termb otermb;
577 termb ntermb;
578
579 static long ichan; // Gets channel number for TT:
580
581 register int errorcode;
582 int kbdflgs; // saved keyboard fd flags
583 mike 1.2 int kbdpoll; // in O_NDELAY mode
584 int kbdqp = false; // there is a char in kbdq
585 int psize; // size of the prompt
586
587 const size_t MAX_PASS_LEN = 32;
588 static char buf[MAX_PASS_LEN];
589 char kbdq; // char we've already read
590
591 iosb iostatus;
592
593 static long termset[2] = { 0, 0 }; // No terminator
594
595 $DESCRIPTOR(inpdev, "TT"); // Terminal to use for input
596
597 // Get a channel for the terminal
598
599 buf[0] = 0;
600
601 errorcode = sys$assign(&inpdev, // Device name
602 &ichan, // Channel assigned
603 0, // request KERNEL mode access
604 mike 1.2 0); // No mailbox assigned
605
606 if (errorcode != SS$_NORMAL)
607 {
608 return buf;
609 }
610
611 // Read current terminal settings
612
613 errorcode = sys$qiow(0, // Wait on event flag zero
614 ichan, // Channel to input terminal
615 IO$_SENSEMODE, // Function - Sense Mode
616 &iostatus, // Status after operation
617 0, 0, // No AST service
618 &otermb, // [P1] Address of Char Buffer
619 sizeof (otermb), // [P2] Size of Char Buffer
620 0, 0, 0, 0); // [P3] - [P6]
621
622 if (errorcode != SS$_NORMAL)
623 {
624 return buf;
625 mike 1.2 }
626
627 // setup new settings
628
629 ntermb = otermb;
630
631 // turn on passthru and nobroadcast
632
633 ntermb.t_extend |= TT2$M_PASTHRU;
634 ntermb.t_mandl |= TT$M_NOBRDCST;
635
636 // Write out new terminal settings
637
638 errorcode = sys$qiow(0, // Wait on event flag zero
639 ichan, // Channel to input terminal
640 IO$_SETMODE, // Function - Set Mode
641 &iostatus, // Status after operation
642 0, 0, // No AST service
643 &ntermb, // [P1] Address of Char Buffer
644 sizeof (ntermb), // [P2] Size of Char Buffer
645 0, 0, 0, 0); // [P3] - [P6]
646 mike 1.2
647 if (errorcode != SS$_NORMAL)
648 {
649 return buf;
650 }
651
652 // Write a prompt, read characters from the terminal, performing no
653 // editing
654 // and doing no echo at all.
655
656 psize = strlen(prompt);
657
658 errorcode = sys$qiow(0, // Event flag
659 ichan, // Input channel
660 IO$_READPROMPT | IO$M_NOECHO | IO$M_NOFILTR |
661 IO$M_TRMNOECHO,
662 // Read with prompt, no echo, no translate, no
663 // termination character echo
664 &iostatus, // I/O status block
665 NULL, // AST block (none)
666 0, // AST parameter
667 mike 1.2 &buf, // P1 - input buffer
668 MAX_PASS_LEN, // P2 - buffer length
669 0, // P3 - ignored (timeout)
670 0, // P4 - ignored (terminator char set)
671 prompt, // P5 - prompt buffer
672 psize); // P6 - prompt size
673
674 if (errorcode != SS$_NORMAL)
675 {
676 return buf;
677 }
678
679 // Write out old terminal settings
680 errorcode = sys$qiow(0, // Wait on event flag zero
681 ichan, // Channel to input terminal
682 IO$_SETMODE, // Function - Set Mode
683 &iostatus, // Status after operation
684 0, 0, // No AST service
685 &otermb, // [P1] Address of Char Buffer
686 sizeof (otermb), // [P2] Size of Char Buffer
687 0, 0, 0, 0); // [P3] - [P6]
688 mike 1.2
689 if (errorcode != SS$_NORMAL)
690 {
691 return buf;
692 }
693
694 // Start new line
695
696 const int CR = 0x0d;
697 const int LF = 0x0a;
698 fputc(CR, stdout);
699 fputc(LF, stdout);
700
701 // Remove the termination character
702 psize = strlen(buf);
703 buf[psize - 1] = 0;
704
705 return buf;
706
707 #elif defined(PEGASUS_OS_OS400)
708
709 mike 1.2 // Not supported on OS/400, and we don't need it.
710 // 'getpass' is DEPRECATED
711 return String();
712
713 #elif defined(PEGASUS_OS_LSB)
714
715 return String(getpassword(prompt));
716
717 #else /* default */
718
719 return String(getpass(prompt));
720
721 #endif /* default */
722 }
723
724 String System::getEffectiveUserName()
725 {
726 String userName = String::EMPTY;
727 struct passwd* pwd = NULL;
728
729 #if defined(PEGASUS_OS_SOLARIS) || \
730 mike 1.2 defined(PEGASUS_OS_HPUX) || \
731 defined(PEGASUS_OS_LINUX) || \
732 defined(PEGASUS_OS_OS400)
733
734 const unsigned int PWD_BUFF_SIZE = 1024;
735 struct passwd local_pwd;
736 char buf[PWD_BUFF_SIZE];
737
738 if(getpwuid_r(geteuid(), &local_pwd, buf, PWD_BUFF_SIZE, &pwd) != 0)
739 {
740 String errorMsg = String("getpwuid_r failure : ") +
741 String(strerror(errno));
742 PEG_TRACE_STRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2, errorMsg);
743 // L10N TODO - This message needs to be added.
744 //Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::WARNING,
745 // errorMsg);
746 }
747 #elif defined(PEGASUS_OS_ZOS)
748 char effective_username[9];
749 __getuserid(effective_username, 9);
750 __etoa_l(effective_username,9);
751 mike 1.2 userName.assign(effective_username);
752 return userName;
753 #else
754 //
755 // get the currently logged in user's UID.
756 //
757 pwd = getpwuid(geteuid());
758 #endif
759 if (pwd == NULL)
760 {
761 // L10N TODO - This message needs to be added.
762 //Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::WARNING,
763 // "getpwuid_r failure, user may have been removed just after login");
764 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL4,
765 "getpwuid_r failure, user may have been removed just after login");
766 }
767 else
768 {
769 #if defined(PEGASUS_OS_OS400)
770 EtoA(pwd->pw_name);
771 #endif
772 mike 1.2 //
773 // get the user name
774 //
775 userName.assign(pwd->pw_name);
776 }
777
778 return(userName);
779 }
780
781 String System::encryptPassword(const char* password, const char* salt)
782 {
|
783 carson.hovey 1.3 #if defined(PEGASUS_OS_VMS)
|
784 mike 1.2
785 const size_t MAX_PASS_LEN = 1024;
786 char pbBuffer[MAX_PASS_LEN] = {0};
787 int dwByteCount;
788 char pcSalt[3] = {0};
789
790 strncpy(pcSalt, salt, 2);
791 dwByteCount = strlen(password);
792 memcpy(pbBuffer, password, dwByteCount);
793
794 for (int i=0; (i<dwByteCount) || (i>=MAX_PASS_LEN); i++)
795 {
796 (i%2 == 0) ? pbBuffer[i] ^= pcSalt[1] : pbBuffer[i] ^= pcSalt[0];
797 }
798
799 return String(pcSalt) + String((char *)pbBuffer);
800
|
801 carson.hovey 1.3 #elif !defined(PEGASUS_OS_OS400)
802
803 return ( String(crypt( password,salt)) );
804
|
805 mike 1.2 #else
806
807 // Not supported on OS400, and we don't need it.
808 return ( String(password) );
809
810 #endif
811 }
812
813 Boolean System::isSystemUser(const char* userName)
814 {
815 #if defined(PEGASUS_OS_SOLARIS) || \
816 defined(PEGASUS_OS_HPUX) || \
817 defined(PEGASUS_OS_LINUX) || \
818 defined(PEGASUS_OS_OS400)
819
820 const unsigned int PWD_BUFF_SIZE = 1024;
821 struct passwd pwd;
822 struct passwd *result;
823 char pwdBuffer[PWD_BUFF_SIZE];
824
825 if (getpwnam_r(userName, &pwd, pwdBuffer, PWD_BUFF_SIZE, &result) != 0)
826 mike 1.2 {
827 String errorMsg = String("getpwnam_r failure : ") +
828 String(strerror(errno));
829 PEG_TRACE_STRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2, errorMsg);
830 // L10N TODO - This message needs to be added.
831 //Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::WARNING,
832 // errorMsg);
833 }
834
835 if (result == NULL)
836 return false;
837
838 return true;
839
840 #elif defined(PEGASUS_OS_OS400)
841
842 AtoE((char*)userName);
843
844 if (getpwnam(userName) == NULL)
845 {
846 EtoA((char*)userName);
847 mike 1.2 return false;
848 }
849
850 EtoA((char*)userName);
851 return true;
852
853 #else /* default */
854
855 return getpwnam(userName) != NULL;
856
857 #endif /* default */
858 }
859
860 Boolean System::isPrivilegedUser(const String& userName)
861 {
862 #if !defined(PEGASUS_OS_OS400)
863 struct passwd pwd;
864 struct passwd *result;
865 const unsigned int PWD_BUFF_SIZE = 1024;
866 char pwdBuffer[PWD_BUFF_SIZE];
867
868 mike 1.2 if (getpwnam_r(
869 userName.getCString(), &pwd, pwdBuffer, PWD_BUFF_SIZE, &result) != 0)
870 {
871 String errorMsg = String("getpwnam_r failure : ") +
872 String(strerror(errno));
873 PEG_TRACE_STRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2, errorMsg);
874 // L10N TODO - This message needs to be added.
875 //Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::WARNING,
876 // errorMsg);
877 }
878
879 // Check if the requested entry was found. If not return false.
880 if ( result != NULL )
881 {
882 // Check if the uid is 0.
883 if ( pwd.pw_uid == 0 )
884 {
885 return true;
886 }
887 }
888 return false;
889 mike 1.2
890 #elif defined(PEGASUS_OS_VMS)
891
892 int retStat;
893
894 unsigned long int prvPrv = 0;
895 retStat = sys$setprv(0, 0, 0, &prvPrv);
896
897 if (!$VMS_STATUS_SUCCESS(retStat))
898 return false;
899
900 // ATTN-VMS: should this be a bitwise and?
901 return ((PRV$M_SETPRV && prvPrv) == 1) ? true : false;
902
903 #else /* default */
904
905 CString user = userName.getCString();
906 const char * tmp = (const char *)user;
907 AtoE((char *)tmp);
908 return ycmCheckUserCmdAuthorities(tmp);
909
910 mike 1.2 #endif /* default */
911 }
912
913 static String _priviledgedUserName;
914 static Once _priviledgedUserNameOnce = PEGASUS_ONCE_INITIALIZER;
915
916 static void _initPrivilegedUserName()
917 {
918 struct passwd* pwd = NULL;
919
920 #if defined(PEGASUS_OS_SOLARIS) || \
921 defined(PEGASUS_OS_HPUX) || \
922 defined(PEGASUS_OS_LINUX) || \
923 defined(PEGASUS_OS_OS400)
924
925 const unsigned int PWD_BUFF_SIZE = 1024;
926 struct passwd local_pwd;
927 char buf[PWD_BUFF_SIZE];
928
929 if (getpwuid_r(0, &local_pwd, buf, PWD_BUFF_SIZE, &pwd) != 0)
930 {
931 mike 1.2 String errorMsg = String("getpwuid_r failure : ") +
932 String(strerror(errno));
933 PEG_TRACE_STRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2, errorMsg);
934 // L10N TODO - This message needs to be added.
935 // Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::WARNING,
936 // errorMsg);
937 }
938
939 #else /* default */
940
941 pwd = getpwuid(0);
942
943 #endif /* default */
944
945 if ( pwd != NULL )
946 {
947 #if defined(PEGASUS_OS_OS400)
948 EtoA(pwd->pw_name);
949 #endif
950 _priviledgedUserName.assign(pwd->pw_name);
951 }
952 mike 1.2 else
953 {
954 Tracer::trace (
955 TRC_OS_ABSTRACTION, Tracer::LEVEL4, "Could not find entry.");
956 PEGASUS_ASSERT(0);
957 }
958 }
959
960 String System::getPrivilegedUserName()
961 {
962 once(&_priviledgedUserNameOnce, _initPrivilegedUserName);
963 return _priviledgedUserName;
964 }
965
966 #if !defined(PEGASUS_OS_VMS) || defined(PEGASUS_ENABLE_USERGROUP_AUTHORIZATION)
967
968 Boolean System::isGroupMember(const char* userName, const char* groupName)
969 {
970 struct group grp;
971 char* member;
972 Boolean retVal = false;
973 mike 1.2 const unsigned int PWD_BUFF_SIZE = 1024;
974 const unsigned int GRP_BUFF_SIZE = 1024;
975 struct passwd pwd;
976 struct passwd* result;
977 struct group* grpresult;
978 char pwdBuffer[PWD_BUFF_SIZE];
979 char grpBuffer[GRP_BUFF_SIZE];
980
981 // Search Primary group information.
982
983 // Find the entry that matches "userName"
984
985 if (getpwnam_r(userName, &pwd, pwdBuffer, PWD_BUFF_SIZE, &result) != 0)
986 {
987 String errorMsg = String("getpwnam_r failure : ") +
988 String(strerror(errno));
989 PEG_TRACE_STRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2, errorMsg);
990 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::WARNING,
991 errorMsg);
992 throw InternalSystemError();
993 }
994 mike 1.2
995 if ( result != NULL )
996 {
997 // User found, check for group information.
998 gid_t group_id;
999 group_id = pwd.pw_gid;
1000
1001 // Get the group name using group_id and compare with group passed.
1002 if ( getgrgid_r(group_id, &grp,
1003 grpBuffer, GRP_BUFF_SIZE, &grpresult) != 0)
1004 {
1005 String errorMsg = String("getgrgid_r failure : ") +
1006 String(strerror(errno));
1007 PEG_TRACE_STRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2, errorMsg);
1008 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::WARNING,
1009 errorMsg);
1010 throw InternalSystemError();
1011 }
1012
1013 // Compare the user's group name to groupName.
1014 if ( strcmp (grp.gr_name, groupName) == 0 )
1015 mike 1.2 {
1016 // User is a member of the group.
1017 return true;
1018 }
1019 }
1020
1021 //
1022 // Search supplemental groups.
1023 // Get a user group entry
1024 //
1025 if (getgrnam_r((char *)groupName, &grp,
1026 grpBuffer, GRP_BUFF_SIZE, &grpresult) != 0)
1027 {
1028 String errorMsg = String("getgrnam_r failure : ") +
1029 String(strerror(errno));
1030 PEG_TRACE_STRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2, errorMsg);
1031 Logger::put(
1032 Logger::STANDARD_LOG, "CIMServer", Logger::WARNING, errorMsg);
1033 throw InternalSystemError();
1034 }
1035
1036 mike 1.2 // Check if the requested group was found.
1037 if (grpresult == NULL)
1038 {
1039 return false;
1040 }
1041
1042 Uint32 j = 0;
1043
1044 //
1045 // Get all the members of the group
1046 //
1047 member = grp.gr_mem[j++];
1048
1049 while (member)
1050 {
1051 //
1052 // Check if the user is a member of the group
1053 //
1054 if ( strcmp(userName, member) == 0 )
1055 {
1056 retVal = true;
1057 mike 1.2 break;
1058 }
1059 member = grp.gr_mem[j++];
1060 }
1061
1062 return retVal;
1063 }
1064
1065 #endif /* !PEGASUS_OS_VMS || PEGASUS_ENABLE_USERGROUP_AUTHORIZATION */
1066
1067 #ifndef PEGASUS_OS_OS400
1068
1069 Boolean System::lookupUserId(
1070 const char* userName,
1071 PEGASUS_UID_T& uid,
1072 PEGASUS_GID_T& gid)
1073 {
1074 const unsigned int PWD_BUFF_SIZE = 1024;
1075 struct passwd pwd;
1076 struct passwd *result;
1077 char pwdBuffer[PWD_BUFF_SIZE];
1078 mike 1.2
1079 # if defined(PEGASUS_OS_OS400)
1080 AtoE((char *)userName);
1081 # endif
1082
1083 int rc = getpwnam_r(userName, &pwd, pwdBuffer, PWD_BUFF_SIZE, &result);
1084
1085 # if defined(PEGASUS_OS_OS400)
1086 EtoA((char *)userName);
1087 # endif
1088
1089 if (rc != 0)
1090 {
1091 PEG_TRACE_STRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2,
1092 String("getpwnam_r failed: ") + String(strerror(errno)));
1093 return false;
1094 }
1095
1096 if (result == 0)
1097 {
1098 PEG_TRACE_STRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2,
1099 mike 1.2 "getpwnam_r failed.");
1100 return false;
1101 }
1102
1103 uid = pwd.pw_uid;
1104 gid = pwd.pw_gid;
1105
1106 return true;
1107 }
1108
1109 Boolean System::changeUserContext(
1110 const PEGASUS_UID_T& uid,
1111 const PEGASUS_GID_T& gid)
1112 {
1113 Tracer::trace(TRC_OS_ABSTRACTION, Tracer::LEVEL4,
1114 "Changing user context to: uid = %d, gid = %d",
1115 (int)uid, (int)gid);
1116
1117 if (setgid(gid) != 0)
1118 {
1119 PEG_TRACE_STRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2,
1120 mike 1.2 String("setgid failed: ") + String(strerror(errno)));
1121 return false;
1122 }
1123
1124 if (setuid(uid) != 0)
1125 {
1126 PEG_TRACE_STRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2,
1127 String("setuid failed: ") + String(strerror(errno)));
1128 return false;
1129 }
1130
1131 return true;
1132 }
1133
1134 #endif /* PEGASUS_OS_OS400 */
1135
1136 Uint32 System::getPID()
1137 {
1138 return getpid();
1139 }
1140
1141 mike 1.2 Boolean System::truncateFile(
1142 const char* path,
1143 size_t newSize)
1144 {
1145 #if defined(PEGASUS_OS_OS400)
1146 int fd = QlgOpen(QlgPath(path), O_WRONLY);
1147
1148 if (fd != -1)
1149 {
1150 int rc = ftruncate(fd, newSize);
1151 close(fd);
1152 return (rc == 0);
1153 }
1154
1155 return false;
1156 #else
1157 return (truncate(path, newSize) == 0);
1158 #endif
1159 }
1160
1161 Boolean System::is_absolute_path(const char *path)
1162 mike 1.2 {
1163 if (path == NULL)
1164 return false;
1165
1166 if (path[0] == '/')
1167 return true;
1168
1169 return false;
1170 }
1171
1172 Boolean System::changeFilePermissions(const char* path, mode_t mode)
1173 {
1174 Sint32 ret = 0;
1175 const char * tmp = path;
1176
1177 #if defined(PEGASUS_OS_OS400)
1178 // ATTN: Update this code to handle UTF8 when path contains UTF8
1179 AtoE((char *)tmp);
1180 #endif
1181
1182 return chmod(tmp, mode) == 0 ? true : false;
1183 mike 1.2 }
1184
1185 Boolean System::verifyFileOwnership(const char* path)
1186 {
1187 struct stat st;
1188
1189 #if defined(PEGASUS_OS_OS400)
1190 if (QlgStat(QlgPath(path), &st) != 0)
1191 return false;
1192 #else
1193 if (lstat(path, &st) != 0)
1194 return false;
1195 #endif
1196
1197 return ((st.st_uid == geteuid()) && // Verify the file owner
1198 S_ISREG(st.st_mode) && // Verify it is a regular file
1199 (st.st_nlink == 1)); // Verify it is not a hard link
1200 }
1201
1202 void System::syslog(const String& ident, Uint32 severity, const char* message)
1203 {
1204 mike 1.2 #if defined(PEGASUS_OS_HPUX) || defined(PEGASUS_OS_LINUX)
1205
1206 // Since the openlog(), syslog(), and closelog() function calls must be
1207 // coordinated (see below), we need a thread control.
1208
1209 static Mutex logMutex;
1210
1211 AutoMutex loglock(logMutex);
1212
1213 // Get a const char* representation of the identifier string. Note: The
1214 // character string passed to the openlog() function must persist until
1215 // closelog() is called. The syslog() method uses this pointer directly
1216 // rather than a copy of the string it refers to.
1217
1218 CString identCString = ident.getCString();
1219 openlog(identCString, LOG_PID, LOG_DAEMON);
1220
1221 // Map from the Logger log level to the system log level.
1222
1223 Uint32 syslogLevel;
1224 if (severity & Logger::FATAL)
1225 mike 1.2 {
1226 syslogLevel = LOG_CRIT;
1227 }
1228 else if (severity & Logger::SEVERE)
1229 {
1230 syslogLevel = LOG_ERR;
1231 }
1232 else if (severity & Logger::WARNING)
1233 {
1234 syslogLevel = LOG_WARNING;
1235 }
1236 else if (severity & Logger::INFORMATION)
1237 {
1238 syslogLevel = LOG_INFO;
1239 }
1240 else // if (severity & Logger::TRACE)
1241 {
1242 syslogLevel = LOG_DEBUG;
1243 }
1244
1245 // Write the message to the system log.
1246 mike 1.2
1247 ::syslog(syslogLevel, "%s", message);
1248
1249 closelog();
1250
1251 #elif defined(PEGASUS_OS_OS400)
1252
1253 std::string replacementData = message;
1254 // All messages will go to the joblog. In the future
1255 // some messages may go to other message queues yet
1256 // to be determined.
1257 if ((severity & Logger::TRACE) ||
1258 (severity & Logger::INFORMATION))
1259 {
1260
1261 // turn into ycmMessage so we can put it in the job log
1262 # pragma convert(37)
1263 ycmMessage theMessage("CPIDF80",
1264 message,
1265 strlen(message),
1266 "Logger",
1267 mike 1.2 ycmCTLCIMID,
1268 TRUE);
1269 # pragma convert(0)
1270
1271 // put the message in the joblog
1272 theMessage.joblogIt(UnitOfWorkError,
1273 ycmMessage::Informational);
1274 }
1275
1276 if ((severity & Logger::WARNING) ||
1277 (severity & Logger::SEVERE) ||
1278 (severity & Logger::FATAL))
1279 {
1280 // turn into ycmMessage so we can put it in the job log
1281 # pragma convert(37)
1282 ycmMessage theMessage("CPDDF82",
1283 message,
1284 strlen(message),
1285 "Logger",
1286 ycmCTLCIMID,
1287 TRUE);
1288 mike 1.2 # pragma convert(0)
1289 // put the message in the joblog
1290 theMessage.joblogIt(UnitOfWorkError,
1291 ycmMessage::Diagnostic);
1292 }
1293
1294 #else /* default */
1295
1296 // Not implemented!
1297
1298 #endif /* default */
1299 }
1300
|
1301 kumpf 1.6
1302 ///////////////////////////////////////////////////////////////////////////////
1303 // AutoFileLock class
1304 ///////////////////////////////////////////////////////////////////////////////
1305
1306 AutoFileLock::AutoFileLock(const char* fileName)
1307 {
1308 #ifdef PEGASUS_OS_TYPE_UNIX
1309 _fl.l_type = F_WRLCK;
1310 _fl.l_whence = SEEK_SET;
1311 _fl.l_start = 0;
1312 _fl.l_len = 0;
1313 _fl.l_pid = getpid();
1314
1315 do
1316 {
1317 _fd = open(fileName, O_WRONLY);
1318 } while ((_fd == -1) && (errno == EINTR));
1319
1320 if (_fd != -1)
1321 {
1322 kumpf 1.6 int rc;
1323
1324 do
1325 {
1326 rc = fcntl(_fd, F_SETLKW, &_fl);
1327 } while ((rc == -1) && (errno == EINTR));
1328
1329 if (rc == -1)
1330 {
1331 Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
1332 "AutoFileLock: Failed to lock file '%s', error code %d.",
1333 fileName, errno);
1334 _fd = -1;
1335 }
1336 }
1337 else
1338 {
1339 Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
1340 "AutoFileLock: Failed to open lock file '%s', error code %d.",
1341 fileName, errno);
1342 }
1343 kumpf 1.6 #endif
1344 }
1345
1346 AutoFileLock::~AutoFileLock()
1347 {
1348 #ifdef PEGASUS_OS_TYPE_UNIX
1349 if (_fd != -1)
1350 {
1351 _fl.l_type = F_UNLCK;
1352 int rc = fcntl(_fd, F_SETLK, &_fl);
1353 if (rc == -1)
1354 {
1355 Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
1356 "AutoFileLock: Failed to unlock file, error code %d.",
1357 errno);
1358 }
1359 close(_fd);
1360 }
1361 #endif
1362 }
1363
1364 kumpf 1.6
|
1365 mike 1.2 //==============================================================================
1366 //
1367 // PEGASUS_OS_AIX
1368 //
1369 //==============================================================================
1370
1371 // System Initializater for AIX
1372 #ifdef PEGASUS_OS_AIX
1373 # include <cstdlib>
1374
1375 class SystemInitializer
1376 {
1377
1378 public:
1379 /**
1380 *
1381 * Default constructor.
1382 *
1383 */
1384 SystemInitializer();
1385 };
1386 mike 1.2
1387 SystemInitializer::SystemInitializer()
1388 {
1389 putenv("XPG_SUS_ENV=ON");
1390 }
1391
1392 static SystemInitializer initializer;
1393
1394 #endif /* PEGASUS_OS_AIX */
1395
1396 PEGASUS_NAMESPACE_END
|