Merge branch 'v4-0-test' into v4-0-gmake3
[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         struct auth_session_info *session_info = NULL;
108
109         status = auth_anonymous_session_info(srv_conn, srv_conn->event.ctx, dcesrv_sock->dcesrv_ctx->lp_ctx, &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 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx, 
219                                    struct loadparm_context *lp_ctx,
220                                    struct dcesrv_endpoint *e,
221                             struct event_context *event_ctx, const struct model_ops *model_ops)
222 {
223         struct dcesrv_socket_context *dcesrv_sock;
224         uint16_t port = 1;
225         NTSTATUS status;
226
227         dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context);
228         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
229
230         /* remember the endpoint of this socket */
231         dcesrv_sock->endpoint           = e;
232         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
233
234         status = stream_setup_socket(event_ctx, lp_ctx,
235                                      model_ops, &dcesrv_stream_ops, 
236                                      "unix", e->ep_description->endpoint, &port, 
237                                      lp_socket_options(lp_ctx), 
238                                      dcesrv_sock);
239         if (!NT_STATUS_IS_OK(status)) {
240                 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
241                          e->ep_description->endpoint, nt_errstr(status)));
242         }
243
244         return status;
245 }
246
247 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx, 
248                                       struct loadparm_context *lp_ctx,
249                                       struct dcesrv_endpoint *e,
250                                       struct event_context *event_ctx, const struct model_ops *model_ops)
251 {
252         struct dcesrv_socket_context *dcesrv_sock;
253         uint16_t port = 1;
254         char *full_path;
255         NTSTATUS status;
256
257         if (!e->ep_description->endpoint) {
258                 /* No identifier specified: use DEFAULT. 
259                  * DO NOT hardcode this value anywhere else. Rather, specify 
260                  * no endpoint and let the epmapper worry about it. */
261                 e->ep_description->endpoint = talloc_strdup(dce_ctx, "DEFAULT");
262         }
263
264         full_path = talloc_asprintf(dce_ctx, "%s/%s", lp_ncalrpc_dir(lp_ctx), 
265                                     e->ep_description->endpoint);
266
267         dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context);
268         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
269
270         /* remember the endpoint of this socket */
271         dcesrv_sock->endpoint           = e;
272         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
273
274         status = stream_setup_socket(event_ctx, lp_ctx,
275                                      model_ops, &dcesrv_stream_ops, 
276                                      "unix", full_path, &port, 
277                                      lp_socket_options(lp_ctx), 
278                                      dcesrv_sock);
279         if (!NT_STATUS_IS_OK(status)) {
280                 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
281                          e->ep_description->endpoint, full_path, nt_errstr(status)));
282         }
283         return status;
284 }
285
286
287 /*
288   add a socket address to the list of events, one event per dcerpc endpoint
289 */
290 static NTSTATUS add_socket_rpc_pipe_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
291                                          struct event_context *event_ctx, const struct model_ops *model_ops)
292 {
293         struct dcesrv_socket_context *dcesrv_sock;
294         NTSTATUS status;
295                         
296         if (e->ep_description->endpoint == NULL) {
297                 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
298                 return NT_STATUS_INVALID_PARAMETER;
299         }
300
301         dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context);
302         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
303
304         /* remember the endpoint of this socket */
305         dcesrv_sock->endpoint           = e;
306         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
307
308         status = NT_STATUS_OK;
309 #if 0
310
311         status = stream_setup_smb_pipe(event_ctx, model_ops, &dcesrv_stream_ops, 
312                                      e->ep_description->endpoint, dcesrv_sock);
313         if (!NT_STATUS_IS_OK(status)) {
314                 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n", 
315                          e->ep_description->endpoint, nt_errstr(status)));
316         }
317 #endif
318         return status;
319 }
320
321 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx, 
322                                  struct loadparm_context *lp_ctx,
323                                  struct dcesrv_endpoint *e,
324                                  struct event_context *event_ctx, const struct model_ops *model_ops)
325 {
326         NTSTATUS status;
327
328         status = add_socket_rpc_pipe_iface(dce_ctx, e, event_ctx, model_ops);
329         NT_STATUS_NOT_OK_RETURN(status);
330
331         return status;
332 }
333
334 /*
335   add a socket address to the list of events, one event per dcerpc endpoint
336 */
337 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
338                                          struct event_context *event_ctx, const struct model_ops *model_ops,
339                                          const char *address)
340 {
341         struct dcesrv_socket_context *dcesrv_sock;
342         uint16_t port = 0;
343         NTSTATUS status;
344                         
345         if (e->ep_description->endpoint) {
346                 port = atoi(e->ep_description->endpoint);
347         }
348
349         dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context);
350         NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
351
352         /* remember the endpoint of this socket */
353         dcesrv_sock->endpoint           = e;
354         dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
355
356         status = stream_setup_socket(event_ctx, dce_ctx->lp_ctx,
357                                      model_ops, &dcesrv_stream_ops, 
358                                      "ipv4", address, &port, 
359                                      lp_socket_options(dce_ctx->lp_ctx), 
360                                      dcesrv_sock);
361         if (!NT_STATUS_IS_OK(status)) {
362                 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n", 
363                          address, port, nt_errstr(status)));
364         }
365
366         if (e->ep_description->endpoint == NULL) {
367                 e->ep_description->endpoint = talloc_asprintf(dce_ctx, "%d", port);
368         }
369
370         return status;
371 }
372
373 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx, 
374                                   struct loadparm_context *lp_ctx,
375                                   struct dcesrv_endpoint *e,
376                                   struct event_context *event_ctx, const struct model_ops *model_ops)
377 {
378         NTSTATUS status;
379
380         /* Add TCP/IP sockets */
381         if (lp_interfaces(lp_ctx) && lp_bind_interfaces_only(lp_ctx)) {
382                 int num_interfaces;
383                 int i;
384                 struct interface *ifaces;
385
386                 load_interfaces(dce_ctx, lp_interfaces(lp_ctx), &ifaces);
387
388                 num_interfaces = iface_count(ifaces);
389                 for(i = 0; i < num_interfaces; i++) {
390                         const char *address = iface_n_ip(ifaces, i);
391                         status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
392                         NT_STATUS_NOT_OK_RETURN(status);
393                 }
394         } else {
395                 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, 
396                                                   lp_socket_address(lp_ctx));
397                 NT_STATUS_NOT_OK_RETURN(status);
398         }
399
400         return NT_STATUS_OK;
401 }
402
403
404 static NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx, 
405                               struct loadparm_context *lp_ctx,
406                               struct dcesrv_endpoint *e,
407                           struct event_context *event_ctx, const struct model_ops *model_ops)
408 {
409         switch (e->ep_description->transport) {
410         case NCACN_UNIX_STREAM:
411                 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
412
413         case NCALRPC:
414                 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
415
416         case NCACN_IP_TCP:
417                 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
418
419         case NCACN_NP:
420                 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
421
422         default:
423                 return NT_STATUS_NOT_SUPPORTED;
424         }
425 }
426
427 /*
428   open the dcerpc server sockets
429 */
430 static void dcesrv_task_init(struct task_server *task)
431 {
432         NTSTATUS status;
433         struct dcesrv_context *dce_ctx;
434         struct dcesrv_endpoint *e;
435
436         task_server_set_title(task, "task[dcesrv]");
437
438         status = dcesrv_init_context(task->event_ctx,
439                                      task->lp_ctx,
440                                      lp_dcerpc_endpoint_servers(task->lp_ctx),
441                                      &dce_ctx);
442         if (!NT_STATUS_IS_OK(status)) goto failed;
443
444         /* Make sure the directory for NCALRPC exists */
445         if (!directory_exist(lp_ncalrpc_dir(task->lp_ctx))) {
446                 mkdir(lp_ncalrpc_dir(task->lp_ctx), 0755);
447         }
448
449         for (e=dce_ctx->endpoint_list;e;e=e->next) {
450                 status = dcesrv_add_ep(dce_ctx, task->lp_ctx, e, task->event_ctx, task->model_ops);
451                 if (!NT_STATUS_IS_OK(status)) goto failed;
452         }
453
454         return;
455 failed:
456         task_server_terminate(task, "Failed to startup dcerpc server task");    
457 }
458
459 NTSTATUS server_service_rpc_init(void)
460 {
461         extern NTSTATUS dcerpc_server_wkssvc_init(void);
462         extern NTSTATUS dcerpc_server_drsuapi_init(void);
463         extern NTSTATUS dcerpc_server_winreg_init(void);
464         extern NTSTATUS dcerpc_server_spoolss_init(void);
465         extern NTSTATUS dcerpc_server_epmapper_init(void);
466         extern NTSTATUS dcerpc_server_srvsvc_init(void);
467         extern NTSTATUS dcerpc_server_netlogon_init(void);
468         extern NTSTATUS dcerpc_server_rpcecho_init(void);
469         extern NTSTATUS dcerpc_server_unixinfo_init(void);
470         extern NTSTATUS dcerpc_server_samr_init(void);
471         extern NTSTATUS dcerpc_server_remote_init(void);
472         extern NTSTATUS dcerpc_server_lsa_init(void);
473         init_module_fn static_init[] = { STATIC_DCESRV_MODULES };
474         init_module_fn *shared_init = load_samba_modules(NULL, global_loadparm, "dcerpc_server");
475
476         run_init_functions(static_init);
477         run_init_functions(shared_init);
478
479         talloc_free(shared_init);
480         
481         return register_server_service("rpc", dcesrv_task_init);
482 }