Configuring the Restriction facility

Post installation, a system administrator can optionally add a restrict.txt file in $gtm_dist to restrict the use of certain GT.M facilities to a group-name. The owner and group for $gtm_dist/restrict.txt can be different from those used to install GT.M. The file may contain zero or more of the following case-insensitive lines in any order:

A{D|L|M|PD|ZA}_ENABLE:[comma-separated-list-of-options]:{path-to-sock-file|host:port}[:tls-id]
BREAK[:<group-name>]
CENABLE[:<group-name>]
DIRECT_MODE[:<group-name>]
DSE[:<group-name>]
HALT[:<group-name>]
LIBRARY:[<group-name>]
LKE:[<group-name>]
LKECLEAR:[<group-name>]
LOGDENIALS:[<group-name>]
PIPE_OPEN[:<group-name>]
TRIGGER_MOD[:<group-name>
ZBREAK[:<group-name>]
ZCMDLINE[:<group-name>]
ZEDIT[:<group-name>]
ZHALT[:<group-nam>]
ZLINK[:<group-nam>]
ZROUTINES[:<group-nam>]
ZRUPDATE[:<group-nam>]
ZSYSTEM[:<group-name>]

If the file $gtm_dist/restrict.txt does not exist, GT.M does not restrict any facilities.

Any non-empty lines that do not match the above format cause processes with read-only permission to behave as if they could not read the file, and GT.M enforces all restrictions.

Restrictions apply as follows:

GT.M facility

Behavior

APD_ENABLE

GT.M supports the ability to log actions initiated from a principal device including MUMPS commands typed interactively, or piped in by a script or redirect, from the principal device ($PRINCIPAL) and / or any information entered in response to a READ from $PRINCIPAL. An action initiated from $PRINCIPAL executes as usual when Audit Principal Device is disabled, which it is by default. However, when Audit Principal Device is enabled, GT.M attempts to send the action out for logging before acting on it. Additionally, the $ZAUDIT Intrinsic Special Variable (ISV) provides a Boolean value that indicates whether Audit Principal Device is enabled. Please see the Audit Principal Device section below for details.

AD_ENABLE

Enables the logging of DSE commands from shell and DSE prompt

AL_ENABLE

Enables the logging of LKE commands from shell and LKE prompt

AM_ENABLE

Enables the logging of MUPIP commands from shell and MUPIP prompt

AZA_ENABLE

Enables the use of the $ZAUDITLOG() function. When LGDE is specified as the keyword for AZA_ENABLE, GDE logs GDE commands

BREAK

GT.M ignores any BREAK command

CENABLE

the process acts like $gtm_nocenable is TRUE and ignores any CENABLE deviceparameter

DIRECT_MODE

mumps -direct terminates immediately with a RESTRICTEDOP error

DSE

terminates immediately with a RESTRICTEDOP error

HALT

any HALT produces a RESTRICTEDOP error

LIBRARY

any attempt to load an external library produces a RESTRICTEDOP error

Library restrictions apply to third party libraries loaded by GT.M directly and those loaded at the behest of GT.M applications. This restriction allows administrators to control which libraries GT.M is able to load at run-time. To allow library loading, place symbolic links to the desired libraries in $gtm_dist/plugin.

LKE

any invocation of the $gtm_dist/lke utility produces a RESTRICTEDOP error

LKECLEAR

any LKE CLEAR produces a RESTRICTEDOP error

LOGDENIALS

restrict logging when GT.M denies access to a process to the named groups

GT.M supports logging a number of errors related to permissions and access using the syslog() facility. The GT.M restriction LOGDENIALS provides a facility for disabling this loggging on a Unix group basis. If this mechanism is not used the logging takes place for all GT.M processes. If the restriction is used logging takes place for specified groups only.

PIPE_OPEN

any OPEN of a PIPE device produces a RESTRICTEDOP error

TRIGGER_MOD

any $ZTRIGGER() or MUPIP TRIGGER that attempts a change or delete produces a RESTRICTEDOP error; in addition, while executing code within a trigger, ZBREAK results in a RESTRICTEDOP error, and both ZBREAK and ZSTEP actions are ignored

ZBREAK

any ZBREAK or ZSTEP produces a RESTRICTEDOP error

ZCMDLINE

GT.M returns an empty string for all references to $ZCMDLINE

ZEDIT

any ZEDIT produces a RESTRICTEDOP error

ZHALT

any ZHALT produces a RESTRICTEDOP error

ZLINK

any explicit ZLINK produces a RESTRICTEDOP error

ZROUTINES

any SET of $ZROUTINES produces a RESTRICTEDOP error

ZRUPDATE

any ZRUPDATE produces a RESTRICTEDOP error

ZSYSTEM

any ZSYSTEM produces a RESTRICTEDOP error

If the file exists, a process:

Note that restricting $ZCMDLINE prevents things like: mumps -run %XCMD 'for read x xecute x' which can act as substitutes for Direct Mode.

In order to limit pathological looping from restricted HALT or ZHALT, if A GT.M process issues a second occurrence of the restricted command within half a second, the process terminates after sending a fatal error to both the principal device and the syslog, and also producing a GTM_FATAL* context file, but no core file. With these restrictions in place, a process should terminate with, for example: ZGOTO 0. Note that, with or without a restriction, executing these commands as part triggered logic on a replicating instance may cause the Update Server to terminate and thereby stop replication.

ZSYSTEM and PIPE OPEN command restriction facility

The GT.M restriction mechanism recognizes the following lines:

    ZSYSTEM_FILTER[:M labelref]
    PIPE_FILTER[:M labelref]

The labelref must include a routine name. If a process is restricted by a ZSYSTEM or PIPE_OPEN line in the restrictions file that restriction takes precedence over the corresponding filter restriction. Otherwise when a process is subject to these restrictions, GT.M inserts an invocation of the labelref prior to the restricted command, passing a string containing the argument to the ZSYSTEM command or the command deviceparameter of the PIPE OPEN. The path to the filter routine must be included in $zroutines. FIS recommends that the filter routine is placed in a location with restricted access such as $gtm_dist. If the filter invocation return is -1,GT.M produces a RESTRICTEDOP error, otherwise it executes the command using the returned string via output parameters as a, possibly identical, replacement for the original string. Since GT.M uses the call-ins mechanism to execute the filters, a filter invocation inside a TP transaction in call-ins produces a CITPNESTED error. Note that because ZSYSTEM and OPEN are not Isolated actions FIS recommends against their use within a TP transaction. Filters will also increment the nested level of call-ins. A recursive filter invocation produces a NOFILTERNEST error. GT.M reports all filter errors to the operator log accompanied by a COMMFILTERERR.

An example restrict file for this:

cat $gtm_dist/restrict.txt
ZSYSTEM_FILTER:^filterzsy
PIPE_FILTER:^filterzsy

The actual filter routine:

filterzsy(inarg,outarg);
 if ""=inarg set outarg="-1;must provide a command" quit
 for i=1:1 set arg=$piece(inarg,";",i) quit:""=arg  do  quit:$data(outarg)
 . for  quit:$zchar(9,32)'[$extract(arg)  set arg=$extract(arg,2,9999)
 . set cmd=$piece(arg," ")
 . for restrict="sudo","cd" if cmd=restrict set outarg="-1;command "_restrict_" not permitted" quit
 . quit:$data(outarg)
 . if "echo"=cmd set $piece(arg," ")="echo #",$piece(inarg,";",i)=arg    ;example of modification
 set:'$data(outarg) outarg=inarg
 quit +outarg

Filter execution starts with $STACK=1 ($ZLEVEL=2).

Following are the GT.M commands, Intrinsic Special Variables, and functions whose behavior changes in the context of a filter invocation.

ZGOTO 0 (zero) returns to the processing of the restricted command as does ZGOTO 1 (one) with no entryref, while ZGOTO 1:entryref replaces the originally invoked filter and continues filter execution.

$ZTRAP/$ETRAP NEW'd at level 1.

$ZLEVEL initializes to one (1) in GTM$CI, and increments for every new stack level.

$STACK initializes to zero (0) in GTM$CI frame, and increments for every new stack level.

$ESTACK NEW'd at level one (1) in GTM$CI frame.

$ECODE/$STACK() initialized to the empty string at level one (1) in GTM$CI frame.

After the filter completes, GT.M restores the above to their values at the invocation of the filter.

Audit Logging facility

To enable the audit logging facility, add a line in the following format to $gtm_dist/restrict.txt:

A{D|L|M|PD|ZA}_ENABLE:[comma-separated-list-of-options]:{path-to-sock-file|host:port}[:tls-id]

APD_ENABLE enables the logging of all code entered from Direct Mode and optionally any input entered on the principal device ($PRINCIPAL). AD_ENABLE, AL_ENABLE and AM_ENABLE enable the logging of all DSE, LKE and MUPIP commands entered from the shell and utility prompt. AZA_ENABLE enables the logging for arguments to the $ZAUDITLOG() function.

  • The optional "comma-separated-list-of-options" can consist of zero or more of these options:

    • LGDE - Enable logging of all GDE commands from shell and GDE prompt. The LGDE option only applies to AZA_ENABLE.

    • RD - Enables logging of all responses from READ at the Direct Mode prompt. The RD option only applies to APD_ENABLE.

    • TLS - Enables TLS connectivity between GT.M and the logger; this option requires a tls-id and the host information (e.g. IP/port or hostname/port).

  • The "path-to-sock-file" is the absolute path of the UNIX domain socket file for connecting to the logger.

  • The "host" is the hostname or numeric IPv4/IPv6 address of the logger; numeric IP addresses must be enclosed in square brackets (i.e. '[' and ']').

  • The "port" is the port number the logger listens on.

  • You can specify the same or different {path-to-sock-file|host:port} for any audit logging facility.

  • The optional "tls-id" is the label of the section within the GT.M configuration file that contains TLS options and/or certificates for GT.M to use; logging ignores any "tls-id" that appears on a line without the "TLS" option.

If parsing any "A*_ENABLE" line in restriction file or initializing logger information fails, GT.M enforces all restrictions (default restriction file behavior).

Examples:

APD_ENABLE::/path/to/sock/file/audit.sock

Adding this line to the restriction file enables APD. GT.M connects with the logger via UNIX domain socket using the domain socket file "/path/to/sock/file/audit.sock" and sends all Direct Mode activity from $PRINCIPAL to logger.

APD_ENABLE:RD:[123.456.789.100]:12345

Adding this line to the restriction file enables APD. GT.M connects with the logger (listening on port 12345 at the IPv4 address 1enable23.456.789.100) via TCP socket and sends all Direct Mode and READ activities from $PRINCIPAL to logger.

APD_ENABLE::loggerhost:56789

Adding this line to the restriction file enables APD. GT.M connects with the logger (listening on port 56789 at the hostname "loggerhost") using a TCP socket and sends all Direct Mode activities from $PRINCIPAL to logger.

APD_ENABLE:TLS,RD:[1234:5678:910a:bcde::f:]:12345:clicert

Adding this line to the restriction file enables APD. GT.M connects with the logger (listening on port 12345 at the IPv6 address 1234:5678:910a:bcde::f:) via TLS socket. GT.M configures its TLS options for APD based on the contents within the section of the configuration file labeled "clicert". GT.M sends all Direct Mode and READ activities from $PRINCIPAL to a logger.

AD_ENABLE::/path/to/sock/file/audit.sock

Adding this line to the restriction file enables the logging of all DSE commands. GT.M connects with the logger via UNIX domain socket using the domain socket file "/path/to/sock/file/audit.sock" and sends all DSE activity to a logger.

AL_ENABLE::/path/to/sock/file/audit.sock

Adding this line to the restriction file enables the logging of all LKE commands. GT.M connects with the logger via UNIX domain socket using the domain socket file "/path/to/sock/file/audit.sock" and sends all LKE activity to a logger.

AM_ENABLE::/path/to/sock/file/audit.sock

Adding this line to the restriction file enables the logging of all MUPIP commands. GT.M connects with the logger via UNIX domain socket using the domain socket file "/path/to/sock/file/audit.sock" and sends all MUPIP activity to a logger.

AZA_ENABLE:LGDE:/path/to/sock/file/audit.sock

Adding this line to the restriction file enables the logging of all $ZAUDITLOG() arguments. GT.M connects with the logger via UNIX domain socket using the domain socket file "/path/to/sock/file/audit.sock" and sends all $ZAUDITLOG() arguments to a logger.Because of LGDE option, it also sends all GDE commands to that logger.

Logging

A "logger" is a separate server-like program responsible for receiving and logging information from GT.M's audit logging facilities (A*_ENABLE). A logger program can run in the foreground or background. You can use the same logger program or specify different logger programs for each audit logging facilities.

Click on Download dm_audit_listener.zip to download sample logger programs. You can also download dm_audit_listener.zip from http://tinco.pair.com/bhaskar/gtm/doc/books/ao/UNIX_manual/downloadables/dm_audit_listener.zip.

dm_audit_listener.zip contains three sample logger programs that can be used for logging. The difference amongst the three is the socket connection type used to communicate with GT.M. The dm_audit_unix_listener.c, dm_audit_tcp_listener.c, and dm_audit_tls_listener.c use the UNIX domain, TCP, and TLS socket type respectively to communicate with GT.M. Choose the logger program based on the connection type specified in the A*_ENABLE entry in $gtm_dist/restrict.txt. The zip file contains a Makefile to help with compilation.

Compiling all logger programs:

Unzip dm_audit_listener.zip and run the make command. This compiles the three logger programs.

Compiling logger programs seperately:

  • Compile the UNIX domain logger (dm_audit_unix_listener.c) with:

    make dm_audit_unix_listener
  • Compile the TCP logger (dm_audit_tcp_listener.c) with:

    make dm_audit_tcp_listener
  • To compile the TLS logger (dm_audit_tls_listener.c), the make command links the ssl (-lssl) and crypto (-lcrypto) libraries when compiling. Assuming you have OpenSSL development packege installed, compile the TLS logger with:

    make dm_audit_tls_listener 

    If you do not have the OpenSSL development package installed, then you will have to install it first.

Running the Logger Program:

  • Run the UNIX domain logger as follows:

    ./dm_audit_unix <logfile> <sockfile>
    • The "logfile" field is file path of output audit log.

    • The "sockfile" field is file path of unix domain socket file.

  • Run the TCP logger as follows:

    ./dm_audit_tcp <logfile> <portno>
    • The "logfile" field is file path of output audit log.

    • The "portno" field is port number to listen on.

  • Run the TLS logger as follows:

    ./dm_audit_tls_listener <logfile> <portno> <certfile> <privkeyfile> <passphrase> [-clicert] [-cafile <CAfilepath>] [-capath <CApath>]
    • The "logfile" field is file path of output audit log.

    • The "portno" field is port number to listen on.

    • The "certfile" field is file path of TLS/SSL certificate to use.

    • The "privkeyfile" field is file path of private key to use.

    • The "passphrase" field is password or passphrase for certificate/key.

    • The "clicert" option (optional), if present, then logger requests for client certificate when performing the TLS handshake with GT.M.

    • The "CAfilepath" field (optional) is path to file of CA certificates in PEM format (specifies the locations for SSL context, at which CA certificates for verification purposes are located.)

    • The "CApath" field (optional) is path to directory containing CA certificates in PEM format (specifies the locations for SSL context, at which CA certificates for verification purposes are located.)

Logger Message Format:

The seven fields in a message are separated by semicolons (';') and contain information on the to-be-logged activity. Each to-be-logged message sent to the logger from GT.M has the following format:

dist=<path>; src={1|2|3|4|5|6}; uid=<uid>; euid=<euid>; pid=<pid>; tty=<ttyname>; command=<text>
  • The "dist" field, shows the path to location of the sender/user's $gtm_dist (GT.M executables).

  • The "src" field shows one (1) for Direct Mode input, two (2) for READ input from $PRINCIPAL or when the standard input to the Direct Mode prompt is not from a terminal (that is, commands entered via HEREDOCs from a shell script or a UNIX pipe), three (3) for MUPIP commands, four (4) for $ZAUDITLOG() and GDE, five (5) for LKE, and six (6) for DSE.

  • The next three fields ("uid", "euid", and "pid") show (respectively) decimal representations of the user ID, effective user ID, and process ID of the process sending the message.

  • The tty field shows the standard input for the process. If the standard input at process startup is not terminal device, GT.M logs tty=0.

  • The "command" field is the input provided on the GT.M side.

Examples:

dist=/path/to/gtm_dist; src=1; uid=112233445; euid=112233445; pid=987654; tty=/dev/pts/0; command=write "Hello world",! 
dist=/path/to/gtm_dist; src=1; uid=998877665; euid=998877665; pid=123456; tty=/dev/pts/1; command=read num  
dist=/path/to/gtm_dist; src=2; uid=998877665; euid=998877665; pid=123456; tty=/dev/pts/1; command=7

This example demonstrates the audit logging with APD_ENABLE:RD facility. Logging activity shows that PID 987654 and PID 123456 ran two Direct Mode commands - write "Hello world",! and read num. The response from PID 123456 for read num was 7.