Multics Technical Bulletin MTB-699 Messages Priv Processes -> Users To: Distribution From: Benson I. Margulies Date: 01/15/85 Subject: Messages from privileged processes to user processes 1 ABSTRACT This MTB describes a mechanism for sending large messages from privileged processes, such as the Answering Service, to user processes. It is proposed at this time to solve two problems: (1) the B2 project requires such a mechanism to inform processes about dialed channels; (2) the DSA project requires such a mechanism to comunicate between the Initializer and login servers and between login servers and users, to replace "blast" messages. This MTB only proposes the implementation and installation of the general mechanism and the B2 application. It does not offer the DSA applications for review and approval, only as examples. Comments should be sent to the author: via Multics Mail: Margulies at either System-M, MIT, or CISL-SERVICE. via Forum: >udd>m>mtgs>B2 on System-M via telephone: _________________________________________________________________ Multics project internal working documentation. Not to be reproduced or distributed outside the Multics project without the consent of the author or the author's management. MTB-699 Multics Technical Bulletin Messages Priv Processes -> Users (HVN) 261-9333, or (617) 492-9333 Multics Technical Bulletin MTB-699 Messages Priv Processes -> Users 2 INTRODUCTION The current mechanism for communications between the Answering Service and user processes is as_request. This consists of a message segment in >sc1 and a process id and an event channel advertised in the whotab. A process can put a message into the message segment and send a wakeup to the advertised process id and event channel. The as_request server in the Initializer process reads messages out of the message segment and calls appropriate programs to perform the requested services. These services include bumping running absentee jobs, management of communications channels via dial_manager_, and send_admin_command. All processes have ao access to the message segment, >sc1>as_request.ms. If a server of one of these requests wishes to reply to the request (for example, to acknowledge it), the only means available is to send an IPC wakeup to an event channel supplied in the original message. As always, an IPC message is limited to 72 bits. 72 bits is a very severe limitation. Several current requirements will be very difficult to implement without a facility for sending more data from the Initializer (and other trusted processes) to user processes. The details of these requirements are described later on in this MTB. An individual server could get around the limitations by accepting a pathname into which a reply would be placed. This would be very difficult to do right. The server would have to make an interpretive access control decision to see whether the user is indeed entitled to write into the specified segment. For message segments and mailboxes, this is not very dangerous. The worst a user could do is clutter another user's mailbox. For this reason, the send_admin_command server is willing to deliver mail to any mailbox to which the Initializer has access. For ordinary segments, this would be very dangerous, due to the risk of data destruction. There would also be an efficiency problem with having the sender of a request specify a location for the response. It would require the Initializer to reference at least one segment per user, and require the user to create the segment. As we will see, that is a cost that is not reasonable for some of the proposed applications of a facility to send messages from privileged processes to users. MTB-699 Multics Technical Bulletin Messages Priv Processes -> Users 3 APPLICATIONS OF SENDING MESSAGES TO USERS There are several important requirements for this facility. 3.1 B2 IDENTIFICATION AND AUTHENTICATION The B2 criteria require all users connected to the system to be identified and authenticated. Thus, users who use the dial or slave pre-access requests to connect to server processes must supply a name and password, and be authenticated. Furthermore, the process to which the users are connected (i.e., the process that is serving dials) must be able to determine the name that they supplied and the AIM authorization associated with them by the Answering Service. Requiring a name and password was fairly straightforward, and has already been designed, implemented and installed. Passing this information to server processes is a more difficult problem. There is no way to encode 32 characters of user name, AIM information, and the channel characteristics in a 72 bit message. Adding this data to the ring 0 tty database would be complicated. Worse, the work would have to be discarded or duplicated as part of the new network architecture (the DSA project). Adding a special purpose inner ring database would have the same problems. The alternative is to create and use a mechanism for passing the results of a query back to a process from the Answering Service. 3.2 LOGIN SERVERS The DSA project/new networking architecture will split the Answering Service into multiple processes. In the initial implementation, process management and accounting will remain in the Initializer, while the network-specific code will move to server processes. These processes must engage in a protocol with the Initializer portion of the Answering Service to create and destroy processes. This protocol, in turn, requires significant quantities of information to be passed between the servers and the Initializer. 3.3 THE WARN COMMAND By now, every Multics user of the video system or emacs has experienced the unpleasant effects of the "blast" mechanism, whereby the Initializer dumps output into user communications channels without regard for the current state of the channel or the terminal. The complaints from the field are reason enough to replace this. In addition, though, the new networking Multics Technical Bulletin MTB-699 Messages Priv Processes -> Users architecture will irretrievably break the current approach. There is simply no general way to stuff output into the output stream of a process over an arbitrary network connection. This mechanism must be replaced by one that sends the message to the user process and depends on the user process to present it to the user appropriately. The existing message facility, even with the addition of urgent messages, would not suffice. For one thing, it would have the efficiency cost above. For another thing, the message facility is not designed to carry data structures, but only text messages. Without real data structures, it is difficult to build applications that respond programatically. For example, an application like xmail might want to handle warn commands differently from bumps. 4 DESIGN REQUIREMENTS This section describes the functional requirements of a facility for sending messages from the privileged processes to user processes. The following items characterize what the facility will (and in some case, will not) be able to do. 1) This facility will permit trusted system processes to send messages to other processes. This facility will not allow user processes to intercommunicate. 2) This facility will transmit messages of large but not arbitrary length. The longest message may be on the order of a full Multics segment, but it need not be as big as a full Multics segment. 3) This facility will provide reliable message transmission. No message will be lost by the facility once it is accepted for delivery. (A malfunctioning user process can, of course, read out a message and drop it.) This facility will impose no limits on the total number of messages that can be pending at one time or on the number of messages a particular sender can send. No malfunction of a non-trusted process will prevent messages from being accepted for delivery. 4) This facility will allow the sender of a message to designate its destination by specifying the target process(es) and a "handle" within the process. The process(es) may be specified by either: a) A single process id. b) A group id starname, specifying one or more processes. MTB-699 Multics Technical Bulletin Messages Priv Processes -> Users The handle is a bit 72 quantity used to identify a particular protocol, or a particular transaction between a trusted process and its correspondent. Some handles are reserved for global system protocols. The handle (72)"0"b is reserved as an invalid handle. In addition, the sender must specify the access class and ring of the message. Senders without ring1 privilege may only specify their current authorization. Privileged senders may specify any authorization from system_low to their maximum authorization. A message is implicitly addressed only to processes whose authorization is identical to the message access class and whose ring is less than or equal to the specified destination ring. 5) The disposition of the message is specified by the sender. The sender may choose one of the following two dispositions: a) The message may be deleted by any process that is a legitimate recipient. Recipients may decline to delete such messages, but protocols will be designed to assume that in the normal case any recipient will delete any message that it can. b) The message may only be deleted by the sender. The sender is responsible for keeping track of outstanding messages and deleting them as appropriate. In addition, all outstanding messages for a specific process specified by process id will be deleted automatically when the process terminates. 6) This facility provides no receipt acknowledgement. 7) No message will be retained for delivery across a bootload. 5 IMPLEMENTATION This section describes a design that provides the services described above. 5.1 BASIC APPROACH The basic approach of this design is to make use of the existing message segment primitives, mseg_. These primitives are already capable of efficiently and reliably recording messages and Multics Technical Bulletin MTB-699 Messages Priv Processes -> Users marking them with AIM information. This design is a special-purpose ring 1 multiclass database that uses a set of mseg_ managed segments as its underlying storage medium. Note that these will NOT be message segments or mailboxes accessible through the standard gates. The fact that they are implemented with mseg_ will be hidden, since the database will be referenced only through its own gates. Mseg_ is far from the ideal of design or efficiency. However, any attempt to avoid it (given that FAMIS is not available in this environment) would be a large job, and could not possibly receive the degree of testing and exposure that mseg_ has had. This design makes two small enhancements to mseg_. The rest is implemented with data stored in the mseg_ segments and the programs around it. 5.2 ENHANCEMENTS TO MSEG_ As described below, this design stores some overhead information in messages in mseg_ segments. The existing interface for reading from these segments assumes that it is the target of a gate and allocates a copy of the message in a caller-supplied area. To improve the efficiency of accessing overhead data that is only read in the inner ring, this design adds entrypoints to mseg_ that return pointers to the header message and to ordinary messages. These entrypoints are mseg_$find_msg and mseg_$find_hdr_msg, and are described in detail below. 5.3 MSEG_ SEGMENTS AS A DATABASE An mseg_ segment is a set of messages together with a special "header" message. Each message has an envelope that records information about its source as well as an AIM marking for the information in the message. Each message has a 72 bit unique message id, which is in fact a clock value.(1) The envelope has no information about the destination of the message; the segment itself is assumed to have been the destination. As implied by the term "mseg_ segment," mseg_ provides no intrinsic support for the use of multiple segments. _________________________________________________________________ (1) Note that it is not quite unique. The ID is just a reading of the SCU clock. On a DPS8/70M processor, it is possible to get the same value from two subsequent readings of the SCU clock. This event is very unlikely, though. MTB-699 Multics Technical Bulletin Messages Priv Processes -> Users To make use of mseg_ segments for this purpose, there are three tasks: first, to arrange for the use of a set of segments to avoid limitations on the amount of data outstanding; second, to store destination information with each message; third, to be able to efficiently find a message without knowing its message_id. 5.4 USING MULTIPLE SEGMENTS The database will consist of a set of segments, named by the convention "as_user_message_NN". The header of the first segment will contain the number of segments currently in use, the highest numbered segment that currently contains at least one message, and the time that that information last changed. User processes will keep a static list of mseg_ segment pointers, and initiate additional segments by comparing the time that they last checked the list against the change time in the first segment. The pad bits at the top of a clock value will be used to encode the segment index in a message id. To look up a message by message id, a process will first pick up the top 20 bits (the pad area), and find a segment index there. Then the process will zero the top 20 bits, and use the resultant doubleword as a message_id within the message segment. 5.5 STORING DESTINATION INFORMATION Each message written in a mseg_ segment will have a standard header that describes its destination. The details of this data structure are given below. The header will specify the target process_id (if any), group_id (if any),(2) handle, and ring. It will also specify whether or not the recipient is to delete the message. 5.6 EFFICIENT RETRIEVAL WITHOUT A MESSAGE_ID It is desirable to implement protocols that work without the use of wakeups. They are easier to code and debug, and often more efficient. It is required to implement protocols that work without the reliable use of wakeups, since IPC is not _________________________________________________________________ (2) "group_id" is the original Multics term for a user.project.tag string. All of the existing system code uses this term in data structures, so this design follows the example. Multics Technical Bulletin MTB-699 Messages Priv Processes -> Users reliable.(3) In a wakeup-free protocol, a process would call the message facility to retrieve the chronologically first message sent to it at a specified handle. While the message facility has a pseudo-hash table that allows effecient lookup by message_id, a search by destination would require the examination of all the messages. It would be impractical to add support for this kind of searching to mseg_ proper in MR11. The alternative is to store a simple table that associates the message_id's, handles, and destination process id's of the messages in a segment. If the table is a fixed size, then it can be searched very quickly. A fixed size table is not ideal. It imposes an artificial limit on the number of messages that can be stored in the segment. This is not a serious problem. The fixed table consumes 5 words per message (process id, handle, and message_id). A 64K mseg_ segment can accomodate a 900 entry table and have room for 900 messages of average size 64 words. (64 was actually calculated; the mseg_ overhead and destination is 35 words, leaving 31 for actual data). If the messages are generally smaller, then more segments will be used. The result is still far more efficient than reading all the messages in the segment or even chasing hash table threads from message to message. The search table will be stored as the first regular message in the mseg_ segment, since the header message may only be 64 words long. 6 DATA STRUCTURES This section documents the data structures for the database itself. Data structures passed through interfaces are documented along with the interfaces. _________________________________________________________________ (3) IPC is unreliable because the system has no mechanism to wait for space to be available in the ITT. If the ITT is full, then IPC wakeups will be lost. Given the fact that the ITT is a wired database, and therefore of limited size, it may never be possible to guarantee that all IPC messages will be delivered under all circumstances. MTB-699 Multics Technical Bulletin Messages Priv Processes -> Users 6.1 DATABASE SEGMENT NAME The database will reside in the directory >system_control_dir>user_messages. The following declarations describe the names of the segments. declare 1 as_user_message_segment_name unaligned, 2 constant char (17), 2 index picture "99"; declare AS_USER_MESSAGE_SEGMENT_NAME_CONSTANT char (17) init ("as_user_message_") int static options (constant); 6.2 MESSAGE ID'S The following declaration describes the use of the 72 bit mseg_ message ID. Only the top 9 bits are used to leave room for larger clock values. This declaration is used only within the subsystem. Programs use unspec to copy data to this automatic variable and then back to a bit (72), rather than based overlays. declare 1 as_user_message_id aligned, 2 segment_index fixed bin (9) unsigned unaligned, 2 pad bit (11) unaligned, 2 pad_clock bit (52) unaligned; STRUCTURE ELEMENTS segment_index is the zero-based index of the segment of the user message database that contains the message. To convert a user_message message into an mseg_ message id, clear this field to zero. pad is zero in mseg_ message id's and is unused by user_message message id's. pad_clock is the clock reading from the SCU clock that uniquely identifies a message in an mseg_ segment. 6.3 MSEG_ HEADER MESSAGE This structure is stored in the 64 word mseg_ header message of all segments of the database. Some of the information is only valid in the first segment. Multics Technical Bulletin MTB-699 Messages Priv Processes -> Users declare as_user_message_system_info_ptr pointer; declare 1 as_user_message_system_info aligned based (as_user_message_system_info_ptr), 2 sentinel char (8) aligned, 2 time_of_bootload fixed bin (71), 2 segment_update_time fixed bin (71), 2 n_segments fixed bin, 2 highest_segment_in_use fixed bin, 2 handle_table_message_id bit (72) aligned; declare AS_USER_MESSAGE_SYSTEM_SENTINEL char (8) aligned init ("asumsys1") int static options (constant); STRUCTURE ELEMENTS sentinel is a value used to cross-check the validity of the database. It must have the value AS_USER_MESSAGE_SYSTEM_SENTINEL. time_of_bootload is the value of sys_info$time_of_bootload at the time this segment was initialized. This value is used to tell if a given segment has ever been used in the current bootload. This obviates the need to delete old database segments at system initialization. segment_update_time is the time that the values "n_segments" or "highest_segment_in_use" were last changed. This value should only be changed under the mseg_ lock on the first segment. This value is only valid in the first segment. n_segments is the number of segments in the database. This value should only be changed under the mseg_ lock on the first segment. This value is only valid in the first segment. highest_segment_in_use is the number of the highest numbered segment currently containing at least one message. This value should only be changed under the mseg_ lock on the first segment. This value is only valid in the first segment. handle_table_messsage_id is the mseg_ message id of the message containing the search table of handles. This message will always be the first message in the segment. The handle is stored here as a cross-check. MTB-699 Multics Technical Bulletin Messages Priv Processes -> Users 6.4 MESSAGE HANDLE TABLE Each mseg_ segment contains a message handle table as its first message. This fixed size table lists all the messages stored in the segment. The table is maintained with stacq. To add a message, the sender finds a slot with zero for a process_id and stacq's it in with either a specific target or the special value AS_USER_ANY_PROCESS_ID. Having claimed the process_id slot, the sender then adds the message to the mseg_ segment and records the handle and the message id. To delete a message, the process_id is stacq'd to zero. declare AS_USER_MESSAGES_PER_SEGMENT fixed bin init (900) int static options (constant); declare as_user_message_handle_table_ptr pointer; declare 1 as_user_message_handle_table aligned based (as_user_message_handle_table), 2 highest_in_use fixed bin (35), 2 process_id_list (900) bit (36) aligned, 2 handle_list (900) bit (72) aligned, 2 message_id_list (900) bit (72) aligned; declare AS_USER_ANY_PROCESS_ID bit (36) aligned init ("777777777777"b3) int static options (constant); STRUCTURE ELEMENTS AS_USER_MESSAGES_PER_SEGMENT is the maximum number of messages stored in an mseg_ segment. This is NOT used as a variable bound for the arrays below so that the compiler will generate efficient code. highest_in_use is the highests numbered slot in the arrays in use. This is maintained with the careful use of stacq. A process adding a message tries to stacq the max of the current value and the slot number just filled in. If the stacq fails, the new value must again be compared to the updater's slot number. Similiar care must be taken with deletions, since another process can claim a slot in between zeroing the process_id array and updating the highest_in_use. process_id_list is an array listing the target process_id of each message in the mseg_ segment. handle_list Multics Technical Bulletin MTB-699 Messages Priv Processes -> Users is an array listing the target handle of each message in the mseg_ segment. message_id_list is an array listing the mseg_ message_id of each message in the mseg_ segment. 6.5 PERPROCESS INFORMATION For efficiency, some information is stored in the ring 1 static of each process that uses the user_message facility. declare as_user_message_perprocess_info_ptr_ pointer external init (null ()); declare as_user_message_perprocess_info_ptr pointer; declare 1 as_user_message_perprocess_info aligned, 2 sentinel char (8) aligned, 2 segment_update_time fixed bin (71), 2 n_segments fixed bin, 2 ms_ptr (1000) pointer unaligned; declare AS_USER_MESSAGE_PROCESS_SENTINEL char (8) aligned init ("asumprc1") int static options (constant); STRUCTURE ELEMENTS sentinel is a value used to validate the copy of the per_process information. The information is discarded if this value does not contain AS_USER_MESSAGE_PROCESS_SENTINEL. segment_update_time is the time that this process last checked the per-system segment table in the first mseg_ segment header. n_segments is the number of mseg_ segments currently initiated in this process. ms_ptr are pointers to each of the n_segments mseg_ segments that this process has initiated. MTB-699 Multics Technical Bulletin Messages Priv Processes -> Users 7 INTERFACES This section describes the callable interfaces of the user_message facility. It also contains descriptions of the new mseg_ entrypoints. This section refers to each interface by the gate that contains it. Since there are three gates, a transfer vector is provided for all three. The transfer vector is briefly described at the end. ________________________________________ NAME: MSEG_ mseg_ is the inner ring utility procedure that implements .ms and .mbx segments. It maintains a segment containing a series of messages each marked with their source and AIM classification. ENTRY: MSEG_$FIND_HDR_MSG This entry, callable only from the ring of the segment, returns a pointer to the header message. USAGE declare mseg_$find_hdr_msg entry (ptr, ptr, fixed bin (18), bit (72) aligned, fixed bin (35)); call mseg_$find_hdr_msg (mseg_ptr, hdr_msg_ptr, hdr_msg_length, hdr_msg_access_class, code); ARGUMENTS mseg_ptr is a pointer to an mseg_ managed segment. (Input) hdr_msg_ptr is a pointer to the header message of segment, if any. (Output) hdr_msg_length is the length, in words, of the data in the header message. (Output) hdr_msg_access_class is the access class of the information stored in the header message. It is the callers responsability to check this against the process authorization before returning this information out of ring 1. (Output) _____ __________________ mseg_ user_message_priv_ _____ __________________ code will be zero if there was a header message defined, and error_table_$no_message otherwise. (Output) ENTRY: MSEG_$FIND_MSG This entry is similiar to mseg_$priv_read. No area pointer is supplied, because no data is copied. It is the callers responsibility to make all access control checks. USAGE declare mseg_$find_msg entry (ptr, ptr, fixed bin (35)); call mseg_$find_msg (mseg_ptr, mseg_message_info_ptr, code); ARGUMENTS mseg_ptr is a pointer to a mseg_ managed segment. (Input) mseg_message_info_ptr is a pointer to a standard mseg_message_info structure, as declared in mseg_message_info.incl.pl1. On output, the fields ms_ptr and ms_len are set to the actual location and length of the message text in the segment. The other output fields are set as usual. (Input, but fields output) code is a standard system status code. It will be error_table_$no_message if the requested message could not be located. (Output) ________________________________________ NAME: USER_MESSAGE_PRIV_ This gate contains entries used by trusted processes to send messages to user processes using the user_message facility. In this context, a "trusted process" is a process trusted not to mis-use this facility (e.g., by sending infinite quantities of messages or disrupting another process's use). Access to this gate does not permit a process to write messages down to lower authorizations without the ring1 system privilege. __________________ __________________ user_message_priv_ user_message_priv_ __________________ __________________ ENTRY: USER_MESSAGE_PRIV_$SYSTEM_INIT This entrypoint is called by the Initializer as part of Answering Service initialization. It deletes any information left from a previous bootload and creates a new user_message database. This entrypoint uses the syserr log to report details of problems on the bootload console. USAGE declare user_message_priv_$system_init entry (fixed bin (35)); call user_message_priv_$system_init (code); ARGUMENTS code is a standard system status code. It will be nonzero if and only if it was impossible to set up a functional user_message facility. ENTRY: USER_MESSAGE_PRIV_$ADD_MESSAGE This entry is called to queue a message for delivery to a process. USAGE declare user_message_priv_$add_message entry (ptr, fixed bin (35)); call user_message_priv_$add_message (as_user_add_message_info_ptr, code); ARGUMENTS as_user_message_add_ptr is a pointer to the as_user_message_add structure, as declared in as_user_message_add.incl.pl1 and described below. (Input) code is a standard system status code. It will be nonzero only if the message could not be added. __________________ __________________ user_message_priv_ user_message_priv_ __________________ __________________ AS_USER_MESSAGE_ADD_INFO declare as_user_message_add_info_ptr pointer; declare 1 as_user_message_add_info aligned based (as_user_message_add_info), 2 version char (8) aligned, 2 message_info aligned, 3 message_ptr pointer, 3 message_length fixed bin (18), 3 message_access_class bit (72) aligned, 3 message_id bit (72) aligned, 2 destination_info aligned, 3 group_id char (32) unal, 3 process_id bit (36) aligned, 3 handle bit (72) aligned, 3 reader_deletes bit (1) aligned; declare AS_USER_MESSAGE_ADD_INFO_VERSION_1 char (8) init ("auma0001") int static options (constant); STRUCTURE ELEMENTS version is the version of this structure, and must be set to AS_USER_MESSAGE_ADD_INFO_VERSION_1. (Input) message_ptr is a pointer to the text of the message to be added. (Input) message_length is the length, in words, of the message to be added. (Input) message_access_class is the access class marking for the message. Unless the caller has the ring1 system privilege set, this must be equal to the calling process authorization. message_id is the unique id assigned to the message when it is stored. (Output) group_id is the target group_id of the message. If process_id is not all ones, then this should be set to "" as it is not used. This may be a starname. If this is not "" and process_id is not all ones, the call is invalid and an error code is returned. __________________ __________________ user_message_priv_ user_message_priv_ __________________ __________________ process_id is the process id of the process to which the message will be delivered. If the message is to be delivered to more than one process, (or the target process id is unknown) then this must be set to all ones. handle is the protocol handle within the target processes to which the message will be delivered. This may not be zero. Handles with the first bit equal to 1 are reserved for global system protocols. reader_deletes specifies whether the recipient the message should delete it. If this is set to 1, then any recipient may delete the message. If this is set to 0, then only the sender may delete the message. NOTES The system automatically deletes all messages destined for a specific process id when the process terminates. Thus a sender may set reader_deletes to 0 and specify a process id, and the message will be readable until the process terminates. ENTRY: USER_MESSAGE_PRIV_$DELETE_MESSAGE_ID This entry is used by a sender to delete a message. The message must be specified by message_id. The message access class must be equal to the caller authorization unless the caller has ring1 privilege. USAGE declare user_message_priv_$delete_message_id entry (bit (72) aligned, fixed bin (35)); call user_message_priv_$delete_message_id (message_id, code); ARGUMENTS message_id is the message id returned by add_message when the message was added. code is a standard system status code. __________________ ___________________ user_message_priv_ user_message_admin_ __________________ ___________________ ENTRY: USER_MESSAGE_PRIV_$DELETE_PROCESS_MESSAGES This entrypoint deletes all the messages whose destination is a specific process as specified by process_id. Only those messages whose access classes are equal to the caller's authorization are deleted unless the caller has ring1 privilege. USAGE declare user_message_priv_$delete_process_messages entry (bit (36) aligned, fixed bin (35)); call user_message_priv_$delete_process_messages (pid, code); ARGUMENTS pid is the process id of the process whose messages are to be deleted. All messages whose destination is this process id specifically are deleted. code is a standard system status code. ________________________________________ NAME: USER_MESSAGE_ADMIN_ This gate contains entries callable by system maintainers and administrators. They permit an administrator to examine the messages in the user message database. ENTRY: USER_MESSAGE_ADMIN_$READ_MESSAGE This entrypoint permits a process to read any message in the user message database, subject to AIM restrictions. ring1 privilege is required to read messages whose access classes are not less than or equal to the caller's authorization. USAGE declare user_message_admin_$read_message entry (ptr, ptr, fixed bin (35)); call user_message_admin_$read_message (as_user_message_admin_read_info_ptr, as_user_message_info_ptr, area_ptr, code); ___________________ ___________________ user_message_admin_ user_message_admin_ ___________________ ___________________ ARGUMENTS as_user_message_admin_read_info_ptr is a pointer to the as_user_message_admin_read_info structure. as_user_message_info_ptr is a pointer to the as_user_message_info structure descrbed below under the "user_message_$read" entrypoint. All input fields in the structure except the version are ignored, since the message is completely specified by the user_message_admin_read_info structure. (Input) area_ptr is a pointer to an area. The message returned will be copied into storage allocated in this area. (Input) code is a standard system status code. AS_USER_MESSAGE_ADMIN_READ_INFO declare as_user_message_admin_read_info_ptr pointer; declare 1 as_user_message_admin_read_info aligned based (as_user_message_admin_read_info_ptr), 2 version char (8) aligned, 2 source_group_id char (32) unal, 2 source_process_id bit (36) aligned, 2 target_group_id char (32) unal, 2 target_process_id bit (36) aligned, 2 target_handle bit (72) aligned, 2 after_message_id bit (72) aligned; declare AS_USER_MESSAGE_ADMIN_READ_INFO_VERSION_1 char (8) init ("aumar001") int static options (constant); STRUCTURE ELEMENTS version must be AS_USER_MESSAGE_ADMIN_READ_INFO_VERSION_1. (Input) source_group_id is a starname specifying the sender of the message to be read. "" is equivalent to *.*.*. (Input) source_process_id is the process id of the source process. If zero, the source process id is not specified. (Input) ___________________ _____________ user_message_admin_ user_message_ ___________________ _____________ target_group_id is a starname specifying the recipient(s) of the message to be read. This starname must be character identical to the starname specified by the message sender for a message to match. That is, if a message is sent to "*.*.a", then this value must be "*.*.a" to read it out. If this value is equal to "", messages are read regardless of their group id. (Note that if a message is sent to all users it is stored with a destination of "*.*.*", not "".) (Input) target_process_id is the process id of the recipient of the message. If zero, then the recipient process id is not specified. (Input) target_handle is the target handle of the message to be read. If zero, then the handle is not specified. (Input) after_message_id is a message id of a message previously read. The message returned will be one entered after the message identified by this message_id. If any of the target_ fields are specified, then it will be the next message that matches those fields. If no target fields are specified, then it will be the very next message. If this message_id refers to a message whose access class is not less than or equal to that of the process, and the caller lacks ring1 privilege, this argument is ignored. (Input) ________________________________________ NAME: USER_MESSAGE_ This gate allows a user process to read the messages sent to it by trusted processes. ENTRY: USER_MESSAGE_$READ_MESSAGE This entry is used to read a message from the user message database. USAGE declare user_message_$read_message entry (ptr, ptr, fixed bin (35)); _____________ _____________ user_message_ user_message_ _____________ _____________ call user_message_$read_message (area_ptr, as_user_message_info_ptr, code); ARGUMENTS area_ptr is a pointer to an area in which the returned message will be allocated. (Input) as_user_message_info_ptr is a pointer to the as_user_message_info structure. code is a standard system status code. AS_USER_MESSAGE_INFO declare as_user_message_info_ptr pointer; declare 1 as_user_message_info aligned based (as_user_message_info_ptr), 2 version char (8) aligned, 2 flags aligned, 3 read_message_id bit (1) unaligned, 3 read_after_message_id bit (1) unaligned, 3 no_handle_given bit (1) unaligned, 3 ring_given bit (1) unaligned, 3 dont_delete bit (1) unaligned, 3 pad bit (31) unaligned, 2 message_info aligned, 3 message_ptr pointer, 3 message_length fixed bin (18), 3 message_id bit (72) aligned, 3 message_access_class bit (72) aligned, 3 message_handle bit (72) aligned, 3 message_ring fixed bin (3), 2 sender_info aligned, 3 group_id char (32) unaligned, 3 process_id bit (36) aligned, 2 destination_info aligned, 3 group_id char (32) unal, 3 process_id bit (36) aligned, 3 ring fixed bin (3) aligned; declare AS_USER_MESSAGE_INFO_VERSION_1 char (8) aligned init ("asum0001") int static options (constant); _____________ _____________ user_message_ user_message_ _____________ _____________ STRUCTURE ELEMENTS version must be equal to AS_USER_MESSAGE_INFO_VERSION_1. (Input) read_message_id is a flag. If "1"b, then the field "message_id" is interpreted as an input argument. The message whose id is "message_id" is returned if it exists. The message_handle field is not respected on input. This flag may not be on if read_after_message_id is on. (Input) read_after_message_id is a flag. If "1"b, then the field "message_id" is interpreted as an input argument. The first message after message_id for the handle message_handle is returned. This flag may not be on if read_message_id is on. (Input) no_handle_given is a flag. If "1"b, then a message is returned subject to the read_message_id or read_after_message_id flags without regard to the handle of the message. If "0"b, then the field message_handle specifies the handle of the message to be returned. (Input) ring_given is a flag. If "1"b, then the field message_ring is respected on input, and specified the destination ring of the message to be read. If "0"b, then messages destined for the current validation level are returned. (Input) dont_delete is a flag. If "1"b, then the message is not deleted from the user message database even if it is marked for deletion by its recipient. If "0"b, the message is deleted if it is marked for deletion. (Input) message_ptr is a pointer to the allocated copy of the message. (Output) message_length is the length of the allocated message in words. (Output) message_access_class is the access class of the message. (Output) _____________ _____________ user_message_ user_message_ _____________ _____________ message_handle if the handle within the process to which the message was sent. If the flag no_handle_given is "1"b, then this is (Output). Otherwise it is (Input). message_ring is the ring to which the message was sent. This field is only respected of the flag ring_given is "1"b. (Input) sender_info is a substructure describing the process who sent the message. group_id is the User.Project.* user name of the sender. (Output) process_id is the process id of the sender. (Output) ring is the validation level of the sender at the time that the sender sent the message. (Output) destination_info is a substructure describing how the message was addressed. group_id is the starname that specified the user name of the recipient(s). (Output) process_id is the process id, if any, specified for the recipient. If no process id was specified then this will contain all ones. (Output) ring is the ring specified for the recipient. (Output) NOTES Normally, a caller should fill this structure up as follows: set read_message_id to 1 if the message if is known, zero otherwise. Set read_after_message_id, no_handle_given, ring_given, and dont_delete to 0. They are only used for tools that display the messages pending for the process. Set the message_handle to the handle for which the message is to be read. _____________ _____________ user_message_ user_message_ _____________ _____________ 8 TRANSFER VECTOR User ring callers of this facility will call the transfer vector as_user_message_ rather than the actual gates. This removes dependencies on the names of the gates themselves, and permits us to move the gate entries to other gates at a future time. The following table gives the corespondance between gate entries documented above and transfer vector names. GATE NAME TRANSFER VECTOR NAME user_message_priv_$system_init as_user_message_$system_init user_message_priv_$add_message as_user_message_$priv_add_message user_message_priv_$delete_message_id as_user_mesage_$priv_delete_message_id user_message_priv_$delete_process_messages as_user_message_$priv_delete_process_messages user_message_admin_$read_message as_user_message_$admin_read_message user_message_$read_message as_user_message_$user_read_message 9 AS_REQUEST FOR B2 TERMINAL INFORMATION To meet the B2 criteria, it is neccessary that a process attaching a communicationn channel other than its login channel be able to obtain the security-related information about that channel. In particular, the process must be able to learn the user name of the person identified and authenticated for the channel via the dial or slave pre-access requests. This section describes a facility that allows a process to query the Answering Service for information about a communications channel. The process sends an as_request message, and the Answering Service replies with a user_message. Multics Technical Bulletin MTB-699 9.1 THE AS REQUEST ITSELF This section describes the data structure passed in the as_request itself. ASR_COM_CHANNEL_INFO This structure is passed to the as_request mechanism via send_as_request_$block. All fields are input. dcl 1 asr_com_channel_info aligned based (asr_com_channel_info_ptr), 2 header aligned like as_request_header, 2 channel_name char (32) unaligned, 2 reply_message_handle bit (72) aligned; STRUCTURE ELEMENTS header is the standard as_request_header structure. The user of this must fill in the version and type fields, and set the reply_channel to zero so that send_as_request_ will manage the event channel. channel_name is the communications channel name to return information about. reply_message_handle is the message_handle to which a user message containing the information about the channel will be sent. ASR_REPLY_COM_CHANNEL_INFO This structure is packed into the 72 bit IPC reply message. dcl 1 asr_reply_com_channel_info aligned based (asr_reply_com_channel_info_ptr), 2 error_code fixed bin (35), 2 pad bit (36) aligned; STRUCTURE ELEMENTS error_code Is an standard system status code. It will be zero if a user_message has been sent to the process with the requested information, and non-zero if the user lacked access to issue the query. Multics Technical Bulletin MTB-699 9.2 THE REPLY MESSAGE AS_COM_CHANNEL_INFO This structure is returned as a user message in reply to the com_channel_info as_request. dcl 1 as_com_channel_info aligned based (as_com_channel_info_ptr), 2 version char (8), 2 channel_name char (32), 2 flags aligned, 3 access_control unaligned, 4 login bit (1), 4 dial_slave bit (1), 4 priv_attach bit (1), 4 dial_server bit (1), 4 dial_out bit (1), 3 attached_to_caller bit (1) unaligned, 3 user_authenticated bit (1) unal, 3 dialed_to_caller bit (1) unal, 3 pad bit (28) unaligned, 2 service_type fixed bin, 2 current_service_type fixed bin, 2 access_class (2) bit (72) aligned, 2 current_access_class bit (72) aligned, 2 auth_user_name char (32) unaligned; STRUCTURE ELEMENTS version is the version of this structure. The current version is AS_COM_CHANNEL_INFO_VERSION_1. channel_name is the name of the channel about which information is returned. flags is a substructure of bit flags. access_control is a set of flags that specify under what circumstances the system checks access to the channel ACS (>sc1>rcp>CHANNEL_NAME.acs). Note that the system always checks access to the acs before returning this structure to a user for a channel which is not attached to the user. These flags are the same as the flags in the CMF/cdt. Multics Technical Bulletin MTB-699 login is "1"b if a user must have rw access to the ACS to login over the channel. dial_slave is "1"b if a user must have rw access to the ACS to give the dial or slave pre-access commands over the channel. If this flag is "1"b, then any user giving a dial or slave pre-access command must use the -user control argument to supply a user name and project. priv_attach is "1"b if a process must have rw access to the ACS to privileged attach the channel. dial_server is "1"b if a process acting as a dial server must have rw access to the ACS for the channel to be dialed to the process. dial_out is "1"b if a process must have rw access to the ACS to do a dial_out on the channel. attached_to_caller is "1"b if the specified channel is currently attached to the calling process. All of the fields below are not returned to the user if this is "0"b to prevent processes from spying on other processes. user_authenticated This field is not returned if attached_to_channel is "0"b. It is "1"b if a user was identified and authenticated on the channel. dialed_to_caller This field is not returned if attached_to_channel is "0"b. It is "1"b if the channel is attached to the caller via the dial facility. service_type This field is not returned if attached_to_channel is "0"b. It is the service type defined in the cdt for the channel. current_service_type This field is not returned if attached_to_channel is "0"b. It is the current service type of the channel. access_class This field is not returned if attached_to_channel is "0"b. It is the AIM access class defined in the cdt for the channel. Multics Technical Bulletin MTB-699 current_access_class This field is not returned if attached_to_channel is "0"b. It is the AIM access class associated with the current attachment of the channel. auth_user_name This field is not returned if attached_to_channel is "0"b. This field is only returned if user_authenticated is "1"b. It is the person.project name of the user authenticated and identified for the channel. 9.3 SUBROUTINE INTERFACE FOR COM_CHANNEL_INFO The following subroutine is provided to encapsulate the use of as_request and the user message. _____________________ _____________________ get_com_channel_info_ get_com_channel_info_ _____________________ _____________________ NAME: GET_COM_CHANNEL_INFO_ This subroutine returns info about a communications channel by querying the answering service. USAGE declare get_com_channel_info_ entry (ptr, fixed bin (35)); call get_com_channel_info_ (as_com_channel_info_ptr, code); ARGUMENTS as_com_channel_info_ptr is a pointer to the as_com_channel_info structure, as defined above. The version and channel name fields must be set. code is a standard system status code. If will be non-zero if the specified channel does not exist or if the user lacks access to get information about the channel. For channels attached to the caller's process, no further access required. Otherwise, r access to the channel ACS (>sc1>rcp>CHANNEL_NAME). _____________________ ____ get_com_channel_info_ tty_ _____________________ ____ 9.4 TTY_ CONTROL ORDERS ________________________________________ NAME: TTY_ To make it easier to write applications, a control order interface to tty_ will be provided for this. At the same time, a control order that should have been added when starname processing was added to dial_manager_ will be added as well. Order name: get_com_channel_info Function: This control order returns the Answering Service com_channel_info structure for the attached channel. The user provides the as_com_channel_info structure as described for get_com_channel_info_ subroutine, filling in the version, and passes the address of the structure as the info_ptr. Order name: get_channel_name Function: This control order returns the name of the communications channel to which the switch is attached. This is useful when the switch is attached with a generic destination or a starname. The info_ptr should point to a char (32) aligned variable. 10 TASK LIST The following tasks are neccessary to complete this: 1) Code the message facility as described here. 2) Create functional tests for the gate level interfaces. 3) Create an as_request for a process to ask for information about a dialed channel that responds with a user_message. 4) Change tty_ to implement a control order that uses the as_request to return the information. Include io_call support so that the as_request can be tested from command level. Multics Technical Bulletin MTB-699 11 TESTING The gate interfaces described here will be tested with the standard gate testing technology, which is not completely defined as of this writing. The as_request mechanism is accessed through a subroutine that can be tested as if it were a gate.