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