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