(file) Return to SystemVms.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

  1 john.eisenbraun 1.21 //%LICENSE////////////////////////////////////////////////////////////////
  2 gs.keenan       1.1  //
  3 john.eisenbraun 1.21 // Licensed to The Open Group (TOG) under one or more contributor license
  4                      // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
  5                      // this work for additional information regarding copyright ownership.
  6                      // Each contributor licenses this file to you under the OpenPegasus Open
  7                      // Source License; you may not use this file except in compliance with the
  8                      // License.
  9 gs.keenan       1.1  //
 10 john.eisenbraun 1.21 // Permission is hereby granted, free of charge, to any person obtaining a
 11                      // copy of this software and associated documentation files (the "Software"),
 12                      // to deal in the Software without restriction, including without limitation
 13                      // the rights to use, copy, modify, merge, publish, distribute, sublicense,
 14                      // and/or sell copies of the Software, and to permit persons to whom the
 15                      // Software is furnished to do so, subject to the following conditions:
 16 gs.keenan       1.1  //
 17 john.eisenbraun 1.21 // The above copyright notice and this permission notice shall be included
 18                      // in all copies or substantial portions of the Software.
 19 gs.keenan       1.1  //
 20 john.eisenbraun 1.21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 21                      // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 22                      // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 23                      // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 24                      // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 25                      // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 26                      // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 27 gs.keenan       1.1  //
 28 john.eisenbraun 1.21 //////////////////////////////////////////////////////////////////////////
 29 gs.keenan       1.1  //
 30                      //%/////////////////////////////////////////////////////////////////////////////
 31                      
 32 john.eisenbraun 1.21 #include <descrip.h>           //  $DESCRIPTOR
 33                      #include <iodef.h>             // IO$_SENSEMODE
 34                      #include <ttdef.h>             // TT$M_NOBRDCST
 35                      #include <tt2def.h>            // TT2$M_PASTHRU
 36 gs.keenan       1.1  #include <starlet.h>
 37 john.eisenbraun 1.21 #include <ssdef.h>             // SS$_NORMAL
 38                      #include <stsdef.h>            // VMS_STATUS_SUCCESS
 39 john.eisenbraun 1.22 #include <chpdef.h>            // CHP$_
 40                      #include <armdef.h>            // ARM$_
 41                      #include <prvdef.h>            // PRV$M_SETPRV
 42                      #include <unixlib.h>
 43                      #include <rms.h>
 44 gs.keenan       1.1  
 45                      PEGASUS_NAMESPACE_BEGIN
 46                      
 47 john.eisenbraun 1.21 //==============================================================================
 48                      //
 49                      // System
 50                      //
 51                      //==============================================================================
 52 gs.keenan       1.7  
 53 john.eisenbraun 1.22 static String vmsPath;
 54                      static Mutex vmsPathMutex(Mutex::NON_RECURSIVE);
 55                      
 56 john.eisenbraun 1.23 static char* toVmsDir(const char* path)
 57                      {
 58                          char* dirend;
 59                          char* dirstart;
 60                          char* dir_path;
 61                          dirend = strrchr(path, '.');
 62                          if (dirend)
 63                          {
 64                              dir_path = new char[strlen(path) + sizeof("DIR")];
 65                              strcpy(dir_path, path);
 66                              dirend = strrchr(dir_path, '.');
 67                              *dirend = ']';
 68                              dirend = strrchr(dir_path, ']');
 69                              *dirend = '\0';
 70                              strcat(dir_path, ".DIR");
 71                          }
 72                          else
 73                          {
 74                              dir_path = new char[strlen(path) + sizeof("[000000].DIR")];
 75                              dirstart = strchr(path, '[');
 76                              if (dirstart) // Top level directory
 77 john.eisenbraun 1.23         {
 78                                  strncpy(dir_path, path, dirstart-path);
 79                                  dir_path[dirstart-path] = '\0';
 80                                  strcat(dir_path, "[000000]"); // Top level directory
 81                                  strcat(dir_path, ++dirstart); // Add the directory name
 82                                  dirend = strrchr(dir_path, ']');
 83                                  *dirend = '\0';
 84                                  strcat(dir_path, ".DIR");
 85                              }
 86                              else
 87                              {
 88                                  delete dir_path;
 89                                  dir_path = 0;
 90                              }
 91                          }
 92                          return dir_path;
 93                      }
 94                      
 95 john.eisenbraun 1.22 static int action(char *path, int type_of_file)
 96                      {
 97 john.eisenbraun 1.23     int ret;
 98                          char *dir_path;
 99                      
100                          if (type_of_file == DECC$K_DIRECTORY)
101                          {
102                              dir_path = toVmsDir(path);
103                              if (dir_path)
104                              {
105                                  vmsPath = dir_path;
106                                  delete dir_path;
107                              }
108                              ret = dir_path != 0;
109                          }
110                          else
111                          {
112                              vmsPath = path;
113                              ret = 1;
114                          }
115                          return ret;
116 john.eisenbraun 1.22 }
117                      
118                      static int toVms(const char* path, String& vms_path)
119                      {
120 john.eisenbraun 1.23     char cwd[256]; // OpenVMS file can't be larger than 255 chars.
121                          char *result;
122                          char *dir_path;
123                          int ret;
124                      
125                          // Treat the current directory as a special case
126                      
127                          if ((strcmp(path, ".") == 0) || (strcmp(path, "./") == 0))
128                          {
129                              result = getcwd(cwd, sizeof(cwd), 1);
130                              if (!result) return 0;
131                              dir_path = toVmsDir(cwd);
132                              if (dir_path)
133                              {
134                                  vms_path = dir_path;
135                                  delete dir_path;
136                                  ret = 1;
137                              }
138                              else
139                                  ret = 0;
140                          }
141 john.eisenbraun 1.23     else if (strchr(path, '/') != 0)
142                          {
143                              AutoMutex pathLock(vmsPathMutex);
144                              ret = decc$to_vms(path, action, 0, 0);
145                              vms_path = vmsPath;
146                          }
147                          else
148                          {
149                              vms_path = path;
150                              ret = 1;
151                          }
152 john.eisenbraun 1.22     return ret;
153                      }
154                      
155                      static int canAccess(const char* path, int access_right)
156                      {
157                          struct itm
158                          {
159                              unsigned short bufLen;
160                              unsigned short itmCode;
161                              void *bufAddr;
162                              void *retAddr;
163                          };
164                      
165                          int retStat;
166                          int len;
167                      
168                          union armdef armval;
169                          struct FAB fab;
170                          struct XABPRO xabpro;
171                      
172                          struct
173 john.eisenbraun 1.22     {
174                              struct itm item[3];
175                              unsigned long term;
176                          } itmlst;
177                      
178                          String vms_path;
179                          CString cvms_path;
180                      
181                          // Convert the path to OpenVMS format (if necessary)
182                      
183 john.eisenbraun 1.23     retStat = toVms(path, vms_path);
184                      
185 john.eisenbraun 1.22     cvms_path = vms_path.getCString();
186                          len = strlen(cvms_path);
187                          if (len > 255) return SS$_FILACCERR;
188                      
189                          // Get the file protections
190                      
191                          fab = cc$rms_fab;
192                      
193                          fab.fab$l_fna = (char *) (const char *) cvms_path;
194                          fab.fab$b_fns = len;
195                          fab.fab$b_fac = FAB$M_GET;
196                          fab.fab$l_xab = &xabpro;
197                      
198                          xabpro.xab$b_cod = XAB$C_PRO;
199                          xabpro.xab$b_bln = XAB$C_PROLEN;
200                          xabpro.xab$w_aclsiz = 0;    // Not considering ACLs at this time
201                          xabpro.xab$l_aclbuf = 0;
202                          xabpro.xab$l_nxt = 0;
203                      
204                          retStat = sys$open(&fab, 0, 0);
205                          if (!$VMS_STATUS_SUCCESS(retStat))
206 john.eisenbraun 1.22     {
207                              if (retStat != RMS$_FNF)
208                              {
209                                  PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL1,
210                                      "sys$open error: %s", strerror(EVMSERR, retStat)));
211                              }
212                              return retStat;
213                          }
214                      
215                          sys$close(&fab, 0, 0);
216                      
217                          armval.arm$r_fill_47_.arm$l_file_access = access_right;
218                      
219                          itmlst.item[0].itmCode = CHP$_ACCESS;
220                          itmlst.item[0].bufLen = sizeof(armval);
221                          itmlst.item[0].bufAddr = &armval;
222                          itmlst.item[0].retAddr = 0;
223                          itmlst.item[1].itmCode = CHP$_OWNER;
224                          itmlst.item[1].bufLen = sizeof(xabpro.xab$l_uic);
225                          itmlst.item[1].bufAddr = &xabpro.xab$l_uic;
226                          itmlst.item[1].retAddr = 0;
227 john.eisenbraun 1.22     itmlst.item[2].itmCode = CHP$_PROT;
228                          itmlst.item[2].bufLen = sizeof(xabpro.xab$w_pro);
229                          itmlst.item[2].bufAddr = &xabpro.xab$w_pro;
230                          itmlst.item[2].retAddr = 0;
231                          itmlst.term = 0;
232                      
233                          retStat = sys$chkpro(&itmlst, 0, 0);
234                          if (!$VMS_STATUS_SUCCESS(retStat))
235                          {
236                              if (retStat != SS$_NOPRIV)
237                              {
238                                  PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL1,
239                                      "sys$chkpro error: %s", strerror(EVMSERR, retStat)));
240                              }
241                          }
242                      
243                          return retStat;
244                      }
245                      
246                      Boolean System::canRead(const char* path)
247                      {
248 john.eisenbraun 1.22     return canAccess(path, ARM$M_READ) == SS$_NORMAL;
249                      }
250                      
251                      Boolean System::canWrite(const char* path)
252                      {
253                          return canAccess(path, ARM$M_WRITE) == SS$_NORMAL;
254                      }
255                      
256 john.eisenbraun 1.21 String System::getPassword(const char* prompt)
257 gs.keenan       1.1  {
258 john.eisenbraun 1.21     struct
259                          {
260                              short int numbuf;
261                              char frst_char;
262                              char rsv1;
263                              long rsv2;
264                          }
265                          tahead;
266 gs.keenan       1.1  
267 john.eisenbraun 1.21     typedef struct
268                          {                           // I/O status block
269                              short i_cond;           // Condition value
270                              short i_xfer;           // Transfer count
271                              long i_info;            // Device information
272                          }
273                          iosb;
274 gs.keenan       1.1  
275 john.eisenbraun 1.21     typedef struct
276                          {                           // Terminal characteristics
277                              char t_class;           // Terminal class
278                              char t_type;            // Terminal type
279                              short t_width;          // Terminal width in characters
280                              long t_mandl;           // Terminal's mode and length
281                              long t_extend;          // Extended terminal characteristics
282                          }
283                          termb;
284 jim.wunderlich  1.16 
285 john.eisenbraun 1.21     termb otermb;
286                          termb ntermb;
287 gs.keenan       1.1  
288 john.eisenbraun 1.21     short int ichan;            // Gets channel number for TT:
289 gs.keenan       1.1  
290 john.eisenbraun 1.21     int errorcode;
291                          int kbdflgs;                // saved keyboard fd flags
292                          int kbdpoll;                // in O_NDELAY mode
293                          int kbdqp = false;          // there is a char in kbdq
294                          int psize;                  // size of the prompt
295 gs.keenan       1.1  
296 john.eisenbraun 1.21     const size_t MAX_PASS_LEN = 32;
297                          static char buf[MAX_PASS_LEN];
298                          char kbdq;                  // char we've already read
299 gs.keenan       1.1  
300 john.eisenbraun 1.21     iosb iostatus;
301 gs.keenan       1.1  
302 john.eisenbraun 1.21     static long termset[2] = { 0, 0 };  // No terminator
303 gs.keenan       1.1  
304 john.eisenbraun 1.21     $DESCRIPTOR(inpdev, "TT");  // Terminal to use for input
305 gs.keenan       1.1  
306 john.eisenbraun 1.21     buf[0] = 0;
307 gs.keenan       1.1  
308 john.eisenbraun 1.21     ichan = 0;
309 gs.keenan       1.1  
310 john.eisenbraun 1.21     try
311                          {
312                              // Get a channel for the terminal
313 gs.keenan       1.1  
314 john.eisenbraun 1.21         errorcode = sys$assign(&inpdev,     // Device name
315                                                     &ichan,      // Channel assigned
316                                                     0,   // request KERNEL mode access
317                                                     0);  // No mailbox assigned
318                      
319                              if (errorcode != SS$_NORMAL)
320                              {
321                                  throw Exception("sys$assign failure");
322                              }
323                      
324                              // Read current terminal settings
325                      
326                              errorcode = sys$qiow(0,     // Wait on event flag zero
327                                                   ichan, // Channel to input terminal
328                                                   IO$_SENSEMODE, // Function - Sense Mode
329                                                   &iostatus,     // Status after operation
330                                                   0, 0,  // No AST service
331                                                   &otermb,       // [P1] Address of Char Buffer
332                                                   sizeof (otermb),       // [P2] Size of Char Buffer
333                                                   0, 0, 0, 0);   // [P3] - [P6]
334                      
335 john.eisenbraun 1.21         if (errorcode != SS$_NORMAL)
336                              {
337                                  throw Exception("sys$qiow IO$_SENSEMODE failure");
338                              }
339                      
340                              // setup new settings
341                      
342                              ntermb = otermb;
343                      
344                              // turn on passthru and nobroadcast
345                      
346                              ntermb.t_extend |= TT2$M_PASTHRU;
347                              ntermb.t_mandl |= TT$M_NOBRDCST;
348                      
349                              // Write out new terminal settings
350                      
351                              errorcode = sys$qiow(0,     // Wait on event flag zero
352                                                   ichan, // Channel to input terminal
353                                                   IO$_SETMODE,   // Function - Set Mode
354                                                   &iostatus,     // Status after operation
355                                                   0, 0,  // No AST service
356 john.eisenbraun 1.21                              &ntermb,       // [P1] Address of Char Buffer
357                                                   sizeof (ntermb),       // [P2] Size of Char Buffer
358                                                   0, 0, 0, 0);   // [P3] - [P6]
359                      
360                              if (errorcode != SS$_NORMAL)
361                              {
362                                  throw Exception("sys$qiow IO$_SETMODE failure");
363                              }
364                      
365                              // Write a prompt, read characters from the terminal, performing no
366                              // editing
367                              // and doing no echo at all.
368                      
369                              psize = strlen(prompt);
370                      
371                              errorcode = sys$qiow(0,     // Event flag
372                                                   ichan, // Input channel
373                                                   IO$_READPROMPT | IO$M_NOECHO | IO$M_NOFILTR |
374                                                   IO$M_TRMNOECHO,
375                                                   // Read with prompt, no echo, no translate, no
376                                                   // termination character echo
377 john.eisenbraun 1.21                              &iostatus,     // I/O status block
378                                                   NULL,  // AST block (none)
379                                                   0,     // AST parameter
380                                                   &buf,  // P1 - input buffer
381                                                   MAX_PASS_LEN,  // P2 - buffer length
382                                                   0,     // P3 - ignored (timeout)
383                                                   0,     // P4 - ignored (terminator char set)
384                                                   prompt,        // P5 - prompt buffer
385                                                   psize);        // P6 - prompt size
386                      
387                              if (errorcode != SS$_NORMAL)
388                              {
389                                  throw Exception("sys$qiow IO$_READPROMPT failure:");
390                              }
391                      
392                              // Write out old terminal settings
393                              errorcode = sys$qiow(0,     // Wait on event flag zero
394                                                   ichan, // Channel to input terminal
395                                                   IO$_SETMODE,   // Function - Set Mode
396                                                   &iostatus,     // Status after operation
397                                                   0, 0,  // No AST service
398 john.eisenbraun 1.21                              &otermb,       // [P1] Address of Char Buffer
399                                                   sizeof (otermb),       // [P2] Size of Char Buffer
400                                                   0, 0, 0, 0);   // [P3] - [P6]
401                      
402                              if (errorcode != SS$_NORMAL)
403                              {
404                                  throw Exception("sys$qiow IO$_SETMODE failure");
405                              }
406                      
407                              // Start new line
408                      
409                              const int CR = 0x0d;
410                              const int LF = 0x0a;
411                              fputc(CR, stdout);
412                              fputc(LF, stdout);
413                      
414                              // Remove the termination character
415                              psize = strlen(buf);
416                              buf[psize - 1] = 0;
417                          }
418 gs.keenan       1.1  
419 john.eisenbraun 1.21     catch (Exception &e)
420                          {
421                              PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL1, "%s: %s",
422                                  (const char *) (e.getMessage()).getCString(),
423                                  strerror(EVMSERR, errorcode)));
424                          }
425 gs.keenan       1.8  
426 john.eisenbraun 1.21     // Deassign the channel
427 gs.keenan       1.6  
428 john.eisenbraun 1.21     if (ichan) sys$dassgn(ichan);
429 gs.keenan       1.8  
430                          return buf;
431 gs.keenan       1.1  }
432                      
433 john.eisenbraun 1.21 String System::encryptPassword(const char* password, const char* salt)
434 gs.keenan       1.1  {
435 john.eisenbraun 1.21     const size_t MAX_PASS_LEN = 1024;
436                          char pbBuffer[MAX_PASS_LEN] = {0};
437                          Uint32 dwByteCount;
438                          char pcSalt[3] = {0};
439                      
440                          strncpy(pcSalt, salt, 2);
441                          dwByteCount = strlen(password);
442                          memcpy(pbBuffer, password, dwByteCount);
443 gs.keenan       1.1  
444 john.eisenbraun 1.21     for (Uint32 i=0; (i<dwByteCount) || (i>=MAX_PASS_LEN); i++)
445                          {
446                              (i%2 == 0) ? pbBuffer[i] ^= pcSalt[1] : pbBuffer[i] ^= pcSalt[0];
447                          }
448 gs.keenan       1.6  
449 john.eisenbraun 1.21     return String(pcSalt) + String((char *)pbBuffer);
450 gs.keenan       1.1  }
451                      
452 john.eisenbraun 1.21 Boolean System::isPrivilegedUser(const String& userName)
453 gs.keenan       1.1  {
454 john.eisenbraun 1.22     unsigned int audsts;
455                          union prvdef priv_mask;
456                      
457 john.eisenbraun 1.21     int retStat;
458 gs.keenan       1.1  
459 john.eisenbraun 1.22     priv_mask.prv$l_l1_bits =
460                          priv_mask.prv$l_l2_bits = 0;
461                          priv_mask.prv$v_sysprv = true;    // SYSPRV privilege.
462                          priv_mask.prv$v_bypass = true;    // BYPASS privilege.
463 gs.keenan       1.1  
464 john.eisenbraun 1.22     retStat = sys$check_privilegew(0, &priv_mask, 0, 0, 0, &audsts, 0, 0);
465 gs.keenan       1.1  
466 john.eisenbraun 1.22     return retStat == SS$_NORMAL;
467 gs.keenan       1.1  }
468                      
469                      PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2