--- /dev/null
+/*
+ Unix SMB/CIFS implementation.
+
+ Copyright (C) 2012 Stefan Metzmacher
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "ntdomain.h"
+#include "../libcli/security/security.h"
+#include "../lib/tsocket/tsocket.h"
+#include "librpc/gen_ndr/srv_mgmt.h"
+#include "auth.h"
+
+bool srv_mgmt_delete_endpoints(struct pipes_struct *p)
+{
+ return true;
+}
+
+void srv_mgmt_cleanup(void)
+{
+}
+
+WERROR _mgmt_inq_if_ids(struct pipes_struct *p,
+ struct mgmt_inq_if_ids *r)
+{
+ //const struct dcesrv_endpoint *ep = dce_call->conn->endpoint;
+ //struct dcesrv_if_list *l;
+ struct rpc_if_id_vector_t *vector;
+
+ vector = *r->out.if_id_vector = talloc(p->mem_ctx, struct rpc_if_id_vector_t);
+ vector->count = 0;
+ vector->if_id = NULL;
+#if 0
+ for (l = ep->interface_list; l; l = l->next) {
+ vector->count++;
+ vector->if_id = talloc_realloc(mem_ctx, vector->if_id, struct ndr_syntax_id_p, vector->count);
+ vector->if_id[vector->count-1].id = &l->iface.syntax_id;
+ }
+#endif
+ return WERR_OK;
+}
+
+
+/*
+ mgmt_inq_stats
+*/
+WERROR _mgmt_inq_stats(struct pipes_struct *p,
+ struct mgmt_inq_stats *r)
+{
+ if (r->in.max_count != MGMT_STATS_ARRAY_MAX_SIZE)
+ return WERR_NOT_SUPPORTED;
+
+ r->out.statistics->count = r->in.max_count;
+ r->out.statistics->statistics = talloc_array(p->mem_ctx, uint32_t, r->in.max_count);
+ /* FIXME */
+ r->out.statistics->statistics[MGMT_STATS_CALLS_IN] = 0;
+ r->out.statistics->statistics[MGMT_STATS_CALLS_OUT] = 0;
+ r->out.statistics->statistics[MGMT_STATS_PKTS_IN] = 0;
+ r->out.statistics->statistics[MGMT_STATS_PKTS_OUT] = 0;
+
+ return WERR_OK;
+}
+
+
+/*
+ mgmt_is_server_listening
+*/
+uint32_t _mgmt_is_server_listening(struct pipes_struct *p,
+ struct mgmt_is_server_listening *r)
+{
+ *r->out.status = 0;
+ return 1;
+}
+
+/*
+ mgmt_stop_server_listening
+*/
+WERROR _mgmt_stop_server_listening(struct pipes_struct *p,
+ struct mgmt_stop_server_listening *r)
+{
+ return WERR_ACCESS_DENIED;
+}
+
+
+/*
+ mgmt_inq_princ_name
+*/
+WERROR _mgmt_inq_princ_name(struct pipes_struct *p,
+ struct mgmt_inq_princ_name *r)
+{
+ snprintf(r->out.princ_name, r->in.princ_name_size, "cifs/%s",
+ lp_netbios_name());
+ DEBUG(0,("_mgmt_inq_princ_name[%s]\n", r->out.princ_name));
+ return WERR_OK;
+}
--- /dev/null
+/*
+ Unix SMB/CIFS implementation.
+
+ Copyright (C) 2012 Stefan Metzmacher
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "ntdomain.h"
+#include "../libcli/security/security.h"
+#include "../lib/tsocket/tsocket.h"
+#include "librpc/gen_ndr/srv_witness.h"
+#include "srv_witness.h"
+#include "auth.h"
+
+bool srv_witness_delete_endpoints(struct pipes_struct *p)
+{
+ return true;
+}
+
+void srv_witness_cleanup(void)
+{
+}
+/*
+ typedef struct {
+ [charset(UTF16),to_null] uint16 group_name[260];
+ uint32 version;
+ uint16 state;
+ ipv4address ipv4;
+ ipv6address ipv6;
+ uint32 flags;
+ } witness_interfaceInfo;
+
+ typedef struct {
+ uint32 num_interfaces;
+ [size_is(num_interfaces)] witness_interfaceInfo *interfaces;
+ } witness_interfaceList;
+*/
+static const char * const ifaces[] = {
+ "172.31.91.173",
+ "172.31.91.174",
+ "172.31.91.175",
+};
+static uint32_t ifaces_idx;
+
+WERROR _witness_GetInterfaceList(struct pipes_struct *p,
+ struct witness_GetInterfaceList *r)
+{
+ struct witness_interfaceList *list;
+ struct witness_interfaceInfo *infos;
+ uint32_t i;
+ uint32_t n = ARRAY_SIZE(ifaces);
+
+ list = talloc_zero(p->mem_ctx, struct witness_interfaceList);
+ if (list == NULL) {
+ return WERR_NOMEM;
+ }
+
+ infos = talloc_zero_array(list, struct witness_interfaceInfo, n);
+ if (infos == NULL) {
+ return WERR_NOMEM;
+ }
+
+ list->num_interfaces = n;
+ list->interfaces = infos;
+
+ for (i=0; i < n; i++) {
+ struct witness_interfaceInfo *info = &infos[i];
+
+ info->group_name = talloc_strdup(infos, "\\\\fedora14.vm.base");
+ info->version = 0x00010001;
+ info->state = 0x0001;
+ info->ipv4 = ifaces[i];
+ info->flags |= 0x00000001;
+ info->ipv6 = "::";
+ info->flags |= 0x00000004;
+ }
+
+ *r->out.interface_list = list;
+ return WERR_OK;
+}
+
+WERROR _witness_Register(struct pipes_struct *p,
+ struct witness_Register *r)
+{
+ bool ok;
+
+ if (r->in.version != 0x00010001) {
+ return WERR_REVISION_MISMATCH;
+ }
+
+ ok = create_policy_hnd(p, r->out.context_handle, NULL);
+ if (!ok) {
+ return WERR_NO_SYSTEM_RESOURCES;
+ }
+
+ return WERR_OK;
+}
+
+WERROR _witness_RegisterEx(struct pipes_struct *p,
+ struct witness_RegisterEx *r)
+{
+ return WERR_NOT_SUPPORTED; //???
+}
+
+WERROR _witness_UnRegister(struct pipes_struct *p,
+ struct witness_UnRegister *r)
+{
+ bool ok;
+
+ ok = close_policy_hnd(p, &r->in.context_handle);
+ if (!ok) {
+ return WERR_NOT_FOUND;
+ }
+
+ return WERR_OK;
+}
+
+WERROR _witness_AsyncNotify(struct pipes_struct *p,
+ struct witness_AsyncNotify *r)
+{
+ bool ok;
+ struct witness_notifyResponse *response = NULL;
+ DATA_BLOB blob = data_blob_null;
+ uint8_t msg[0x24];
+ uint32_t addr;
+
+ ok = find_policy_by_hnd(p, &r->in.context_handle, NULL);
+ if (!ok) {
+ return WERR_NOT_FOUND;
+ }
+
+ // HACK to avoid client loop...
+ // TODO => async response...
+ smb_msleep(15000);
+
+ addr = inet_addr(ifaces[ifaces_idx]);
+ ifaces_idx += 1;
+ if (ifaces_idx == ARRAY_SIZE(ifaces)) {
+ ifaces_idx = 0;
+ }
+
+ response = talloc_zero(p->mem_ctx, struct witness_notifyResponse);
+ if (response == NULL) {
+ return WERR_NOMEM;
+ }
+
+ SIVAL(msg, 0x00, sizeof(msg));
+ SIVAL(msg, 0x04, 0);
+ SIVAL(msg, 0x08, 1);
+
+ SIVAL(msg, 0x0C, 0x00000001);
+ RSIVAL(msg,0x10, htonl(addr));
+ SBVAL(msg, 0x14, 0);
+ SBVAL(msg, 0x1C, 0);
+
+ blob = data_blob_talloc(response, msg, sizeof(msg));
+ if (blob.data == NULL) {
+ return WERR_NOMEM;
+ }
+
+ response->message_type = 0x00000002;
+ response->num_messages = 1;
+ response->message_buffer = blob.data;
+ response->length = blob.length;
+
+ *r->out.response = response;
+ return WERR_OK;
+}
--- /dev/null
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Copyright (C) 2012 Stefan Metzmacher
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SRV_WITNESS_H_
+#define _SRV_WITNESS_H_
+
+/**
+ * @brief Cleanup memory and other stuff.
+ */
+void srv_witness_cleanup(void);
+
+bool srv_witness_delete_endpoints(struct pipes_struct *p);
+
+#endif /*_SRV_WITNESS_H_ */
--- /dev/null
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * SMBD RPC service callbacks
+ *
+ * Copyright (c) 2011 Andreas Schneider <asn@samba.org>
+ * Copyright (c) 2012 Stefan Metzmacher <metze@samba.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+
+#include "serverid.h"
+#include "ntdomain.h"
+#include "messages.h"
+
+#include "librpc/rpc/dcerpc_ep.h"
+#include "../librpc/gen_ndr/srv_mgmt.h"
+#include "../librpc/gen_ndr/srv_witness.h"
+#include "rpc_server/rpc_server.h"
+#include "rpc_server/rpc_sock_helper.h"
+#include "rpc_server/rpc_ep_register.h"
+#include "rpc_server/witness/srv_witness.h"
+
+#define DAEMON_NAME "witnessd"
+
+void start_witnessd(struct tevent_context *ev_ctx,
+ struct messaging_context *msg_ctx);
+
+static void witnessd_reopen_logs(void)
+{
+ char *lfile = lp_logfile(talloc_tos());
+ int rc;
+
+ if (lfile == NULL || lfile[0] == '\0') {
+ rc = asprintf(&lfile, "%s/log.%s", get_dyn_LOGFILEBASE(), DAEMON_NAME);
+ if (rc > 0) {
+ lp_set_logfile(lfile);
+ SAFE_FREE(lfile);
+ }
+ } else {
+ if (strstr(lfile, DAEMON_NAME) == NULL) {
+ rc = asprintf(&lfile, "%s.%s",
+ lp_logfile(talloc_tos()), DAEMON_NAME);
+ if (rc > 0) {
+ lp_set_logfile(lfile);
+ SAFE_FREE(lfile);
+ }
+ }
+ }
+
+ reopen_logs();
+}
+
+static void witnessd_smb_conf_updated(struct messaging_context *msg,
+ void *private_data,
+ uint32_t msg_type,
+ struct server_id server_id,
+ DATA_BLOB *data)
+{
+ DEBUG(10, ("Got message saying smb.conf was updated. Reloading.\n"));
+ change_to_root_user();
+ witnessd_reopen_logs();
+}
+
+static void witnessd_sig_term_handler(struct tevent_context *ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ void *private_data)
+{
+ rpc_witness_shutdown();
+
+ exit_server_cleanly("termination signal");
+}
+
+static void witnessd_setup_sig_term_handler(struct tevent_context *ev_ctx)
+{
+ struct tevent_signal *se;
+
+ se = tevent_add_signal(ev_ctx,
+ ev_ctx,
+ SIGTERM, 0,
+ witnessd_sig_term_handler,
+ NULL);
+ if (se == NULL) {
+ exit_server("failed to setup SIGTERM handler");
+ }
+}
+
+static void witnessd_sig_hup_handler(struct tevent_context *ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ void *private_data)
+{
+ change_to_root_user();
+
+ DEBUG(1,("Reloading printers after SIGHUP\n"));
+ witnessd_reopen_logs();
+}
+
+static void witnessd_setup_sig_hup_handler(struct tevent_context *ev_ctx,
+ struct messaging_context *msg_ctx)
+{
+ struct tevent_signal *se;
+
+ se = tevent_add_signal(ev_ctx,
+ ev_ctx,
+ SIGHUP, 0,
+ witnessd_sig_hup_handler,
+ msg_ctx);
+ if (se == NULL) {
+ exit_server("failed to setup SIGHUP handler");
+ }
+}
+
+static bool witness_shutdown_cb(void *ptr) {
+ srv_witness_cleanup();
+
+ return true;
+}
+
+void start_witnessd(struct tevent_context *ev_ctx,
+ struct messaging_context *msg_ctx)
+{
+ struct rpc_srv_callbacks mgmt_cb;
+ struct rpc_srv_callbacks witness_cb;
+ NTSTATUS status;
+ pid_t pid;
+ bool ok;
+ int rc;
+ struct dcerpc_binding_vector *bvec = NULL;
+
+ ZERO_STRUCT(mgmt_cb);
+ ZERO_STRUCT(witness_cb);
+
+ witness_cb.init = NULL;
+ witness_cb.shutdown = witness_shutdown_cb;
+ witness_cb.private_data = NULL;
+
+ DEBUG(1, ("Forking SMB Witness Daemon\n"));
+
+ pid = fork();
+
+ if (pid == -1) {
+ DEBUG(0, ("Failed to fork Endpoint Mapper [%s], aborting ...\n",
+ strerror(errno)));
+ exit(1);
+ }
+
+ if (pid) {
+ /* parent */
+ return;
+ }
+
+ status = reinit_after_fork(msg_ctx,
+ ev_ctx,
+ true);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("reinit_after_fork() failed\n"));
+ smb_panic("reinit_after_fork() failed");
+ }
+
+ witnessd_reopen_logs();
+
+ witnessd_setup_sig_term_handler(ev_ctx);
+ witnessd_setup_sig_hup_handler(ev_ctx, msg_ctx);
+
+ ok = serverid_register(messaging_server_id(msg_ctx),
+ FLAG_MSG_GENERAL |
+ FLAG_MSG_PRINT_GENERAL);
+ if (!ok) {
+ DEBUG(0, ("Failed to register serverid in witnessd!\n"));
+ exit(1);
+ }
+
+ messaging_register(msg_ctx,
+ ev_ctx,
+ MSG_SMB_CONF_UPDATED,
+ witnessd_smb_conf_updated);
+
+ status = rpc_mgmt_init(&mgmt_cb);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to register mgmt rpc inteface! (%s)\n",
+ nt_errstr(status)));
+ exit(1);
+ }
+
+ status = rpc_witness_init(&witness_cb);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to register witnessd rpc inteface! (%s)\n",
+ nt_errstr(status)));
+ exit(1);
+ }
+
+ status = dcerpc_binding_vector_new(ev_ctx, &bvec);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to create binding vector (%s)\n",
+ nt_errstr(status)));
+ exit(1);
+ }
+
+ status = rpc_setup_tcpip_sockets(ev_ctx,
+ msg_ctx,
+ &ndr_table_witness,
+ bvec,
+ 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to open witnessd tcpip sockets!\n"));
+ exit(1);
+ }
+
+ status = rpc_ep_register(ev_ctx,
+ msg_ctx,
+ &ndr_table_witness,
+ bvec);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to register with endpoint mapper!\n"));
+ exit(1);
+ }
+
+ DEBUG(1, ("SMB Witness Daemon Started (%d)\n", getpid()));
+
+ /* loop forever */
+ rc = tevent_loop_wait(ev_ctx);
+
+ /* should not be reached */
+ DEBUG(0,(": tevent_loop_wait() exited with %d - %s\n",
+ rc, (rc == 0) ? "out of events" : strerror(errno)));
+
+ exit(1);
+}
+
+/* vim: set ts=8 sw=8 noet cindent ft=c.doxygen: */
RPC_SERVER_LOOP
RPC_CRYPTO
NDR_NAMED_PIPE_AUTH
+ RPC_WITNESS RPC_MGMT
''')
### RPC_SERVICES
../../librpc/gen_ndr/srv_eventlog.c''',
deps='LIBEVENTLOG LIBCLI_WINREG_INTERNAL')
+bld.SAMBA3_SUBSYSTEM('WITNESSD',
+ source='witnessd.c',
+ deps='samba-util')
+
+bld.SAMBA3_SUBSYSTEM('RPC_WITNESS',
+ source='''witness/srv_witness.c
+ ../../librpc/gen_ndr/srv_witness.c''',
+ deps='samba-util',
+ vars=locals())
+
+bld.SAMBA3_SUBSYSTEM('RPC_MGMT',
+ source='''mgmt/srv_mgmt.c
+ ../../librpc/gen_ndr/srv_mgmt.c''',
+ deps='samba-util',
+ vars=locals())
+
bld.SAMBA3_SUBSYSTEM('RPC_INITSHUTDOWN',
source='''initshutdown/srv_initshutdown_nt.c
../../librpc/gen_ndr/srv_initshutdown.c''',
extern void start_lsasd(struct tevent_context *ev_ctx,
struct messaging_context *msg_ctx);
+extern void start_witnessd(struct tevent_context *ev_ctx,
+ struct messaging_context *msg_ctx);
+
#ifdef WITH_DFS
extern int dcelogin_atmost_once;
#endif /* WITH_DFS */
}
if (is_daemon && !interactive) {
- if (rpc_epmapper_daemon() == RPC_DAEMON_FORK) {
+ if (1 || rpc_epmapper_daemon() == RPC_DAEMON_FORK) {
start_epmd(ev_ctx, msg_ctx);
}
}
exit_daemon("Samba failed to init printing subsystem", EACCES);
}
}
+
+ if (1|| rpc_daemon_type("witnessd") == RPC_DAEMON_FORK) {
+ start_witnessd(ev_ctx, msg_ctx);
+ }
} else if (!lp__disable_spoolss() &&
(rpc_spoolss_daemon() != RPC_DAEMON_DISABLED)) {
if (!printing_subsystem_init(ev_ctx, msg_ctx, false, false)) {
bld.SAMBA3_BINARY('smbd/smbd',
source='smbd/server.c',
- deps='smbd_base EPMD LSASD',
+ deps='smbd_base EPMD LSASD WITNESSD',
install_path='${SBINDIR}')
bld.SAMBA3_BINARY('nmbd/nmbd',