1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 2009, Sun Microsystems, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: 9 * - Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * - Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * - Neither the name of Sun Microsystems, Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 /* 33 * svc_auth_unix.c 34 * Handles UNIX flavor authentication parameters on the service side of rpc. 35 * There are two svc auth implementations here: AUTH_UNIX and AUTH_SHORT. 36 * _svcauth_unix does full blown unix style uid,gid+gids auth, 37 * _svcauth_short uses a shorthand auth to index into a cache of longhand auths. 38 * Note: the shorthand has been gutted for efficiency. 39 * 40 * Copyright (C) 1984, Sun Microsystems, Inc. 41 */ 42 43 #include <sys/param.h> 44 #include <sys/ucred.h> 45 46 #include <rpc/rpc.h> 47 48 #include <rpc/rpc_com.h> 49 50 /* 51 * Unix longhand authenticator 52 */ 53 enum auth_stat 54 _svcauth_unix(struct svc_req *rqst, struct rpc_msg *msg) 55 { 56 enum auth_stat stat; 57 XDR xdrs; 58 int32_t *buf; 59 struct xucred *xcr; 60 uint32_t auth_len, time; 61 62 xcr = rqst->rq_clntcred; 63 auth_len = (u_int)msg->rm_call.cb_cred.oa_length; 64 xdrmem_create(&xdrs, msg->rm_call.cb_cred.oa_base, auth_len, 65 XDR_DECODE); 66 buf = XDR_INLINE(&xdrs, auth_len); 67 if (buf != NULL) { 68 /* 'time', 'str_len', UID, GID and 'supp_ngroups'. */ 69 const uint32_t min_len = 5 * BYTES_PER_XDR_UNIT; 70 uint32_t str_len, supp_ngroups; 71 72 if (auth_len < min_len) 73 goto badcred; 74 time = IXDR_GET_UINT32(buf); 75 str_len = IXDR_GET_UINT32(buf); 76 if (str_len > AUTH_SYS_MAX_HOSTNAME) 77 goto badcred; 78 str_len = RNDUP(str_len); 79 /* 80 * Recheck message length now that we know the value of 81 * 'str_len' (and that it won't cause an overflow in additions 82 * below) to protect access to the credentials part. 83 */ 84 if (auth_len < min_len + str_len) 85 goto badcred; 86 buf += str_len / sizeof (int32_t); 87 xcr->cr_uid = IXDR_GET_UINT32(buf); 88 xcr->cr_gid = IXDR_GET_UINT32(buf); 89 supp_ngroups = IXDR_GET_UINT32(buf); 90 /* 91 * See the herald comment before a similar test at the end of 92 * xdr_authunix_parms() for why we strictly respect RFC 5531 and 93 * why we may have to drop the last supplementary group when 94 * there are AUTH_SYS_MAX_GROUPS of them. 95 */ 96 if (supp_ngroups > AUTH_SYS_MAX_GROUPS) 97 goto badcred; 98 /* 99 * Final message length check, as we now know how much we will 100 * read in total. 101 */ 102 if (auth_len < min_len + str_len + 103 supp_ngroups * BYTES_PER_XDR_UNIT) 104 goto badcred; 105 106 /* 107 * Note that 'xcr' is a 'struct xucred', which still has the 108 * historical layout where the effective GID is in cr_groups[0] 109 * and is accounted in 'cr_ngroups'. 110 */ 111 for (uint32_t i = 0; i < supp_ngroups; ++i) { 112 if (i < XU_NGROUPS - 1) 113 xcr->cr_sgroups[i] = IXDR_GET_INT32(buf); 114 else 115 buf++; 116 } 117 xcr->cr_ngroups = MIN(supp_ngroups + 1, XU_NGROUPS); 118 } else if (!xdr_authunix_parms(&xdrs, &time, xcr)) 119 goto badcred; 120 121 rqst->rq_verf = _null_auth; 122 stat = AUTH_OK; 123 done: 124 XDR_DESTROY(&xdrs); 125 126 return (stat); 127 128 badcred: 129 stat = AUTH_BADCRED; 130 goto done; 131 } 132 133 134 /* 135 * Shorthand unix authenticator 136 * Looks up longhand in a cache. 137 */ 138 /*ARGSUSED*/ 139 enum auth_stat 140 _svcauth_short(struct svc_req *rqst, struct rpc_msg *msg) 141 { 142 return (AUTH_REJECTEDCRED); 143 } 144