/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Portions of this source code were derived from Berkeley 4.3 BSD * under license from the Regents of the University of California. */ #pragma ident "%Z%%M% %I% %E% SMI" /* * auth_loopb.c, implements UNIX style authentication parameters in the * kernel. Interfaces with svc_auth_loopback on the server. See * auth_loopb.c for the user level implementation of the loopback auth. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* * Unix authenticator operations vector */ static void authloopback_nextverf(AUTH *); static bool_t authloopback_marshal(AUTH *, XDR *, struct cred *); static bool_t authloopback_validate(AUTH *, struct opaque_auth *); static bool_t authloopback_refresh(AUTH *, struct rpc_msg *, cred_t *); static void authloopback_destroy(AUTH *); static struct auth_ops authloopback_ops = { authloopback_nextverf, authloopback_marshal, authloopback_validate, authloopback_refresh, authloopback_destroy, authany_wrap, authany_unwrap }; /* * Create a kernel unix style authenticator. * Returns an auth handle. */ AUTH * authloopback_create(void) { /* * Allocate and set up auth handle */ return (kmem_cache_alloc(authloopback_cache, KM_SLEEP)); } /* * The constructor of the authloopback_cache. */ /* ARGSUSED */ int authloopback_init(void *buf, void *cdrarg, int kmflags) { AUTH *auth = (AUTH *)buf; auth->ah_ops = &authloopback_ops; auth->ah_cred.oa_flavor = AUTH_LOOPBACK; auth->ah_verf = _null_auth; return (0); } /* * authloopback operations */ /* ARGSUSED */ static void authloopback_nextverf(AUTH *auth) { /* no action necessary */ } static bool_t authloopback_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; /* * First we try a fast path to get through * this very common operation. */ gp = crgetgroups(cr); gidlen = crgetngroups(cr); if (gidlen > NGRPS_LOOPBACK) return (FALSE); gpend = &gp[gidlen-1]; namelen = (int)strlen(uts_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_LOOPBACK); /* cred flavor */ IXDR_PUT_INT32(ptr, credsize); /* cred len */ IXDR_PUT_INT32(ptr, gethrestime_sec()); IXDR_PUT_INT32(ptr, namelen); bcopy(uts_nodename(), 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_authloopback(&xdrm)) { printf("authloopback_marshal: xdr_authloopback 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); } /* ARGSUSED */ static bool_t authloopback_validate(AUTH *auth, struct opaque_auth *verf) { return (TRUE); } /* ARGSUSED */ static bool_t authloopback_refresh(AUTH *auth, struct rpc_msg *msg, cred_t *cr) { return (FALSE); } static void authloopback_destroy(register AUTH *auth) { kmem_cache_free(authloopback_cache, auth); }