1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00

rpc_server: Move socket creation to rpc_sock_helper.[ch]

dcesrv_create_ncacn_ip_tcp_sockets() already was there, move the rest
as well. This makes dcesrv_create_ncacn_np_socket() static to
rpc_sock_helper.c.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
Volker Lendecke 2021-01-16 22:24:05 +01:00 committed by Jeremy Allison
parent 27987e313f
commit 125c605ea5
4 changed files with 188 additions and 194 deletions

View File

@ -52,193 +52,6 @@ struct dcerpc_ncacn_listen_state {
void *termination_data;
};
NTSTATUS dcesrv_create_ncacn_np_socket(struct dcerpc_binding *b, int *out_fd)
{
char *np_dir = NULL;
int fd = -1;
NTSTATUS status;
const char *endpoint;
char *endpoint_normalized = NULL;
char *p = NULL;
endpoint = dcerpc_binding_get_string_option(b, "endpoint");
if (endpoint == NULL) {
DBG_ERR("Endpoint mandatory for named pipes\n");
return NT_STATUS_INVALID_PARAMETER;
}
/* The endpoint string from IDL can be mixed uppercase and case is
* normalized by smbd on connection */
endpoint_normalized = strlower_talloc(talloc_tos(), endpoint);
if (endpoint_normalized == NULL) {
return NT_STATUS_NO_MEMORY;
}
/* The endpoint string from IDL can be prefixed by \pipe\ */
p = endpoint_normalized;
if (strncmp(p, "\\pipe\\", 6) == 0) {
p += 6;
}
/*
* As lp_ncalrpc_dir() should have 0755, but
* lp_ncalrpc_dir()/np should have 0700, we need to
* create lp_ncalrpc_dir() first.
*/
if (!directory_create_or_exist(lp_ncalrpc_dir(), 0755)) {
status = map_nt_error_from_unix_common(errno);
DBG_ERR("Failed to create pipe directory %s - %s\n",
lp_ncalrpc_dir(), strerror(errno));
goto out;
}
np_dir = talloc_asprintf(talloc_tos(), "%s/np", lp_ncalrpc_dir());
if (!np_dir) {
status = NT_STATUS_NO_MEMORY;
DBG_ERR("Out of memory\n");
goto out;
}
if (!directory_create_or_exist_strict(np_dir, geteuid(), 0700)) {
status = map_nt_error_from_unix_common(errno);
DBG_ERR("Failed to create pipe directory %s - %s\n",
np_dir, strerror(errno));
goto out;
}
fd = create_pipe_sock(np_dir, p, 0700);
if (fd == -1) {
status = map_nt_error_from_unix_common(errno);
DBG_ERR("Failed to create ncacn_np socket! '%s/%s': %s\n",
np_dir, p, strerror(errno));
goto out;
}
DBG_DEBUG("Opened pipe socket fd %d for %s\n", fd, p);
*out_fd = fd;
status = NT_STATUS_OK;
out:
TALLOC_FREE(endpoint_normalized);
TALLOC_FREE(np_dir);
return status;
}
/********************************************************************
* Start listening on the tcp/ip socket
********************************************************************/
NTSTATUS dcesrv_create_ncacn_ip_tcp_socket(const struct sockaddr_storage *ifss,
uint16_t *port,
int *out_fd)
{
int fd = -1;
if (*port == 0) {
uint16_t i;
for (i = lp_rpc_low_port(); i <= lp_rpc_high_port(); i++) {
fd = open_socket_in(SOCK_STREAM,
i,
0,
ifss,
false);
if (fd >= 0) {
*port = i;
break;
}
}
} else {
fd = open_socket_in(SOCK_STREAM,
*port,
0,
ifss,
true);
}
if (fd == -1) {
DBG_ERR("Failed to create socket on port %u!\n", *port);
return NT_STATUS_UNSUCCESSFUL;
}
/* ready to listen */
set_socket_options(fd, "SO_KEEPALIVE");
set_socket_options(fd, lp_socket_options());
DBG_DEBUG("Opened ncacn_ip_tcp socket fd %d for port %u\n", fd, *port);
*out_fd = fd;
return NT_STATUS_OK;
}
/********************************************************************
* Start listening on the ncalrpc socket
********************************************************************/
NTSTATUS dcesrv_create_ncalrpc_socket(struct dcerpc_binding *b, int *out_fd)
{
int fd = -1;
const char *endpoint = NULL;
NTSTATUS status;
endpoint = dcerpc_binding_get_string_option(b, "endpoint");
if (endpoint == NULL) {
/*
* No identifier specified: use DEFAULT or SMBD.
*
* When role is AD DC we run two rpc server instances, the one
* started by 'samba' and the one embedded in 'smbd'.
* Avoid listening in DEFAULT socket for NCALRPC as both
* servers will race to accept connections. In this case smbd
* will listen in SMBD socket and rpcint binding handle
* implementation will pick the right socket to use.
*
* TODO: DO NOT hardcode this value anywhere else. Rather,
* specify no endpoint and let the epmapper worry about it.
*/
if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
endpoint = "SMBD";
} else {
endpoint = "DEFAULT";
}
status = dcerpc_binding_set_string_option(
b, "endpoint", endpoint);
if (!NT_STATUS_IS_OK(status)) {
DBG_ERR("Failed to set ncalrpc 'endpoint' binding "
"string option to '%s': %s\n",
endpoint, nt_errstr(status));
return status;
}
}
if (!directory_create_or_exist(lp_ncalrpc_dir(), 0755)) {
status = map_nt_error_from_unix_common(errno);
DBG_ERR("Failed to create ncalrpc directory '%s': %s\n",
lp_ncalrpc_dir(), strerror(errno));
goto out;
}
fd = create_pipe_sock(lp_ncalrpc_dir(), endpoint, 0755);
if (fd == -1) {
status = map_nt_error_from_unix_common(errno);
DBG_ERR("Failed to create ncalrpc socket '%s/%s': %s\n",
lp_ncalrpc_dir(), endpoint, strerror(errno));
goto out;
}
DBG_DEBUG("Opened ncalrpc socket fd '%d' for '%s/%s'\n",
fd, lp_ncalrpc_dir(), endpoint);
*out_fd = fd;
return NT_STATUS_OK;
out:
return status;
}
static void dcesrv_ncacn_listener(
struct tevent_context *ev,
struct tevent_fd *fde,

View File

@ -67,13 +67,6 @@ NTSTATUS dcerpc_ncacn_conn_init(TALLOC_CTX *mem_ctx,
void set_incoming_fault(struct pipes_struct *p);
void process_complete_pdu(struct pipes_struct *p, struct ncacn_packet *pkt);
NTSTATUS dcesrv_create_ncacn_np_socket(struct dcerpc_binding *b, int *out_fd);
NTSTATUS dcesrv_create_ncacn_ip_tcp_socket(const struct sockaddr_storage *ifss,
uint16_t *port,
int *out_fd);
NTSTATUS dcesrv_create_ncalrpc_socket(struct dcerpc_binding *b, int *fd);
struct dcerpc_ncacn_listen_state;
int dcesrv_setup_ncacn_listener(

View File

@ -32,6 +32,126 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
NTSTATUS dcesrv_create_ncacn_np_socket(struct dcerpc_binding *b, int *out_fd)
{
char *np_dir = NULL;
int fd = -1;
NTSTATUS status;
const char *endpoint;
char *endpoint_normalized = NULL;
char *p = NULL;
endpoint = dcerpc_binding_get_string_option(b, "endpoint");
if (endpoint == NULL) {
DBG_ERR("Endpoint mandatory for named pipes\n");
return NT_STATUS_INVALID_PARAMETER;
}
/* The endpoint string from IDL can be mixed uppercase and case is
* normalized by smbd on connection */
endpoint_normalized = strlower_talloc(talloc_tos(), endpoint);
if (endpoint_normalized == NULL) {
return NT_STATUS_NO_MEMORY;
}
/* The endpoint string from IDL can be prefixed by \pipe\ */
p = endpoint_normalized;
if (strncmp(p, "\\pipe\\", 6) == 0) {
p += 6;
}
/*
* As lp_ncalrpc_dir() should have 0755, but
* lp_ncalrpc_dir()/np should have 0700, we need to
* create lp_ncalrpc_dir() first.
*/
if (!directory_create_or_exist(lp_ncalrpc_dir(), 0755)) {
status = map_nt_error_from_unix_common(errno);
DBG_ERR("Failed to create pipe directory %s - %s\n",
lp_ncalrpc_dir(), strerror(errno));
goto out;
}
np_dir = talloc_asprintf(talloc_tos(), "%s/np", lp_ncalrpc_dir());
if (!np_dir) {
status = NT_STATUS_NO_MEMORY;
DBG_ERR("Out of memory\n");
goto out;
}
if (!directory_create_or_exist_strict(np_dir, geteuid(), 0700)) {
status = map_nt_error_from_unix_common(errno);
DBG_ERR("Failed to create pipe directory %s - %s\n",
np_dir, strerror(errno));
goto out;
}
fd = create_pipe_sock(np_dir, p, 0700);
if (fd == -1) {
status = map_nt_error_from_unix_common(errno);
DBG_ERR("Failed to create ncacn_np socket! '%s/%s': %s\n",
np_dir, p, strerror(errno));
goto out;
}
DBG_DEBUG("Opened pipe socket fd %d for %s\n", fd, p);
*out_fd = fd;
status = NT_STATUS_OK;
out:
TALLOC_FREE(endpoint_normalized);
TALLOC_FREE(np_dir);
return status;
}
/********************************************************************
* Start listening on the tcp/ip socket
********************************************************************/
static NTSTATUS dcesrv_create_ncacn_ip_tcp_socket(
const struct sockaddr_storage *ifss, uint16_t *port, int *out_fd)
{
int fd = -1;
if (*port == 0) {
uint16_t i;
for (i = lp_rpc_low_port(); i <= lp_rpc_high_port(); i++) {
fd = open_socket_in(SOCK_STREAM,
i,
0,
ifss,
false);
if (fd >= 0) {
*port = i;
break;
}
}
} else {
fd = open_socket_in(SOCK_STREAM,
*port,
0,
ifss,
true);
}
if (fd == -1) {
DBG_ERR("Failed to create socket on port %u!\n", *port);
return NT_STATUS_UNSUCCESSFUL;
}
/* ready to listen */
set_socket_options(fd, "SO_KEEPALIVE");
set_socket_options(fd, lp_socket_options());
DBG_DEBUG("Opened ncacn_ip_tcp socket fd %d for port %u\n", fd, *port);
*out_fd = fd;
return NT_STATUS_OK;
}
NTSTATUS dcesrv_create_ncacn_ip_tcp_sockets(
struct dcerpc_binding *b,
TALLOC_CTX *mem_ctx,
@ -152,4 +272,70 @@ fail:
return status;
}
/********************************************************************
* Start listening on the ncalrpc socket
********************************************************************/
NTSTATUS dcesrv_create_ncalrpc_socket(struct dcerpc_binding *b, int *out_fd)
{
int fd = -1;
const char *endpoint = NULL;
NTSTATUS status;
endpoint = dcerpc_binding_get_string_option(b, "endpoint");
if (endpoint == NULL) {
/*
* No identifier specified: use DEFAULT or SMBD.
*
* When role is AD DC we run two rpc server instances, the one
* started by 'samba' and the one embedded in 'smbd'.
* Avoid listening in DEFAULT socket for NCALRPC as both
* servers will race to accept connections. In this case smbd
* will listen in SMBD socket and rpcint binding handle
* implementation will pick the right socket to use.
*
* TODO: DO NOT hardcode this value anywhere else. Rather,
* specify no endpoint and let the epmapper worry about it.
*/
if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
endpoint = "SMBD";
} else {
endpoint = "DEFAULT";
}
status = dcerpc_binding_set_string_option(
b, "endpoint", endpoint);
if (!NT_STATUS_IS_OK(status)) {
DBG_ERR("Failed to set ncalrpc 'endpoint' binding "
"string option to '%s': %s\n",
endpoint, nt_errstr(status));
return status;
}
}
if (!directory_create_or_exist(lp_ncalrpc_dir(), 0755)) {
status = map_nt_error_from_unix_common(errno);
DBG_ERR("Failed to create ncalrpc directory '%s': %s\n",
lp_ncalrpc_dir(), strerror(errno));
goto out;
}
fd = create_pipe_sock(lp_ncalrpc_dir(), endpoint, 0755);
if (fd == -1) {
status = map_nt_error_from_unix_common(errno);
DBG_ERR("Failed to create ncalrpc socket '%s/%s': %s\n",
lp_ncalrpc_dir(), endpoint, strerror(errno));
goto out;
}
DBG_DEBUG("Opened ncalrpc socket fd '%d' for '%s/%s'\n",
fd, lp_ncalrpc_dir(), endpoint);
*out_fd = fd;
return NT_STATUS_OK;
out:
return status;
}
/* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */

View File

@ -27,6 +27,8 @@
struct pf_listen_fd;
NTSTATUS dcesrv_create_ncacn_np_socket(struct dcerpc_binding *b, int *out_fd);
NTSTATUS dcesrv_create_ncalrpc_socket(struct dcerpc_binding *b, int *fd);
NTSTATUS dcesrv_create_ncacn_ip_tcp_sockets(
struct dcerpc_binding *b,
TALLOC_CTX *mem_ctx,