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