クライアント側で AUTH_SYS (旧バージョンでは AUTH_UNIX) タイプの認証を使用 するには、RPC クライアントハンドルの作成後に clnt–>cl_auth を次のように設定します。
clnt->cl_auth = authsys_create_default(); |
以降は、この clnt を使用した RPC 呼び出しでは、次に示す資格 - 認証構造体が渡されます。
/*
* AUTH_SYS タイプの資格
*/
struct authsys_parms {
u_long aup_time; /* 資格作成時刻 */
char *aup_machname; /* クライアント側のホスト名 */
uid_t aup_uid; /* クライアント側の実効 uid */
gid_t aup_gid; /* クライアント側の現在のグループ ID */
u_int aup_len; /* aup_gids の配列の長さ */
gid_t *aup_gids; /* ユーザーが所属するグループの配列 */
};
|
rpc.broadcast では、デフォルトで AUTH_SYS タイプの認証になります。
次に、手続きを使用し、ネットワーク上のユーザー数を返すサーバープログラムである RUSERPROC_1 () を示します。認証の例として AUTH_SYS タイプの資格をチェックし、呼び出し側の uid が 16 の場合は要求に応じないようにしてあります。
nuser(rqstp, transp)
struct svc_req *rqstp;
SVCXPRT *transp;
{
struct authsys_parms *sys_cred;
uid_t uid;
unsigned int nusers;
/* NULLPROC の場合は認証データなし */
if (rqstp->rq_proc == NULLPROC) {
if (!svc_sendreply( transp, xdr_void, (caddr_t) NULL))
fprintf(stderr, "can't reply to RPC call\n");
return;
}
/* ここで uid を取得 */
switch(rqstp->rq_cred.oa_flavor) {
case AUTH_SYS:
sys_cred = (struct authsys_parms *) rqstp->rq_clntcred;
uid = sys_cred->aup_uid;
break;
default:
svcerr_weakauth(transp);
return;
}
switch(rqstp->rq_proc) {
case RUSERSPROC_1:
/* 呼び出し側が、この手続きの呼び出し資格を持っているかどうか確認 */
if (uid == 16) {
svcerr_systemerr(transp);
return;
}
/*
* ユーザー数を求めて変数 nusers に設定するコード
*/
if (!svc_sendreply( transp, xdr_u_int, &nusers))
fprintf(stderr, "can't reply to RPC call\n");
return;
default:
svcerr_noproc(transp);
return;
}
}
|
次の点に注意してください。
NULLPROC (手続き番号はゼロ) に結合した認証パラメータは、通常はチェックされません。
認証パラメータのタイプが弱すぎる場合、サーバーは svcerr_weakauth() を呼び出します。サーバーが要求する認証タイプのリストを取り出す方法はありません。
サービスプロトコルでは、アクセスが拒否された場合のステータスを返さなければなりません。例のプロトコルでは、その代わりにサービスプリミティブ svcerr_systemerr() を呼び出しています。
最後の点で重要なのは、RPC の認証パッケージとサービスの関係です。RPC は認証を処理しますが、個々のサービスへのアクセス制御は行いません。サービス自体でアクセス制御の方針を決め、それがプロトコル内で戻り値として反映されるようにしなければなりません。