RCMD(3)

名称
rcmd, rresvport, iruserok, ruserok, rcmd_af, rresvport_af, iruserok_sa - リモートコマンドにストリームを返すルーチン

ライブラリ
libc

書式
#include <unistd.h> int rcmd(char **ahost, int inport, const char *locuser, const char *remuser, const char *cmd, int *fd2p) int rresvport(int *port) int iruserok(u_long raddr, int superuser, const char *ruser, const char *luser) int ruserok(const char *rhost, int superuser, const char *ruser, const char *luser) int rcmd_af(char **ahost, int inport, const char *locuser, const char *remuser, const char *cmd, int *fd2p, int) af" int rresvport_af(int *port, int af) int iruserok_sa(const void *addr, int addrlen, int superuser, const char *ruser, const char *luser)

解説
rcmd() 関数はスーパユーザが使用するもので、予約されたポート番号に基づいた 認証スキームを使用してコマンドをリモートマシンで実行します。 rresvport() 関数は、権限があるポート空間のアドレスとともにソケットの記述子を返します。 ruserok() 関数はサーバが使用するもので、 rcmd() を使用してサービスを要求するクライアントを認証します。 3 つのすべての関数は同じファイルに存在し、 rshd(8) サーバによって使用されます。

rcmd() 関数は gethostbyname(3) を使用してホスト *ahost を調べ、ホストが存在しない場合は -1 を返します。 ホストが存在する場合は、ホストの標準名に *ahost を設定し、よく知られているインターネットポート inport に存在するサーバとの接続を確立します。

接続が確立されると、タイプ SOCK_STREAM のインターネットドメインのソケットが呼び出し側に返され、また stdin と stdout としてリモートコマンドに渡されます。 fd2p が 0 以外である場合は、制御プロセスへ追加のチャンネルが設定され、 その記述子が *fd2p に収められます。 制御プロセスは、このチャンネルでコマンド (ユニット 2) からの診断出力を返し、 また UNIX シグナル番号としてこのチャンネルのバイトを受け取って、 コマンドのプロセスグループに転送します。 fd2p が 0 である場合は、 stderr (リモートコマンドのユニット 2) が stdout と同じように作成されます。 任意のシグナルをリモートプロセスに送信する準備はされませんが、 バンド外のデータを使用することでリモートプロセスの注目を得ることはできます。

プロトコルの詳細については、 rshd(8) を参照してください。

rresvport() 関数は、特権インターネットポートを持つアドレスに結び付いたソケットを 入手するのに使います。 このソケットは、 rcmd() やその他いくつかの関数での使用に適しています。 特権インターネットポートは、 0 から 1023 の範囲にあるものです。 この種のアドレスをソケットに結合できるのはスーパユーザのみです。

iruserok() 関数と ruserok() 関数は、 gethostbyname(3) ルーチンが返すリモートホストの IP アドレスか名前、2 つのユーザ名、 そしてローカルユーザの名前がスーパユーザの名前であるかどうかを示すフラグを 引数にとります。 ユーザがスーパユーザ でない 場合は、 /etc/hosts.equiv ファイルをチェックします。 この検索が実行されなかった場合、またはこの検索が成功しなかった場合は、 ローカルユーザのホームディレクトリの .rhosts をチェックし、サービスへの要求が許可されているかどうかを確認します。

このファイルが存在しない場合や通常のファイルでない場合、またはユーザや スーパユーザ以外がこのファイルの所有者である場合、あるいは所有者以外がこの ファイルに書き込める場合、チェックは自動的にエラーとなります。 マシン名が “hosts.equiv” ファイルにリストされている場合、またはホストとリモートユーザ名が “.rhosts” ファイルに存在する場合は 0 が返されます。 その他の場合、 iruserok() と ruserok() は -1 を返します。 gethostname(3) で入手したローカルドメインがリモートドメインと同じである場合は、 マシン名のみを指定する必要があります。

iruserok() 関数は、セキュリティ上の理由で強く推奨されます。 ruserok() 関数は DNS 全体を信用する必要があり、侵害される可能性がありますが、 iruserok() はせいぜいローカル DNS を信頼する必要しかありません。

“_af” や “_sa” といった接尾辞のついた関数、たとえば rcmd_af(), rresvport_af() や iruserok_sa() などは、IPv6 と IPv4 ポートを扱えることを除いて、 対応する接尾辞のない関数と同じ動作をします。

“_af” 接尾辞は、アドレスファミリ (下記参照) を指定するために使われる af 引数が加わっていることを意味しています。 af 引数の拡張は、バイナリアドレス引数を持たない関数に対して実装されています。 バイナリアドレスの代わりに af 引数はどのアドレスファミリが必要かを指定します。

“_sa” 接尾辞は、関数が汎用ソケットアドレスと長さを 引数に持っていることを意味しています。 ソケットアドレスはプロトコルに依存しないデータ構造なので、 必要に応じて IPv4 と IPv6 のソケットアドレスを渡すことができます。 sa 引数の拡張は、プロトコルに依存したバイナリアドレス引数を渡す関数に対して 実装されています。 引数は、汎用的な方法でいくつものアドレスファミリをサポートするように、 更に汎用的なアドレス構造に置き換えられる必要があります。

“_af” 接尾辞も “_sa” 接尾辞もついていない関数は、IPv6 と IPv4 の両方とも扱える ruserok() 関数を除いて、IPv4 のみで動作します。 アドレスファミリを切替えるには、 af 引数に AF_INET もしくは AF_INET6 を設定しなければなりません。 rcmd_af() に対しては、 PF_UNSPEC も許されます。

診断
成功した場合、 rcmd() 関数は有効なソケット記述子を返します。 エラーが発生した場合は -1 を返し、診断メッセージを標準エラーに出力します。

成功した場合、 rresvport() 関数は有効で結合したソケット記述子を返します。 エラーが発生した場合は -1 を返し、エラーの原因に従ってグローバル変数 errno が設定されます。 「すべてのネットワークポートが使用されている」ことを示す場合は、 エラーコード EAGAIN がオーバロードされます。

関連項目
rlogin(1), rsh(1), intro(2), rexec(3), rexecd(8), rlogind(8), rshd(8)

W. Stevens, M. Thomas, Advanced Socket API for IPv6, RFC2292. W. Stevens, M. Thomas, E. Nordmark, Advanced Socket API for IPv6, draft-ietf-ipngwg-rfc2292bis-01.txt.

歴史
これらのほとんどの関数は、 4.2BSD で登場しました。 rresvport_af() は RFC2292 で登場し、 Hydrangea IPv6 プロトコルスタックキットのために WIDE プロジェクトによって実装されました。 rcmd_af() は draft-ietf-ipngwg-rfc2292bis-01.txt で登場し、 WIDE/KAME IPv6 プロトコルスタックキットで実装されました。 iruserok_sa() は IETF の ipngwg メーリングリストの議論で登場し、 FreeBSD 4.0 で実装されました。