39
44
void *private_data;
42
struct named_pipe_connection {
43
struct stream_connection *connection;
44
struct packet_context *packet;
45
const struct named_pipe_socket *pipe_sock;
49
static void named_pipe_handover_connection(void *private_data)
51
struct named_pipe_connection *pipe_conn = talloc_get_type(
52
private_data, struct named_pipe_connection);
53
struct stream_connection *conn = pipe_conn->connection;
55
TEVENT_FD_NOT_WRITEABLE(conn->event.fde);
57
packet_set_socket(pipe_conn->packet, NULL);
58
packet_set_event_context(pipe_conn->packet, NULL);
59
packet_set_fde(pipe_conn->packet, NULL);
60
TALLOC_FREE(pipe_conn->packet);
62
if (!NT_STATUS_IS_OK(pipe_conn->status)) {
63
stream_terminate_connection(conn, nt_errstr(pipe_conn->status));
68
* remove the named_pipe layer together with its packet layer
70
conn->ops = pipe_conn->pipe_sock->ops;
71
conn->private_data = pipe_conn->pipe_sock->private_data;
72
talloc_unlink(conn, pipe_conn);
74
/* we're now ready to start receiving events on this stream */
75
TEVENT_FD_READABLE(conn->event.fde);
47
static void named_pipe_accept_done(struct tevent_req *subreq);
49
static void named_pipe_accept(struct stream_connection *conn)
51
struct tstream_context *plain_tstream;
53
struct tevent_req *subreq;
56
/* Let tstream take over fd operations */
58
fd = socket_get_fd(conn->socket);
59
socket_set_flags(conn->socket, SOCKET_FLAG_NOCLOSE);
60
TALLOC_FREE(conn->event.fde);
61
TALLOC_FREE(conn->socket);
63
ret = tstream_bsd_existing_socket(conn, fd, &plain_tstream);
65
stream_terminate_connection(conn,
66
"named_pipe_accept: out of memory");
70
subreq = tstream_npa_accept_existing_send(conn, conn->event.ctx,
72
FILE_TYPE_MESSAGE_MODE_PIPE,
73
0xff | 0x0400 | 0x0100,
76
stream_terminate_connection(conn,
78
"no memory for tstream_npa_accept_existing_send");
81
tevent_req_set_callback(subreq, named_pipe_accept_done, conn);
84
static void named_pipe_accept_done(struct tevent_req *subreq)
86
struct stream_connection *conn = tevent_req_callback_data(subreq,
87
struct stream_connection);
88
struct named_pipe_socket *pipe_sock =
89
talloc_get_type(conn->private_data,
90
struct named_pipe_socket);
91
struct tsocket_address *client;
93
struct tsocket_address *server;
95
struct auth_session_info_transport *session_info_transport;
96
const char *reason = NULL;
101
tmp_ctx = talloc_new(conn);
103
reason = "Out of memory!\n";
107
ret = tstream_npa_accept_existing_recv(subreq, &error, tmp_ctx,
113
&session_info_transport);
116
reason = talloc_asprintf(conn,
117
"tstream_npa_accept_existing_recv()"
118
" failed: %s", strerror(error));
122
DEBUG(10, ("Accepted npa connection from %s. "
123
"Client: %s (%s). Server: %s (%s)\n",
124
tsocket_address_string(conn->remote_address, tmp_ctx),
125
client_name, tsocket_address_string(client, tmp_ctx),
126
server_name, tsocket_address_string(server, tmp_ctx)));
128
conn->session_info = auth_session_info_from_transport(conn, session_info_transport,
131
if (!conn->session_info) {
78
136
* hand over to the real pipe implementation,
79
137
* now that we have setup the transport session_info
139
conn->ops = pipe_sock->ops;
140
conn->private_data = pipe_sock->private_data;
81
141
conn->ops->accept_connection(conn);
83
DEBUG(10,("named_pipe_handover_connection[%s]: succeeded\n",
87
static NTSTATUS named_pipe_recv_auth_request(void *private_data,
90
struct named_pipe_connection *pipe_conn = talloc_get_type(
91
private_data, struct named_pipe_connection);
92
struct stream_connection *conn = pipe_conn->connection;
93
enum ndr_err_code ndr_err;
94
struct named_pipe_auth_req req;
95
union netr_Validation val;
96
struct auth_serversupplied_info *server_info;
97
struct named_pipe_auth_rep rep;
102
* make sure nothing happens on the socket untill the
103
* real implemenation takes over
105
packet_recv_disable(pipe_conn->packet);
108
* TODO: check it's a root (uid == 0) pipe
113
rep.status = NT_STATUS_INTERNAL_ERROR;
115
DEBUG(10,("named_pipe_auth: req_blob.length[%u]\n",
116
(unsigned int)req_blob.length));
117
dump_data(11, req_blob.data, req_blob.length);
119
/* parse the passed credentials */
120
ndr_err = ndr_pull_struct_blob_all(
123
lp_iconv_convenience(conn->lp_ctx),
125
(ndr_pull_flags_fn_t)ndr_pull_named_pipe_auth_req);
126
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
127
rep.status = ndr_map_error2ntstatus(ndr_err);
128
DEBUG(2, ("Could not unmarshall named_pipe_auth_req: %s\n",
129
nt_errstr(rep.status)));
134
NDR_PRINT_DEBUG(named_pipe_auth_req, &req);
137
if (strcmp(NAMED_PIPE_AUTH_MAGIC, req.magic) != 0) {
138
DEBUG(2, ("named_pipe_auth_req: invalid magic '%s' != %s\n",
139
req.magic, NAMED_PIPE_AUTH_MAGIC));
140
rep.status = NT_STATUS_INVALID_PARAMETER;
147
* anon connection, we don't create a session info
151
rep.status = NT_STATUS_OK;
154
val.sam3 = &req.info.info1;
157
rep.status = make_server_info_netlogon_validation(pipe_conn,
161
if (!NT_STATUS_IS_OK(rep.status)) {
162
DEBUG(2, ("make_server_info_netlogon_validation returned "
163
"%s\n", nt_errstr(rep.status)));
167
/* setup the session_info on the connection */
168
rep.status = auth_generate_session_info(conn,
172
&conn->session_info);
173
if (!NT_STATUS_IS_OK(rep.status)) {
174
DEBUG(2, ("auth_generate_session_info failed: %s\n",
175
nt_errstr(rep.status)));
182
rep.info.info2.file_type = FILE_TYPE_MESSAGE_MODE_PIPE;
183
rep.info.info2.device_state = 0xff | 0x0400 | 0x0100;
184
rep.info.info2.allocation_size = 4096;
186
if (!req.info.info2.sam_info3) {
188
* anon connection, we don't create a session info
191
rep.status = NT_STATUS_OK;
195
val.sam3 = req.info.info2.sam_info3;
197
rep.status = make_server_info_netlogon_validation(pipe_conn,
198
val.sam3->base.account_name.string,
199
3, &val, &server_info);
200
if (!NT_STATUS_IS_OK(rep.status)) {
201
DEBUG(2, ("make_server_info_netlogon_validation returned "
202
"%s\n", nt_errstr(rep.status)));
206
/* setup the session_info on the connection */
207
rep.status = auth_generate_session_info(conn,
211
&conn->session_info);
212
if (!NT_STATUS_IS_OK(rep.status)) {
213
DEBUG(2, ("auth_generate_session_info failed: %s\n",
214
nt_errstr(rep.status)));
218
conn->session_info->session_key = data_blob_const(req.info.info2.session_key,
219
req.info.info2.session_key_length);
220
talloc_steal(conn->session_info, req.info.info2.session_key);
225
rep.info.info3.file_type = FILE_TYPE_MESSAGE_MODE_PIPE;
226
rep.info.info3.device_state = 0xff | 0x0400 | 0x0100;
227
rep.info.info3.allocation_size = 4096;
229
if (!req.info.info3.sam_info3) {
231
* anon connection, we don't create a session info
234
rep.status = NT_STATUS_OK;
238
val.sam3 = req.info.info3.sam_info3;
240
rep.status = make_server_info_netlogon_validation(pipe_conn,
241
val.sam3->base.account_name.string,
242
3, &val, &server_info);
243
if (!NT_STATUS_IS_OK(rep.status)) {
244
DEBUG(2, ("make_server_info_netlogon_validation returned "
245
"%s\n", nt_errstr(rep.status)));
249
/* setup the session_info on the connection */
250
rep.status = auth_generate_session_info(conn,
254
&conn->session_info);
255
if (!NT_STATUS_IS_OK(rep.status)) {
256
DEBUG(2, ("auth_generate_session_info failed: %s\n",
257
nt_errstr(rep.status)));
261
if (req.info.info3.gssapi_delegated_creds_length) {
262
OM_uint32 minor_status;
263
gss_buffer_desc cred_token;
264
gss_cred_id_t cred_handle;
267
DEBUG(10, ("named_pipe_auth: delegated credentials supplied by client\n"));
269
cred_token.value = req.info.info3.gssapi_delegated_creds;
270
cred_token.length = req.info.info3.gssapi_delegated_creds_length;
272
ret = gss_import_cred(&minor_status,
275
if (ret != GSS_S_COMPLETE) {
276
rep.status = NT_STATUS_INTERNAL_ERROR;
280
conn->session_info->credentials = cli_credentials_init(conn->session_info);
281
if (!conn->session_info->credentials) {
282
rep.status = NT_STATUS_NO_MEMORY;
286
cli_credentials_set_conf(conn->session_info->credentials,
288
/* Just so we don't segfault trying to get at a username */
289
cli_credentials_set_anonymous(conn->session_info->credentials);
291
ret = cli_credentials_set_client_gss_creds(conn->session_info->credentials,
297
rep.status = NT_STATUS_INTERNAL_ERROR;
301
/* This credential handle isn't useful for password authentication, so ensure nobody tries to do that */
302
cli_credentials_set_kerberos_state(conn->session_info->credentials,
303
CRED_MUST_USE_KERBEROS);
306
conn->session_info->session_key = data_blob_const(req.info.info3.session_key,
307
req.info.info3.session_key_length);
308
talloc_steal(conn->session_info, req.info.info3.session_key);
312
DEBUG(2, ("named_pipe_auth_req: unknown level %u\n",
315
rep.status = NT_STATUS_INVALID_LEVEL;
320
/* create the output */
321
ndr_err = ndr_push_struct_blob(&rep_blob, pipe_conn,
322
lp_iconv_convenience(conn->lp_ctx),
324
(ndr_push_flags_fn_t)ndr_push_named_pipe_auth_rep);
325
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
326
status = ndr_map_error2ntstatus(ndr_err);
327
DEBUG(2, ("Could not marshall named_pipe_auth_rep: %s\n",
332
DEBUG(10,("named_pipe_auth reply[%u]\n", (unsigned)rep_blob.length));
333
dump_data(11, rep_blob.data, rep_blob.length);
335
NDR_PRINT_DEBUG(named_pipe_auth_rep, &rep);
338
pipe_conn->status = rep.status;
339
status = packet_send_callback(pipe_conn->packet, rep_blob,
340
named_pipe_handover_connection,
342
if (!NT_STATUS_IS_OK(status)) {
343
DEBUG(0, ("packet_send_callback returned %s\n",
143
DEBUG(10, ("named pipe connection [%s] established\n",
146
talloc_free(tmp_ctx);
150
talloc_free(tmp_ctx);
152
reason = "Internal error";
154
stream_terminate_connection(conn, reason);
367
168
static void named_pipe_send(struct stream_connection *conn, uint16_t flags)
369
struct named_pipe_connection *pipe_conn = talloc_get_type(
370
conn->private_data, struct named_pipe_connection);
372
packet_queue_run(pipe_conn->packet);
376
handle socket recv errors
378
static void named_pipe_recv_error(void *private_data, NTSTATUS status)
380
struct named_pipe_connection *pipe_conn = talloc_get_type(
381
private_data, struct named_pipe_connection);
383
stream_terminate_connection(pipe_conn->connection, nt_errstr(status));
386
static NTSTATUS named_pipe_full_request(void *private_data, DATA_BLOB blob, size_t *size)
388
if (blob.length < 8) {
389
return STATUS_MORE_ENTRIES;
392
if (memcmp(NAMED_PIPE_AUTH_MAGIC, &blob.data[4], 4) != 0) {
393
DEBUG(0,("named_pipe_full_request: wrong protocol\n"));
395
/* the error will be handled in named_pipe_recv_auth_request */
399
*size = 4 + RIVAL(blob.data, 0);
400
if (*size > blob.length) {
401
return STATUS_MORE_ENTRIES;
407
static void named_pipe_accept(struct stream_connection *conn)
409
struct named_pipe_socket *pipe_sock = talloc_get_type(
410
conn->private_data, struct named_pipe_socket);
411
struct named_pipe_connection *pipe_conn;
413
DEBUG(5,("named_pipe_accept\n"));
415
pipe_conn = talloc_zero(conn, struct named_pipe_connection);
417
stream_terminate_connection(conn, "out of memory");
421
pipe_conn->packet = packet_init(pipe_conn);
422
if (!pipe_conn->packet) {
423
stream_terminate_connection(conn, "out of memory");
426
packet_set_private(pipe_conn->packet, pipe_conn);
427
packet_set_socket(pipe_conn->packet, conn->socket);
428
packet_set_callback(pipe_conn->packet, named_pipe_recv_auth_request);
429
packet_set_full_request(pipe_conn->packet, named_pipe_full_request);
430
packet_set_error_handler(pipe_conn->packet, named_pipe_recv_error);
431
packet_set_event_context(pipe_conn->packet, conn->event.ctx);
432
packet_set_fde(pipe_conn->packet, conn->event.fde);
433
packet_set_serialise(pipe_conn->packet);
434
packet_set_initial_read(pipe_conn->packet, 8);
436
pipe_conn->pipe_sock = pipe_sock;
438
pipe_conn->connection = conn;
439
conn->private_data = pipe_conn;
170
stream_terminate_connection(conn, "named_pipe_send: called");
442
173
static const struct stream_server_ops named_pipe_stream_ops = {