remctl allows me to remotely invoke a program (with arguments) and retrieve output (stdout and stderr) of said program, together with its exit status. Program invocation is authenticated and encrypted by GSS-API Kerberos 5.


Using the remctl client program, I might invoke the following command on a client machine, provided I have a valid Kerberos ticket:

remctl hippo who boot

and remctld (started on the specified server via inetd or as a daemon) will execute the following command:

/usr/local/bin/mywho boot

if the server’s remctl.conf configuration file contains

server reboot /bin/reboot princ:f2@MENS.DE
who ALL /usr/local/bin/mywho ANYUSER

There are two magic tokens in the previous configuration line:

  • ALL stands for all subcommands. Remctld supports the notion of subclassing a command and I can apply different ACLs to specific subcommands. In this particular case I leave that to the program.
  • ANYUSER in the ACL specifies that any principal may invoke this particular program/subcommand pair.

I launch remctl via xinetd thusly:

service remctl
    socket_type = stream
    disable     = no
    protocol    = tcp
    wait        = no
    user        = root
    server      = /usr/sbin/remctld
    port        = 4373

The trivial mywho script supports three “subcommands” (in remctld-speak):


case "$1" in
                /usr/bin/who -u;;
                /usr/bin/who -b;;
                env | grep REMOTE;;
        *)                echo "Unknown subcommand $*" >&2;
                exit 14;;
exit 0

The program is invoked on the server (under remctld’s control) as the user remctld is running as (typically root). Reminiscent of HTTP CGI scripts, it gets these environment variables passed to it:

  • REMOTE_USER: the Kerberos identity of the caller.
  • REMOTE_ADDR: the IP address of the client host.
  • REMOTE_HOST: the name of the client host.

I can configure remctld to allow program invocation for particular principals only, or I can (as in the example above) allow ANY user and use the $REMOTE_USER to decide whether that principal may use the accounts program.

remctl is like a lightweight rsh or ssh and can be used for a number of purposes, such as

  • Monitoring (think: fetch Nagios results)
  • Service provisioning; for example, I could securely invoke an on-demand Puppet run on a machine.
  • Centralized account creation (c.f. kadmin-remctl, a remctl back-end which implements Kerberos account administration with the same functionality as kadmin)
  • Remote system-administration (e.g. reboot)
  • Or even just checking for new mail. :)

remctl has bindings for C, Perl, PHP, Java and Python. Here’s a tiny example in C:

#include <stdio.h>
#include <stdlib.h>
#include <remctl.h>

int main(int argc, char **argv)
	struct remctl_result *remc;
	static const char *cmd[] = {
	int rc;

	remc = remctl("", 0, NULL, cmd);

	if (remc == NULL) {
		fprintf(stderr, "%s: Can't alloc remctl()\n", *argv);
	if (remc->error != NULL) {
		fprintf(stderr, "%s: remctl says: %s\n", *argv, remc->error);
	/* Success? */

	rc = remc->status;

	if (remc->stdout_len > 0) {
		fwrite(remc->stdout_buf, remc->stdout_len, 1, stdout);
	if (remc->stderr_len > 0) {
		fwrite(remc->stderr_buf, remc->stderr_len, 1, stderr);
	return (rc);

When I run this, the output for my principal is: