mirror of
https://github.com/samba-team/samba.git
synced 2025-08-26 01:49:31 +03:00
s3:rpc_server: Setup ncacn_ip_tcp sockets through endpoint init
The listener is created in the endpoint memory context. If the endpoint is freed, the listener will be freed too and the socket closed. Signed-off-by: Samuel Cabrero <scabrero@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
committed by
Samuel Cabrero
parent
5e7dc9fbea
commit
a18163a147
@ -238,16 +238,6 @@ void start_epmd(struct tevent_context *ev_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
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",
|
||||
|
@ -93,6 +93,8 @@ struct dcerpc_ncacn_listen_state {
|
||||
|
||||
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;
|
||||
};
|
||||
@ -308,32 +310,48 @@ NTSTATUS dcesrv_create_ncacn_ip_tcp_socket(const struct sockaddr_storage *ifss,
|
||||
|
||||
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());
|
||||
@ -350,7 +368,7 @@ NTSTATUS dcesrv_setup_ncacn_ip_tcp_socket(struct tevent_context *ev_ctx,
|
||||
}
|
||||
|
||||
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,
|
||||
@ -371,7 +389,16 @@ NTSTATUS dcesrv_setup_ncacn_ip_tcp_socket(struct tevent_context *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;
|
||||
|
||||
|
@ -87,8 +87,11 @@ NTSTATUS dcesrv_create_ncacn_ip_tcp_socket(const struct sockaddr_storage *ifss,
|
||||
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,
|
||||
|
@ -213,8 +213,13 @@ NTSTATUS dcesrv_setup_endpoint_sockets(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:
|
||||
|
@ -27,6 +27,7 @@
|
||||
#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
|
||||
@ -158,16 +159,15 @@ done:
|
||||
}
|
||||
|
||||
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();
|
||||
@ -176,6 +176,9 @@ NTSTATUS dcesrv_setup_ncacn_ip_tcp_sockets(struct tevent_context *ev_ctx,
|
||||
}
|
||||
|
||||
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
|
||||
@ -188,16 +191,23 @@ NTSTATUS dcesrv_setup_ncacn_ip_tcp_sockets(struct tevent_context *ev_ctx,
|
||||
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),
|
||||
@ -214,12 +224,24 @@ NTSTATUS dcesrv_setup_ncacn_ip_tcp_sockets(struct tevent_context *ev_ctx,
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -248,19 +270,38 @@ NTSTATUS dcesrv_setup_ncacn_ip_tcp_sockets(struct tevent_context *ev_ctx,
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,8 @@
|
||||
#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(
|
||||
@ -33,10 +35,12 @@ 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_ */
|
||||
|
||||
|
Reference in New Issue
Block a user