remctld is normally started using tcpserver or from inetd, but it may be run in stand-alone mode as a daemon using -m. Either -s must be given to use an alternate identity (which will require the same flag be used for remctl client invocations), or it must be run as root to read the host keytab file. remctld logs its activity using syslog (the daemon facility).
The location of the configuration file may be specified with the -f option. The default location is /etc/remctl.conf. For information on the format of the configuration file, see ``CONFIGURATION FILE'' below.
When the command is run, several environment variables will be set providing information about the remote connection. See ENVIRONMENT below for more information.
Command-line and configuration options and ACL methods are annotated below with the version at which they were added. For version information for more general features, see COMPATIBILITY below.
This option is ignored if remctld is passed already open sockets via the systemd socket activation protocol. In that case, the bind addresses of the sockets should be controlled via the systemd configuration.
To determine the port, remctld attempts to look up the "remctl" service in the local /etc/services file and uses the port defined there. If the "remctl" service could not be found, it uses 4373, the registered remctl port.
This option is ignored if remctld is passed already open sockets via the systemd socket activation protocol. In that case, the listening port should be controlled via the systemd configuration.
command subcommand executable [option=value ...] acl [acl ...]
Each command consists of a command, a subcommand, and zero or more arguments. Each configuration line defines an acceptable command and subcommand (or, if "ALL" is used as mentioned below under command and subcommand, a set of commands). The first configuration line matching the received command is used, so list more specific entries before more general entries.
Blank lines and lines beginning with "#" are ignored. Lines can be continued on the next line by ending them with a backslash ("\"). Be aware that comments can be continued with a backslash as well.
As a special case, a line like:
include file
will include file as if its contents were pasted verbatim into the configuration file at that point. file may be a directory, in which case all files whose names do not contain a period found in that directory will be included (in no particular order). file should be a fully qualified path.
The meaning of the fields on each configuration line are:
If the keyword "ALL" is used instead of a specific subcommand, this line matches all commands with the given subcommand (so "ALL ALL" matches any command) and can be used to dispatch all commands to the same executable with the same ACLs. Since the first matching entry is used, list entries for specific commands first (if any) and then the "ALL" catch-all.
Note that while the subcommand is passed to the executable as a command-line option, the command is not. The command is available to the executable in the environment variable REMCTL_COMMAND (see ENVIRONMENT below).
The command "help" is handled specially if no such command is defined in the configuration file. See below under the "help" and "summary" options.
If the keyword "ALL" is used instead of a specific subcommand, this line matches all subcommands with the given command and can be used to dispatch all subcommands under that command to the same executable with the same ACLs. Since the first matching entry is used, list entries for specific services first (if any) and then the "ALL" catch-all.
If the keyword "EMPTY" is used instead of a specific subcommand, this line matches only commands where no subcommand was given.
The subcommand is always passed as the first argument to the executable program that is listed for that service unless no subcommand was given.
If remctld receives the command "help" with one or two arguments, and no "help" command is defined in the configuration file, the server will take the command arguments as a command and subcommand. It will then look through the configuration for a configuration line matching that command and subcommand with a "help" option set. If one is found and the user is authorized to run that command, the server will run the specified executable with the argument arg and second and optional third arguments taken from the arguments to the "help" command, sending the output back to the user.
This permits a standard interface to get additional help for a particular remctl command. Also see the "summary" option.
For example, if the command is "admin passwd username password", then you'd want to set logmask to 3, so the password argument gets logged as "**MASKED**". If the command is "user passwd username old-password new-password", you'd want to set logmask to "3,4".
The command cannot be passed on standard input, so n must be at least 1. If this option is set to "last" and no arguments are given except the command and possibly the subcommand, nothing will be passed on standard input.
This option is used primarily for passing large amounts of data that may not fit on the command line or data that contains NUL characters. It can also be used for arguments like passwords that shouldn't be exposed on the command line. Only at most one argument may be passed on standard input to the command. Be aware that even if the subcommand is the designated argument to pass on standard input ("stdin=1"), the subcommand may not contain NUL characters.
The user option is simpler and easier if remctld is running as root. However, it may be desirable in some configurations to run remctld as a non-root user, and remctl-shell (which shares the same configuration files) usually runs as a non-root user. In those cases, this option can be used to use sudo to switch users before running the command.
Since the argument is passed verbatim to sudo's -u option, you can specify a numeric UID by prepending it with "#".
If remctld receives the command "help" with no arguments, and no "help" command is defined in the configuration file, the server will look through the configuration for any command with a "summary" option set. If this option is set, and the user is authorized to run the command, the server will run the specified executable with the argument arg, sending the output back to the user. It will do this for every command in the configuration that meets the above criteria.
This allows display of a summary of available commands to the user based on which commands that user is authorized to run. It's a lightweight form of service discovery. Also see the "help" option.
If method is omitted, acl must either begin with "/" or must not contain "=". Otherwise, it will be parsed as an option instead. If there is any ambiguity, prepend the method.
As a special exception for backward compatibility, the ACL "ANYUSER" (case-sensitive) is treated as equivalent to "anyuser:auth".
Each entry is checked in order, and access is granted as soon as an entry matches. If no entry matches, access is denied. The following methods may supported; however, be aware that the availability of several ACL types depends on whether remctld was built with that support. Each ACL type is annotated with the version in which it was added.
For backwards compatibility, the ACL "ANYUSER" is treated as identical to "anyuser:auth". This was the only supported any-user ACL syntax prior to remctl 3.10.
For backward compatibility, a line like:
include [<method>:]<data>
in an ACL file behaves exactly as if the "include" directive had been omitted, except that the default method is "file". Thus, writing:
include <path>
in an ACL file is the same as writing:
file:<path>
and is handled identically to the include directive in configuration files.
Remember that access is granted as soon as an entry matches. For "deny" rules to be effective, they therefore must come before any ACLs they are intended to override. Be careful when using "deny" when including a directory of ACL files, since the files in that directory are read in an undefined order (not in alphabetical order by filename). It's best to explicitly include the file containing "deny" ACL rules first.
Note that "deny" only denies access; it never grants it. Thus, deny alone does not grant access to anyone, and using deny on itself as in "deny:deny:foo" neither denies nor grants access to anyone.
This method is supported only if remctld was compiled with GPUT support by using the "--with-gput" configure option.
For example, to allow access to the members of group "goodguys", use an ACL of "localgroup:goodguys" syntax. To deny access to the members of group "badguys", use "deny:localgroup:badguys".
krb5_aname_to_localname() follows local configuration rules to determine how to convert Kerberos principal to local users. If the realm of the principal is not in a local realm and is not otherwise covered by one of those rules, the principal will be unchanged, which will almost certainly mean that it will not be a member of any local group and access will be denied.
This method is supported only if remctld was built with Kerberos support and the getgrnam_r(3) library function was supported by the C library when it was built.
This method is supported only if remctld was compiled with PCRE support by using the "--with-pcre" configure option.
This method is supported only if a library for POSIX-compatible regular expressions was found when remctld was built.
To see the list of ACL types supported by a particular build of remctld, run "remctld -h".
The keyword ANYUSER may be used instead of the ACLs to allow access to all users. The user still needs to authenticate to remctld; this only affects authorization. This can be used for backend programs that want to check ACLs themselves and will retrieve the authenticated principal from the REMOTE_USER environment variable. Note that ANYUSER accepts any authenticated user, including cross-realm users from foreign Kerberos realms.
Note that using socket activation is recommended when running under systemd in stand-alone mode, and status notification is not necessary or useful when using socket activation.
When running in stand-alone mode, these environment variables will be cleared by remctld before running any commands.
The following environment variables will be set for any commands run via remctld (annotated with the version at which they were added):
This is determined via a simple reverse DNS lookup and should be considered under the control of the client. remctl commands should treat it with skepticism and not use it for anything other than logging purposes.
If the -k flag is used, remctld will also set KRB5_KTNAME to the provided keytab path. This is primarily for communication with the GSS-API library, but this setting will also be inherited by any commands run by remctld.
tcpserver hostname 4373 remctld
The equivalent line for /etc/inetd.conf is:
4373 stream tcp nowait root /usr/sbin/tcpd /usr/sbin/remctld
or:
remctl stream tcp nowait root /usr/sbin/tcpd /usr/sbin/remctld
if the "remctl" service is listed in your /etc/services file.
To start remctld in stand-alone mode instead, run:
remctld -m
To start remctld in stand-alone mode in the foreground, use:
remctld -F -m
This is a typical invocation with systemd using socket activation. For upstart (with "expect stop"), use:
remctld -F -m -Z
Example configuration file:
# Comments can be used like this. accounts create /usr/local/bin/doaccount /etc/acl/group1 \ /etc/acl/group2 accounts delete /usr/local/bin/doaccount /etc/acl/group3 accounts view /usr/local/bin/doaccount ANYUSER accounts passwd /usr/local/bin/dopasswd logmask=3 /etc/acl/group1 printing ALL /usr/local/bin/printthing /etc/acl/group2
The commands "accounts create", "accounts delete", and so forth will all be passed to /usr/local/bin/doaccount with the first argument being the specific subcommand, with the exception of "accounts passwd". That command will be passed to /usr/local/bin/dopasswd instead, but it will still get "passwd" as its first argument. The third argument to "accounts passwd" (presumably the password) will not be logged to syslog. All commands starting with "printing" will be passed to /usr/local/bin/printthing.
Example ACL file:
# This is a comment. deny:baduser@EXAMPLE.ORG file:/etc/remctl/acl/admins principal:service/admin@EXAMPLE.ORG service/other@EXAMPLE.ORG
This ACL file will reject "baduser@EXAMPLE.ORG" even if that user would have been allowed by one of the other ACL rules. It will then grant access according to the ACL entries in /etc/remctl/acl/admins and the specific principals "service/admin@EXAMPLE.ORG" and "service/other@EXAMPLE.ORG". The last line takes advantage of the default ACL method of "principal" when processing an ACL file.
Support for the systemd readiness protocol and socket activation, including honoring the environment variables LISTEN_FDS, LISTEN_PID, and NOTIFY_SOCKET, was added in version 3.7.
Special handling of the "help" and "summary" commands was added in version 3.2.
Support for the "ALL" keyword in the command field of the configuration file was added in version 2.15. (It has always been supported in the subcommand field.)
Support for the "EMPTY" keyword in the subcommand field of the configuration file was added in version 2.15.
Support for ACL schemes and the method:data syntax was added in remctl 2.13. Prior versions of remctld expected only files in the main remctld configuration file, and only principals or lines starting with "include" in those files, without any method: prefixes.
The default listening port with the -m option was changed to the IANA-registered port of 4373 in version 2.11.
Support for IPv6 addresses in the REMOTE_ADDR environment variable was added in version 2.4.
remctld used to set the environment variable SCPRINCIPAL when running commands, for (partial) backward compatibility with sysctld, but stopped doing so in version 2.1.
"include" directives in ACL files were added in version 1.11. "include" directives in configuration files were added in version 1.8.
remctld does not itself impose any limits on the number of child processes or other system resources. You may want to set resource limits in your inetd server or with ulimit when running it as a standalone daemon or under tcpserver.
Command arguments may not contain NUL characters and must be shorter than the operating system limit on the length of a command line since they're passed to the command as command-line arguments. The exception is an argument passed via standard input using the "stdin=" option in the configuration file. At most one argument may be passed that way.
Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without any warranty.
SPDX-License-Identifier: FSFAP
The current version of this program is available from its web page at <https://www.eyrie.org/~eagle/software/remctl/>.