Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : helper functions for task based servers (nbtd, winbind etc)
5 :
6 : Copyright (C) Andrew Tridgell 2005
7 :
8 : This program is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include "includes.h"
23 : #include "process_model.h"
24 : #include "lib/messaging/irpc.h"
25 : #include "param/param.h"
26 : #include "librpc/gen_ndr/ndr_irpc_c.h"
27 :
28 : /*
29 : terminate a task service
30 : */
31 42 : void task_server_terminate(struct task_server *task, const char *reason, bool fatal)
32 : {
33 42 : struct tevent_context *event_ctx = task->event_ctx;
34 42 : const struct model_ops *model_ops = task->model_ops;
35 42 : if (fatal) {
36 0 : DBG_ERR("task_server_terminate: [%s]\n", reason);
37 : } else {
38 42 : DBG_NOTICE("task_server_terminate: [%s]\n", reason);
39 : }
40 :
41 42 : if (fatal && task->msg_ctx != NULL) {
42 0 : struct dcerpc_binding_handle *irpc_handle;
43 0 : struct samba_terminate r;
44 :
45 0 : irpc_handle = irpc_binding_handle_by_name(task, task->msg_ctx,
46 : "samba", &ndr_table_irpc);
47 0 : if (irpc_handle != NULL) {
48 : /* Note: this makes use of nested event loops... */
49 0 : dcerpc_binding_handle_set_sync_ev(irpc_handle, event_ctx);
50 0 : r.in.reason = reason;
51 0 : dcerpc_samba_terminate_r(irpc_handle, task, &r);
52 : }
53 : }
54 :
55 42 : imessaging_cleanup(task->msg_ctx);
56 :
57 42 : model_ops->terminate_task(
58 : event_ctx, task->lp_ctx, reason, fatal, task->process_context);
59 : /* don't free this above, it might contain the 'reason' being printed */
60 0 : talloc_free(task);
61 0 : }
62 :
63 : /* used for the callback from the process model code */
64 : struct task_state {
65 : const struct service_details *service_details;
66 : const struct model_ops *model_ops;
67 : };
68 :
69 :
70 : /*
71 : called by the process model code when the new task starts up. This then calls
72 : the server specific startup code
73 : */
74 916 : static struct task_server *task_server_callback(struct tevent_context *event_ctx,
75 : struct loadparm_context *lp_ctx,
76 : struct server_id server_id,
77 : void *private_data,
78 : void *context)
79 : {
80 28 : struct task_server *task;
81 916 : NTSTATUS status = NT_STATUS_OK;
82 :
83 916 : struct task_state *state = talloc_get_type(private_data, struct task_state);
84 916 : task = talloc(event_ctx, struct task_server);
85 916 : if (task == NULL) return NULL;
86 :
87 916 : task->event_ctx = event_ctx;
88 916 : task->model_ops = state->model_ops;
89 916 : task->server_id = server_id;
90 916 : task->lp_ctx = lp_ctx;
91 916 : task->process_context = context;
92 :
93 916 : task->msg_ctx = imessaging_init(task,
94 : task->lp_ctx,
95 : task->server_id,
96 : task->event_ctx);
97 916 : if (!task->msg_ctx) {
98 0 : task_server_terminate(task, "imessaging_init() failed", true);
99 0 : return NULL;
100 : }
101 :
102 916 : status = state->service_details->task_init(task);
103 874 : if (!NT_STATUS_IS_OK(status)) {
104 6 : return NULL;
105 : }
106 840 : return task;
107 : }
108 :
109 : /*
110 : startup a task based server
111 : */
112 910 : NTSTATUS task_server_startup(struct tevent_context *event_ctx,
113 : struct loadparm_context *lp_ctx,
114 : const char *service_name,
115 : const struct model_ops *model_ops,
116 : const struct service_details *service_details,
117 : int from_parent_fd)
118 : {
119 28 : struct task_state *state;
120 :
121 910 : state = talloc(event_ctx, struct task_state);
122 910 : NT_STATUS_HAVE_NO_MEMORY(state);
123 :
124 910 : state->service_details = service_details;
125 910 : state->model_ops = model_ops;
126 :
127 910 : state->model_ops->new_task(event_ctx, lp_ctx, service_name,
128 : task_server_callback, state, service_details,
129 : from_parent_fd);
130 :
131 910 : return NT_STATUS_OK;
132 : }
133 :
134 : /*
135 : setup a task title
136 : */
137 871 : void task_server_set_title(struct task_server *task, const char *title)
138 : {
139 871 : task->model_ops->set_title(task->event_ctx, title);
140 871 : }
|