2 Unix SMB/CIFS implementation.
4 server side dcerpc over tcp code
6 Copyright (C) Andrew Tridgell 2003
7 Copyright (C) Stefan (metze) Metzmacher 2004
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 struct dcesrv_socket_context {
27 const struct dcesrv_endpoint *endpoint;
28 struct dcesrv_context *dcesrv_ctx;
32 write_fn callback for dcesrv_output()
34 static ssize_t dcerpc_write_fn(void *private, DATA_BLOB *out)
37 struct socket_context *sock = private;
40 status = socket_send(sock, sock, out, &sendlen, 0);
41 if (!NT_STATUS_IS_OK(status)) {
48 void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
50 server_terminate_connection(dce_conn->srv_conn, reason);
54 add a socket address to the list of events, one event per dcerpc endpoint
56 static void add_socket_rpc(struct server_service *service,
57 const struct model_ops *model_ops,
58 struct dcesrv_context *dce_ctx,
61 struct dcesrv_endpoint *e;
62 char *ip_str = talloc_strdup(service->mem_ctx, inet_ntoa(*ifip));
64 for (e=dce_ctx->endpoint_list;e;e=e->next) {
65 if (e->ep_description.type == ENDPOINT_TCP) {
66 struct server_socket *sock;
67 struct dcesrv_socket_context *dcesrv_sock;
69 sock = service_setup_socket(service,model_ops, ip_str, &e->ep_description.info.tcp_port);
71 DEBUG(0,("service_setup_socket(port=%u) failed\n",e->ep_description.info.tcp_port));
75 dcesrv_sock = talloc_p(sock, struct dcesrv_socket_context);
77 DEBUG(0,("talloc_p(sock->mem_ctx, struct dcesrv_socket_context) failed\n"));
81 /* remeber the enpoint of this socket */
82 dcesrv_sock->endpoint = e;
83 dcesrv_sock->dcesrv_ctx = dce_ctx;
85 sock->private_data = dcesrv_sock;
92 /****************************************************************************
93 Open the listening sockets for RPC over TCP
94 ****************************************************************************/
95 void dcesrv_tcp_init(struct server_service *service, const struct model_ops *model_ops, struct dcesrv_context *dce_ctx)
97 DEBUG(1,("dcesrv_tcp_init\n"));
99 if (lp_interfaces() && lp_bind_interfaces_only()) {
100 int num_interfaces = iface_count();
102 for(i = 0; i < num_interfaces; i++) {
103 struct in_addr *ifip = iface_n_ip(i);
107 add_socket_rpc(service, model_ops, dce_ctx, ifip);
110 struct in_addr *ifip;
111 TALLOC_CTX *mem_ctx = talloc_init("open_sockets_smbd");
113 smb_panic("No memory");
116 ifip = interpret_addr2(mem_ctx, lp_socket_address());
117 add_socket_rpc(service, model_ops, dce_ctx, ifip);
118 talloc_destroy(mem_ctx);
124 void dcesrv_tcp_accept(struct server_connection *conn)
127 struct dcesrv_socket_context *dcesrv_sock = conn->server_socket->private_data;
128 struct dcesrv_connection *dcesrv_conn = NULL;
130 DEBUG(5,("dcesrv_tcp_accept\n"));
132 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx, dcesrv_sock->endpoint, &dcesrv_conn);
133 if (!NT_STATUS_IS_OK(status)) {
134 DEBUG(0,("dcesrv_tcp_accept: dcesrv_endpoint_connect failed: %s\n",
139 dcesrv_conn->srv_conn = conn;
141 conn->private_data = dcesrv_conn;
146 void dcesrv_tcp_recv(struct server_connection *conn, time_t t, uint16_t flags)
149 struct dcesrv_connection *dce_conn = conn->private_data;
152 DEBUG(10,("dcesrv_tcp_recv\n"));
154 status = socket_recv(conn->socket, conn->socket, &tmp_blob, 0x4000, 0);
155 if (!NT_STATUS_IS_OK(status)) {
156 if (NT_STATUS_IS_ERR(status)) {
157 dcesrv_terminate_connection(dce_conn, "eof on socket");
163 status = dcesrv_input(dce_conn, &tmp_blob);
164 talloc_free(tmp_blob.data);
165 if (!NT_STATUS_IS_OK(status)) {
166 dcesrv_terminate_connection(dce_conn, "eof on socket");
170 if (dce_conn->call_list && dce_conn->call_list->replies) {
171 conn->event.fde->flags |= EVENT_FD_WRITE;
177 void dcesrv_tcp_send(struct server_connection *conn, time_t t, uint16_t flags)
179 struct dcesrv_connection *dce_conn = conn->private_data;
182 DEBUG(10,("dcesrv_tcp_send\n"));
184 status = dcesrv_output(dce_conn, conn->socket, dcerpc_write_fn);
185 if (!NT_STATUS_IS_OK(status)) {
186 dcesrv_terminate_connection(dce_conn, "eof on socket");
190 if (!dce_conn->call_list || !dce_conn->call_list->replies) {
191 conn->event.fde->flags &= ~EVENT_FD_WRITE;
197 void dcesrv_tcp_idle(struct server_connection *conn, time_t t)
199 DEBUG(10,("dcesrv_tcp_idle\n"));
200 conn->event.idle->next_event = t + 5;
205 void dcesrv_tcp_close(struct server_connection *conn, const char *reason)
207 struct dcesrv_connection *dce_conn = conn->private_data;
209 DEBUG(5,("dcesrv_tcp_close: %s\n",reason));
211 talloc_destroy(dce_conn->mem_ctx);
216 void dcesrv_tcp_exit(struct server_service *service, const char *reason)
218 DEBUG(1,("dcesrv_tcp_exit: %s\n",reason));