static void dns_tcp_terminate_connection(struct dns_tcp_connection *dnsconn, const char *reason) { stream_terminate_connection(dnsconn->conn, reason); }
/* called when a pipe socket becomes writable */ static void named_pipe_send(struct stream_connection *conn, uint16_t flags) { stream_terminate_connection(conn, "named_pipe_send: called"); }
static void kdc_tcp_terminate_connection(struct kdc_tcp_connection *kdcconn, const char *reason) { stream_terminate_connection(kdcconn->conn, reason); }
/* called when we get a new connection */ static void kdc_tcp_accept(struct stream_connection *conn) { struct kdc_socket *kdc_socket = talloc_get_type(conn->private_data, struct kdc_socket); struct kdc_tcp_connection *kdcconn; struct socket_address *src_addr; struct socket_address *my_addr; int ret; kdcconn = talloc_zero(conn, struct kdc_tcp_connection); if (!kdcconn) { stream_terminate_connection(conn, "kdc_tcp_accept: out of memory"); return; } kdcconn->conn = conn; kdcconn->kdc_socket = kdc_socket; conn->private_data = kdcconn; src_addr = socket_get_peer_addr(kdcconn->conn->socket, kdcconn); if (!src_addr) { kdc_tcp_terminate_connection(kdcconn, "kdc_tcp_accept: out of memory"); return; } my_addr = socket_get_my_addr(kdcconn->conn->socket, kdcconn); if (!my_addr) { kdc_tcp_terminate_connection(kdcconn, "kdc_tcp_accept: out of memory"); return; } ret = tsocket_address_bsd_from_sockaddr(kdcconn, src_addr->sockaddr, src_addr->sockaddrlen, &kdcconn->remote_address); if (ret < 0) { kdc_tcp_terminate_connection(kdcconn, "kdc_tcp_accept: out of memory"); return; } ret = tsocket_address_bsd_from_sockaddr(kdcconn, my_addr->sockaddr, my_addr->sockaddrlen, &kdcconn->local_address); if (ret < 0) { kdc_tcp_terminate_connection(kdcconn, "kdc_tcp_accept: out of memory"); return; } TALLOC_FREE(src_addr); TALLOC_FREE(my_addr); kdcconn->packet = packet_init(kdcconn); if (kdcconn->packet == NULL) { kdc_tcp_terminate_connection(kdcconn, "kdc_tcp_accept: out of memory"); return; } packet_set_private(kdcconn->packet, kdcconn); packet_set_socket(kdcconn->packet, conn->socket); packet_set_callback(kdcconn->packet, kdc_tcp_recv); packet_set_full_request(kdcconn->packet, packet_full_request_u32); packet_set_error_handler(kdcconn->packet, kdc_tcp_recv_error); packet_set_event_context(kdcconn->packet, conn->event.ctx); packet_set_fde(kdcconn->packet, conn->event.fde); packet_set_serialise(kdcconn->packet); }
/* initialise a server_context from a open socket and register a event handler for reading from that socket */ static void ldapsrv_accept(struct stream_connection *c, struct auth_session_info *session_info, bool is_privileged) { struct ldapsrv_service *ldapsrv_service = talloc_get_type(c->private_data, struct ldapsrv_service); struct ldapsrv_connection *conn; struct cli_credentials *server_credentials; struct socket_address *socket_address; NTSTATUS status; int port; int ret; struct tevent_req *subreq; struct timeval endtime; conn = talloc_zero(c, struct ldapsrv_connection); if (!conn) { stream_terminate_connection(c, "ldapsrv_accept: out of memory"); return; } conn->is_privileged = is_privileged; conn->sockets.send_queue = tevent_queue_create(conn, "ldapsev send queue"); if (conn->sockets.send_queue == NULL) { stream_terminate_connection(c, "ldapsrv_accept: tevent_queue_create failed"); return; } TALLOC_FREE(c->event.fde); ret = tstream_bsd_existing_socket(conn, socket_get_fd(c->socket), &conn->sockets.raw); if (ret == -1) { stream_terminate_connection(c, "ldapsrv_accept: out of memory"); return; } socket_set_flags(c->socket, SOCKET_FLAG_NOCLOSE); conn->connection = c; conn->service = ldapsrv_service; conn->lp_ctx = ldapsrv_service->task->lp_ctx; c->private_data = conn; socket_address = socket_get_my_addr(c->socket, conn); if (!socket_address) { ldapsrv_terminate_connection(conn, "ldapsrv_accept: failed to obtain local socket address!"); return; } port = socket_address->port; talloc_free(socket_address); if (port == 3268 || port == 3269) /* Global catalog */ { conn->global_catalog = true; } server_credentials = cli_credentials_init(conn); if (!server_credentials) { stream_terminate_connection(c, "Failed to init server credentials\n"); return; } cli_credentials_set_conf(server_credentials, conn->lp_ctx); status = cli_credentials_set_machine_account(server_credentials, conn->lp_ctx); if (!NT_STATUS_IS_OK(status)) { stream_terminate_connection(c, talloc_asprintf(conn, "Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(status))); return; } conn->server_credentials = server_credentials; conn->session_info = session_info; conn->sockets.active = conn->sockets.raw; if (!NT_STATUS_IS_OK(ldapsrv_backend_Init(conn))) { ldapsrv_terminate_connection(conn, "backend Init failed"); return; } /* load limits from the conf partition */ ldapsrv_load_limits(conn); /* should we fail on error ? */ /* register the server */ irpc_add_name(c->msg_ctx, "ldap_server"); if (port != 636 && port != 3269) { ldapsrv_call_read_next(conn); return; } endtime = timeval_current_ofs(conn->limits.conn_idle_time, 0); subreq = tstream_tls_accept_send(conn, conn->connection->event.ctx, conn->sockets.raw, conn->service->tls_params); if (subreq == NULL) { ldapsrv_terminate_connection(conn, "ldapsrv_accept: " "no memory for tstream_tls_accept_send"); return; } tevent_req_set_endtime(subreq, conn->connection->event.ctx, endtime); tevent_req_set_callback(subreq, ldapsrv_accept_tls_done, conn); }
/* called when a new socket connection has been established. This is called in the process context of the new process (if appropriate) */ static void stream_new_connection(struct tevent_context *ev, struct loadparm_context *lp_ctx, struct socket_context *sock, struct server_id server_id, void *private_data) { struct stream_socket *stream_socket = talloc_get_type(private_data, struct stream_socket); struct stream_connection *srv_conn; srv_conn = talloc_zero(ev, struct stream_connection); if (!srv_conn) { DEBUG(0,("talloc(mem_ctx, struct stream_connection) failed\n")); return; } talloc_steal(srv_conn, sock); srv_conn->private_data = stream_socket->private_data; srv_conn->model_ops = stream_socket->model_ops; srv_conn->socket = sock; srv_conn->server_id = server_id; srv_conn->ops = stream_socket->ops; srv_conn->event.ctx = ev; srv_conn->lp_ctx = lp_ctx; if (!socket_check_access(sock, "smbd", lpcfg_hosts_allow(NULL, lpcfg_default_service(lp_ctx)), lpcfg_hosts_deny(NULL, lpcfg_default_service(lp_ctx)))) { stream_terminate_connection(srv_conn, "denied by access rules"); return; } srv_conn->event.fde = tevent_add_fd(ev, srv_conn, socket_get_fd(sock), 0, stream_io_handler_fde, srv_conn); if (!srv_conn->event.fde) { stream_terminate_connection(srv_conn, "tevent_add_fd() failed"); return; } /* setup to receive internal messages on this connection */ srv_conn->msg_ctx = imessaging_init(srv_conn, lp_ctx, srv_conn->server_id, ev); if (!srv_conn->msg_ctx) { stream_terminate_connection(srv_conn, "imessaging_init() failed"); return; } srv_conn->remote_address = socket_get_remote_addr(srv_conn->socket, srv_conn); if (!srv_conn->remote_address) { stream_terminate_connection(srv_conn, "socket_get_remote_addr() failed"); return; } srv_conn->local_address = socket_get_local_addr(srv_conn->socket, srv_conn); if (!srv_conn->local_address) { stream_terminate_connection(srv_conn, "socket_get_local_addr() failed"); return; } { TALLOC_CTX *tmp_ctx; const char *title; struct server_id_buf idbuf; tmp_ctx = talloc_new(srv_conn); title = talloc_asprintf(tmp_ctx, "conn[%s] c[%s] s[%s] server_id[%s]", stream_socket->ops->name, tsocket_address_string(srv_conn->remote_address, tmp_ctx), tsocket_address_string(srv_conn->local_address, tmp_ctx), server_id_str_buf(server_id, &idbuf)); if (title) { stream_connection_set_title(srv_conn, title); } talloc_free(tmp_ctx); } /* we're now ready to start receiving events on this stream */ TEVENT_FD_READABLE(srv_conn->event.fde); /* call the server specific accept code */ stream_socket->ops->accept_connection(srv_conn); }
/* initialise a server_context from a open socket and register a event handler for reading from that socket */ static void ldapsrv_accept(struct stream_connection *c, struct auth_session_info *session_info) { struct ldapsrv_service *ldapsrv_service = talloc_get_type(c->private_data, struct ldapsrv_service); struct ldapsrv_connection *conn; struct cli_credentials *server_credentials; struct socket_address *socket_address; NTSTATUS status; int port; conn = talloc_zero(c, struct ldapsrv_connection); if (!conn) { stream_terminate_connection(c, "ldapsrv_accept: out of memory"); return; } conn->packet = NULL; conn->connection = c; conn->service = ldapsrv_service; conn->sockets.raw = c->socket; conn->lp_ctx = ldapsrv_service->task->lp_ctx; c->private_data = conn; socket_address = socket_get_my_addr(c->socket, conn); if (!socket_address) { ldapsrv_terminate_connection(conn, "ldapsrv_accept: failed to obtain local socket address!"); return; } port = socket_address->port; talloc_free(socket_address); if (port == 636) { struct socket_context *tls_socket = tls_init_server(ldapsrv_service->tls_params, c->socket, c->event.fde, NULL); if (!tls_socket) { ldapsrv_terminate_connection(conn, "ldapsrv_accept: tls_init_server() failed"); return; } talloc_steal(c, tls_socket); c->socket = tls_socket; conn->sockets.tls = tls_socket; } else if (port == 3268) /* Global catalog */ { conn->global_catalog = true; } conn->packet = packet_init(conn); if (conn->packet == NULL) { ldapsrv_terminate_connection(conn, "out of memory"); return; } packet_set_private(conn->packet, conn); packet_set_socket(conn->packet, c->socket); packet_set_callback(conn->packet, ldapsrv_decode); packet_set_full_request(conn->packet, ldap_full_packet); packet_set_error_handler(conn->packet, ldapsrv_error_handler); packet_set_event_context(conn->packet, c->event.ctx); packet_set_fde(conn->packet, c->event.fde); packet_set_serialise(conn->packet); if (conn->sockets.tls) { packet_set_unreliable_select(conn->packet); } /* Ensure we don't get packets until the database is ready below */ packet_recv_disable(conn->packet); server_credentials = cli_credentials_init(conn); if (!server_credentials) { stream_terminate_connection(c, "Failed to init server credentials\n"); return; } cli_credentials_set_conf(server_credentials, conn->lp_ctx); status = cli_credentials_set_machine_account(server_credentials, conn->lp_ctx); if (!NT_STATUS_IS_OK(status)) { stream_terminate_connection(c, talloc_asprintf(conn, "Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(status))); return; } conn->server_credentials = server_credentials; conn->session_info = talloc_move(conn, &session_info); if (!NT_STATUS_IS_OK(ldapsrv_backend_Init(conn))) { ldapsrv_terminate_connection(conn, "backend Init failed"); return; } /* load limits from the conf partition */ ldapsrv_load_limits(conn); /* should we fail on error ? */ /* register the server */ irpc_add_name(c->msg_ctx, "ldap_server"); /* set connections limits */ conn->limits.ite = event_add_timed(c->event.ctx, conn, timeval_current_ofs(conn->limits.initial_timeout, 0), ldapsrv_conn_init_timeout, conn); packet_recv_enable(conn->packet); }