/*
Unix SMB/CIFS implementation.
Samba internal messaging functions
Copyright (C) Andrew Tridgell 2004
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 "lib/events/events.h"
#include "lib/util/server_id.h"
#include "system/filesys.h"
#include "messaging/messaging.h"
#include "messaging/messaging_internal.h"
#include "../lib/util/dlinklist.h"
#include "lib/socket/socket.h"
#include "librpc/gen_ndr/ndr_irpc.h"
#include "lib/messaging/irpc.h"
#include "../lib/util/unix_privs.h"
#include "librpc/rpc/dcerpc.h"
#include "cluster/cluster.h"
#include "../lib/util/tevent_ntstatus.h"
#include "lib/param/param.h"
#include "lib/util/server_id_db.h"
#include "lib/util/talloc_report_printf.h"
#include "lib/messaging/messages_dgm.h"
#include "lib/messaging/messages_dgm_ref.h"
#include "../source3/lib/messages_util.h"
#include <tdb.h>
#include "lib/util/idtree.h"
/* change the message version with any incompatible changes in the protocol */
#define IMESSAGING_VERSION 1
/*
a pending irpc call
*/
struct irpc_request {
struct irpc_request *prev, *next;
struct imessaging_context *msg_ctx;
int callid;
struct {
void (*handler)(struct irpc_request *irpc, struct irpc_message *m);
void *private_data;
} incoming;
};
/* we have a linked list of dispatch handlers for each msg_type that
this messaging server can deal with */
struct dispatch_fn {
struct dispatch_fn *next, *prev;
uint32_t msg_type;
void *private_data;
msg_callback_t fn;
};
/* an individual message */
static void irpc_handler(struct imessaging_context *,
void *,
uint32_t,
struct server_id,
size_t,
int *,
DATA_BLOB *);
/*
A useful function for testing the message system.
*/
static void ping_message(struct imessaging_context *msg,
void *private_data,
uint32_t msg_type,
struct server_id src,
size_t num_fds,
int *fds,
DATA_BLOB *data)
{
struct server_id_buf idbuf;
if (num_fds != 0) {
DBG_WARNING("Received %zu fds, ignoring message\n", num_fds);
return;
}
DEBUG(1,("INFO: Received PING message from server %s [%.*s]\n",
server_id_str_buf(src, &idbuf), (int)data->length,
data->data?(const char *)data->data:""));
imessaging_send(msg, src, MSG_PONG, data);
}
static void pool_message(struct imessaging_context *msg,
void *private_data,
uint32_t msg_type,
struct server_id src,
size_t num_fds,
int *fds,
DATA_BLOB *data)
{
FILE *f = NULL;
if (num_fds != 1) {
DBG_WARNING("Received %zu fds, ignoring message\n", num_fds);
return;
}
f = fdopen(fds[0], "w");
if (f == NULL) {
DBG_DEBUG("fopen failed: %s\n", strerror(errno));
return;
}
talloc_full_report_printf(NULL, f);
fclose(f);
}
static void ringbuf_log_msg(struct imessaging_context *msg,
void *private_data,
uint32_t msg_type,
struct server_id src,
size_t num_fds,
int *fds,
DATA_BLOB *data)
{
char *log = debug_get_ringbuf();
size_t logsize = debug_get_ringbuf_size();
DATA_BLOB blob;
if (num_fds != 0) {
DBG_WARNING("Received %zu fds, ignoring message\n", num_fds);
return;
}
if (log == NULL) {
log = discard_const_p(char, "*disabled*\n");
logsize = strlen(log) + 1;
}
blob.data = (uint8_t *)log;
blob.length = logsize;
imessaging_send(msg, src, MSG_RINGBUF_LOG, &blob);
}
/****************************************************************************
Receive a "set debug level" message.
****************************************************************************/
static void debug_imessage(struct imessaging_context *msg_ctx,
void *private_data,
uint32_t msg_type,
struct server_id src,
size_t num_fds,
int *fds,
DATA_BLOB *data)
{
const char *params_str = (const char *)data->data;
struct server_id_buf src_buf;
struct server_id dst = imessaging_get_server_id(msg_ctx);
struct server_id_buf dst_buf;
if (num_fds != 0) {
DBG_WARNING("Received %zu fds, ignoring message\n", num_fds);
return;
}
/* Check, it's a proper string! */
if (params_str[(data->length)-1] != '\0') {
DBG_ERR("Invalid debug message from pid %s to pid %s\n",
server_id_str_buf(src, &src_buf),
server_id_str_buf(dst, &dst_buf));
retur
|