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 event_remove_fd(conn->event.ctx, conn->event.fde);
196 conn->event.fde = NULL;
197 event_remove_timed(conn->event.ctx, conn->event.idle);
198 conn->event.idle = NULL;
200 DLIST_REMOVE(conn->server_socket->connection_list, conn);
205 struct server_connection *server_setup_connection(struct event_context *ev,
206 struct server_socket *server_socket,
207 struct socket_context *sock,
212 struct timed_event idle;
213 struct server_connection *srv_conn;
215 srv_conn = talloc_p(server_socket, struct server_connection);
217 DEBUG(0,("talloc_p(mem_ctx, struct server_connection) failed\n"));
221 ZERO_STRUCTP(srv_conn);
223 fde.private = srv_conn;
224 fde.fd = socket_get_fd(sock);
225 fde.flags = EVENT_FD_READ;
226 fde.handler = server_io_handler;
228 idle.private = srv_conn;
229 idle.next_event = t + SERVER_DEFAULT_IDLE_TIME;
230 idle.handler = server_idle_handler;
232 srv_conn->event.ctx = ev;
233 srv_conn->event.fde = &fde;
234 srv_conn->event.idle = &idle;
235 srv_conn->event.idle_time = SERVER_DEFAULT_IDLE_TIME;
237 srv_conn->server_socket = server_socket;
238 srv_conn->service = server_socket->service;
239 srv_conn->socket = sock;
240 srv_conn->server_id = server_id;
242 /* create a smb server context and add it to out event
244 server_socket->service->ops->accept_connection(srv_conn);
246 /* accpect_connection() of the service may changed idle.next_event */
247 srv_conn->event.fde = event_add_fd(ev,&fde);
248 srv_conn->event.idle = event_add_timed(ev,&idle);
250 talloc_set_destructor(srv_conn, server_destructor);
252 if (!socket_check_access(sock, "smbd", lp_hostsallow(-1), lp_hostsdeny(-1))) {
253 server_terminate_connection(srv_conn, "denied by access rules");
257 /* setup to receive internal messages on this connection */
258 srv_conn->messaging_ctx = messaging_init(srv_conn, srv_conn->server_id, ev);
264 close the socket and shutdown a server_context
266 void server_terminate_connection(struct server_connection *srv_conn, const char *reason)
268 DEBUG(2,("server_terminate_connection\n"));
269 srv_conn->service->model_ops->terminate_connection(srv_conn, reason);
272 void server_io_handler(struct event_context *ev, struct fd_event *fde, time_t t, uint16_t flags)
274 struct server_connection *conn = fde->private;
276 conn->event.idle->next_event = t + conn->event.idle_time;
278 if (flags & EVENT_FD_WRITE) {
279 conn->service->ops->send_handler(conn, t, flags);
283 if (flags & EVENT_FD_READ) {
284 conn->service->ops->recv_handler(conn, t, flags);
289 void server_idle_handler(struct event_context *ev, struct timed_event *idle, time_t t)
291 struct server_connection *conn = idle->private;
293 conn->event.idle->next_event = t + conn->event.idle_time;
295 conn->service->ops->idle_handler(conn,t);
298 return the operations structure for a named backend of the specified type
300 const struct server_service_ops *server_service_byname(const char *name)
302 if (strcmp("smb",name)==0) {
303 return smbsrv_get_ops();
305 if (strcmp("rpc",name)==0) {
306 return dcesrv_get_ops();
308 if (strcmp("ldap",name)==0) {
309 return ldapsrv_get_ops();
314 static NTSTATUS register_server_service_ops(const void *_ops)
316 return NT_STATUS_NOT_IMPLEMENTED;
320 initialise the SERVER SERVICE subsystem
322 BOOL server_service_init(void)
326 status = register_subsystem("service", register_server_service_ops);
327 if (!NT_STATUS_IS_OK(status)) {
331 /* FIXME: Perhaps panic if a basic endpoint server, such as EPMAPER, fails to initialise? */
332 static_init_server_service;
334 DEBUG(3,("SERVER SERVICE subsystem version %d initialised\n", SERVER_SERVICE_VERSION));
340 close all listening sockets. This is called by process models that fork, to
341 ensure that the listen sockets from the parent are closed
343 void service_close_listening_sockets(struct server_context *srv_ctx)
345 struct server_service *svc;
346 for (svc=srv_ctx->service_list;svc;svc=svc->next) {
347 struct server_socket *sock;
348 for (sock=svc->socket_list;sock;sock=sock->next) {
349 event_remove_fd(sock->event.ctx, sock->event.fde);
350 sock->event.fde = NULL;
351 socket_destroy(sock->socket);
359 cleanup temporary files. This is the new alternative to
360 TDB_CLEAR_IF_FIRST. Unfortunately TDB_CLEAR_IF_FIRST is not
361 efficient on unix systems due to the lack of scaling of the byte
362 range locking system. So instead of putting the burden on tdb to
363 cleanup tmp files, this function deletes them.
365 void service_cleanup_tmp_files(void)
370 TALLOC_CTX *mem_ctx = talloc_init("service_cleanup_tmp_files");
372 path = smbd_tmp_path(mem_ctx, NULL);
376 talloc_free(mem_ctx);
380 for (de=readdir(dir);de;de=readdir(dir)) {
381 char *fname = talloc_asprintf(mem_ctx, "%s/%s", path, de->d_name);
382 int ret = unlink(fname);
387 DEBUG(0,("Unabled to delete '%s' - %s\n",
388 fname, strerror(errno)));
389 smb_panic("unable to cleanup tmp files");
395 talloc_free(mem_ctx);