static void named_pipe_accept_done(struct tevent_req *subreq) { struct auth_session_info_transport *session_info_transport; struct named_pipe_client *npc = tevent_req_callback_data(subreq, struct named_pipe_client); int error; int ret; ret = tstream_npa_accept_existing_recv(subreq, &error, npc, &npc->tstream, &npc->client, &npc->client_name, &npc->server, &npc->server_name, &session_info_transport); npc->session_info = talloc_move(npc, &session_info_transport->session_info); TALLOC_FREE(subreq); if (ret != 0) { DEBUG(2, ("Failed to accept named pipe connection! (%s)\n", strerror(error))); TALLOC_FREE(npc); return; } ret = make_server_pipes_struct(npc, npc->msg_ctx, npc->pipe_name, NCACN_NP, false, npc->server, npc->client, npc->session_info, &npc->p, &error); if (ret != 0) { DEBUG(2, ("Failed to create pipes_struct! (%s)\n", strerror(error))); goto fail; } npc->write_queue = tevent_queue_create(npc, "np_server_write_queue"); if (!npc->write_queue) { DEBUG(2, ("Failed to set up write queue!\n")); goto fail; } /* And now start receiving and processing packets */ subreq = dcerpc_read_ncacn_packet_send(npc, npc->ev, npc->tstream); if (!subreq) { DEBUG(2, ("Failed to start receving packets\n")); goto fail; } tevent_req_set_callback(subreq, named_pipe_packet_process, npc); return; fail: DEBUG(2, ("Fatal error. Terminating client(%s) connection!\n", npc->client_name)); /* terminate client connection */ talloc_free(npc); return; }
NTSTATUS make_internal_rpc_pipe_socketpair( TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, struct messaging_context *msg_ctx, const char *pipe_name, const struct ndr_syntax_id *syntax, const struct tsocket_address *remote_address, const struct tsocket_address *local_address, const struct auth_session_info *session_info, struct npa_state **pnpa) { TALLOC_CTX *tmp_ctx = talloc_stackframe(); struct named_pipe_client *npc; struct tevent_req *subreq; struct npa_state *npa; NTSTATUS status; int error; int rc; DEBUG(4, ("Create of internal pipe %s requested\n", pipe_name)); npa = npa_state_init(tmp_ctx); if (npa == NULL) { status = NT_STATUS_NO_MEMORY; goto out; } npa->file_type = FILE_TYPE_MESSAGE_MODE_PIPE; npa->device_state = 0xff | 0x0400 | 0x0100; npa->allocation_size = 4096; npc = named_pipe_client_init(npa, ev_ctx, msg_ctx, pipe_name, NULL, /* term_fn */ npa->file_type, npa->device_state, npa->allocation_size, NULL); /* private_data */ if (npc == NULL) { status = NT_STATUS_NO_MEMORY; goto out; } npa->private_data = (void*) npc; rc = tstream_npa_socketpair(npa->file_type, npa, &npa->stream, npc, &npc->tstream); if (rc == -1) { status = map_nt_error_from_unix(errno); goto out; } npc->remote_client_addr = tsocket_address_copy(remote_address, npc); if (npc->remote_client_addr == NULL) { status = NT_STATUS_NO_MEMORY; goto out; } npc->remote_client_name = tsocket_address_inet_addr_string(npc->remote_client_addr, npc); if (npc->remote_client_name == NULL) { status = NT_STATUS_NO_MEMORY; goto out; } npc->local_server_addr = tsocket_address_copy(local_address, npc); if (npc->local_server_addr == NULL) { status = NT_STATUS_NO_MEMORY; goto out; } npc->local_server_name = tsocket_address_inet_addr_string( npc->local_server_addr, npc); if (npc->local_server_name == NULL) { status = NT_STATUS_NO_MEMORY; goto out; } npc->session_info = copy_session_info(npc, session_info); if (npc->session_info == NULL) { status = NT_STATUS_NO_MEMORY; goto out; } rc = make_server_pipes_struct(npc, npc->msg_ctx, npc->pipe_name, NCACN_NP, npc->remote_client_addr, npc->local_server_addr, npc->session_info, &npc->p, &error); if (rc == -1) { status = map_nt_error_from_unix(error); goto out; } npc->write_queue = tevent_queue_create(npc, "npa_server_write_queue"); if (npc->write_queue == NULL) { status = NT_STATUS_NO_MEMORY; goto out; } subreq = dcerpc_read_ncacn_packet_send(npc, npc->ev, npc->tstream); if (subreq == NULL) { DEBUG(2, ("Failed to start receiving packets\n")); status = NT_STATUS_PIPE_BROKEN; goto out; } tevent_req_set_callback(subreq, named_pipe_packet_process, npc); *pnpa = talloc_steal(mem_ctx, npa); status = NT_STATUS_OK; out: talloc_free(tmp_ctx); return status; }