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 dl.meetei 1.24 delete [] dir_path;
|
89 john.eisenbraun 1.23 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 ashok.pathak 1.25 delete [] dir_path;
|
107 john.eisenbraun 1.23 }
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 ashok.pathak 1.25 delete [] dir_path;
|
136 john.eisenbraun 1.23 ret = 1;
137 }
138 else
139 ret = 0;
140 }
141 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
|