1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 append: procedure;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129 %page;
130
131
132
133 dcl a_arg_ptr ptr parameter;
134 dcl a_bitcnt fixed bin (24) parameter;
135 dcl a_code fixed bin (35) parameter;
136 dcl a_copysw fixed bin (2) parameter;
137 dcl a_dirname char (*) parameter;
138 dcl a_dirsw fixed bin (1) parameter;
139 dcl a_ename char (*) parameter;
140 dcl a_linkname char (*) parameter;
141 dcl a_mode fixed bin (5) parameter;
142 dcl a_retv_append_argp ptr parameter;
143 dcl a_ringbrack (3) fixed bin (6) parameter;
144 dcl a_sons bit (36) parameter;
145 dcl a_uid_path (0:15) bit (36) aligned parameter;
146 dcl a_userid char (*) parameter;
147
148
149 dcl create_branch_version_1 fixed bin int static options (constant) init (1);
150
151
152
153 dcl ac_sw bit (1) aligned;
154 dcl acbr_version fixed bin;
155 dcl access_class bit (72) aligned;
156 dcl acl_count fixed bin;
157 dcl acl_start_ptr ptr;
158 dcl add_sw bit (1);
159 dcl admin_append bit (1) aligned;
160 dcl areap ptr;
161 dcl arg_ptr ptr;
162 dcl asize fixed bin;
163 dcl audit_eventflags bit (36) aligned;
164 dcl authp ptr;
165 dcl bcount fixed bin;
166 dcl bitcnt fixed bin (24);
167 dcl bmode bit (3) aligned;
168 dcl branch_sw bit (1);
169 dcl chase_sw bit (1) aligned;
170 dcl code fixed bin (35);
171 dcl copysw fixed bin (1);
172 dcl default_sw bit (1);
173 dcl dep ptr;
174 dcl dir_quota fixed bin (18);
175 dcl dirl bit (1) aligned;
176 dcl dirname char (168);
177 dcl dirp ptr;
178 dcl dirsw fixed bin (1);
179 dcl dtem bit (36) aligned;
180 dcl dumcode fixed bin (35);
181 dcl dummy char (32) aligned;
182 dcl ename char (32);
183 dcl ename_aligned char (32) aligned;
184 dcl i fixed bin;
185 dcl iacl_start_ptr ptr;
186 dcl iaclp ptr;
187 dcl 1 initial_acl aligned like input_acl;
188 dcl level fixed bin;
189 dcl linkname char (168) aligned;
190 dcl llngth fixed bin (18);
191 dcl 1 local_entry like entry aligned;
192 dcl max_access_authorization bit (72) aligned;
193 dcl 1 mk_info aligned like makeknown_info;
194 dcl 1 my_audit_user_info aligned like audit_user_info;
195 dcl n_iacls fixed bin;
196 dcl newuid bit (36) aligned;
197 dcl nwords fixed bin;
198 dcl parent_access_class bit (72) aligned;
199 dcl prevep ptr;
200 dcl prior_dir_acl_count fixed bin;
201 dcl priv_mqsw bit (1) aligned;
202 dcl project char (32) aligned;
203 dcl quota fixed bin (18);
204 dcl read_lock bit (36) aligned;
205 dcl retv bit (1) aligned;
206 dcl retv_cross_segment bit (1) aligned;
207 dcl ringbrack (3) fixed bin (6);
208 dcl segno fixed bin;
209 dcl 1 service_acl aligned,
210 2 person char (32) init ("*"),
211 2 project char (32) init ("SysDaemon"),
212 2 tag char (1) init ("*"),
213 2 mode bit (36) init ("101"b),
214 2 exmode bit (36) init ("0"b);
215 dcl sons bit (36) aligned;
216 dcl sonsw bit (1) aligned;
217 dcl sp_sw bit (1) aligned;
218 dcl sysl bit (1) aligned;
219 dcl temp_b4 bit (4) aligned;
220 dcl uid_path (0:15) bit (36) aligned;
221 dcl 1 user_acl aligned,
222 2 person char (32),
223 2 project char (32),
224 2 tag char (1),
225 2 mode bit (36) init ("111"b),
226 2 exmode bit (36) init ("0"b);
227 dcl userid char (32) aligned;
228 dcl vtocx_temp fixed bin;
229 dcl xsize fixed bin;
230
231
232
233 dcl 1 acbr like create_branch_info based (arg_ptr) aligned;
234 dcl 1 input_acl based aligned,
235 2 person char (32),
236 2 project char (32),
237 2 tag char (1),
238 2 mode bit (36),
239 2 exmode bit (36);
240
241
242
243 dcl active_all_rings_data$max_tree_depth external fixed bin;
244 dcl active_hardcore_data$alloc_sizes (6) external fixed bin;
245 dcl active_hardcore_data$dir_arearp ext fixed bin (35);
246 dcl active_hardcore_data$dir_hdrsize external fixed bin;
247 dcl active_hardcore_data$elcsize external fixed bin;
248 dcl active_hardcore_data$ensize external fixed bin;
249 dcl active_hardcore_data$esize external fixed bin;
250 dcl active_hardcore_data$nalloc_sizes external fixed bin;
251 dcl error_table_$ai_restricted external fixed bin (35);
252 dcl error_table_$argerr external fixed bin (35);
253 dcl error_table_$invalid_mode external fixed bin (35);
254 dcl error_table_$invalid_project_for_gate external fixed bin (35);
255 dcl error_table_$invalid_ring_brackets external fixed bin (35);
256 dcl error_table_$lower_ring external fixed bin (35);
257 dcl error_table_$max_depth_exceeded external fixed bin (35);
258 dcl error_table_$namedup external fixed bin (35);
259 dcl error_table_$noalloc external fixed bin (35);
260 dcl error_table_$noentry external fixed bin (35);
261 dcl error_table_$unimplemented_version external fixed bin (35);
262 dcl 1 pds$access_authorization aligned like aim_template external;
263 dcl 1 pds$access_name aligned external,
264 2 person char (32),
265 2 project char (32),
266 2 tag char (1);
267 dcl pds$max_access_authorization bit (72) aligned external;
268 dcl pds$processid bit (36) aligned external;
269 dcl sys_info$access_class_ceiling external bit (72) aligned;
270 dcl sys_info$default_dir_max_length fixed bin (19) external;
271
272
273
274 dcl acc_name_$elements entry (ptr, ptr, fixed bin (35));
275 dcl acc_name_$encode entry (ptr, ptr, fixed bin (35));
276 dcl access_audit_check_ep_$self entry (bit (36) aligned, bit (36) aligned, ptr) returns (bit (1));
277 dcl access_audit_check_ep_$user entry (bit (36) aligned, bit (36) aligned, ptr, bit (72) aligned, bit (36) aligned) returns (bit (1));
278 dcl access_audit_$log_entry_ptr entry (char (*), fixed bin, bit (36) aligned, bit (36) aligned, ptr, fixed bin (35), ptr, fixed bin (18), char (*));
279 dcl access_audit_$log_entry_ptr_user entry (char (*), fixed bin, bit (36) aligned, bit (36) aligned, ptr, fixed bin (35), ptr, fixed bin (18), ptr, char (*));
280 dcl acl_$add_entry entry (fixed bin, bit (36) aligned, ptr, ptr, bit (1), fixed bin (35));
281 dcl acl_$del_acl entry (fixed bin, bit (36) aligned, ptr);
282 dcl acl_$list_entry entry (fixed bin, bit (36) aligned, ptr, ptr, fixed bin, fixed bin (35));
283 dcl aim_check_$equal entry (bit (72) aligned, bit (72) aligned) returns (bit (1) aligned);
284 dcl aim_check_$greater entry (bit (72) aligned, bit (72) aligned) returns (bit (1) aligned);
285 dcl aim_check_$greater_or_equal entry (bit (72) aligned, bit (72) aligned) returns (bit (1) aligned);
286 dcl allocate_dir_ht_ entry (ptr, fixed bin, fixed bin (35));
287 dcl check_gate_acl_ entry (ptr, bit (1) aligned, fixed bin, char (32) aligned, fixed bin (35));
288 dcl create_vtoce entry (ptr, bit (36), fixed bin (17), fixed bin (35));
289 dcl delete_vtoce entry (ptr, fixed bin (35));
290 dcl fs_alloc$alloc entry (ptr, fixed bin, ptr);
291 dcl fs_alloc$free entry (ptr, fixed bin, ptr);
292 dcl fs_alloc$init entry (ptr, fixed bin, ptr, fixed bin);
293 dcl getuid entry () returns (bit (36) aligned);
294 dcl hash$in entry (ptr, ptr, fixed bin (35));
295 dcl hash$out entry (ptr, ptr, ptr, fixed bin (35));
296 dcl hash$search entry (ptr, ptr, ptr, fixed bin (35));
297 dcl level$get entry returns (fixed bin);
298 dcl lock$dir_unlock entry (ptr);
299 dcl makeknown_ entry (ptr, fixed bin, fixed bin, fixed bin (35));
300 dcl makeunknown_ entry (fixed bin, bit (36) aligned, bit (1) aligned, fixed bin (35));
301 dcl mountedp entry (bit (36) aligned) returns (fixed bin (35));
302 dcl quota$append_mdir_set entry (ptr, fixed bin (18), fixed bin (35));
303 dcl quota$check entry (ptr, fixed bin (18), fixed bin (35));
304 dcl quota$qmove_mylock entry (ptr, ptr, fixed bin (18), bit (1) aligned, fixed bin (35));
305 dcl sum$dirmod entry (ptr);
306 dcl syserr$error_code entry options (variable);
307 dcl truncate$trentry entry (ptr);
308 dcl uid_path_util$get entry (ptr, dim (0:15) bit (36) aligned, fixed bin (35));
309
310
311
312 dcl (addr, baseptr, bin, bit, clock, collate, divide, fixed, length, null, ptr, rel, rtrim, substr, unspec, verify) builtin;
313
314 dcl bad_dir_ condition;
315 %page;
316 master_dir: entry (a_dirname, a_ename, a_arg_ptr, a_sons, a_uid_path, a_code);
317
318 call setup;
319
320 sons = a_sons;
321 sonsw = "1"b;
322
323 max_access_authorization = pds$max_access_authorization;
324 go to cbcomm;
325
326 retv: entry (a_dirname, a_ename, a_arg_ptr, a_retv_append_argp, a_code);
327
328 call setup;
329
330 retv = "1"b;
331
332 retv_append_argp = a_retv_append_argp;
333 if retv_append_args.version ^= RETV_APPEND_ARGS_VERSION_1 then do;
334 a_code = error_table_$unimplemented_version;
335 return;
336 end;
337
338 level = retv_append_args.level;
339 max_access_authorization = retv_append_args.max_access_authorization;
340
341 arg_ptr = addr (a_arg_ptr -> acbr);
342 acbr_version = acbr.version;
343 if acbr_version < create_branch_version_1 |
344 acbr_version > create_branch_version_2 then go to arg_err;
345
346 audit_user_info_ptr = addr (my_audit_user_info);
347 unspec (audit_user_info) = "0"b;
348
349 audit_user_info.version = audit_user_info_version_1;
350 audit_user_info.user_id = acbr.userid;
351
352 audit_user_info.process_id = "0"b;
353 audit_user_info.authorization = retv_append_args.access_authorization;
354 audit_user_info.authorization_range(2) = retv_append_args.max_access_authorization;
355 audit_user_info.audit_flags = (36)"1"b;
356 audit_user_info.ring = retv_append_args.level;
357
358 if retv_append_args.link then linkname = retv_append_args.ep -> link.pathname;
359 else local_entry = retv_append_args.ep -> entry;
360
361 if retv_append_args.link then goto join_link;
362
363 retv_cross_segment = retv_append_args.cross_segment;
364 goto cbcomm2;
365
366 admin_create_branch_: entry (a_dirname, a_ename, a_arg_ptr, a_code);
367
368 call setup;
369
370 admin_append = "1"b;
371
372 max_access_authorization = sys_info$access_class_ceiling;
373 go to cbcomm;
374
375 create_branch_: entry (a_dirname, a_ename, a_arg_ptr, a_code);
376
377 call setup;
378
379 max_access_authorization = pds$max_access_authorization;
380
381 cbcomm: arg_ptr = addr (a_arg_ptr -> acbr);
382 acbr_version = acbr.version;
383 if acbr_version < create_branch_version_1 |
384 acbr_version > create_branch_version_2 then go to arg_err;
385
386 cbcomm2: ac_sw = ^acbr.parent_ac_sw;
387 if ac_sw then do;
388 access_class = acbr.access_class;
389 if ^aim_check_$greater_or_equal (max_access_authorization, access_class) then do;
390 code = error_table_$ai_restricted;
391 go to fin;
392 end;
393 end;
394 copysw = fixed (acbr.switches.copy_sw, 1);
395 bmode = acbr.mode;
396 dirsw = fixed (acbr.switches.dir_sw, 1);
397 ringbrack (1) = acbr.rings (1);
398 ringbrack (2) = acbr.rings (2);
399 if dirsw = 1 then ringbrack (3) = ringbrack (2);
400 else ringbrack (3) = acbr.rings (3);
401 userid = acbr.userid;
402 bitcnt = acbr.bitcnt;
403 chase_sw = acbr.switches.chase_sw;
404 priv_mqsw = acbr.switches.priv_upgrade_sw;
405 quota = acbr.quota;
406 if acbr_version > create_branch_version_1 then dir_quota = acbr.dir_quota;
407 go to comm2;
408
409 branchx: entry (a_dirname, a_ename, a_mode, a_ringbrack, a_userid, a_dirsw, a_copysw, a_bitcnt, a_code);
410
411 call setup;
412
413 if a_copysw = 0 then copysw = 0;
414 else copysw = 1;
415 if a_dirsw = 0 then dirsw = 0; else dirsw = 1;
416 if dirsw = 0 then bmode = substr (bit (fixed (a_mode, 4), 4), 1, 3);
417 else do;
418 temp_b4 = bit (fixed (a_mode, 4), 4);
419 bmode = substr (temp_b4, 1, 1) || substr (temp_b4, 3, 2);
420 end;
421
422 userid = a_userid;
423 ringbrack = a_ringbrack;
424 if dirsw = 1 then ringbrack (3) = ringbrack (2);
425 bitcnt = a_bitcnt;
426 comm2:
427 branch_sw = "1"b;
428 default_sw = "0"b;
429 do i = 1 to 3;
430 if ringbrack (i) >= 8 then go to inv_rb_err;
431 if ringbrack (i) < 0 then go to inv_rb_err;
432 end;
433 if ^retv then
434 level = level$get ();
435 if ^retv | (retv & ^local_entry.dirsw) then
436 if ringbrack (1) < level then goto lower_ring_err;
437 else if ringbrack (1) > ringbrack (2)
438 | ringbrack (2) > ringbrack (3) then
439 go to inv_rb_err;
440
441 call acc_name_$elements (addr (userid), addr (user_acl), code);
442 if code ^= 0 then go to arg_err;
443 go to join;
444
445 branch: entry (a_dirname, a_ename, a_mode, a_code);
446
447 call setup;
448
449 branch_sw,
450 default_sw = "1"b;
451
452 dirsw,
453 copysw,
454 bitcnt = 0;
455
456 user_acl.person = pds$access_name.person;
457 user_acl.project = pds$access_name.project;
458 user_acl.tag = "*";
459 level,
460 ringbrack (*) = level$get ();
461
462 bmode = substr (bit (fixed (a_mode, 4), 4), 1, 3);
463 go to join;
464
465 link: entry (a_dirname, a_ename, a_linkname, a_code);
466
467 call setup;
468
469 linkname = a_linkname;
470 join_link:
471 branch_sw = "0"b;
472 if substr (linkname, 1, 1) ^= ">" then go to arg_err;
473
474
475 llngth = length (rtrim (linkname));
476 if verify (substr (linkname, 1, llngth), collate ()) > 0 then go to arg_err;
477 join:
478 dirl = "0"b;
479 code = 0;
480 if retv then authp = addr (user_acl);
481 else authp = addr (pds$access_name);
482
483 dirname = a_dirname;
484 ename = a_ename;
485
486 if branch_sw then do;
487
488
489
490 if dirsw = 0 then user_acl.mode = bmode;
491
492 else do;
493 user_acl.exmode = bmode;
494 if (user_acl.exmode & "11"b) = "01"b then
495 go to invalid_mode;
496 service_acl.mode = "111"b;
497 service_acl.exmode = "111"b;
498
499 end;
500 end;
501
502 if ^branch_sw then chase_sw = "0"b;
503
504 if retv then do;
505 call dc_find$dir_for_retrieve_append
506 (dirname, ename, bin (chase_sw, 1), audit_user_info_ptr, dep, dp, code);
507 if code ^= 0 then go to fin;
508 dirl = "1"b;
509 end;
510 else do;
511 if admin_append then
512 call dc_find$dir_for_append_raw (dirname, ename, bin (chase_sw, 1), dep, dp, code);
513 else call dc_find$dir_for_append (dirname, ename, bin (chase_sw, 1), dep, dp, code);
514 if code ^= 0 then go to fin;
515 dirl = "1"b;
516 end;
517
518 if dep = null then parent_access_class = "0"b;
519 else do;
520 if branch_sw then parent_access_class = dep -> entry.access_class;
521 call lock$dir_unlock (ptr (dep, 0));
522 dep = null;
523 end;
524
525 code = 0;
526 ename_aligned = ename;
527
528 if branch_sw then do;
529 if ac_sw then call check_aim_access;
530 else access_class = parent_access_class;
531 end;
532
533 if retv then do;
534 if ^retv_append_args.link then do;
535 i = 0;
536 bcount = dir.dir_count + dir.seg_count + dir.lcount;
537 do ep = ptr (dp, dir.entryfrp) repeat (ptr (dp, entry.efrp)) while (rel (ep) ^= "0"b);
538 i = i + 1;
539 if i > bcount then signal bad_dir_;
540 if entry.uid = local_entry.uid then goto name_dup;
541 end;
542 end;
543 end;
544
545 if dirsw = 1 & dir.tree_depth >= active_all_rings_data$max_tree_depth then do;
546 code = error_table_$max_depth_exceeded;
547 go to unlock;
548 end;
549
550 call hash$search (dp, addr (ename_aligned), ep, code);
551 if code = 0 then go to name_dup;
552 if code ^= error_table_$noentry then signal bad_dir_;
553
554 if ^branch_sw | (dirsw = 1) then code = 0;
555 else code = mountedp (dir.sons_lvid);
556 if code ^= 0 then go to unlock;
557
558 areap = ptr (dp, dir.arearp);
559 dir.modify = pds$processid;
560
561 if retv then newuid = local_entry.uid;
562 else newuid = getuid ();
563 if branch_sw then do;
564 if dirsw = 1 then do;
565 iacl_start_ptr = addr (dir.iacl (level).dir_frp);
566 n_iacls = dir.iacl_count (level).dir;
567 end;
568 else do;
569 iacl_start_ptr = addr (dir.iacl (level).seg_frp);
570 n_iacls = dir.iacl_count (level).seg;
571 if ringbrack (2) ^= ringbrack (3) then
572 if level > 1 then do;
573 if retv then project = user_acl.project;
574 else project = pds$access_name.project;
575 if user_acl.project ^= project then
576 if user_acl.project ^= "SysDaemon" then do;
577 code = error_table_$invalid_project_for_gate;
578 go to unlock;
579 end;
580 call check_gate_acl_ (iacl_start_ptr, "1"b, 0, dummy, code);
581 if code ^= 0 then go to unlock;
582 end;
583 end;
584 xsize = active_hardcore_data$esize;
585 call fs_alloc$alloc (areap, xsize, ep);
586 if ep = null then go to alloc_err;
587 if retv then do;
588 entry = local_entry;
589 entry.acl_frp, entry.acl_brp = "0"b;
590 entry.acle_count = 0;
591 dtem = entry.dtem;
592 end;
593 if dirsw = 1 then entry.type = DIR_TYPE;
594 else entry.type = SEG_TYPE;
595 entry.size = xsize;
596 entry.owner = dir.uid;
597
598 acl_count = 0;
599 acl_start_ptr = addr (entry.acl_frp);
600 prior_dir_acl_count = dir.acle_total;
601
602 if ^retv | retv_cross_segment then do;
603 call acl_$add_entry (0, newuid, acl_start_ptr, addr (service_acl), add_sw, code);
604 if code ^= 0 then go to cleanup_acl;
605
606
607
608 acl_count = 1;
609 dir.acle_total = dir.acle_total + 1;
610 iaclp = addr (initial_acl);
611 do i = 1 by 1 while (code = 0);
612 call acl_$list_entry (n_iacls, dir.uid, iacl_start_ptr, iaclp, i, code);
613 if code = 0 then do;
614 call acl_$add_entry (acl_count, newuid, acl_start_ptr, iaclp, add_sw, code);
615 if code ^= 0 then goto cleanup_acl;
616 if add_sw then do;
617 acl_count = acl_count + 1;
618 dir.acle_total = dir.acle_total + 1;
619 end;
620 end;
621 else if code ^= error_table_$argerr then go to cleanup_acl;
622 end;
623
624 if ^retv_cross_segment then do;
625 call acl_$add_entry (acl_count, newuid, acl_start_ptr, addr (user_acl), add_sw, code);
626 if code ^= 0 then goto cleanup_acl;
627 end;
628 if add_sw then do;
629 acl_count = acl_count + 1;
630 dir.acle_total = dir.acle_total + 1;
631 end;
632 entry.acle_count = acl_count;
633 end;
634
635 end;
636
637 else do;
638 nwords = active_hardcore_data$elcsize + 3 + divide (llngth + 3, 4, 17, 0);
639
640
641 do i = active_hardcore_data$nalloc_sizes - 1 to 1 by -1
642 while (nwords <= active_hardcore_data$alloc_sizes (i));
643 end;
644 xsize = active_hardcore_data$alloc_sizes (i + 1);
645
646 call fs_alloc$alloc (areap, xsize, ep);
647 if ep = null then go to alloc_err;
648 link.type = LINK_TYPE;
649 link.size = xsize;
650 link.pathname_size = llngth;
651 link.pathname = linkname;
652 link.owner = dir.uid;
653
654 end;
655
656 call acc_name_$encode (addr (entry.author), authp, code);
657 if code ^= 0 then go to cleanup_acl;
658
659 np = addr (entry.primary_name);
660 entry.name_frp,
661 entry.name_brp = rel (np);
662 entry.nnames = 1;
663 np -> names.entry_rp = rel (ep);
664 np -> names.name = ename;
665 np -> names.type = NAME_TYPE;
666 np -> names.size = active_hardcore_data$ensize;
667 np -> names.owner = newuid;
668
669 call hash$in (dp, np, code);
670 if code ^= 0 then goto cleanup_acl;
671
672
673
674 entry.uid = newuid;
675 entry.dtem = substr (bit (fixed (clock, 52), 52), 1, 36);
676 if ^branch_sw then dir.lcount = dir.lcount + 1;
677 else do;
678 entry.bs = "1"b;
679 entry.per_process_sw = dir.per_process_sw;
680 entry.bc = bitcnt;
681 entry.dirsw = bit (dirsw, 1);
682 entry.access_class = access_class & sys_info$access_class_ceiling;
683 entry.multiple_class = sp_sw;
684
685
686
687
688
689 if retv then if entry.multiple_class then do;
690 if ^pds$access_authorization.soos then entry.security_oosw = "1"b;
691 end;
692 entry.master_dir = sonsw;
693
694 call acc_name_$encode (addr (entry.bc_author), authp, code);
695 if code ^= 0 then go to make_err;
696
697 call uid_path_util$get (dp, uid_path, code);
698 if code ^= 0 then go to make_err;
699 uid_path (dir.tree_depth + 1) = entry.uid;
700
701 if ^retv then do;
702 call create_vtoce (ep, entry.pvid, vtocx_temp, code);
703 if code ^= 0 then go to make_err;
704 entry.vtocx = vtocx_temp;
705 if dirsw = 1 then call setup_directory;
706 else do;
707 entry.ring_brackets (1) = bit (fixed (ringbrack (1), 3), 3);
708 entry.ring_brackets (2) = bit (fixed (ringbrack (2), 3), 3);
709 entry.ring_brackets (3) = bit (fixed (ringbrack (3), 3), 3);
710 entry.copysw = bit (copysw, 1);
711 dir.seg_count = dir.seg_count + 1;
712 end;
713 end;
714 else do;
715 if retv_cross_segment then do;
716 call create_vtoce (ep, entry.pvid, vtocx_temp, code);
717 if code ^= 0 then goto make_err;
718 entry.vtocx = vtocx_temp;
719 end;
720 if dirsw = 1 then do;
721 dir.dir_count = dir.dir_count + 1;
722 if ^entry.master_dir then
723 entry.sons_lvid = dir.sons_lvid;
724 end;
725 else dir.seg_count = dir.seg_count + 1;
726 end;
727 end;
728
729 if dir.entryfrp = ""b then
730 do;
731 dir.entryfrp, dir.entrybrp = rel (ep);
732 entry.efrp, entry.ebrp = ""b;
733 end;
734 else do;
735 prevep = ptr (ep, dir.entrybrp);
736 entry.ebrp = rel (prevep);
737 prevep -> entry.efrp = rel (ep);
738 entry.efrp = ""b;
739 dir.entrybrp = rel (ep);
740 end;
741
742
743 if retv then entry.dtem = dtem;
744 dir.modify = "0"b;
745 call sum$dirmod (dp);
746
747 audit_eventflags = "0"b;
748 addr (audit_eventflags) -> audit_event_flags.grant = "1"b;
749 if retv then
750 if access_audit_check_ep_$user
751 (audit_eventflags, access_operations_$fs_obj_create, ep, audit_user_info.authorization, audit_user_info.audit_flags) then
752 call access_audit_$log_entry_ptr_user
753 ("append", level, audit_eventflags, access_operations_$fs_obj_create, ep, 0, null, 0, audit_user_info_ptr, "");
754 else ;
755 else if access_audit_check_ep_$self
756 (audit_eventflags, access_operations_$fs_obj_create, ep) then
757 call access_audit_$log_entry_ptr
758 ("append", level, audit_eventflags, access_operations_$fs_obj_create, ep, 0, null, 0, "");
759
760 call dc_find$finished (dp, dirl);
761
762 fin:
763 a_code = code;
764
765 return;
766
767 arg_err:
768 code = error_table_$argerr; go to fin;
769 lower_ring_err:
770 code = error_table_$lower_ring; goto fin;
771 inv_rb_err:
772 code = error_table_$invalid_ring_brackets; go to fin;
773 invalid_mode:
774 code = error_table_$invalid_mode; go to fin;
775 name_dup:
776 code = error_table_$namedup; go to unlock;
777 alloc_err:
778 code = error_table_$noalloc; go to unlock;
779 free_vtoce:
780 call delete_vtoce (ep, dumcode);
781 if dumcode ^= 0 then call syserr$error_code (4, dumcode, "append: err from delete_vtoce for ^a>^a:", dirname, ename);
782 make_err:
783 call hash$out (dp, addr (ename_aligned), np, dumcode);
784 if dumcode ^= 0 then call syserr$error_code (4, dumcode, "append: error from hash$out for ^a>^a:", dirname, ename);
785 cleanup_acl:
786 if branch_sw then do;
787 call acl_$del_acl (acl_count, newuid, acl_start_ptr);
788 dir.acle_total = prior_dir_acl_count;
789 end;
790 call fs_alloc$free (areap, xsize, ep);
791 unlock:
792 if dep ^= null then call lock$dir_unlock (ptr (dep, 0));
793 dir.modify = "0"b;
794 call dc_find$finished (dp, dirl);
795 go to fin;
796 %page;
797 check_aim_access: proc;
798
799 if aim_check_$greater (access_class, parent_access_class) then do;
800 if dirsw = 1 then do;
801 if quota <= 0 then if level > 1 then goto ai_err;
802 else if ^priv_mqsw then goto ai_err;
803
804 if bitcnt ^= 0 then if level > 1 then goto ai_err;
805 sp_sw = "1"b;
806 end;
807 else do;
808 if ringbrack (3) > 1 then go to ai_err;
809 if priv_mqsw then sp_sw = "1"b;
810 else go to ai_err;
811 end;
812 end;
813 else if ^aim_check_$equal (access_class, parent_access_class) then do;
814 ai_err: code = error_table_$ai_restricted;
815 goto unlock;
816 end;
817
818 end check_aim_access;
819
820 setup: proc;
821
822 ac_sw = "0"b;
823 admin_append = "0"b;
824 chase_sw = "1"b;
825 dir_quota = 0;
826 priv_mqsw = "0"b;
827 quota = 0;
828 read_lock = "0"b;
829 retv = "0"b;
830 retv_cross_segment = "0"b;
831 sonsw = "0"b;
832 sp_sw = "0"b;
833 sysl = "0"b;
834 return;
835 end setup;
836 %page;
837
838
839
840 setup_directory: proc;
841
842 if sonsw then entry.sons_lvid = sons;
843 else entry.sons_lvid = dir.sons_lvid;
844
845 entry.ex_ring_brackets (1) = bit (bin (ringbrack (1), 3), 3);
846 entry.ex_ring_brackets (2) = bit (bin (ringbrack (2), 3), 3);
847
848 if ^sonsw then do;
849 call quota$check (ep, quota, code);
850 if code ^= 0 then go to free_vtoce;
851 end;
852
853
854 Note
855
856
857 dir.modify = "0"b;
858
859 unspec (mk_info) = "0"b;
860 mk_info.uid = entry.uid;
861 mk_info.entryp = ep;
862 mk_info.dirsw = "1"b;
863 mk_info.allow_write = "1"b;
864 mk_info.activate = "1"b;
865 dirp = null;
866 call makeknown_ (addr (mk_info), segno, (0), code);
867 if code ^= 0 then go to free_vtoce;
868 dirp = baseptr (segno);
869
870 unspec (dirp -> dir) = "0"b;
871 dirp -> dir.type = DIR_HEADER_TYPE;
872 dirp -> dir.size = active_hardcore_data$dir_hdrsize;
873 dirp -> dir.version_number = version_number_2;
874 dirp -> dir.owner = dir.uid;
875 dirp -> dir.uid = entry.uid;
876 dirp -> dir.arearp = bit (fixed (active_hardcore_data$dir_arearp, 18), 18);
877 dirp -> dir.pvid = entry.pvid;
878 dirp -> dir.per_process_sw = entry.per_process_sw;
879 dirp -> dir.sons_lvid = entry.sons_lvid;
880 dirp -> dir.master_dir = entry.master_dir;
881 if entry.master_dir then dirp -> dir.master_dir_uid = entry.uid;
882 else dirp -> dir.master_dir_uid = dir.master_dir_uid;
883 dirp -> dir.access_class = entry.access_class;
884 dirp -> dir.vtocx = entry.vtocx;
885 asize = sys_info$default_dir_max_length - fixed (dirp -> dir.arearp, 18);
886 call fs_alloc$init (ptr (dirp, dirp -> dir.arearp), asize,
887 addr (active_hardcore_data$alloc_sizes), active_hardcore_data$nalloc_sizes);
888
889 call allocate_dir_ht_ (dirp, 0, (0));
890 dirp -> dir.tree_depth = dir.tree_depth + 1;
891
892 if quota > 0 then
893 if ^sonsw then do;
894 call quota$qmove_mylock (ep, dirp, quota, "0"b, code);
895 if code ^= 0 then do;
896
897 qerr: call truncate$trentry (ep);
898 call makeunknown_ (segno, "0"b, ("0"b), dumcode);
899 if dumcode ^= 0 then call syserr$error_code (4, dumcode,
900 "append: makeunknown_ err after quota err for ^a>^a:", dirname, ename);
901 go to free_vtoce;
902 end;
903 end;
904 else do;
905 call quota$append_mdir_set (ep, quota, code);
906 if code ^= 0 then go to qerr;
907 end;
908 else if priv_mqsw & ac_sw then do;
909 if aim_check_$greater (access_class, parent_access_class) then
910 ep -> entry.security_oosw = "1"b;
911 end;
912
913 if dir_quota > 0 then do;
914 call quota$qmove_mylock (ep, dirp, dir_quota, "1"b, code);
915 if code ^= 0 then go to qerr;
916 end;
917
918 call sum$dirmod (dirp);
919 call makeunknown_ (segno, "0"b, ("0"b), code);
920 if code ^= 0 then call syserr$error_code (4, code, "append: error from makeunknown_ for ^a>^a:", dirname, ename);
921
922 dir.modify = pds$processid;
923
924
925
926
927 dir.dir_count = dir.dir_count + 1;
928 if sonsw then a_uid_path = uid_path;
929
930 return;
931
932 end setup_directory;
933 %page; %include access_audit_eventflags;
934 %page; %include access_audit_user_info;
935 %page; %include aim_template;
936 %page; %include create_branch_info;
937 %page; %include dc_find_dcls;
938 %page; %include dir_entry;
939 %page; %include dir_header;
940 %page; %include dir_ht;
941 %page; %include dir_link;
942 %page; %include dir_name;
943 %page; %include fs_obj_access_codes;
944 %page; %include fs_types;
945 %page; %include makeknown_info;
946 %page; %include null_addresses;
947 %page; %include retv_append_args;
948 %page;
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965 note
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980 note
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995 note
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009 note
1010
1011
1012
1013 end append;