Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : helper functions for stream based servers
5 :
6 : Copyright (C) Andrew Tridgell 2003-2005
7 : Copyright (C) Stefan (metze) Metzmacher 2004
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "includes.h"
24 : #include <tevent.h>
25 : #include "process_model.h"
26 : #include "lib/util/server_id.h"
27 : #include "lib/messaging/irpc.h"
28 : #include "cluster/cluster.h"
29 : #include "param/param.h"
30 : #include "../lib/tsocket/tsocket.h"
31 : #include "lib/util/util_net.h"
32 :
33 : /* size of listen() backlog in smbd */
34 : #define SERVER_LISTEN_BACKLOG 10
35 :
36 :
37 : /*
38 : private structure for a single listening stream socket
39 : */
40 : struct stream_socket {
41 : const struct stream_server_ops *ops;
42 : struct loadparm_context *lp_ctx;
43 : struct tevent_context *event_ctx;
44 : const struct model_ops *model_ops;
45 : struct socket_context *sock;
46 : void *private_data;
47 : void *process_context;
48 : };
49 :
50 :
51 : /*
52 : close the socket and shutdown a stream_connection
53 : */
54 131924 : void stream_terminate_connection(struct stream_connection *srv_conn, const char *reason)
55 : {
56 131924 : struct tevent_context *event_ctx = srv_conn->event.ctx;
57 131924 : const struct model_ops *model_ops = srv_conn->model_ops;
58 131924 : struct loadparm_context *lp_ctx = srv_conn->lp_ctx;
59 131924 : void *process_context = srv_conn->process_context;
60 131924 : TALLOC_CTX *frame = NULL;
61 :
62 131924 : if (!reason) reason = "unknown reason";
63 :
64 131924 : if (srv_conn->processing) {
65 2574 : DBG_NOTICE("Terminating connection deferred - '%s'\n", reason);
66 : } else {
67 129350 : DBG_NOTICE("Terminating connection - '%s'\n", reason);
68 : }
69 :
70 131924 : srv_conn->terminate = reason;
71 :
72 131924 : if (srv_conn->processing) {
73 : /*
74 : * if we're currently inside the stream_io_handler(),
75 : * defer the termination to the end of stream_io_hendler()
76 : *
77 : * and we don't want to read or write to the connection...
78 : */
79 2574 : tevent_fd_set_flags(srv_conn->event.fde, 0);
80 2574 : return;
81 : }
82 :
83 129350 : frame = talloc_stackframe();
84 :
85 129350 : reason = talloc_strdup(frame, reason);
86 129350 : if (reason == NULL) {
87 0 : reason = "OOM - unknown reason";
88 : }
89 :
90 129350 : TALLOC_FREE(srv_conn->event.fde);
91 129350 : imessaging_cleanup(srv_conn->msg_ctx);
92 129350 : TALLOC_FREE(srv_conn);
93 129350 : model_ops->terminate_connection(
94 : event_ctx, lp_ctx, reason, process_context);
95 113935 : TALLOC_FREE(frame);
96 : }
97 :
98 : /**
99 : the select loop has indicated that a stream is ready for IO
100 : */
101 2602615 : static void stream_io_handler(struct stream_connection *conn, uint16_t flags)
102 : {
103 2602615 : conn->processing++;
104 2602615 : if (flags & TEVENT_FD_WRITE) {
105 886656 : conn->ops->send_handler(conn, flags);
106 1715959 : } else if (flags & TEVENT_FD_READ) {
107 1715959 : conn->ops->recv_handler(conn, flags);
108 : }
109 2602615 : conn->processing--;
110 :
111 2602615 : if (conn->terminate) {
112 2574 : stream_terminate_connection(conn, conn->terminate);
113 : }
114 2602615 : }
115 :
116 2602615 : void stream_io_handler_fde(struct tevent_context *ev, struct tevent_fd *fde,
117 : uint16_t flags, void *private_data)
118 : {
119 2602615 : struct stream_connection *conn = talloc_get_type(private_data,
120 : struct stream_connection);
121 2602615 : stream_io_handler(conn, flags);
122 2602615 : }
123 :
124 0 : void stream_io_handler_callback(void *private_data, uint16_t flags)
125 : {
126 0 : struct stream_connection *conn = talloc_get_type(private_data,
127 : struct stream_connection);
128 0 : stream_io_handler(conn, flags);
129 0 : }
130 :
131 : /*
132 : this creates a stream_connection from an already existing connection,
133 : used for protocols, where a client connection needs to switched into
134 : a server connection
135 : */
136 0 : NTSTATUS stream_new_connection_merge(struct tevent_context *ev,
137 : struct loadparm_context *lp_ctx,
138 : const struct model_ops *model_ops,
139 : const struct stream_server_ops *stream_ops,
140 : struct imessaging_context *msg_ctx,
141 : void *private_data,
142 : struct stream_connection **_srv_conn,
143 : void *process_context)
144 : {
145 0 : struct stream_connection *srv_conn;
146 :
147 0 : srv_conn = talloc_zero(ev, struct stream_connection);
148 0 : NT_STATUS_HAVE_NO_MEMORY(srv_conn);
149 :
150 0 : srv_conn->private_data = private_data;
151 0 : srv_conn->model_ops = model_ops;
152 0 : srv_conn->socket = NULL;
153 0 : srv_conn->server_id = cluster_id(0, 0);
154 0 : srv_conn->ops = stream_ops;
155 0 : srv_conn->msg_ctx = msg_ctx;
156 0 : srv_conn->event.ctx = ev;
157 0 : srv_conn->lp_ctx = lp_ctx;
158 0 : srv_conn->event.fde = NULL;
159 0 : srv_conn->process_context = process_context;
160 :
161 0 : *_srv_conn = srv_conn;
162 0 : return NT_STATUS_OK;
163 : }
164 :
165 : /*
166 : called when a new socket connection has been established. This is called in the process
167 : context of the new process (if appropriate)
168 : */
169 129382 : static void stream_new_connection(struct tevent_context *ev,
170 : struct loadparm_context *lp_ctx,
171 : struct socket_context *sock,
172 : struct server_id server_id,
173 : void *private_data,
174 : void *process_context)
175 : {
176 129382 : struct stream_socket *stream_socket = talloc_get_type(private_data, struct stream_socket);
177 3243 : struct stream_connection *srv_conn;
178 :
179 129382 : srv_conn = talloc_zero(ev, struct stream_connection);
180 129382 : if (!srv_conn) {
181 0 : DBG_ERR("talloc(mem_ctx, struct stream_connection) failed\n");
182 0 : return;
183 : }
184 :
185 129382 : talloc_steal(srv_conn, sock);
186 :
187 129382 : srv_conn->private_data = stream_socket->private_data;
188 129382 : srv_conn->model_ops = stream_socket->model_ops;
189 129382 : srv_conn->socket = sock;
190 129382 : srv_conn->server_id = server_id;
191 129382 : srv_conn->ops = stream_socket->ops;
192 129382 : srv_conn->event.ctx = ev;
193 129382 : srv_conn->lp_ctx = lp_ctx;
194 129382 : srv_conn->process_context = process_context;
195 :
196 129382 : if (!socket_check_access(sock, "smbd", lpcfg_hosts_allow(NULL, lpcfg_default_service(lp_ctx)), lpcfg_hosts_deny(NULL, lpcfg_default_service(lp_ctx)))) {
197 0 : stream_terminate_connection(srv_conn, "denied by access rules");
198 0 : return;
199 : }
200 :
201 129382 : srv_conn->event.fde = tevent_add_fd(ev, srv_conn, socket_get_fd(sock),
202 : 0, stream_io_handler_fde, srv_conn);
203 129382 : if (!srv_conn->event.fde) {
204 0 : stream_terminate_connection(srv_conn, "tevent_add_fd() failed");
205 0 : return;
206 : }
207 :
208 : /* setup to receive internal messages on this connection */
209 129382 : srv_conn->msg_ctx = imessaging_init(srv_conn,
210 : lp_ctx,
211 : srv_conn->server_id, ev);
212 129382 : if (!srv_conn->msg_ctx) {
213 0 : stream_terminate_connection(srv_conn, "imessaging_init() failed");
214 0 : return;
215 : }
216 :
217 129382 : srv_conn->remote_address = socket_get_remote_addr(srv_conn->socket, srv_conn);
218 129382 : if (!srv_conn->remote_address) {
219 0 : stream_terminate_connection(srv_conn, "socket_get_remote_addr() failed");
220 0 : return;
221 : }
222 :
223 129382 : srv_conn->local_address = socket_get_local_addr(srv_conn->socket, srv_conn);
224 129382 : if (!srv_conn->local_address) {
225 0 : stream_terminate_connection(srv_conn, "socket_get_local_addr() failed");
226 0 : return;
227 : }
228 :
229 : {
230 3243 : TALLOC_CTX *tmp_ctx;
231 3243 : const char *title;
232 3243 : struct server_id_buf idbuf;
233 :
234 129382 : tmp_ctx = talloc_new(srv_conn);
235 :
236 129382 : title = talloc_asprintf(tmp_ctx, "conn[%s] c[%s] s[%s] server_id[%s]",
237 129382 : stream_socket->ops->name,
238 129382 : tsocket_address_string(srv_conn->remote_address, tmp_ctx),
239 129382 : tsocket_address_string(srv_conn->local_address, tmp_ctx),
240 : server_id_str_buf(server_id, &idbuf));
241 129382 : if (title) {
242 129382 : stream_connection_set_title(srv_conn, title);
243 : }
244 129382 : talloc_free(tmp_ctx);
245 : }
246 :
247 : /* we're now ready to start receiving events on this stream */
248 129382 : TEVENT_FD_READABLE(srv_conn->event.fde);
249 :
250 : /* call the server specific accept code */
251 129382 : stream_socket->ops->accept_connection(srv_conn);
252 : }
253 :
254 :
255 : /*
256 : called when someone opens a connection to one of our listening ports
257 : */
258 159575 : static void stream_accept_handler(struct tevent_context *ev, struct tevent_fd *fde,
259 : uint16_t flags, void *private_data)
260 : {
261 159575 : struct stream_socket *stream_socket = talloc_get_type(private_data, struct stream_socket);
262 :
263 : /* ask the process model to create us a process for this new
264 : connection. When done, it calls stream_new_connection()
265 : with the newly created socket */
266 159575 : stream_socket->model_ops->accept_connection(
267 : ev,
268 : stream_socket->lp_ctx,
269 : stream_socket->sock,
270 : stream_new_connection,
271 : stream_socket,
272 : stream_socket->process_context);
273 159575 : }
274 :
275 : /*
276 : setup a listen stream socket
277 : if you pass *port == 0, then a port > 1024 is used
278 :
279 : FIXME: This function is TCP/IP specific - uses an int rather than
280 : a string for the port. Should leave allocating a port nr
281 : to the socket implementation - JRV20070903
282 : */
283 2454 : NTSTATUS stream_setup_socket(TALLOC_CTX *mem_ctx,
284 : struct tevent_context *event_context,
285 : struct loadparm_context *lp_ctx,
286 : const struct model_ops *model_ops,
287 : const struct stream_server_ops *stream_ops,
288 : const char *family,
289 : const char *sock_addr,
290 : uint16_t *port,
291 : const char *socket_options,
292 : void *private_data,
293 : void *process_context)
294 : {
295 74 : NTSTATUS status;
296 74 : struct stream_socket *stream_socket;
297 74 : struct socket_address *socket_address;
298 74 : struct tevent_fd *fde;
299 74 : int i;
300 74 : struct sockaddr_storage ss;
301 :
302 2454 : stream_socket = talloc_zero(mem_ctx, struct stream_socket);
303 2454 : NT_STATUS_HAVE_NO_MEMORY(stream_socket);
304 :
305 2454 : if (strcmp(family, "ip") == 0) {
306 : /* we will get the real family from the address itself */
307 1264 : if (!interpret_string_addr(&ss, sock_addr, 0)) {
308 0 : talloc_free(stream_socket);
309 0 : return NT_STATUS_INVALID_ADDRESS;
310 : }
311 :
312 1264 : socket_address = socket_address_from_sockaddr_storage(stream_socket, &ss, port?*port:0);
313 1264 : if (socket_address == NULL) {
314 0 : TALLOC_FREE(stream_socket);
315 0 : return NT_STATUS_NO_MEMORY;
316 : }
317 :
318 1264 : status = socket_create(stream_socket, socket_address->family,
319 : SOCKET_TYPE_STREAM,
320 : &stream_socket->sock, 0);
321 1264 : NT_STATUS_NOT_OK_RETURN(status);
322 : } else {
323 1190 : status = socket_create(stream_socket, family,
324 : SOCKET_TYPE_STREAM,
325 : &stream_socket->sock, 0);
326 1190 : NT_STATUS_NOT_OK_RETURN(status);
327 :
328 : /* this is for non-IP sockets, eg. unix domain sockets */
329 1190 : socket_address = socket_address_from_strings(stream_socket,
330 1190 : stream_socket->sock->backend_name,
331 203 : sock_addr, port?*port:0);
332 1190 : NT_STATUS_HAVE_NO_MEMORY(socket_address);
333 : }
334 :
335 :
336 2454 : stream_socket->lp_ctx = talloc_reference(stream_socket, lp_ctx);
337 :
338 : /* ready to listen */
339 2454 : status = socket_set_option(stream_socket->sock, "SO_KEEPALIVE", NULL);
340 2454 : NT_STATUS_NOT_OK_RETURN(status);
341 :
342 2454 : if (socket_options != NULL) {
343 1652 : status = socket_set_option(stream_socket->sock, socket_options, NULL);
344 1652 : NT_STATUS_NOT_OK_RETURN(status);
345 : }
346 :
347 : /* TODO: set socket ACL's (host allow etc) here when they're
348 : * implemented */
349 :
350 : /* Some sockets don't have a port, or are just described from
351 : * the string. We are indicating this by having port == NULL */
352 2454 : if (!port) {
353 987 : status = socket_listen(stream_socket->sock, socket_address, SERVER_LISTEN_BACKLOG, 0);
354 1467 : } else if (*port == 0) {
355 68 : for (i = lpcfg_rpc_low_port(lp_ctx);
356 68 : i <= lpcfg_rpc_high_port(lp_ctx);
357 0 : i++) {
358 68 : socket_address->port = i;
359 68 : status = socket_listen(stream_socket->sock, socket_address,
360 : SERVER_LISTEN_BACKLOG, 0);
361 68 : if (NT_STATUS_IS_OK(status)) {
362 68 : *port = i;
363 68 : break;
364 : }
365 : }
366 : } else {
367 1399 : status = socket_listen(stream_socket->sock, socket_address, SERVER_LISTEN_BACKLOG, 0);
368 : }
369 :
370 2454 : if (!NT_STATUS_IS_OK(status)) {
371 0 : DBG_ERR("Failed to listen on %s:%u - %s\n",
372 : sock_addr, port ? (unsigned int)(*port) : 0,
373 : nt_errstr(status));
374 0 : talloc_free(stream_socket);
375 0 : return status;
376 : }
377 :
378 : /* Add the FD from the newly created socket into the event
379 : * subsystem. it will call the accept handler whenever we get
380 : * new connections */
381 :
382 2454 : fde = tevent_add_fd(event_context, stream_socket->sock,
383 : socket_get_fd(stream_socket->sock),
384 : TEVENT_FD_READ,
385 : stream_accept_handler, stream_socket);
386 2454 : if (!fde) {
387 0 : DBG_ERR("Failed to setup fd event\n");
388 0 : talloc_free(stream_socket);
389 0 : return NT_STATUS_NO_MEMORY;
390 : }
391 :
392 : /* we let events system to the close on the socket. This avoids
393 : * nasty interactions with waiting for talloc to close the socket. */
394 2454 : tevent_fd_set_close_fn(fde, socket_tevent_fd_close_fn);
395 2454 : socket_set_flags(stream_socket->sock, SOCKET_FLAG_NOCLOSE);
396 :
397 2454 : stream_socket->private_data = talloc_reference(stream_socket, private_data);
398 2454 : stream_socket->ops = stream_ops;
399 2454 : stream_socket->event_ctx = event_context;
400 2454 : stream_socket->model_ops = model_ops;
401 2454 : stream_socket->process_context = process_context;
402 :
403 2454 : return NT_STATUS_OK;
404 : }
405 :
406 :
407 : /*
408 : setup a connection title
409 : */
410 129382 : void stream_connection_set_title(struct stream_connection *conn, const char *title)
411 : {
412 129382 : conn->model_ops->set_title(conn->event.ctx, title);
413 129382 : }
|