xref: /original-bsd/sbin/mount_portal/activate.c (revision 00695d63)
1 /*
2  * Copyright (c) 1992, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  * All rights reserved.
5  *
6  * This code is derived from software donated to Berkeley by
7  * Jan-Simon Pendry.
8  *
9  * %sccs.include.redist.c%
10  *
11  *	@(#)activate.c	8.3 (Berkeley) 04/28/95
12  *
13  * $Id: activate.c,v 1.2 1992/05/27 07:09:27 jsp Exp jsp $
14  */
15 
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <unistd.h>
19 #include <string.h>
20 #include <errno.h>
21 #include <signal.h>
22 #include <sys/types.h>
23 #include <sys/param.h>
24 #include <sys/socket.h>
25 #include <sys/un.h>
26 #include <sys/syslog.h>
27 #include <sys/uio.h>
28 
29 #include "portald.h"
30 
31 /*
32  * Scan the providers list and call the
33  * appropriate function.
34  */
35 static int activate_argv(pcr, key, v, so, fdp)
36 struct portal_cred *pcr;
37 char *key;
38 char **v;
39 int so;
40 int *fdp;
41 {
42 	provider *pr;
43 
44 	for (pr = providers; pr->pr_match; pr++)
45 		if (strcmp(v[0], pr->pr_match) == 0)
46 			return ((*pr->pr_func)(pcr, key, v, so, fdp));
47 
48 	return (ENOENT);
49 }
50 
51 static int get_request(so, pcr, key, klen)
52 int so;
53 struct portal_cred *pcr;
54 char *key;
55 int klen;
56 {
57 	struct iovec iov[2];
58 	struct msghdr msg;
59 	int n;
60 
61 	iov[0].iov_base = (caddr_t) pcr;
62 	iov[0].iov_len = sizeof(*pcr);
63 	iov[1].iov_base = key;
64 	iov[1].iov_len = klen;
65 
66 	memset(&msg, 0, sizeof(msg));
67 	msg.msg_iov = iov;
68 	msg.msg_iovlen = 2;
69 
70 	n = recvmsg(so, &msg, 0);
71 	if (n < 0)
72 		return (errno);
73 
74 	if (n <= sizeof(*pcr))
75 		return (EINVAL);
76 
77 	n -= sizeof(*pcr);
78 	key[n] = '\0';
79 
80 	return (0);
81 }
82 
83 static void send_reply(so, fd, error)
84 int so;
85 int fd;
86 int error;
87 {
88 	int n;
89 	struct iovec iov;
90 	struct msghdr msg;
91 	struct {
92 		struct cmsghdr cmsg;
93 		int fd;
94 	} ctl;
95 
96 	/*
97 	 * Line up error code.  Don't worry about byte ordering
98 	 * because we must be sending to the local machine.
99 	 */
100 	iov.iov_base = (caddr_t) &error;
101 	iov.iov_len = sizeof(error);
102 
103 	/*
104 	 * Build a msghdr
105 	 */
106 	memset(&msg, 0, sizeof(msg));
107 	msg.msg_iov = &iov;
108 	msg.msg_iovlen = 1;
109 
110 	/*
111 	 * If there is a file descriptor to send then
112 	 * construct a suitable rights control message.
113 	 */
114 	if (fd >= 0) {
115 		ctl.fd = fd;
116 		ctl.cmsg.cmsg_len = sizeof(ctl);
117 		ctl.cmsg.cmsg_level = SOL_SOCKET;
118 		ctl.cmsg.cmsg_type = SCM_RIGHTS;
119 		msg.msg_control = (caddr_t) &ctl;
120 		msg.msg_controllen = ctl.cmsg.cmsg_len;
121 	}
122 
123 	/*
124 	 * Send to kernel...
125 	 */
126 	if ((n = sendmsg(so, &msg, MSG_EOR)) < 0)
127 		syslog(LOG_ERR, "send: %s", strerror(errno));
128 #ifdef DEBUG
129 	fprintf(stderr, "sent %d bytes\n", n);
130 #endif
131 	sleep(1);	/*XXX*/
132 #ifdef notdef
133 	if (shutdown(so, 2) < 0)
134 		syslog(LOG_ERR, "shutdown: %s", strerror(errno));
135 #endif
136 	/*
137 	 * Throw away the open file descriptor
138 	 */
139 	(void) close(fd);
140 }
141 
142 void activate(q, so)
143 qelem *q;
144 int so;
145 {
146 	struct portal_cred pcred;
147 	char key[MAXPATHLEN+1];
148 	int error;
149 	char **v;
150 	int fd = -1;
151 
152 	/*
153 	 * Read the key from the socket
154 	 */
155 	error = get_request(so, &pcred, key, sizeof(key));
156 	if (error) {
157 		syslog(LOG_ERR, "activate: recvmsg: %s", strerror(error));
158 		goto drop;
159 	}
160 
161 #ifdef DEBUG
162 	fprintf(stderr, "lookup key %s\n", key);
163 #endif
164 
165 	/*
166 	 * Find a match in the configuration file
167 	 */
168 	v = conf_match(q, key);
169 
170 	/*
171 	 * If a match existed, then find an appropriate portal
172 	 * otherwise simply return ENOENT.
173 	 */
174 	if (v) {
175 		error = activate_argv(&pcred, key, v, so, &fd);
176 		if (error)
177 			fd = -1;
178 		else if (fd < 0)
179 			error = -1;
180 	} else {
181 		error = ENOENT;
182 	}
183 
184 	if (error >= 0)
185 		send_reply(so, fd, error);
186 
187 drop:;
188 	close(so);
189 }
190