服务器必须能够取出一个客户机的资格。 rpc_gss_getcred() 函数,如 实例 8-5 所示,允许服务器来取回 UNIX 资格或 RPCSEC_GSS 资格 (或两者,就其而言)。这是通过两个变元而做到的,如果函数成功的话,这两个变元就得到设定。一个变元是到一个 rpc_gss_ucred_t 结构的指针,它包含调用方的 UNIX 资格,如果其资格存在的话:
typedef struct {
uid_t uid; /* user ID */
gid_t gid; /* group ID */
short gidlen;
git_t *gidlist; /* list of groups */
} rpc_gss_ucred_t;
另一个变元是到一个 rpc_gss_raw_cred_t 结构的指针,其看似:
typedef struct {
u_int version; /* RPCSEC_GSS program version */
char *mechanism;
char *qop;
rpc_gss_principal_t client_principal; /* client principal name */
char *svc_principal; /* server principal name */
rpc_gss_service_t service; /* privacy, integrity enum */
} rpc_gss_rawcred_t;
(请参见 "生成客户机授权对象名称",了解对 rpc_gss_principal_t 结构以及其创建方式的描述。) 因为 rpc_gss_rawcred_t 包含客户机和服务器授权对象名称两者,rpc_gss_getcred() 可以返回它们两者。
实例 8-5 是一个简单的服务器侧的调度过程的一个示例,其中服务器为调用方获得资格。该过程获得调用方的 UNIX 资格,然后使用在 rpc_gss_rcred_t 变元找到的机制、 QOP 和服务类型,验证用户的身份。
static void server_prog(struct svc_req *rqstp, SVCXPRT *xprt)
{ rpc_gss_ucred_t *ucred;
rpc_gss_rawcred_t *rcred;
if (rqst->rq_proq == NULLPROC) {
svc_sendreply(xprt, xdr_void, NULL);
return;
}
/*
* authenticate all other requests */
*/
switch (rqstp->rq_cred.oa_flavor) {
case RPCSEC_GSS:
/*
* get credential information
*/
rpc_gss_getcred(rqstp, &rcred, &ucred, NULL);
/*
* verify that the user is allowed to access
* using received security parameters by
* peeking into my config file
*/
if (!authenticate_user(ucred->uid, rcred->mechanism,
rcred->qop, rcred->service)) {
svcerr_weakauth(xprt);
return;
}
break; /* allow the user in */
default:
svcerr_weakauth(xprt);
return;
} /* end switch */
switch (rqstp->rq_proq) {
case SERV_PROC1:
. . .
}
/* usual request processing; send response ... */
return;
}
|
如要了解更多的信息,请参见 rpc_gss_getcred(3N) 手册页。
在 Missing Cross Reference Target 中,用于 rpc_gss_getcred() 的最后一个变元 (这里是一个 NULL) 是一个用户定义的 cookie, 返回时其值是环境得到创建时服务器所指定的任何内容。该 cookie 是一个四字节的值,可以以适合于应用程序的任何方法加以利用 - RPC 并不对其加以解释。例如, cookie 可以是到一个结构的指针或索引,该结构代表环境初始器;服务器在环境创建时间进行计算,而不是为每个请求都计算该值 (从而节省请求处理时间)。