The client can use AUTH_SYS style authentication (called AUTH_UNIX in previous releases) by setting clnt–>cl_auth after creating the RPC client handle:
clnt->cl_auth = authsys_create_default();
This setting causes each RPC call associated with clnt to carry with it the following credentials-authentication structure shown in the following example:
/* * AUTH_SYS flavor credentials. */ struct authsys_parms { u_long aup_time; /* credentials creation time */ char *aup_machname; /* client's host name */ uid_t aup_uid; /* client's effective uid */ gid_t aup_gid; /* client's current group id */ u_int aup_len; /* element length of aup_gids*/ gid_t *aup_gids; /* array of groups user is in */ };
rpc.broadcast defaults to AUTH_SYS authentication.
The following example shows a server, with procedure RUSERPROC_1(), that returns the number of users on the network. As an example of authentication, the server checks AUTH_SYS credentials and does not service requests from callers with a uid of 16.
nuser(rqstp, transp) struct svc_req *rqstp; SVCXPRT *transp; { struct authsys_parms *sys_cred; uid_t uid; unsigned int nusers; /* NULLPROC should never be authenticated */ if (rqstp->rq_proc == NULLPROC) { if (!svc_sendreply( transp, xdr_void, (caddr_t) NULL)) fprintf(stderr, "can't reply to RPC call\n"); return; } /* now get the 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: /* make sure caller is allowed to call this proc */ if (uid == 16) { svcerr_systemerr(transp); return; } /* * Code here to compute the number of users and assign it * to the variable nusers */ if (!svc_sendreply( transp, xdr_u_int, &nusers)) fprintf(stderr, "can't reply to RPC call\n"); return; default: svcerr_noproc(transp); return; } }
Note the following points about the example:
The authentication parameters associated with the NULLPROC (procedure number zero) are usually not checked.
The server calls svcerr_weakauth() if the authentication parameter's flavor is too weak. In this case, there is no way to get the list of authentication flavors the server requires.
The service protocol should return status for access denied. In the examples, the protocol instead calls the service primitive svcerr_systemerr().
The last point underscores the relation between the RPC authentication package and the services: RPC deals only with authentication and not with an individual service's access control. The services must establish access-control policies and reflect these policies as return statuses in their protocols.