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.