26bb2402e8d49b47701ea47fb5dcc0a80ac141c1
[samba.git] / source4 / ldap_server / ldap_server.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    LDAP server
5
6    Copyright (C) Andrew Tridgell 2005
7    Copyright (C) Volker Lendecke 2004
8    Copyright (C) Stefan Metzmacher 2004
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 2 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, write to the Free Software
22    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25 #include "includes.h"
26 #include "lib/events/events.h"
27 #include "auth/auth.h"
28 #include "dlinklist.h"
29 #include "asn_1.h"
30 #include "ldap_server/ldap_server.h"
31 #include "smbd/service_task.h"
32 #include "smbd/service_stream.h"
33 #include "lib/socket/socket.h"
34 #include "lib/tls/tls.h"
35 #include "lib/messaging/irpc.h"
36 #include "lib/stream/packet.h"
37
38 /*
39   close the socket and shutdown a server_context
40 */
41 static void ldapsrv_terminate_connection(struct ldapsrv_connection *conn, 
42                                          const char *reason)
43 {
44         if (conn->tls) {
45                 talloc_free(conn->tls);
46                 conn->tls = NULL;
47         }
48         stream_terminate_connection(conn->connection, reason);
49 }
50
51 /*
52   handle packet errors
53 */
54 static void ldapsrv_error_handler(void *private, NTSTATUS status)
55 {
56         struct ldapsrv_connection *conn = talloc_get_type(private, 
57                                                           struct ldapsrv_connection);
58         ldapsrv_terminate_connection(conn, nt_errstr(status));
59 }
60
61 /*
62   process a decoded ldap message
63 */
64 static void ldapsrv_process_message(struct ldapsrv_connection *conn,
65                                     struct ldap_message *msg)
66 {
67         struct ldapsrv_call *call;
68         NTSTATUS status;
69         DATA_BLOB blob;
70         BOOL enable_wrap = conn->enable_wrap;
71
72         call = talloc(conn, struct ldapsrv_call);
73         if (!call) {
74                 ldapsrv_terminate_connection(conn, "no memory");
75                 return;         
76         }
77         
78         call->request = talloc_steal(call, msg);
79         call->conn = conn;
80         call->replies = NULL;
81
82         /* make the call */
83         status = ldapsrv_do_call(call);
84         if (!NT_STATUS_IS_OK(status)) {
85                 goto failed;
86         }
87         
88         blob = data_blob(NULL, 0);
89
90         if (call->replies == NULL) {
91                 talloc_free(call);
92                 return;
93         }
94
95         /* build all the replies into a single blob */
96         while (call->replies) {
97                 DATA_BLOB b;
98
99                 msg = call->replies->msg;
100                 if (!ldap_encode(msg, &b, call)) {
101                         DEBUG(0,("Failed to encode ldap reply of type %d\n", msg->type));
102                         goto failed;
103                 }
104
105                 status = data_blob_append(call, &blob, b.data, b.length);
106                 data_blob_free(&b);
107
108                 if (!NT_STATUS_IS_OK(status)) goto failed;
109
110                 DLIST_REMOVE(call->replies, call->replies);
111         }
112
113         /* possibly encrypt/sign the reply */
114         if (enable_wrap) {
115                 DATA_BLOB wrapped;
116
117                 status = gensec_wrap(conn->gensec, call, &blob, &wrapped);
118                 if (!NT_STATUS_IS_OK(status)) {
119                         goto failed;
120                 }
121                 data_blob_free(&blob);
122                 blob = data_blob_talloc(call, NULL, wrapped.length + 4);
123                 if (blob.data == NULL) {
124                         goto failed;
125                 }
126                 RSIVAL(blob.data, 0, wrapped.length);
127                 memcpy(blob.data+4, wrapped.data, wrapped.length);
128                 data_blob_free(&wrapped);
129         }
130
131         packet_send(conn->packet, blob);
132         talloc_free(call);
133         return;
134
135 failed:
136         talloc_free(call);
137 }
138
139
140 /*
141   decode the input buffer
142 */
143 static NTSTATUS ldapsrv_decode_plain(struct ldapsrv_connection *conn, DATA_BLOB blob)
144 {
145         struct asn1_data asn1;
146         struct ldap_message *msg = talloc(conn, struct ldap_message);
147
148         if (msg == NULL) {
149                 return NT_STATUS_NO_MEMORY;
150         }
151
152         if (!asn1_load(&asn1, blob)) {
153                 return NT_STATUS_NO_MEMORY;
154         }
155
156         if (!ldap_decode(&asn1, msg)) {
157                 asn1_free(&asn1);
158                 return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
159         }
160
161         data_blob_free(&blob);
162         ldapsrv_process_message(conn, msg);
163         asn1_free(&asn1);
164         return NT_STATUS_OK;
165 }
166
167
168 /*
169   decode/process wrapped data
170 */
171 static NTSTATUS ldapsrv_decode_wrapped(struct ldapsrv_connection *conn, 
172                                        DATA_BLOB blob)
173 {
174         DATA_BLOB wrapped, unwrapped;
175         struct asn1_data asn1;
176         struct ldap_message *msg = talloc(conn, struct ldap_message);
177         NTSTATUS status;
178
179         if (msg == NULL) {
180                 return NT_STATUS_NO_MEMORY;
181         }
182
183         wrapped = data_blob_const(blob.data+4, blob.length-4);
184
185         status = gensec_unwrap(conn->gensec, msg, &wrapped, &unwrapped);
186         if (!NT_STATUS_IS_OK(status)) {
187                 return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
188         }
189
190         data_blob_free(&blob);
191
192         if (!asn1_load(&asn1, unwrapped)) {
193                 return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
194         }
195
196         while (ldap_decode(&asn1, msg)) {
197                 ldapsrv_process_message(conn, msg);
198                 msg = talloc(conn, struct ldap_message);
199         }
200
201         if (asn1.ofs < asn1.length) {
202                 return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
203         }
204                 
205         talloc_free(msg);
206         asn1_free(&asn1);
207
208         return NT_STATUS_OK;
209 }
210
211 /*
212   decode/process data
213 */
214 static NTSTATUS ldapsrv_decode(void *private, DATA_BLOB blob)
215 {
216         struct ldapsrv_connection *conn = talloc_get_type(private, 
217                                                           struct ldapsrv_connection);
218         if (conn->enable_wrap) {
219                 return ldapsrv_decode_wrapped(conn, blob);
220         }
221         return ldapsrv_decode_plain(conn, blob);
222 }
223
224 /*
225   called when a LDAP socket becomes readable
226 */
227 static void ldapsrv_recv(struct stream_connection *c, uint16_t flags)
228 {
229         struct ldapsrv_connection *conn = 
230                 talloc_get_type(c->private, struct ldapsrv_connection);
231         
232         packet_recv(conn->packet);
233 }
234
235 /*
236   check if a blob is a complete ldap packet
237   handle wrapper or unwrapped connections
238 */
239 NTSTATUS ldapsrv_complete_packet(void *private, DATA_BLOB blob, size_t *size)
240 {
241         struct ldapsrv_connection *conn = talloc_get_type(private, 
242                                                           struct ldapsrv_connection);
243         if (conn->enable_wrap) {
244                 return packet_full_request_u32(private, blob, size);
245         }
246         return ldap_full_packet(private, blob, size);
247 }
248         
249 /*
250   called when a LDAP socket becomes writable
251 */
252 static void ldapsrv_send(struct stream_connection *c, uint16_t flags)
253 {
254         struct ldapsrv_connection *conn = 
255                 talloc_get_type(c->private, struct ldapsrv_connection);
256         
257         packet_queue_run(conn->packet);
258 }
259
260 /*
261   initialise a server_context from a open socket and register a event handler
262   for reading from that socket
263 */
264 static void ldapsrv_accept(struct stream_connection *c)
265 {
266         struct ldapsrv_partition *part;
267         struct ldapsrv_service *ldapsrv_service = 
268                 talloc_get_type(c->private, struct ldapsrv_service);
269         struct ldapsrv_connection *conn;
270         struct cli_credentials *server_credentials;
271         NTSTATUS status;
272         int port;
273
274         conn = talloc_zero(c, struct ldapsrv_connection);
275         if (!conn) {
276                 stream_terminate_connection(c, "ldapsrv_accept: out of memory");
277                 return;
278         }
279
280         conn->enable_wrap = False;
281         conn->packet      = NULL;
282         conn->connection  = c;
283         conn->service     = ldapsrv_service;
284
285         server_credentials 
286                 = cli_credentials_init(conn);
287         if (!server_credentials) {
288                 stream_terminate_connection(c, "Failed to init server credentials\n");
289                 talloc_free(conn);
290                 return;
291         }
292         
293         cli_credentials_set_conf(server_credentials);
294         status = cli_credentials_set_machine_account(server_credentials);
295         if (!NT_STATUS_IS_OK(status)) {
296                 stream_terminate_connection(c, talloc_asprintf(conn, "Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(status)));
297                 talloc_free(conn);
298                 return;
299         }
300         conn->server_credentials = server_credentials;
301
302         c->private        = conn;
303
304         port = socket_get_my_port(c->socket);
305
306         conn->tls = tls_init_server(ldapsrv_service->tls_params, c->socket, 
307                                     c->event.fde, NULL, port != 389);
308         if (!conn->tls) {
309                 ldapsrv_terminate_connection(conn, "ldapsrv_accept: tls_init_server() failed");
310                 return;
311         }
312
313         conn->packet = packet_init(conn);
314         if (conn->packet == NULL) {
315                 ldapsrv_terminate_connection(conn, "out of memory");
316                 return;
317         }
318         packet_set_private(conn->packet, conn);
319         packet_set_tls(conn->packet, conn->tls);
320         packet_set_callback(conn->packet, ldapsrv_decode);
321         packet_set_full_request(conn->packet, ldapsrv_complete_packet);
322         packet_set_error_handler(conn->packet, ldapsrv_error_handler);
323         packet_set_event_context(conn->packet, c->event.ctx);
324         packet_set_fde(conn->packet, c->event.fde);
325         packet_set_serialise(conn->packet);
326
327         /* Connections start out anonymous */
328         if (!NT_STATUS_IS_OK(auth_anonymous_session_info(conn, &conn->session_info))) {
329                 ldapsrv_terminate_connection(conn, "failed to setup anonymous session info");
330                 return;
331         }
332
333         part = talloc(conn, struct ldapsrv_partition);
334         if (part == NULL) {
335                 ldapsrv_terminate_connection(conn, "talloc failed");
336                 return;
337         }
338
339         part->base_dn = "*"; /* default partition */
340         part->ops = ldapsrv_get_sldb_partition_ops();
341         if (!NT_STATUS_IS_OK(part->ops->Init(part, conn))) {
342                 ldapsrv_terminate_connection(conn, "default partition Init failed");
343                 return;
344         }
345
346         conn->default_partition = part;
347         DLIST_ADD_END(conn->partitions, part, struct ldapsrv_partition *);
348
349         irpc_add_name(c->msg_ctx, "ldap_server");
350 }
351
352 static const struct stream_server_ops ldap_stream_ops = {
353         .name                   = "ldap",
354         .accept_connection      = ldapsrv_accept,
355         .recv_handler           = ldapsrv_recv,
356         .send_handler           = ldapsrv_send,
357 };
358
359 /*
360   add a socket address to the list of events, one event per port
361 */
362 static NTSTATUS add_socket(struct event_context *event_context,
363                            const struct model_ops *model_ops,
364                            const char *address, struct ldapsrv_service *ldap_service)
365 {
366         uint16_t port = 389;
367         NTSTATUS status;
368
369         status = stream_setup_socket(event_context, model_ops, &ldap_stream_ops, 
370                                      "ipv4", address, &port, ldap_service);
371         if (!NT_STATUS_IS_OK(status)) {
372                 DEBUG(0,("ldapsrv failed to bind to %s:%u - %s\n",
373                          address, port, nt_errstr(status)));
374         }
375
376         if (tls_support(ldap_service->tls_params)) {
377                 /* add ldaps server */
378                 port = 636;
379                 status = stream_setup_socket(event_context, model_ops, &ldap_stream_ops, 
380                                              "ipv4", address, &port, ldap_service);
381                 if (!NT_STATUS_IS_OK(status)) {
382                         DEBUG(0,("ldapsrv failed to bind to %s:%u - %s\n",
383                                  address, port, nt_errstr(status)));
384                 }
385         }
386
387         /* if we are a PDC, then also enable the global catalog server port, 3268 */
388         if (lp_server_role() == ROLE_DOMAIN_PDC) {
389                 port = 3268;
390                 status = stream_setup_socket(event_context, model_ops, &ldap_stream_ops, 
391                                              "ipv4", address, &port, ldap_service);
392                 if (!NT_STATUS_IS_OK(status)) {
393                         DEBUG(0,("ldapsrv failed to bind to %s:%u - %s\n",
394                                  address, port, nt_errstr(status)));
395                 }
396         }
397
398         return status;
399 }
400
401 /*
402   open the ldap server sockets
403 */
404 static void ldapsrv_task_init(struct task_server *task)
405 {       
406         struct ldapsrv_service *ldap_service;
407         NTSTATUS status;
408
409         ldap_service = talloc_zero(task, struct ldapsrv_service);
410         if (ldap_service == NULL) goto failed;
411
412         ldap_service->tls_params = tls_initialise(ldap_service);
413         if (ldap_service->tls_params == NULL) goto failed;
414
415         if (lp_interfaces() && lp_bind_interfaces_only()) {
416                 int num_interfaces = iface_count();
417                 int i;
418
419                 /* We have been given an interfaces line, and been 
420                    told to only bind to those interfaces. Create a
421                    socket per interface and bind to only these.
422                 */
423                 for(i = 0; i < num_interfaces; i++) {
424                         const char *address = iface_n_ip(i);
425                         status = add_socket(task->event_ctx, task->model_ops, address, ldap_service);
426                         if (!NT_STATUS_IS_OK(status)) goto failed;
427                 }
428         } else {
429                 status = add_socket(task->event_ctx, task->model_ops, lp_socket_address(), ldap_service);
430                 if (!NT_STATUS_IS_OK(status)) goto failed;
431         }
432
433         return;
434
435 failed:
436         task_server_terminate(task, "Failed to startup ldap server task");      
437 }
438
439 /*
440   called on startup of the web server service It's job is to start
441   listening on all configured sockets
442 */
443 static NTSTATUS ldapsrv_init(struct event_context *event_context, 
444                              const struct model_ops *model_ops)
445 {       
446         return task_server_startup(event_context, model_ops, ldapsrv_task_init);
447 }
448
449
450 NTSTATUS server_service_ldap_init(void)
451 {
452         return register_server_service("ldap", ldapsrv_init);
453 }