xref: /original-bsd/sbin/mount_portal/activate.c (revision c3e32dec)
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.1 (Berkeley) 06/05/93
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 	bzero((char *) &msg, 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 	bzero((char *) &msg, 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 n;
149 	int error;
150 	char **v;
151 	int fd = -1;
152 
153 	/*
154 	 * Read the key from the socket
155 	 */
156 	error = get_request(so, &pcred, key, sizeof(key));
157 	if (error) {
158 		syslog(LOG_ERR, "activate: recvmsg: %s", strerror(error));
159 		goto drop;
160 	}
161 
162 #ifdef DEBUG
163 	fprintf(stderr, "lookup key %s\n", key);
164 #endif
165 
166 	/*
167 	 * Find a match in the configuration file
168 	 */
169 	v = conf_match(q, key);
170 
171 	/*
172 	 * If a match existed, then find an appropriate portal
173 	 * otherwise simply return ENOENT.
174 	 */
175 	if (v) {
176 		error = activate_argv(&pcred, key, v, so, &fd);
177 		if (error)
178 			fd = -1;
179 		else if (fd < 0)
180 			error = -1;
181 	} else {
182 		error = ENOENT;
183 	}
184 
185 	if (error >= 0)
186 		send_reply(so, fd, error);
187 
188 drop:;
189 	close(so);
190 }
191