r24937: Merge tests spoolss RPC callbacks.
[gd/samba-autobuild/.git] / source4 / rpc_server / service_rpc.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    smbd-specific dcerpc server code
5
6    Copyright (C) Andrew Tridgell 2003-2005
7    Copyright (C) Stefan (metze) Metzmacher 2004-2005
8    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2004,2007
9    
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25 #include "librpc/gen_ndr/ndr_dcerpc.h"
26 #include "auth/auth.h"
27 #include "auth/gensec/gensec.h"
28 #include "lib/util/dlinklist.h"
29 #include "rpc_server/dcerpc_server.h"
30 #include "lib/events/events.h"
31 #include "smbd/service_task.h"
32 #include "smbd/service_stream.h"
33 #include "smbd/service.h"
34 #include "system/filesys.h"
35 #include "libcli/security/security.h"
36 #include "lib/socket/socket.h"
37 #include "lib/messaging/irpc.h"
38 #include "system/network.h"
39 #include "lib/socket/netif.h"
40 #include "build.h"
41
42 struct dcesrv_socket_context {
43         const struct dcesrv_endpoint *endpoint;
44         struct dcesrv_context *dcesrv_ctx;
45 };
46
47 /*
48   write_fn callback for dcesrv_output()
49 */
50 static NTSTATUS dcerpc_write_fn(void *private_data, DATA_BLOB *out, size_t *nwritten)
51 {
52         NTSTATUS status;
53         struct socket_context *sock = talloc_get_type(private_data, struct socket_context);
54         size_t sendlen;
55
56         status = socket_send(sock, out, &sendlen);
57         NT_STATUS_IS_ERR_RETURN(status);
58
59         *nwritten = sendlen;
60         return status;
61 }
62
63 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
64 {
65         struct stream_connection *srv_conn;
66         srv_conn = talloc_get_type(dce_conn->transport.private_data,
67                                    struct stream_connection);
68
69         stream_terminate_connection(srv_conn, reason);
70 }
71
72 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dcesrv_conn)
73 {
74         struct stream_connection *srv_conn;
75         srv_conn = talloc_get_type(dcesrv_conn->transport.private_data,
76                                    struct stream_connection);
77
78         if (srv_conn && srv_conn->event.fde) {
79                 EVENT_FD_WRITEABLE(srv_conn->event.fde);
80         }
81 }
82
83 static struct socket_address *dcesrv_sock_get_my_addr(struct dcesrv_connection *dcesrv_conn, TALLOC_CTX *mem_ctx)
84 {
85         struct stream_connection *srv_conn;
86         srv_conn = talloc_get_type(dcesrv_conn->transport.private_data,
87                                    struct stream_connection);
88
89         return socket_get_my_addr(srv_conn->socket, mem_ctx);
90 }
91
92 static struct socket_address *dcesrv_sock_get_peer_addr(struct dcesrv_connection *dcesrv_conn, TALLOC_CTX *mem_ctx)
93 {
94         struct stream_connection *srv_conn;
95         srv_conn = talloc_get_type(dcesrv_conn->transport.private_data,
96                                    struct stream_connection);
97
98         return socket_get_peer_addr(srv_conn->socket, mem_ctx);
99 }
100
101 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
102 {
103         NTSTATUS status;
104         struct dcesrv_socket_context *dcesrv_sock = 
105                 talloc_get_type(srv_conn->private, struct dcesrv_socket_context);
106         struct dcesrv_connection *dcesrv_conn = NULL;
107         struct auth_session_info *session_info = NULL;
108
109         status = auth_anonymous_session_info(srv_conn, &session_info);
110         if (!NT_STATUS_IS_OK(status)) {
111                 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n", 
112                         nt_errstr(status)));
113                 stream_terminate_connection(srv_conn, nt_errstr(status));
114                 return;
115         }
116
117         status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
118                                          srv_conn,
119                                          dcesrv_sock->endpoint,
120                                          session_info,
121                                          srv_conn->event.ctx,
122                                          srv_conn->msg_ctx,
123                                          srv_conn->server_id,
124                                          DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
125                                          &dcesrv_conn);
126         if (!NT_STATUS_IS_OK(status)) {
127                 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n", 
128                         nt_errstr(status)));
129                 stream_terminate_connection(srv_conn, nt_errstr(status));
130                 return;
131         }
132
133         dcesrv_conn->transport.private_data             = srv_conn;
134         dcesrv_conn->transport.report_output_data       = dcesrv_sock_report_output_data;
135         dcesrv_conn->transport.get_my_addr              = dcesrv_sock_get_my_addr;
136         dcesrv_conn->transport.get_peer_addr            = dcesrv_sock_get_peer_addr;
137
138         srv_conn->private = dcesrv_conn;
139
140         irpc_add_name(srv_conn->msg_ctx, "rpc_server");
141
142         return; 
143 }
144
145 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
146 {
147         NTSTATUS status;
148         struct dcesrv_connection *dce_conn = talloc_get_type(conn->private, struct dcesrv_connection);
149         DATA_BLOB tmp_blob;
150         size_t nread;
151
152         if (dce_conn->processing) {
153                 EVENT_FD_NOT_READABLE(conn->event.fde);
154                 return;
155         }
156
157         tmp_blob = data_blob_talloc(conn->socket, NULL, 0x1000);
158         if (tmp_blob.data == NULL) {
159                 dcesrv_terminate_connection(dce_conn, "out of memory");
160                 return;
161         }
162
163         status = socket_recv(conn->socket, tmp_blob.data, tmp_blob.length, &nread);
164         if (NT_STATUS_IS_ERR(status)) {
165                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
166                 return;
167         }
168         if (nread == 0) {
169                 talloc_free(tmp_blob.data);
170                 return;
171         }
172
173         tmp_blob.length = nread;
174
175         dce_conn->processing = True;
176         status = dcesrv_input(dce_conn, &tmp_blob);
177         dce_conn->processing = False;
178         talloc_free(tmp_blob.data);
179
180         EVENT_FD_READABLE(conn->event.fde);
181
182         if (!NT_STATUS_IS_OK(status)) {
183                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
184                 return;
185         }
186
187         if (dce_conn->call_list && dce_conn->call_list->replies) {
188                 EVENT_FD_WRITEABLE(conn->event.fde);
189         }
190 }
191
192 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
193 {
194         struct dcesrv_connection *dce_conn = talloc_get_type(conn->private, struct dcesrv_connection);
195         NTSTATUS status;
196
197         status = dcesrv_output(dce_conn, conn->socket, dcerpc_write_fn);
198         if (NT_STATUS_IS_ERR(status)) {
199                 dcesrv_terminate_connection(dce_conn, "eof on socket");
200                 return;
201         }
202
203         if (!dce_conn->call_list || !dce_conn->call_list->replies) {
204                 EVENT_FD_NOT_WRITEABLE(conn->event.fde);
205         }
206 }
207
208
209 static const struct stream_server_ops dcesrv_stream_ops = {
210         .name                   = "rpc",
211         .accept_connection      = dcesrv_sock_accept,
212         .recv_handler           = dcesrv_sock_recv,
213         .send_handler           = dcesrv_sock_send,
214 };
215
216
217
218 NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
219                             struct event_context *event_ctx, const struct model_ops *model_ops)
220 {
221         struct dcesrv_socket_context *dcesrv_sock;
222         uint16_t port = 1;
223         NTSTATUS status;
224
225         dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context);
226         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
227
228         /* remember the endpoint of this socket */
229         dcesrv_sock->endpoint           = e;
230         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
231
232         status = stream_setup_socket(event_ctx, model_ops, &dcesrv_stream_ops, 
233                                      "unix", e->ep_description->endpoint, &port, 
234                                      dcesrv_sock);
235         if (!NT_STATUS_IS_OK(status)) {
236                 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
237                          e->ep_description->endpoint, nt_errstr(status)));
238         }
239
240         return status;
241 }
242
243 NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
244                                struct event_context *event_ctx, const struct model_ops *model_ops)
245 {
246         struct dcesrv_socket_context *dcesrv_sock;
247         uint16_t port = 1;
248         char *full_path;
249         NTSTATUS status;
250
251         if (!e->ep_description->endpoint) {
252                 /* No identifier specified: use DEFAULT. 
253                  * DO NOT hardcode this value anywhere else. Rather, specify 
254                  * no endpoint and let the epmapper worry about it. */
255                 e->ep_description->endpoint = talloc_strdup(dce_ctx, "DEFAULT");
256         }
257
258         full_path = talloc_asprintf(dce_ctx, "%s/%s", lp_ncalrpc_dir(), e->ep_description->endpoint);
259
260         dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context);
261         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
262
263         /* remember the endpoint of this socket */
264         dcesrv_sock->endpoint           = e;
265         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
266
267         status = stream_setup_socket(event_ctx, model_ops, &dcesrv_stream_ops, 
268                                      "unix", full_path, &port, dcesrv_sock);
269         if (!NT_STATUS_IS_OK(status)) {
270                 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
271                          e->ep_description->endpoint, full_path, nt_errstr(status)));
272         }
273         return status;
274 }
275
276
277 /*
278   add a socket address to the list of events, one event per dcerpc endpoint
279 */
280 static NTSTATUS add_socket_rpc_pipe_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
281                                          struct event_context *event_ctx, const struct model_ops *model_ops)
282 {
283         struct dcesrv_socket_context *dcesrv_sock;
284         NTSTATUS status;
285                         
286         if (e->ep_description->endpoint == NULL) {
287                 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
288                 return NT_STATUS_INVALID_PARAMETER;
289         }
290
291         dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context);
292         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
293
294         /* remember the endpoint of this socket */
295         dcesrv_sock->endpoint           = e;
296         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
297
298         status = NT_STATUS_OK;
299 #if 0
300
301         status = stream_setup_smb_pipe(event_ctx, model_ops, &dcesrv_stream_ops, 
302                                      e->ep_description->endpoint, dcesrv_sock);
303         if (!NT_STATUS_IS_OK(status)) {
304                 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n", 
305                          e->ep_description->endpoint, nt_errstr(status)));
306         }
307 #endif
308         return status;
309 }
310
311 NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
312                                    struct event_context *event_ctx, const struct model_ops *model_ops)
313 {
314         NTSTATUS status;
315
316         status = add_socket_rpc_pipe_iface(dce_ctx, e, event_ctx, model_ops);
317         NT_STATUS_NOT_OK_RETURN(status);
318
319         return status;
320 }
321
322 /*
323   add a socket address to the list of events, one event per dcerpc endpoint
324 */
325 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
326                                          struct event_context *event_ctx, const struct model_ops *model_ops,
327                                          const char *address)
328 {
329         struct dcesrv_socket_context *dcesrv_sock;
330         uint16_t port = 0;
331         NTSTATUS status;
332                         
333         if (e->ep_description->endpoint) {
334                 port = atoi(e->ep_description->endpoint);
335         }
336
337         dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context);
338         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
339
340         /* remember the endpoint of this socket */
341         dcesrv_sock->endpoint           = e;
342         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
343
344         status = stream_setup_socket(event_ctx, model_ops, &dcesrv_stream_ops, 
345                                      "ipv4", address, &port, dcesrv_sock);
346         if (!NT_STATUS_IS_OK(status)) {
347                 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n", 
348                          address, port, nt_errstr(status)));
349         }
350
351         if (e->ep_description->endpoint == NULL) {
352                 e->ep_description->endpoint = talloc_asprintf(dce_ctx, "%d", port);
353         }
354
355         return status;
356 }
357
358 NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
359                                    struct event_context *event_ctx, const struct model_ops *model_ops)
360 {
361         NTSTATUS status;
362
363         /* Add TCP/IP sockets */
364         if (lp_interfaces() && lp_bind_interfaces_only()) {
365                 int num_interfaces = iface_count();
366                 int i;
367                 for(i = 0; i < num_interfaces; i++) {
368                         const char *address = iface_n_ip(i);
369                         status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
370                         NT_STATUS_NOT_OK_RETURN(status);
371                 }
372         } else {
373                 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, lp_socket_address());
374                 NT_STATUS_NOT_OK_RETURN(status);
375         }
376
377         return NT_STATUS_OK;
378 }
379
380
381 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
382                           struct event_context *event_ctx, const struct model_ops *model_ops)
383 {
384         switch (e->ep_description->transport) {
385         case NCACN_UNIX_STREAM:
386                 return dcesrv_add_ep_unix(dce_ctx, e, event_ctx, model_ops);
387
388         case NCALRPC:
389                 return dcesrv_add_ep_ncalrpc(dce_ctx, e, event_ctx, model_ops);
390
391         case NCACN_IP_TCP:
392                 return dcesrv_add_ep_tcp(dce_ctx, e, event_ctx, model_ops);
393
394         case NCACN_NP:
395                 return dcesrv_add_ep_np(dce_ctx, e, event_ctx, model_ops);
396
397         default:
398                 return NT_STATUS_NOT_SUPPORTED;
399         }
400 }
401
402 /*
403   open the dcerpc server sockets
404 */
405 static void dcesrv_task_init(struct task_server *task)
406 {
407         NTSTATUS status;
408         struct dcesrv_context *dce_ctx;
409         struct dcesrv_endpoint *e;
410
411         task_server_set_title(task, "task[dcesrv]");
412
413         status = dcesrv_init_context(task->event_ctx,
414                                      lp_dcerpc_endpoint_servers(),
415                                      &dce_ctx);
416         if (!NT_STATUS_IS_OK(status)) goto failed;
417
418         /* Make sure the directory for NCALRPC exists */
419         if (!directory_exist(lp_ncalrpc_dir())) {
420                 mkdir(lp_ncalrpc_dir(), 0755);
421         }
422
423         for (e=dce_ctx->endpoint_list;e;e=e->next) {
424                 status = dcesrv_add_ep(dce_ctx, e, task->event_ctx, task->model_ops);
425                 if (!NT_STATUS_IS_OK(status)) goto failed;
426         }
427
428         return;
429 failed:
430         task_server_terminate(task, "Failed to startup dcerpc server task");    
431 }
432
433 /*
434   called on startup of the smb server service It's job is to start
435   listening on all configured sockets
436 */
437 static NTSTATUS dcesrv_init(struct event_context *event_context, 
438                             const struct model_ops *model_ops)
439 {       
440         return task_server_startup(event_context, model_ops, dcesrv_task_init);
441 }
442
443 NTSTATUS server_service_rpc_init(void)
444 {
445         init_module_fn static_init[] = STATIC_dcerpc_server_MODULES;
446         init_module_fn *shared_init = load_samba_modules(NULL, "dcerpc_server");
447
448         run_init_functions(static_init);
449         run_init_functions(shared_init);
450
451         talloc_free(shared_init);
452         
453         return register_server_service("rpc", dcesrv_init);
454 }
455
456