/* * XDR loopback unix auth parameters. * NOTE: this is an XDR_ENCODE only routine. */ bool_t xdr_authloopback(XDR *xdrs) { uid_t uid; gid_t gid; int len; caddr_t groups; char *name = uts_nodename(); struct cred *cr; time_t now; if (xdrs->x_op != XDR_ENCODE) return (FALSE); cr = CRED(); uid = crgetuid(cr); gid = crgetgid(cr); len = crgetngroups(cr); groups = (caddr_t)crgetgroups(cr); now = gethrestime_sec(); if (xdr_uint32(xdrs, (uint32_t *)&now) && xdr_string(xdrs, &name, MAX_MACHINE_NAME) && xdr_uid_t(xdrs, &uid) && xdr_gid_t(xdrs, &gid) && xdr_array(xdrs, &groups, (uint_t *)&len, NGRPS_LOOPBACK, sizeof (int), (xdrproc_t)xdr_int)) return (TRUE); return (FALSE); }
/* * void *exacct_create_header(size_t *) * * Overview * exacct_create_header() constructs an exacct file header identifying the * accounting file as the output of the kernel. exacct_create_header() and * the static write_header() and verify_header() routines in libexacct must * remain synchronized. * * Return values * A pointer to a packed exacct buffer containing the appropriate header is * returned; the size of the buffer is placed in the location indicated by * sizep. * * Caller's context * Suitable for KM_SLEEP allocations. */ void * exacct_create_header(size_t *sizep) { ea_object_t *hdr_grp; uint32_t bskip; void *buf; size_t bufsize; hdr_grp = ea_alloc_group(EXT_GROUP | EXC_DEFAULT | EXD_GROUP_HEADER); (void) ea_attach_item(hdr_grp, (void *)&exacct_version, 0, EXT_UINT32 | EXC_DEFAULT | EXD_VERSION); (void) ea_attach_item(hdr_grp, (void *)exacct_header, 0, EXT_STRING | EXC_DEFAULT | EXD_FILETYPE); (void) ea_attach_item(hdr_grp, (void *)exacct_creator, 0, EXT_STRING | EXC_DEFAULT | EXD_CREATOR); (void) ea_attach_item(hdr_grp, uts_nodename(), 0, EXT_STRING | EXC_DEFAULT | EXD_HOSTNAME); bufsize = ea_pack_object(hdr_grp, NULL, 0); buf = kmem_alloc(bufsize, KM_SLEEP); (void) ea_pack_object(hdr_grp, buf, bufsize); ea_free_object(hdr_grp, EUP_ALLOC); /* * To prevent reading the header when reading the file backwards, * set the large backskip of the header group to 0 (last 4 bytes). */ bskip = 0; exacct_order32(&bskip); bcopy(&bskip, (char *)buf + bufsize - sizeof (bskip), sizeof (bskip)); *sizep = bufsize; return (buf); }
static bool_t authkern_marshal(AUTH *auth, XDR *xdrs, struct cred *cr) { char *sercred; XDR xdrm; struct opaque_auth *cred; bool_t ret = FALSE; const gid_t *gp, *gpend; int gidlen, credsize, namelen, rounded_namelen; int32_t *ptr; char *nodename = uts_nodename(); /* * First we try a fast path to get through * this very common operation. */ gp = crgetgroups(cr); gidlen = crgetngroups(cr); if (gidlen > NGRPS) gidlen = NGRPS; gpend = &gp[gidlen-1]; namelen = (int)strlen(nodename); rounded_namelen = RNDUP(namelen); credsize = 4 + 4 + rounded_namelen + 4 + 4 + 4 + gidlen * 4; ptr = XDR_INLINE(xdrs, 4 + 4 + credsize + 4 + 4); if (ptr) { /* * We can do the fast path. */ IXDR_PUT_INT32(ptr, AUTH_UNIX); /* cred flavor */ IXDR_PUT_INT32(ptr, credsize); /* cred len */ IXDR_PUT_INT32(ptr, gethrestime_sec()); IXDR_PUT_INT32(ptr, namelen); bcopy(nodename, (caddr_t)ptr, namelen); if (rounded_namelen - namelen) bzero(((caddr_t)ptr) + namelen, rounded_namelen - namelen); ptr += rounded_namelen / BYTES_PER_XDR_UNIT; IXDR_PUT_INT32(ptr, crgetuid(cr)); IXDR_PUT_INT32(ptr, crgetgid(cr)); IXDR_PUT_INT32(ptr, gidlen); while (gp <= gpend) { IXDR_PUT_INT32(ptr, *gp++); } IXDR_PUT_INT32(ptr, AUTH_NULL); /* verf flavor */ IXDR_PUT_INT32(ptr, 0); /* verf len */ return (TRUE); } sercred = kmem_alloc(MAX_AUTH_BYTES, KM_SLEEP); /* * serialize u struct stuff into sercred */ xdrmem_create(&xdrm, sercred, MAX_AUTH_BYTES, XDR_ENCODE); if (!xdr_authkern(&xdrm)) { printf("authkern_marshal: xdr_authkern failed\n"); ret = FALSE; goto done; } /* * Make opaque auth credentials that point at serialized u struct */ cred = &(auth->ah_cred); cred->oa_length = XDR_GETPOS(&xdrm); cred->oa_base = sercred; /* * serialize credentials and verifiers (null) */ if ((xdr_opaque_auth(xdrs, &(auth->ah_cred))) && (xdr_opaque_auth(xdrs, &(auth->ah_verf)))) ret = TRUE; else ret = FALSE; done: kmem_free(sercred, MAX_AUTH_BYTES); return (ret); }