1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * nfsauth.c 24 * 25 * Copyright (c) 1988-1996,1998,1999 by Sun Microsystems, Inc. 26 * All rights reserved. 27 */ 28 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <sys/types.h> 34 #include <string.h> 35 #include <sys/param.h> 36 #include <sys/stat.h> 37 #include <sys/file.h> 38 #include <sys/time.h> 39 #include <sys/errno.h> 40 #include <rpcsvc/mount.h> 41 #include <sys/pathconf.h> 42 #include <sys/systeminfo.h> 43 #include <sys/utsname.h> 44 #include <arpa/inet.h> 45 #include <signal.h> 46 #include <syslog.h> 47 #include <locale.h> 48 #include <unistd.h> 49 #include <thread.h> 50 #include <netdir.h> 51 #include <rpcsvc/nfsauth_prot.h> 52 #include "../lib/sharetab.h" 53 #include "mountd.h" 54 55 static void nfsauth_access_svc(auth_req *, auth_res *, struct svc_req *); 56 57 void 58 nfsauth_prog(struct svc_req *rqstp, register SVCXPRT *transp) 59 { 60 union { 61 auth_req nfsauth_access_arg; 62 } argument; 63 auth_res result; 64 65 bool_t (*xdr_argument)(); 66 bool_t (*xdr_result)(); 67 void (*local)(); 68 69 switch (rqstp->rq_proc) { 70 case NULLPROC: 71 (void) svc_sendreply(transp, xdr_void, (char *)NULL); 72 return; 73 74 case NFSAUTH_ACCESS: 75 xdr_argument = xdr_auth_req; 76 xdr_result = xdr_auth_res; 77 local = nfsauth_access_svc; 78 break; 79 80 default: 81 svcerr_noproc(transp); 82 return; 83 } 84 85 (void) memset((char *)&argument, 0, sizeof (argument)); 86 if (!svc_getargs(transp, xdr_argument, (caddr_t)&argument)) { 87 svcerr_decode(transp); 88 return; 89 } 90 91 (*local)(&argument, &result, rqstp); 92 93 if (!svc_sendreply(transp, xdr_result, (caddr_t)&result)) { 94 svcerr_systemerr(transp); 95 } 96 97 if (!svc_freeargs(transp, xdr_argument, (caddr_t)&argument)) { 98 syslog(LOG_ERR, "unable to free arguments"); 99 } 100 } 101 102 /*ARGSUSED*/ 103 104 static void 105 nfsauth_access_svc(auth_req *argp, auth_res *result, struct svc_req *rqstp) 106 { 107 struct netconfig *nconf; 108 struct nd_hostservlist *clnames = NULL; 109 struct netbuf nbuf; 110 struct share *sh; 111 char tmp[MAXIPADDRLEN]; 112 char *host = NULL; 113 114 result->auth_perm = NFSAUTH_DENIED; 115 116 /* 117 * Convert the client's address to a hostname 118 */ 119 nconf = getnetconfigent(argp->req_netid); 120 if (nconf == NULL) { 121 syslog(LOG_ERR, "No netconfig entry for %s", argp->req_netid); 122 return; 123 } 124 125 nbuf.len = argp->req_client.n_len; 126 nbuf.buf = argp->req_client.n_bytes; 127 128 if (netdir_getbyaddr(nconf, &clnames, &nbuf)) { 129 host = &tmp[0]; 130 if (strcmp(nconf->nc_protofmly, NC_INET) == 0) { 131 struct sockaddr_in *sa; 132 133 /* LINTED pointer alignment */ 134 sa = (struct sockaddr_in *)nbuf.buf; 135 (void) inet_ntoa_r(sa->sin_addr, tmp); 136 } else if (strcmp(nconf->nc_protofmly, NC_INET6) == 0) { 137 struct sockaddr_in6 *sa; 138 /* LINTED pointer */ 139 sa = (struct sockaddr_in6 *)nbuf.buf; 140 (void) inet_ntop(AF_INET6, sa->sin6_addr.s6_addr, 141 tmp, INET6_ADDRSTRLEN); 142 } 143 clnames = anon_client(host); 144 } 145 146 /* 147 * Now find the export 148 */ 149 sh = findentry(argp->req_path); 150 if (sh == NULL) { 151 syslog(LOG_ERR, "%s not exported", argp->req_path); 152 goto done; 153 } 154 155 result->auth_perm = check_client(sh, &nbuf, clnames, argp->req_flavor); 156 157 sharefree(sh); 158 159 if (result->auth_perm == NFSAUTH_DENIED) { 160 syslog(LOG_ERR, "%s denied access to %s", 161 clnames->h_hostservs[0].h_host, argp->req_path); 162 } 163 164 done: 165 freenetconfigent(nconf); 166 if (clnames) 167 netdir_free(clnames, ND_HOSTSERVLIST); 168 } 169