2
* Unix SMB/CIFS implementation.
4
* SMBD RPC service callbacks
6
* Copyright (c) 2011 Andreas Schneider <asn@samba.org>
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.
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.
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/>.
26
#include "../librpc/gen_ndr/srv_epmapper.h"
27
#include "rpc_server/rpc_server.h"
28
#include "rpc_server/epmapper/srv_epmapper.h"
31
#define DAEMON_NAME "epmd"
33
void start_epmd(struct tevent_context *ev_ctx,
34
struct messaging_context *msg_ctx);
36
static bool epmd_open_sockets(struct tevent_context *ev_ctx,
37
struct messaging_context *msg_ctx)
39
uint32_t num_ifs = iface_count();
43
if (lp_interfaces() && lp_bind_interfaces_only()) {
45
* We have been given an interfaces line, and been told to only
46
* bind to those interfaces. Create a socket per interface and
50
/* Now open a listen socket for each of the interfaces. */
51
for(i = 0; i < num_ifs; i++) {
52
const struct sockaddr_storage *ifss =
53
iface_n_sockaddr_storage(i);
55
port = setup_dcerpc_ncacn_tcpip_socket(ev_ctx,
57
ndr_table_epmapper.syntax_id,
65
const char *sock_addr = lp_socket_address();
69
if (strequal(sock_addr, "0.0.0.0") ||
70
strequal(sock_addr, "::")) {
74
sock_addr = "0.0.0.0";
78
for (sock_ptr = sock_addr;
79
next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,");
81
struct sockaddr_storage ss;
83
/* open an incoming socket */
84
if (!interpret_string_addr(&ss,
86
AI_NUMERICHOST|AI_PASSIVE)) {
90
port = setup_dcerpc_ncacn_tcpip_socket(ev_ctx,
92
ndr_table_epmapper.syntax_id,
104
static void epmd_reopen_logs(void)
106
char *lfile = lp_logfile();
109
if (lfile == NULL || lfile[0] == '\0') {
110
rc = asprintf(&lfile, "%s/log.%s", get_dyn_LOGFILEBASE(), DAEMON_NAME);
112
lp_set_logfile(lfile);
116
if (strstr(lfile, DAEMON_NAME) == NULL) {
117
rc = asprintf(&lfile, "%s.%s", lp_logfile(), DAEMON_NAME);
119
lp_set_logfile(lfile);
128
static void epmd_smb_conf_updated(struct messaging_context *msg,
131
struct server_id server_id,
134
DEBUG(10, ("Got message saying smb.conf was updated. Reloading.\n"));
135
change_to_root_user();
139
static void epmd_sig_term_handler(struct tevent_context *ev,
140
struct tevent_signal *se,
146
rpc_epmapper_shutdown();
148
exit_server_cleanly("termination signal");
151
static void epmd_setup_sig_term_handler(struct tevent_context *ev_ctx)
153
struct tevent_signal *se;
155
se = tevent_add_signal(ev_ctx,
158
epmd_sig_term_handler,
161
exit_server("failed to setup SIGTERM handler");
165
static void epmd_sig_hup_handler(struct tevent_context *ev,
166
struct tevent_signal *se,
172
change_to_root_user();
174
DEBUG(1,("Reloading printers after SIGHUP\n"));
178
static void epmd_setup_sig_hup_handler(struct tevent_context *ev_ctx,
179
struct messaging_context *msg_ctx)
181
struct tevent_signal *se;
183
se = tevent_add_signal(ev_ctx,
186
epmd_sig_hup_handler,
189
exit_server("failed to setup SIGHUP handler");
193
static bool epmapper_shutdown_cb(void *ptr) {
194
srv_epmapper_cleanup();
199
void start_epmd(struct tevent_context *ev_ctx,
200
struct messaging_context *msg_ctx)
202
struct rpc_srv_callbacks epmapper_cb;
208
epmapper_cb.init = NULL;
209
epmapper_cb.shutdown = epmapper_shutdown_cb;
210
epmapper_cb.private_data = NULL;
212
DEBUG(1, ("Forking Endpoint Mapper Daemon\n"));
217
DEBUG(0, ("Failed to fork Endpoint Mapper [%s], aborting ...\n",
228
close_low_fds(false);
230
status = reinit_after_fork(msg_ctx,
234
if (!NT_STATUS_IS_OK(status)) {
235
DEBUG(0,("reinit_after_fork() failed\n"));
236
smb_panic("reinit_after_fork() failed");
241
epmd_setup_sig_term_handler(ev_ctx);
242
epmd_setup_sig_hup_handler(ev_ctx, msg_ctx);
244
ok = serverid_register(procid_self(),
245
FLAG_MSG_GENERAL|FLAG_MSG_SMBD
246
|FLAG_MSG_PRINT_GENERAL);
248
DEBUG(0, ("Failed to register serverid in epmd!\n"));
252
messaging_register(msg_ctx,
254
MSG_SMB_CONF_UPDATED,
255
epmd_smb_conf_updated);
257
status = rpc_epmapper_init(&epmapper_cb);
258
if (!NT_STATUS_IS_OK(status)) {
259
DEBUG(0, ("Failed to register epmd rpc inteface! (%s)\n",
264
ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
266
ndr_table_epmapper.syntax_id,
268
srv_epmapper_delete_endpoints);
270
DEBUG(0, ("Failed to open epmd ncalrpc pipe!\n"));
274
ok = epmd_open_sockets(ev_ctx, msg_ctx);
276
DEBUG(0, ("Failed to open epmd tcpip sockets!\n"));
280
ok = setup_named_pipe_socket("epmapper", ev_ctx);
282
DEBUG(0, ("Failed to open epmd named pipe!\n"));
286
DEBUG(1, ("Endpoint Mapper Daemon Started (%d)\n", getpid()));
289
rc = tevent_loop_wait(ev_ctx);
291
/* should not be reached */
292
DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
293
rc, (rc == 0) ? "out of events" : strerror(errno)));
298
/* vim: set ts=8 sw=8 noet cindent ft=c.doxygen: */