summaryrefslogtreecommitdiff
path: root/source4/lib/messaging
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/messaging')
-rw-r--r--source4/lib/messaging/irpc.h5
-rw-r--r--source4/lib/messaging/messaging.c123
2 files changed, 126 insertions, 2 deletions
diff --git a/source4/lib/messaging/irpc.h b/source4/lib/messaging/irpc.h
index 0482e9a957..4fb1acfedb 100644
--- a/source4/lib/messaging/irpc.h
+++ b/source4/lib/messaging/irpc.h
@@ -86,7 +86,6 @@ void messaging_deregister(struct messaging_context *msg, uint32_t msg_type, void
NTSTATUS irpc_register(struct messaging_context *msg_ctx,
const struct dcerpc_interface_table *table,
int call, irpc_function_t fn, void *private);
-NTSTATUS irpc_add_name(struct messaging_context *msg_ctx, const char *name);
struct irpc_request *irpc_call_send(struct messaging_context *msg_ctx,
uint32_t server_id,
const struct dcerpc_interface_table *table,
@@ -97,3 +96,7 @@ NTSTATUS irpc_call(struct messaging_context *msg_ctx,
const struct dcerpc_interface_table *table,
int callnum, void *r);
+NTSTATUS irpc_add_name(struct messaging_context *msg_ctx, const char *name);
+uint32_t *irpc_servers_byname(struct messaging_context *msg_ctx, const char *name);
+void irpc_remove_name(struct messaging_context *msg_ctx, const char *name);
+
diff --git a/source4/lib/messaging/messaging.c b/source4/lib/messaging/messaging.c
index 9bf5071e90..8345c79c77 100644
--- a/source4/lib/messaging/messaging.c
+++ b/source4/lib/messaging/messaging.c
@@ -30,6 +30,9 @@
#include "lib/socket/socket.h"
#include "librpc/gen_ndr/ndr_irpc.h"
#include "lib/messaging/irpc.h"
+#include "db_wrap.h"
+#include "lib/tdb/include/tdb.h"
+#include "lib/tdb/include/tdbutil.h"
/* change the message version with any incompatible changes in the protocol */
#define MESSAGING_VERSION 1
@@ -43,6 +46,7 @@ struct messaging_context {
struct messaging_rec *pending;
struct irpc_list *irpc;
struct idr_context *idr;
+ const char **names;
struct {
struct event_context *ev;
@@ -350,6 +354,9 @@ static int messaging_destructor(void *ptr)
{
struct messaging_context *msg = ptr;
unlink(msg->path);
+ while (msg->names && msg->names[0]) {
+ irpc_remove_name(msg, msg->names[0]);
+ }
return 0;
}
@@ -380,6 +387,7 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, uint32_t server_id
msg->pending = NULL;
msg->idr = idr_init(msg);
msg->irpc = NULL;
+ msg->names = NULL;
status = socket_create("unix", SOCKET_TYPE_DGRAM, &msg->sock, 0);
if (!NT_STATUS_IS_OK(status)) {
@@ -692,11 +700,124 @@ NTSTATUS irpc_call(struct messaging_context *msg_ctx,
}
/*
+ open the naming database
+*/
+static struct tdb_wrap *irpc_namedb_open(struct messaging_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);
+ 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)
{
- return NT_STATUS_OK;
+ struct tdb_wrap *t;
+ TDB_DATA rec;
+ int count;
+ NTSTATUS status = NT_STATUS_OK;
+
+ t = irpc_namedb_open(msg_ctx);
+ NT_STATUS_HAVE_NO_MEMORY(t);
+
+ rec = tdb_fetch_bystring(t->tdb, name);
+ count = rec.dsize / sizeof(uint32_t);
+ rec.dptr = (char *)realloc_p(rec.dptr, uint32_t, count+1);
+ rec.dsize += sizeof(uint32_t);
+ if (rec.dptr == NULL) {
+ talloc_free(t);
+ return NT_STATUS_NO_MEMORY;
+ }
+ ((uint32_t *)rec.dptr)[count] = msg_ctx->server_id;
+ if (tdb_store_bystring(t->tdb, name, rec, 0) != 0) {
+ status = NT_STATUS_INTERNAL_ERROR;
+ }
+ free(rec.dptr);
+ talloc_free(t);
+
+ msg_ctx->names = str_list_add(msg_ctx->names, name);
+ talloc_steal(msg_ctx, msg_ctx->names);
+
+ return status;
}
+/*
+ return a list of server ids for a server name
+*/
+uint32_t *irpc_servers_byname(struct messaging_context *msg_ctx, const char *name)
+{
+ struct tdb_wrap *t;
+ TDB_DATA rec;
+ int count, i;
+ uint32_t *ret;
+
+ t = irpc_namedb_open(msg_ctx);
+ if (t == NULL) {
+ return NULL;
+ }
+ rec = tdb_fetch_bystring(t->tdb, name);
+ if (rec.dptr == NULL) {
+ talloc_free(t);
+ return NULL;
+ }
+ count = rec.dsize / sizeof(uint32_t);
+ ret = talloc_array(msg_ctx, uint32_t, count);
+ if (ret == NULL) {
+ talloc_free(t);
+ return NULL;
+ }
+ for (i=0;i<count;i++) {
+ ret[i] = ((uint32_t *)rec.dptr)[i];
+ }
+ free(rec.dptr);
+ talloc_free(t);
+
+ return ret;
+}
+
+/*
+ remove a name from a messaging context
+*/
+void irpc_remove_name(struct messaging_context *msg_ctx, const char *name)
+{
+ struct tdb_wrap *t;
+ TDB_DATA rec;
+ int count, i;
+ uint32_t *ids;
+
+ str_list_remove(msg_ctx->names, name);
+
+ t = irpc_namedb_open(msg_ctx);
+ if (t == NULL) {
+ return;
+ }
+
+ rec = tdb_fetch_bystring(t->tdb, name);
+ count = rec.dsize / sizeof(uint32_t);
+ if (count == 0) {
+ talloc_free(t);
+ return;
+ }
+ ids = (uint32_t *)rec.dptr;
+ for (i=0;i<count;i++) {
+ if (ids[i] == msg_ctx->server_id) {
+ if (i < count-1) {
+ memmove(ids+i, ids+i+1, count-(i+1));
+ }
+ rec.dsize -= sizeof(uint32_t);
+ break;
+ }
+ }
+ tdb_store_bystring(t->tdb, name, rec, 0);
+ free(rec.dptr);
+ talloc_free(t);
+}