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 variants 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
)));
675 /* Parse the string manually */
681 SMB_ASSERT(sizeof(protocol
)>10 && sizeof(host
)>254);
684 /* skip leading "URL:" (if any) */
685 if ( strnequal( uri
, "URL:", 4 ) ) {
689 sscanf(uri
, "%10[^:]://%254[^:/]:%d", protocol
, host
, &port
);
692 if (strequal(protocol
, "ldap")) {
694 } else if (strequal(protocol
, "ldaps")) {
697 DEBUG(0, ("unrecognised protocol (%s)!\n", protocol
));
701 if ((*ldap_struct
= ldap_init(host
, port
)) == NULL
) {
702 DEBUG(0, ("ldap_init failed !\n"));
703 return LDAP_OPERATIONS_ERROR
;
706 if (strequal(protocol
, "ldaps")) {
707 #ifdef LDAP_OPT_X_TLS
708 int tls
= LDAP_OPT_X_TLS_HARD
;
709 if (ldap_set_option (*ldap_struct
, LDAP_OPT_X_TLS
, &tls
) != LDAP_SUCCESS
)
711 DEBUG(0, ("Failed to setup a TLS session\n"));
714 DEBUG(3,("LDAPS option set...!\n"));
716 DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));
717 return LDAP_OPERATIONS_ERROR
;
718 #endif /* LDAP_OPT_X_TLS */
722 /* now set connection timeout */
723 #ifdef LDAP_X_OPT_CONNECT_TIMEOUT /* Netscape */
725 int ct
= lp_ldap_connection_timeout()*1000;
726 rc
= ldap_set_option(*ldap_struct
, LDAP_X_OPT_CONNECT_TIMEOUT
, &ct
);
727 if (rc
!= LDAP_SUCCESS
) {
728 DEBUG(0,("Failed to setup an ldap connection timeout %d: %s\n",
729 ct
, ldap_err2string(rc
)));
732 #elif defined (LDAP_OPT_NETWORK_TIMEOUT) /* OpenLDAP */
736 ct
.tv_sec
= lp_ldap_connection_timeout();
737 rc
= ldap_set_option(*ldap_struct
, LDAP_OPT_NETWORK_TIMEOUT
, &ct
);
738 if (rc
!= LDAP_SUCCESS
) {
739 DEBUG(0,("Failed to setup an ldap connection timeout %d: %s\n",
740 (int)ct
.tv_sec
, ldap_err2string(rc
)));
745 #endif /* HAVE_LDAP_INITIALIZE */
749 /********************************************************************
750 try to upgrade to Version 3 LDAP if not already, in either case return current
752 *******************************************************************/
754 static int smb_ldap_upgrade_conn(LDAP
*ldap_struct
, int *new_version
)
759 /* assume the worst */
760 *new_version
= LDAP_VERSION2
;
762 rc
= ldap_get_option(ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
767 if (version
== LDAP_VERSION3
) {
768 *new_version
= LDAP_VERSION3
;
773 version
= LDAP_VERSION3
;
774 rc
= ldap_set_option (ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
779 *new_version
= LDAP_VERSION3
;
783 /*******************************************************************
784 open a connection to the ldap server (just until the bind)
785 ******************************************************************/
787 int smbldap_setup_full_conn(LDAP
**ldap_struct
, const char *uri
)
791 rc
= smb_ldap_setup_conn(ldap_struct
, uri
);
796 rc
= smb_ldap_upgrade_conn(*ldap_struct
, &version
);
801 rc
= smbldap_start_tls(*ldap_struct
, version
);
809 /*******************************************************************
810 open a connection to the ldap server.
811 ******************************************************************/
812 static int smbldap_open_connection (struct smbldap_state
*ldap_state
)
815 int rc
= LDAP_SUCCESS
;
818 LDAP
**ldap_struct
= &ldap_state
->ldap_struct
;
820 rc
= smb_ldap_setup_conn(ldap_struct
, ldap_state
->uri
);
825 /* Store the LDAP pointer in a lookup list */
827 smbldap_store_state(*ldap_struct
, ldap_state
);
829 /* Upgrade to LDAPv3 if possible */
831 rc
= smb_ldap_upgrade_conn(*ldap_struct
, &version
);
836 /* Start TLS if required */
838 rc
= smbldap_start_tls(*ldap_struct
, version
);
843 /* Set alias dereferencing method */
844 deref
= lp_ldap_deref();
846 if (ldap_set_option (*ldap_struct
, LDAP_OPT_DEREF
, &deref
) != LDAP_OPT_SUCCESS
) {
847 DEBUG(1,("smbldap_open_connection: Failed to set dereferencing method: %d\n", deref
));
849 DEBUG(5,("Set dereferencing method: %d\n", deref
));
853 DEBUG(2, ("smbldap_open_connection: connection opened\n"));
857 /*******************************************************************
858 a rebind function for authenticated referrals
859 This version takes a void* that we can shove useful stuff in :-)
860 ******************************************************************/
861 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
863 static int rebindproc_with_state (LDAP
* ld
, char **whop
, char **credp
,
864 int *methodp
, int freeit
, void *arg
)
866 struct smbldap_state
*ldap_state
= arg
;
869 /** @TODO Should we be doing something to check what servers we rebind to?
870 Could we get a referral to a machine that we don't want to give our
871 username and password to? */
876 memset(*credp
, '\0', strlen(*credp
));
880 DEBUG(5,("rebind_proc_with_state: Rebinding as \"%s\"\n",
881 ldap_state
->bind_dn
?ldap_state
->bind_dn
:"[Anonymous bind]"));
883 if (ldap_state
->anonymous
) {
887 *whop
= SMB_STRDUP(ldap_state
->bind_dn
);
889 return LDAP_NO_MEMORY
;
891 *credp
= SMB_STRDUP(ldap_state
->bind_secret
);
894 return LDAP_NO_MEMORY
;
897 *methodp
= LDAP_AUTH_SIMPLE
;
900 clock_gettime_mono(&ts
);
901 ldap_state
->last_rebind
= convert_timespec_to_timeval(ts
);
905 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
907 /*******************************************************************
908 a rebind function for authenticated referrals
909 This version takes a void* that we can shove useful stuff in :-)
910 and actually does the connection.
911 ******************************************************************/
912 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
913 static int rebindproc_connect_with_state (LDAP
*ldap_struct
,
914 LDAP_CONST
char *url
,
916 ber_int_t msgid
, void *arg
)
918 struct smbldap_state
*ldap_state
=
919 (struct smbldap_state
*)arg
;
924 DEBUG(5,("rebindproc_connect_with_state: Rebinding to %s as \"%s\"\n",
925 url
, ldap_state
->bind_dn
?ldap_state
->bind_dn
:"[Anonymous bind]"));
927 /* call START_TLS again (ldaps:// is handled by the OpenLDAP library
928 * itself) before rebinding to another LDAP server to avoid to expose
929 * our credentials. At least *try* to secure the connection - Guenther */
931 smb_ldap_upgrade_conn(ldap_struct
, &version
);
932 smbldap_start_tls(ldap_struct
, version
);
934 /** @TODO Should we be doing something to check what servers we rebind to?
935 Could we get a referral to a machine that we don't want to give our
936 username and password to? */
938 rc
= ldap_simple_bind_s(ldap_struct
, ldap_state
->bind_dn
, ldap_state
->bind_secret
);
940 /* only set the last rebind timestamp when we did rebind after a
941 * non-read LDAP operation. That way we avoid the replication sleep
942 * after a simple redirected search operation - Guenther */
946 case LDAP_REQ_MODIFY
:
948 case LDAP_REQ_DELETE
:
950 case LDAP_REQ_EXTENDED
:
951 DEBUG(10,("rebindproc_connect_with_state: "
952 "setting last_rebind timestamp "
953 "(req: 0x%02x)\n", (unsigned int)request
));
954 clock_gettime_mono(&ts
);
955 ldap_state
->last_rebind
= convert_timespec_to_timeval(ts
);
958 ZERO_STRUCT(ldap_state
->last_rebind
);
964 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
966 /*******************************************************************
967 Add a rebind function for authenticated referrals
968 ******************************************************************/
969 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
971 # if LDAP_SET_REBIND_PROC_ARGS == 2
972 static int rebindproc (LDAP
*ldap_struct
, char **whop
, char **credp
,
973 int *method
, int freeit
)
975 struct smbldap_state
*ldap_state
= smbldap_find_state(ldap_struct
);
977 return rebindproc_with_state(ldap_struct
, whop
, credp
,
978 method
, freeit
, ldap_state
);
980 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
981 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
983 /*******************************************************************
984 a rebind function for authenticated referrals
985 this also does the connection, but no void*.
986 ******************************************************************/
987 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
988 # if LDAP_SET_REBIND_PROC_ARGS == 2
989 static int rebindproc_connect (LDAP
* ld
, LDAP_CONST
char *url
, int request
,
992 struct smbldap_state
*ldap_state
= smbldap_find_state(ld
);
994 return rebindproc_connect_with_state(ld
, url
, (ber_tag_t
)request
, msgid
,
997 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
998 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
1000 /*******************************************************************
1001 connect to the ldap server under system privilege.
1002 ******************************************************************/
1003 static int smbldap_connect_system(struct smbldap_state
*ldap_state
)
1005 LDAP
*ldap_struct
= smbldap_get_ldap(ldap_state
);
1009 /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
1010 (OpenLDAP) doesn't seem to support it */
1012 DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n",
1013 ldap_state
->uri
, ldap_state
->bind_dn
));
1015 #ifdef HAVE_LDAP_SET_REBIND_PROC
1016 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
1017 # if LDAP_SET_REBIND_PROC_ARGS == 2
1018 ldap_set_rebind_proc(ldap_struct
, &rebindproc_connect
);
1020 # if LDAP_SET_REBIND_PROC_ARGS == 3
1021 ldap_set_rebind_proc(ldap_struct
, &rebindproc_connect_with_state
, (void *)ldap_state
);
1023 #else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
1024 # if LDAP_SET_REBIND_PROC_ARGS == 2
1025 ldap_set_rebind_proc(ldap_struct
, &rebindproc
);
1027 # if LDAP_SET_REBIND_PROC_ARGS == 3
1028 ldap_set_rebind_proc(ldap_struct
, &rebindproc_with_state
, (void *)ldap_state
);
1030 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
1033 /* When there is an alternative bind callback is set,
1034 attempt to use it to perform the bind */
1035 if (ldap_state
->bind_callback
!= NULL
) {
1036 /* We have to allow bind callback to be run under become_root/unbecome_root
1037 to make sure within smbd the callback has proper write access to its resources,
1038 like credential cache. This is similar to passdb case where this callback is supposed
1039 to be used. When used outside smbd, become_root()/unbecome_root() are no-op.
1042 rc
= ldap_state
->bind_callback(ldap_struct
, ldap_state
, ldap_state
->bind_callback_data
);
1045 rc
= ldap_simple_bind_s(ldap_struct
, ldap_state
->bind_dn
, ldap_state
->bind_secret
);
1048 if (rc
!= LDAP_SUCCESS
) {
1049 char *ld_error
= NULL
;
1050 ldap_get_option(smbldap_get_ldap(ldap_state
),
1051 LDAP_OPT_ERROR_STRING
,
1053 DEBUG(ldap_state
->num_failures
? 2 : 0,
1054 ("failed to bind to server %s with dn=\"%s\" Error: %s\n\t%s\n",
1056 ldap_state
->bind_dn
? ldap_state
->bind_dn
: "[Anonymous bind]",
1057 ldap_err2string(rc
),
1058 ld_error
? ld_error
: "(unknown)"));
1059 SAFE_FREE(ld_error
);
1060 ldap_state
->num_failures
++;
1064 ldap_state
->num_failures
= 0;
1065 ldap_state
->paged_results
= False
;
1067 ldap_get_option(smbldap_get_ldap(ldap_state
),
1068 LDAP_OPT_PROTOCOL_VERSION
, &version
);
1070 if (smbldap_has_control(smbldap_get_ldap(ldap_state
), ADS_PAGE_CTL_OID
)
1072 ldap_state
->paged_results
= True
;
1075 DEBUG(3, ("ldap_connect_system: successful connection to the LDAP server\n"));
1076 DEBUGADD(10, ("ldap_connect_system: LDAP server %s support paged results\n",
1077 ldap_state
->paged_results
? "does" : "does not"));
1080 ldap_unbind(ldap_struct
);
1081 ldap_state
->ldap_struct
= NULL
;
1086 static void smbldap_idle_fn(struct tevent_context
*tevent_ctx
,
1087 struct tevent_timer
*te
,
1088 struct timeval now_abs
,
1089 void *private_data
);
1091 /**********************************************************************
1092 Connect to LDAP server (called before every ldap operation)
1093 *********************************************************************/
1094 static int smbldap_open(struct smbldap_state
*ldap_state
)
1097 bool reopen
= False
;
1098 SMB_ASSERT(ldap_state
);
1100 if ((smbldap_get_ldap(ldap_state
) != NULL
) &&
1101 ((ldap_state
->last_ping
+ SMBLDAP_DONT_PING_TIME
) <
1104 #ifdef HAVE_UNIXSOCKET
1105 struct sockaddr_un addr
;
1107 struct sockaddr_storage addr
;
1109 socklen_t len
= sizeof(addr
);
1112 opt_rc
= ldap_get_option(smbldap_get_ldap(ldap_state
),
1113 LDAP_OPT_DESC
, &sd
);
1114 if (opt_rc
== 0 && (getpeername(sd
, (struct sockaddr
*) &addr
, &len
)) < 0 )
1117 #ifdef HAVE_UNIXSOCKET
1118 if (opt_rc
== 0 && addr
.sun_family
== AF_UNIX
)
1122 /* the other end has died. reopen. */
1123 ldap_unbind(smbldap_get_ldap(ldap_state
));
1124 ldap_state
->ldap_struct
= NULL
;
1125 ldap_state
->last_ping
= (time_t)0;
1127 ldap_state
->last_ping
= time_mono(NULL
);
1131 if (smbldap_get_ldap(ldap_state
) != NULL
) {
1132 DEBUG(11,("smbldap_open: already connected to the LDAP server\n"));
1133 return LDAP_SUCCESS
;
1136 if ((rc
= smbldap_open_connection(ldap_state
))) {
1140 if ((rc
= smbldap_connect_system(ldap_state
))) {
1145 ldap_state
->last_ping
= time_mono(NULL
);
1146 ldap_state
->pid
= getpid();
1148 TALLOC_FREE(ldap_state
->idle_event
);
1150 if (ldap_state
->tevent_context
!= NULL
) {
1151 ldap_state
->idle_event
= tevent_add_timer(
1152 ldap_state
->tevent_context
, ldap_state
,
1153 timeval_current_ofs(SMBLDAP_IDLE_TIME
, 0),
1154 smbldap_idle_fn
, ldap_state
);
1157 DEBUG(4,("The LDAP server is successfully connected\n"));
1159 return LDAP_SUCCESS
;
1162 /**********************************************************************
1163 Disconnect from LDAP server
1164 *********************************************************************/
1165 static NTSTATUS
smbldap_close(struct smbldap_state
*ldap_state
)
1168 return NT_STATUS_INVALID_PARAMETER
;
1170 if (smbldap_get_ldap(ldap_state
) != NULL
) {
1171 ldap_unbind(smbldap_get_ldap(ldap_state
));
1172 ldap_state
->ldap_struct
= NULL
;
1175 smbldap_delete_state(ldap_state
);
1177 TALLOC_FREE(ldap_state
->idle_event
);
1179 DEBUG(5,("The connection to the LDAP server was closed\n"));
1180 /* maybe free the results here --metze */
1182 return NT_STATUS_OK
;
1185 static SIG_ATOMIC_T got_alarm
;
1187 static void gotalarm_sig(int dummy
)
1192 static time_t calc_ldap_abs_endtime(int ldap_to
)
1195 /* No timeout - don't
1201 /* Make the alarm time one second beyond
1202 the timeout we're setting for the
1203 remote search timeout, to allow that
1204 to fire in preference. */
1206 return time_mono(NULL
)+ldap_to
+1;
1209 static int end_ldap_local_alarm(time_t absolute_endtime
, int rc
)
1211 if (absolute_endtime
) {
1213 CatchSignal(SIGALRM
, SIG_IGN
);
1215 /* Client timeout error code. */
1217 return LDAP_TIMEOUT
;
1223 static void setup_ldap_local_alarm(struct smbldap_state
*ldap_state
, time_t absolute_endtime
)
1225 time_t now
= time_mono(NULL
);
1227 if (absolute_endtime
) {
1229 CatchSignal(SIGALRM
, gotalarm_sig
);
1230 alarm(absolute_endtime
- now
);
1233 if (ldap_state
->pid
!= getpid()) {
1234 smbldap_close(ldap_state
);
1238 static void get_ldap_errs(struct smbldap_state
*ldap_state
, char **pp_ld_error
, int *p_ld_errno
)
1240 ldap_get_option(smbldap_get_ldap(ldap_state
),
1241 LDAP_OPT_ERROR_NUMBER
, p_ld_errno
);
1243 ldap_get_option(smbldap_get_ldap(ldap_state
),
1244 LDAP_OPT_ERROR_STRING
, pp_ld_error
);
1247 static int get_cached_ldap_connect(struct smbldap_state
*ldap_state
, time_t abs_endtime
)
1255 now
= time_mono(NULL
);
1256 ldap_state
->last_use
= now
;
1258 if (abs_endtime
&& now
> abs_endtime
) {
1259 smbldap_close(ldap_state
);
1260 return LDAP_TIMEOUT
;
1263 rc
= smbldap_open(ldap_state
);
1265 if (rc
== LDAP_SUCCESS
) {
1266 return LDAP_SUCCESS
;
1270 DEBUG(1, ("Connection to LDAP server failed for the "
1271 "%d try!\n", attempts
));
1273 if (rc
== LDAP_INSUFFICIENT_ACCESS
) {
1274 /* The fact that we are non-root or any other
1275 * access-denied condition will not change in the next
1276 * round of trying */
1281 smbldap_close(ldap_state
);
1282 return LDAP_TIMEOUT
;
1288 smbldap_close(ldap_state
);
1289 return LDAP_TIMEOUT
;
1294 /*********************************************************************
1295 ********************************************************************/
1297 static int smbldap_search_ext(struct smbldap_state
*ldap_state
,
1298 const char *base
, int scope
, const char *filter
,
1299 const char *attrs
[], int attrsonly
,
1300 LDAPControl
**sctrls
, LDAPControl
**cctrls
,
1301 int sizelimit
, LDAPMessage
**res
)
1303 int rc
= LDAP_SERVER_DOWN
;
1305 int to
= lp_ldap_timeout();
1306 time_t abs_endtime
= calc_ldap_abs_endtime(to
);
1307 struct timeval timeout
;
1308 struct timeval
*timeout_ptr
= NULL
;
1309 size_t converted_size
;
1311 SMB_ASSERT(ldap_state
);
1313 DEBUG(5,("smbldap_search_ext: base => [%s], filter => [%s], "
1314 "scope => [%d]\n", base
, filter
, scope
));
1316 if (ldap_state
->last_rebind
.tv_sec
> 0) {
1317 struct timeval tval
;
1322 clock_gettime_mono(&ts
);
1323 tval
= convert_timespec_to_timeval(ts
);
1325 tdiff
= usec_time_diff(&tval
, &ldap_state
->last_rebind
);
1326 tdiff
/= 1000; /* Convert to milliseconds. */
1328 sleep_time
= lp_ldap_replication_sleep()-(int)tdiff
;
1329 sleep_time
= MIN(sleep_time
, MAX_LDAP_REPLICATION_SLEEP_TIME
);
1331 if (sleep_time
> 0) {
1332 /* we wait for the LDAP replication */
1333 DEBUG(5,("smbldap_search_ext: waiting %d milliseconds "
1334 "for LDAP replication.\n",sleep_time
));
1335 smb_msleep(sleep_time
);
1336 DEBUG(5,("smbldap_search_ext: go on!\n"));
1338 ZERO_STRUCT(ldap_state
->last_rebind
);
1341 if (!push_utf8_talloc(talloc_tos(), &utf8_filter
, filter
, &converted_size
)) {
1342 return LDAP_NO_MEMORY
;
1345 /* Setup remote timeout for the ldap_search_ext_s call. */
1347 timeout
.tv_sec
= to
;
1348 timeout
.tv_usec
= 0;
1349 timeout_ptr
= &timeout
;
1352 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1355 char *ld_error
= NULL
;
1358 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1359 if (rc
!= LDAP_SUCCESS
) {
1363 rc
= ldap_search_ext_s(smbldap_get_ldap(ldap_state
),
1366 discard_const_p(char *, attrs
),
1367 attrsonly
, sctrls
, cctrls
, timeout_ptr
,
1369 if (rc
== LDAP_SUCCESS
) {
1373 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1375 DEBUG(10, ("Failed search for base: %s, error: %d (%s) "
1376 "(%s)\n", base
, ld_errno
,
1377 ldap_err2string(rc
),
1378 ld_error
? ld_error
: "unknown"));
1379 SAFE_FREE(ld_error
);
1381 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1384 ldap_unbind(smbldap_get_ldap(ldap_state
));
1385 ldap_state
->ldap_struct
= NULL
;
1388 TALLOC_FREE(utf8_filter
);
1389 return end_ldap_local_alarm(abs_endtime
, rc
);
1392 int smbldap_search(struct smbldap_state
*ldap_state
,
1393 const char *base
, int scope
, const char *filter
,
1394 const char *attrs
[], int attrsonly
,
1397 return smbldap_search_ext(ldap_state
, base
, scope
, filter
, attrs
,
1398 attrsonly
, NULL
, NULL
, LDAP_NO_LIMIT
, res
);
1401 int smbldap_search_paged(struct smbldap_state
*ldap_state
,
1402 const char *base
, int scope
, const char *filter
,
1403 const char **attrs
, int attrsonly
, int pagesize
,
1404 LDAPMessage
**res
, void **cookie
)
1407 LDAPControl
**rcontrols
;
1408 LDAPControl
*controls
[2] = { NULL
, NULL
};
1409 BerElement
*cookie_be
= NULL
;
1410 struct berval
*cookie_bv
= NULL
;
1412 bool critical
= True
;
1416 DEBUG(3,("smbldap_search_paged: base => [%s], filter => [%s],"
1417 "scope => [%d], pagesize => [%d]\n",
1418 base
, filter
, scope
, pagesize
));
1420 cookie_be
= ber_alloc_t(LBER_USE_DER
);
1421 if (cookie_be
== NULL
) {
1422 DEBUG(0,("smbldap_create_page_control: ber_alloc_t returns "
1424 return LDAP_NO_MEMORY
;
1427 /* construct cookie */
1428 if (*cookie
!= NULL
) {
1429 ber_printf(cookie_be
, "{iO}", (ber_int_t
) pagesize
, *cookie
);
1430 ber_bvfree((struct berval
*)*cookie
); /* don't need it from last time */
1433 ber_printf(cookie_be
, "{io}", (ber_int_t
) pagesize
, "", 0);
1435 ber_flatten(cookie_be
, &cookie_bv
);
1437 pr
.ldctl_oid
= discard_const_p(char, ADS_PAGE_CTL_OID
);
1438 pr
.ldctl_iscritical
= (char) critical
;
1439 pr
.ldctl_value
.bv_len
= cookie_bv
->bv_len
;
1440 pr
.ldctl_value
.bv_val
= cookie_bv
->bv_val
;
1445 rc
= smbldap_search_ext(ldap_state
, base
, scope
, filter
, attrs
,
1446 0, controls
, NULL
, LDAP_NO_LIMIT
, res
);
1448 ber_free(cookie_be
, 1);
1449 ber_bvfree(cookie_bv
);
1452 DEBUG(3,("smbldap_search_paged: smbldap_search_ext(%s) "
1453 "failed with [%s]\n", filter
, ldap_err2string(rc
)));
1457 DEBUG(3,("smbldap_search_paged: search was successful\n"));
1459 rc
= ldap_parse_result(smbldap_get_ldap(ldap_state
), *res
, NULL
, NULL
,
1460 NULL
, NULL
, &rcontrols
, 0);
1462 DEBUG(3,("smbldap_search_paged: ldap_parse_result failed " \
1463 "with [%s]\n", ldap_err2string(rc
)));
1467 if (rcontrols
== NULL
)
1470 for (i
=0; rcontrols
[i
]; i
++) {
1472 if (strcmp(ADS_PAGE_CTL_OID
, rcontrols
[i
]->ldctl_oid
) != 0)
1475 cookie_be
= ber_init(&rcontrols
[i
]->ldctl_value
);
1476 ber_scanf(cookie_be
,"{iO}", &tmp
, &cookie_bv
);
1477 /* the berval is the cookie, but must be freed when it is all
1479 if (cookie_bv
->bv_len
)
1480 *cookie
=ber_bvdup(cookie_bv
);
1483 ber_bvfree(cookie_bv
);
1484 ber_free(cookie_be
, 1);
1487 ldap_controls_free(rcontrols
);
1492 int smbldap_modify(struct smbldap_state
*ldap_state
, const char *dn
, LDAPMod
*attrs
[])
1494 int rc
= LDAP_SERVER_DOWN
;
1496 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1497 size_t converted_size
;
1499 SMB_ASSERT(ldap_state
);
1501 DEBUG(5,("smbldap_modify: dn => [%s]\n", dn
));
1503 if (!push_utf8_talloc(talloc_tos(), &utf8_dn
, dn
, &converted_size
)) {
1504 return LDAP_NO_MEMORY
;
1507 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1510 char *ld_error
= NULL
;
1513 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1514 if (rc
!= LDAP_SUCCESS
) {
1518 rc
= ldap_modify_s(smbldap_get_ldap(ldap_state
), utf8_dn
,
1520 if (rc
== LDAP_SUCCESS
) {
1524 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1526 DEBUG(10, ("Failed to modify dn: %s, error: %d (%s) "
1527 "(%s)\n", dn
, ld_errno
,
1528 ldap_err2string(rc
),
1529 ld_error
? ld_error
: "unknown"));
1530 SAFE_FREE(ld_error
);
1532 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1535 ldap_unbind(smbldap_get_ldap(ldap_state
));
1536 ldap_state
->ldap_struct
= NULL
;
1539 TALLOC_FREE(utf8_dn
);
1540 return end_ldap_local_alarm(abs_endtime
, rc
);
1543 int smbldap_add(struct smbldap_state
*ldap_state
, const char *dn
, LDAPMod
*attrs
[])
1545 int rc
= LDAP_SERVER_DOWN
;
1547 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1548 size_t converted_size
;
1550 SMB_ASSERT(ldap_state
);
1552 DEBUG(5,("smbldap_add: dn => [%s]\n", dn
));
1554 if (!push_utf8_talloc(talloc_tos(), &utf8_dn
, dn
, &converted_size
)) {
1555 return LDAP_NO_MEMORY
;
1558 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1561 char *ld_error
= NULL
;
1564 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1565 if (rc
!= LDAP_SUCCESS
) {
1569 rc
= ldap_add_s(smbldap_get_ldap(ldap_state
), utf8_dn
, attrs
);
1570 if (rc
== LDAP_SUCCESS
) {
1574 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1576 DEBUG(10, ("Failed to add dn: %s, error: %d (%s) "
1577 "(%s)\n", dn
, ld_errno
,
1578 ldap_err2string(rc
),
1579 ld_error
? ld_error
: "unknown"));
1580 SAFE_FREE(ld_error
);
1582 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1585 ldap_unbind(smbldap_get_ldap(ldap_state
));
1586 ldap_state
->ldap_struct
= NULL
;
1589 TALLOC_FREE(utf8_dn
);
1590 return end_ldap_local_alarm(abs_endtime
, rc
);
1593 int smbldap_delete(struct smbldap_state
*ldap_state
, const char *dn
)
1595 int rc
= LDAP_SERVER_DOWN
;
1597 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1598 size_t converted_size
;
1600 SMB_ASSERT(ldap_state
);
1602 DEBUG(5,("smbldap_delete: dn => [%s]\n", dn
));
1604 if (!push_utf8_talloc(talloc_tos(), &utf8_dn
, dn
, &converted_size
)) {
1605 return LDAP_NO_MEMORY
;
1608 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1611 char *ld_error
= NULL
;
1614 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1615 if (rc
!= LDAP_SUCCESS
) {
1619 rc
= ldap_delete_s(smbldap_get_ldap(ldap_state
), utf8_dn
);
1620 if (rc
== LDAP_SUCCESS
) {
1624 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1626 DEBUG(10, ("Failed to delete dn: %s, error: %d (%s) "
1627 "(%s)\n", dn
, ld_errno
,
1628 ldap_err2string(rc
),
1629 ld_error
? ld_error
: "unknown"));
1630 SAFE_FREE(ld_error
);
1632 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1635 ldap_unbind(smbldap_get_ldap(ldap_state
));
1636 ldap_state
->ldap_struct
= NULL
;
1639 TALLOC_FREE(utf8_dn
);
1640 return end_ldap_local_alarm(abs_endtime
, rc
);
1643 int smbldap_extended_operation(struct smbldap_state
*ldap_state
,
1644 LDAP_CONST
char *reqoid
, struct berval
*reqdata
,
1645 LDAPControl
**serverctrls
, LDAPControl
**clientctrls
,
1646 char **retoidp
, struct berval
**retdatap
)
1648 int rc
= LDAP_SERVER_DOWN
;
1649 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1654 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1657 char *ld_error
= NULL
;
1660 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1661 if (rc
!= LDAP_SUCCESS
) {
1665 rc
= ldap_extended_operation_s(smbldap_get_ldap(ldap_state
),
1667 reqdata
, serverctrls
,
1668 clientctrls
, retoidp
, retdatap
);
1669 if (rc
== LDAP_SUCCESS
) {
1673 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1675 DEBUG(10, ("Extended operation failed with error: "
1676 "%d (%s) (%s)\n", ld_errno
,
1677 ldap_err2string(rc
),
1678 ld_error
? ld_error
: "unknown"));
1679 SAFE_FREE(ld_error
);
1681 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1684 ldap_unbind(smbldap_get_ldap(ldap_state
));
1685 ldap_state
->ldap_struct
= NULL
;
1688 return end_ldap_local_alarm(abs_endtime
, rc
);
1691 /*******************************************************************
1692 run the search by name.
1693 ******************************************************************/
1694 int smbldap_search_suffix (struct smbldap_state
*ldap_state
,
1695 const char *filter
, const char **search_attr
,
1696 LDAPMessage
** result
)
1698 return smbldap_search(ldap_state
, lp_ldap_suffix(),
1700 filter
, search_attr
, 0, result
);
1703 static void smbldap_idle_fn(struct tevent_context
*tevent_ctx
,
1704 struct tevent_timer
*te
,
1705 struct timeval now_abs
,
1708 struct smbldap_state
*state
= (struct smbldap_state
*)private_data
;
1710 TALLOC_FREE(state
->idle_event
);
1712 if (smbldap_get_ldap(state
) == NULL
) {
1713 DEBUG(10,("ldap connection not connected...\n"));
1717 if ((state
->last_use
+SMBLDAP_IDLE_TIME
) > time_mono(NULL
)) {
1718 DEBUG(10,("ldap connection not idle...\n"));
1720 /* this needs to be made monotonic clock aware inside tevent: */
1721 state
->idle_event
= tevent_add_timer(
1723 timeval_add(&now_abs
, SMBLDAP_IDLE_TIME
, 0),
1729 DEBUG(7,("ldap connection idle...closing connection\n"));
1730 smbldap_close(state
);
1733 /**********************************************************************
1735 *********************************************************************/
1737 void smbldap_free_struct(struct smbldap_state
**ldap_state
)
1739 smbldap_close(*ldap_state
);
1741 if ((*ldap_state
)->bind_secret
) {
1742 memset((*ldap_state
)->bind_secret
, '\0', strlen((*ldap_state
)->bind_secret
));
1745 SAFE_FREE((*ldap_state
)->bind_dn
);
1746 BURN_FREE_STR((*ldap_state
)->bind_secret
);
1747 smbldap_set_bind_callback(*ldap_state
, NULL
, NULL
);
1749 TALLOC_FREE(*ldap_state
);
1751 /* No need to free any further, as it is talloc()ed */
1754 static int smbldap_state_destructor(struct smbldap_state
*state
)
1756 smbldap_free_struct(&state
);
1761 /**********************************************************************
1762 Initialise the 'general' ldap structures, on which ldap operations may be conducted
1763 *********************************************************************/
1765 NTSTATUS
smbldap_init(TALLOC_CTX
*mem_ctx
, struct tevent_context
*tevent_ctx
,
1766 const char *location
,
1768 const char *bind_dn
,
1769 const char *bind_secret
,
1770 struct smbldap_state
**smbldap_state
)
1772 *smbldap_state
= talloc_zero(mem_ctx
, struct smbldap_state
);
1773 if (!*smbldap_state
) {
1774 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
1775 return NT_STATUS_NO_MEMORY
;
1779 (*smbldap_state
)->uri
= talloc_strdup(mem_ctx
, location
);
1781 (*smbldap_state
)->uri
= "ldap://localhost";
1784 (*smbldap_state
)->tevent_context
= tevent_ctx
;
1786 if (bind_dn
&& bind_secret
) {
1787 smbldap_set_creds(*smbldap_state
, anon
, bind_dn
, bind_secret
);
1790 talloc_set_destructor(*smbldap_state
, smbldap_state_destructor
);
1791 return NT_STATUS_OK
;
1794 char *smbldap_talloc_dn(TALLOC_CTX
*mem_ctx
, LDAP
*ld
,
1797 char *utf8_dn
, *unix_dn
;
1798 size_t converted_size
;
1800 utf8_dn
= ldap_get_dn(ld
, entry
);
1802 DEBUG (5, ("smbldap_talloc_dn: ldap_get_dn failed\n"));
1805 if (!pull_utf8_talloc(mem_ctx
, &unix_dn
, utf8_dn
, &converted_size
)) {
1806 DEBUG (0, ("smbldap_talloc_dn: String conversion failure utf8 "
1807 "[%s]\n", utf8_dn
));
1810 ldap_memfree(utf8_dn
);
1814 /*******************************************************************
1815 Check if root-dse has a certain Control or Extension
1816 ********************************************************************/
1818 static bool smbldap_check_root_dse(LDAP
*ld
, const char **attrs
, const char *value
)
1820 LDAPMessage
*msg
= NULL
;
1821 LDAPMessage
*entry
= NULL
;
1822 char **values
= NULL
;
1823 int rc
, num_result
, num_values
, i
;
1824 bool result
= False
;
1827 DEBUG(3,("smbldap_check_root_dse: nothing to look for\n"));
1831 if (!strequal(attrs
[0], "supportedExtension") &&
1832 !strequal(attrs
[0], "supportedControl") &&
1833 !strequal(attrs
[0], "namingContexts")) {
1834 DEBUG(3,("smbldap_check_root_dse: no idea what to query root-dse for: %s ?\n", attrs
[0]));
1838 rc
= ldap_search_s(ld
, "", LDAP_SCOPE_BASE
,
1839 "(objectclass=*)", discard_const_p(char *, attrs
), 0 , &msg
);
1841 if (rc
!= LDAP_SUCCESS
) {
1842 DEBUG(3,("smbldap_check_root_dse: Could not search rootDSE\n"));
1846 num_result
= ldap_count_entries(ld
, msg
);
1848 if (num_result
!= 1) {
1849 DEBUG(3,("smbldap_check_root_dse: Expected one rootDSE, got %d\n", num_result
));
1853 entry
= ldap_first_entry(ld
, msg
);
1855 if (entry
== NULL
) {
1856 DEBUG(3,("smbldap_check_root_dse: Could not retrieve rootDSE\n"));
1860 values
= ldap_get_values(ld
, entry
, attrs
[0]);
1862 if (values
== NULL
) {
1863 DEBUG(5,("smbldap_check_root_dse: LDAP Server does not support any %s\n", attrs
[0]));
1867 num_values
= ldap_count_values(values
);
1869 if (num_values
== 0) {
1870 DEBUG(5,("smbldap_check_root_dse: LDAP Server does not have any %s\n", attrs
[0]));
1874 for (i
=0; i
<num_values
; i
++) {
1875 if (strcmp(values
[i
], value
) == 0)
1882 ldap_value_free(values
);
1890 /*******************************************************************
1891 Check if LDAP-Server supports a certain Control (OID in string format)
1892 ********************************************************************/
1894 bool smbldap_has_control(LDAP
*ld
, const char *control
)
1896 const char *attrs
[] = { "supportedControl", NULL
};
1897 return smbldap_check_root_dse(ld
, attrs
, control
);
1900 /*******************************************************************
1901 Check if LDAP-Server supports a certain Extension (OID in string format)
1902 ********************************************************************/
1904 bool smbldap_has_extension(LDAP
*ld
, const char *extension
)
1906 const char *attrs
[] = { "supportedExtension", NULL
};
1907 return smbldap_check_root_dse(ld
, attrs
, extension
);
1910 /*******************************************************************
1911 Check if LDAP-Server holds a given namingContext
1912 ********************************************************************/
1914 bool smbldap_has_naming_context(LDAP
*ld
, const char *naming_context
)
1916 const char *attrs
[] = { "namingContexts", NULL
};
1917 return smbldap_check_root_dse(ld
, attrs
, naming_context
);
1920 bool smbldap_set_creds(struct smbldap_state
*ldap_state
, bool anon
, const char *dn
, const char *secret
)
1922 ldap_state
->anonymous
= anon
;
1924 /* free any previously set credential */
1926 SAFE_FREE(ldap_state
->bind_dn
);
1927 smbldap_set_bind_callback(ldap_state
, NULL
, NULL
);
1929 if (ldap_state
->bind_secret
) {
1930 /* make sure secrets are zeroed out of memory */
1931 memset(ldap_state
->bind_secret
, '\0', strlen(ldap_state
->bind_secret
));
1932 SAFE_FREE(ldap_state
->bind_secret
);
1936 ldap_state
->bind_dn
= SMB_STRDUP(dn
);
1937 ldap_state
->bind_secret
= SMB_STRDUP(secret
);