.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings. \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
.\" nothing in troff, for use with C<>.
.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
. ds -- \(*W-
. ds PI pi
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
. ds L" ""
. ds R" ""
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds -- \|\(em\|
. ds PI \(*p
. ds L" ``
. ds R" ''
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is turned on, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.ie \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. nr % 0
. rr F
.\}
.el \{\
. de IX
..
.\}
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
. \" fudge factors for nroff and troff
.if n \{\
. ds #H 0
. ds #V .8m
. ds #F .3m
. ds #[ \f1
. ds #] \fP
.\}
.if t \{\
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
. ds #V .6m
. ds #F 0
. ds #[ \&
. ds #] \&
.\}
. \" simple accents for nroff and troff
.if n \{\
. ds ' \&
. ds ` \&
. ds ^ \&
. ds , \&
. ds ~ ~
. ds /
.\}
.if t \{\
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
.\}
. \" troff and (daisy-wheel) nroff accents
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
.ds ae a\h'-(\w'a'u*4/10)'e
.ds Ae A\h'-(\w'A'u*4/10)'E
. \" corrections for vroff
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
. \" for low resolution devices (crt and lpr)
.if \n(.H>23 .if \n(.V>19 \
\{\
. ds : e
. ds 8 ss
. ds o a
. ds d- d\h'-1'\(ga
. ds D- D\h'-1'\(hy
. ds th \o'bp'
. ds Th \o'LP'
. ds ae ae
. ds Ae AE
.\}
.rm #[ #] #H #V #F C
.\" ========================================================================
.\"
.IX Title "Remctl 3pm"
.TH Remctl 3pm "2012-09-28" "perl v5.14.2" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
Net::Remctl \- Perl bindings for remctl (Kerberos remote command execution)
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
.Vb 10
\& # Simplified form.
\& use Net::Remctl;
\& my $result = remctl("hostname", undef, undef, "test", "echo", "Hi");
\& if ($result\->error) {
\& die "test echo failed with error ", $result\->error, "\en";
\& } else {
\& warn $result\->stderr;
\& print $result\->stdout;
\& exit $result\->status;
\& }
\&
\& # Full interface.
\& use Net::Remctl ();
\& my $remctl = Net::Remctl\->new;
\& $remctl\->open("hostname")
\& or die "Cannot connect to hostname: ", $remctl\->error, "\en";
\& $remctl\->command("test", "echo", "Hi there")
\& or die "Cannot send command: ", $remctl\->error, "\en";
\& my $output;
\& do {
\& $output = $remctl\->output;
\& if ($output\->type eq \*(Aqoutput\*(Aq) {
\& if ($output\->stream == 1) {
\& print $output\->data;
\& } elsif ($output\->stream == 2) {
\& warn $output\->data;
\& }
\& } elsif ($output\->type eq \*(Aqerror\*(Aq) {
\& warn $output\->error, "\en";
\& } elsif ($output\->type eq \*(Aqstatus\*(Aq) {
\& exit $output\->status;
\& } else {
\& die "Unknown output token from library: ", $output\->type, "\en";
\& }
\& } while ($output\->type eq \*(Aqoutput\*(Aq);
\& $remctl\->noop or die "Cannot send NOOP: ", $remctl\->error, "\en";
.Ve
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
Net::Remctl provides Perl bindings to the libremctl client library. remctl
is a protocol for remote command execution using GSS-API authentication.
The specific allowable commands must be listed in a configuration file on
the remote system and the remote system can map the remctl command names to
any local command without exposing that mapping to the client. This module
implements a remctl client.
.SS "Simplified Interface"
.IX Subsection "Simplified Interface"
If you want to run a single command on a remote system and get back the
output and exit status, you can use the exported \fIremctl()\fR function:
.IP "remctl(\s-1HOSTNAME\s0, \s-1PORT\s0, \s-1PRINCIPAL\s0, \s-1COMMAND\s0, [\s-1ARGS\s0, ...])" 4
.IX Item "remctl(HOSTNAME, PORT, PRINCIPAL, COMMAND, [ARGS, ...])"
Runs a command on the remote system and returns a Net::Remctl::Result
object (see below). \s-1HOSTNAME\s0 is the remote host to contact. \s-1PORT\s0 is the
port of the remote \fBremctld\fR server and may be 0 to tell the library to
use the default (first try 4373, the registered remctl port, and fall back
to the legacy 4444 port if that fails). \s-1PRINCIPAL\s0 is the principal of the
server to use for authentication; pass in the empty string to use the
default of host/HOSTNAME, with the realm determined by domain-realm
mapping. The remaining arguments are the remctl command and arguments
passed to the remote server.
.Sp
As far as the module is concerned, undef may be passed as \s-1PORT\s0 and
\&\s-1PRINCIPAL\s0 and is the same as 0 and the empty string respectively.
However, Perl will warn about passing undef explicitly as a function
argument.
.Sp
The return value is a Net::Remctl::Result object which supports the
following methods:
.RS 4
.IP "\fIerror()\fR" 4
.IX Item "error()"
Returns the error message from either the remote host or from the local
client library (if, for instance, contacting the remote host failed).
Returns undef if there was no error. Checking whether \fIerror()\fR returns undef
is the supported way of determining whether the \fIremctl()\fR call succeeded.
.IP "\fIstdout()\fR" 4
.IX Item "stdout()"
Returns the command's standard output or undef if there was none.
.IP "\fIstderr()\fR" 4
.IX Item "stderr()"
Returns the command's standard error or undef if there was none.
.IP "\fIstatus()\fR" 4
.IX Item "status()"
Returns the command's exit status.
.RE
.RS 4
.Sp
Each call to \fIremctl()\fR will open a new connection to the remote host and
close it after retrieving the results of the command. To maintain a
persistent connection, use the full interface described below.
.RE
.SS "Full Interface"
.IX Subsection "Full Interface"
The full remctl library interface requires that the user do more
bookkeeping, but it provides more flexibility and allows one to issue
multiple commands on the same persistent connection (provided that the
remote server supports protocol version two; if not, the library will
transparently fall back to opening a new connection for each command).
.PP
To use the full interface, first create a Net::Remctl object with \fInew()\fR and
then \fIconnect()\fR to a remote server. Then, issue a \fIcommand()\fR and call
\&\fIoutput()\fR to retrieve output tokens (as Net::Remctl::Output objects) until a
status token is received. Destroying the Net::Remctl object will close the
connection.
.PP
The supported object methods are:
.IP "\fInew()\fR" 4
.IX Item "new()"
Create a new Net::Remctl object. This doesn't attempt to connect to a host
and hence will only fail (by throwing an exception) if the library cannot
allocate memory.
.IP "\fIerror()\fR" 4
.IX Item "error()"
Retrieves the error message from the last failing operation and returns it
as a string.
.IP "set_ccache(\s-1CCACHE\s0)" 4
.IX Item "set_ccache(CCACHE)"
Sets the GSS-API credential cache for outgoing connections to \s-1CCACHE\s0,
which is normally the path to a Kerberos ticket cache but may have other
valid forms depending on the underlying Kerberos implementation in use by
GSS-API. This method must be called prior to calling \fIopen()\fR and will
affect all subsequent \fIopen()\fR calls on at least the same object. Returns
true on success and false on failure.
.Sp
For current GSS-API implementations, this will affect not only all
subsequent \fIopen()\fR calls for the same object, but all subsequent remctl
connections of any kind from the same process, and even other GSS-API
connections from the same process unrelated to remctl. This is due to a
limitation in the GSS-API that makes this setting a global setting for the
process or thread.
.Sp
Not all GSS-API implementations support setting the credential cache. If
this is not supported, false will be returned.
.IP "set_source_ip(\s-1SOURCE\s0)" 4
.IX Item "set_source_ip(SOURCE)"
Sets the source \s-1IP\s0 for outgoing connections to \s-1SOURCE\s0, which can be either
an IPv4 or an IPv6 address (if IPv6 is supported). It must be an \s-1IP\s0
address, not a host name. This method must be called prior to calling
\&\fIopen()\fR and will affect all subsequent \fIopen()\fR calls on the same object.
Returns true on success and false on failure.
.IP "set_timeout(\s-1TIMEOUT\s0)" 4
.IX Item "set_timeout(TIMEOUT)"
Sets the timeout for connections and commands to \s-1TIMEOUT\s0, which should be
an integer number of seconds. \s-1TIMEOUT\s0 may be 0 to clear a timeout that
was previously set. All subsequent operations on this Net::Remctl object
will be subject to this timeout, including \fIopen()\fR if called prior to
calling \fIopen()\fR. Returns true on success and false on failure. Failure is
only possible if \s-1TIMEOUT\s0 is malformed.
.Sp
The timeout is a timeout on network activity from the server, not on a
complete operation. So, for example, a timeout of ten seconds just
requires that the server send some data every ten seconds. If the server
sends only tiny amounts of data at a time, the complete operation could
take much longer than ten seconds without triggering the timeout.
.IP "open(HOSTNAME[, PORT[, \s-1PRINCIPAL\s0]])" 4
.IX Item "open(HOSTNAME[, PORT[, PRINCIPAL]])"
Connect to \s-1HOSTNAME\s0 on port \s-1PORT\s0 using \s-1PRINCIPAL\s0 as the remote server's
principal for authentication. If \s-1PORT\s0 is omitted or 0, use the default
(first try 4373, the registered remctl port, and fall back to the legacy
4444 port if that fails). If \s-1PRINCIPAL\s0 is omitted or the empty string,
use the default of host/HOSTNAME, with the realm determined by
domain-realm mapping. Returns true on success, false on failure. On
failure, call \fIerror()\fR to get the failure message.
.Sp
As far as the module is concerned, undef may be passed as \s-1PORT\s0 and
\&\s-1PRINCIPAL\s0 and is the same as 0 and the empty string respectively.
However, Perl will warn about passing undef explicitly as a function
argument.
.IP "command(COMMAND[, \s-1ARGS\s0, ...])" 4
.IX Item "command(COMMAND[, ARGS, ...])"
Send the command and arguments to the remote host. The command and the
arguments may, under the remctl protocol, contain any character, but be
aware that most remctl servers will reject commands or arguments containing
\&\s-1ASCII\s0 0 (\s-1NUL\s0), so currently this cannot be used for upload of arbitrary
unencoded binary data. Returns true on success (meaning success in sending
the command, and implying nothing about the result of the command), false on
failure. On failure, call \fIerror()\fR to get the failure message.
.IP "\fIoutput()\fR" 4
.IX Item "output()"
Returns the next output token from the remote host. The token is returned
as a Net::Remctl::Output object, which supports the following methods:
.RS 4
.IP "\fItype()\fR" 4
.IX Item "type()"
Returns the type of the output token, which will be one of \f(CW\*(C`output\*(C'\fR,
\&\f(CW\*(C`error\*(C'\fR, \f(CW\*(C`status\*(C'\fR, or \f(CW\*(C`done\*(C'\fR. A command will result in either one
\&\f(CW\*(C`error\*(C'\fR token or zero or more \f(CW\*(C`output\*(C'\fR tokens followed by a \f(CW\*(C`status\*(C'\fR
token. After either a \f(CW\*(C`error\*(C'\fR or \f(CW\*(C`status\*(C'\fR token is seen, another command
can be issued. If the caller tries to retrieve another output token when it
has already consumed all of them for that command, the library will return a
\&\f(CW\*(C`done\*(C'\fR token.
.IP "\fIdata()\fR" 4
.IX Item "data()"
Returns the contents of the token. This method only makes sense for
\&\f(CW\*(C`output\*(C'\fR and \f(CW\*(C`error\*(C'\fR tokens; otherwise, it will return undef. Note that
the returned value may contain any character, including \s-1ASCII\s0 0 (\s-1NUL\s0).
.IP "\fIlength()\fR" 4
.IX Item "length()"
Returns the length of the data in the token. As with \fIdata()\fR, this method
only makes sense for the \f(CW\*(C`output\*(C'\fR and \f(CW\*(C`error\*(C'\fR tokens. It will return 0 if
there is no data or if the data is zero-length.
.IP "\fIstream()\fR" 4
.IX Item "stream()"
For an \f(CW\*(C`output\*(C'\fR token, returns the stream with which the data is
associated. Currently, only two stream values will be used: 1, meaning
standard output; and 2, meaning standard error. The value is undefined for
all other output token types.
.IP "\fIstatus()\fR" 4
.IX Item "status()"
For a \f(CW\*(C`status\*(C'\fR token, returns the exit status of the remote command. The
value is undefined for all other token types.
.IP "\fIerror()\fR" 4
.IX Item "error()"
For an \f(CW\*(C`error\*(C'\fR token, returns the remctl error code for the protocol
error. The text message will be returned by \fIdata()\fR. The value is undefined
for all other token types.
.RE
.RS 4
.RE
.IP "\fInoop()\fR" 4
.IX Item "noop()"
Send a \s-1NOOP\s0 message to the server and read the reply. This is primarily
used to keep a connection to a remctl server alive, such as through a
firewall with a session timeout, while waiting to issue further commands.
Returns true on success, false on failure. On failure, call \fIerror()\fR to
get the failure message.
.Sp
The \s-1NOOP\s0 message requires protocol version 3 support in the server, so the
caller should be prepared for this function to fail, indicating that the
connection could not be kept alive and possibly that it was closed by the
server. In this case, the client will need to explicitly reopen the
connection with \fIopen()\fR.
.PP
Note that, due to internal implementation details in the library, the
Net::Remctl::Output object returned by \fIoutput()\fR will be invalidated by the
next call to \fIcommand()\fR or \fIoutput()\fR or by destroying the producing
Net::Remctl object. Therefore, any data in the output token should be
processed and stored if needed before making any further Net::Remctl method
calls on the same object.
.SH "CAVEATS"
.IX Header "CAVEATS"
If the \fIprincipal\fR argument to \fIremctl()\fR or \fIremctl_open()\fR is \s-1NULL\s0, most
GSS-API libraries will canonicalize the \fIhost\fR using \s-1DNS\s0 before deriving
the principal name from it. This means that when connecting to a remctl
server via a \s-1CNAME\s0, \fIremctl()\fR and \fIremctl_open()\fR will normally authenticate
using a principal based on the canonical name of the host instead of the
specified \fIhost\fR parameter. This behavior may cause problems if two
consecutive \s-1DNS\s0 lookups of \fIhost\fR may return two different results, such
as with some DNS-based load-balancing systems.
.PP
The canonicalization behavior is controlled by the GSS-API library; with
the \s-1MIT\s0 Kerberos GSS-API library, canonicalization can be disabled by
setting \f(CW\*(C`rdns\*(C'\fR to false in the [libdefaults] section of \fIkrb5.conf\fR. It
can also be disabled by passing an explicit Kerberos principal name via
the \fIprincipal\fR argument, which will then be used without changes. If
canonicalization is desired, the caller may wish to canonicalize \fIhost\fR
before calling \fIremctl()\fR or \fIremctl_open()\fR to avoid problems with multiple
\&\s-1DNS\s0 calls returning different results.
.PP
The default behavior, when the port is not specified, of trying 4373 and
falling back to 4444 will be removed in a future version of this module in
favor of using the \f(CW\*(C`remctl\*(C'\fR service in \fI/etc/services\fR if set and then
falling back on only 4373. 4444 was the poorly-chosen original remctl
port and should be phased out.
.SH "NOTES"
.IX Header "NOTES"
The remctl port number, 4373, was derived by tracing the diagonals of a
\&\s-1QWERTY\s0 keyboard up from the letters \f(CW\*(C`remc\*(C'\fR to the number row.
.SH "SEE ALSO"
.IX Header "SEE ALSO"
\&\fIremctl\fR\|(1), \fIremctld\fR\|(8)
.PP
The current version of this module is available from its web page at
.
.SH "AUTHOR"
.IX Header "AUTHOR"
Russ Allbery
.SH "COPYRIGHT AND LICENSE"
.IX Header "COPYRIGHT AND LICENSE"
Copyright 2007, 2008, 2011 The Board of Trustees of the Leland Stanford
Junior University. All rights reserved.
.PP
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the \*(L"Software\*(R"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
.PP
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
.PP
\&\s-1THE\s0 \s-1SOFTWARE\s0 \s-1IS\s0 \s-1PROVIDED\s0 \*(L"\s-1AS\s0 \s-1IS\s0\*(R", \s-1WITHOUT\s0 \s-1WARRANTY\s0 \s-1OF\s0 \s-1ANY\s0 \s-1KIND\s0, \s-1EXPRESS\s0 \s-1OR\s0
\&\s-1IMPLIED\s0, \s-1INCLUDING\s0 \s-1BUT\s0 \s-1NOT\s0 \s-1LIMITED\s0 \s-1TO\s0 \s-1THE\s0 \s-1WARRANTIES\s0 \s-1OF\s0 \s-1MERCHANTABILITY\s0,
\&\s-1FITNESS\s0 \s-1FOR\s0 A \s-1PARTICULAR\s0 \s-1PURPOSE\s0 \s-1AND\s0 \s-1NONINFRINGEMENT\s0. \s-1IN\s0 \s-1NO\s0 \s-1EVENT\s0 \s-1SHALL\s0
\&\s-1THE\s0 \s-1AUTHORS\s0 \s-1OR\s0 \s-1COPYRIGHT\s0 \s-1HOLDERS\s0 \s-1BE\s0 \s-1LIABLE\s0 \s-1FOR\s0 \s-1ANY\s0 \s-1CLAIM\s0, \s-1DAMAGES\s0 \s-1OR\s0 \s-1OTHER\s0
\&\s-1LIABILITY\s0, \s-1WHETHER\s0 \s-1IN\s0 \s-1AN\s0 \s-1ACTION\s0 \s-1OF\s0 \s-1CONTRACT\s0, \s-1TORT\s0 \s-1OR\s0 \s-1OTHERWISE\s0, \s-1ARISING\s0
\&\s-1FROM\s0, \s-1OUT\s0 \s-1OF\s0 \s-1OR\s0 \s-1IN\s0 \s-1CONNECTION\s0 \s-1WITH\s0 \s-1THE\s0 \s-1SOFTWARE\s0 \s-1OR\s0 \s-1THE\s0 \s-1USE\s0 \s-1OR\s0 \s-1OTHER\s0
\&\s-1DEALINGS\s0 \s-1IN\s0 \s-1THE\s0 \s-1SOFTWARE\s0.