ldb: move struct ldb_debug_ops to ldb_private.h
[samba.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         ssize_t 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 != -1);
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 variants 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 per config
602 *******************************************************************/
603
604 int smbldap_start_tls(LDAP *ldap_struct, int version)
605 {
606         if (lp_ldap_ssl() != LDAP_SSL_START_TLS) {
607                 return LDAP_SUCCESS;
608         }
609
610         return smbldap_start_tls_start(ldap_struct, version);
611 }
612
613 /********************************************************************
614  start TLS on an existing LDAP connection unconditionally
615 *******************************************************************/
616
617 int smbldap_start_tls_start(LDAP *ldap_struct, int version)
618 {
619 #ifdef LDAP_OPT_X_TLS
620         int rc,tls;
621
622         /* check if we use ldaps already */
623         ldap_get_option(ldap_struct, LDAP_OPT_X_TLS, &tls);
624         if (tls == LDAP_OPT_X_TLS_HARD) {
625                 return LDAP_SUCCESS;
626         }
627
628         if (version != LDAP_VERSION3) {
629                 DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
630                 return LDAP_OPERATIONS_ERROR;
631         }
632
633         if ((rc = ldap_start_tls_s (ldap_struct, NULL, NULL)) != LDAP_SUCCESS)  {
634                 DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
635                          ldap_err2string(rc)));
636                 return rc;
637         }
638
639         DEBUG (3, ("StartTLS issued: using a TLS connection\n"));
640         return LDAP_SUCCESS;
641 #else
642         DEBUG(0,("StartTLS not supported by LDAP client libraries!\n"));
643         return LDAP_OPERATIONS_ERROR;
644 #endif
645 }
646
647 /********************************************************************
648  setup a connection to the LDAP server based on a uri
649 *******************************************************************/
650
651 static int smb_ldap_setup_conn(LDAP **ldap_struct, const char *uri)
652 {
653         int rc;
654
655         DEBUG(10, ("smb_ldap_setup_connection: %s\n", uri));
656
657 #ifdef HAVE_LDAP_INITIALIZE
658
659         rc = ldap_initialize(ldap_struct, uri);
660         if (rc) {
661                 DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc)));
662                 return rc;
663         }
664
665         if (lp_ldap_follow_referral() != Auto) {
666                 rc = ldap_set_option(*ldap_struct, LDAP_OPT_REFERRALS,
667                      lp_ldap_follow_referral() ? LDAP_OPT_ON : LDAP_OPT_OFF);
668                 if (rc != LDAP_SUCCESS)
669                         DEBUG(0, ("Failed to set LDAP_OPT_REFERRALS: %s\n",
670                                 ldap_err2string(rc)));
671         }
672
673 #else
674
675         /* Parse the string manually */
676
677         {
678                 int port = 0;
679                 fstring protocol;
680                 fstring host;
681                 SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254);
682
683
684                 /* skip leading "URL:" (if any) */
685                 if ( strnequal( uri, "URL:", 4 ) ) {
686                         uri += 4;
687                 }
688
689                 sscanf(uri, "%10[^:]://%254[^:/]:%d", protocol, host, &port);
690
691                 if (port == 0) {
692                         if (strequal(protocol, "ldap")) {
693                                 port = LDAP_PORT;
694                         } else if (strequal(protocol, "ldaps")) {
695                                 port = LDAPS_PORT;
696                         } else {
697                                 DEBUG(0, ("unrecognised protocol (%s)!\n", protocol));
698                         }
699                 }
700
701                 if ((*ldap_struct = ldap_init(host, port)) == NULL)     {
702                         DEBUG(0, ("ldap_init failed !\n"));
703                         return LDAP_OPERATIONS_ERROR;
704                 }
705
706                 if (strequal(protocol, "ldaps")) {
707 #ifdef LDAP_OPT_X_TLS
708                         int tls = LDAP_OPT_X_TLS_HARD;
709                         if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
710                         {
711                                 DEBUG(0, ("Failed to setup a TLS session\n"));
712                         }
713
714                         DEBUG(3,("LDAPS option set...!\n"));
715 #else
716                         DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));
717                         return LDAP_OPERATIONS_ERROR;
718 #endif /* LDAP_OPT_X_TLS */
719                 }
720         }
721
722         /* now set connection timeout */
723 #ifdef LDAP_X_OPT_CONNECT_TIMEOUT /* Netscape */
724         {
725                 int ct = lp_ldap_connection_timeout()*1000;
726                 rc = ldap_set_option(*ldap_struct, LDAP_X_OPT_CONNECT_TIMEOUT, &ct);
727                 if (rc != LDAP_SUCCESS) {
728                         DEBUG(0,("Failed to setup an ldap connection timeout %d: %s\n",
729                                 ct, ldap_err2string(rc)));
730                 }
731         }
732 #elif defined (LDAP_OPT_NETWORK_TIMEOUT) /* OpenLDAP */
733         {
734                 struct timeval ct;
735                 ct.tv_usec = 0;
736                 ct.tv_sec = lp_ldap_connection_timeout();
737                 rc = ldap_set_option(*ldap_struct, LDAP_OPT_NETWORK_TIMEOUT, &ct);
738                 if (rc != LDAP_SUCCESS) {
739                         DEBUG(0,("Failed to setup an ldap connection timeout %d: %s\n",
740                                 (int)ct.tv_sec, ldap_err2string(rc)));
741                 }
742         }
743 #endif
744
745 #endif /* HAVE_LDAP_INITIALIZE */
746         return LDAP_SUCCESS;
747 }
748
749 /********************************************************************
750  try to upgrade to Version 3 LDAP if not already, in either case return current
751  version
752  *******************************************************************/
753
754 static int smb_ldap_upgrade_conn(LDAP *ldap_struct, int *new_version)
755 {
756         int version;
757         int rc;
758
759         /* assume the worst */
760         *new_version = LDAP_VERSION2;
761
762         rc = ldap_get_option(ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);
763         if (rc) {
764                 return rc;
765         }
766
767         if (version == LDAP_VERSION3) {
768                 *new_version = LDAP_VERSION3;
769                 return LDAP_SUCCESS;
770         }
771
772         /* try upgrade */
773         version = LDAP_VERSION3;
774         rc = ldap_set_option (ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);
775         if (rc) {
776                 return rc;
777         }
778
779         *new_version = LDAP_VERSION3;
780         return LDAP_SUCCESS;
781 }
782
783 /*******************************************************************
784  open a connection to the ldap server (just until the bind)
785  ******************************************************************/
786
787 int smbldap_setup_full_conn(LDAP **ldap_struct, const char *uri)
788 {
789         int rc, version;
790
791         rc = smb_ldap_setup_conn(ldap_struct, uri);
792         if (rc) {
793                 return rc;
794         }
795
796         rc = smb_ldap_upgrade_conn(*ldap_struct, &version);
797         if (rc) {
798                 return rc;
799         }
800
801         rc = smbldap_start_tls(*ldap_struct, version);
802         if (rc) {
803                 return rc;
804         }
805
806         return LDAP_SUCCESS;
807 }
808
809 /*******************************************************************
810  open a connection to the ldap server.
811 ******************************************************************/
812 static int smbldap_open_connection (struct smbldap_state *ldap_state)
813
814 {
815         int rc = LDAP_SUCCESS;
816         int version;
817         int deref;
818         LDAP **ldap_struct = &ldap_state->ldap_struct;
819
820         rc = smb_ldap_setup_conn(ldap_struct, ldap_state->uri);
821         if (rc) {
822                 return rc;
823         }
824
825         /* Store the LDAP pointer in a lookup list */
826
827         smbldap_store_state(*ldap_struct, ldap_state);
828
829         /* Upgrade to LDAPv3 if possible */
830
831         rc = smb_ldap_upgrade_conn(*ldap_struct, &version);
832         if (rc) {
833                 return rc;
834         }
835
836         /* Start TLS if required */
837
838         rc = smbldap_start_tls(*ldap_struct, version);
839         if (rc) {
840                 return rc;
841         }
842
843         /* Set alias dereferencing method */
844         deref = lp_ldap_deref();
845         if (deref != -1) {
846                 if (ldap_set_option (*ldap_struct, LDAP_OPT_DEREF, &deref) != LDAP_OPT_SUCCESS) {
847                         DEBUG(1,("smbldap_open_connection: Failed to set dereferencing method: %d\n", deref));
848                 } else {
849                         DEBUG(5,("Set dereferencing method: %d\n", deref));
850                 }
851         }
852
853         DEBUG(2, ("smbldap_open_connection: connection opened\n"));
854         return rc;
855 }
856
857 /*******************************************************************
858  a rebind function for authenticated referrals
859  This version takes a void* that we can shove useful stuff in :-)
860 ******************************************************************/
861 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
862 #else
863 static int rebindproc_with_state  (LDAP * ld, char **whop, char **credp,
864                                    int *methodp, int freeit, void *arg)
865 {
866         struct smbldap_state *ldap_state = arg;
867         struct timespec ts;
868
869         /** @TODO Should we be doing something to check what servers we rebind to?
870             Could we get a referral to a machine that we don't want to give our
871             username and password to? */
872
873         if (freeit) {
874                 SAFE_FREE(*whop);
875                 if (*credp) {
876                         memset(*credp, '\0', strlen(*credp));
877                 }
878                 SAFE_FREE(*credp);
879         } else {
880                 DEBUG(5,("rebind_proc_with_state: Rebinding as \"%s\"\n",
881                           ldap_state->bind_dn?ldap_state->bind_dn:"[Anonymous bind]"));
882
883                 if (ldap_state->anonymous) {
884                         *whop = NULL;
885                         *credp = NULL;
886                 } else {
887                         *whop = SMB_STRDUP(ldap_state->bind_dn);
888                         if (!*whop) {
889                                 return LDAP_NO_MEMORY;
890                         }
891                         *credp = SMB_STRDUP(ldap_state->bind_secret);
892                         if (!*credp) {
893                                 SAFE_FREE(*whop);
894                                 return LDAP_NO_MEMORY;
895                         }
896                 }
897                 *methodp = LDAP_AUTH_SIMPLE;
898         }
899
900         clock_gettime_mono(&ts);
901         ldap_state->last_rebind = convert_timespec_to_timeval(ts);
902
903         return 0;
904 }
905 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
906
907 /*******************************************************************
908  a rebind function for authenticated referrals
909  This version takes a void* that we can shove useful stuff in :-)
910  and actually does the connection.
911 ******************************************************************/
912 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
913 static int rebindproc_connect_with_state (LDAP *ldap_struct,
914                                           LDAP_CONST char *url,
915                                           ber_tag_t request,
916                                           ber_int_t msgid, void *arg)
917 {
918         struct smbldap_state *ldap_state =
919                 (struct smbldap_state *)arg;
920         int rc;
921         struct timespec ts;
922         int version;
923
924         DEBUG(5,("rebindproc_connect_with_state: Rebinding to %s as \"%s\"\n",
925                  url, ldap_state->bind_dn?ldap_state->bind_dn:"[Anonymous bind]"));
926
927         /* call START_TLS again (ldaps:// is handled by the OpenLDAP library
928          * itself) before rebinding to another LDAP server to avoid to expose
929          * our credentials. At least *try* to secure the connection - Guenther */
930
931         smb_ldap_upgrade_conn(ldap_struct, &version);
932         smbldap_start_tls(ldap_struct, version);
933
934         /** @TODO Should we be doing something to check what servers we rebind to?
935             Could we get a referral to a machine that we don't want to give our
936             username and password to? */
937
938         rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
939
940         /* only set the last rebind timestamp when we did rebind after a
941          * non-read LDAP operation. That way we avoid the replication sleep
942          * after a simple redirected search operation - Guenther */
943
944         switch (request) {
945
946                 case LDAP_REQ_MODIFY:
947                 case LDAP_REQ_ADD:
948                 case LDAP_REQ_DELETE:
949                 case LDAP_REQ_MODDN:
950                 case LDAP_REQ_EXTENDED:
951                         DEBUG(10,("rebindproc_connect_with_state: "
952                                 "setting last_rebind timestamp "
953                                 "(req: 0x%02x)\n", (unsigned int)request));
954                         clock_gettime_mono(&ts);
955                         ldap_state->last_rebind = convert_timespec_to_timeval(ts);
956                         break;
957                 default:
958                         ZERO_STRUCT(ldap_state->last_rebind);
959                         break;
960         }
961
962         return rc;
963 }
964 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
965
966 /*******************************************************************
967  Add a rebind function for authenticated referrals
968 ******************************************************************/
969 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
970 #else
971 # if LDAP_SET_REBIND_PROC_ARGS == 2
972 static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
973                        int *method, int freeit )
974 {
975         struct smbldap_state *ldap_state = smbldap_find_state(ldap_struct);
976
977         return rebindproc_with_state(ldap_struct, whop, credp,
978                                      method, freeit, ldap_state);
979 }
980 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
981 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
982
983 /*******************************************************************
984  a rebind function for authenticated referrals
985  this also does the connection, but no void*.
986 ******************************************************************/
987 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
988 # if LDAP_SET_REBIND_PROC_ARGS == 2
989 static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request,
990                                ber_int_t msgid)
991 {
992         struct smbldap_state *ldap_state = smbldap_find_state(ld);
993
994         return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid,
995                                              ldap_state);
996 }
997 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
998 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
999
1000 /*******************************************************************
1001  connect to the ldap server under system privilege.
1002 ******************************************************************/
1003 static int smbldap_connect_system(struct smbldap_state *ldap_state)
1004 {
1005         LDAP *ldap_struct = smbldap_get_ldap(ldap_state);
1006         int rc;
1007         int version;
1008
1009         /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
1010            (OpenLDAP) doesn't seem to support it */
1011
1012         DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n",
1013                   ldap_state->uri, ldap_state->bind_dn));
1014
1015 #ifdef HAVE_LDAP_SET_REBIND_PROC
1016 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
1017 # if LDAP_SET_REBIND_PROC_ARGS == 2
1018         ldap_set_rebind_proc(ldap_struct, &rebindproc_connect);
1019 # endif
1020 # if LDAP_SET_REBIND_PROC_ARGS == 3
1021         ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state);
1022 # endif
1023 #else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
1024 # if LDAP_SET_REBIND_PROC_ARGS == 2
1025         ldap_set_rebind_proc(ldap_struct, &rebindproc);
1026 # endif
1027 # if LDAP_SET_REBIND_PROC_ARGS == 3
1028         ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state);
1029 # endif
1030 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
1031 #endif
1032
1033         /* When there is an alternative bind callback is set,
1034            attempt to use it to perform the bind */
1035         if (ldap_state->bind_callback != NULL) {
1036                 /* We have to allow bind callback to be run under become_root/unbecome_root
1037                    to make sure within smbd the callback has proper write access to its resources,
1038                    like credential cache. This is similar to passdb case where this callback is supposed
1039                    to be used. When used outside smbd, become_root()/unbecome_root() are no-op.
1040                 */
1041                 become_root();
1042                 rc = ldap_state->bind_callback(ldap_struct, ldap_state, ldap_state->bind_callback_data);
1043                 unbecome_root();
1044         } else {
1045                 rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
1046         }
1047
1048         if (rc != LDAP_SUCCESS) {
1049                 char *ld_error = NULL;
1050                 ldap_get_option(smbldap_get_ldap(ldap_state),
1051                                 LDAP_OPT_ERROR_STRING,
1052                                 &ld_error);
1053                 DEBUG(ldap_state->num_failures ? 2 : 0,
1054                       ("failed to bind to server %s with dn=\"%s\" Error: %s\n\t%s\n",
1055                                ldap_state->uri,
1056                                ldap_state->bind_dn ? ldap_state->bind_dn : "[Anonymous bind]",
1057                                ldap_err2string(rc),
1058                                ld_error ? ld_error : "(unknown)"));
1059                 SAFE_FREE(ld_error);
1060                 ldap_state->num_failures++;
1061                 goto done;
1062         }
1063
1064         ldap_state->num_failures = 0;
1065         ldap_state->paged_results = False;
1066
1067         ldap_get_option(smbldap_get_ldap(ldap_state),
1068                         LDAP_OPT_PROTOCOL_VERSION, &version);
1069
1070         if (smbldap_has_control(smbldap_get_ldap(ldap_state), ADS_PAGE_CTL_OID)
1071             && version == 3) {
1072                 ldap_state->paged_results = True;
1073         }
1074
1075         DEBUG(3, ("ldap_connect_system: successful connection to the LDAP server\n"));
1076         DEBUGADD(10, ("ldap_connect_system: LDAP server %s support paged results\n",
1077                 ldap_state->paged_results ? "does" : "does not"));
1078 done:
1079         if (rc != 0) {
1080                 ldap_unbind(ldap_struct);
1081                 ldap_state->ldap_struct = NULL;
1082         }
1083         return rc;
1084 }
1085
1086 static void smbldap_idle_fn(struct tevent_context *tevent_ctx,
1087                             struct tevent_timer *te,
1088                             struct timeval now_abs,
1089                             void *private_data);
1090
1091 /**********************************************************************
1092  Connect to LDAP server (called before every ldap operation)
1093 *********************************************************************/
1094 static int smbldap_open(struct smbldap_state *ldap_state)
1095 {
1096         int rc, opt_rc;
1097         bool reopen = False;
1098         SMB_ASSERT(ldap_state);
1099
1100         if ((smbldap_get_ldap(ldap_state) != NULL) &&
1101             ((ldap_state->last_ping + SMBLDAP_DONT_PING_TIME) <
1102              time_mono(NULL))) {
1103
1104 #ifdef HAVE_UNIXSOCKET
1105                 struct sockaddr_un addr;
1106 #else
1107                 struct sockaddr_storage addr;
1108 #endif
1109                 socklen_t len = sizeof(addr);
1110                 int sd;
1111
1112                 opt_rc = ldap_get_option(smbldap_get_ldap(ldap_state),
1113                                          LDAP_OPT_DESC, &sd);
1114                 if (opt_rc == 0 && (getpeername(sd, (struct sockaddr *) &addr, &len)) < 0 )
1115                         reopen = True;
1116
1117 #ifdef HAVE_UNIXSOCKET
1118                 if (opt_rc == 0 && addr.sun_family == AF_UNIX)
1119                         reopen = True;
1120 #endif
1121                 if (reopen) {
1122                         /* the other end has died. reopen. */
1123                         ldap_unbind(smbldap_get_ldap(ldap_state));
1124                         ldap_state->ldap_struct = NULL;
1125                         ldap_state->last_ping = (time_t)0;
1126                 } else {
1127                         ldap_state->last_ping = time_mono(NULL);
1128                 }
1129         }
1130
1131         if (smbldap_get_ldap(ldap_state) != NULL) {
1132                 DEBUG(11,("smbldap_open: already connected to the LDAP server\n"));
1133                 return LDAP_SUCCESS;
1134         }
1135
1136         if ((rc = smbldap_open_connection(ldap_state))) {
1137                 return rc;
1138         }
1139
1140         if ((rc = smbldap_connect_system(ldap_state))) {
1141                 return rc;
1142         }
1143
1144
1145         ldap_state->last_ping = time_mono(NULL);
1146         ldap_state->pid = getpid();
1147
1148         TALLOC_FREE(ldap_state->idle_event);
1149
1150         if (ldap_state->tevent_context != NULL) {
1151                 ldap_state->idle_event = tevent_add_timer(
1152                         ldap_state->tevent_context, ldap_state,
1153                         timeval_current_ofs(SMBLDAP_IDLE_TIME, 0),
1154                         smbldap_idle_fn, ldap_state);
1155         }
1156
1157         DEBUG(4,("The LDAP server is successfully connected\n"));
1158
1159         return LDAP_SUCCESS;
1160 }
1161
1162 /**********************************************************************
1163 Disconnect from LDAP server
1164 *********************************************************************/
1165 static NTSTATUS smbldap_close(struct smbldap_state *ldap_state)
1166 {
1167         if (!ldap_state)
1168                 return NT_STATUS_INVALID_PARAMETER;
1169
1170         if (smbldap_get_ldap(ldap_state) != NULL) {
1171                 ldap_unbind(smbldap_get_ldap(ldap_state));
1172                 ldap_state->ldap_struct = NULL;
1173         }
1174
1175         smbldap_delete_state(ldap_state);
1176
1177         TALLOC_FREE(ldap_state->idle_event);
1178
1179         DEBUG(5,("The connection to the LDAP server was closed\n"));
1180         /* maybe free the results here --metze */
1181
1182         return NT_STATUS_OK;
1183 }
1184
1185 static SIG_ATOMIC_T got_alarm;
1186
1187 static void gotalarm_sig(int dummy)
1188 {
1189         got_alarm = 1;
1190 }
1191
1192 static time_t calc_ldap_abs_endtime(int ldap_to)
1193 {
1194         if (ldap_to == 0) {
1195                 /* No timeout - don't
1196                    return a value for
1197                    the alarm. */
1198                 return (time_t)0;
1199         }
1200
1201         /* Make the alarm time one second beyond
1202            the timeout we're setting for the
1203            remote search timeout, to allow that
1204            to fire in preference. */
1205
1206         return time_mono(NULL)+ldap_to+1;
1207 }
1208
1209 static int end_ldap_local_alarm(time_t absolute_endtime, int rc)
1210 {
1211         if (absolute_endtime) {
1212                 alarm(0);
1213                 CatchSignal(SIGALRM, SIG_IGN);
1214                 if (got_alarm) {
1215                         /* Client timeout error code. */
1216                         got_alarm = 0;
1217                         return LDAP_TIMEOUT;
1218                 }
1219         }
1220         return rc;
1221 }
1222
1223 static void setup_ldap_local_alarm(struct smbldap_state *ldap_state, time_t absolute_endtime)
1224 {
1225         time_t now = time_mono(NULL);
1226
1227         if (absolute_endtime) {
1228                 got_alarm = 0;
1229                 CatchSignal(SIGALRM, gotalarm_sig);
1230                 alarm(absolute_endtime - now);
1231         }
1232
1233         if (ldap_state->pid != getpid()) {
1234                 smbldap_close(ldap_state);
1235         }
1236 }
1237
1238 static void get_ldap_errs(struct smbldap_state *ldap_state, char **pp_ld_error, int *p_ld_errno)
1239 {
1240         ldap_get_option(smbldap_get_ldap(ldap_state),
1241                         LDAP_OPT_ERROR_NUMBER, p_ld_errno);
1242
1243         ldap_get_option(smbldap_get_ldap(ldap_state),
1244                         LDAP_OPT_ERROR_STRING, pp_ld_error);
1245 }
1246
1247 static int get_cached_ldap_connect(struct smbldap_state *ldap_state, time_t abs_endtime)
1248 {
1249         int attempts = 0;
1250
1251         while (1) {
1252                 int rc;
1253                 time_t now;
1254
1255                 now = time_mono(NULL);
1256                 ldap_state->last_use = now;
1257
1258                 if (abs_endtime && now > abs_endtime) {
1259                         smbldap_close(ldap_state);
1260                         return LDAP_TIMEOUT;
1261                 }
1262
1263                 rc = smbldap_open(ldap_state);
1264
1265                 if (rc == LDAP_SUCCESS) {
1266                         return LDAP_SUCCESS;
1267                 }
1268
1269                 attempts++;
1270                 DEBUG(1, ("Connection to LDAP server failed for the "
1271                         "%d try!\n", attempts));
1272
1273                 if (rc == LDAP_INSUFFICIENT_ACCESS) {
1274                         /* The fact that we are non-root or any other
1275                          * access-denied condition will not change in the next
1276                          * round of trying */
1277                         return rc;
1278                 }
1279
1280                 if (got_alarm) {
1281                         smbldap_close(ldap_state);
1282                         return LDAP_TIMEOUT;
1283                 }
1284
1285                 smb_msleep(1000);
1286
1287                 if (got_alarm) {
1288                         smbldap_close(ldap_state);
1289                         return LDAP_TIMEOUT;
1290                 }
1291         }
1292 }
1293
1294 /*********************************************************************
1295  ********************************************************************/
1296
1297 static int smbldap_search_ext(struct smbldap_state *ldap_state,
1298                               const char *base, int scope, const char *filter,
1299                               const char *attrs[], int attrsonly,
1300                               LDAPControl **sctrls, LDAPControl **cctrls,
1301                               int sizelimit, LDAPMessage **res)
1302 {
1303         int             rc = LDAP_SERVER_DOWN;
1304         char           *utf8_filter;
1305         int             to = lp_ldap_timeout();
1306         time_t          abs_endtime = calc_ldap_abs_endtime(to);
1307         struct          timeval timeout;
1308         struct          timeval *timeout_ptr = NULL;
1309         size_t          converted_size;
1310
1311         SMB_ASSERT(ldap_state);
1312
1313         DEBUG(5,("smbldap_search_ext: base => [%s], filter => [%s], "
1314                  "scope => [%d]\n", base, filter, scope));
1315
1316         if (ldap_state->last_rebind.tv_sec > 0) {
1317                 struct timeval  tval;
1318                 struct timespec ts;
1319                 int64_t tdiff = 0;
1320                 int             sleep_time = 0;
1321
1322                 clock_gettime_mono(&ts);
1323                 tval = convert_timespec_to_timeval(ts);
1324
1325                 tdiff = usec_time_diff(&tval, &ldap_state->last_rebind);
1326                 tdiff /= 1000; /* Convert to milliseconds. */
1327
1328                 sleep_time = lp_ldap_replication_sleep()-(int)tdiff;
1329                 sleep_time = MIN(sleep_time, MAX_LDAP_REPLICATION_SLEEP_TIME);
1330
1331                 if (sleep_time > 0) {
1332                         /* we wait for the LDAP replication */
1333                         DEBUG(5,("smbldap_search_ext: waiting %d milliseconds "
1334                                  "for LDAP replication.\n",sleep_time));
1335                         smb_msleep(sleep_time);
1336                         DEBUG(5,("smbldap_search_ext: go on!\n"));
1337                 }
1338                 ZERO_STRUCT(ldap_state->last_rebind);
1339         }
1340
1341         if (!push_utf8_talloc(talloc_tos(), &utf8_filter, filter, &converted_size)) {
1342                 return LDAP_NO_MEMORY;
1343         }
1344
1345         /* Setup remote timeout for the ldap_search_ext_s call. */
1346         if (to) {
1347                 timeout.tv_sec = to;
1348                 timeout.tv_usec = 0;
1349                 timeout_ptr = &timeout;
1350         }
1351
1352         setup_ldap_local_alarm(ldap_state, abs_endtime);
1353
1354         while (1) {
1355                 char *ld_error = NULL;
1356                 int ld_errno;
1357
1358                 rc = get_cached_ldap_connect(ldap_state, abs_endtime);
1359                 if (rc != LDAP_SUCCESS) {
1360                         break;
1361                 }
1362
1363                 rc = ldap_search_ext_s(smbldap_get_ldap(ldap_state),
1364                                        base, scope,
1365                                        utf8_filter,
1366                                        discard_const_p(char *, attrs),
1367                                        attrsonly, sctrls, cctrls, timeout_ptr,
1368                                        sizelimit, res);
1369                 if (rc == LDAP_SUCCESS) {
1370                         break;
1371                 }
1372
1373                 get_ldap_errs(ldap_state, &ld_error, &ld_errno);
1374
1375                 DEBUG(10, ("Failed search for base: %s, error: %d (%s) "
1376                            "(%s)\n", base, ld_errno,
1377                            ldap_err2string(rc),
1378                            ld_error ? ld_error : "unknown"));
1379                 SAFE_FREE(ld_error);
1380
1381                 if (ld_errno != LDAP_SERVER_DOWN) {
1382                         break;
1383                 }
1384                 ldap_unbind(smbldap_get_ldap(ldap_state));
1385                 ldap_state->ldap_struct = NULL;
1386         }
1387
1388         TALLOC_FREE(utf8_filter);
1389         return end_ldap_local_alarm(abs_endtime, rc);
1390 }
1391
1392 int smbldap_search(struct smbldap_state *ldap_state,
1393                    const char *base, int scope, const char *filter,
1394                    const char *attrs[], int attrsonly,
1395                    LDAPMessage **res)
1396 {
1397         return smbldap_search_ext(ldap_state, base, scope, filter, attrs,
1398                                   attrsonly, NULL, NULL, LDAP_NO_LIMIT, res);
1399 }
1400
1401 int smbldap_search_paged(struct smbldap_state *ldap_state,
1402                          const char *base, int scope, const char *filter,
1403                          const char **attrs, int attrsonly, int pagesize,
1404                          LDAPMessage **res, void **cookie)
1405 {
1406         LDAPControl     pr;
1407         LDAPControl     **rcontrols;
1408         LDAPControl     *controls[2] = { NULL, NULL};
1409         BerElement      *cookie_be = NULL;
1410         struct berval   *cookie_bv = NULL;
1411         int             tmp = 0, i, rc;
1412         bool            critical = True;
1413
1414         *res = NULL;
1415
1416         DEBUG(3,("smbldap_search_paged: base => [%s], filter => [%s],"
1417                  "scope => [%d], pagesize => [%d]\n",
1418                  base, filter, scope, pagesize));
1419
1420         cookie_be = ber_alloc_t(LBER_USE_DER);
1421         if (cookie_be == NULL) {
1422                 DEBUG(0,("smbldap_create_page_control: ber_alloc_t returns "
1423                          "NULL\n"));
1424                 return LDAP_NO_MEMORY;
1425         }
1426
1427         /* construct cookie */
1428         if (*cookie != NULL) {
1429                 ber_printf(cookie_be, "{iO}", (ber_int_t) pagesize, *cookie);
1430                 ber_bvfree((struct berval *)*cookie); /* don't need it from last time */
1431                 *cookie = NULL;
1432         } else {
1433                 ber_printf(cookie_be, "{io}", (ber_int_t) pagesize, "", 0);
1434         }
1435         ber_flatten(cookie_be, &cookie_bv);
1436
1437         pr.ldctl_oid = discard_const_p(char, ADS_PAGE_CTL_OID);
1438         pr.ldctl_iscritical = (char) critical;
1439         pr.ldctl_value.bv_len = cookie_bv->bv_len;
1440         pr.ldctl_value.bv_val = cookie_bv->bv_val;
1441
1442         controls[0] = &pr;
1443         controls[1] = NULL;
1444
1445         rc = smbldap_search_ext(ldap_state, base, scope, filter, attrs,
1446                                  0, controls, NULL, LDAP_NO_LIMIT, res);
1447
1448         ber_free(cookie_be, 1);
1449         ber_bvfree(cookie_bv);
1450
1451         if (rc != 0) {
1452                 DEBUG(3,("smbldap_search_paged: smbldap_search_ext(%s) "
1453                          "failed with [%s]\n", filter, ldap_err2string(rc)));
1454                 goto done;
1455         }
1456
1457         DEBUG(3,("smbldap_search_paged: search was successful\n"));
1458
1459         rc = ldap_parse_result(smbldap_get_ldap(ldap_state), *res, NULL, NULL,
1460                                NULL, NULL, &rcontrols,  0);
1461         if (rc != 0) {
1462                 DEBUG(3,("smbldap_search_paged: ldap_parse_result failed " \
1463                          "with [%s]\n", ldap_err2string(rc)));
1464                 goto done;
1465         }
1466
1467         if (rcontrols == NULL)
1468                 goto done;
1469
1470         for (i=0; rcontrols[i]; i++) {
1471
1472                 if (strcmp(ADS_PAGE_CTL_OID, rcontrols[i]->ldctl_oid) != 0)
1473                         continue;
1474
1475                 cookie_be = ber_init(&rcontrols[i]->ldctl_value);
1476                 ber_scanf(cookie_be,"{iO}", &tmp, &cookie_bv);
1477                 /* the berval is the cookie, but must be freed when it is all
1478                    done */
1479                 if (cookie_bv->bv_len)
1480                         *cookie=ber_bvdup(cookie_bv);
1481                 else
1482                         *cookie=NULL;
1483                 ber_bvfree(cookie_bv);
1484                 ber_free(cookie_be, 1);
1485                 break;
1486         }
1487         ldap_controls_free(rcontrols);
1488 done:
1489         return rc;
1490 }
1491
1492 int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs[])
1493 {
1494         int             rc = LDAP_SERVER_DOWN;
1495         char           *utf8_dn;
1496         time_t          abs_endtime = calc_ldap_abs_endtime(lp_ldap_timeout());
1497         size_t          converted_size;
1498
1499         SMB_ASSERT(ldap_state);
1500
1501         DEBUG(5,("smbldap_modify: dn => [%s]\n", dn ));
1502
1503         if (!push_utf8_talloc(talloc_tos(), &utf8_dn, dn, &converted_size)) {
1504                 return LDAP_NO_MEMORY;
1505         }
1506
1507         setup_ldap_local_alarm(ldap_state, abs_endtime);
1508
1509         while (1) {
1510                 char *ld_error = NULL;
1511                 int ld_errno;
1512
1513                 rc = get_cached_ldap_connect(ldap_state, abs_endtime);
1514                 if (rc != LDAP_SUCCESS) {
1515                         break;
1516                 }
1517
1518                 rc = ldap_modify_s(smbldap_get_ldap(ldap_state), utf8_dn,
1519                                    attrs);
1520                 if (rc == LDAP_SUCCESS) {
1521                         break;
1522                 }
1523
1524                 get_ldap_errs(ldap_state, &ld_error, &ld_errno);
1525
1526                 DEBUG(10, ("Failed to modify dn: %s, error: %d (%s) "
1527                            "(%s)\n", dn, ld_errno,
1528                            ldap_err2string(rc),
1529                            ld_error ? ld_error : "unknown"));
1530                 SAFE_FREE(ld_error);
1531
1532                 if (ld_errno != LDAP_SERVER_DOWN) {
1533                         break;
1534                 }
1535                 ldap_unbind(smbldap_get_ldap(ldap_state));
1536                 ldap_state->ldap_struct = NULL;
1537         }
1538
1539         TALLOC_FREE(utf8_dn);
1540         return end_ldap_local_alarm(abs_endtime, rc);
1541 }
1542
1543 int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs[])
1544 {
1545         int             rc = LDAP_SERVER_DOWN;
1546         char           *utf8_dn;
1547         time_t          abs_endtime = calc_ldap_abs_endtime(lp_ldap_timeout());
1548         size_t          converted_size;
1549
1550         SMB_ASSERT(ldap_state);
1551
1552         DEBUG(5,("smbldap_add: dn => [%s]\n", dn ));
1553
1554         if (!push_utf8_talloc(talloc_tos(), &utf8_dn, dn, &converted_size)) {
1555                 return LDAP_NO_MEMORY;
1556         }
1557
1558         setup_ldap_local_alarm(ldap_state, abs_endtime);
1559
1560         while (1) {
1561                 char *ld_error = NULL;
1562                 int ld_errno;
1563
1564                 rc = get_cached_ldap_connect(ldap_state, abs_endtime);
1565                 if (rc != LDAP_SUCCESS) {
1566                         break;
1567                 }
1568
1569                 rc = ldap_add_s(smbldap_get_ldap(ldap_state), utf8_dn, attrs);
1570                 if (rc == LDAP_SUCCESS) {
1571                         break;
1572                 }
1573
1574                 get_ldap_errs(ldap_state, &ld_error, &ld_errno);
1575
1576                 DEBUG(10, ("Failed to add dn: %s, error: %d (%s) "
1577                            "(%s)\n", dn, ld_errno,
1578                            ldap_err2string(rc),
1579                            ld_error ? ld_error : "unknown"));
1580                 SAFE_FREE(ld_error);
1581
1582                 if (ld_errno != LDAP_SERVER_DOWN) {
1583                         break;
1584                 }
1585                 ldap_unbind(smbldap_get_ldap(ldap_state));
1586                 ldap_state->ldap_struct = NULL;
1587         }
1588
1589         TALLOC_FREE(utf8_dn);
1590         return end_ldap_local_alarm(abs_endtime, rc);
1591 }
1592
1593 int smbldap_delete(struct smbldap_state *ldap_state, const char *dn)
1594 {
1595         int             rc = LDAP_SERVER_DOWN;
1596         char           *utf8_dn;
1597         time_t          abs_endtime = calc_ldap_abs_endtime(lp_ldap_timeout());
1598         size_t          converted_size;
1599
1600         SMB_ASSERT(ldap_state);
1601
1602         DEBUG(5,("smbldap_delete: dn => [%s]\n", dn ));
1603
1604         if (!push_utf8_talloc(talloc_tos(), &utf8_dn, dn, &converted_size)) {
1605                 return LDAP_NO_MEMORY;
1606         }
1607
1608         setup_ldap_local_alarm(ldap_state, abs_endtime);
1609
1610         while (1) {
1611                 char *ld_error = NULL;
1612                 int ld_errno;
1613
1614                 rc = get_cached_ldap_connect(ldap_state, abs_endtime);
1615                 if (rc != LDAP_SUCCESS) {
1616                         break;
1617                 }
1618
1619                 rc = ldap_delete_s(smbldap_get_ldap(ldap_state), utf8_dn);
1620                 if (rc == LDAP_SUCCESS) {
1621                         break;
1622                 }
1623
1624                 get_ldap_errs(ldap_state, &ld_error, &ld_errno);
1625
1626                 DEBUG(10, ("Failed to delete dn: %s, error: %d (%s) "
1627                            "(%s)\n", dn, ld_errno,
1628                            ldap_err2string(rc),
1629                            ld_error ? ld_error : "unknown"));
1630                 SAFE_FREE(ld_error);
1631
1632                 if (ld_errno != LDAP_SERVER_DOWN) {
1633                         break;
1634                 }
1635                 ldap_unbind(smbldap_get_ldap(ldap_state));
1636                 ldap_state->ldap_struct = NULL;
1637         }
1638
1639         TALLOC_FREE(utf8_dn);
1640         return end_ldap_local_alarm(abs_endtime, rc);
1641 }
1642
1643 int smbldap_extended_operation(struct smbldap_state *ldap_state,
1644                                LDAP_CONST char *reqoid, struct berval *reqdata,
1645                                LDAPControl **serverctrls, LDAPControl **clientctrls,
1646                                char **retoidp, struct berval **retdatap)
1647 {
1648         int             rc = LDAP_SERVER_DOWN;
1649         time_t          abs_endtime = calc_ldap_abs_endtime(lp_ldap_timeout());
1650
1651         if (!ldap_state)
1652                 return (-1);
1653
1654         setup_ldap_local_alarm(ldap_state, abs_endtime);
1655
1656         while (1) {
1657                 char *ld_error = NULL;
1658                 int ld_errno;
1659
1660                 rc = get_cached_ldap_connect(ldap_state, abs_endtime);
1661                 if (rc != LDAP_SUCCESS) {
1662                         break;
1663                 }
1664
1665                 rc = ldap_extended_operation_s(smbldap_get_ldap(ldap_state),
1666                                                reqoid,
1667                                                reqdata, serverctrls,
1668                                                clientctrls, retoidp, retdatap);
1669                 if (rc == LDAP_SUCCESS) {
1670                         break;
1671                 }
1672
1673                 get_ldap_errs(ldap_state, &ld_error, &ld_errno);
1674
1675                 DEBUG(10, ("Extended operation failed with error: "
1676                            "%d (%s) (%s)\n", ld_errno,
1677                            ldap_err2string(rc),
1678                            ld_error ? ld_error : "unknown"));
1679                 SAFE_FREE(ld_error);
1680
1681                 if (ld_errno != LDAP_SERVER_DOWN) {
1682                         break;
1683                 }
1684                 ldap_unbind(smbldap_get_ldap(ldap_state));
1685                 ldap_state->ldap_struct = NULL;
1686         }
1687
1688         return end_ldap_local_alarm(abs_endtime, rc);
1689 }
1690
1691 /*******************************************************************
1692  run the search by name.
1693 ******************************************************************/
1694 int smbldap_search_suffix (struct smbldap_state *ldap_state,
1695                            const char *filter, const char **search_attr,
1696                            LDAPMessage ** result)
1697 {
1698         return smbldap_search(ldap_state, lp_ldap_suffix(),
1699                               LDAP_SCOPE_SUBTREE,
1700                               filter, search_attr, 0, result);
1701 }
1702
1703 static void smbldap_idle_fn(struct tevent_context *tevent_ctx,
1704                             struct tevent_timer *te,
1705                             struct timeval now_abs,
1706                             void *private_data)
1707 {
1708         struct smbldap_state *state = (struct smbldap_state *)private_data;
1709
1710         TALLOC_FREE(state->idle_event);
1711
1712         if (smbldap_get_ldap(state) == NULL) {
1713                 DEBUG(10,("ldap connection not connected...\n"));
1714                 return;
1715         }
1716
1717         if ((state->last_use+SMBLDAP_IDLE_TIME) > time_mono(NULL)) {
1718                 DEBUG(10,("ldap connection not idle...\n"));
1719
1720                 /* this needs to be made monotonic clock aware inside tevent: */
1721                 state->idle_event = tevent_add_timer(
1722                         tevent_ctx, state,
1723                         timeval_add(&now_abs, SMBLDAP_IDLE_TIME, 0),
1724                         smbldap_idle_fn,
1725                         private_data);
1726                 return;
1727         }
1728
1729         DEBUG(7,("ldap connection idle...closing connection\n"));
1730         smbldap_close(state);
1731 }
1732
1733 /**********************************************************************
1734  Housekeeping
1735  *********************************************************************/
1736
1737 void smbldap_free_struct(struct smbldap_state **ldap_state)
1738 {
1739         smbldap_close(*ldap_state);
1740
1741         if ((*ldap_state)->bind_secret) {
1742                 memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
1743         }
1744
1745         SAFE_FREE((*ldap_state)->bind_dn);
1746         BURN_FREE_STR((*ldap_state)->bind_secret);
1747         smbldap_set_bind_callback(*ldap_state, NULL, NULL);
1748
1749         TALLOC_FREE(*ldap_state);
1750
1751         /* No need to free any further, as it is talloc()ed */
1752 }
1753
1754 static int smbldap_state_destructor(struct smbldap_state *state)
1755 {
1756         smbldap_free_struct(&state);
1757         return 0;
1758 }
1759
1760
1761 /**********************************************************************
1762  Initialise the 'general' ldap structures, on which ldap operations may be conducted
1763  *********************************************************************/
1764
1765 NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, struct tevent_context *tevent_ctx,
1766                       const char *location,
1767                       bool anon,
1768                       const char *bind_dn,
1769                       const char *bind_secret,
1770                       struct smbldap_state **smbldap_state)
1771 {
1772         *smbldap_state = talloc_zero(mem_ctx, struct smbldap_state);
1773         if (!*smbldap_state) {
1774                 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
1775                 return NT_STATUS_NO_MEMORY;
1776         }
1777
1778         if (location) {
1779                 (*smbldap_state)->uri = talloc_strdup(mem_ctx, location);
1780         } else {
1781                 (*smbldap_state)->uri = "ldap://localhost";
1782         }
1783
1784         (*smbldap_state)->tevent_context = tevent_ctx;
1785
1786         if (bind_dn && bind_secret) {
1787                 smbldap_set_creds(*smbldap_state, anon, bind_dn, bind_secret);
1788         }
1789
1790         talloc_set_destructor(*smbldap_state, smbldap_state_destructor);
1791         return NT_STATUS_OK;
1792 }
1793
1794  char *smbldap_talloc_dn(TALLOC_CTX *mem_ctx, LDAP *ld,
1795                          LDAPMessage *entry)
1796 {
1797         char *utf8_dn, *unix_dn;
1798         size_t converted_size;
1799
1800         utf8_dn = ldap_get_dn(ld, entry);
1801         if (!utf8_dn) {
1802                 DEBUG (5, ("smbldap_talloc_dn: ldap_get_dn failed\n"));
1803                 return NULL;
1804         }
1805         if (!pull_utf8_talloc(mem_ctx, &unix_dn, utf8_dn, &converted_size)) {
1806                 DEBUG (0, ("smbldap_talloc_dn: String conversion failure utf8 "
1807                            "[%s]\n", utf8_dn));
1808                 return NULL;
1809         }
1810         ldap_memfree(utf8_dn);
1811         return unix_dn;
1812 }
1813
1814 /*******************************************************************
1815  Check if root-dse has a certain Control or Extension
1816 ********************************************************************/
1817
1818 static bool smbldap_check_root_dse(LDAP *ld, const char **attrs, const char *value)
1819 {
1820         LDAPMessage *msg = NULL;
1821         LDAPMessage *entry = NULL;
1822         char **values = NULL;
1823         int rc, num_result, num_values, i;
1824         bool result = False;
1825
1826         if (!attrs[0]) {
1827                 DEBUG(3,("smbldap_check_root_dse: nothing to look for\n"));
1828                 return False;
1829         }
1830
1831         if (!strequal(attrs[0], "supportedExtension") &&
1832             !strequal(attrs[0], "supportedControl") &&
1833             !strequal(attrs[0], "namingContexts")) {
1834                 DEBUG(3,("smbldap_check_root_dse: no idea what to query root-dse for: %s ?\n", attrs[0]));
1835                 return False;
1836         }
1837
1838         rc = ldap_search_s(ld, "", LDAP_SCOPE_BASE,
1839                            "(objectclass=*)", discard_const_p(char *, attrs), 0 , &msg);
1840
1841         if (rc != LDAP_SUCCESS) {
1842                 DEBUG(3,("smbldap_check_root_dse: Could not search rootDSE\n"));
1843                 return False;
1844         }
1845
1846         num_result = ldap_count_entries(ld, msg);
1847
1848         if (num_result != 1) {
1849                 DEBUG(3,("smbldap_check_root_dse: Expected one rootDSE, got %d\n", num_result));
1850                 goto done;
1851         }
1852
1853         entry = ldap_first_entry(ld, msg);
1854
1855         if (entry == NULL) {
1856                 DEBUG(3,("smbldap_check_root_dse: Could not retrieve rootDSE\n"));
1857                 goto done;
1858         }
1859
1860         values = ldap_get_values(ld, entry, attrs[0]);
1861
1862         if (values == NULL) {
1863                 DEBUG(5,("smbldap_check_root_dse: LDAP Server does not support any %s\n", attrs[0]));
1864                 goto done;
1865         }
1866
1867         num_values = ldap_count_values(values);
1868
1869         if (num_values == 0) {
1870                 DEBUG(5,("smbldap_check_root_dse: LDAP Server does not have any %s\n", attrs[0]));
1871                 goto done;
1872         }
1873
1874         for (i=0; i<num_values; i++) {
1875                 if (strcmp(values[i], value) == 0)
1876                         result = True;
1877         }
1878
1879
1880  done:
1881         if (values != NULL)
1882                 ldap_value_free(values);
1883         if (msg != NULL)
1884                 ldap_msgfree(msg);
1885
1886         return result;
1887
1888 }
1889
1890 /*******************************************************************
1891  Check if LDAP-Server supports a certain Control (OID in string format)
1892 ********************************************************************/
1893
1894 bool smbldap_has_control(LDAP *ld, const char *control)
1895 {
1896         const char *attrs[] = { "supportedControl", NULL };
1897         return smbldap_check_root_dse(ld, attrs, control);
1898 }
1899
1900 /*******************************************************************
1901  Check if LDAP-Server supports a certain Extension (OID in string format)
1902 ********************************************************************/
1903
1904 bool smbldap_has_extension(LDAP *ld, const char *extension)
1905 {
1906         const char *attrs[] = { "supportedExtension", NULL };
1907         return smbldap_check_root_dse(ld, attrs, extension);
1908 }
1909
1910 /*******************************************************************
1911  Check if LDAP-Server holds a given namingContext
1912 ********************************************************************/
1913
1914 bool smbldap_has_naming_context(LDAP *ld, const char *naming_context)
1915 {
1916         const char *attrs[] = { "namingContexts", NULL };
1917         return smbldap_check_root_dse(ld, attrs, naming_context);
1918 }
1919
1920 bool smbldap_set_creds(struct smbldap_state *ldap_state, bool anon, const char *dn, const char *secret)
1921 {
1922         ldap_state->anonymous = anon;
1923
1924         /* free any previously set credential */
1925
1926         SAFE_FREE(ldap_state->bind_dn);
1927         smbldap_set_bind_callback(ldap_state, NULL, NULL);
1928
1929         if (ldap_state->bind_secret) {
1930                 /* make sure secrets are zeroed out of memory */
1931                 memset(ldap_state->bind_secret, '\0', strlen(ldap_state->bind_secret));
1932                 SAFE_FREE(ldap_state->bind_secret);
1933         }
1934
1935         if ( ! anon) {
1936                 ldap_state->bind_dn = SMB_STRDUP(dn);
1937                 ldap_state->bind_secret = SMB_STRDUP(secret);
1938         }
1939
1940         return True;
1941 }