服务器必须能够取出一个客户机的资格。 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 可以是到一个结构的指针或索引,该结构代表环境初始器;服务器在环境创建时间进行计算,而不是为每个请求都计算该值 (从而节省请求处理时间)。