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
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.
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.
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/>.
27 #include "../libcli/security/security.h"
29 #include "lib/param/loadparm.h"
31 /* Try not to hit the up or down server forever */
33 #define SMBLDAP_DONT_PING_TIME 10 /* ping only all 10 seconds */
34 #define SMBLDAP_NUM_RETRIES 8 /* retry only 8 times */
36 #define SMBLDAP_IDLE_TIME 150 /* After 2.5 minutes disconnect */
38 struct smbldap_state
{
41 time_t last_ping
; /* monotonic */
42 /* retrieve-once info */
49 smbldap_bind_callback_fn bind_callback
;
50 void *bind_callback_data
;
54 unsigned int num_failures
;
56 time_t last_use
; /* monotonic */
57 struct tevent_context
*tevent_context
;
58 struct tevent_timer
*idle_event
;
60 struct timeval last_rebind
; /* monotonic */
63 LDAP
*smbldap_get_ldap(struct smbldap_state
*state
)
65 return state
->ldap_struct
;
68 bool smbldap_get_paged_results(struct smbldap_state
*state
)
70 return state
->paged_results
;
73 void smbldap_set_paged_results(struct smbldap_state
*state
,
76 state
->paged_results
= paged_results
;
79 void smbldap_set_bind_callback(struct smbldap_state
*state
,
80 smbldap_bind_callback_fn callback
,
83 state
->bind_callback
= callback
;
84 state
->bind_callback_data
= callback_data
;
86 /*******************************************************************
87 Search an attribute and return the first value found.
88 ******************************************************************/
90 bool smbldap_get_single_attribute (LDAP
* ldap_struct
, LDAPMessage
* entry
,
91 const char *attribute
, char *value
,
102 if ((values
= ldap_get_values (ldap_struct
, entry
, attribute
)) == NULL
) {
103 DEBUG (10, ("smbldap_get_single_attribute: [%s] = [<does not exist>]\n", attribute
));
108 if (!convert_string(CH_UTF8
, CH_UNIX
,values
[0], -1, value
, max_len
, &size
)) {
109 DEBUG(1, ("smbldap_get_single_attribute: string conversion of [%s] = [%s] failed!\n",
110 attribute
, values
[0]));
111 ldap_value_free(values
);
115 ldap_value_free(values
);
116 #ifdef DEBUG_PASSWORDS
117 DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n", attribute
, value
));
122 char * smbldap_talloc_single_attribute(LDAP
*ldap_struct
, LDAPMessage
*entry
,
123 const char *attribute
,
128 size_t converted_size
;
130 if (attribute
== NULL
) {
134 values
= ldap_get_values(ldap_struct
, entry
, attribute
);
136 if (values
== NULL
) {
137 DEBUG(10, ("attribute %s does not exist\n", attribute
));
141 if (ldap_count_values(values
) != 1) {
142 DEBUG(10, ("attribute %s has %d values, expected only one\n",
143 attribute
, ldap_count_values(values
)));
144 ldap_value_free(values
);
148 if (!pull_utf8_talloc(mem_ctx
, &result
, values
[0], &converted_size
)) {
149 DEBUG(10, ("pull_utf8_talloc failed\n"));
150 ldap_value_free(values
);
154 ldap_value_free(values
);
156 #ifdef DEBUG_PASSWORDS
157 DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n",
163 char * smbldap_talloc_first_attribute(LDAP
*ldap_struct
, LDAPMessage
*entry
,
164 const char *attribute
,
169 size_t converted_size
;
171 if (attribute
== NULL
) {
175 values
= ldap_get_values(ldap_struct
, entry
, attribute
);
177 if (values
== NULL
) {
178 DEBUG(10, ("attribute %s does not exist\n", attribute
));
182 if (!pull_utf8_talloc(mem_ctx
, &result
, values
[0], &converted_size
)) {
183 DEBUG(10, ("pull_utf8_talloc failed\n"));
184 ldap_value_free(values
);
188 ldap_value_free(values
);
190 #ifdef DEBUG_PASSWORDS
191 DEBUG (100, ("smbldap_get_first_attribute: [%s] = [%s]\n",
197 char * smbldap_talloc_smallest_attribute(LDAP
*ldap_struct
, LDAPMessage
*entry
,
198 const char *attribute
,
203 size_t converted_size
;
206 if (attribute
== NULL
) {
210 values
= ldap_get_values(ldap_struct
, entry
, attribute
);
212 if (values
== NULL
) {
213 DEBUG(10, ("attribute %s does not exist\n", attribute
));
217 if (!pull_utf8_talloc(mem_ctx
, &result
, values
[0], &converted_size
)) {
218 DEBUG(10, ("pull_utf8_talloc failed\n"));
219 ldap_value_free(values
);
223 num_values
= ldap_count_values(values
);
225 for (i
=1; i
<num_values
; i
++) {
228 if (!pull_utf8_talloc(mem_ctx
, &tmp
, values
[i
],
230 DEBUG(10, ("pull_utf8_talloc failed\n"));
232 ldap_value_free(values
);
236 if (strcasecmp_m(tmp
, result
) < 0) {
244 ldap_value_free(values
);
246 #ifdef DEBUG_PASSWORDS
247 DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n",
253 bool smbldap_talloc_single_blob(TALLOC_CTX
*mem_ctx
, LDAP
*ld
,
254 LDAPMessage
*msg
, const char *attrib
,
257 struct berval
**values
;
259 values
= ldap_get_values_len(ld
, msg
, attrib
);
264 if (ldap_count_values_len(values
) != 1) {
265 DEBUG(10, ("Expected one value for %s, got %d\n", attrib
,
266 ldap_count_values_len(values
)));
270 *blob
= data_blob_talloc(mem_ctx
, values
[0]->bv_val
,
272 ldap_value_free_len(values
);
274 return (blob
->data
!= NULL
);
277 bool smbldap_pull_sid(LDAP
*ld
, LDAPMessage
*msg
, const char *attrib
,
283 if (!smbldap_talloc_single_blob(talloc_tos(), ld
, msg
, attrib
,
287 ret
= sid_parse(blob
.data
, blob
.length
, sid
);
288 TALLOC_FREE(blob
.data
);
292 static int ldapmsg_destructor(LDAPMessage
**result
) {
293 ldap_msgfree(*result
);
297 void smbldap_talloc_autofree_ldapmsg(TALLOC_CTX
*mem_ctx
, LDAPMessage
*result
)
299 LDAPMessage
**handle
;
301 if (result
== NULL
) {
305 handle
= talloc(mem_ctx
, LDAPMessage
*);
306 SMB_ASSERT(handle
!= NULL
);
309 talloc_set_destructor(handle
, ldapmsg_destructor
);
312 static int ldapmod_destructor(LDAPMod
***mod
) {
313 ldap_mods_free(*mod
, True
);
317 void smbldap_talloc_autofree_ldapmod(TALLOC_CTX
*mem_ctx
, LDAPMod
**mod
)
325 handle
= talloc(mem_ctx
, LDAPMod
**);
326 SMB_ASSERT(handle
!= NULL
);
329 talloc_set_destructor(handle
, ldapmod_destructor
);
332 /************************************************************************
333 Routine to manage the LDAPMod structure array
334 manage memory used by the array, by each struct, and values
335 ***********************************************************************/
337 static void smbldap_set_mod_internal(LDAPMod
*** modlist
, int modop
, const char *attribute
, const char *value
, const DATA_BLOB
*blob
)
345 /* sanity checks on the mod values */
347 if (attribute
== NULL
|| *attribute
== '\0') {
351 #if 0 /* commented out after discussion with abartlet. Do not re-enable.
352 left here so other do not re-add similar code --jerry */
353 if (value
== NULL
|| *value
== '\0')
358 mods
= SMB_MALLOC_P(LDAPMod
*);
360 smb_panic("smbldap_set_mod: out of memory!");
366 for (i
= 0; mods
[i
] != NULL
; ++i
) {
367 if (mods
[i
]->mod_op
== modop
&& strequal(mods
[i
]->mod_type
, attribute
))
371 if (mods
[i
] == NULL
) {
372 mods
= SMB_REALLOC_ARRAY (mods
, LDAPMod
*, i
+ 2);
374 smb_panic("smbldap_set_mod: out of memory!");
377 mods
[i
] = SMB_MALLOC_P(LDAPMod
);
378 if (mods
[i
] == NULL
) {
379 smb_panic("smbldap_set_mod: out of memory!");
382 mods
[i
]->mod_op
= modop
;
383 mods
[i
]->mod_values
= NULL
;
384 mods
[i
]->mod_type
= SMB_STRDUP(attribute
);
388 if (blob
&& (modop
& LDAP_MOD_BVALUES
)) {
390 if (mods
[i
]->mod_bvalues
!= NULL
) {
391 for (; mods
[i
]->mod_bvalues
[j
] != NULL
; j
++);
393 mods
[i
]->mod_bvalues
= SMB_REALLOC_ARRAY(mods
[i
]->mod_bvalues
, struct berval
*, j
+ 2);
395 if (mods
[i
]->mod_bvalues
== NULL
) {
396 smb_panic("smbldap_set_mod: out of memory!");
400 mods
[i
]->mod_bvalues
[j
] = SMB_MALLOC_P(struct berval
);
401 SMB_ASSERT(mods
[i
]->mod_bvalues
[j
] != NULL
);
403 mods
[i
]->mod_bvalues
[j
]->bv_val
= (char *)smb_memdup(blob
->data
, blob
->length
);
404 SMB_ASSERT(mods
[i
]->mod_bvalues
[j
]->bv_val
!= NULL
);
405 mods
[i
]->mod_bvalues
[j
]->bv_len
= blob
->length
;
407 mods
[i
]->mod_bvalues
[j
+ 1] = NULL
;
408 } else if (value
!= NULL
) {
409 char *utf8_value
= NULL
;
410 size_t converted_size
;
413 if (mods
[i
]->mod_values
!= NULL
) {
414 for (; mods
[i
]->mod_values
[j
] != NULL
; j
++);
416 mods
[i
]->mod_values
= SMB_REALLOC_ARRAY(mods
[i
]->mod_values
, char *, j
+ 2);
418 if (mods
[i
]->mod_values
== NULL
) {
419 smb_panic("smbldap_set_mod: out of memory!");
423 if (!push_utf8_talloc(talloc_tos(), &utf8_value
, value
, &converted_size
)) {
424 smb_panic("smbldap_set_mod: String conversion failure!");
428 mods
[i
]->mod_values
[j
] = SMB_STRDUP(utf8_value
);
429 TALLOC_FREE(utf8_value
);
430 SMB_ASSERT(mods
[i
]->mod_values
[j
] != NULL
);
432 mods
[i
]->mod_values
[j
+ 1] = NULL
;
437 void smbldap_set_mod (LDAPMod
*** modlist
, int modop
, const char *attribute
, const char *value
)
439 smbldap_set_mod_internal(modlist
, modop
, attribute
, value
, NULL
);
442 void smbldap_set_mod_blob(LDAPMod
*** modlist
, int modop
, const char *attribute
, const DATA_BLOB
*value
)
444 smbldap_set_mod_internal(modlist
, modop
| LDAP_MOD_BVALUES
, attribute
, NULL
, value
);
447 /**********************************************************************
448 Set attribute to newval in LDAP, regardless of what value the
449 attribute had in LDAP before.
450 *********************************************************************/
452 static void smbldap_make_mod_internal(LDAP
*ldap_struct
, LDAPMessage
*existing
,
454 const char *attribute
, int op
,
456 const DATA_BLOB
*newblob
)
458 char oldval
[2048]; /* current largest allowed value is mungeddial */
460 DATA_BLOB oldblob
= data_blob_null
;
462 if (existing
!= NULL
) {
463 if (op
& LDAP_MOD_BVALUES
) {
464 existed
= smbldap_talloc_single_blob(talloc_tos(), ldap_struct
, existing
, attribute
, &oldblob
);
466 existed
= smbldap_get_single_attribute(ldap_struct
, existing
, attribute
, oldval
, sizeof(oldval
));
475 if (op
& LDAP_MOD_BVALUES
) {
476 equal
= (newblob
&& (data_blob_cmp(&oldblob
, newblob
) == 0));
478 /* all of our string attributes are case insensitive */
479 equal
= (newval
&& (strcasecmp_m(oldval
, newval
) == 0));
483 /* Believe it or not, but LDAP will deny a delete and
484 an add at the same time if the values are the
486 DEBUG(10,("smbldap_make_mod: attribute |%s| not changed.\n", attribute
));
490 /* There has been no value before, so don't delete it.
491 * Here's a possible race: We might end up with
492 * duplicate attributes */
493 /* By deleting exactly the value we found in the entry this
494 * should be race-free in the sense that the LDAP-Server will
495 * deny the complete operation if somebody changed the
496 * attribute behind our back. */
497 /* This will also allow modifying single valued attributes
498 * in Novell NDS. In NDS you have to first remove attribute and then
499 * you could add new value */
501 if (op
& LDAP_MOD_BVALUES
) {
502 DEBUG(10,("smbldap_make_mod: deleting attribute |%s| blob\n", attribute
));
503 smbldap_set_mod_blob(mods
, LDAP_MOD_DELETE
, attribute
, &oldblob
);
505 DEBUG(10,("smbldap_make_mod: deleting attribute |%s| values |%s|\n", attribute
, oldval
));
506 smbldap_set_mod(mods
, LDAP_MOD_DELETE
, attribute
, oldval
);
510 /* Regardless of the real operation (add or modify)
511 we add the new value here. We rely on deleting
512 the old value, should it exist. */
514 if (op
& LDAP_MOD_BVALUES
) {
515 if (newblob
&& newblob
->length
) {
516 DEBUG(10,("smbldap_make_mod: adding attribute |%s| blob\n", attribute
));
517 smbldap_set_mod_blob(mods
, LDAP_MOD_ADD
, attribute
, newblob
);
520 if ((newval
!= NULL
) && (strlen(newval
) > 0)) {
521 DEBUG(10,("smbldap_make_mod: adding attribute |%s| value |%s|\n", attribute
, newval
));
522 smbldap_set_mod(mods
, LDAP_MOD_ADD
, attribute
, newval
);
527 void smbldap_make_mod(LDAP
*ldap_struct
, LDAPMessage
*existing
,
529 const char *attribute
, const char *newval
)
531 smbldap_make_mod_internal(ldap_struct
, existing
, mods
, attribute
,
535 void smbldap_make_mod_blob(LDAP
*ldap_struct
, LDAPMessage
*existing
,
537 const char *attribute
, const DATA_BLOB
*newblob
)
539 smbldap_make_mod_internal(ldap_struct
, existing
, mods
, attribute
,
540 LDAP_MOD_BVALUES
, NULL
, newblob
);
543 /**********************************************************************
544 Some varients of the LDAP rebind code do not pass in the third 'arg'
545 pointer to a void*, so we try and work around it by assuming that the
546 value of the 'LDAP *' pointer is the same as the one we had passed in
547 **********************************************************************/
549 struct smbldap_state_lookup
{
551 struct smbldap_state
*smbldap_state
;
552 struct smbldap_state_lookup
*prev
, *next
;
555 static struct smbldap_state_lookup
*smbldap_state_lookup_list
;
557 static struct smbldap_state
*smbldap_find_state(LDAP
*ld
)
559 struct smbldap_state_lookup
*t
;
561 for (t
= smbldap_state_lookup_list
; t
; t
= t
->next
) {
563 return t
->smbldap_state
;
569 static void smbldap_delete_state(struct smbldap_state
*smbldap_state
)
571 struct smbldap_state_lookup
*t
;
573 for (t
= smbldap_state_lookup_list
; t
; t
= t
->next
) {
574 if (t
->smbldap_state
== smbldap_state
) {
575 DLIST_REMOVE(smbldap_state_lookup_list
, t
);
582 static void smbldap_store_state(LDAP
*ld
, struct smbldap_state
*smbldap_state
)
584 struct smbldap_state
*tmp_ldap_state
;
585 struct smbldap_state_lookup
*t
;
587 if ((tmp_ldap_state
= smbldap_find_state(ld
))) {
588 SMB_ASSERT(tmp_ldap_state
== smbldap_state
);
592 t
= SMB_XMALLOC_P(struct smbldap_state_lookup
);
595 DLIST_ADD_END(smbldap_state_lookup_list
, t
);
597 t
->smbldap_state
= smbldap_state
;
600 /********************************************************************
601 start TLS on an existing LDAP connection per config
602 *******************************************************************/
604 int smbldap_start_tls(LDAP
*ldap_struct
, int version
)
606 if (lp_ldap_ssl() != LDAP_SSL_START_TLS
) {
610 return smbldap_start_tls_start(ldap_struct
, version
);
613 /********************************************************************
614 start TLS on an existing LDAP connection unconditionally
615 *******************************************************************/
617 int smbldap_start_tls_start(LDAP
*ldap_struct
, int version
)
619 #ifdef LDAP_OPT_X_TLS
622 /* check if we use ldaps already */
623 ldap_get_option(ldap_struct
, LDAP_OPT_X_TLS
, &tls
);
624 if (tls
== LDAP_OPT_X_TLS_HARD
) {
628 if (version
!= LDAP_VERSION3
) {
629 DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
630 return LDAP_OPERATIONS_ERROR
;
633 if ((rc
= ldap_start_tls_s (ldap_struct
, NULL
, NULL
)) != LDAP_SUCCESS
) {
634 DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
635 ldap_err2string(rc
)));
639 DEBUG (3, ("StartTLS issued: using a TLS connection\n"));
642 DEBUG(0,("StartTLS not supported by LDAP client libraries!\n"));
643 return LDAP_OPERATIONS_ERROR
;
647 /********************************************************************
648 setup a connection to the LDAP server based on a uri
649 *******************************************************************/
651 static int smb_ldap_setup_conn(LDAP
**ldap_struct
, const char *uri
)
655 DEBUG(10, ("smb_ldap_setup_connection: %s\n", uri
));
657 #ifdef HAVE_LDAP_INITIALIZE
659 rc
= ldap_initialize(ldap_struct
, uri
);
661 DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc
)));
665 if (lp_ldap_follow_referral() != Auto
) {
666 rc
= ldap_set_option(*ldap_struct
, LDAP_OPT_REFERRALS
,
667 lp_ldap_follow_referral() ? LDAP_OPT_ON
: LDAP_OPT_OFF
);
668 if (rc
!= LDAP_SUCCESS
)
669 DEBUG(0, ("Failed to set LDAP_OPT_REFERRALS: %s\n",
670 ldap_err2string(rc
)));
676 /* Parse the string manually */
682 SMB_ASSERT(sizeof(protocol
)>10 && sizeof(host
)>254);
685 /* skip leading "URL:" (if any) */
686 if ( strnequal( uri
, "URL:", 4 ) ) {
690 sscanf(uri
, "%10[^:]://%254[^:/]:%d", protocol
, host
, &port
);
693 if (strequal(protocol
, "ldap")) {
695 } else if (strequal(protocol
, "ldaps")) {
698 DEBUG(0, ("unrecognised protocol (%s)!\n", protocol
));
702 if ((*ldap_struct
= ldap_init(host
, port
)) == NULL
) {
703 DEBUG(0, ("ldap_init failed !\n"));
704 return LDAP_OPERATIONS_ERROR
;
707 if (strequal(protocol
, "ldaps")) {
708 #ifdef LDAP_OPT_X_TLS
709 int tls
= LDAP_OPT_X_TLS_HARD
;
710 if (ldap_set_option (*ldap_struct
, LDAP_OPT_X_TLS
, &tls
) != LDAP_SUCCESS
)
712 DEBUG(0, ("Failed to setup a TLS session\n"));
715 DEBUG(3,("LDAPS option set...!\n"));
717 DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));
718 return LDAP_OPERATIONS_ERROR
;
719 #endif /* LDAP_OPT_X_TLS */
722 #endif /* HAVE_LDAP_INITIALIZE */
724 /* now set connection timeout */
725 #ifdef LDAP_X_OPT_CONNECT_TIMEOUT /* Netscape */
727 int ct
= lp_ldap_connection_timeout()*1000;
728 rc
= ldap_set_option(*ldap_struct
, LDAP_X_OPT_CONNECT_TIMEOUT
, &ct
);
729 if (rc
!= LDAP_SUCCESS
) {
730 DEBUG(0,("Failed to setup an ldap connection timeout %d: %s\n",
731 ct
, ldap_err2string(rc
)));
734 #elif defined (LDAP_OPT_NETWORK_TIMEOUT) /* OpenLDAP */
738 ct
.tv_sec
= lp_ldap_connection_timeout();
739 rc
= ldap_set_option(*ldap_struct
, LDAP_OPT_NETWORK_TIMEOUT
, &ct
);
740 if (rc
!= LDAP_SUCCESS
) {
741 DEBUG(0,("Failed to setup an ldap connection timeout %d: %s\n",
742 (int)ct
.tv_sec
, ldap_err2string(rc
)));
750 /********************************************************************
751 try to upgrade to Version 3 LDAP if not already, in either case return current
753 *******************************************************************/
755 static int smb_ldap_upgrade_conn(LDAP
*ldap_struct
, int *new_version
)
760 /* assume the worst */
761 *new_version
= LDAP_VERSION2
;
763 rc
= ldap_get_option(ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
768 if (version
== LDAP_VERSION3
) {
769 *new_version
= LDAP_VERSION3
;
774 version
= LDAP_VERSION3
;
775 rc
= ldap_set_option (ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
780 *new_version
= LDAP_VERSION3
;
784 /*******************************************************************
785 open a connection to the ldap server (just until the bind)
786 ******************************************************************/
788 int smbldap_setup_full_conn(LDAP
**ldap_struct
, const char *uri
)
792 rc
= smb_ldap_setup_conn(ldap_struct
, uri
);
797 rc
= smb_ldap_upgrade_conn(*ldap_struct
, &version
);
802 rc
= smbldap_start_tls(*ldap_struct
, version
);
810 /*******************************************************************
811 open a connection to the ldap server.
812 ******************************************************************/
813 static int smbldap_open_connection (struct smbldap_state
*ldap_state
)
816 int rc
= LDAP_SUCCESS
;
819 LDAP
**ldap_struct
= &ldap_state
->ldap_struct
;
821 rc
= smb_ldap_setup_conn(ldap_struct
, ldap_state
->uri
);
826 /* Store the LDAP pointer in a lookup list */
828 smbldap_store_state(*ldap_struct
, ldap_state
);
830 /* Upgrade to LDAPv3 if possible */
832 rc
= smb_ldap_upgrade_conn(*ldap_struct
, &version
);
837 /* Start TLS if required */
839 rc
= smbldap_start_tls(*ldap_struct
, version
);
844 /* Set alias dereferencing method */
845 deref
= lp_ldap_deref();
847 if (ldap_set_option (*ldap_struct
, LDAP_OPT_DEREF
, &deref
) != LDAP_OPT_SUCCESS
) {
848 DEBUG(1,("smbldap_open_connection: Failed to set dereferencing method: %d\n", deref
));
850 DEBUG(5,("Set dereferencing method: %d\n", deref
));
854 DEBUG(2, ("smbldap_open_connection: connection opened\n"));
858 /*******************************************************************
859 a rebind function for authenticated referrals
860 This version takes a void* that we can shove useful stuff in :-)
861 ******************************************************************/
862 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
864 static int rebindproc_with_state (LDAP
* ld
, char **whop
, char **credp
,
865 int *methodp
, int freeit
, void *arg
)
867 struct smbldap_state
*ldap_state
= arg
;
870 /** @TODO Should we be doing something to check what servers we rebind to?
871 Could we get a referral to a machine that we don't want to give our
872 username and password to? */
877 memset(*credp
, '\0', strlen(*credp
));
881 DEBUG(5,("rebind_proc_with_state: Rebinding as \"%s\"\n",
882 ldap_state
->bind_dn
?ldap_state
->bind_dn
:"[Anonymous bind]"));
884 if (ldap_state
->anonymous
) {
888 *whop
= SMB_STRDUP(ldap_state
->bind_dn
);
890 return LDAP_NO_MEMORY
;
892 *credp
= SMB_STRDUP(ldap_state
->bind_secret
);
895 return LDAP_NO_MEMORY
;
898 *methodp
= LDAP_AUTH_SIMPLE
;
901 clock_gettime_mono(&ts
);
902 ldap_state
->last_rebind
= convert_timespec_to_timeval(ts
);
906 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
908 /*******************************************************************
909 a rebind function for authenticated referrals
910 This version takes a void* that we can shove useful stuff in :-)
911 and actually does the connection.
912 ******************************************************************/
913 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
914 static int rebindproc_connect_with_state (LDAP
*ldap_struct
,
915 LDAP_CONST
char *url
,
917 ber_int_t msgid
, void *arg
)
919 struct smbldap_state
*ldap_state
=
920 (struct smbldap_state
*)arg
;
925 DEBUG(5,("rebindproc_connect_with_state: Rebinding to %s as \"%s\"\n",
926 url
, ldap_state
->bind_dn
?ldap_state
->bind_dn
:"[Anonymous bind]"));
928 /* call START_TLS again (ldaps:// is handled by the OpenLDAP library
929 * itself) before rebinding to another LDAP server to avoid to expose
930 * our credentials. At least *try* to secure the connection - Guenther */
932 smb_ldap_upgrade_conn(ldap_struct
, &version
);
933 smbldap_start_tls(ldap_struct
, version
);
935 /** @TODO Should we be doing something to check what servers we rebind to?
936 Could we get a referral to a machine that we don't want to give our
937 username and password to? */
939 rc
= ldap_simple_bind_s(ldap_struct
, ldap_state
->bind_dn
, ldap_state
->bind_secret
);
941 /* only set the last rebind timestamp when we did rebind after a
942 * non-read LDAP operation. That way we avoid the replication sleep
943 * after a simple redirected search operation - Guenther */
947 case LDAP_REQ_MODIFY
:
949 case LDAP_REQ_DELETE
:
951 case LDAP_REQ_EXTENDED
:
952 DEBUG(10,("rebindproc_connect_with_state: "
953 "setting last_rebind timestamp "
954 "(req: 0x%02x)\n", (unsigned int)request
));
955 clock_gettime_mono(&ts
);
956 ldap_state
->last_rebind
= convert_timespec_to_timeval(ts
);
959 ZERO_STRUCT(ldap_state
->last_rebind
);
965 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
967 /*******************************************************************
968 Add a rebind function for authenticated referrals
969 ******************************************************************/
970 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
972 # if LDAP_SET_REBIND_PROC_ARGS == 2
973 static int rebindproc (LDAP
*ldap_struct
, char **whop
, char **credp
,
974 int *method
, int freeit
)
976 struct smbldap_state
*ldap_state
= smbldap_find_state(ldap_struct
);
978 return rebindproc_with_state(ldap_struct
, whop
, credp
,
979 method
, freeit
, ldap_state
);
981 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
982 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
984 /*******************************************************************
985 a rebind function for authenticated referrals
986 this also does the connection, but no void*.
987 ******************************************************************/
988 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
989 # if LDAP_SET_REBIND_PROC_ARGS == 2
990 static int rebindproc_connect (LDAP
* ld
, LDAP_CONST
char *url
, int request
,
993 struct smbldap_state
*ldap_state
= smbldap_find_state(ld
);
995 return rebindproc_connect_with_state(ld
, url
, (ber_tag_t
)request
, msgid
,
998 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
999 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
1001 /*******************************************************************
1002 connect to the ldap server under system privilege.
1003 ******************************************************************/
1004 static int smbldap_connect_system(struct smbldap_state
*ldap_state
)
1006 LDAP
*ldap_struct
= smbldap_get_ldap(ldap_state
);
1010 /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
1011 (OpenLDAP) doesn't seem to support it */
1013 DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n",
1014 ldap_state
->uri
, ldap_state
->bind_dn
));
1016 #ifdef HAVE_LDAP_SET_REBIND_PROC
1017 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
1018 # if LDAP_SET_REBIND_PROC_ARGS == 2
1019 ldap_set_rebind_proc(ldap_struct
, &rebindproc_connect
);
1021 # if LDAP_SET_REBIND_PROC_ARGS == 3
1022 ldap_set_rebind_proc(ldap_struct
, &rebindproc_connect_with_state
, (void *)ldap_state
);
1024 #else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
1025 # if LDAP_SET_REBIND_PROC_ARGS == 2
1026 ldap_set_rebind_proc(ldap_struct
, &rebindproc
);
1028 # if LDAP_SET_REBIND_PROC_ARGS == 3
1029 ldap_set_rebind_proc(ldap_struct
, &rebindproc_with_state
, (void *)ldap_state
);
1031 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
1034 /* When there is an alternative bind callback is set,
1035 attempt to use it to perform the bind */
1036 if (ldap_state
->bind_callback
!= NULL
) {
1037 /* We have to allow bind callback to be run under become_root/unbecome_root
1038 to make sure within smbd the callback has proper write access to its resources,
1039 like credential cache. This is similar to passdb case where this callback is supposed
1040 to be used. When used outside smbd, become_root()/unbecome_root() are no-op.
1043 rc
= ldap_state
->bind_callback(ldap_struct
, ldap_state
, ldap_state
->bind_callback_data
);
1046 rc
= ldap_simple_bind_s(ldap_struct
, ldap_state
->bind_dn
, ldap_state
->bind_secret
);
1049 if (rc
!= LDAP_SUCCESS
) {
1050 char *ld_error
= NULL
;
1051 ldap_get_option(smbldap_get_ldap(ldap_state
),
1052 LDAP_OPT_ERROR_STRING
,
1054 DEBUG(ldap_state
->num_failures
? 2 : 0,
1055 ("failed to bind to server %s with dn=\"%s\" Error: %s\n\t%s\n",
1057 ldap_state
->bind_dn
? ldap_state
->bind_dn
: "[Anonymous bind]",
1058 ldap_err2string(rc
),
1059 ld_error
? ld_error
: "(unknown)"));
1060 SAFE_FREE(ld_error
);
1061 ldap_state
->num_failures
++;
1065 ldap_state
->num_failures
= 0;
1066 ldap_state
->paged_results
= False
;
1068 ldap_get_option(smbldap_get_ldap(ldap_state
),
1069 LDAP_OPT_PROTOCOL_VERSION
, &version
);
1071 if (smbldap_has_control(smbldap_get_ldap(ldap_state
), ADS_PAGE_CTL_OID
)
1073 ldap_state
->paged_results
= True
;
1076 DEBUG(3, ("ldap_connect_system: successful connection to the LDAP server\n"));
1077 DEBUGADD(10, ("ldap_connect_system: LDAP server %s support paged results\n",
1078 ldap_state
->paged_results
? "does" : "does not"));
1081 ldap_unbind(ldap_struct
);
1082 ldap_state
->ldap_struct
= NULL
;
1087 static void smbldap_idle_fn(struct tevent_context
*tevent_ctx
,
1088 struct tevent_timer
*te
,
1089 struct timeval now_abs
,
1090 void *private_data
);
1092 /**********************************************************************
1093 Connect to LDAP server (called before every ldap operation)
1094 *********************************************************************/
1095 static int smbldap_open(struct smbldap_state
*ldap_state
)
1098 bool reopen
= False
;
1099 SMB_ASSERT(ldap_state
);
1101 if ((smbldap_get_ldap(ldap_state
) != NULL
) &&
1102 ((ldap_state
->last_ping
+ SMBLDAP_DONT_PING_TIME
) <
1105 #ifdef HAVE_UNIXSOCKET
1106 struct sockaddr_un addr
;
1108 struct sockaddr_storage addr
;
1110 socklen_t len
= sizeof(addr
);
1113 opt_rc
= ldap_get_option(smbldap_get_ldap(ldap_state
),
1114 LDAP_OPT_DESC
, &sd
);
1115 if (opt_rc
== 0 && (getpeername(sd
, (struct sockaddr
*) &addr
, &len
)) < 0 )
1118 #ifdef HAVE_UNIXSOCKET
1119 if (opt_rc
== 0 && addr
.sun_family
== AF_UNIX
)
1123 /* the other end has died. reopen. */
1124 ldap_unbind(smbldap_get_ldap(ldap_state
));
1125 ldap_state
->ldap_struct
= NULL
;
1126 ldap_state
->last_ping
= (time_t)0;
1128 ldap_state
->last_ping
= time_mono(NULL
);
1132 if (smbldap_get_ldap(ldap_state
) != NULL
) {
1133 DEBUG(11,("smbldap_open: already connected to the LDAP server\n"));
1134 return LDAP_SUCCESS
;
1137 if ((rc
= smbldap_open_connection(ldap_state
))) {
1141 if ((rc
= smbldap_connect_system(ldap_state
))) {
1146 ldap_state
->last_ping
= time_mono(NULL
);
1147 ldap_state
->pid
= getpid();
1149 TALLOC_FREE(ldap_state
->idle_event
);
1151 if (ldap_state
->tevent_context
!= NULL
) {
1152 ldap_state
->idle_event
= tevent_add_timer(
1153 ldap_state
->tevent_context
, ldap_state
,
1154 timeval_current_ofs(SMBLDAP_IDLE_TIME
, 0),
1155 smbldap_idle_fn
, ldap_state
);
1158 DEBUG(4,("The LDAP server is successfully connected\n"));
1160 return LDAP_SUCCESS
;
1163 /**********************************************************************
1164 Disconnect from LDAP server
1165 *********************************************************************/
1166 static NTSTATUS
smbldap_close(struct smbldap_state
*ldap_state
)
1169 return NT_STATUS_INVALID_PARAMETER
;
1171 if (smbldap_get_ldap(ldap_state
) != NULL
) {
1172 ldap_unbind(smbldap_get_ldap(ldap_state
));
1173 ldap_state
->ldap_struct
= NULL
;
1176 smbldap_delete_state(ldap_state
);
1178 TALLOC_FREE(ldap_state
->idle_event
);
1180 DEBUG(5,("The connection to the LDAP server was closed\n"));
1181 /* maybe free the results here --metze */
1183 return NT_STATUS_OK
;
1186 static SIG_ATOMIC_T got_alarm
;
1188 static void gotalarm_sig(int dummy
)
1193 static time_t calc_ldap_abs_endtime(int ldap_to
)
1196 /* No timeout - don't
1202 /* Make the alarm time one second beyond
1203 the timout we're setting for the
1204 remote search timeout, to allow that
1205 to fire in preference. */
1207 return time_mono(NULL
)+ldap_to
+1;
1210 static int end_ldap_local_alarm(time_t absolute_endtime
, int rc
)
1212 if (absolute_endtime
) {
1214 CatchSignal(SIGALRM
, SIG_IGN
);
1216 /* Client timeout error code. */
1218 return LDAP_TIMEOUT
;
1224 static void setup_ldap_local_alarm(struct smbldap_state
*ldap_state
, time_t absolute_endtime
)
1226 time_t now
= time_mono(NULL
);
1228 if (absolute_endtime
) {
1230 CatchSignal(SIGALRM
, gotalarm_sig
);
1231 alarm(absolute_endtime
- now
);
1234 if (ldap_state
->pid
!= getpid()) {
1235 smbldap_close(ldap_state
);
1239 static void get_ldap_errs(struct smbldap_state
*ldap_state
, char **pp_ld_error
, int *p_ld_errno
)
1241 ldap_get_option(smbldap_get_ldap(ldap_state
),
1242 LDAP_OPT_ERROR_NUMBER
, p_ld_errno
);
1244 ldap_get_option(smbldap_get_ldap(ldap_state
),
1245 LDAP_OPT_ERROR_STRING
, pp_ld_error
);
1248 static int get_cached_ldap_connect(struct smbldap_state
*ldap_state
, time_t abs_endtime
)
1256 now
= time_mono(NULL
);
1257 ldap_state
->last_use
= now
;
1259 if (abs_endtime
&& now
> abs_endtime
) {
1260 smbldap_close(ldap_state
);
1261 return LDAP_TIMEOUT
;
1264 rc
= smbldap_open(ldap_state
);
1266 if (rc
== LDAP_SUCCESS
) {
1267 return LDAP_SUCCESS
;
1271 DEBUG(1, ("Connection to LDAP server failed for the "
1272 "%d try!\n", attempts
));
1274 if (rc
== LDAP_INSUFFICIENT_ACCESS
) {
1275 /* The fact that we are non-root or any other
1276 * access-denied condition will not change in the next
1277 * round of trying */
1282 smbldap_close(ldap_state
);
1283 return LDAP_TIMEOUT
;
1289 smbldap_close(ldap_state
);
1290 return LDAP_TIMEOUT
;
1295 /*********************************************************************
1296 ********************************************************************/
1298 static int smbldap_search_ext(struct smbldap_state
*ldap_state
,
1299 const char *base
, int scope
, const char *filter
,
1300 const char *attrs
[], int attrsonly
,
1301 LDAPControl
**sctrls
, LDAPControl
**cctrls
,
1302 int sizelimit
, LDAPMessage
**res
)
1304 int rc
= LDAP_SERVER_DOWN
;
1306 int to
= lp_ldap_timeout();
1307 time_t abs_endtime
= calc_ldap_abs_endtime(to
);
1308 struct timeval timeout
;
1309 struct timeval
*timeout_ptr
= NULL
;
1310 size_t converted_size
;
1312 SMB_ASSERT(ldap_state
);
1314 DEBUG(5,("smbldap_search_ext: base => [%s], filter => [%s], "
1315 "scope => [%d]\n", base
, filter
, scope
));
1317 if (ldap_state
->last_rebind
.tv_sec
> 0) {
1318 struct timeval tval
;
1323 clock_gettime_mono(&ts
);
1324 tval
= convert_timespec_to_timeval(ts
);
1326 tdiff
= usec_time_diff(&tval
, &ldap_state
->last_rebind
);
1327 tdiff
/= 1000; /* Convert to milliseconds. */
1329 sleep_time
= lp_ldap_replication_sleep()-(int)tdiff
;
1330 sleep_time
= MIN(sleep_time
, MAX_LDAP_REPLICATION_SLEEP_TIME
);
1332 if (sleep_time
> 0) {
1333 /* we wait for the LDAP replication */
1334 DEBUG(5,("smbldap_search_ext: waiting %d milliseconds "
1335 "for LDAP replication.\n",sleep_time
));
1336 smb_msleep(sleep_time
);
1337 DEBUG(5,("smbldap_search_ext: go on!\n"));
1339 ZERO_STRUCT(ldap_state
->last_rebind
);
1342 if (!push_utf8_talloc(talloc_tos(), &utf8_filter
, filter
, &converted_size
)) {
1343 return LDAP_NO_MEMORY
;
1346 /* Setup remote timeout for the ldap_search_ext_s call. */
1348 timeout
.tv_sec
= to
;
1349 timeout
.tv_usec
= 0;
1350 timeout_ptr
= &timeout
;
1353 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1356 char *ld_error
= NULL
;
1359 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1360 if (rc
!= LDAP_SUCCESS
) {
1364 rc
= ldap_search_ext_s(smbldap_get_ldap(ldap_state
),
1367 discard_const_p(char *, attrs
),
1368 attrsonly
, sctrls
, cctrls
, timeout_ptr
,
1370 if (rc
== LDAP_SUCCESS
) {
1374 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1376 DEBUG(10, ("Failed search for base: %s, error: %d (%s) "
1377 "(%s)\n", base
, ld_errno
,
1378 ldap_err2string(rc
),
1379 ld_error
? ld_error
: "unknown"));
1380 SAFE_FREE(ld_error
);
1382 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1385 ldap_unbind(smbldap_get_ldap(ldap_state
));
1386 ldap_state
->ldap_struct
= NULL
;
1389 TALLOC_FREE(utf8_filter
);
1390 return end_ldap_local_alarm(abs_endtime
, rc
);
1393 int smbldap_search(struct smbldap_state
*ldap_state
,
1394 const char *base
, int scope
, const char *filter
,
1395 const char *attrs
[], int attrsonly
,
1398 return smbldap_search_ext(ldap_state
, base
, scope
, filter
, attrs
,
1399 attrsonly
, NULL
, NULL
, LDAP_NO_LIMIT
, res
);
1402 int smbldap_search_paged(struct smbldap_state
*ldap_state
,
1403 const char *base
, int scope
, const char *filter
,
1404 const char **attrs
, int attrsonly
, int pagesize
,
1405 LDAPMessage
**res
, void **cookie
)
1408 LDAPControl
**rcontrols
;
1409 LDAPControl
*controls
[2] = { NULL
, NULL
};
1410 BerElement
*cookie_be
= NULL
;
1411 struct berval
*cookie_bv
= NULL
;
1413 bool critical
= True
;
1417 DEBUG(3,("smbldap_search_paged: base => [%s], filter => [%s],"
1418 "scope => [%d], pagesize => [%d]\n",
1419 base
, filter
, scope
, pagesize
));
1421 cookie_be
= ber_alloc_t(LBER_USE_DER
);
1422 if (cookie_be
== NULL
) {
1423 DEBUG(0,("smbldap_create_page_control: ber_alloc_t returns "
1425 return LDAP_NO_MEMORY
;
1428 /* construct cookie */
1429 if (*cookie
!= NULL
) {
1430 ber_printf(cookie_be
, "{iO}", (ber_int_t
) pagesize
, *cookie
);
1431 ber_bvfree((struct berval
*)*cookie
); /* don't need it from last time */
1434 ber_printf(cookie_be
, "{io}", (ber_int_t
) pagesize
, "", 0);
1436 ber_flatten(cookie_be
, &cookie_bv
);
1438 pr
.ldctl_oid
= discard_const_p(char, ADS_PAGE_CTL_OID
);
1439 pr
.ldctl_iscritical
= (char) critical
;
1440 pr
.ldctl_value
.bv_len
= cookie_bv
->bv_len
;
1441 pr
.ldctl_value
.bv_val
= cookie_bv
->bv_val
;
1446 rc
= smbldap_search_ext(ldap_state
, base
, scope
, filter
, attrs
,
1447 0, controls
, NULL
, LDAP_NO_LIMIT
, res
);
1449 ber_free(cookie_be
, 1);
1450 ber_bvfree(cookie_bv
);
1453 DEBUG(3,("smbldap_search_paged: smbldap_search_ext(%s) "
1454 "failed with [%s]\n", filter
, ldap_err2string(rc
)));
1458 DEBUG(3,("smbldap_search_paged: search was successful\n"));
1460 rc
= ldap_parse_result(smbldap_get_ldap(ldap_state
), *res
, NULL
, NULL
,
1461 NULL
, NULL
, &rcontrols
, 0);
1463 DEBUG(3,("smbldap_search_paged: ldap_parse_result failed " \
1464 "with [%s]\n", ldap_err2string(rc
)));
1468 if (rcontrols
== NULL
)
1471 for (i
=0; rcontrols
[i
]; i
++) {
1473 if (strcmp(ADS_PAGE_CTL_OID
, rcontrols
[i
]->ldctl_oid
) != 0)
1476 cookie_be
= ber_init(&rcontrols
[i
]->ldctl_value
);
1477 ber_scanf(cookie_be
,"{iO}", &tmp
, &cookie_bv
);
1478 /* the berval is the cookie, but must be freed when it is all
1480 if (cookie_bv
->bv_len
)
1481 *cookie
=ber_bvdup(cookie_bv
);
1484 ber_bvfree(cookie_bv
);
1485 ber_free(cookie_be
, 1);
1488 ldap_controls_free(rcontrols
);
1493 int smbldap_modify(struct smbldap_state
*ldap_state
, const char *dn
, LDAPMod
*attrs
[])
1495 int rc
= LDAP_SERVER_DOWN
;
1497 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1498 size_t converted_size
;
1500 SMB_ASSERT(ldap_state
);
1502 DEBUG(5,("smbldap_modify: dn => [%s]\n", dn
));
1504 if (!push_utf8_talloc(talloc_tos(), &utf8_dn
, dn
, &converted_size
)) {
1505 return LDAP_NO_MEMORY
;
1508 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1511 char *ld_error
= NULL
;
1514 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1515 if (rc
!= LDAP_SUCCESS
) {
1519 rc
= ldap_modify_s(smbldap_get_ldap(ldap_state
), utf8_dn
,
1521 if (rc
== LDAP_SUCCESS
) {
1525 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1527 DEBUG(10, ("Failed to modify dn: %s, error: %d (%s) "
1528 "(%s)\n", dn
, ld_errno
,
1529 ldap_err2string(rc
),
1530 ld_error
? ld_error
: "unknown"));
1531 SAFE_FREE(ld_error
);
1533 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1536 ldap_unbind(smbldap_get_ldap(ldap_state
));
1537 ldap_state
->ldap_struct
= NULL
;
1540 TALLOC_FREE(utf8_dn
);
1541 return end_ldap_local_alarm(abs_endtime
, rc
);
1544 int smbldap_add(struct smbldap_state
*ldap_state
, const char *dn
, LDAPMod
*attrs
[])
1546 int rc
= LDAP_SERVER_DOWN
;
1548 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1549 size_t converted_size
;
1551 SMB_ASSERT(ldap_state
);
1553 DEBUG(5,("smbldap_add: dn => [%s]\n", dn
));
1555 if (!push_utf8_talloc(talloc_tos(), &utf8_dn
, dn
, &converted_size
)) {
1556 return LDAP_NO_MEMORY
;
1559 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1562 char *ld_error
= NULL
;
1565 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1566 if (rc
!= LDAP_SUCCESS
) {
1570 rc
= ldap_add_s(smbldap_get_ldap(ldap_state
), utf8_dn
, attrs
);
1571 if (rc
== LDAP_SUCCESS
) {
1575 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1577 DEBUG(10, ("Failed to add dn: %s, error: %d (%s) "
1578 "(%s)\n", dn
, ld_errno
,
1579 ldap_err2string(rc
),
1580 ld_error
? ld_error
: "unknown"));
1581 SAFE_FREE(ld_error
);
1583 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1586 ldap_unbind(smbldap_get_ldap(ldap_state
));
1587 ldap_state
->ldap_struct
= NULL
;
1590 TALLOC_FREE(utf8_dn
);
1591 return end_ldap_local_alarm(abs_endtime
, rc
);
1594 int smbldap_delete(struct smbldap_state
*ldap_state
, const char *dn
)
1596 int rc
= LDAP_SERVER_DOWN
;
1598 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1599 size_t converted_size
;
1601 SMB_ASSERT(ldap_state
);
1603 DEBUG(5,("smbldap_delete: dn => [%s]\n", dn
));
1605 if (!push_utf8_talloc(talloc_tos(), &utf8_dn
, dn
, &converted_size
)) {
1606 return LDAP_NO_MEMORY
;
1609 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1612 char *ld_error
= NULL
;
1615 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1616 if (rc
!= LDAP_SUCCESS
) {
1620 rc
= ldap_delete_s(smbldap_get_ldap(ldap_state
), utf8_dn
);
1621 if (rc
== LDAP_SUCCESS
) {
1625 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1627 DEBUG(10, ("Failed to delete dn: %s, error: %d (%s) "
1628 "(%s)\n", dn
, ld_errno
,
1629 ldap_err2string(rc
),
1630 ld_error
? ld_error
: "unknown"));
1631 SAFE_FREE(ld_error
);
1633 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1636 ldap_unbind(smbldap_get_ldap(ldap_state
));
1637 ldap_state
->ldap_struct
= NULL
;
1640 TALLOC_FREE(utf8_dn
);
1641 return end_ldap_local_alarm(abs_endtime
, rc
);
1644 int smbldap_extended_operation(struct smbldap_state
*ldap_state
,
1645 LDAP_CONST
char *reqoid
, struct berval
*reqdata
,
1646 LDAPControl
**serverctrls
, LDAPControl
**clientctrls
,
1647 char **retoidp
, struct berval
**retdatap
)
1649 int rc
= LDAP_SERVER_DOWN
;
1650 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1655 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1658 char *ld_error
= NULL
;
1661 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1662 if (rc
!= LDAP_SUCCESS
) {
1666 rc
= ldap_extended_operation_s(smbldap_get_ldap(ldap_state
),
1668 reqdata
, serverctrls
,
1669 clientctrls
, retoidp
, retdatap
);
1670 if (rc
== LDAP_SUCCESS
) {
1674 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1676 DEBUG(10, ("Extended operation failed with error: "
1677 "%d (%s) (%s)\n", ld_errno
,
1678 ldap_err2string(rc
),
1679 ld_error
? ld_error
: "unknown"));
1680 SAFE_FREE(ld_error
);
1682 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1685 ldap_unbind(smbldap_get_ldap(ldap_state
));
1686 ldap_state
->ldap_struct
= NULL
;
1689 return end_ldap_local_alarm(abs_endtime
, rc
);
1692 /*******************************************************************
1693 run the search by name.
1694 ******************************************************************/
1695 int smbldap_search_suffix (struct smbldap_state
*ldap_state
,
1696 const char *filter
, const char **search_attr
,
1697 LDAPMessage
** result
)
1699 return smbldap_search(ldap_state
, lp_ldap_suffix(),
1701 filter
, search_attr
, 0, result
);
1704 static void smbldap_idle_fn(struct tevent_context
*tevent_ctx
,
1705 struct tevent_timer
*te
,
1706 struct timeval now_abs
,
1709 struct smbldap_state
*state
= (struct smbldap_state
*)private_data
;
1711 TALLOC_FREE(state
->idle_event
);
1713 if (smbldap_get_ldap(state
) == NULL
) {
1714 DEBUG(10,("ldap connection not connected...\n"));
1718 if ((state
->last_use
+SMBLDAP_IDLE_TIME
) > time_mono(NULL
)) {
1719 DEBUG(10,("ldap connection not idle...\n"));
1721 /* this needs to be made monotonic clock aware inside tevent: */
1722 state
->idle_event
= tevent_add_timer(
1724 timeval_add(&now_abs
, SMBLDAP_IDLE_TIME
, 0),
1730 DEBUG(7,("ldap connection idle...closing connection\n"));
1731 smbldap_close(state
);
1734 /**********************************************************************
1736 *********************************************************************/
1738 void smbldap_free_struct(struct smbldap_state
**ldap_state
)
1740 smbldap_close(*ldap_state
);
1742 if ((*ldap_state
)->bind_secret
) {
1743 memset((*ldap_state
)->bind_secret
, '\0', strlen((*ldap_state
)->bind_secret
));
1746 SAFE_FREE((*ldap_state
)->bind_dn
);
1747 SAFE_FREE((*ldap_state
)->bind_secret
);
1748 smbldap_set_bind_callback(*ldap_state
, NULL
, NULL
);
1750 TALLOC_FREE(*ldap_state
);
1752 /* No need to free any further, as it is talloc()ed */
1755 static int smbldap_state_destructor(struct smbldap_state
*state
)
1757 smbldap_free_struct(&state
);
1762 /**********************************************************************
1763 Intitalise the 'general' ldap structures, on which ldap operations may be conducted
1764 *********************************************************************/
1766 NTSTATUS
smbldap_init(TALLOC_CTX
*mem_ctx
, struct tevent_context
*tevent_ctx
,
1767 const char *location
,
1769 const char *bind_dn
,
1770 const char *bind_secret
,
1771 struct smbldap_state
**smbldap_state
)
1773 *smbldap_state
= talloc_zero(mem_ctx
, struct smbldap_state
);
1774 if (!*smbldap_state
) {
1775 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
1776 return NT_STATUS_NO_MEMORY
;
1780 (*smbldap_state
)->uri
= talloc_strdup(mem_ctx
, location
);
1782 (*smbldap_state
)->uri
= "ldap://localhost";
1785 (*smbldap_state
)->tevent_context
= tevent_ctx
;
1787 if (bind_dn
&& bind_secret
) {
1788 smbldap_set_creds(*smbldap_state
, anon
, bind_dn
, bind_secret
);
1791 talloc_set_destructor(*smbldap_state
, smbldap_state_destructor
);
1792 return NT_STATUS_OK
;
1795 char *smbldap_talloc_dn(TALLOC_CTX
*mem_ctx
, LDAP
*ld
,
1798 char *utf8_dn
, *unix_dn
;
1799 size_t converted_size
;
1801 utf8_dn
= ldap_get_dn(ld
, entry
);
1803 DEBUG (5, ("smbldap_talloc_dn: ldap_get_dn failed\n"));
1806 if (!pull_utf8_talloc(mem_ctx
, &unix_dn
, utf8_dn
, &converted_size
)) {
1807 DEBUG (0, ("smbldap_talloc_dn: String conversion failure utf8 "
1808 "[%s]\n", utf8_dn
));
1811 ldap_memfree(utf8_dn
);
1815 /*******************************************************************
1816 Check if root-dse has a certain Control or Extension
1817 ********************************************************************/
1819 static bool smbldap_check_root_dse(LDAP
*ld
, const char **attrs
, const char *value
)
1821 LDAPMessage
*msg
= NULL
;
1822 LDAPMessage
*entry
= NULL
;
1823 char **values
= NULL
;
1824 int rc
, num_result
, num_values
, i
;
1825 bool result
= False
;
1828 DEBUG(3,("smbldap_check_root_dse: nothing to look for\n"));
1832 if (!strequal(attrs
[0], "supportedExtension") &&
1833 !strequal(attrs
[0], "supportedControl") &&
1834 !strequal(attrs
[0], "namingContexts")) {
1835 DEBUG(3,("smbldap_check_root_dse: no idea what to query root-dse for: %s ?\n", attrs
[0]));
1839 rc
= ldap_search_s(ld
, "", LDAP_SCOPE_BASE
,
1840 "(objectclass=*)", discard_const_p(char *, attrs
), 0 , &msg
);
1842 if (rc
!= LDAP_SUCCESS
) {
1843 DEBUG(3,("smbldap_check_root_dse: Could not search rootDSE\n"));
1847 num_result
= ldap_count_entries(ld
, msg
);
1849 if (num_result
!= 1) {
1850 DEBUG(3,("smbldap_check_root_dse: Expected one rootDSE, got %d\n", num_result
));
1854 entry
= ldap_first_entry(ld
, msg
);
1856 if (entry
== NULL
) {
1857 DEBUG(3,("smbldap_check_root_dse: Could not retrieve rootDSE\n"));
1861 values
= ldap_get_values(ld
, entry
, attrs
[0]);
1863 if (values
== NULL
) {
1864 DEBUG(5,("smbldap_check_root_dse: LDAP Server does not support any %s\n", attrs
[0]));
1868 num_values
= ldap_count_values(values
);
1870 if (num_values
== 0) {
1871 DEBUG(5,("smbldap_check_root_dse: LDAP Server does not have any %s\n", attrs
[0]));
1875 for (i
=0; i
<num_values
; i
++) {
1876 if (strcmp(values
[i
], value
) == 0)
1883 ldap_value_free(values
);
1891 /*******************************************************************
1892 Check if LDAP-Server supports a certain Control (OID in string format)
1893 ********************************************************************/
1895 bool smbldap_has_control(LDAP
*ld
, const char *control
)
1897 const char *attrs
[] = { "supportedControl", NULL
};
1898 return smbldap_check_root_dse(ld
, attrs
, control
);
1901 /*******************************************************************
1902 Check if LDAP-Server supports a certain Extension (OID in string format)
1903 ********************************************************************/
1905 bool smbldap_has_extension(LDAP
*ld
, const char *extension
)
1907 const char *attrs
[] = { "supportedExtension", NULL
};
1908 return smbldap_check_root_dse(ld
, attrs
, extension
);
1911 /*******************************************************************
1912 Check if LDAP-Server holds a given namingContext
1913 ********************************************************************/
1915 bool smbldap_has_naming_context(LDAP
*ld
, const char *naming_context
)
1917 const char *attrs
[] = { "namingContexts", NULL
};
1918 return smbldap_check_root_dse(ld
, attrs
, naming_context
);
1921 bool smbldap_set_creds(struct smbldap_state
*ldap_state
, bool anon
, const char *dn
, const char *secret
)
1923 ldap_state
->anonymous
= anon
;
1925 /* free any previously set credential */
1927 SAFE_FREE(ldap_state
->bind_dn
);
1928 smbldap_set_bind_callback(ldap_state
, NULL
, NULL
);
1930 if (ldap_state
->bind_secret
) {
1931 /* make sure secrets are zeroed out of memory */
1932 memset(ldap_state
->bind_secret
, '\0', strlen(ldap_state
->bind_secret
));
1933 SAFE_FREE(ldap_state
->bind_secret
);
1937 ldap_state
->bind_dn
= SMB_STRDUP(dn
);
1938 ldap_state
->bind_secret
= SMB_STRDUP(secret
);