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