ONC+ 開発ガイド

AUTH_SYS タイプの認証

クライアント側で AUTH_SYS (旧バージョンでは AUTH_UNIX) タイプの認証を使用するには、RPC クライアントハンドルの作成後に clnt->cl_auth を次のように設定します。

clnt->cl_auth = authsys_create_default();

以降は、この clnt を使用した RPC 呼び出しでは、clnt とともに以下に示す資格 - 認証構造体例 4-26 が渡されます。


例 4-26 AUTH_SYS タイプの資格 - 認証構造体

/*
 * 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 タイプの資格をチェックし、呼び出し側の uid16 の場合は要求に応じないようにしてあります。


例 4-27 認証データをチェックするサーバープログラム

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;
	}
} 

このプログラムでは次の点に注意してください。

最後の点で重要なのは、RPC の認証パッケージとサービスの関係です。RPC は認証を処理しますが、個々のサービスへのアクセス制御は行いません。サービス自体でアクセス制御の方針を決め、それがプロトコル内で戻り値として反映されるようにしなければなりません。