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