/*
* Endpoint Mapper Functions
* DCERPC local endpoint mapper client routines
- * Copyright (c) 2010 Andreas Schneider.
+ * Copyright (c) 2010-2011 Andreas Schneider.
*
* 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
#include "../librpc/gen_ndr/ndr_epmapper_c.h"
#include "rpc_client/cli_pipe.h"
#include "auth.h"
+#include "rpc_server/rpc_ncacn_np.h"
+#include "../lib/tsocket/tsocket.h"
#define EPM_MAX_ANNOTATION_SIZE 64
+static bool binding_vector_realloc(struct dcerpc_binding_vector *bvec)
+{
+ if (bvec->count >= bvec->allocated) {
+ struct dcerpc_binding *tmp;
+
+ tmp = talloc_realloc(bvec,
+ bvec->bindings,
+ struct dcerpc_binding,
+ bvec->allocated * 2);
+ if (tmp == NULL) {
+ return false;
+ }
+ bvec->bindings = tmp;
+ bvec->allocated = bvec->allocated * 2;
+ }
+
+ return true;
+}
+
+NTSTATUS dcerpc_binding_vector_new(TALLOC_CTX *mem_ctx,
+ struct dcerpc_binding_vector **pbvec)
+{
+ struct dcerpc_binding_vector *bvec;
+ NTSTATUS status;
+ TALLOC_CTX *tmp_ctx;
+
+ tmp_ctx = talloc_stackframe();
+ if (tmp_ctx == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ bvec = talloc_zero(tmp_ctx, struct dcerpc_binding_vector);
+ if (bvec == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ bvec->bindings = talloc_zero_array(bvec,
+ struct dcerpc_binding,
+ 4);
+ if (bvec->bindings == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ bvec->allocated = 4;
+ bvec->count = 0;
+
+ *pbvec = talloc_move(mem_ctx, &bvec);
+
+ status = NT_STATUS_OK;
+done:
+ talloc_free(tmp_ctx);
+
+ return status;
+}
+
+NTSTATUS dcerpc_binding_vector_add_np_default(const struct ndr_interface_table *iface,
+ struct dcerpc_binding_vector *bvec)
+{
+ uint32_t ep_count = iface->endpoints->count;
+ uint32_t i;
+ NTSTATUS status;
+ bool ok;
+
+ for (i = 0; i < ep_count; i++) {
+ struct dcerpc_binding *b;
+
+ b = talloc_zero(bvec->bindings, struct dcerpc_binding);
+ if (b == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = dcerpc_parse_binding(b, iface->endpoints->names[i], &b);
+ if (!NT_STATUS_IS_OK(status)) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* Only add the named pipes defined in the iface endpoints */
+ if (b->transport != NCACN_NP) {
+ talloc_free(b);
+ continue;
+ }
+
+ b->object = iface->syntax_id;
+
+ b->host = talloc_asprintf(b, "\\\\%s", lp_netbios_name());
+ if (b->host == NULL) {
+ talloc_free(b);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ ok = binding_vector_realloc(bvec);
+ if (!ok) {
+ talloc_free(b);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ bvec->bindings[bvec->count] = *b;
+ bvec->count++;
+ }
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS dcerpc_binding_vector_add_port(const struct ndr_interface_table *iface,
+ struct dcerpc_binding_vector *bvec,
+ const char *host,
+ uint16_t port)
+{
+ uint32_t ep_count = iface->endpoints->count;
+ uint32_t i;
+ NTSTATUS status;
+ bool ok;
+
+ for (i = 0; i < ep_count; i++) {
+ struct dcerpc_binding *b;
+
+ b = talloc_zero(bvec->bindings, struct dcerpc_binding);
+ if (b == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = dcerpc_parse_binding(b, iface->endpoints->names[i], &b);
+ if (!NT_STATUS_IS_OK(status)) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (b->transport != NCACN_IP_TCP) {
+ talloc_free(b);
+ continue;
+ }
+
+ b->object = iface->syntax_id;
+
+ b->host = talloc_strdup(b, host);
+ if (b->host == NULL) {
+ talloc_free(b);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ b->endpoint = talloc_asprintf(b, "%u", port);
+ if (b->endpoint == NULL) {
+ talloc_free(b);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ ok = binding_vector_realloc(bvec);
+ if (!ok) {
+ talloc_free(b);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ bvec->bindings[bvec->count] = *b;
+ bvec->count++;
+
+ break;
+ }
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS dcerpc_binding_vector_add_unix(const struct ndr_interface_table *iface,
+ struct dcerpc_binding_vector *bvec,
+ const char *name)
+{
+ uint32_t ep_count = iface->endpoints->count;
+ uint32_t i;
+ NTSTATUS status;
+ bool ok;
+
+ for (i = 0; i < ep_count; i++) {
+ struct dcerpc_binding *b;
+
+ b = talloc_zero(bvec->bindings, struct dcerpc_binding);
+ if (b == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = dcerpc_parse_binding(b, iface->endpoints->names[i], &b);
+ if (!NT_STATUS_IS_OK(status)) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (b->transport != NCALRPC) {
+ talloc_free(b);
+ continue;
+ }
+
+ b->object = iface->syntax_id;
+
+ b->endpoint = talloc_asprintf(b,
+ "%s/%s",
+ lp_ncalrpc_dir(),
+ name);
+ if (b->endpoint == NULL) {
+ talloc_free(b);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ ok = binding_vector_realloc(bvec);
+ if (!ok) {
+ talloc_free(b);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ bvec->bindings[bvec->count] = *b;
+ bvec->count++;
+
+ break;
+ }
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS dcerpc_binding_vector_replace_iface(const struct ndr_interface_table *iface,
+ struct dcerpc_binding_vector *v)
+{
+ uint32_t i;
+
+ for (i = 0; i < v->count; i++) {
+ struct dcerpc_binding *b;
+
+ b = &(v->bindings[i]);
+ b->object = iface->syntax_id;
+ }
+
+ return NT_STATUS_OK;
+}
+
+struct dcerpc_binding_vector *dcerpc_binding_vector_dup(TALLOC_CTX *mem_ctx,
+ const struct dcerpc_binding_vector *bvec)
+{
+ struct dcerpc_binding_vector *v;
+ uint32_t i;
+
+ v = talloc(mem_ctx, struct dcerpc_binding_vector);
+ if (v == NULL) {
+ return NULL;
+ }
+
+ v->bindings = talloc_array(v, struct dcerpc_binding, bvec->allocated);
+ if (v->bindings == NULL) {
+ talloc_free(v);
+ return NULL;
+ }
+ v->allocated = bvec->allocated;
+
+ for (i = 0; i < bvec->count; i++) {
+ struct dcerpc_binding *b;
+
+ b = dcerpc_binding_dup(v->bindings, &bvec->bindings[i]);
+ if (b == NULL) {
+ talloc_free(v);
+ return NULL;
+ }
+ v->bindings[i] = *b;
+ }
+ v->count = bvec->count;
+
+ return v;
+}
+
NTSTATUS dcerpc_binding_vector_create(TALLOC_CTX *mem_ctx,
const struct ndr_interface_table *iface,
uint16_t port,
switch (b->transport) {
case NCACN_NP:
- b->host = talloc_asprintf(b, "\\\\%s", global_myname());
+ b->host = talloc_asprintf(b, "\\\\%s", lp_netbios_name());
if (b->host == NULL) {
status = NT_STATUS_NO_MEMORY;
goto done;
}
static NTSTATUS ep_register(TALLOC_CTX *mem_ctx,
+ struct messaging_context *msg_ctx,
const struct ndr_interface_table *iface,
const struct dcerpc_binding_vector *bind_vec,
const struct GUID *object_guid,
"rpc_server", "epmapper",
"none");
- if (StrCaseCmp(rpcsrv_type, "embedded") == 0) {
- static struct client_address client_id;
-
- strlcpy(client_id.addr, "localhost", sizeof(client_id.addr));
- client_id.name = "localhost";
+ if (strcasecmp_m(rpcsrv_type, "embedded") == 0) {
+ struct tsocket_address *local;
+ int rc;
+
+ rc = tsocket_address_inet_from_strings(tmp_ctx,
+ "ip",
+ "127.0.0.1",
+ 0,
+ &local);
+ if (rc < 0) {
+ return NT_STATUS_NO_MEMORY;
+ }
status = rpcint_binding_handle(tmp_ctx,
&ndr_table_epmapper,
- &client_id,
+ local,
get_session_info_system(),
- server_messaging_context(),
+ msg_ctx,
&h);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("dcerpc_ep_register: Could not connect to "
"epmapper (%s)", nt_errstr(status)));
goto done;
}
- } else if (StrCaseCmp(rpcsrv_type, "daemon") == 0) {
+ } else if (strcasecmp_m(rpcsrv_type, "daemon") == 0) {
/* Connect to the endpoint mapper locally */
ncalrpc_sock = talloc_asprintf(tmp_ctx,
"%s/%s",
}
NTSTATUS dcerpc_ep_register(TALLOC_CTX *mem_ctx,
+ struct messaging_context *msg_ctx,
const struct ndr_interface_table *iface,
const struct dcerpc_binding_vector *bind_vec,
const struct GUID *object_guid,
struct dcerpc_binding_handle **ph)
{
return ep_register(mem_ctx,
+ msg_ctx,
iface,
bind_vec,
object_guid,
}
NTSTATUS dcerpc_ep_register_noreplace(TALLOC_CTX *mem_ctx,
+ struct messaging_context *msg_ctx,
const struct ndr_interface_table *iface,
const struct dcerpc_binding_vector *bind_vec,
const struct GUID *object_guid,
struct dcerpc_binding_handle **ph)
{
return ep_register(mem_ctx,
+ msg_ctx,
iface,
bind_vec,
object_guid,
ph);
}
-NTSTATUS dcerpc_ep_unregister(const struct ndr_interface_table *iface,
+NTSTATUS dcerpc_ep_unregister(struct messaging_context *msg_ctx,
+ const struct ndr_interface_table *iface,
const struct dcerpc_binding_vector *bind_vec,
const struct GUID *object_guid)
{
return ep_register(NULL,
+ msg_ctx,
iface,
bind_vec,
object_guid,