ONC+ Developer's Guide

Receiving Credentials at the Server

A server must be able to fetch the credentials of a client. The rpc_gss_getcred() function, shown in Example 5–14, enables the server to retrieve either UNIX credentials or RPCSEC_GSS credentials, or both. The function has two arguments that are set if the function is successful. One is a pointer to an rpc_gss_ucred_t structure, which contains the caller's UNIX credentials, if such exist:

typedef struct {
    uid_t   uid;          /* user ID */
    gid_t   gid;          /* group ID */
    short   gidlen; 
    git_t   *gidlist;     /* list of groups */
} rpc_gss_ucred_t;

The other argument is a pointer to a rpc_gss_raw_cred_t structure, which looks like this:

typedef struct {
	u_int  version;              /*RPCSEC_GS program version *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;

Because rpc_gss_rawcred_t contains both the client and server principal names, rpc_gss_getcred() can return them both. See Generating Client Principal Names for a description of the rpc_gss_principal_t structure and how it is created.

The following example is a simple server-side dispatch procedure, in which the server gets the credentials for the caller. The procedure gets the caller's UNIX credentials and then verifies the user's identity, using the mechanism, QOP, and service type found in the rpc_gss_rcred_t argument.


Example 5–14 Getting Credentials

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

For more information, see the rpc_gss_getcred(3NSL) man page.

Cookies

In Example 5–14, the last argument to rpc_gss_getcred() (here, a NULL) is a user-defined cookie, with a value on return of whatever was specified by the server when the context was created. This cookie, a 4-byte value, can be used in any way appropriate for the application. RPC does not interpret the cookie. For example, the cookie can be a pointer or index to a structure that represents the context initiator. Instead of computing this value for every request, the server computes it at context-creation time, saving on request-processing time.