}
}
- status = dcesrv_setup_ncacn_ip_tcp_sockets(ev_ctx,
- msg_ctx,
- &ndr_table_epmapper,
- NULL,
- 135);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("Failed to open epmd tcpip sockets!\n"));
- exit(1);
- }
-
status = dcesrv_setup_ncalrpc_socket(ev_ctx,
msg_ctx,
"EPMAPPER",
struct tevent_context *ev_ctx;
struct messaging_context *msg_ctx;
+ struct dcesrv_context *dce_ctx;
+ struct dcesrv_endpoint *endpoint;
dcerpc_ncacn_termination_fn termination_fn;
void *termination_data;
};
NTSTATUS dcesrv_setup_ncacn_ip_tcp_socket(struct tevent_context *ev_ctx,
struct messaging_context *msg_ctx,
+ struct dcesrv_context *dce_ctx,
+ struct dcesrv_endpoint *e,
const struct sockaddr_storage *ifss,
- uint16_t *port)
+ dcerpc_ncacn_termination_fn term_fn,
+ void *term_data)
{
- struct dcerpc_ncacn_listen_state *state;
- struct tevent_fd *fde;
+ struct dcerpc_ncacn_listen_state *state = NULL;
+ struct tevent_fd *fde = NULL;
+ const char *endpoint = NULL;
+ uint16_t port = 0;
+ char port_str[6];
int rc;
NTSTATUS status;
- state = talloc_zero(ev_ctx, struct dcerpc_ncacn_listen_state);
+ endpoint = dcerpc_binding_get_string_option(e->ep_description,
+ "endpoint");
+ if (endpoint != NULL) {
+ port = atoi(endpoint);
+ }
+
+ /* Alloc in endpoint context. If the endpoint is freed (for example
+ * when forked daemons reinit the dcesrv_context, the tevent_fd
+ * listener will be stopped and the socket closed */
+ state = talloc_zero(e, struct dcerpc_ncacn_listen_state);
if (state == NULL) {
DBG_ERR("Out of memory\n");
return NT_STATUS_NO_MEMORY;
}
state->fd = -1;
- state->ep.port = *port;
+ state->ev_ctx = ev_ctx;
+ state->msg_ctx = msg_ctx;
+ state->endpoint = e;
+ state->dce_ctx = talloc_reference(state, dce_ctx);
+ state->termination_fn = term_fn;
+ state->termination_data = term_data;
- status = dcesrv_create_ncacn_ip_tcp_socket(ifss, &state->ep.port,
- &state->fd);
+ status = dcesrv_create_ncacn_ip_tcp_socket(ifss, &port, &state->fd);
if (!NT_STATUS_IS_OK(status)) {
goto out;
}
- state->ev_ctx = ev_ctx;
- state->msg_ctx = msg_ctx;
-
/* ready to listen */
set_socket_options(state->fd, "SO_KEEPALIVE");
set_socket_options(state->fd, lp_socket_options());
}
DBG_DEBUG("Opened socket fd %d for port %u\n",
- state->fd, state->ep.port);
+ state->fd, port);
errno = 0;
fde = tevent_add_fd(state->ev_ctx,
tevent_fd_set_auto_close(fde);
- *port = state->ep.port;
+ /* Set the port in the endpoint */
+ snprintf(port_str, sizeof(port_str), "%u", port);
+
+ status = dcerpc_binding_set_string_option(e->ep_description,
+ "endpoint", port_str);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("Failed to set binding endpoint '%s': %s\n",
+ port_str, nt_errstr(status));
+ goto out;
+ }
return NT_STATUS_OK;
int *out_fd);
NTSTATUS dcesrv_setup_ncacn_ip_tcp_socket(struct tevent_context *ev_ctx,
struct messaging_context *msg_ctx,
+ struct dcesrv_context *dce_ctx,
+ struct dcesrv_endpoint *e,
const struct sockaddr_storage *ifss,
- uint16_t *port);
+ dcerpc_ncacn_termination_fn term_fn,
+ void *term_data);
NTSTATUS dcesrv_create_ncalrpc_socket(const char *name, int *out_fd);
NTSTATUS dcesrv_setup_ncalrpc_socket(struct tevent_context *ev_ctx,
break;
case NCACN_IP_TCP:
- /* TODO */
- status = NT_STATUS_OK;
+ status = dcesrv_setup_ncacn_ip_tcp_sockets(ev_ctx,
+ msg_ctx,
+ dce_ctx,
+ e,
+ bvec,
+ term_fn,
+ term_data);
break;
case NCACN_NP:
#include "rpc_server/rpc_server.h"
#include "rpc_server/rpc_sock_helper.h"
#include "lib/server_prefork.h"
+#include "librpc/ndr/ndr_table.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
}
NTSTATUS dcesrv_setup_ncacn_ip_tcp_sockets(struct tevent_context *ev_ctx,
- struct messaging_context *msg_ctx,
- const struct ndr_interface_table *iface,
- struct dcerpc_binding_vector *bvec,
- uint16_t port)
+ struct messaging_context *msg_ctx,
+ struct dcesrv_context *dce_ctx,
+ struct dcesrv_endpoint *e,
+ struct dcerpc_binding_vector *bvec,
+ dcerpc_ncacn_termination_fn t_fn,
+ void *t_data)
{
- uint32_t num_ifs = iface_count();
- uint32_t i;
- uint16_t p = port;
TALLOC_CTX *tmp_ctx;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS status;
int rc;
tmp_ctx = talloc_stackframe();
}
if (lp_interfaces() && lp_bind_interfaces_only()) {
+ uint32_t num_ifs = iface_count();
+ uint32_t i;
+
/*
* We have been given an interfaces line, and been told to only
* bind to those interfaces. Create a socket per interface and
iface_n_sockaddr_storage(i);
struct tsocket_address *bind_addr;
const char *addr;
+ const char *endpoint;
+ uint16_t port = 0;
status = dcesrv_setup_ncacn_ip_tcp_socket(ev_ctx,
msg_ctx,
+ dce_ctx,
+ e,
ifss,
- &p);
+ t_fn,
+ t_data);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
if (bvec != NULL) {
+ struct dcesrv_if_list *if_list = NULL;
+
rc = tsocket_address_bsd_from_sockaddr(tmp_ctx,
(const struct sockaddr*)ifss,
sizeof(struct sockaddr_storage),
goto done;
}
- status = dcerpc_binding_vector_add_port(iface,
- bvec,
- addr,
- p);
- if (!NT_STATUS_IS_OK(status)) {
- goto done;
+ endpoint = dcerpc_binding_get_string_option(e->ep_description,
+ "endpoint");
+ if (endpoint != NULL) {
+ port = atoi(endpoint);
+ }
+
+ for (if_list = e->interface_list; if_list; if_list = if_list->next) {
+ const struct ndr_interface_table *iface = NULL;
+ iface = ndr_table_by_syntax(&if_list->iface->syntax_id);
+ if (iface != NULL) {
+ status = dcerpc_binding_vector_add_port(iface,
+ bvec,
+ addr,
+ port);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+ }
}
}
}
status = dcesrv_setup_ncacn_ip_tcp_socket(ev_ctx,
msg_ctx,
+ dce_ctx,
+ e,
&ss,
- &p);
+ t_fn,
+ t_data);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
if (bvec != NULL) {
- status = dcerpc_binding_vector_add_port(iface,
- bvec,
- sock_tok,
- p);
- if (!NT_STATUS_IS_OK(status)) {
- goto done;
+ struct dcesrv_if_list *if_list = NULL;
+ const char *endpoint;
+ uint16_t port = 0;
+
+ endpoint = dcerpc_binding_get_string_option(e->ep_description,
+ "endpoint");
+ if (endpoint != NULL) {
+ port = atoi(endpoint);
+ }
+
+ for (if_list = e->interface_list; if_list; if_list = if_list->next) {
+ const struct ndr_interface_table *iface = NULL;
+ iface = ndr_table_by_syntax(&if_list->iface->syntax_id);
+ if (iface != NULL) {
+ status = dcerpc_binding_vector_add_port(iface,
+ bvec,
+ sock_tok,
+ port);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+ }
}
}
}
#ifndef _RPC_SOCK_HELPER_H_
#define _RPC_SOCK_HELPER_H_
+#include "rpc_server.h"
+
struct pf_listen_fd;
NTSTATUS dcesrv_create_ncacn_ip_tcp_sockets(
int *listen_fd_size);
NTSTATUS dcesrv_setup_ncacn_ip_tcp_sockets(struct tevent_context *ev_ctx,
- struct messaging_context *msg_ctx,
- const struct ndr_interface_table *iface,
- struct dcerpc_binding_vector *bvec,
- uint16_t port);
+ struct messaging_context *msg_ctx,
+ struct dcesrv_context *dce_ctx,
+ struct dcesrv_endpoint *e,
+ struct dcerpc_binding_vector *bvec,
+ dcerpc_ncacn_termination_fn t_fn,
+ void *t_data);
#endif /* _RPC_SOCK_HELPER_H_ */