2 Unix SMB/CIFS implementation.
6 Copyright (C) Andrew Tridgell 2003
7 Copyright (C) Stefan (metze) Metzmacher 2004
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 2 of the License, or
12 (at your option) any later version.
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.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include "system/dir.h"
27 #include "dlinklist.h"
28 #include "process_model.h"
30 struct server_context *server_service_startup(const char *model)
33 const char **server_services = lp_server_services();
34 struct server_context *srv_ctx;
35 const struct model_ops *model_ops;
37 if (!server_services) {
38 DEBUG(0,("process_model_startup: no endpoint servers configured\n"));
42 model_ops = process_model_startup(model);
44 DEBUG(0,("process_model_startup('%s') failed\n", model));
48 srv_ctx = talloc_p(NULL, struct server_context);
53 ZERO_STRUCTP(srv_ctx);
55 srv_ctx->events = event_context_init(srv_ctx);
56 if (!srv_ctx->events) {
57 DEBUG(0,("event_context_init() failed\n"));
62 for (i=0;server_services[i];i++) {
63 const struct server_service_ops *service_ops;
64 struct server_service *service;
66 service_ops = server_service_byname(server_services[i]);
68 DEBUG(0,("process_model_startup: failed to find server service = '%s'\n", server_services[i]));
72 service = talloc_p(srv_ctx, struct server_service);
77 ZERO_STRUCTP(service);
78 service->ops = service_ops;
79 service->model_ops = model_ops;
80 service->srv_ctx = srv_ctx;
82 /* TODO: service_init() should return a result */
83 service->ops->service_init(service, model_ops);
85 DLIST_ADD(srv_ctx->service_list, service);
92 setup a listen stream socket
93 if you pass *port == 0, then a port > 1024 is used
95 struct server_socket *service_setup_socket(struct server_service *service,
96 const struct model_ops *model_ops,
98 const char *sock_addr,
102 struct server_socket *srv_sock;
103 struct socket_context *socket_ctx;
107 status = socket_create(family, SOCKET_TYPE_STREAM, &socket_ctx, 0);
108 if (!NT_STATUS_IS_OK(status)) {
109 DEBUG(0,("Failed to open socket on %s:%u - %s\n",
110 sock_addr, *port, nt_errstr(status)));
114 talloc_steal(service, socket_ctx);
116 /* ready to listen */
117 status = socket_set_option(socket_ctx, "SO_KEEPALIVE SO_REUSEADDR=1", NULL);
118 if (!NT_STATUS_IS_OK(status)) {
119 DEBUG(0,("socket_set_option(socket_ctx, SO_KEEPALIVE, NULL): %s\n",
121 socket_destroy(socket_ctx);
124 status = socket_set_option(socket_ctx, lp_socket_options(), NULL);
125 if (!NT_STATUS_IS_OK(status)) {
126 DEBUG(0,("socket_set_option(socket_ctx, lp_socket_options(), NULL): %s\n",
128 socket_destroy(socket_ctx);
132 /* TODO: set socket ACL's here when they're implemented */
135 for (i=SERVER_TCP_LOW_PORT;i<= SERVER_TCP_HIGH_PORT;i++) {
136 status = socket_listen(socket_ctx, sock_addr, i, SERVER_LISTEN_BACKLOG, 0);
137 if (NT_STATUS_IS_OK(status)) {
143 status = socket_listen(socket_ctx, sock_addr, *port, SERVER_LISTEN_BACKLOG, 0);
146 if (!NT_STATUS_IS_OK(status)) {
147 DEBUG(0,("Failed to listen on %s:%u - %s\n",
148 sock_addr, *port, nt_errstr(status)));
149 socket_destroy(socket_ctx);
153 srv_sock = talloc_p(service, struct server_socket);
155 DEBUG(0,("talloc_p(mem_ctx, struct server_socket) failed\n"));
156 socket_destroy(socket_ctx);
160 /* we are only interested in read events on the listen socket */
161 fde.fd = socket_get_fd(socket_ctx);
162 fde.flags = EVENT_FD_READ;
163 fde.private = srv_sock;
164 fde.handler = model_ops->accept_connection;
166 ZERO_STRUCTP(srv_sock);
167 srv_sock->service = service;
168 srv_sock->socket = socket_ctx;
169 srv_sock->event.ctx = service->srv_ctx->events;
170 srv_sock->event.fde = event_add_fd(srv_sock->event.ctx, &fde);
171 if (!srv_sock->event.fde) {
172 DEBUG(0,("event_add_fd(srv_sock->event.ctx, &fde) failed\n"));
173 socket_destroy(socket_ctx);
177 DLIST_ADD(service->socket_list, srv_sock);
183 destructor that handles necessary event context changes
185 static int server_destructor(void *ptr)
187 struct server_connection *conn = ptr;
190 conn->service->ops->close_connection(conn, "shutdown");
193 socket_destroy(conn->socket);
195 if (conn->event.fde) {
196 event_remove_fd(conn->event.ctx, conn->event.fde);
197 conn->event.fde = NULL;
199 if (conn->event.idle) {
200 event_remove_timed(conn->event.ctx, conn->event.idle);
201 conn->event.idle = NULL;
204 DLIST_REMOVE(conn->server_socket->connection_list, conn);
209 struct server_connection *server_setup_connection(struct event_context *ev,
210 struct server_socket *server_socket,
211 struct socket_context *sock,
216 struct timed_event idle;
217 struct server_connection *srv_conn;
219 srv_conn = talloc_p(server_socket, struct server_connection);
221 DEBUG(0,("talloc_p(mem_ctx, struct server_connection) failed\n"));
225 ZERO_STRUCTP(srv_conn);
227 fde.private = srv_conn;
228 fde.fd = socket_get_fd(sock);
229 fde.flags = EVENT_FD_READ;
230 fde.handler = server_io_handler;
232 idle.private = srv_conn;
233 idle.next_event = timeval_add(&t, SERVER_DEFAULT_IDLE_TIME, 0);
234 idle.handler = server_idle_handler;
236 srv_conn->event.ctx = ev;
237 srv_conn->event.fde = &fde;
238 srv_conn->event.idle = &idle;
239 srv_conn->event.idle_time = timeval_set(SERVER_DEFAULT_IDLE_TIME, 0);
241 srv_conn->server_socket = server_socket;
242 srv_conn->service = server_socket->service;
243 srv_conn->socket = sock;
244 srv_conn->server_id = server_id;
246 /* create a server context and add it to out event
248 server_socket->service->ops->accept_connection(srv_conn);
250 /* accpect_connection() of the service may changed idle.next_event */
251 srv_conn->event.fde = event_add_fd(ev,&fde);
252 srv_conn->event.idle = event_add_timed(ev,&idle);
254 talloc_set_destructor(srv_conn, server_destructor);
256 if (!socket_check_access(sock, "smbd", lp_hostsallow(-1), lp_hostsdeny(-1))) {
257 server_terminate_connection(srv_conn, "denied by access rules");
261 /* setup to receive internal messages on this connection */
262 srv_conn->messaging_ctx = messaging_init(srv_conn, srv_conn->server_id, ev);
268 close the socket and shutdown a server_context
270 void server_terminate_connection(struct server_connection *srv_conn, const char *reason)
272 DEBUG(2,("server_terminate_connection\n"));
273 srv_conn->service->model_ops->terminate_connection(srv_conn, reason);
276 void server_io_handler(struct event_context *ev, struct fd_event *fde,
277 struct timeval t, uint16_t flags)
279 struct server_connection *conn = fde->private;
281 conn->event.idle->next_event = timeval_sum(&t, &conn->event.idle_time);
283 if (flags & EVENT_FD_WRITE) {
284 conn->service->ops->send_handler(conn, t, flags);
288 if (flags & EVENT_FD_READ) {
289 conn->service->ops->recv_handler(conn, t, flags);
294 void server_idle_handler(struct event_context *ev, struct timed_event *idle,
297 struct server_connection *conn = idle->private;
299 conn->event.idle->next_event = timeval_sum(&t, &conn->event.idle_time);
301 /* Not all services provide an idle handler */
302 if (conn->service->ops->idle_handler) {
303 conn->service->ops->idle_handler(conn, t);
307 return the operations structure for a named backend of the specified type
309 const struct server_service_ops *server_service_byname(const char *name)
311 if (strcmp("smb",name)==0) {
312 return smbsrv_get_ops();
314 if (strcmp("rpc",name)==0) {
315 return dcesrv_get_ops();
317 if (strcmp("ldap",name)==0) {
318 return ldapsrv_get_ops();
323 NTSTATUS register_server_service_ops(const void *_ops)
325 return NT_STATUS_NOT_IMPLEMENTED;
329 close all listening sockets. This is called by process models that fork, to
330 ensure that the listen sockets from the parent are closed
332 void service_close_listening_sockets(struct server_context *srv_ctx)
334 struct server_service *svc;
335 for (svc=srv_ctx->service_list;svc;svc=svc->next) {
336 struct server_socket *sock;
337 for (sock=svc->socket_list;sock;sock=sock->next) {
338 event_remove_fd(sock->event.ctx, sock->event.fde);
339 sock->event.fde = NULL;
340 socket_destroy(sock->socket);
348 cleanup temporary files. This is the new alternative to
349 TDB_CLEAR_IF_FIRST. Unfortunately TDB_CLEAR_IF_FIRST is not
350 efficient on unix systems due to the lack of scaling of the byte
351 range locking system. So instead of putting the burden on tdb to
352 cleanup tmp files, this function deletes them.
354 void service_cleanup_tmp_files(void)
359 TALLOC_CTX *mem_ctx = talloc_init("service_cleanup_tmp_files");
361 path = smbd_tmp_path(mem_ctx, NULL);
365 talloc_free(mem_ctx);
369 for (de=readdir(dir);de;de=readdir(dir)) {
370 char *fname = talloc_asprintf(mem_ctx, "%s/%s", path, de->d_name);
371 int ret = unlink(fname);
376 DEBUG(0,("Unabled to delete '%s' - %s\n",
377 fname, strerror(errno)));
378 smb_panic("unable to cleanup tmp files");
384 talloc_free(mem_ctx);