クライアント側で AUTH_SYS (旧バージョンでは AUTH_UNIX) タイプの認証を使用するには、RPC クライアントハンドルの作成後に clnt->cl_auth を次のように設定します。
clnt->cl_auth = authsys_create_default();
以降は、この clnt を使用した RPC 呼び出しでは、clnt とともに以下に示す資格 - 認証構造体Failed Cross Reference Formatが渡されます。
/* * 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 タイプの認証になります。
例 4-27 には、手続きを使用し、ネットワーク上のユーザ数を返すサーバプログラムである RUSERPROC_1() を示します。認証の例として AUTH_SYS タイプの資格をチェックし、呼び出し側の uid が 16 の場合は要求に応じないようにしてあります。
nuser(rqstp, transp) struct svc_req *rqstp; SVCXPRT *transp; { struct authsys_parms *sys_cred; uid_t uid; unsigned long 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_long, &nusers)) fprintf(stderr, "can't reply to RPC call¥n"); return; default: svcerr_noproc(transp); return; } }
このプログラムでは次の点に注意してください。
NULLPROC (手続き番号はゼロ) に結合した認証パラメタは、通常はチェックされません。
サービスプロトコルでは、アクセスが拒否された場合のステータスを返さなければなりません。例 4-27のプロトコルでは、その代わりに サービスプリミティブ svcerr_systemerr() を呼び出しています。
最後の点で重要なのは、RPC の認証パッケージとサービスの関係です。RPC は認証を処理しますが、個々のサービスへのアクセス制御は行いません。サービス自体でアクセス制御の方針を決め、それがプロトコル内で戻り値として反映されるようにしなければなりません。