xref: /illumos-gate/usr/src/cmd/fs.d/nfs/mountd/nfsauth.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
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