Extending remctl

Introduction

This is a guide for users and implementors of remctl who notice features or support currently missing and want to see how to add it, or who are curious which parts of remctl can be easily extended and which parts are more difficult. Most of the easy extensibility is on the server, which is written to permit straightforward addition of new features, particularly to the configuration and ACL files.

Extension areas are presented here in roughly the order of complexity of additions.

If you're considering extending remctl, please feel free to contact me at eagle@eyrie.org and let me know what you're planning and what problem you're trying to solve. I'm generally happy to offer advice and incorporate and maintain extensions in the base distribution, even if they're optional features that require external libraries to build.

ACL Methods

remctl currently supports four ACL methods, but there is support in the ACL syntax for tagging an ACL with a new method and it's relatively straightforward to add new ACL methods to the server.

An ACL method name may be any alphanumerics plus hyphen (-). The current methods are defined in server/config.c (but may be broken int a separate file if many more ACL methods are added). The methods struct defined in that file associates method names with the function implementing that method.

To add a new ACL method, first write a function that checks a given user against an ACL of that method. Your function must take four arguments: the remote username as a string, the ACL data as a string (this is the part after the colon in the ACL for the current command), and the file and line number in the ACL for error reporting. The function must return CONFIG_SUCCESS if the user is authorized by that ACL data, CONFIG_NOMATCH if they are not, and CONFIG_ERROR on some sort of failure, such as failure of a remote service or a syntax error in the ACL data.

For example, the standard acl_check_princ function which implements the princ ACL method does a string comparison of the ACL data to the remote user identity and returns CONFIG_SUCCESS if they match and CONFIG_NOMATCH otherwise.

Once you've written that function, add it and its method name to the methods struct definition in server/config.c. That's all there is to it (although if you're submitting it for inclusion into remctl, documentation additions to docs/remctld.pod and either a new test suite or an addition to tests/server/acl-t.c would be nice).

Config Options

remctld configuration options are handled somewhat similarly to ACLs, but implementing them is likely to require more work since most new options will not be as self-contained in only one portion of remctld. But apart from implementing the effects of the option, adding a new option is straightforward.

An option name must begin with a letter and may contain any alphanumerics plus hyphen (-). All options must have a value, and options are always written in the configuration file as <option>=<value>, after the command and before any ACLs. Boolean options should interpret "yes", "on", "true", and "1" as turning them on and "no", "off", "false", and "0" as turning them off.

To add a new option, first write a parser for it in server/config.c. That function should have a name starting with option_ and will take a pointer to the configuration line, the value of the option as a string, and the name and line number of the configuration file for error reporting. It should return CONFIG_SUCCESS on successful parsing and CONFIG_ERROR on any error to parse (such as a syntax error).

What the function does is up to you, but normally configuration options will add an additional member to the confline struct and the parser should analyze the value of the option and add the appropriate parsed information to the confline struct. Then, elsewhere (usually in server/command.c), once the command being run has been determined, that data can be used to do whatever the option is supposed to do. The members of the confline struct are defined in server/internal.h.

As with ACL methods, if you submit the new option for inclusion, documentation for docs/remctld.pod and either a new test case or an addition to an existing test case are appreciated. (If you don't write them, I'll have to in order to incorporate the code.)

Client Library

The main way in which people have wanted to enhance the client library is to add bindings for additional programming languages. remctl now supports Perl, PHP, and Python, as well as a separate implementation in Java, but there are many other languages that could be added (Ruby, for example).

I'm happy to include new language bindings in the main remctl distribution, and will also try to do the work to build packages for Debian and Ubuntu. Please follow the following guidelines for adding new language bindings:

Protocol

The remctl protocol is designed to be extensible by introducing a new protocol version. All commands come tagged with the protocol version required to understand them, and the server will automatically reject, with a version error, protocol commands with too high of a version. The client can also ask the server what version it supports.

Currently, the protocol version is three. An initial draft of the changes for protocol version four is available in docs/protocol-v4, but may change prior to implementation.

The remctl protocol is defined by docs/protocol.xml, which is translated into docs/protocol.txt and docs/protocl.html by xml2rfc. Any changes to the protocol should be documented here.

I would like to keep remctl interoperable, so please talk to me before making changes that would modify the protocol.

License

    Copyright 2009, 2011
        The Board of Trustees of the Leland Stanford Junior University
    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