xref: /netbsd-src/sbin/mount_portal/activate.c (revision 8e2fe69844c96cc22071335604a9d91f634f8d41)
1*8e2fe698Slukem /*	$NetBSD: activate.c,v 1.15 2009/04/11 07:36:43 lukem Exp $	*/
20114e805Scgd 
3b8b85029Scgd /*
4b8b85029Scgd  * Copyright (c) 1992, 1993
5b8b85029Scgd  *	The Regents of the University of California.  All rights reserved.
6b8b85029Scgd  *
7b8b85029Scgd  * This code is derived from software donated to Berkeley by
8b8b85029Scgd  * Jan-Simon Pendry.
9b8b85029Scgd  *
10b8b85029Scgd  * Redistribution and use in source and binary forms, with or without
11b8b85029Scgd  * modification, are permitted provided that the following conditions
12b8b85029Scgd  * are met:
13b8b85029Scgd  * 1. Redistributions of source code must retain the above copyright
14b8b85029Scgd  *    notice, this list of conditions and the following disclaimer.
15b8b85029Scgd  * 2. Redistributions in binary form must reproduce the above copyright
16b8b85029Scgd  *    notice, this list of conditions and the following disclaimer in the
17b8b85029Scgd  *    documentation and/or other materials provided with the distribution.
18276d62f6Sagc  * 3. Neither the name of the University nor the names of its contributors
19b8b85029Scgd  *    may be used to endorse or promote products derived from this software
20b8b85029Scgd  *    without specific prior written permission.
21b8b85029Scgd  *
22b8b85029Scgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23b8b85029Scgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24b8b85029Scgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25b8b85029Scgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26b8b85029Scgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27b8b85029Scgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28b8b85029Scgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29b8b85029Scgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30b8b85029Scgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31b8b85029Scgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32b8b85029Scgd  * SUCH DAMAGE.
33b8b85029Scgd  *
345922d844Smycroft  *	from: Id: activate.c,v 1.2 1992/05/27 07:09:27 jsp Exp
354b0b1ba8Slukem  *	@(#)activate.c	8.3 (Berkeley) 4/28/95
36b8b85029Scgd  */
37b8b85029Scgd 
384eb9f40aSlukem #include <sys/cdefs.h>
394eb9f40aSlukem #ifndef lint
40*8e2fe698Slukem __RCSID("$NetBSD: activate.c,v 1.15 2009/04/11 07:36:43 lukem Exp $");
414eb9f40aSlukem #endif /* not lint */
424eb9f40aSlukem 
43b8b85029Scgd #include <stdio.h>
44b8b85029Scgd #include <stdlib.h>
45b8b85029Scgd #include <unistd.h>
46b8b85029Scgd #include <string.h>
47b8b85029Scgd #include <errno.h>
48b8b85029Scgd #include <signal.h>
49b8b85029Scgd #include <sys/types.h>
50b8b85029Scgd #include <sys/param.h>
51b8b85029Scgd #include <sys/socket.h>
52b8b85029Scgd #include <sys/un.h>
53b8b85029Scgd #include <sys/syslog.h>
54b8b85029Scgd #include <sys/uio.h>
55b8b85029Scgd 
56b8b85029Scgd #include "portald.h"
57b8b85029Scgd 
58*8e2fe698Slukem static	int	get_request(int, struct portal_cred *, char *, size_t);
59a8d83732Sxtraeme static	void	send_reply(int, int, int);
604eb9f40aSlukem 
61b8b85029Scgd /*
62b8b85029Scgd  * Scan the providers list and call the
63b8b85029Scgd  * appropriate function.
64b8b85029Scgd  */
6501d79aaeSpooka int
activate_argv(struct portal_cred * pcr,char * key,char ** v,int * fdp)6601d79aaeSpooka activate_argv(struct portal_cred *pcr, char *key, char **v, int *fdp)
67b8b85029Scgd {
68b8b85029Scgd 	provider *pr;
69b8b85029Scgd 
70b8b85029Scgd 	for (pr = providers; pr->pr_match; pr++)
71b8b85029Scgd 		if (strcmp(v[0], pr->pr_match) == 0)
7201d79aaeSpooka 			return ((*pr->pr_func)(pcr, key, v, fdp));
73b8b85029Scgd 
74b8b85029Scgd 	return (ENOENT);
75b8b85029Scgd }
76b8b85029Scgd 
774eb9f40aSlukem static int
get_request(int so,struct portal_cred * pcr,char * key,size_t klen)78*8e2fe698Slukem get_request(int so, struct portal_cred *pcr, char *key, size_t klen)
79b8b85029Scgd {
80b8b85029Scgd 	struct iovec iov[2];
81b8b85029Scgd 	struct msghdr msg;
82*8e2fe698Slukem 	ssize_t n;
83b8b85029Scgd 
84b8b85029Scgd 	iov[0].iov_base = (caddr_t) pcr;
85b8b85029Scgd 	iov[0].iov_len = sizeof(*pcr);
86b8b85029Scgd 	iov[1].iov_base = key;
87b8b85029Scgd 	iov[1].iov_len = klen;
88b8b85029Scgd 
89ea7b5d4eSmycroft 	memset(&msg, 0, sizeof(msg));
90b8b85029Scgd 	msg.msg_iov = iov;
91b8b85029Scgd 	msg.msg_iovlen = 2;
92b8b85029Scgd 
93b8b85029Scgd 	n = recvmsg(so, &msg, 0);
94b8b85029Scgd 	if (n < 0)
95b8b85029Scgd 		return (errno);
96b8b85029Scgd 
97*8e2fe698Slukem 	if (n <= (ssize_t)sizeof(*pcr))
98b8b85029Scgd 		return (EINVAL);
99b8b85029Scgd 
100b8b85029Scgd 	n -= sizeof(*pcr);
101b8b85029Scgd 	key[n] = '\0';
102b8b85029Scgd 
103b8b85029Scgd 	return (0);
104b8b85029Scgd }
105b8b85029Scgd 
1064eb9f40aSlukem static void
send_reply(int so,int fd,int error)107a8d83732Sxtraeme send_reply(int so, int fd, int error)
108b8b85029Scgd {
109b8b85029Scgd 	int n;
110b8b85029Scgd 	struct iovec iov;
111b8b85029Scgd 	struct msghdr msg;
1120ffb5bb9Sthorpej 	void *ctl = NULL;
1130ffb5bb9Sthorpej 	struct cmsghdr *cmsg;
1140ffb5bb9Sthorpej 	int *files;
1150ffb5bb9Sthorpej 	socklen_t cmsgsize;
116b8b85029Scgd 
117b8b85029Scgd 	/*
118b8b85029Scgd 	 * Line up error code.  Don't worry about byte ordering
119b8b85029Scgd 	 * because we must be sending to the local machine.
120b8b85029Scgd 	 */
121b8b85029Scgd 	iov.iov_base = (caddr_t) &error;
122b8b85029Scgd 	iov.iov_len = sizeof(error);
123b8b85029Scgd 
124b8b85029Scgd 	/*
125b8b85029Scgd 	 * Build a msghdr
126b8b85029Scgd 	 */
127ea7b5d4eSmycroft 	memset(&msg, 0, sizeof(msg));
128b8b85029Scgd 	msg.msg_iov = &iov;
129b8b85029Scgd 	msg.msg_iovlen = 1;
130b8b85029Scgd 
131b8b85029Scgd 	/*
132b8b85029Scgd 	 * If there is a file descriptor to send then
133b8b85029Scgd 	 * construct a suitable rights control message.
134b8b85029Scgd 	 */
135b8b85029Scgd 	if (fd >= 0) {
136a63801edSatatat 		cmsgsize = CMSG_LEN(sizeof(*files));
1370ffb5bb9Sthorpej 
1380ffb5bb9Sthorpej 		ctl = malloc(cmsgsize);
1390ffb5bb9Sthorpej 		if (ctl == NULL) {
140415d1abdSlukem 			syslog(LOG_WARNING, "malloc control message: %m");
1410ffb5bb9Sthorpej 			return;
1420ffb5bb9Sthorpej 		}
1430ffb5bb9Sthorpej 		memset(ctl, 0, cmsgsize);
1440ffb5bb9Sthorpej 
1450ffb5bb9Sthorpej 		cmsg = (struct cmsghdr *) ctl;
1460ffb5bb9Sthorpej 		cmsg->cmsg_len = CMSG_LEN(sizeof(int));
1470ffb5bb9Sthorpej 		cmsg->cmsg_level = SOL_SOCKET;
1480ffb5bb9Sthorpej 		cmsg->cmsg_type = SCM_RIGHTS;
1490ffb5bb9Sthorpej 
1500ffb5bb9Sthorpej 		files = (int *)CMSG_DATA(cmsg);
1510ffb5bb9Sthorpej 		files[0] = fd;
1520ffb5bb9Sthorpej 
1530ffb5bb9Sthorpej 		msg.msg_control = ctl;
1540ffb5bb9Sthorpej 		msg.msg_controllen = cmsgsize;
155b8b85029Scgd 	}
156b8b85029Scgd 
157b8b85029Scgd 	/*
158b8b85029Scgd 	 * Send to kernel...
159b8b85029Scgd 	 */
160b8b85029Scgd 	if ((n = sendmsg(so, &msg, MSG_EOR)) < 0)
161415d1abdSlukem 		syslog(LOG_WARNING, "send: %m");
162b8b85029Scgd #ifdef DEBUG
163b8b85029Scgd 	fprintf(stderr, "sent %d bytes\n", n);
164b8b85029Scgd #endif
165b8b85029Scgd 	sleep(1);	/*XXX*/
166b8b85029Scgd #ifdef notdef
167b8b85029Scgd 	if (shutdown(so, 2) < 0)
168415d1abdSlukem 		syslog(LOG_WARNING, "shutdown: %m");
169b8b85029Scgd #endif
170b8b85029Scgd 	/*
1710ffb5bb9Sthorpej 	 * Throw away the open file descriptor and control
1720ffb5bb9Sthorpej 	 * message buffer.
173b8b85029Scgd 	 */
1740ffb5bb9Sthorpej 	if (fd >= 0)
175b8b85029Scgd 		(void) close(fd);
1760ffb5bb9Sthorpej 	if (ctl != NULL)
1770ffb5bb9Sthorpej 		free(ctl);
178b8b85029Scgd }
179b8b85029Scgd 
1804eb9f40aSlukem void
activate(qelem * q,int so)181a8d83732Sxtraeme activate(qelem *q, int so)
182b8b85029Scgd {
183b8b85029Scgd 	struct portal_cred pcred;
184b8b85029Scgd 	char key[MAXPATHLEN+1];
185b8b85029Scgd 	int error;
186b8b85029Scgd 	char **v;
187b8b85029Scgd 	int fd = -1;
188b8b85029Scgd 
189b8b85029Scgd 	/*
190b8b85029Scgd 	 * Read the key from the socket
191b8b85029Scgd 	 */
192b8b85029Scgd 	error = get_request(so, &pcred, key, sizeof(key));
193b8b85029Scgd 	if (error) {
194415d1abdSlukem 		syslog(LOG_WARNING, "activate: recvmsg: %m");
195b8b85029Scgd 		goto drop;
196b8b85029Scgd 	}
197b8b85029Scgd 
198b8b85029Scgd #ifdef DEBUG
199b8b85029Scgd 	fprintf(stderr, "lookup key %s\n", key);
200b8b85029Scgd #endif
201b8b85029Scgd 
202b8b85029Scgd 	/*
203b8b85029Scgd 	 * Find a match in the configuration file
204b8b85029Scgd 	 */
205b8b85029Scgd 	v = conf_match(q, key);
206b8b85029Scgd 
207b8b85029Scgd 	/*
208b8b85029Scgd 	 * If a match existed, then find an appropriate portal
209b8b85029Scgd 	 * otherwise simply return ENOENT.
210b8b85029Scgd 	 */
211b8b85029Scgd 	if (v) {
21201d79aaeSpooka 		error = activate_argv(&pcred, key, v, &fd);
213b8b85029Scgd 		if (error)
214b8b85029Scgd 			fd = -1;
215b8b85029Scgd 		else if (fd < 0)
216b8b85029Scgd 			error = -1;
2170ac5bcaaSenami 	} else
218b8b85029Scgd 		error = ENOENT;
219b8b85029Scgd 
220b8b85029Scgd 	if (error >= 0)
221b8b85029Scgd 		send_reply(so, fd, error);
222b8b85029Scgd 
223b8b85029Scgd drop:;
224b8b85029Scgd 	close(so);
225b8b85029Scgd }
226