#include "librpc/rpc/dcerpc_ep.h"
#include "../librpc/gen_ndr/ndr_epmapper_c.h"
#include "rpc_client/cli_pipe.h"
+#include "auth.h"
+#include "rpc_server/rpc_ncacn_np.h"
#define EPM_MAX_ANNOTATION_SIZE 64
NTSTATUS dcerpc_binding_vector_create(TALLOC_CTX *mem_ctx,
const struct ndr_interface_table *iface,
uint16_t port,
+ const char *ncalrpc,
struct dcerpc_binding_vector **pbvec)
{
struct dcerpc_binding_vector *bvec;
goto done;
}
- bvec->bindings = talloc_array(bvec, struct dcerpc_binding, ep_count);
+ bvec->bindings = talloc_zero_array(bvec, struct dcerpc_binding, ep_count);
if (bvec->bindings == NULL) {
status = NT_STATUS_NO_MEMORY;
goto done;
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;
break;
case NCACN_IP_TCP:
if (port == 0) {
+ talloc_free(b);
continue;
}
break;
case NCALRPC:
- /* TODO */
+ if (ncalrpc == NULL) {
+ talloc_free(b);
+ continue;
+ }
+
+ b->endpoint = talloc_asprintf(b,
+ "%s/%s",
+ lp_ncalrpc_dir(),
+ ncalrpc);
+ if (b->endpoint == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+ break;
default:
+ talloc_free(b);
continue;
}
return status;
}
-static NTSTATUS ep_register(const struct ndr_interface_table *iface,
+static NTSTATUS ep_register(TALLOC_CTX *mem_ctx,
+ const struct ndr_interface_table *iface,
const struct dcerpc_binding_vector *bind_vec,
const struct GUID *object_guid,
const char *annotation,
uint32_t replace,
- uint32_t unregister)
+ uint32_t unregister,
+ struct dcerpc_binding_handle **pbh)
{
- struct dcerpc_binding_handle *h = NULL;
- static struct client_address client_id;
+ struct rpc_pipe_client *cli = NULL;
+ struct dcerpc_binding_handle *h;
+ struct pipe_auth_data *auth;
+ const char *ncalrpc_sock;
+ const char *rpcsrv_type;
struct epm_entry_t *entries;
uint32_t num_ents, i;
TALLOC_CTX *tmp_ctx;
return NT_STATUS_NO_MEMORY;
}
-#if 0
- /* NOTE: Samba3 doesn't have a ncalrpc server component yet. As soon as
- * this is supported, we should talk to the endpoint mapper over the
- * local transport.
- */
-
- /* Connect to the endpoint mapper locally */
- ncalrpc_sock = talloc_asprintf(tmp_ctx,
- "%s/%s",
- get_dyn_NCALRPCDIR(),
- "epmapper");
- if (ncalrpc_sock == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
+ rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
+ "rpc_server", "epmapper",
+ "none");
- status = rpc_pipe_open_ncalrpc(tmp_ctx,
- ncalrpc_sock,
- &ndr_table_epmapper.syntax_id,
- &cli);
- if (!NT_STATUS_IS_OK(status)) {
- goto done;
- }
-#endif
+ if (strcasecmp_m(rpcsrv_type, "embedded") == 0) {
+ static struct client_address client_id;
- strlcpy(client_id.addr, "localhost", sizeof(client_id.addr));
- client_id.name = "localhost";
+ strlcpy(client_id.addr, "localhost", sizeof(client_id.addr));
+ client_id.name = "localhost";
- status = rpcint_binding_handle(tmp_ctx,
- &ndr_table_epmapper,
- &client_id,
- get_session_info_system(),
- server_messaging_context(),
- &h);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("dcerpc_ep_register: Could not connect to epmapper (%s)",
- nt_errstr(status)));
+ status = rpcint_binding_handle(tmp_ctx,
+ &ndr_table_epmapper,
+ &client_id,
+ get_session_info_system(),
+ server_messaging_context(),
+ &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_m(rpcsrv_type, "daemon") == 0) {
+ /* Connect to the endpoint mapper locally */
+ ncalrpc_sock = talloc_asprintf(tmp_ctx,
+ "%s/%s",
+ lp_ncalrpc_dir(),
+ "EPMAPPER");
+ if (ncalrpc_sock == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ status = rpc_pipe_open_ncalrpc(tmp_ctx,
+ ncalrpc_sock,
+ &ndr_table_epmapper.syntax_id,
+ &cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ status = rpccli_ncalrpc_bind_data(cli, &auth);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to initialize anonymous bind.\n"));
+ goto done;
+ }
+
+ status = rpc_pipe_bind(cli, auth);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(2, ("Failed to bind ncalrpc socket.\n"));
+ goto done;
+ }
+
+ h = cli->binding_handle;
+ } else {
+ status = NT_STATUS_INVALID_PARAMETER;
goto done;
}
goto done;
}
+ if (pbh != NULL) {
+ *pbh = talloc_move(mem_ctx, &h);
+ talloc_steal(*pbh, cli);
+ }
+
done:
talloc_free(tmp_ctx);
return status;
}
-NTSTATUS dcerpc_ep_register(const struct ndr_interface_table *iface,
+NTSTATUS dcerpc_ep_register(TALLOC_CTX *mem_ctx,
+ const struct ndr_interface_table *iface,
const struct dcerpc_binding_vector *bind_vec,
const struct GUID *object_guid,
- const char *annotation)
+ const char *annotation,
+ struct dcerpc_binding_handle **ph)
{
- return ep_register(iface, bind_vec, object_guid, annotation, 1, 0);
+ return ep_register(mem_ctx,
+ iface,
+ bind_vec,
+ object_guid,
+ annotation,
+ 1,
+ 0,
+ ph);
}
-NTSTATUS dcerpc_ep_register_noreplace(const struct ndr_interface_table *iface,
+NTSTATUS dcerpc_ep_register_noreplace(TALLOC_CTX *mem_ctx,
+ const struct ndr_interface_table *iface,
const struct dcerpc_binding_vector *bind_vec,
const struct GUID *object_guid,
- const char *annotation)
+ const char *annotation,
+ struct dcerpc_binding_handle **ph)
{
- return ep_register(iface, bind_vec, object_guid, annotation, 0, 0);
+ return ep_register(mem_ctx,
+ iface,
+ bind_vec,
+ object_guid,
+ annotation,
+ 0,
+ 0,
+ ph);
}
NTSTATUS dcerpc_ep_unregister(const struct ndr_interface_table *iface,
const struct dcerpc_binding_vector *bind_vec,
const struct GUID *object_guid)
{
- return ep_register(iface, bind_vec, object_guid, NULL, 0, 1);
+ return ep_register(NULL,
+ iface,
+ bind_vec,
+ object_guid,
+ NULL,
+ 0,
+ 1,
+ NULL);
}
/* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */