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.h" 27 28/* 29 terminate a task service 30*/ 31void task_server_terminate(struct task_server *task, const char *reason, bool fatal) 32{ 33 struct tevent_context *event_ctx = task->event_ctx; 34 const struct model_ops *model_ops = task->model_ops; 35 DEBUG(0,("task_server_terminate: [%s]\n", reason)); 36 37 if (fatal) { 38 struct samba_terminate r; 39 struct server_id *sid; 40 41 sid = irpc_servers_byname(task->msg_ctx, task, "samba"); 42 43 r.in.reason = reason; 44 IRPC_CALL(task->msg_ctx, sid[0], 45 irpc, SAMBA_TERMINATE, 46 &r, NULL); 47 } 48 49 model_ops->terminate(event_ctx, task->lp_ctx, reason); 50 51 /* don't free this above, it might contain the 'reason' being printed */ 52 talloc_free(task); 53} 54 55/* used for the callback from the process model code */ 56struct task_state { 57 void (*task_init)(struct task_server *); 58 const struct model_ops *model_ops; 59}; 60 61 62/* 63 called by the process model code when the new task starts up. This then calls 64 the server specific startup code 65*/ 66static void task_server_callback(struct tevent_context *event_ctx, 67 struct loadparm_context *lp_ctx, 68 struct server_id server_id, void *private_data) 69{ 70 struct task_state *state = talloc_get_type(private_data, struct task_state); 71 struct task_server *task; 72 73 task = talloc(event_ctx, struct task_server); 74 if (task == NULL) return; 75 76 task->event_ctx = event_ctx; 77 task->model_ops = state->model_ops; 78 task->server_id = server_id; 79 task->lp_ctx = lp_ctx; 80 81 task->msg_ctx = messaging_init(task, 82 lp_messaging_path(task, task->lp_ctx), 83 task->server_id, 84 lp_iconv_convenience(task->lp_ctx), 85 task->event_ctx); 86 if (!task->msg_ctx) { 87 task_server_terminate(task, "messaging_init() failed", true); 88 return; 89 } 90 91 state->task_init(task); 92} 93 94/* 95 startup a task based server 96*/ 97NTSTATUS task_server_startup(struct tevent_context *event_ctx, 98 struct loadparm_context *lp_ctx, 99 const char *service_name, 100 const struct model_ops *model_ops, 101 void (*task_init)(struct task_server *)) 102{ 103 struct task_state *state; 104 105 state = talloc(event_ctx, struct task_state); 106 NT_STATUS_HAVE_NO_MEMORY(state); 107 108 state->task_init = task_init; 109 state->model_ops = model_ops; 110 111 model_ops->new_task(event_ctx, lp_ctx, service_name, task_server_callback, state); 112 113 return NT_STATUS_OK; 114} 115 116/* 117 setup a task title 118*/ 119void task_server_set_title(struct task_server *task, const char *title) 120{ 121 task->model_ops->set_title(task->event_ctx, title); 122} 123