The client can use AUTH_SYS (called AUTH_UNIX in previous releases) style authentication by setting clnt->cl_auth after creating the RPC client handle:
clnt->cl_auth = authsys_create_default();
This causes each RPC call associated with clnt to carry with it the following credentials-authentication structure shown in Failed Cross Reference Format.
/* * 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.
Example 4-27 shows a server, with procedure RUSERPROC_1(), that returns the number of users on the network. As an example of authentication, it checks AUTH_SYS credentials and does not service requests from callers whose uid is 16.
nuser(rqstp, transp) struct svc_req *rqstp; SVCXPRT *transp; { struct authsys_parms *sys_cred; uid_t uid; unsigned long 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_long, &nusers)) fprintf(stderr, "can't reply to RPC call\n"); return; default: svcerr_noproc(transp); return; } }
Note the following:
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; there is no way to get the list of authentication flavors the server requires.
The service protocol should return status for access denied; in Example 4-27, the protocol calls the service primitive svcerr_systemerr(), instead.
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 themselves must establish access-control policies and reflect these policies as return statuses in their protocols.