b68cec4c7dba190167099a55e498e66319e75eaa
[kai/samba.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 "param/param.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
108         if (!srv_conn->session_info) {
109                 status = auth_anonymous_session_info(srv_conn,
110                                                      srv_conn->event.ctx,
111                                                      srv_conn->lp_ctx,
112                                                      &srv_conn->session_info);
113                 if (!NT_STATUS_IS_OK(status)) {
114                         DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
115                                 nt_errstr(status)));
116                         stream_terminate_connection(srv_conn, nt_errstr(status));
117                         return;
118                 }
119         }
120
121         status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
122                                          srv_conn,
123                                          dcesrv_sock->endpoint,
124                                          srv_conn->session_info,
125                                          srv_conn->event.ctx,
126                                          srv_conn->msg_ctx,
127                                          srv_conn->server_id,
128                                          DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
129                                          &dcesrv_conn);
130         if (!NT_STATUS_IS_OK(status)) {
131                 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n", 
132                         nt_errstr(status)));
133                 stream_terminate_connection(srv_conn, nt_errstr(status));
134                 return;
135         }
136
137         dcesrv_conn->transport.private_data             = srv_conn;
138         dcesrv_conn->transport.report_output_data       = dcesrv_sock_report_output_data;
139         dcesrv_conn->transport.get_my_addr              = dcesrv_sock_get_my_addr;
140         dcesrv_conn->transport.get_peer_addr            = dcesrv_sock_get_peer_addr;
141
142         srv_conn->private = dcesrv_conn;
143
144         irpc_add_name(srv_conn->msg_ctx, "rpc_server");
145
146         return; 
147 }
148
149 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
150 {
151         NTSTATUS status;
152         struct dcesrv_connection *dce_conn = talloc_get_type(conn->private, struct dcesrv_connection);
153         DATA_BLOB tmp_blob;
154         size_t nread;
155
156         if (dce_conn->processing) {
157                 EVENT_FD_NOT_READABLE(conn->event.fde);
158                 return;
159         }
160
161         tmp_blob = data_blob_talloc(conn->socket, NULL, 0x1000);
162         if (tmp_blob.data == NULL) {
163                 dcesrv_terminate_connection(dce_conn, "out of memory");
164                 return;
165         }
166
167         status = socket_recv(conn->socket, tmp_blob.data, tmp_blob.length, &nread);
168         if (NT_STATUS_IS_ERR(status)) {
169                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
170                 return;
171         }
172         if (nread == 0) {
173                 talloc_free(tmp_blob.data);
174                 return;
175         }
176
177         tmp_blob.length = nread;
178
179         dce_conn->processing = true;
180         status = dcesrv_input(dce_conn, &tmp_blob);
181         dce_conn->processing = false;
182         talloc_free(tmp_blob.data);
183
184         EVENT_FD_READABLE(conn->event.fde);
185
186         if (!NT_STATUS_IS_OK(status)) {
187                 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
188                 return;
189         }
190
191         if (dce_conn->call_list && dce_conn->call_list->replies) {
192                 EVENT_FD_WRITEABLE(conn->event.fde);
193         }
194 }
195
196 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
197 {
198         struct dcesrv_connection *dce_conn = talloc_get_type(conn->private, struct dcesrv_connection);
199         NTSTATUS status;
200
201         status = dcesrv_output(dce_conn, conn->socket, dcerpc_write_fn);
202         if (NT_STATUS_IS_ERR(status)) {
203                 dcesrv_terminate_connection(dce_conn, "eof on socket");
204                 return;
205         }
206
207         if (!dce_conn->call_list || !dce_conn->call_list->replies) {
208                 EVENT_FD_NOT_WRITEABLE(conn->event.fde);
209         }
210 }
211
212
213 static const struct stream_server_ops dcesrv_stream_ops = {
214         .name                   = "rpc",
215         .accept_connection      = dcesrv_sock_accept,
216         .recv_handler           = dcesrv_sock_recv,
217         .send_handler           = dcesrv_sock_send,
218 };
219
220
221
222 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx, 
223                                    struct loadparm_context *lp_ctx,
224                                    struct dcesrv_endpoint *e,
225                             struct event_context *event_ctx, const struct model_ops *model_ops)
226 {
227         struct dcesrv_socket_context *dcesrv_sock;
228         uint16_t port = 1;
229         NTSTATUS status;
230
231         dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context);
232         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
233
234         /* remember the endpoint of this socket */
235         dcesrv_sock->endpoint           = e;
236         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
237
238         status = stream_setup_socket(event_ctx, lp_ctx,
239                                      model_ops, &dcesrv_stream_ops, 
240                                      "unix", e->ep_description->endpoint, &port, 
241                                      lp_socket_options(lp_ctx), 
242                                      dcesrv_sock);
243         if (!NT_STATUS_IS_OK(status)) {
244                 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
245                          e->ep_description->endpoint, nt_errstr(status)));
246         }
247
248         return status;
249 }
250
251 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx, 
252                                       struct loadparm_context *lp_ctx,
253                                       struct dcesrv_endpoint *e,
254                                       struct event_context *event_ctx, const struct model_ops *model_ops)
255 {
256         struct dcesrv_socket_context *dcesrv_sock;
257         uint16_t port = 1;
258         char *full_path;
259         NTSTATUS status;
260
261         if (!e->ep_description->endpoint) {
262                 /* No identifier specified: use DEFAULT. 
263                  * DO NOT hardcode this value anywhere else. Rather, specify 
264                  * no endpoint and let the epmapper worry about it. */
265                 e->ep_description->endpoint = talloc_strdup(dce_ctx, "DEFAULT");
266         }
267
268         full_path = talloc_asprintf(dce_ctx, "%s/%s", lp_ncalrpc_dir(lp_ctx), 
269                                     e->ep_description->endpoint);
270
271         dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context);
272         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
273
274         /* remember the endpoint of this socket */
275         dcesrv_sock->endpoint           = e;
276         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
277
278         status = stream_setup_socket(event_ctx, lp_ctx,
279                                      model_ops, &dcesrv_stream_ops, 
280                                      "unix", full_path, &port, 
281                                      lp_socket_options(lp_ctx), 
282                                      dcesrv_sock);
283         if (!NT_STATUS_IS_OK(status)) {
284                 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
285                          e->ep_description->endpoint, full_path, nt_errstr(status)));
286         }
287         return status;
288 }
289
290
291 /*
292   add a socket address to the list of events, one event per dcerpc endpoint
293 */
294 static NTSTATUS add_socket_rpc_pipe_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
295                                          struct event_context *event_ctx, const struct model_ops *model_ops)
296 {
297         struct dcesrv_socket_context *dcesrv_sock;
298         NTSTATUS status;
299                         
300         if (e->ep_description->endpoint == NULL) {
301                 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
302                 return NT_STATUS_INVALID_PARAMETER;
303         }
304
305         dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context);
306         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
307
308         /* remember the endpoint of this socket */
309         dcesrv_sock->endpoint           = e;
310         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
311
312         status = NT_STATUS_OK;
313 #if 0
314
315         status = stream_setup_smb_pipe(event_ctx, model_ops, &dcesrv_stream_ops, 
316                                      e->ep_description->endpoint, dcesrv_sock);
317         if (!NT_STATUS_IS_OK(status)) {
318                 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n", 
319                          e->ep_description->endpoint, nt_errstr(status)));
320         }
321 #endif
322         return status;
323 }
324
325 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx, 
326                                  struct loadparm_context *lp_ctx,
327                                  struct dcesrv_endpoint *e,
328                                  struct event_context *event_ctx, const struct model_ops *model_ops)
329 {
330         NTSTATUS status;
331
332         status = add_socket_rpc_pipe_iface(dce_ctx, e, event_ctx, model_ops);
333         NT_STATUS_NOT_OK_RETURN(status);
334
335         return status;
336 }
337
338 /*
339   add a socket address to the list of events, one event per dcerpc endpoint
340 */
341 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
342                                          struct event_context *event_ctx, const struct model_ops *model_ops,
343                                          const char *address)
344 {
345         struct dcesrv_socket_context *dcesrv_sock;
346         uint16_t port = 0;
347         NTSTATUS status;
348                         
349         if (e->ep_description->endpoint) {
350                 port = atoi(e->ep_description->endpoint);
351         }
352
353         dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context);
354         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
355
356         /* remember the endpoint of this socket */
357         dcesrv_sock->endpoint           = e;
358         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
359
360         status = stream_setup_socket(event_ctx, dce_ctx->lp_ctx,
361                                      model_ops, &dcesrv_stream_ops, 
362                                      "ipv4", address, &port, 
363                                      lp_socket_options(dce_ctx->lp_ctx), 
364                                      dcesrv_sock);
365         if (!NT_STATUS_IS_OK(status)) {
366                 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n", 
367                          address, port, nt_errstr(status)));
368         }
369
370         if (e->ep_description->endpoint == NULL) {
371                 e->ep_description->endpoint = talloc_asprintf(dce_ctx, "%d", port);
372         }
373
374         return status;
375 }
376
377 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx, 
378                                   struct loadparm_context *lp_ctx,
379                                   struct dcesrv_endpoint *e,
380                                   struct event_context *event_ctx, const struct model_ops *model_ops)
381 {
382         NTSTATUS status;
383
384         /* Add TCP/IP sockets */
385         if (lp_interfaces(lp_ctx) && lp_bind_interfaces_only(lp_ctx)) {
386                 int num_interfaces;
387                 int i;
388                 struct interface *ifaces;
389
390                 load_interfaces(dce_ctx, lp_interfaces(lp_ctx), &ifaces);
391
392                 num_interfaces = iface_count(ifaces);
393                 for(i = 0; i < num_interfaces; i++) {
394                         const char *address = iface_n_ip(ifaces, i);
395                         status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
396                         NT_STATUS_NOT_OK_RETURN(status);
397                 }
398         } else {
399                 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, 
400                                                   lp_socket_address(lp_ctx));
401                 NT_STATUS_NOT_OK_RETURN(status);
402         }
403
404         return NT_STATUS_OK;
405 }
406
407
408 static NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx, 
409                               struct loadparm_context *lp_ctx,
410                               struct dcesrv_endpoint *e,
411                           struct event_context *event_ctx, const struct model_ops *model_ops)
412 {
413         switch (e->ep_description->transport) {
414         case NCACN_UNIX_STREAM:
415                 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
416
417         case NCALRPC:
418                 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
419
420         case NCACN_IP_TCP:
421                 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
422
423         case NCACN_NP:
424                 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
425
426         default:
427                 return NT_STATUS_NOT_SUPPORTED;
428         }
429 }
430
431 /*
432   open the dcerpc server sockets
433 */
434 static void dcesrv_task_init(struct task_server *task)
435 {
436         NTSTATUS status;
437         struct dcesrv_context *dce_ctx;
438         struct dcesrv_endpoint *e;
439
440         task_server_set_title(task, "task[dcesrv]");
441
442         status = dcesrv_init_context(task->event_ctx,
443                                      task->lp_ctx,
444                                      lp_dcerpc_endpoint_servers(task->lp_ctx),
445                                      &dce_ctx);
446         if (!NT_STATUS_IS_OK(status)) goto failed;
447
448         /* Make sure the directory for NCALRPC exists */
449         if (!directory_exist(lp_ncalrpc_dir(task->lp_ctx))) {
450                 mkdir(lp_ncalrpc_dir(task->lp_ctx), 0755);
451         }
452
453         for (e=dce_ctx->endpoint_list;e;e=e->next) {
454                 status = dcesrv_add_ep(dce_ctx, task->lp_ctx, e, task->event_ctx, task->model_ops);
455                 if (!NT_STATUS_IS_OK(status)) goto failed;
456         }
457
458         return;
459 failed:
460         task_server_terminate(task, "Failed to startup dcerpc server task");    
461 }
462
463 NTSTATUS server_service_rpc_init(void)
464 {
465         extern NTSTATUS dcerpc_server_wkssvc_init(void);
466         extern NTSTATUS dcerpc_server_drsuapi_init(void);
467         extern NTSTATUS dcerpc_server_winreg_init(void);
468         extern NTSTATUS dcerpc_server_spoolss_init(void);
469         extern NTSTATUS dcerpc_server_epmapper_init(void);
470         extern NTSTATUS dcerpc_server_srvsvc_init(void);
471         extern NTSTATUS dcerpc_server_netlogon_init(void);
472         extern NTSTATUS dcerpc_server_rpcecho_init(void);
473         extern NTSTATUS dcerpc_server_unixinfo_init(void);
474         extern NTSTATUS dcerpc_server_samr_init(void);
475         extern NTSTATUS dcerpc_server_remote_init(void);
476         extern NTSTATUS dcerpc_server_lsa_init(void);
477         init_module_fn static_init[] = { STATIC_DCESRV_MODULES };
478         init_module_fn *shared_init = load_samba_modules(NULL, global_loadparm, "dcerpc_server");
479
480         run_init_functions(static_init);
481         run_init_functions(shared_init);
482
483         talloc_free(shared_init);
484         
485         return register_server_service("rpc", dcesrv_task_init);
486 }