2 Unix SMB/Netbios implementation.
3 Generic infrstructure for RPC Daemons
4 Copyright (C) Simo Sorce 2010
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "rpc_server/rpc_server.h"
23 #include "librpc/gen_ndr/netlogon.h"
24 #include "registry/reg_parse_prs.h"
26 /* Creates a pipes_struct and initializes it with the information
27 * sent from the client */
28 static int make_server_pipes_struct(TALLOC_CTX
*mem_ctx
,
29 const char *pipe_name
,
30 const struct ndr_syntax_id id
,
31 const char *client_address
,
32 struct netr_SamInfo3
*info3
,
33 struct pipes_struct
**_p
,
36 struct pipes_struct
*p
;
40 p
= talloc_zero(mem_ctx
, struct pipes_struct
);
47 p
->mem_ctx
= talloc_named(p
, 0, "pipe %s %p", pipe_name
, p
);
54 ok
= init_pipe_handles(p
, &id
);
56 DEBUG(1, ("Failed to init handles\n"));
63 * Initialize the incoming RPC data buffer with one PDU worth of
64 * memory. We cheat here and say we're marshalling, as we intend
65 * to add incoming data directly into the prs_struct and we want
66 * it to auto grow. We will change the type to UNMARSALLING before
67 * processing the stream.
69 if (!prs_init(&p
->in_data
.data
, 128, p
->mem_ctx
, MARSHALL
)) {
70 DEBUG(0, ("malloc fail for in_data struct.\n"));
77 * Initialize the outgoing RPC data buffer with no memory.
79 prs_init_empty(&p
->out_data
.rdata
, p
->mem_ctx
, MARSHALL
);
81 p
->endian
= RPC_LITTLE_ENDIAN
;
83 status
= make_server_info_info3(p
,
84 info3
->base
.account_name
.string
,
85 info3
->base
.domain
.string
,
86 &p
->server_info
, info3
);
87 if (!NT_STATUS_IS_OK(status
)) {
88 DEBUG(1, ("Failed to init server info\n"));
95 * Some internal functions need a local token to determine access to
98 status
= create_local_token(p
->server_info
);
99 if (!NT_STATUS_IS_OK(status
)) {
100 DEBUG(1, ("Failed to init local auth token\n"));
106 p
->client_id
= talloc_zero(p
, struct client_address
);
112 strlcpy(p
->client_id
->addr
,
113 client_address
, sizeof(p
->client_id
->addr
));
115 talloc_set_destructor(p
, close_internal_rpc_pipe_hnd
);
122 struct named_pipe_listen_state
{
127 static void named_pipe_listener(struct tevent_context
*ev
,
128 struct tevent_fd
*fde
,
132 bool setup_named_pipe_socket(const char *pipe_name
,
133 struct tevent_context
*ev_ctx
)
135 struct named_pipe_listen_state
*state
;
136 struct tevent_fd
*fde
;
139 state
= talloc(ev_ctx
, struct named_pipe_listen_state
);
141 DEBUG(0, ("Out of memory\n"));
144 state
->name
= talloc_strdup(state
, pipe_name
);
146 DEBUG(0, ("Out of memory\n"));
151 np_dir
= talloc_asprintf(state
, "%s/np", lp_ncalrpc_dir());
153 DEBUG(0, ("Out of memory\n"));
157 if (!directory_create_or_exist(np_dir
, geteuid(), 0700)) {
158 DEBUG(0, ("Failed to create pipe directory %s - %s\n",
159 np_dir
, strerror(errno
)));
163 state
->fd
= create_pipe_sock(np_dir
, pipe_name
, 0700);
164 if (state
->fd
== -1) {
165 DEBUG(0, ("Failed to create pipe socket! [%s/%s]\n",
170 DEBUG(10, ("Openened pipe socket fd %d for %s\n",
171 state
->fd
, pipe_name
));
173 fde
= tevent_add_fd(ev_ctx
,
174 state
, state
->fd
, TEVENT_FD_READ
,
175 named_pipe_listener
, state
);
177 DEBUG(0, ("Failed to add event handler!\n"));
181 tevent_fd_set_auto_close(fde
);
185 if (state
->fd
!= -1) {
192 static void named_pipe_accept_function(const char *pipe_name
, int fd
);
194 static void named_pipe_listener(struct tevent_context
*ev
,
195 struct tevent_fd
*fde
,
199 struct named_pipe_listen_state
*state
=
200 talloc_get_type_abort(private_data
,
201 struct named_pipe_listen_state
);
202 struct sockaddr_un sunaddr
;
206 /* TODO: should we have a limit to the number of clients ? */
208 len
= sizeof(sunaddr
);
211 sd
= accept(state
->fd
,
212 (struct sockaddr
*)(void *)&sunaddr
, &len
);
213 if (errno
!= EINTR
) break;
217 DEBUG(6, ("Failed to get a valid socket [%s]\n",
222 DEBUG(6, ("Accepted socket %d\n", sd
));
224 named_pipe_accept_function(state
->name
, sd
);
227 static void named_pipe_accept_function(const char *pipe_name
, int fd
)