5a67ab79058dd0cec331d12c86b7b99370731532
[ambi/samba-autobuild/.git] / source3 / lib / smbldap.c
1 /* 
2    Unix SMB/CIFS implementation.
3    LDAP protocol helper functions for SAMBA
4    Copyright (C) Jean François Micouleau       1998
5    Copyright (C) Gerald Carter                  2001-2003
6    Copyright (C) Shahms King                    2001
7    Copyright (C) Andrew Bartlett                2002-2003
8    Copyright (C) Stefan (metze) Metzmacher      2002-2003
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
25 #include "includes.h"
26 #include "smbldap.h"
27 #include "../libcli/security/security.h"
28 #include <tevent.h>
29 #include "lib/param/loadparm.h"
30
31 /* Try not to hit the up or down server forever */
32
33 #define SMBLDAP_DONT_PING_TIME 10       /* ping only all 10 seconds */
34 #define SMBLDAP_NUM_RETRIES 8           /* retry only 8 times */
35
36 #define SMBLDAP_IDLE_TIME 150           /* After 2.5 minutes disconnect */
37
38 struct smbldap_state {
39         LDAP *ldap_struct;
40         pid_t pid;
41         time_t last_ping; /* monotonic */
42         /* retrieve-once info */
43         const char *uri;
44
45         /* credentials */
46         bool anonymous;
47         char *bind_dn;
48         char *bind_secret;
49         smbldap_bind_callback_fn bind_callback;
50         void *bind_callback_data;
51
52         bool paged_results;
53
54         unsigned int num_failures;
55
56         time_t last_use; /* monotonic */
57         struct tevent_context *tevent_context;
58         struct tevent_timer *idle_event;
59
60         struct timeval last_rebind; /* monotonic */
61 };
62
63 LDAP *smbldap_get_ldap(struct smbldap_state *state)
64 {
65         return state->ldap_struct;
66 }
67
68 bool smbldap_get_paged_results(struct smbldap_state *state)
69 {
70         return state->paged_results;
71 }
72
73 void smbldap_set_paged_results(struct smbldap_state *state,
74                                bool paged_results)
75 {
76         state->paged_results = paged_results;
77 }
78
79 void smbldap_set_bind_callback(struct smbldap_state *state,
80                                smbldap_bind_callback_fn callback,
81                                void *callback_data)
82 {
83         state->bind_callback = callback;
84         state->bind_callback_data = callback_data;
85 }
86 /*******************************************************************
87  Search an attribute and return the first value found.
88 ******************************************************************/
89
90  bool smbldap_get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
91                                     const char *attribute, char *value,
92                                     int max_len)
93 {
94         char **values;
95         size_t size = 0;
96
97         if ( !attribute )
98                 return False;
99
100         value[0] = '\0';
101
102         if ((values = ldap_get_values (ldap_struct, entry, attribute)) == NULL) {
103                 DEBUG (10, ("smbldap_get_single_attribute: [%s] = [<does not exist>]\n", attribute));
104
105                 return False;
106         }
107
108         if (!convert_string(CH_UTF8, CH_UNIX,values[0], -1, value, max_len, &size)) {
109                 DEBUG(1, ("smbldap_get_single_attribute: string conversion of [%s] = [%s] failed!\n", 
110                           attribute, values[0]));
111                 ldap_value_free(values);
112                 return False;
113         }
114
115         ldap_value_free(values);
116 #ifdef DEBUG_PASSWORDS
117         DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n", attribute, value));
118 #endif  
119         return True;
120 }
121
122  char * smbldap_talloc_single_attribute(LDAP *ldap_struct, LDAPMessage *entry,
123                                         const char *attribute,
124                                         TALLOC_CTX *mem_ctx)
125 {
126         char **values;
127         char *result;
128         size_t converted_size;
129
130         if (attribute == NULL) {
131                 return NULL;
132         }
133
134         values = ldap_get_values(ldap_struct, entry, attribute);
135
136         if (values == NULL) {
137                 DEBUG(10, ("attribute %s does not exist\n", attribute));
138                 return NULL;
139         }
140
141         if (ldap_count_values(values) != 1) {
142                 DEBUG(10, ("attribute %s has %d values, expected only one\n",
143                            attribute, ldap_count_values(values)));
144                 ldap_value_free(values);
145                 return NULL;
146         }
147
148         if (!pull_utf8_talloc(mem_ctx, &result, values[0], &converted_size)) {
149                 DEBUG(10, ("pull_utf8_talloc failed\n"));
150                 ldap_value_free(values);
151                 return NULL;
152         }
153
154         ldap_value_free(values);
155
156 #ifdef DEBUG_PASSWORDS
157         DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n",
158                      attribute, result));
159 #endif  
160         return result;
161 }
162
163  char * smbldap_talloc_first_attribute(LDAP *ldap_struct, LDAPMessage *entry,
164                                        const char *attribute,
165                                        TALLOC_CTX *mem_ctx)
166 {
167         char **values;
168         char *result;
169         size_t converted_size;
170
171         if (attribute == NULL) {
172                 return NULL;
173         }
174
175         values = ldap_get_values(ldap_struct, entry, attribute);
176
177         if (values == NULL) {
178                 DEBUG(10, ("attribute %s does not exist\n", attribute));
179                 return NULL;
180         }
181
182         if (!pull_utf8_talloc(mem_ctx, &result, values[0], &converted_size)) {
183                 DEBUG(10, ("pull_utf8_talloc failed\n"));
184                 ldap_value_free(values);
185                 return NULL;
186         }
187
188         ldap_value_free(values);
189
190 #ifdef DEBUG_PASSWORDS
191         DEBUG (100, ("smbldap_get_first_attribute: [%s] = [%s]\n",
192                      attribute, result));
193 #endif
194         return result;
195 }
196
197  char * smbldap_talloc_smallest_attribute(LDAP *ldap_struct, LDAPMessage *entry,
198                                           const char *attribute,
199                                           TALLOC_CTX *mem_ctx)
200 {
201         char **values;
202         char *result;
203         size_t converted_size;
204         int i, num_values;
205
206         if (attribute == NULL) {
207                 return NULL;
208         }
209
210         values = ldap_get_values(ldap_struct, entry, attribute);
211
212         if (values == NULL) {
213                 DEBUG(10, ("attribute %s does not exist\n", attribute));
214                 return NULL;
215         }
216
217         if (!pull_utf8_talloc(mem_ctx, &result, values[0], &converted_size)) {
218                 DEBUG(10, ("pull_utf8_talloc failed\n"));
219                 ldap_value_free(values);
220                 return NULL;
221         }
222
223         num_values = ldap_count_values(values);
224
225         for (i=1; i<num_values; i++) {
226                 char *tmp;
227
228                 if (!pull_utf8_talloc(mem_ctx, &tmp, values[i],
229                                       &converted_size)) {
230                         DEBUG(10, ("pull_utf8_talloc failed\n"));
231                         TALLOC_FREE(result);
232                         ldap_value_free(values);
233                         return NULL;
234                 }
235
236                 if (strcasecmp_m(tmp, result) < 0) {
237                         TALLOC_FREE(result);
238                         result = tmp;
239                 } else {
240                         TALLOC_FREE(tmp);
241                 }
242         }
243
244         ldap_value_free(values);
245
246 #ifdef DEBUG_PASSWORDS
247         DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n",
248                      attribute, result));
249 #endif
250         return result;
251 }
252
253  bool smbldap_talloc_single_blob(TALLOC_CTX *mem_ctx, LDAP *ld,
254                                  LDAPMessage *msg, const char *attrib,
255                                  DATA_BLOB *blob)
256 {
257         struct berval **values;
258
259         values = ldap_get_values_len(ld, msg, attrib);
260         if (!values) {
261                 return false;
262         }
263
264         if (ldap_count_values_len(values) != 1) {
265                 DEBUG(10, ("Expected one value for %s, got %d\n", attrib,
266                            ldap_count_values_len(values)));
267                 return false;
268         }
269
270         *blob = data_blob_talloc(mem_ctx, values[0]->bv_val,
271                                  values[0]->bv_len);
272         ldap_value_free_len(values);
273
274         return (blob->data != NULL);
275 }
276
277  bool smbldap_pull_sid(LDAP *ld, LDAPMessage *msg, const char *attrib,
278                        struct dom_sid *sid)
279 {
280         DATA_BLOB blob;
281         bool ret;
282
283         if (!smbldap_talloc_single_blob(talloc_tos(), ld, msg, attrib,
284                                         &blob)) {
285                 return false;
286         }
287         ret = sid_parse(blob.data, blob.length, sid);
288         TALLOC_FREE(blob.data);
289         return ret;
290 }
291
292  static int ldapmsg_destructor(LDAPMessage **result) {
293         ldap_msgfree(*result);
294         return 0;
295 }
296
297  void smbldap_talloc_autofree_ldapmsg(TALLOC_CTX *mem_ctx, LDAPMessage *result)
298 {
299         LDAPMessage **handle;
300
301         if (result == NULL) {
302                 return;
303         }
304
305         handle = talloc(mem_ctx, LDAPMessage *);
306         SMB_ASSERT(handle != NULL);
307
308         *handle = result;
309         talloc_set_destructor(handle, ldapmsg_destructor);
310 }
311
312  static int ldapmod_destructor(LDAPMod ***mod) {
313         ldap_mods_free(*mod, True);
314         return 0;
315 }
316
317  void smbldap_talloc_autofree_ldapmod(TALLOC_CTX *mem_ctx, LDAPMod **mod)
318 {
319         LDAPMod ***handle;
320
321         if (mod == NULL) {
322                 return;
323         }
324
325         handle = talloc(mem_ctx, LDAPMod **);
326         SMB_ASSERT(handle != NULL);
327
328         *handle = mod;
329         talloc_set_destructor(handle, ldapmod_destructor);
330 }
331
332 /************************************************************************
333  Routine to manage the LDAPMod structure array
334  manage memory used by the array, by each struct, and values
335  ***********************************************************************/
336
337 static void smbldap_set_mod_internal(LDAPMod *** modlist, int modop, const char *attribute, const char *value, const DATA_BLOB *blob)
338 {
339         LDAPMod **mods;
340         int i;
341         int j;
342
343         mods = *modlist;
344
345         /* sanity checks on the mod values */
346
347         if (attribute == NULL || *attribute == '\0') {
348                 return; 
349         }
350
351 #if 0   /* commented out after discussion with abartlet.  Do not re-enable.
352            left here so other do not re-add similar code   --jerry */
353         if (value == NULL || *value == '\0')
354                 return;
355 #endif
356
357         if (mods == NULL) {
358                 mods = SMB_MALLOC_P(LDAPMod *);
359                 if (mods == NULL) {
360                         smb_panic("smbldap_set_mod: out of memory!");
361                         /* notreached. */
362                 }
363                 mods[0] = NULL;
364         }
365
366         for (i = 0; mods[i] != NULL; ++i) {
367                 if (mods[i]->mod_op == modop && strequal(mods[i]->mod_type, attribute))
368                         break;
369         }
370
371         if (mods[i] == NULL) {
372                 mods = SMB_REALLOC_ARRAY (mods, LDAPMod *, i + 2);
373                 if (mods == NULL) {
374                         smb_panic("smbldap_set_mod: out of memory!");
375                         /* notreached. */
376                 }
377                 mods[i] = SMB_MALLOC_P(LDAPMod);
378                 if (mods[i] == NULL) {
379                         smb_panic("smbldap_set_mod: out of memory!");
380                         /* notreached. */
381                 }
382                 mods[i]->mod_op = modop;
383                 mods[i]->mod_values = NULL;
384                 mods[i]->mod_type = SMB_STRDUP(attribute);
385                 mods[i + 1] = NULL;
386         }
387
388         if (blob && (modop & LDAP_MOD_BVALUES)) {
389                 j = 0;
390                 if (mods[i]->mod_bvalues != NULL) {
391                         for (; mods[i]->mod_bvalues[j] != NULL; j++);
392                 }
393                 mods[i]->mod_bvalues = SMB_REALLOC_ARRAY(mods[i]->mod_bvalues, struct berval *, j + 2);
394
395                 if (mods[i]->mod_bvalues == NULL) {
396                         smb_panic("smbldap_set_mod: out of memory!");
397                         /* notreached. */
398                 }
399
400                 mods[i]->mod_bvalues[j] = SMB_MALLOC_P(struct berval);
401                 SMB_ASSERT(mods[i]->mod_bvalues[j] != NULL);
402
403                 mods[i]->mod_bvalues[j]->bv_val = (char *)smb_memdup(blob->data, blob->length);
404                 SMB_ASSERT(mods[i]->mod_bvalues[j]->bv_val != NULL);
405                 mods[i]->mod_bvalues[j]->bv_len = blob->length;
406
407                 mods[i]->mod_bvalues[j + 1] = NULL;
408         } else if (value != NULL) {
409                 char *utf8_value = NULL;
410                 size_t converted_size;
411
412                 j = 0;
413                 if (mods[i]->mod_values != NULL) {
414                         for (; mods[i]->mod_values[j] != NULL; j++);
415                 }
416                 mods[i]->mod_values = SMB_REALLOC_ARRAY(mods[i]->mod_values, char *, j + 2);
417
418                 if (mods[i]->mod_values == NULL) {
419                         smb_panic("smbldap_set_mod: out of memory!");
420                         /* notreached. */
421                 }
422
423                 if (!push_utf8_talloc(talloc_tos(), &utf8_value, value, &converted_size)) {
424                         smb_panic("smbldap_set_mod: String conversion failure!");
425                         /* notreached. */
426                 }
427
428                 mods[i]->mod_values[j] = SMB_STRDUP(utf8_value);
429                 TALLOC_FREE(utf8_value);
430                 SMB_ASSERT(mods[i]->mod_values[j] != NULL);
431
432                 mods[i]->mod_values[j + 1] = NULL;
433         }
434         *modlist = mods;
435 }
436
437  void smbldap_set_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value)
438 {
439         smbldap_set_mod_internal(modlist, modop, attribute, value, NULL);
440 }
441
442  void smbldap_set_mod_blob(LDAPMod *** modlist, int modop, const char *attribute, const DATA_BLOB *value)
443 {
444         smbldap_set_mod_internal(modlist, modop | LDAP_MOD_BVALUES, attribute, NULL, value);
445 }
446
447 /**********************************************************************
448   Set attribute to newval in LDAP, regardless of what value the
449   attribute had in LDAP before.
450 *********************************************************************/
451
452 static void smbldap_make_mod_internal(LDAP *ldap_struct, LDAPMessage *existing,
453                                       LDAPMod ***mods,
454                                       const char *attribute, int op,
455                                       const char *newval,
456                                       const DATA_BLOB *newblob)
457 {
458         char oldval[2048]; /* current largest allowed value is mungeddial */
459         bool existed;
460         DATA_BLOB oldblob = data_blob_null;
461
462         if (existing != NULL) {
463                 if (op & LDAP_MOD_BVALUES) {
464                         existed = smbldap_talloc_single_blob(talloc_tos(), ldap_struct, existing, attribute, &oldblob);
465                 } else {
466                         existed = smbldap_get_single_attribute(ldap_struct, existing, attribute, oldval, sizeof(oldval));
467                 }
468         } else {
469                 existed = False;
470                 *oldval = '\0';
471         }
472
473         if (existed) {
474                 bool equal = false;
475                 if (op & LDAP_MOD_BVALUES) {
476                         equal = (newblob && (data_blob_cmp(&oldblob, newblob) == 0));
477                 } else {
478                         /* all of our string attributes are case insensitive */
479                         equal = (newval && (strcasecmp_m(oldval, newval) == 0));
480                 }
481
482                 if (equal) {
483                         /* Believe it or not, but LDAP will deny a delete and
484                            an add at the same time if the values are the
485                            same... */
486                         DEBUG(10,("smbldap_make_mod: attribute |%s| not changed.\n", attribute));
487                         return;
488                 }
489
490                 /* There has been no value before, so don't delete it.
491                  * Here's a possible race: We might end up with
492                  * duplicate attributes */
493                 /* By deleting exactly the value we found in the entry this
494                  * should be race-free in the sense that the LDAP-Server will
495                  * deny the complete operation if somebody changed the
496                  * attribute behind our back. */
497                 /* This will also allow modifying single valued attributes 
498                  * in Novell NDS. In NDS you have to first remove attribute and then
499                  * you could add new value */
500
501                 if (op & LDAP_MOD_BVALUES) {
502                         DEBUG(10,("smbldap_make_mod: deleting attribute |%s| blob\n", attribute));
503                         smbldap_set_mod_blob(mods, LDAP_MOD_DELETE, attribute, &oldblob);
504                 } else {
505                         DEBUG(10,("smbldap_make_mod: deleting attribute |%s| values |%s|\n", attribute, oldval));
506                         smbldap_set_mod(mods, LDAP_MOD_DELETE, attribute, oldval);
507                 }
508         }
509
510         /* Regardless of the real operation (add or modify)
511            we add the new value here. We rely on deleting
512            the old value, should it exist. */
513
514         if (op & LDAP_MOD_BVALUES) {
515                 if (newblob && newblob->length) {
516                         DEBUG(10,("smbldap_make_mod: adding attribute |%s| blob\n", attribute));
517                         smbldap_set_mod_blob(mods, LDAP_MOD_ADD, attribute, newblob);
518                 }
519         } else {
520                 if ((newval != NULL) && (strlen(newval) > 0)) {
521                         DEBUG(10,("smbldap_make_mod: adding attribute |%s| value |%s|\n", attribute, newval));
522                         smbldap_set_mod(mods, LDAP_MOD_ADD, attribute, newval);
523                 }
524         }
525 }
526
527  void smbldap_make_mod(LDAP *ldap_struct, LDAPMessage *existing,
528                       LDAPMod ***mods,
529                       const char *attribute, const char *newval)
530 {
531         smbldap_make_mod_internal(ldap_struct, existing, mods, attribute,
532                                   0, newval, NULL);
533 }
534
535  void smbldap_make_mod_blob(LDAP *ldap_struct, LDAPMessage *existing,
536                             LDAPMod ***mods,
537                             const char *attribute, const DATA_BLOB *newblob)
538 {
539         smbldap_make_mod_internal(ldap_struct, existing, mods, attribute,
540                                   LDAP_MOD_BVALUES, NULL, newblob);
541 }
542
543 /**********************************************************************
544  Some varients of the LDAP rebind code do not pass in the third 'arg' 
545  pointer to a void*, so we try and work around it by assuming that the 
546  value of the 'LDAP *' pointer is the same as the one we had passed in
547  **********************************************************************/
548
549 struct smbldap_state_lookup {
550         LDAP *ld;
551         struct smbldap_state *smbldap_state;
552         struct smbldap_state_lookup *prev, *next;
553 };
554
555 static struct smbldap_state_lookup *smbldap_state_lookup_list;
556
557 static struct smbldap_state *smbldap_find_state(LDAP *ld) 
558 {
559         struct smbldap_state_lookup *t;
560
561         for (t = smbldap_state_lookup_list; t; t = t->next) {
562                 if (t->ld == ld) {
563                         return t->smbldap_state;
564                 }
565         }
566         return NULL;
567 }
568
569 static void smbldap_delete_state(struct smbldap_state *smbldap_state) 
570 {
571         struct smbldap_state_lookup *t;
572
573         for (t = smbldap_state_lookup_list; t; t = t->next) {
574                 if (t->smbldap_state == smbldap_state) {
575                         DLIST_REMOVE(smbldap_state_lookup_list, t);
576                         SAFE_FREE(t);
577                         return;
578                 }
579         }
580 }
581
582 static void smbldap_store_state(LDAP *ld, struct smbldap_state *smbldap_state) 
583 {
584         struct smbldap_state *tmp_ldap_state;
585         struct smbldap_state_lookup *t;
586
587         if ((tmp_ldap_state = smbldap_find_state(ld))) {
588                 SMB_ASSERT(tmp_ldap_state == smbldap_state);
589                 return;
590         }
591
592         t = SMB_XMALLOC_P(struct smbldap_state_lookup);
593         ZERO_STRUCTP(t);
594
595         DLIST_ADD_END(smbldap_state_lookup_list, t);
596         t->ld = ld;
597         t->smbldap_state = smbldap_state;
598 }
599
600 /********************************************************************
601  start TLS on an existing LDAP connection
602 *******************************************************************/
603
604 int smbldap_start_tls(LDAP *ldap_struct, int version)
605
606 #ifdef LDAP_OPT_X_TLS
607         int rc,tls;
608 #endif
609
610         if (lp_ldap_ssl() != LDAP_SSL_START_TLS) {
611                 return LDAP_SUCCESS;
612         }
613
614 #ifdef LDAP_OPT_X_TLS
615         /* check if we use ldaps already */
616         ldap_get_option(ldap_struct, LDAP_OPT_X_TLS, &tls);
617         if (tls == LDAP_OPT_X_TLS_HARD) {
618                 return LDAP_SUCCESS;
619         }
620
621         if (version != LDAP_VERSION3) {
622                 DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
623                 return LDAP_OPERATIONS_ERROR;
624         }
625
626         if ((rc = ldap_start_tls_s (ldap_struct, NULL, NULL)) != LDAP_SUCCESS)  {
627                 DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
628                          ldap_err2string(rc)));
629                 return rc;
630         }
631
632         DEBUG (3, ("StartTLS issued: using a TLS connection\n"));
633         return LDAP_SUCCESS;
634 #else
635         DEBUG(0,("StartTLS not supported by LDAP client libraries!\n"));
636         return LDAP_OPERATIONS_ERROR;
637 #endif
638 }
639
640 /********************************************************************
641  setup a connection to the LDAP server based on a uri
642 *******************************************************************/
643
644 static int smb_ldap_setup_conn(LDAP **ldap_struct, const char *uri)
645 {
646         int rc;
647
648         DEBUG(10, ("smb_ldap_setup_connection: %s\n", uri));
649
650 #ifdef HAVE_LDAP_INITIALIZE
651
652         rc = ldap_initialize(ldap_struct, uri);
653         if (rc) {
654                 DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc)));
655                 return rc;
656         }
657
658         if (lp_ldap_follow_referral() != Auto) {
659                 rc = ldap_set_option(*ldap_struct, LDAP_OPT_REFERRALS,
660                      lp_ldap_follow_referral() ? LDAP_OPT_ON : LDAP_OPT_OFF);
661                 if (rc != LDAP_SUCCESS)
662                         DEBUG(0, ("Failed to set LDAP_OPT_REFERRALS: %s\n",
663                                 ldap_err2string(rc)));
664         }
665
666         return LDAP_SUCCESS;
667 #else 
668
669         /* Parse the string manually */
670
671         {
672                 int port = 0;
673                 fstring protocol;
674                 fstring host;
675                 SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254);
676
677
678                 /* skip leading "URL:" (if any) */
679                 if ( strnequal( uri, "URL:", 4 ) ) {
680                         uri += 4;
681                 }
682
683                 sscanf(uri, "%10[^:]://%254[^:/]:%d", protocol, host, &port);
684
685                 if (port == 0) {
686                         if (strequal(protocol, "ldap")) {
687                                 port = LDAP_PORT;
688                         } else if (strequal(protocol, "ldaps")) {
689                                 port = LDAPS_PORT;
690                         } else {
691                                 DEBUG(0, ("unrecognised protocol (%s)!\n", protocol));
692                         }
693                 }
694
695                 if ((*ldap_struct = ldap_init(host, port)) == NULL)     {
696                         DEBUG(0, ("ldap_init failed !\n"));
697                         return LDAP_OPERATIONS_ERROR;
698                 }
699
700                 if (strequal(protocol, "ldaps")) {
701 #ifdef LDAP_OPT_X_TLS
702                         int tls = LDAP_OPT_X_TLS_HARD;
703                         if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
704                         {
705                                 DEBUG(0, ("Failed to setup a TLS session\n"));
706                         }
707
708                         DEBUG(3,("LDAPS option set...!\n"));
709 #else
710                         DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));
711                         return LDAP_OPERATIONS_ERROR;
712 #endif /* LDAP_OPT_X_TLS */
713                 }
714         }
715 #endif /* HAVE_LDAP_INITIALIZE */
716
717         /* now set connection timeout */
718 #ifdef LDAP_X_OPT_CONNECT_TIMEOUT /* Netscape */
719         {
720                 int ct = lp_ldap_connection_timeout()*1000;
721                 rc = ldap_set_option(*ldap_struct, LDAP_X_OPT_CONNECT_TIMEOUT, &ct);
722                 if (rc != LDAP_SUCCESS) {
723                         DEBUG(0,("Failed to setup an ldap connection timeout %d: %s\n",
724                                 ct, ldap_err2string(rc)));
725                 }
726         }
727 #elif defined (LDAP_OPT_NETWORK_TIMEOUT) /* OpenLDAP */
728         {
729                 struct timeval ct;
730                 ct.tv_usec = 0;
731                 ct.tv_sec = lp_ldap_connection_timeout();
732                 rc = ldap_set_option(*ldap_struct, LDAP_OPT_NETWORK_TIMEOUT, &ct);
733                 if (rc != LDAP_SUCCESS) {
734                         DEBUG(0,("Failed to setup an ldap connection timeout %d: %s\n",
735                                 (int)ct.tv_sec, ldap_err2string(rc)));
736                 }
737         }
738 #endif
739
740         return LDAP_SUCCESS;
741 }
742
743 /********************************************************************
744  try to upgrade to Version 3 LDAP if not already, in either case return current
745  version 
746  *******************************************************************/
747
748 static int smb_ldap_upgrade_conn(LDAP *ldap_struct, int *new_version)
749 {
750         int version;
751         int rc;
752
753         /* assume the worst */
754         *new_version = LDAP_VERSION2;
755
756         rc = ldap_get_option(ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);
757         if (rc) {
758                 return rc;
759         }
760
761         if (version == LDAP_VERSION3) {
762                 *new_version = LDAP_VERSION3;
763                 return LDAP_SUCCESS;
764         }
765
766         /* try upgrade */
767         version = LDAP_VERSION3;
768         rc = ldap_set_option (ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);
769         if (rc) {
770                 return rc;
771         }
772
773         *new_version = LDAP_VERSION3;
774         return LDAP_SUCCESS;
775 }
776
777 /*******************************************************************
778  open a connection to the ldap server (just until the bind)
779  ******************************************************************/
780
781 int smbldap_setup_full_conn(LDAP **ldap_struct, const char *uri)
782 {
783         int rc, version;
784
785         rc = smb_ldap_setup_conn(ldap_struct, uri);
786         if (rc) {
787                 return rc;
788         }
789
790         rc = smb_ldap_upgrade_conn(*ldap_struct, &version);
791         if (rc) {
792                 return rc;
793         }
794
795         rc = smbldap_start_tls(*ldap_struct, version);
796         if (rc) {
797                 return rc;
798         }
799
800         return LDAP_SUCCESS;
801 }
802
803 /*******************************************************************
804  open a connection to the ldap server.
805 ******************************************************************/
806 static int smbldap_open_connection (struct smbldap_state *ldap_state)
807
808 {
809         int rc = LDAP_SUCCESS;
810         int version;
811         int deref;
812         LDAP **ldap_struct = &ldap_state->ldap_struct;
813
814         rc = smb_ldap_setup_conn(ldap_struct, ldap_state->uri);
815         if (rc) {
816                 return rc;
817         }
818
819         /* Store the LDAP pointer in a lookup list */
820
821         smbldap_store_state(*ldap_struct, ldap_state);
822
823         /* Upgrade to LDAPv3 if possible */
824
825         rc = smb_ldap_upgrade_conn(*ldap_struct, &version);
826         if (rc) {
827                 return rc;
828         }
829
830         /* Start TLS if required */
831
832         rc = smbldap_start_tls(*ldap_struct, version);
833         if (rc) {
834                 return rc;
835         }
836
837         /* Set alias dereferencing method */
838         deref = lp_ldap_deref();
839         if (deref != -1) {
840                 if (ldap_set_option (*ldap_struct, LDAP_OPT_DEREF, &deref) != LDAP_OPT_SUCCESS) {
841                         DEBUG(1,("smbldap_open_connection: Failed to set dereferencing method: %d\n", deref));
842                 } else {
843                         DEBUG(5,("Set dereferencing method: %d\n", deref));
844                 }
845         }
846
847         DEBUG(2, ("smbldap_open_connection: connection opened\n"));
848         return rc;
849 }
850
851 /*******************************************************************
852  a rebind function for authenticated referrals
853  This version takes a void* that we can shove useful stuff in :-)
854 ******************************************************************/
855 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
856 #else
857 static int rebindproc_with_state  (LDAP * ld, char **whop, char **credp, 
858                                    int *methodp, int freeit, void *arg)
859 {
860         struct smbldap_state *ldap_state = arg;
861         struct timespec ts;
862
863         /** @TODO Should we be doing something to check what servers we rebind to?
864             Could we get a referral to a machine that we don't want to give our
865             username and password to? */
866
867         if (freeit) {
868                 SAFE_FREE(*whop);
869                 if (*credp) {
870                         memset(*credp, '\0', strlen(*credp));
871                 }
872                 SAFE_FREE(*credp);
873         } else {
874                 DEBUG(5,("rebind_proc_with_state: Rebinding as \"%s\"\n", 
875                           ldap_state->bind_dn?ldap_state->bind_dn:"[Anonymous bind]"));
876
877                 if (ldap_state->anonymous) {
878                         *whop = NULL;
879                         *credp = NULL;
880                 } else {
881                         *whop = SMB_STRDUP(ldap_state->bind_dn);
882                         if (!*whop) {
883                                 return LDAP_NO_MEMORY;
884                         }
885                         *credp = SMB_STRDUP(ldap_state->bind_secret);
886                         if (!*credp) {
887                                 SAFE_FREE(*whop);
888                                 return LDAP_NO_MEMORY;
889                         }
890                 }
891                 *methodp = LDAP_AUTH_SIMPLE;
892         }
893
894         clock_gettime_mono(&ts);
895         ldap_state->last_rebind = convert_timespec_to_timeval(ts);
896
897         return 0;
898 }
899 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
900
901 /*******************************************************************
902  a rebind function for authenticated referrals
903  This version takes a void* that we can shove useful stuff in :-)
904  and actually does the connection.
905 ******************************************************************/
906 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
907 static int rebindproc_connect_with_state (LDAP *ldap_struct, 
908                                           LDAP_CONST char *url, 
909                                           ber_tag_t request,
910                                           ber_int_t msgid, void *arg)
911 {
912         struct smbldap_state *ldap_state =
913                 (struct smbldap_state *)arg;
914         int rc;
915         struct timespec ts;
916         int version;
917
918         DEBUG(5,("rebindproc_connect_with_state: Rebinding to %s as \"%s\"\n", 
919                  url, ldap_state->bind_dn?ldap_state->bind_dn:"[Anonymous bind]"));
920
921         /* call START_TLS again (ldaps:// is handled by the OpenLDAP library
922          * itself) before rebinding to another LDAP server to avoid to expose
923          * our credentials. At least *try* to secure the connection - Guenther */
924
925         smb_ldap_upgrade_conn(ldap_struct, &version);
926         smbldap_start_tls(ldap_struct, version);
927
928         /** @TODO Should we be doing something to check what servers we rebind to?
929             Could we get a referral to a machine that we don't want to give our
930             username and password to? */
931
932         rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
933
934         /* only set the last rebind timestamp when we did rebind after a
935          * non-read LDAP operation. That way we avoid the replication sleep
936          * after a simple redirected search operation - Guenther */
937
938         switch (request) {
939
940                 case LDAP_REQ_MODIFY:
941                 case LDAP_REQ_ADD:
942                 case LDAP_REQ_DELETE:
943                 case LDAP_REQ_MODDN:
944                 case LDAP_REQ_EXTENDED:
945                         DEBUG(10,("rebindproc_connect_with_state: "
946                                 "setting last_rebind timestamp "
947                                 "(req: 0x%02x)\n", (unsigned int)request));
948                         clock_gettime_mono(&ts);
949                         ldap_state->last_rebind = convert_timespec_to_timeval(ts);
950                         break;
951                 default:
952                         ZERO_STRUCT(ldap_state->last_rebind);
953                         break;
954         }
955
956         return rc;
957 }
958 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
959
960 /*******************************************************************
961  Add a rebind function for authenticated referrals
962 ******************************************************************/
963 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
964 #else
965 # if LDAP_SET_REBIND_PROC_ARGS == 2
966 static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
967                        int *method, int freeit )
968 {
969         struct smbldap_state *ldap_state = smbldap_find_state(ldap_struct);
970
971         return rebindproc_with_state(ldap_struct, whop, credp,
972                                      method, freeit, ldap_state);
973 }
974 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
975 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
976
977 /*******************************************************************
978  a rebind function for authenticated referrals
979  this also does the connection, but no void*.
980 ******************************************************************/
981 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
982 # if LDAP_SET_REBIND_PROC_ARGS == 2
983 static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request,
984                                ber_int_t msgid)
985 {
986         struct smbldap_state *ldap_state = smbldap_find_state(ld);
987
988         return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid, 
989                                              ldap_state);
990 }
991 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
992 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
993
994 /*******************************************************************
995  connect to the ldap server under system privilege.
996 ******************************************************************/
997 static int smbldap_connect_system(struct smbldap_state *ldap_state)
998 {
999         LDAP *ldap_struct = smbldap_get_ldap(ldap_state);
1000         int rc;
1001         int version;
1002
1003         /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite 
1004            (OpenLDAP) doesn't seem to support it */
1005
1006         DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n",
1007                   ldap_state->uri, ldap_state->bind_dn));
1008
1009 #ifdef HAVE_LDAP_SET_REBIND_PROC
1010 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
1011 # if LDAP_SET_REBIND_PROC_ARGS == 2     
1012         ldap_set_rebind_proc(ldap_struct, &rebindproc_connect); 
1013 # endif
1014 # if LDAP_SET_REBIND_PROC_ARGS == 3     
1015         ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state);  
1016 # endif
1017 #else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
1018 # if LDAP_SET_REBIND_PROC_ARGS == 2     
1019         ldap_set_rebind_proc(ldap_struct, &rebindproc); 
1020 # endif
1021 # if LDAP_SET_REBIND_PROC_ARGS == 3     
1022         ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state);  
1023 # endif
1024 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
1025 #endif
1026
1027         /* When there is an alternative bind callback is set,
1028            attempt to use it to perform the bind */
1029         if (ldap_state->bind_callback != NULL) {
1030                 /* We have to allow bind callback to be run under become_root/unbecome_root
1031                    to make sure within smbd the callback has proper write access to its resources,
1032                    like credential cache. This is similar to passdb case where this callback is supposed
1033                    to be used. When used outside smbd, become_root()/unbecome_root() are no-op.
1034                 */
1035                 become_root();
1036                 rc = ldap_state->bind_callback(ldap_struct, ldap_state, ldap_state->bind_callback_data);
1037                 unbecome_root();
1038         } else {
1039                 rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
1040         }
1041
1042         if (rc != LDAP_SUCCESS) {
1043                 char *ld_error = NULL;
1044                 ldap_get_option(smbldap_get_ldap(ldap_state),
1045                                 LDAP_OPT_ERROR_STRING,
1046                                 &ld_error);
1047                 DEBUG(ldap_state->num_failures ? 2 : 0,
1048                       ("failed to bind to server %s with dn=\"%s\" Error: %s\n\t%s\n",
1049                                ldap_state->uri,
1050                                ldap_state->bind_dn ? ldap_state->bind_dn : "[Anonymous bind]",
1051                                ldap_err2string(rc),
1052                                ld_error ? ld_error : "(unknown)"));
1053                 SAFE_FREE(ld_error);
1054                 ldap_state->num_failures++;
1055                 goto done;
1056         }
1057
1058         ldap_state->num_failures = 0;
1059         ldap_state->paged_results = False;
1060
1061         ldap_get_option(smbldap_get_ldap(ldap_state),
1062                         LDAP_OPT_PROTOCOL_VERSION, &version);
1063
1064         if (smbldap_has_control(smbldap_get_ldap(ldap_state), ADS_PAGE_CTL_OID)
1065             && version == 3) {
1066                 ldap_state->paged_results = True;
1067         }
1068
1069         DEBUG(3, ("ldap_connect_system: successful connection to the LDAP server\n"));
1070         DEBUGADD(10, ("ldap_connect_system: LDAP server %s support paged results\n", 
1071                 ldap_state->paged_results ? "does" : "does not"));
1072 done:
1073         if (rc != 0) {
1074                 ldap_unbind(ldap_struct);
1075                 ldap_state->ldap_struct = NULL;
1076         }
1077         return rc;
1078 }
1079
1080 static void smbldap_idle_fn(struct tevent_context *tevent_ctx,
1081                             struct tevent_timer *te,
1082                             struct timeval now_abs,
1083                             void *private_data);
1084
1085 /**********************************************************************
1086  Connect to LDAP server (called before every ldap operation)
1087 *********************************************************************/
1088 static int smbldap_open(struct smbldap_state *ldap_state)
1089 {
1090         int rc, opt_rc;
1091         bool reopen = False;
1092         SMB_ASSERT(ldap_state);
1093
1094         if ((smbldap_get_ldap(ldap_state) != NULL) &&
1095             ((ldap_state->last_ping + SMBLDAP_DONT_PING_TIME) <
1096              time_mono(NULL))) {
1097
1098 #ifdef HAVE_UNIXSOCKET
1099                 struct sockaddr_un addr;
1100 #else
1101                 struct sockaddr_storage addr;
1102 #endif
1103                 socklen_t len = sizeof(addr);
1104                 int sd;
1105
1106                 opt_rc = ldap_get_option(smbldap_get_ldap(ldap_state),
1107                                          LDAP_OPT_DESC, &sd);
1108                 if (opt_rc == 0 && (getpeername(sd, (struct sockaddr *) &addr, &len)) < 0 )
1109                         reopen = True;
1110
1111 #ifdef HAVE_UNIXSOCKET
1112                 if (opt_rc == 0 && addr.sun_family == AF_UNIX)
1113                         reopen = True;
1114 #endif
1115                 if (reopen) {
1116                         /* the other end has died. reopen. */
1117                         ldap_unbind(smbldap_get_ldap(ldap_state));
1118                         ldap_state->ldap_struct = NULL;
1119                         ldap_state->last_ping = (time_t)0;
1120                 } else {
1121                         ldap_state->last_ping = time_mono(NULL);
1122                 } 
1123         }
1124
1125         if (smbldap_get_ldap(ldap_state) != NULL) {
1126                 DEBUG(11,("smbldap_open: already connected to the LDAP server\n"));
1127                 return LDAP_SUCCESS;
1128         }
1129
1130         if ((rc = smbldap_open_connection(ldap_state))) {
1131                 return rc;
1132         }
1133
1134         if ((rc = smbldap_connect_system(ldap_state))) {
1135                 return rc;
1136         }
1137
1138
1139         ldap_state->last_ping = time_mono(NULL);
1140         ldap_state->pid = getpid();
1141
1142         TALLOC_FREE(ldap_state->idle_event);
1143
1144         if (ldap_state->tevent_context != NULL) {
1145                 ldap_state->idle_event = tevent_add_timer(
1146                         ldap_state->tevent_context, ldap_state,
1147                         timeval_current_ofs(SMBLDAP_IDLE_TIME, 0),
1148                         smbldap_idle_fn, ldap_state);
1149         }
1150
1151         DEBUG(4,("The LDAP server is successfully connected\n"));
1152
1153         return LDAP_SUCCESS;
1154 }
1155
1156 /**********************************************************************
1157 Disconnect from LDAP server 
1158 *********************************************************************/
1159 static NTSTATUS smbldap_close(struct smbldap_state *ldap_state)
1160 {
1161         if (!ldap_state)
1162                 return NT_STATUS_INVALID_PARAMETER;
1163
1164         if (smbldap_get_ldap(ldap_state) != NULL) {
1165                 ldap_unbind(smbldap_get_ldap(ldap_state));
1166                 ldap_state->ldap_struct = NULL;
1167         }
1168
1169         smbldap_delete_state(ldap_state);
1170
1171         TALLOC_FREE(ldap_state->idle_event);
1172
1173         DEBUG(5,("The connection to the LDAP server was closed\n"));
1174         /* maybe free the results here --metze */
1175
1176         return NT_STATUS_OK;
1177 }
1178
1179 static SIG_ATOMIC_T got_alarm;
1180
1181 static void gotalarm_sig(int dummy)
1182 {
1183         got_alarm = 1;
1184 }
1185
1186 static time_t calc_ldap_abs_endtime(int ldap_to)
1187 {
1188         if (ldap_to == 0) {
1189                 /* No timeout - don't
1190                    return a value for
1191                    the alarm. */
1192                 return (time_t)0;
1193         }
1194
1195         /* Make the alarm time one second beyond
1196            the timout we're setting for the
1197            remote search timeout, to allow that
1198            to fire in preference. */
1199
1200         return time_mono(NULL)+ldap_to+1;
1201 }
1202
1203 static int end_ldap_local_alarm(time_t absolute_endtime, int rc)
1204 {
1205         if (absolute_endtime) {
1206                 alarm(0);
1207                 CatchSignal(SIGALRM, SIG_IGN);
1208                 if (got_alarm) {
1209                         /* Client timeout error code. */
1210                         got_alarm = 0;
1211                         return LDAP_TIMEOUT;
1212                 }
1213         }
1214         return rc;
1215 }
1216
1217 static void setup_ldap_local_alarm(struct smbldap_state *ldap_state, time_t absolute_endtime)
1218 {
1219         time_t now = time_mono(NULL);
1220
1221         if (absolute_endtime) {
1222                 got_alarm = 0;
1223                 CatchSignal(SIGALRM, gotalarm_sig);
1224                 alarm(absolute_endtime - now);
1225         }
1226
1227         if (ldap_state->pid != getpid()) {
1228                 smbldap_close(ldap_state);
1229         }
1230 }
1231
1232 static void get_ldap_errs(struct smbldap_state *ldap_state, char **pp_ld_error, int *p_ld_errno)
1233 {
1234         ldap_get_option(smbldap_get_ldap(ldap_state),
1235                         LDAP_OPT_ERROR_NUMBER, p_ld_errno);
1236
1237         ldap_get_option(smbldap_get_ldap(ldap_state),
1238                         LDAP_OPT_ERROR_STRING, pp_ld_error);
1239 }
1240
1241 static int get_cached_ldap_connect(struct smbldap_state *ldap_state, time_t abs_endtime)
1242 {
1243         int attempts = 0;
1244
1245         while (1) {
1246                 int rc;
1247                 time_t now;
1248
1249                 now = time_mono(NULL);
1250                 ldap_state->last_use = now;
1251
1252                 if (abs_endtime && now > abs_endtime) {
1253                         smbldap_close(ldap_state);
1254                         return LDAP_TIMEOUT;
1255                 }
1256
1257                 rc = smbldap_open(ldap_state);
1258
1259                 if (rc == LDAP_SUCCESS) {
1260                         return LDAP_SUCCESS;
1261                 }
1262
1263                 attempts++;
1264                 DEBUG(1, ("Connection to LDAP server failed for the "
1265                         "%d try!\n", attempts));
1266
1267                 if (rc == LDAP_INSUFFICIENT_ACCESS) {
1268                         /* The fact that we are non-root or any other
1269                          * access-denied condition will not change in the next
1270                          * round of trying */
1271                         return rc;
1272                 }
1273
1274                 if (got_alarm) {
1275                         smbldap_close(ldap_state);
1276                         return LDAP_TIMEOUT;
1277                 }
1278
1279                 smb_msleep(1000);
1280
1281                 if (got_alarm) {
1282                         smbldap_close(ldap_state);
1283                         return LDAP_TIMEOUT;
1284                 }
1285         }
1286 }
1287
1288 /*********************************************************************
1289  ********************************************************************/
1290
1291 static int smbldap_search_ext(struct smbldap_state *ldap_state,
1292                               const char *base, int scope, const char *filter, 
1293                               const char *attrs[], int attrsonly,
1294                               LDAPControl **sctrls, LDAPControl **cctrls, 
1295                               int sizelimit, LDAPMessage **res)
1296 {
1297         int             rc = LDAP_SERVER_DOWN;
1298         char           *utf8_filter;
1299         int             to = lp_ldap_timeout();
1300         time_t          abs_endtime = calc_ldap_abs_endtime(to);
1301         struct          timeval timeout;
1302         struct          timeval *timeout_ptr = NULL;
1303         size_t          converted_size;
1304
1305         SMB_ASSERT(ldap_state);
1306
1307         DEBUG(5,("smbldap_search_ext: base => [%s], filter => [%s], "
1308                  "scope => [%d]\n", base, filter, scope));
1309
1310         if (ldap_state->last_rebind.tv_sec > 0) {
1311                 struct timeval  tval;
1312                 struct timespec ts;
1313                 int64_t tdiff = 0;
1314                 int             sleep_time = 0;
1315
1316                 clock_gettime_mono(&ts);
1317                 tval = convert_timespec_to_timeval(ts);
1318
1319                 tdiff = usec_time_diff(&tval, &ldap_state->last_rebind);
1320                 tdiff /= 1000; /* Convert to milliseconds. */
1321
1322                 sleep_time = lp_ldap_replication_sleep()-(int)tdiff;
1323                 sleep_time = MIN(sleep_time, MAX_LDAP_REPLICATION_SLEEP_TIME);
1324
1325                 if (sleep_time > 0) {
1326                         /* we wait for the LDAP replication */
1327                         DEBUG(5,("smbldap_search_ext: waiting %d milliseconds "
1328                                  "for LDAP replication.\n",sleep_time));
1329                         smb_msleep(sleep_time);
1330                         DEBUG(5,("smbldap_search_ext: go on!\n"));
1331                 }
1332                 ZERO_STRUCT(ldap_state->last_rebind);
1333         }
1334
1335         if (!push_utf8_talloc(talloc_tos(), &utf8_filter, filter, &converted_size)) {
1336                 return LDAP_NO_MEMORY;
1337         }
1338
1339         /* Setup remote timeout for the ldap_search_ext_s call. */
1340         if (to) {
1341                 timeout.tv_sec = to;
1342                 timeout.tv_usec = 0;
1343                 timeout_ptr = &timeout;
1344         }
1345
1346         setup_ldap_local_alarm(ldap_state, abs_endtime);
1347
1348         while (1) {
1349                 char *ld_error = NULL;
1350                 int ld_errno;
1351
1352                 rc = get_cached_ldap_connect(ldap_state, abs_endtime);
1353                 if (rc != LDAP_SUCCESS) {
1354                         break;
1355                 }
1356
1357                 rc = ldap_search_ext_s(smbldap_get_ldap(ldap_state),
1358                                        base, scope,
1359                                        utf8_filter,
1360                                        discard_const_p(char *, attrs),
1361                                        attrsonly, sctrls, cctrls, timeout_ptr,
1362                                        sizelimit, res);
1363                 if (rc == LDAP_SUCCESS) {
1364                         break;
1365                 }
1366
1367                 get_ldap_errs(ldap_state, &ld_error, &ld_errno);
1368
1369                 DEBUG(10, ("Failed search for base: %s, error: %d (%s) "
1370                            "(%s)\n", base, ld_errno,
1371                            ldap_err2string(rc),
1372                            ld_error ? ld_error : "unknown"));
1373                 SAFE_FREE(ld_error);
1374
1375                 if (ld_errno != LDAP_SERVER_DOWN) {
1376                         break;
1377                 }
1378                 ldap_unbind(smbldap_get_ldap(ldap_state));
1379                 ldap_state->ldap_struct = NULL;
1380         }
1381
1382         TALLOC_FREE(utf8_filter);
1383         return end_ldap_local_alarm(abs_endtime, rc);
1384 }
1385
1386 int smbldap_search(struct smbldap_state *ldap_state, 
1387                    const char *base, int scope, const char *filter, 
1388                    const char *attrs[], int attrsonly, 
1389                    LDAPMessage **res)
1390 {
1391         return smbldap_search_ext(ldap_state, base, scope, filter, attrs,
1392                                   attrsonly, NULL, NULL, LDAP_NO_LIMIT, res);
1393 }
1394
1395 int smbldap_search_paged(struct smbldap_state *ldap_state, 
1396                          const char *base, int scope, const char *filter, 
1397                          const char **attrs, int attrsonly, int pagesize,
1398                          LDAPMessage **res, void **cookie)
1399 {
1400         LDAPControl     pr;
1401         LDAPControl     **rcontrols;
1402         LDAPControl     *controls[2] = { NULL, NULL};
1403         BerElement      *cookie_be = NULL;
1404         struct berval   *cookie_bv = NULL;
1405         int             tmp = 0, i, rc;
1406         bool            critical = True;
1407
1408         *res = NULL;
1409
1410         DEBUG(3,("smbldap_search_paged: base => [%s], filter => [%s],"
1411                  "scope => [%d], pagesize => [%d]\n",
1412                  base, filter, scope, pagesize));
1413
1414         cookie_be = ber_alloc_t(LBER_USE_DER);
1415         if (cookie_be == NULL) {
1416                 DEBUG(0,("smbldap_create_page_control: ber_alloc_t returns "
1417                          "NULL\n"));
1418                 return LDAP_NO_MEMORY;
1419         }
1420
1421         /* construct cookie */
1422         if (*cookie != NULL) {
1423                 ber_printf(cookie_be, "{iO}", (ber_int_t) pagesize, *cookie);
1424                 ber_bvfree((struct berval *)*cookie); /* don't need it from last time */
1425                 *cookie = NULL;
1426         } else {
1427                 ber_printf(cookie_be, "{io}", (ber_int_t) pagesize, "", 0);
1428         }
1429         ber_flatten(cookie_be, &cookie_bv);
1430
1431         pr.ldctl_oid = discard_const_p(char, ADS_PAGE_CTL_OID);
1432         pr.ldctl_iscritical = (char) critical;
1433         pr.ldctl_value.bv_len = cookie_bv->bv_len;
1434         pr.ldctl_value.bv_val = cookie_bv->bv_val;
1435
1436         controls[0] = &pr;
1437         controls[1] = NULL;
1438
1439         rc = smbldap_search_ext(ldap_state, base, scope, filter, attrs, 
1440                                  0, controls, NULL, LDAP_NO_LIMIT, res);
1441
1442         ber_free(cookie_be, 1);
1443         ber_bvfree(cookie_bv);
1444
1445         if (rc != 0) {
1446                 DEBUG(3,("smbldap_search_paged: smbldap_search_ext(%s) "
1447                          "failed with [%s]\n", filter, ldap_err2string(rc)));
1448                 goto done;
1449         }
1450
1451         DEBUG(3,("smbldap_search_paged: search was successful\n"));
1452
1453         rc = ldap_parse_result(smbldap_get_ldap(ldap_state), *res, NULL, NULL,
1454                                NULL, NULL, &rcontrols,  0);
1455         if (rc != 0) {
1456                 DEBUG(3,("smbldap_search_paged: ldap_parse_result failed " \
1457                          "with [%s]\n", ldap_err2string(rc)));
1458                 goto done;
1459         }
1460
1461         if (rcontrols == NULL)
1462                 goto done;
1463
1464         for (i=0; rcontrols[i]; i++) {
1465
1466                 if (strcmp(ADS_PAGE_CTL_OID, rcontrols[i]->ldctl_oid) != 0)
1467                         continue;
1468
1469                 cookie_be = ber_init(&rcontrols[i]->ldctl_value);
1470                 ber_scanf(cookie_be,"{iO}", &tmp, &cookie_bv);
1471                 /* the berval is the cookie, but must be freed when it is all
1472                    done */
1473                 if (cookie_bv->bv_len)
1474                         *cookie=ber_bvdup(cookie_bv);
1475                 else
1476                         *cookie=NULL;
1477                 ber_bvfree(cookie_bv);
1478                 ber_free(cookie_be, 1);
1479                 break;
1480         }
1481         ldap_controls_free(rcontrols);
1482 done:   
1483         return rc;
1484 }
1485
1486 int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs[])
1487 {
1488         int             rc = LDAP_SERVER_DOWN;
1489         char           *utf8_dn;
1490         time_t          abs_endtime = calc_ldap_abs_endtime(lp_ldap_timeout());
1491         size_t          converted_size;
1492
1493         SMB_ASSERT(ldap_state);
1494
1495         DEBUG(5,("smbldap_modify: dn => [%s]\n", dn ));
1496
1497         if (!push_utf8_talloc(talloc_tos(), &utf8_dn, dn, &converted_size)) {
1498                 return LDAP_NO_MEMORY;
1499         }
1500
1501         setup_ldap_local_alarm(ldap_state, abs_endtime);
1502
1503         while (1) {
1504                 char *ld_error = NULL;
1505                 int ld_errno;
1506
1507                 rc = get_cached_ldap_connect(ldap_state, abs_endtime);
1508                 if (rc != LDAP_SUCCESS) {
1509                         break;
1510                 }
1511
1512                 rc = ldap_modify_s(smbldap_get_ldap(ldap_state), utf8_dn,
1513                                    attrs);
1514                 if (rc == LDAP_SUCCESS) {
1515                         break;
1516                 }
1517
1518                 get_ldap_errs(ldap_state, &ld_error, &ld_errno);
1519
1520                 DEBUG(10, ("Failed to modify dn: %s, error: %d (%s) "
1521                            "(%s)\n", dn, ld_errno,
1522                            ldap_err2string(rc),
1523                            ld_error ? ld_error : "unknown"));
1524                 SAFE_FREE(ld_error);
1525
1526                 if (ld_errno != LDAP_SERVER_DOWN) {
1527                         break;
1528                 }
1529                 ldap_unbind(smbldap_get_ldap(ldap_state));
1530                 ldap_state->ldap_struct = NULL;
1531         }
1532
1533         TALLOC_FREE(utf8_dn);
1534         return end_ldap_local_alarm(abs_endtime, rc);
1535 }
1536
1537 int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs[])
1538 {
1539         int             rc = LDAP_SERVER_DOWN;
1540         char           *utf8_dn;
1541         time_t          abs_endtime = calc_ldap_abs_endtime(lp_ldap_timeout());
1542         size_t          converted_size;
1543
1544         SMB_ASSERT(ldap_state);
1545
1546         DEBUG(5,("smbldap_add: dn => [%s]\n", dn ));
1547
1548         if (!push_utf8_talloc(talloc_tos(), &utf8_dn, dn, &converted_size)) {
1549                 return LDAP_NO_MEMORY;
1550         }
1551
1552         setup_ldap_local_alarm(ldap_state, abs_endtime);
1553
1554         while (1) {
1555                 char *ld_error = NULL;
1556                 int ld_errno;
1557
1558                 rc = get_cached_ldap_connect(ldap_state, abs_endtime);
1559                 if (rc != LDAP_SUCCESS) {
1560                         break;
1561                 }
1562
1563                 rc = ldap_add_s(smbldap_get_ldap(ldap_state), utf8_dn, attrs);
1564                 if (rc == LDAP_SUCCESS) {
1565                         break;
1566                 }
1567
1568                 get_ldap_errs(ldap_state, &ld_error, &ld_errno);
1569
1570                 DEBUG(10, ("Failed to add dn: %s, error: %d (%s) "
1571                            "(%s)\n", dn, ld_errno,
1572                            ldap_err2string(rc),
1573                            ld_error ? ld_error : "unknown"));
1574                 SAFE_FREE(ld_error);
1575
1576                 if (ld_errno != LDAP_SERVER_DOWN) {
1577                         break;
1578                 }
1579                 ldap_unbind(smbldap_get_ldap(ldap_state));
1580                 ldap_state->ldap_struct = NULL;
1581         }
1582
1583         TALLOC_FREE(utf8_dn);
1584         return end_ldap_local_alarm(abs_endtime, rc);
1585 }
1586
1587 int smbldap_delete(struct smbldap_state *ldap_state, const char *dn)
1588 {
1589         int             rc = LDAP_SERVER_DOWN;
1590         char           *utf8_dn;
1591         time_t          abs_endtime = calc_ldap_abs_endtime(lp_ldap_timeout());
1592         size_t          converted_size;
1593
1594         SMB_ASSERT(ldap_state);
1595
1596         DEBUG(5,("smbldap_delete: dn => [%s]\n", dn ));
1597
1598         if (!push_utf8_talloc(talloc_tos(), &utf8_dn, dn, &converted_size)) {
1599                 return LDAP_NO_MEMORY;
1600         }
1601
1602         setup_ldap_local_alarm(ldap_state, abs_endtime);
1603
1604         while (1) {
1605                 char *ld_error = NULL;
1606                 int ld_errno;
1607
1608                 rc = get_cached_ldap_connect(ldap_state, abs_endtime);
1609                 if (rc != LDAP_SUCCESS) {
1610                         break;
1611                 }
1612
1613                 rc = ldap_delete_s(smbldap_get_ldap(ldap_state), utf8_dn);
1614                 if (rc == LDAP_SUCCESS) {
1615                         break;
1616                 }
1617
1618                 get_ldap_errs(ldap_state, &ld_error, &ld_errno);
1619
1620                 DEBUG(10, ("Failed to delete dn: %s, error: %d (%s) "
1621                            "(%s)\n", dn, ld_errno,
1622                            ldap_err2string(rc),
1623                            ld_error ? ld_error : "unknown"));
1624                 SAFE_FREE(ld_error);
1625
1626                 if (ld_errno != LDAP_SERVER_DOWN) {
1627                         break;
1628                 }
1629                 ldap_unbind(smbldap_get_ldap(ldap_state));
1630                 ldap_state->ldap_struct = NULL;
1631         }
1632
1633         TALLOC_FREE(utf8_dn);
1634         return end_ldap_local_alarm(abs_endtime, rc);
1635 }
1636
1637 int smbldap_extended_operation(struct smbldap_state *ldap_state, 
1638                                LDAP_CONST char *reqoid, struct berval *reqdata, 
1639                                LDAPControl **serverctrls, LDAPControl **clientctrls, 
1640                                char **retoidp, struct berval **retdatap)
1641 {
1642         int             rc = LDAP_SERVER_DOWN;
1643         time_t          abs_endtime = calc_ldap_abs_endtime(lp_ldap_timeout());
1644
1645         if (!ldap_state)
1646                 return (-1);
1647
1648         setup_ldap_local_alarm(ldap_state, abs_endtime);
1649
1650         while (1) {
1651                 char *ld_error = NULL;
1652                 int ld_errno;
1653
1654                 rc = get_cached_ldap_connect(ldap_state, abs_endtime);
1655                 if (rc != LDAP_SUCCESS) {
1656                         break;
1657                 }
1658
1659                 rc = ldap_extended_operation_s(smbldap_get_ldap(ldap_state),
1660                                                reqoid,
1661                                                reqdata, serverctrls,
1662                                                clientctrls, retoidp, retdatap);
1663                 if (rc == LDAP_SUCCESS) {
1664                         break;
1665                 }
1666
1667                 get_ldap_errs(ldap_state, &ld_error, &ld_errno);
1668
1669                 DEBUG(10, ("Extended operation failed with error: "
1670                            "%d (%s) (%s)\n", ld_errno,
1671                            ldap_err2string(rc),
1672                            ld_error ? ld_error : "unknown"));
1673                 SAFE_FREE(ld_error);
1674
1675                 if (ld_errno != LDAP_SERVER_DOWN) {
1676                         break;
1677                 }
1678                 ldap_unbind(smbldap_get_ldap(ldap_state));
1679                 ldap_state->ldap_struct = NULL;
1680         }
1681
1682         return end_ldap_local_alarm(abs_endtime, rc);
1683 }
1684
1685 /*******************************************************************
1686  run the search by name.
1687 ******************************************************************/
1688 int smbldap_search_suffix (struct smbldap_state *ldap_state,
1689                            const char *filter, const char **search_attr,
1690                            LDAPMessage ** result)
1691 {
1692         return smbldap_search(ldap_state, lp_ldap_suffix(talloc_tos()),
1693                               LDAP_SCOPE_SUBTREE,
1694                               filter, search_attr, 0, result);
1695 }
1696
1697 static void smbldap_idle_fn(struct tevent_context *tevent_ctx,
1698                             struct tevent_timer *te,
1699                             struct timeval now_abs,
1700                             void *private_data)
1701 {
1702         struct smbldap_state *state = (struct smbldap_state *)private_data;
1703
1704         TALLOC_FREE(state->idle_event);
1705
1706         if (smbldap_get_ldap(state) == NULL) {
1707                 DEBUG(10,("ldap connection not connected...\n"));
1708                 return;
1709         }
1710
1711         if ((state->last_use+SMBLDAP_IDLE_TIME) > time_mono(NULL)) {
1712                 DEBUG(10,("ldap connection not idle...\n"));
1713
1714                 /* this needs to be made monotonic clock aware inside tevent: */
1715                 state->idle_event = tevent_add_timer(
1716                         tevent_ctx, state,
1717                         timeval_add(&now_abs, SMBLDAP_IDLE_TIME, 0),
1718                         smbldap_idle_fn,
1719                         private_data);
1720                 return;
1721         }
1722
1723         DEBUG(7,("ldap connection idle...closing connection\n"));
1724         smbldap_close(state);
1725 }
1726
1727 /**********************************************************************
1728  Housekeeping
1729  *********************************************************************/
1730
1731 void smbldap_free_struct(struct smbldap_state **ldap_state) 
1732 {
1733         smbldap_close(*ldap_state);
1734
1735         if ((*ldap_state)->bind_secret) {
1736                 memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
1737         }
1738
1739         SAFE_FREE((*ldap_state)->bind_dn);
1740         SAFE_FREE((*ldap_state)->bind_secret);
1741         smbldap_set_bind_callback(*ldap_state, NULL, NULL);
1742
1743         TALLOC_FREE(*ldap_state);
1744
1745         /* No need to free any further, as it is talloc()ed */
1746 }
1747
1748 static int smbldap_state_destructor(struct smbldap_state *state)
1749 {
1750         smbldap_free_struct(&state);
1751         return 0;
1752 }
1753
1754
1755 /**********************************************************************
1756  Intitalise the 'general' ldap structures, on which ldap operations may be conducted
1757  *********************************************************************/
1758
1759 NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, struct tevent_context *tevent_ctx,
1760                       const char *location,
1761                       bool anon,
1762                       const char *bind_dn,
1763                       const char *bind_secret,
1764                       struct smbldap_state **smbldap_state)
1765 {
1766         *smbldap_state = talloc_zero(mem_ctx, struct smbldap_state);
1767         if (!*smbldap_state) {
1768                 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
1769                 return NT_STATUS_NO_MEMORY;
1770         }
1771
1772         if (location) {
1773                 (*smbldap_state)->uri = talloc_strdup(mem_ctx, location);
1774         } else {
1775                 (*smbldap_state)->uri = "ldap://localhost";
1776         }
1777
1778         (*smbldap_state)->tevent_context = tevent_ctx;
1779
1780         if (bind_dn && bind_secret) {
1781                 smbldap_set_creds(*smbldap_state, anon, bind_dn, bind_secret);
1782         }
1783
1784         talloc_set_destructor(*smbldap_state, smbldap_state_destructor);
1785         return NT_STATUS_OK;
1786 }
1787
1788  char *smbldap_talloc_dn(TALLOC_CTX *mem_ctx, LDAP *ld,
1789                          LDAPMessage *entry)
1790 {
1791         char *utf8_dn, *unix_dn;
1792         size_t converted_size;
1793
1794         utf8_dn = ldap_get_dn(ld, entry);
1795         if (!utf8_dn) {
1796                 DEBUG (5, ("smbldap_talloc_dn: ldap_get_dn failed\n"));
1797                 return NULL;
1798         }
1799         if (!pull_utf8_talloc(mem_ctx, &unix_dn, utf8_dn, &converted_size)) {
1800                 DEBUG (0, ("smbldap_talloc_dn: String conversion failure utf8 "
1801                            "[%s]\n", utf8_dn));
1802                 return NULL;
1803         }
1804         ldap_memfree(utf8_dn);
1805         return unix_dn;
1806 }
1807
1808 /*******************************************************************
1809  Check if root-dse has a certain Control or Extension
1810 ********************************************************************/
1811
1812 static bool smbldap_check_root_dse(LDAP *ld, const char **attrs, const char *value) 
1813 {
1814         LDAPMessage *msg = NULL;
1815         LDAPMessage *entry = NULL;
1816         char **values = NULL;
1817         int rc, num_result, num_values, i;
1818         bool result = False;
1819
1820         if (!attrs[0]) {
1821                 DEBUG(3,("smbldap_check_root_dse: nothing to look for\n"));
1822                 return False;
1823         }
1824
1825         if (!strequal(attrs[0], "supportedExtension") && 
1826             !strequal(attrs[0], "supportedControl") && 
1827             !strequal(attrs[0], "namingContexts")) {
1828                 DEBUG(3,("smbldap_check_root_dse: no idea what to query root-dse for: %s ?\n", attrs[0]));
1829                 return False;
1830         }
1831
1832         rc = ldap_search_s(ld, "", LDAP_SCOPE_BASE, 
1833                            "(objectclass=*)", discard_const_p(char *, attrs), 0 , &msg);
1834
1835         if (rc != LDAP_SUCCESS) {
1836                 DEBUG(3,("smbldap_check_root_dse: Could not search rootDSE\n"));
1837                 return False;
1838         }
1839
1840         num_result = ldap_count_entries(ld, msg);
1841
1842         if (num_result != 1) {
1843                 DEBUG(3,("smbldap_check_root_dse: Expected one rootDSE, got %d\n", num_result));
1844                 goto done;
1845         }
1846
1847         entry = ldap_first_entry(ld, msg);
1848
1849         if (entry == NULL) {
1850                 DEBUG(3,("smbldap_check_root_dse: Could not retrieve rootDSE\n"));
1851                 goto done;
1852         }
1853
1854         values = ldap_get_values(ld, entry, attrs[0]);
1855
1856         if (values == NULL) {
1857                 DEBUG(5,("smbldap_check_root_dse: LDAP Server does not support any %s\n", attrs[0]));
1858                 goto done;
1859         }
1860
1861         num_values = ldap_count_values(values);
1862
1863         if (num_values == 0) {
1864                 DEBUG(5,("smbldap_check_root_dse: LDAP Server does not have any %s\n", attrs[0]));
1865                 goto done;
1866         }
1867
1868         for (i=0; i<num_values; i++) {
1869                 if (strcmp(values[i], value) == 0)
1870                         result = True;
1871         }
1872
1873
1874  done:
1875         if (values != NULL)
1876                 ldap_value_free(values);
1877         if (msg != NULL)
1878                 ldap_msgfree(msg);
1879
1880         return result;
1881
1882 }
1883
1884 /*******************************************************************
1885  Check if LDAP-Server supports a certain Control (OID in string format)
1886 ********************************************************************/
1887
1888 bool smbldap_has_control(LDAP *ld, const char *control)
1889 {
1890         const char *attrs[] = { "supportedControl", NULL };
1891         return smbldap_check_root_dse(ld, attrs, control);
1892 }
1893
1894 /*******************************************************************
1895  Check if LDAP-Server supports a certain Extension (OID in string format)
1896 ********************************************************************/
1897
1898 bool smbldap_has_extension(LDAP *ld, const char *extension)
1899 {
1900         const char *attrs[] = { "supportedExtension", NULL };
1901         return smbldap_check_root_dse(ld, attrs, extension);
1902 }
1903
1904 /*******************************************************************
1905  Check if LDAP-Server holds a given namingContext
1906 ********************************************************************/
1907
1908 bool smbldap_has_naming_context(LDAP *ld, const char *naming_context)
1909 {
1910         const char *attrs[] = { "namingContexts", NULL };
1911         return smbldap_check_root_dse(ld, attrs, naming_context);
1912 }
1913
1914 bool smbldap_set_creds(struct smbldap_state *ldap_state, bool anon, const char *dn, const char *secret)
1915 {
1916         ldap_state->anonymous = anon;
1917
1918         /* free any previously set credential */
1919
1920         SAFE_FREE(ldap_state->bind_dn);
1921         smbldap_set_bind_callback(ldap_state, NULL, NULL);
1922
1923         if (ldap_state->bind_secret) {
1924                 /* make sure secrets are zeroed out of memory */
1925                 memset(ldap_state->bind_secret, '\0', strlen(ldap_state->bind_secret));
1926                 SAFE_FREE(ldap_state->bind_secret);
1927         }
1928
1929         if ( ! anon) {
1930                 ldap_state->bind_dn = SMB_STRDUP(dn);
1931                 ldap_state->bind_secret = SMB_STRDUP(secret);
1932         }
1933
1934         return True;
1935 }