1 /****^  ***********************************************************
  2         *                                                         *
  3         * Copyright, (C) Honeywell Bull Inc., 1987                *
  4         *                                                         *
  5         * Copyright, (C) Honeywell Information Systems Inc., 1982 *
  6         *                                                         *
  7         * Copyright (c) 1972 by Massachusetts Institute of        *
  8         * Technology and Honeywell Information Systems, Inc.      *
  9         *                                                         *
 10         *********************************************************** */
 11 
 12 /* format: style4 */
 13 
 14 /* LOGOUT - Command to destroy a process and log the user off the system.
 15 
 16    logout -hold                         don't hangup the line...let another user login on this terminal
 17    logout -brief                        don't print logout message
 18 
 19 
 20    NEW_PROC - Command to destroy a process and create a new one for the same user.
 21 
 22    new_proc                             create a new process with same attributes as this one
 23    new_proc -auth new_authorization     create a new process whose authorization is new_authorization
 24 
 25 
 26    Written 750406 by PG (split off from terminate_process_)
 27    Modified Aug 25, 1977 by S. Webber to add term_signal_handler_
 28    Modified April 1979 by T. Casey for MR7.0a to make process type determination work right for foreground absentee jobs.
 29    Modified December 1980 by E. N. Kittlitz for absentee cancellation message
 30    Modified 3/82 BIM for new print_abs_msg_, finish_info.incl.pl1
 31    Modified 84-06-24 BIM to check strict trusted path.
 32 */
 33 
 34 
 35 /****^  HISTORY COMMENTS:
 36   1) change(86-05-19,GDixon), approve(86-09-26,MCR7499),
 37      audit(86-10-08,Beattie), install(86-10-13,MR12.0-1183):
 38      Resolve uninitialized variable (logout_string) in new_proc command by
 39      moving no_more_arguments label so variable doesn't get referenced by the
 40      new_proc control path. (phx20351)
 41   2) change(87-04-08,Parisek), approve(87-07-14,MCR7644),
 42      audit(87-07-24,GDixon), install(87-08-04,MR12.1-1055):
 43      Added the "disconnect" entry point.
 44                                                    END HISTORY COMMENTS */
 45 
 46 
 47 logout:
 48      procedure options (variable);
 49 
 50 /* automatic */
 51 
 52 dcl  process_type fixed bin;                                /* = 2 if this is an absentee process */
 53 dcl  argno fixed bin;
 54 dcl  arg_length fixed bin (21);
 55 dcl  arg_ptr ptr;
 56 dcl  attr char (128) varying;
 57 dcl  authorization bit (72) aligned;
 58 dcl  code fixed bin (35);
 59 dcl  my_name char (12);
 60 dcl  term_structure_ptr ptr;
 61 
 62 
 63 dcl  1 logout_string aligned,                               /* information about logouts */
 64        2 version fixed bin,                                 /* this is version 0 */
 65        2 hold bit (1) unaligned,                            /* don't hangup line */
 66        2 brief bit (1) unaligned,                           /* don't print logout message */
 67        2 pad bit (34) unaligned;                            /* must be zero */
 68 
 69 dcl  1 new_proc_string aligned,                             /* information about new_procs */
 70        2 version fixed bin,                                 /* this is version 1 */
 71        2 authorization_option bit (1) unaligned,            /* use value of new_authorization, below */
 72        2 pad bit (35) unaligned,                            /* must be zero */
 73        2 new_authorization bit (72) aligned;                /* authorization of new process */
 74 
 75 dcl  1 disc_string aligned,                                 /* info about user invoked disconnect */
 76        2 version fixed bin,                                 /* this is version 0 */
 77        2 pad bit(36) aligned;                               /* init "0"b */
 78 
 79 dcl  1 local_finish_info aligned like finish_info;
 80 
 81 %include finish_info;
 82 %include condition_info_header;
 83 %include trusted_path_flags;
 84 
 85 /* based */
 86 
 87 dcl  argument char (arg_length) based (arg_ptr);
 88 
 89 /* builtins */
 90 
 91 dcl  (addr, index, null, size, string, unspec) builtin;
 92 
 93 /* external static */
 94 
 95 dcl  error_table_$badopt fixed bin (35) external static;
 96 
 97 /* entries */
 98 
 99 dcl  aim_check_$equal entry (bit (72) aligned, bit (72) aligned) returns (bit (1) aligned);
100 dcl  aim_check_$greater_or_equal entry (bit (72) aligned, bit (72) aligned) returns (bit (1) aligned);
101 dcl  com_err_ entry options (variable);
102 dcl  convert_access_class_$from_string entry (bit (72) aligned, char (*), fixed bin (35));
103 dcl  cu_$arg_ptr entry (fixed bin, ptr, fixed bin (21), fixed bin (35));
104 dcl  execute_epilogue_ entry (bit (1) aligned);
105 dcl  get_process_authorization_ entry () returns (bit (72) aligned);
106 dcl  get_process_max_authorization_ entry returns (bit (72) aligned);
107 dcl  ioa_ entry options (variable);
108 dcl  print_abs_msg_$logout entry ();
109 dcl  save_on_disconnect entry;
110 dcl  signal_ entry (char (*), ptr, ptr);
111 dcl  system_info_$trusted_path_flags entry returns (bit (36) aligned);
112 dcl  terminate_process_ entry (char (*), ptr);
113 dcl  user_info_$attributes entry (char(*) varying);
114 dcl  user_info_$process_type entry (fixed bin);
115 ^L
116 
117 /* program */
118 
119           my_name = "logout";
120           finish_info_ptr = addr (local_finish_info);
121           finish_info.type = "logout";
122 
123           call user_info_$process_type (process_type);      /* we will need to know if this is absentee later */
124 
125           logout_string.version = 0;
126           logout_string.hold = "0"b;                        /* set default values for arguments */
127           logout_string.brief = "0"b;                       /* .. */
128           logout_string.pad = ""b;
129           term_structure_ptr = addr (logout_string);
130 
131           do argno = 1 by 1;                                /* read all arguments */
132                call cu_$arg_ptr (argno, arg_ptr, arg_length, code);
133                if code ^= 0 then go to no_more_logout_arguments;
134 
135                if argument = "-hold" | argument = "-hd"
136                then logout_string.hold = "1"b;              /* user doesn't want line hung up */
137 
138                else if argument = "-brief" | argument = "-bf"
139                then logout_string.brief = "1"b;             /* user doesn't want logout message printed */
140 
141                else go to bad_argument;
142           end;
143 
144 no_more_logout_arguments:
145           if ^logout_string.brief then do;                  /* print absentee logout message */
146                if process_type = 2 then call print_abs_msg_$logout;
147           end;
148 
149           if logout_string.hold
150           then do;
151                string (trusted_path_flags) = system_info_$trusted_path_flags ();
152                if trusted_path_flags.login then do;
153                     if logout_string.hold & my_name = "logout" then do;
154                          call com_err_ (0, my_name, "logout -hold is not permitted at this site to ensure secure logins.");
155                          return;
156                     end;
157                end;
158           end;
159 
160 no_more_arguments:
161           if my_name = "disconnect" then do;
162                call user_info_$attributes (attr);           /* check for disconnect_ok */
163                if index (attr, "disconnect_ok") = 0 then do;
164                     call com_err_ (0, my_name, "You lack permission to disconnect your process.
165 Check with your project administrator for more information.");
166                     return;
167                end;
168                call save_on_disconnect;                     /* Ensure process will be saved. */
169                call terminate_process_ (my_name, term_structure_ptr);
170                return;
171           end;
172                                                             /* assume that's what we want */
173           else do;
174                finish_info.length = size (finish_info);
175                finish_info.version = 1;
176                finish_info.info_string = "";
177                unspec (finish_info.action_flags) = ""b;
178                finish_info.status_code = 0;
179                call signal_ ("finish", null (), addr (finish_info));
180                call execute_epilogue_ ("0"b);               /* The "0"b says not just a run unit */
181                call terminate_process_ (my_name, term_structure_ptr);
182                go to no_more_arguments;                     /* and don't come back */
183           end;
184 ^L
185 new_proc:
186      entry;                                                 /* entry to create a new process */
187 
188           my_name = "new_proc";
189           finish_info_ptr = addr (local_finish_info);
190           finish_info.type = "new_proc";
191 
192           call user_info_$process_type (process_type);      /* is this an process_type process? */
193 
194           if process_type = 2 then do;                      /* yes! */
195                call com_err_ (0, my_name, "Invalid command for absentee process.");
196                return;
197           end;
198 
199           new_proc_string.version = 1;
200           new_proc_string.authorization_option = "0"b;      /* initialize options */
201           new_proc_string.new_authorization = ""b;          /* .. */
202           new_proc_string.pad = ""b;
203           term_structure_ptr = addr (new_proc_string);      /* set ptr to argument */
204 
205           do argno = 1 by 1;                                /* read all arguments */
206                call cu_$arg_ptr (argno, arg_ptr, arg_length, code);
207                if code ^= 0 then go to no_more_arguments;   /* go do it */
208 
209                if argument = "-authorization" | argument = "-auth"
210                then do;
211                     new_proc_string.authorization_option = "1"b;
212                     argno = argno + 1;
213                     call cu_$arg_ptr (argno, arg_ptr, arg_length, code);
214                     if code ^= 0 then do;
215                          call com_err_ (code, my_name, "-authorization must be followed by an authorization.");
216                          return;
217                     end;
218 
219                     call convert_access_class_$from_string (authorization, argument, code);
220                     if code ^= 0 then do;
221                          call com_err_ (code, my_name, "^a", argument);
222                          return;
223                     end;
224 
225 /* get the max authorization of this process */
226 
227                     if ^aim_check_$greater_or_equal (get_process_max_authorization_ (), authorization) then do;
228                          call com_err_ (0, my_name, "You cannot new_proc to the requested authorization.");
229                          return;
230                     end;
231 
232                     string (trusted_path_flags) = system_info_$trusted_path_flags ();
233                     if trusted_path_flags.login then if
234                               ^aim_check_$equal (get_process_authorization_ (), authorization)
235                          then do;
236                               call com_err_ (0, my_name, "new_proc -authorization is not permitted at this site to ensure secure logins.");
237                               return;
238                          end;
239 
240                     new_proc_string.new_authorization = authorization; /* pass to terminate_process_ */
241                end;
242                else go to bad_argument;
243           end;
244 
245 bad_argument:
246           call com_err_ (error_table_$badopt, my_name, argument);
247           return;
248 
249 term_signal_handler_: entry;
250 
251           my_name = "term_signal";
252           finish_info_ptr = addr (local_finish_info);
253           finish_info.type = "termsgnl";
254 
255           call user_info_$process_type (process_type);
256 
257           if process_type = 2 then                          /* absentee cancellation */
258                call ioa_ ("^2/Process terminated by the system.  The reason will be sent by Multics mail.");
259 
260           logout_string.version = 0;
261           logout_string.hold = "0"b;
262           logout_string.brief = "0"b;
263           logout_string.pad = "0"b;
264           term_structure_ptr = addr (logout_string);
265 
266           goto no_more_logout_arguments;
267 ^L
268 disconnect:
269           entry;
270 
271           my_name = "disconnect";
272 
273           call user_info_$process_type (process_type);
274 
275           if process_type ^= 1 then do;
276                call com_err_ (0, my_name, "Command valid for interactive processes only.");
277                return;
278           end;
279 
280           disc_string.version = 0;
281           disc_string.pad = ""b;
282           term_structure_ptr = addr (disc_string);
283 
284           do argno = 1 by 1;
285                call cu_$arg_ptr (argno, arg_ptr, arg_length, code);
286                if code ^= 0 then go to no_more_arguments;
287                else go to bad_argument;
288           end;
289 
290      end logout;