X-Git-Url: http://git.samba.org/samba.git/?p=kai%2Fsamba-autobuild%2F.git;a=blobdiff_plain;f=source4%2Flib%2Fmessaging%2Fmessaging.c;h=ba1c5bd727cc606d10aeb99e96d2d3e24e2fa978;hp=c61bb7afca11f57ad24e034da93dad70cacd38c9;hb=d6db35d7a564ee556b74131ef4c3a3cdb8097e14;hpb=ed7bbc993d4fd080303611a64fefc2b47d786176 diff --git a/source4/lib/messaging/messaging.c b/source4/lib/messaging/messaging.c index c61bb7afca1..ba1c5bd727c 100644 --- a/source4/lib/messaging/messaging.c +++ b/source4/lib/messaging/messaging.c @@ -1,20 +1,20 @@ -/* +/* 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 . */ @@ -27,22 +27,23 @@ #include "lib/socket/socket.h" #include "librpc/gen_ndr/ndr_irpc.h" #include "lib/messaging/irpc.h" -#include "tdb_wrap.h" +#include "lib/tdb_wrap/tdb_wrap.h" #include "../lib/util/unix_privs.h" #include "librpc/rpc/dcerpc.h" -#include "../tdb/include/tdb.h" +#include "../lib/tdb_compat/tdb_compat.h" #include "../lib/util/util_tdb.h" #include "cluster/cluster.h" #include "../lib/util/tevent_ntstatus.h" +#include "lib/param/param.h" /* change the message version with any incompatible changes in the protocol */ -#define MESSAGING_VERSION 1 +#define IMESSAGING_VERSION 1 /* a pending irpc call */ struct irpc_request { - struct messaging_context *msg_ctx; + struct imessaging_context *msg_ctx; int callid; struct { void (*handler)(struct irpc_request *irpc, struct irpc_message *m); @@ -50,16 +51,17 @@ struct irpc_request { } incoming; }; -struct messaging_context { +struct imessaging_context { struct server_id server_id; struct socket_context *sock; const char *base_path; const char *path; + struct loadparm_context *lp_ctx; struct dispatch_fn **dispatch; uint32_t num_types; struct idr_context *dispatch_tree; - struct messaging_rec *pending; - struct messaging_rec *retry_queue; + struct imessaging_rec *pending; + struct imessaging_rec *retry_queue; struct irpc_list *irpc; struct idr_context *idr; const char **names; @@ -81,12 +83,12 @@ struct dispatch_fn { }; /* an individual message */ -struct messaging_rec { - struct messaging_rec *next, *prev; - struct messaging_context *msg; +struct imessaging_rec { + struct imessaging_rec *next, *prev; + struct imessaging_context *msg; const char *path; - struct messaging_header { + struct imessaging_header { uint32_t version; uint32_t msg_type; struct server_id from; @@ -99,40 +101,42 @@ struct messaging_rec { }; -static void irpc_handler(struct messaging_context *, void *, +static void irpc_handler(struct imessaging_context *, void *, uint32_t, struct server_id, DATA_BLOB *); /* A useful function for testing the message system. */ -static void ping_message(struct messaging_context *msg, void *private_data, +static void ping_message(struct imessaging_context *msg, void *private_data, uint32_t msg_type, struct server_id src, DATA_BLOB *data) { - DEBUG(1,("INFO: Received PING message from server %u.%u [%.*s]\n", - (unsigned int)src.node, (unsigned int)src.id, (int)data->length, + char *task_id = server_id_str(NULL, &src); + DEBUG(1,("INFO: Received PING message from server %s [%.*s]\n", + task_id, (int)data->length, data->data?(const char *)data->data:"")); - messaging_send(msg, src, MSG_PONG, data); + talloc_free(task_id); + imessaging_send(msg, src, MSG_PONG, data); } /* return uptime of messaging server via irpc */ -static NTSTATUS irpc_uptime(struct irpc_message *msg, +static NTSTATUS irpc_uptime(struct irpc_message *msg, struct irpc_uptime *r) { - struct messaging_context *ctx = talloc_get_type(msg->private_data, struct messaging_context); + struct imessaging_context *ctx = talloc_get_type(msg->private_data, struct imessaging_context); *r->out.start_time = timeval_to_nttime(&ctx->start_time); return NT_STATUS_OK; } -/* +/* return the path to a messaging socket */ -static char *messaging_path(struct messaging_context *msg, struct server_id server_id) +static char *imessaging_path(struct imessaging_context *msg, struct server_id server_id) { TALLOC_CTX *tmp_ctx = talloc_new(msg); - const char *id = cluster_id_string(tmp_ctx, server_id); + const char *id = server_id_str(tmp_ctx, &server_id); char *s; if (id == NULL) { return NULL; @@ -149,13 +153,13 @@ static char *messaging_path(struct messaging_context *msg, struct server_id serv per message. That allows a single messasging context to register (for example) a debug handler for more than one piece of code */ -static void messaging_dispatch(struct messaging_context *msg, struct messaging_rec *rec) +static void imessaging_dispatch(struct imessaging_context *msg, struct imessaging_rec *rec) { struct dispatch_fn *d, *next; /* temporary IDs use an idtree, the rest use a array of pointers */ if (rec->header->msg_type >= MSG_TMP_BASE) { - d = (struct dispatch_fn *)idr_find(msg->dispatch_tree, + d = (struct dispatch_fn *)idr_find(msg->dispatch_tree, rec->header->msg_type); } else if (rec->header->msg_type < msg->num_types) { d = msg->dispatch[rec->header->msg_type]; @@ -176,29 +180,29 @@ static void messaging_dispatch(struct messaging_context *msg, struct messaging_r /* handler for messages that arrive from other nodes in the cluster */ -static void cluster_message_handler(struct messaging_context *msg, DATA_BLOB packet) +static void cluster_message_handler(struct imessaging_context *msg, DATA_BLOB packet) { - struct messaging_rec *rec; + struct imessaging_rec *rec; - rec = talloc(msg, struct messaging_rec); + rec = talloc(msg, struct imessaging_rec); if (rec == NULL) { - smb_panic("Unable to allocate messaging_rec"); + smb_panic("Unable to allocate imessaging_rec"); } rec->msg = msg; rec->path = msg->path; - rec->header = (struct messaging_header *)packet.data; + rec->header = (struct imessaging_header *)packet.data; rec->packet = packet; rec->retries = 0; if (packet.length != sizeof(*rec->header) + rec->header->length) { - DEBUG(0,("messaging: bad message header size %d should be %d\n", + DEBUG(0,("messaging: bad message header size %d should be %d\n", rec->header->length, (int)(packet.length - sizeof(*rec->header)))); talloc_free(rec); return; } - messaging_dispatch(msg, rec); + imessaging_dispatch(msg, rec); talloc_free(rec); } @@ -207,9 +211,9 @@ static void cluster_message_handler(struct messaging_context *msg, DATA_BLOB pac /* try to send the message */ -static NTSTATUS try_send(struct messaging_rec *rec) +static NTSTATUS try_send(struct imessaging_rec *rec) { - struct messaging_context *msg = rec->msg; + struct imessaging_context *msg = rec->msg; size_t nsent; void *priv; NTSTATUS status; @@ -217,7 +221,7 @@ static NTSTATUS try_send(struct messaging_rec *rec) /* rec->path is the path of the *other* socket, where we want * this to end up */ - path = socket_address_from_strings(msg, msg->sock->backend_name, + path = socket_address_from_strings(msg, msg->sock->backend_name, rec->path, 0); if (!path) { return NT_STATUS_NO_MEMORY; @@ -235,30 +239,30 @@ static NTSTATUS try_send(struct messaging_rec *rec) /* retry backed off messages */ -static void msg_retry_timer(struct tevent_context *ev, struct tevent_timer *te, +static void msg_retry_timer(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *private_data) { - struct messaging_context *msg = talloc_get_type(private_data, - struct messaging_context); + struct imessaging_context *msg = talloc_get_type(private_data, + struct imessaging_context); msg->retry_te = NULL; /* put the messages back on the main queue */ while (msg->retry_queue) { - struct messaging_rec *rec = msg->retry_queue; + struct imessaging_rec *rec = msg->retry_queue; DLIST_REMOVE(msg->retry_queue, rec); - DLIST_ADD_END(msg->pending, rec, struct messaging_rec *); + DLIST_ADD_END(msg->pending, rec, struct imessaging_rec *); } - EVENT_FD_WRITEABLE(msg->event.fde); + TEVENT_FD_WRITEABLE(msg->event.fde); } /* handle a socket write event */ -static void messaging_send_handler(struct messaging_context *msg) +static void imessaging_send_handler(struct imessaging_context *msg) { while (msg->pending) { - struct messaging_rec *rec = msg->pending; + struct imessaging_rec *rec = msg->pending; NTSTATUS status; status = try_send(rec); if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { @@ -267,12 +271,12 @@ static void messaging_send_handler(struct messaging_context *msg) /* we're getting continuous write errors - backoff this record */ DLIST_REMOVE(msg->pending, rec); - DLIST_ADD_END(msg->retry_queue, rec, - struct messaging_rec *); + DLIST_ADD_END(msg->retry_queue, rec, + struct imessaging_rec *); if (msg->retry_te == NULL) { - msg->retry_te = - event_add_timed(msg->event.ev, msg, - timeval_current_ofs(1, 0), + msg->retry_te = + tevent_add_timer(msg->event.ev, msg, + timeval_current_ofs(1, 0), msg_retry_timer, msg); } } @@ -281,10 +285,10 @@ static void messaging_send_handler(struct messaging_context *msg) rec->retries = 0; if (!NT_STATUS_IS_OK(status)) { TALLOC_CTX *tmp_ctx = talloc_new(msg); - DEBUG(1,("messaging: Lost message from %s to %s of type %u - %s\n", - cluster_id_string(tmp_ctx, rec->header->from), - cluster_id_string(tmp_ctx, rec->header->to), - rec->header->msg_type, + DEBUG(1,("messaging: Lost message from %s to %s of type %u - %s\n", + server_id_str(tmp_ctx, &rec->header->from), + server_id_str(tmp_ctx, &rec->header->to), + rec->header->msg_type, nt_errstr(status))); talloc_free(tmp_ctx); } @@ -292,16 +296,16 @@ static void messaging_send_handler(struct messaging_context *msg) talloc_free(rec); } if (msg->pending == NULL) { - EVENT_FD_NOT_WRITEABLE(msg->event.fde); + TEVENT_FD_NOT_WRITEABLE(msg->event.fde); } } /* handle a new incoming packet */ -static void messaging_recv_handler(struct messaging_context *msg) +static void imessaging_recv_handler(struct imessaging_context *msg) { - struct messaging_rec *rec; + struct imessaging_rec *rec; NTSTATUS status; DATA_BLOB packet; size_t msize; @@ -309,17 +313,17 @@ static void messaging_recv_handler(struct messaging_context *msg) /* see how many bytes are in the next packet */ status = socket_pending(msg->sock, &msize); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("socket_pending failed in messaging - %s\n", + DEBUG(0,("socket_pending failed in messaging - %s\n", nt_errstr(status))); return; } - + packet = data_blob_talloc(msg, NULL, msize); if (packet.data == NULL) { /* assume this is temporary and retry */ return; } - + status = socket_recv(msg->sock, packet.data, msize, &msize); if (!NT_STATUS_IS_OK(status)) { data_blob_free(&packet); @@ -332,26 +336,26 @@ static void messaging_recv_handler(struct messaging_context *msg) return; } - rec = talloc(msg, struct messaging_rec); + rec = talloc(msg, struct imessaging_rec); if (rec == NULL) { - smb_panic("Unable to allocate messaging_rec"); + smb_panic("Unable to allocate imessaging_rec"); } talloc_steal(rec, packet.data); rec->msg = msg; rec->path = msg->path; - rec->header = (struct messaging_header *)packet.data; + rec->header = (struct imessaging_header *)packet.data; rec->packet = packet; rec->retries = 0; if (msize != sizeof(*rec->header) + rec->header->length) { - DEBUG(0,("messaging: bad message header size %d should be %d\n", + DEBUG(0,("messaging: bad message header size %d should be %d\n", rec->header->length, (int)(msize - sizeof(*rec->header)))); talloc_free(rec); return; } - messaging_dispatch(msg, rec); + imessaging_dispatch(msg, rec); talloc_free(rec); } @@ -359,16 +363,16 @@ static void messaging_recv_handler(struct messaging_context *msg) /* handle a socket event */ -static void messaging_handler(struct tevent_context *ev, struct tevent_fd *fde, +static void imessaging_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *private_data) { - struct messaging_context *msg = talloc_get_type(private_data, - struct messaging_context); - if (flags & EVENT_FD_WRITE) { - messaging_send_handler(msg); + struct imessaging_context *msg = talloc_get_type(private_data, + struct imessaging_context); + if (flags & TEVENT_FD_WRITE) { + imessaging_send_handler(msg); } - if (flags & EVENT_FD_READ) { - messaging_recv_handler(msg); + if (flags & TEVENT_FD_READ) { + imessaging_recv_handler(msg); } } @@ -376,7 +380,7 @@ static void messaging_handler(struct tevent_context *ev, struct tevent_fd *fde, /* Register a dispatch function for a particular message type. */ -NTSTATUS messaging_register(struct messaging_context *msg, void *private_data, +NTSTATUS imessaging_register(struct imessaging_context *msg, void *private_data, uint32_t msg_type, msg_callback_t fn) { struct dispatch_fn *d; @@ -409,7 +413,7 @@ NTSTATUS messaging_register(struct messaging_context *msg, void *private_data, register a temporary message handler. The msg_type is allocated above MSG_TMP_BASE */ -NTSTATUS messaging_register_tmp(struct messaging_context *msg, void *private_data, +NTSTATUS imessaging_register_tmp(struct imessaging_context *msg, void *private_data, msg_callback_t fn, uint32_t *msg_type) { struct dispatch_fn *d; @@ -435,12 +439,12 @@ NTSTATUS messaging_register_tmp(struct messaging_context *msg, void *private_dat /* De-register the function for a particular message type. */ -void messaging_deregister(struct messaging_context *msg, uint32_t msg_type, void *private_data) +void imessaging_deregister(struct imessaging_context *msg, uint32_t msg_type, void *private_data) { struct dispatch_fn *d, *next; if (msg_type >= msg->num_types) { - d = (struct dispatch_fn *)idr_find(msg->dispatch_tree, + d = (struct dispatch_fn *)idr_find(msg->dispatch_tree, msg_type); if (!d) return; idr_remove(msg->dispatch_tree, msg_type); @@ -460,14 +464,14 @@ void messaging_deregister(struct messaging_context *msg, uint32_t msg_type, void /* Send a message to a particular server */ -NTSTATUS messaging_send(struct messaging_context *msg, struct server_id server, +NTSTATUS imessaging_send(struct imessaging_context *msg, struct server_id server, uint32_t msg_type, const DATA_BLOB *data) { - struct messaging_rec *rec; + struct imessaging_rec *rec; NTSTATUS status; size_t dlength = data?data->length:0; - rec = talloc(msg, struct messaging_rec); + rec = talloc(msg, struct imessaging_rec); if (rec == NULL) { return NT_STATUS_NO_MEMORY; } @@ -480,16 +484,16 @@ NTSTATUS messaging_send(struct messaging_context *msg, struct server_id server, rec->retries = 0; rec->msg = msg; - rec->header = (struct messaging_header *)rec->packet.data; + rec->header = (struct imessaging_header *)rec->packet.data; /* zero padding */ ZERO_STRUCTP(rec->header); - rec->header->version = MESSAGING_VERSION; + rec->header->version = IMESSAGING_VERSION; rec->header->msg_type = msg_type; rec->header->from = msg->server_id; rec->header->to = server; rec->header->length = dlength; if (dlength != 0) { - memcpy(rec->packet.data + sizeof(*rec->header), + memcpy(rec->packet.data + sizeof(*rec->header), data->data, dlength); } @@ -501,7 +505,7 @@ NTSTATUS messaging_send(struct messaging_context *msg, struct server_id server, return status; } - rec->path = messaging_path(msg, server); + rec->path = imessaging_path(msg, server); talloc_steal(rec, rec->path); if (msg->pending != NULL) { @@ -512,9 +516,9 @@ NTSTATUS messaging_send(struct messaging_context *msg, struct server_id server, if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { if (msg->pending == NULL) { - EVENT_FD_WRITEABLE(msg->event.fde); + TEVENT_FD_WRITEABLE(msg->event.fde); } - DLIST_ADD_END(msg->pending, rec, struct messaging_rec *); + DLIST_ADD_END(msg->pending, rec, struct imessaging_rec *); return NT_STATUS_OK; } @@ -526,7 +530,7 @@ NTSTATUS messaging_send(struct messaging_context *msg, struct server_id server, /* Send a message to a particular server, with the message containing a single pointer */ -NTSTATUS messaging_send_ptr(struct messaging_context *msg, struct server_id server, +NTSTATUS imessaging_send_ptr(struct imessaging_context *msg, struct server_id server, uint32_t msg_type, void *ptr) { DATA_BLOB blob; @@ -534,15 +538,20 @@ NTSTATUS messaging_send_ptr(struct messaging_context *msg, struct server_id serv blob.data = (uint8_t *)&ptr; blob.length = sizeof(void *); - return messaging_send(msg, server, msg_type, &blob); + return imessaging_send(msg, server, msg_type, &blob); } /* - destroy the messaging context + remove our messaging socket and database entry */ -static int messaging_destructor(struct messaging_context *msg) +int imessaging_cleanup(struct imessaging_context *msg) { + if (!msg) { + return 0; + } + + DEBUG(5,("imessaging: cleaning up %s\n", msg->path)); unlink(msg->path); while (msg->names && msg->names[0]) { irpc_remove_name(msg, msg->names[0]); @@ -552,21 +561,28 @@ static int messaging_destructor(struct messaging_context *msg) /* create the listening socket and setup the dispatcher + + use temporary=true when you want a destructor to remove the + associated messaging socket and database entry on talloc free. Don't + use this in processes that may fork and a child may talloc free this + memory */ -struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, - const char *dir, - struct server_id server_id, - struct tevent_context *ev) +struct imessaging_context *imessaging_init(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, + struct server_id server_id, + struct tevent_context *ev, + bool auto_remove) { - struct messaging_context *msg; + struct imessaging_context *msg; NTSTATUS status; struct socket_address *path; + bool ok; if (ev == NULL) { return NULL; } - msg = talloc_zero(mem_ctx, struct messaging_context); + msg = talloc_zero(mem_ctx, struct imessaging_context); if (msg == NULL) { return NULL; } @@ -579,10 +595,22 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, } /* create the messaging directory if needed */ - mkdir(dir, 0700); - msg->base_path = talloc_reference(msg, dir); - msg->path = messaging_path(msg, server_id); + msg->lp_ctx = talloc_reference(msg, lp_ctx); + if (!msg->lp_ctx) { + talloc_free(msg); + return NULL; + } + + msg->base_path = lpcfg_imessaging_path(msg, lp_ctx); + + ok = directory_create_or_exist_strict(msg->base_path, geteuid(), 0700); + if (!ok) { + talloc_free(msg); + return NULL; + } + + msg->path = imessaging_path(msg, server_id); msg->server_id = server_id; msg->idr = idr_init(msg); msg->dispatch_tree = idr_init(msg); @@ -594,11 +622,11 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, return NULL; } - /* by stealing here we ensure that the socket is cleaned up (and even + /* by stealing here we ensure that the socket is cleaned up (and even deleted) on exit */ talloc_steal(msg, msg->sock); - path = socket_address_from_strings(msg, msg->sock->backend_name, + path = socket_address_from_strings(msg, msg->sock->backend_name, msg->path, 0); if (!path) { talloc_free(msg); @@ -616,30 +644,38 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, set_blocking(socket_get_fd(msg->sock), false); msg->event.ev = ev; - msg->event.fde = event_add_fd(ev, msg, socket_get_fd(msg->sock), - EVENT_FD_READ, messaging_handler, msg); + msg->event.fde = tevent_add_fd(ev, msg, socket_get_fd(msg->sock), + TEVENT_FD_READ, imessaging_handler, msg); tevent_fd_set_auto_close(msg->event.fde); - talloc_set_destructor(msg, messaging_destructor); - - messaging_register(msg, NULL, MSG_PING, ping_message); - messaging_register(msg, NULL, MSG_IRPC, irpc_handler); + if (auto_remove) { + talloc_set_destructor(msg, imessaging_cleanup); + } + + imessaging_register(msg, NULL, MSG_PING, ping_message); + imessaging_register(msg, NULL, MSG_IRPC, irpc_handler); IRPC_REGISTER(msg, irpc, IRPC_UPTIME, irpc_uptime, msg); return msg; } -/* - A hack, for the short term until we get 'client only' messaging in place +/* + A hack, for the short term until we get 'client only' messaging in place */ -struct messaging_context *messaging_client_init(TALLOC_CTX *mem_ctx, - const char *dir, +struct imessaging_context *imessaging_client_init(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, struct tevent_context *ev) { struct server_id id; ZERO_STRUCT(id); - id.id = random() % 0x10000000; - return messaging_init(mem_ctx, dir, id, ev); + id.pid = getpid(); + id.task_id = generate_random(); + id.vnn = NONCLUSTER_VNN; + + /* This is because we are not in the s3 serverid database */ + id.unique_id = SERVERID_UNIQUE_ID_NOT_TO_VERIFY; + + return imessaging_init(mem_ctx, lp_ctx, id, ev, true); } /* a list of registered irpc server functions @@ -657,8 +693,8 @@ struct irpc_list { /* register a irpc server function */ -NTSTATUS irpc_register(struct messaging_context *msg_ctx, - const struct ndr_interface_table *table, +NTSTATUS irpc_register(struct imessaging_context *msg_ctx, + const struct ndr_interface_table *table, int callnum, irpc_function_t fn, void *private_data) { struct irpc_list *irpc; @@ -688,7 +724,7 @@ NTSTATUS irpc_register(struct messaging_context *msg_ctx, /* handle an incoming irpc reply message */ -static void irpc_handler_reply(struct messaging_context *msg_ctx, struct irpc_message *m) +static void irpc_handler_reply(struct imessaging_context *msg_ctx, struct irpc_message *m) { struct irpc_request *irpc; @@ -734,7 +770,7 @@ NTSTATUS irpc_send_reply(struct irpc_message *m, NTSTATUS status) /* send the reply message */ packet = ndr_push_blob(push); - status = messaging_send(m->msg_ctx, m->from, MSG_IRPC, &packet); + status = imessaging_send(m->msg_ctx, m->from, MSG_IRPC, &packet); if (!NT_STATUS_IS_OK(status)) goto failed; failed: @@ -745,7 +781,7 @@ failed: /* handle an incoming irpc request message */ -static void irpc_handler_request(struct messaging_context *msg_ctx, +static void irpc_handler_request(struct imessaging_context *msg_ctx, struct irpc_message *m) { struct irpc_list *i; @@ -809,7 +845,7 @@ failed: /* handle an incoming irpc message */ -static void irpc_handler(struct messaging_context *msg_ctx, void *private_data, +static void irpc_handler(struct imessaging_context *msg_ctx, void *private_data, uint32_t msg_type, struct server_id src, DATA_BLOB *packet) { struct irpc_message *m; @@ -856,23 +892,26 @@ static int irpc_destructor(struct irpc_request *irpc) /* open the naming database */ -static struct tdb_wrap *irpc_namedb_open(struct messaging_context *msg_ctx) +static struct tdb_wrap *irpc_namedb_open(struct imessaging_context *msg_ctx) { struct tdb_wrap *t; char *path = talloc_asprintf(msg_ctx, "%s/names.tdb", msg_ctx->base_path); if (path == NULL) { return NULL; } - t = tdb_wrap_open(msg_ctx, path, 0, 0, O_RDWR|O_CREAT, 0660); + t = tdb_wrap_open(msg_ctx, path, + lpcfg_tdb_hash_size(msg_ctx->lp_ctx, path), + lpcfg_tdb_flags(msg_ctx->lp_ctx, 0), + O_RDWR|O_CREAT, 0660); talloc_free(path); return t; } - + /* add a string name that this irpc server can be called on */ -NTSTATUS irpc_add_name(struct messaging_context *msg_ctx, const char *name) +NTSTATUS irpc_add_name(struct imessaging_context *msg_ctx, const char *name) { struct tdb_wrap *t; TDB_DATA rec; @@ -912,7 +951,7 @@ NTSTATUS irpc_add_name(struct messaging_context *msg_ctx, const char *name) /* return a list of server ids for a server name */ -struct server_id *irpc_servers_byname(struct messaging_context *msg_ctx, +struct server_id *irpc_servers_byname(struct imessaging_context *msg_ctx, TALLOC_CTX *mem_ctx, const char *name) { @@ -946,7 +985,7 @@ struct server_id *irpc_servers_byname(struct messaging_context *msg_ctx, for (i=0;itdb, name); talloc_free(t); @@ -954,10 +993,81 @@ struct server_id *irpc_servers_byname(struct messaging_context *msg_ctx, return ret; } +static int all_servers_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) +{ + struct irpc_name_records *name_records = talloc_get_type(state, struct irpc_name_records); + struct irpc_name_record *name_record; + int i; + + name_records->names + = talloc_realloc(name_records, name_records->names, + struct irpc_name_record *, name_records->num_records+1); + if (!name_records->names) { + return -1; + } + + name_records->names[name_records->num_records] = name_record + = talloc(name_records->names, + struct irpc_name_record); + if (!name_record) { + return -1; + } + + name_records->num_records++; + + name_record->name + = talloc_strndup(name_record, + (const char *)key.dptr, key.dsize); + if (!name_record->name) { + return -1; + } + + name_record->count = data.dsize / sizeof(struct server_id); + name_record->ids = talloc_array(name_record, + struct server_id, + name_record->count); + if (name_record->ids == NULL) { + return -1; + } + for (i=0;icount;i++) { + name_record->ids[i] = ((struct server_id *)data.dptr)[i]; + } + return 0; +} + +/* + return a list of server ids for a server name +*/ +struct irpc_name_records *irpc_all_servers(struct imessaging_context *msg_ctx, + TALLOC_CTX *mem_ctx) +{ + struct tdb_wrap *t; + int ret; + struct irpc_name_records *name_records = talloc_zero(mem_ctx, struct irpc_name_records); + if (name_records == NULL) { + return NULL; + } + + t = irpc_namedb_open(msg_ctx); + if (t == NULL) { + return NULL; + } + + ret = tdb_traverse_read(t->tdb, all_servers_func, name_records); + if (ret == -1) { + talloc_free(t); + return NULL; + } + + talloc_free(t); + + return name_records; +} + /* remove a name from a messaging context */ -void irpc_remove_name(struct messaging_context *msg_ctx, const char *name) +void irpc_remove_name(struct imessaging_context *msg_ctx, const char *name) { struct tdb_wrap *t; TDB_DATA rec; @@ -992,7 +1102,7 @@ void irpc_remove_name(struct messaging_context *msg_ctx, const char *name) for (i=0;iserver_id)) { if (i < count-1) { - memmove(ids+i, ids+i+1, + memmove(ids+i, ids+i+1, sizeof(struct server_id) * (count-(i+1))); } rec.dsize -= sizeof(struct server_id); @@ -1005,13 +1115,13 @@ void irpc_remove_name(struct messaging_context *msg_ctx, const char *name) talloc_free(t); } -struct server_id messaging_get_server_id(struct messaging_context *msg_ctx) +struct server_id imessaging_get_server_id(struct imessaging_context *msg_ctx) { return msg_ctx->server_id; } struct irpc_bh_state { - struct messaging_context *msg_ctx; + struct imessaging_context *msg_ctx; struct server_id server_id; const struct ndr_interface_table *table; uint32_t timeout; @@ -1084,7 +1194,7 @@ static struct tevent_req *irpc_bh_raw_call_send(TALLOC_CTX *mem_ctx, ok = irpc_bh_is_connected(h); if (!ok) { - tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION); + tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED); return tevent_req_post(req, ev); } @@ -1137,7 +1247,7 @@ static struct tevent_req *irpc_bh_raw_call_send(TALLOC_CTX *mem_ctx, /* and send it */ state->in_packet = ndr_push_blob(ndr); - status = messaging_send(hs->msg_ctx, hs->server_id, + status = imessaging_send(hs->msg_ctx, hs->server_id, MSG_IRPC, &state->in_packet); if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(req, status); @@ -1176,7 +1286,7 @@ static void irpc_bh_raw_call_incoming_handler(struct irpc_request *irpc, m->ndr->data + m->ndr->offset, m->ndr->data_size - m->ndr->offset); if ((m->ndr->data_size - m->ndr->offset) > 0 && !state->out_data.data) { - tevent_req_nomem(NULL, req); + tevent_req_oom(req); return; } @@ -1228,7 +1338,7 @@ static struct tevent_req *irpc_bh_disconnect_send(TALLOC_CTX *mem_ctx, ok = irpc_bh_is_connected(h); if (!ok) { - tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION); + tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED); return tevent_req_post(req, ev); } @@ -1270,7 +1380,7 @@ static const struct dcerpc_binding_handle_ops irpc_bh_ops = { /* initialise a irpc binding handle */ struct dcerpc_binding_handle *irpc_binding_handle(TALLOC_CTX *mem_ctx, - struct messaging_context *msg_ctx, + struct imessaging_context *msg_ctx, struct server_id server_id, const struct ndr_interface_table *table) { @@ -1298,7 +1408,7 @@ struct dcerpc_binding_handle *irpc_binding_handle(TALLOC_CTX *mem_ctx, } struct dcerpc_binding_handle *irpc_binding_handle_by_name(TALLOC_CTX *mem_ctx, - struct messaging_context *msg_ctx, + struct imessaging_context *msg_ctx, const char *dest_task, const struct ndr_interface_table *table) { @@ -1312,7 +1422,7 @@ struct dcerpc_binding_handle *irpc_binding_handle_by_name(TALLOC_CTX *mem_ctx, errno = EADDRNOTAVAIL; return NULL; } - if (sids[0].id == 0) { + if (server_id_is_disconnected(&sids[0])) { talloc_free(sids); errno = EADDRNOTAVAIL; return NULL;