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
602 *******************************************************************/
604 int smbldap_start_tls(LDAP
*ldap_struct
, int version
)
606 #ifdef LDAP_OPT_X_TLS
610 if (lp_ldap_ssl() != LDAP_SSL_START_TLS
) {
614 #ifdef LDAP_OPT_X_TLS
615 /* check if we use ldaps already */
616 ldap_get_option(ldap_struct
, LDAP_OPT_X_TLS
, &tls
);
617 if (tls
== LDAP_OPT_X_TLS_HARD
) {
621 if (version
!= LDAP_VERSION3
) {
622 DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
623 return LDAP_OPERATIONS_ERROR
;
626 if ((rc
= ldap_start_tls_s (ldap_struct
, NULL
, NULL
)) != LDAP_SUCCESS
) {
627 DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
628 ldap_err2string(rc
)));
632 DEBUG (3, ("StartTLS issued: using a TLS connection\n"));
635 DEBUG(0,("StartTLS not supported by LDAP client libraries!\n"));
636 return LDAP_OPERATIONS_ERROR
;
640 /********************************************************************
641 setup a connection to the LDAP server based on a uri
642 *******************************************************************/
644 static int smb_ldap_setup_conn(LDAP
**ldap_struct
, const char *uri
)
648 DEBUG(10, ("smb_ldap_setup_connection: %s\n", uri
));
650 #ifdef HAVE_LDAP_INITIALIZE
652 rc
= ldap_initialize(ldap_struct
, uri
);
654 DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc
)));
658 if (lp_ldap_follow_referral() != Auto
) {
659 rc
= ldap_set_option(*ldap_struct
, LDAP_OPT_REFERRALS
,
660 lp_ldap_follow_referral() ? LDAP_OPT_ON
: LDAP_OPT_OFF
);
661 if (rc
!= LDAP_SUCCESS
)
662 DEBUG(0, ("Failed to set LDAP_OPT_REFERRALS: %s\n",
663 ldap_err2string(rc
)));
669 /* Parse the string manually */
675 SMB_ASSERT(sizeof(protocol
)>10 && sizeof(host
)>254);
678 /* skip leading "URL:" (if any) */
679 if ( strnequal( uri
, "URL:", 4 ) ) {
683 sscanf(uri
, "%10[^:]://%254[^:/]:%d", protocol
, host
, &port
);
686 if (strequal(protocol
, "ldap")) {
688 } else if (strequal(protocol
, "ldaps")) {
691 DEBUG(0, ("unrecognised protocol (%s)!\n", protocol
));
695 if ((*ldap_struct
= ldap_init(host
, port
)) == NULL
) {
696 DEBUG(0, ("ldap_init failed !\n"));
697 return LDAP_OPERATIONS_ERROR
;
700 if (strequal(protocol
, "ldaps")) {
701 #ifdef LDAP_OPT_X_TLS
702 int tls
= LDAP_OPT_X_TLS_HARD
;
703 if (ldap_set_option (*ldap_struct
, LDAP_OPT_X_TLS
, &tls
) != LDAP_SUCCESS
)
705 DEBUG(0, ("Failed to setup a TLS session\n"));
708 DEBUG(3,("LDAPS option set...!\n"));
710 DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));
711 return LDAP_OPERATIONS_ERROR
;
712 #endif /* LDAP_OPT_X_TLS */
715 #endif /* HAVE_LDAP_INITIALIZE */
717 /* now set connection timeout */
718 #ifdef LDAP_X_OPT_CONNECT_TIMEOUT /* Netscape */
720 int ct
= lp_ldap_connection_timeout()*1000;
721 rc
= ldap_set_option(*ldap_struct
, LDAP_X_OPT_CONNECT_TIMEOUT
, &ct
);
722 if (rc
!= LDAP_SUCCESS
) {
723 DEBUG(0,("Failed to setup an ldap connection timeout %d: %s\n",
724 ct
, ldap_err2string(rc
)));
727 #elif defined (LDAP_OPT_NETWORK_TIMEOUT) /* OpenLDAP */
731 ct
.tv_sec
= lp_ldap_connection_timeout();
732 rc
= ldap_set_option(*ldap_struct
, LDAP_OPT_NETWORK_TIMEOUT
, &ct
);
733 if (rc
!= LDAP_SUCCESS
) {
734 DEBUG(0,("Failed to setup an ldap connection timeout %d: %s\n",
735 (int)ct
.tv_sec
, ldap_err2string(rc
)));
743 /********************************************************************
744 try to upgrade to Version 3 LDAP if not already, in either case return current
746 *******************************************************************/
748 static int smb_ldap_upgrade_conn(LDAP
*ldap_struct
, int *new_version
)
753 /* assume the worst */
754 *new_version
= LDAP_VERSION2
;
756 rc
= ldap_get_option(ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
761 if (version
== LDAP_VERSION3
) {
762 *new_version
= LDAP_VERSION3
;
767 version
= LDAP_VERSION3
;
768 rc
= ldap_set_option (ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
773 *new_version
= LDAP_VERSION3
;
777 /*******************************************************************
778 open a connection to the ldap server (just until the bind)
779 ******************************************************************/
781 int smbldap_setup_full_conn(LDAP
**ldap_struct
, const char *uri
)
785 rc
= smb_ldap_setup_conn(ldap_struct
, uri
);
790 rc
= smb_ldap_upgrade_conn(*ldap_struct
, &version
);
795 rc
= smbldap_start_tls(*ldap_struct
, version
);
803 /*******************************************************************
804 open a connection to the ldap server.
805 ******************************************************************/
806 static int smbldap_open_connection (struct smbldap_state
*ldap_state
)
809 int rc
= LDAP_SUCCESS
;
812 LDAP
**ldap_struct
= &ldap_state
->ldap_struct
;
814 rc
= smb_ldap_setup_conn(ldap_struct
, ldap_state
->uri
);
819 /* Store the LDAP pointer in a lookup list */
821 smbldap_store_state(*ldap_struct
, ldap_state
);
823 /* Upgrade to LDAPv3 if possible */
825 rc
= smb_ldap_upgrade_conn(*ldap_struct
, &version
);
830 /* Start TLS if required */
832 rc
= smbldap_start_tls(*ldap_struct
, version
);
837 /* Set alias dereferencing method */
838 deref
= lp_ldap_deref();
840 if (ldap_set_option (*ldap_struct
, LDAP_OPT_DEREF
, &deref
) != LDAP_OPT_SUCCESS
) {
841 DEBUG(1,("smbldap_open_connection: Failed to set dereferencing method: %d\n", deref
));
843 DEBUG(5,("Set dereferencing method: %d\n", deref
));
847 DEBUG(2, ("smbldap_open_connection: connection opened\n"));
851 /*******************************************************************
852 a rebind function for authenticated referrals
853 This version takes a void* that we can shove useful stuff in :-)
854 ******************************************************************/
855 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
857 static int rebindproc_with_state (LDAP
* ld
, char **whop
, char **credp
,
858 int *methodp
, int freeit
, void *arg
)
860 struct smbldap_state
*ldap_state
= arg
;
863 /** @TODO Should we be doing something to check what servers we rebind to?
864 Could we get a referral to a machine that we don't want to give our
865 username and password to? */
870 memset(*credp
, '\0', strlen(*credp
));
874 DEBUG(5,("rebind_proc_with_state: Rebinding as \"%s\"\n",
875 ldap_state
->bind_dn
?ldap_state
->bind_dn
:"[Anonymous bind]"));
877 if (ldap_state
->anonymous
) {
881 *whop
= SMB_STRDUP(ldap_state
->bind_dn
);
883 return LDAP_NO_MEMORY
;
885 *credp
= SMB_STRDUP(ldap_state
->bind_secret
);
888 return LDAP_NO_MEMORY
;
891 *methodp
= LDAP_AUTH_SIMPLE
;
894 clock_gettime_mono(&ts
);
895 ldap_state
->last_rebind
= convert_timespec_to_timeval(ts
);
899 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
901 /*******************************************************************
902 a rebind function for authenticated referrals
903 This version takes a void* that we can shove useful stuff in :-)
904 and actually does the connection.
905 ******************************************************************/
906 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
907 static int rebindproc_connect_with_state (LDAP
*ldap_struct
,
908 LDAP_CONST
char *url
,
910 ber_int_t msgid
, void *arg
)
912 struct smbldap_state
*ldap_state
=
913 (struct smbldap_state
*)arg
;
918 DEBUG(5,("rebindproc_connect_with_state: Rebinding to %s as \"%s\"\n",
919 url
, ldap_state
->bind_dn
?ldap_state
->bind_dn
:"[Anonymous bind]"));
921 /* call START_TLS again (ldaps:// is handled by the OpenLDAP library
922 * itself) before rebinding to another LDAP server to avoid to expose
923 * our credentials. At least *try* to secure the connection - Guenther */
925 smb_ldap_upgrade_conn(ldap_struct
, &version
);
926 smbldap_start_tls(ldap_struct
, version
);
928 /** @TODO Should we be doing something to check what servers we rebind to?
929 Could we get a referral to a machine that we don't want to give our
930 username and password to? */
932 rc
= ldap_simple_bind_s(ldap_struct
, ldap_state
->bind_dn
, ldap_state
->bind_secret
);
934 /* only set the last rebind timestamp when we did rebind after a
935 * non-read LDAP operation. That way we avoid the replication sleep
936 * after a simple redirected search operation - Guenther */
940 case LDAP_REQ_MODIFY
:
942 case LDAP_REQ_DELETE
:
944 case LDAP_REQ_EXTENDED
:
945 DEBUG(10,("rebindproc_connect_with_state: "
946 "setting last_rebind timestamp "
947 "(req: 0x%02x)\n", (unsigned int)request
));
948 clock_gettime_mono(&ts
);
949 ldap_state
->last_rebind
= convert_timespec_to_timeval(ts
);
952 ZERO_STRUCT(ldap_state
->last_rebind
);
958 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
960 /*******************************************************************
961 Add a rebind function for authenticated referrals
962 ******************************************************************/
963 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
965 # if LDAP_SET_REBIND_PROC_ARGS == 2
966 static int rebindproc (LDAP
*ldap_struct
, char **whop
, char **credp
,
967 int *method
, int freeit
)
969 struct smbldap_state
*ldap_state
= smbldap_find_state(ldap_struct
);
971 return rebindproc_with_state(ldap_struct
, whop
, credp
,
972 method
, freeit
, ldap_state
);
974 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
975 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
977 /*******************************************************************
978 a rebind function for authenticated referrals
979 this also does the connection, but no void*.
980 ******************************************************************/
981 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
982 # if LDAP_SET_REBIND_PROC_ARGS == 2
983 static int rebindproc_connect (LDAP
* ld
, LDAP_CONST
char *url
, int request
,
986 struct smbldap_state
*ldap_state
= smbldap_find_state(ld
);
988 return rebindproc_connect_with_state(ld
, url
, (ber_tag_t
)request
, msgid
,
991 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
992 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
994 /*******************************************************************
995 connect to the ldap server under system privilege.
996 ******************************************************************/
997 static int smbldap_connect_system(struct smbldap_state
*ldap_state
)
999 LDAP
*ldap_struct
= smbldap_get_ldap(ldap_state
);
1003 /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
1004 (OpenLDAP) doesn't seem to support it */
1006 DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n",
1007 ldap_state
->uri
, ldap_state
->bind_dn
));
1009 #ifdef HAVE_LDAP_SET_REBIND_PROC
1010 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
1011 # if LDAP_SET_REBIND_PROC_ARGS == 2
1012 ldap_set_rebind_proc(ldap_struct
, &rebindproc_connect
);
1014 # if LDAP_SET_REBIND_PROC_ARGS == 3
1015 ldap_set_rebind_proc(ldap_struct
, &rebindproc_connect_with_state
, (void *)ldap_state
);
1017 #else /*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
);
1021 # if LDAP_SET_REBIND_PROC_ARGS == 3
1022 ldap_set_rebind_proc(ldap_struct
, &rebindproc_with_state
, (void *)ldap_state
);
1024 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
1027 /* When there is an alternative bind callback is set,
1028 attempt to use it to perform the bind */
1029 if (ldap_state
->bind_callback
!= NULL
) {
1030 /* We have to allow bind callback to be run under become_root/unbecome_root
1031 to make sure within smbd the callback has proper write access to its resources,
1032 like credential cache. This is similar to passdb case where this callback is supposed
1033 to be used. When used outside smbd, become_root()/unbecome_root() are no-op.
1036 rc
= ldap_state
->bind_callback(ldap_struct
, ldap_state
, ldap_state
->bind_callback_data
);
1039 rc
= ldap_simple_bind_s(ldap_struct
, ldap_state
->bind_dn
, ldap_state
->bind_secret
);
1042 if (rc
!= LDAP_SUCCESS
) {
1043 char *ld_error
= NULL
;
1044 ldap_get_option(smbldap_get_ldap(ldap_state
),
1045 LDAP_OPT_ERROR_STRING
,
1047 DEBUG(ldap_state
->num_failures
? 2 : 0,
1048 ("failed to bind to server %s with dn=\"%s\" Error: %s\n\t%s\n",
1050 ldap_state
->bind_dn
? ldap_state
->bind_dn
: "[Anonymous bind]",
1051 ldap_err2string(rc
),
1052 ld_error
? ld_error
: "(unknown)"));
1053 SAFE_FREE(ld_error
);
1054 ldap_state
->num_failures
++;
1058 ldap_state
->num_failures
= 0;
1059 ldap_state
->paged_results
= False
;
1061 ldap_get_option(smbldap_get_ldap(ldap_state
),
1062 LDAP_OPT_PROTOCOL_VERSION
, &version
);
1064 if (smbldap_has_control(smbldap_get_ldap(ldap_state
), ADS_PAGE_CTL_OID
)
1066 ldap_state
->paged_results
= True
;
1069 DEBUG(3, ("ldap_connect_system: successful connection to the LDAP server\n"));
1070 DEBUGADD(10, ("ldap_connect_system: LDAP server %s support paged results\n",
1071 ldap_state
->paged_results
? "does" : "does not"));
1074 ldap_unbind(ldap_struct
);
1075 ldap_state
->ldap_struct
= NULL
;
1080 static void smbldap_idle_fn(struct tevent_context
*tevent_ctx
,
1081 struct tevent_timer
*te
,
1082 struct timeval now_abs
,
1083 void *private_data
);
1085 /**********************************************************************
1086 Connect to LDAP server (called before every ldap operation)
1087 *********************************************************************/
1088 static int smbldap_open(struct smbldap_state
*ldap_state
)
1091 bool reopen
= False
;
1092 SMB_ASSERT(ldap_state
);
1094 if ((smbldap_get_ldap(ldap_state
) != NULL
) &&
1095 ((ldap_state
->last_ping
+ SMBLDAP_DONT_PING_TIME
) <
1098 #ifdef HAVE_UNIXSOCKET
1099 struct sockaddr_un addr
;
1101 struct sockaddr_storage addr
;
1103 socklen_t len
= sizeof(addr
);
1106 opt_rc
= ldap_get_option(smbldap_get_ldap(ldap_state
),
1107 LDAP_OPT_DESC
, &sd
);
1108 if (opt_rc
== 0 && (getpeername(sd
, (struct sockaddr
*) &addr
, &len
)) < 0 )
1111 #ifdef HAVE_UNIXSOCKET
1112 if (opt_rc
== 0 && addr
.sun_family
== AF_UNIX
)
1116 /* the other end has died. reopen. */
1117 ldap_unbind(smbldap_get_ldap(ldap_state
));
1118 ldap_state
->ldap_struct
= NULL
;
1119 ldap_state
->last_ping
= (time_t)0;
1121 ldap_state
->last_ping
= time_mono(NULL
);
1125 if (smbldap_get_ldap(ldap_state
) != NULL
) {
1126 DEBUG(11,("smbldap_open: already connected to the LDAP server\n"));
1127 return LDAP_SUCCESS
;
1130 if ((rc
= smbldap_open_connection(ldap_state
))) {
1134 if ((rc
= smbldap_connect_system(ldap_state
))) {
1139 ldap_state
->last_ping
= time_mono(NULL
);
1140 ldap_state
->pid
= getpid();
1142 TALLOC_FREE(ldap_state
->idle_event
);
1144 if (ldap_state
->tevent_context
!= NULL
) {
1145 ldap_state
->idle_event
= tevent_add_timer(
1146 ldap_state
->tevent_context
, ldap_state
,
1147 timeval_current_ofs(SMBLDAP_IDLE_TIME
, 0),
1148 smbldap_idle_fn
, ldap_state
);
1151 DEBUG(4,("The LDAP server is successfully connected\n"));
1153 return LDAP_SUCCESS
;
1156 /**********************************************************************
1157 Disconnect from LDAP server
1158 *********************************************************************/
1159 static NTSTATUS
smbldap_close(struct smbldap_state
*ldap_state
)
1162 return NT_STATUS_INVALID_PARAMETER
;
1164 if (smbldap_get_ldap(ldap_state
) != NULL
) {
1165 ldap_unbind(smbldap_get_ldap(ldap_state
));
1166 ldap_state
->ldap_struct
= NULL
;
1169 smbldap_delete_state(ldap_state
);
1171 TALLOC_FREE(ldap_state
->idle_event
);
1173 DEBUG(5,("The connection to the LDAP server was closed\n"));
1174 /* maybe free the results here --metze */
1176 return NT_STATUS_OK
;
1179 static SIG_ATOMIC_T got_alarm
;
1181 static void gotalarm_sig(int dummy
)
1186 static time_t calc_ldap_abs_endtime(int ldap_to
)
1189 /* No timeout - don't
1195 /* Make the alarm time one second beyond
1196 the timout we're setting for the
1197 remote search timeout, to allow that
1198 to fire in preference. */
1200 return time_mono(NULL
)+ldap_to
+1;
1203 static int end_ldap_local_alarm(time_t absolute_endtime
, int rc
)
1205 if (absolute_endtime
) {
1207 CatchSignal(SIGALRM
, SIG_IGN
);
1209 /* Client timeout error code. */
1211 return LDAP_TIMEOUT
;
1217 static void setup_ldap_local_alarm(struct smbldap_state
*ldap_state
, time_t absolute_endtime
)
1219 time_t now
= time_mono(NULL
);
1221 if (absolute_endtime
) {
1223 CatchSignal(SIGALRM
, gotalarm_sig
);
1224 alarm(absolute_endtime
- now
);
1227 if (ldap_state
->pid
!= getpid()) {
1228 smbldap_close(ldap_state
);
1232 static void get_ldap_errs(struct smbldap_state
*ldap_state
, char **pp_ld_error
, int *p_ld_errno
)
1234 ldap_get_option(smbldap_get_ldap(ldap_state
),
1235 LDAP_OPT_ERROR_NUMBER
, p_ld_errno
);
1237 ldap_get_option(smbldap_get_ldap(ldap_state
),
1238 LDAP_OPT_ERROR_STRING
, pp_ld_error
);
1241 static int get_cached_ldap_connect(struct smbldap_state
*ldap_state
, time_t abs_endtime
)
1249 now
= time_mono(NULL
);
1250 ldap_state
->last_use
= now
;
1252 if (abs_endtime
&& now
> abs_endtime
) {
1253 smbldap_close(ldap_state
);
1254 return LDAP_TIMEOUT
;
1257 rc
= smbldap_open(ldap_state
);
1259 if (rc
== LDAP_SUCCESS
) {
1260 return LDAP_SUCCESS
;
1264 DEBUG(1, ("Connection to LDAP server failed for the "
1265 "%d try!\n", attempts
));
1267 if (rc
== LDAP_INSUFFICIENT_ACCESS
) {
1268 /* The fact that we are non-root or any other
1269 * access-denied condition will not change in the next
1270 * round of trying */
1275 smbldap_close(ldap_state
);
1276 return LDAP_TIMEOUT
;
1282 smbldap_close(ldap_state
);
1283 return LDAP_TIMEOUT
;
1288 /*********************************************************************
1289 ********************************************************************/
1291 static int smbldap_search_ext(struct smbldap_state
*ldap_state
,
1292 const char *base
, int scope
, const char *filter
,
1293 const char *attrs
[], int attrsonly
,
1294 LDAPControl
**sctrls
, LDAPControl
**cctrls
,
1295 int sizelimit
, LDAPMessage
**res
)
1297 int rc
= LDAP_SERVER_DOWN
;
1299 int to
= lp_ldap_timeout();
1300 time_t abs_endtime
= calc_ldap_abs_endtime(to
);
1301 struct timeval timeout
;
1302 struct timeval
*timeout_ptr
= NULL
;
1303 size_t converted_size
;
1305 SMB_ASSERT(ldap_state
);
1307 DEBUG(5,("smbldap_search_ext: base => [%s], filter => [%s], "
1308 "scope => [%d]\n", base
, filter
, scope
));
1310 if (ldap_state
->last_rebind
.tv_sec
> 0) {
1311 struct timeval tval
;
1316 clock_gettime_mono(&ts
);
1317 tval
= convert_timespec_to_timeval(ts
);
1319 tdiff
= usec_time_diff(&tval
, &ldap_state
->last_rebind
);
1320 tdiff
/= 1000; /* Convert to milliseconds. */
1322 sleep_time
= lp_ldap_replication_sleep()-(int)tdiff
;
1323 sleep_time
= MIN(sleep_time
, MAX_LDAP_REPLICATION_SLEEP_TIME
);
1325 if (sleep_time
> 0) {
1326 /* we wait for the LDAP replication */
1327 DEBUG(5,("smbldap_search_ext: waiting %d milliseconds "
1328 "for LDAP replication.\n",sleep_time
));
1329 smb_msleep(sleep_time
);
1330 DEBUG(5,("smbldap_search_ext: go on!\n"));
1332 ZERO_STRUCT(ldap_state
->last_rebind
);
1335 if (!push_utf8_talloc(talloc_tos(), &utf8_filter
, filter
, &converted_size
)) {
1336 return LDAP_NO_MEMORY
;
1339 /* Setup remote timeout for the ldap_search_ext_s call. */
1341 timeout
.tv_sec
= to
;
1342 timeout
.tv_usec
= 0;
1343 timeout_ptr
= &timeout
;
1346 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1349 char *ld_error
= NULL
;
1352 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1353 if (rc
!= LDAP_SUCCESS
) {
1357 rc
= ldap_search_ext_s(smbldap_get_ldap(ldap_state
),
1360 discard_const_p(char *, attrs
),
1361 attrsonly
, sctrls
, cctrls
, timeout_ptr
,
1363 if (rc
== LDAP_SUCCESS
) {
1367 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1369 DEBUG(10, ("Failed search for base: %s, error: %d (%s) "
1370 "(%s)\n", base
, ld_errno
,
1371 ldap_err2string(rc
),
1372 ld_error
? ld_error
: "unknown"));
1373 SAFE_FREE(ld_error
);
1375 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1378 ldap_unbind(smbldap_get_ldap(ldap_state
));
1379 ldap_state
->ldap_struct
= NULL
;
1382 TALLOC_FREE(utf8_filter
);
1383 return end_ldap_local_alarm(abs_endtime
, rc
);
1386 int smbldap_search(struct smbldap_state
*ldap_state
,
1387 const char *base
, int scope
, const char *filter
,
1388 const char *attrs
[], int attrsonly
,
1391 return smbldap_search_ext(ldap_state
, base
, scope
, filter
, attrs
,
1392 attrsonly
, NULL
, NULL
, LDAP_NO_LIMIT
, res
);
1395 int smbldap_search_paged(struct smbldap_state
*ldap_state
,
1396 const char *base
, int scope
, const char *filter
,
1397 const char **attrs
, int attrsonly
, int pagesize
,
1398 LDAPMessage
**res
, void **cookie
)
1401 LDAPControl
**rcontrols
;
1402 LDAPControl
*controls
[2] = { NULL
, NULL
};
1403 BerElement
*cookie_be
= NULL
;
1404 struct berval
*cookie_bv
= NULL
;
1406 bool critical
= True
;
1410 DEBUG(3,("smbldap_search_paged: base => [%s], filter => [%s],"
1411 "scope => [%d], pagesize => [%d]\n",
1412 base
, filter
, scope
, pagesize
));
1414 cookie_be
= ber_alloc_t(LBER_USE_DER
);
1415 if (cookie_be
== NULL
) {
1416 DEBUG(0,("smbldap_create_page_control: ber_alloc_t returns "
1418 return LDAP_NO_MEMORY
;
1421 /* construct cookie */
1422 if (*cookie
!= NULL
) {
1423 ber_printf(cookie_be
, "{iO}", (ber_int_t
) pagesize
, *cookie
);
1424 ber_bvfree((struct berval
*)*cookie
); /* don't need it from last time */
1427 ber_printf(cookie_be
, "{io}", (ber_int_t
) pagesize
, "", 0);
1429 ber_flatten(cookie_be
, &cookie_bv
);
1431 pr
.ldctl_oid
= discard_const_p(char, ADS_PAGE_CTL_OID
);
1432 pr
.ldctl_iscritical
= (char) critical
;
1433 pr
.ldctl_value
.bv_len
= cookie_bv
->bv_len
;
1434 pr
.ldctl_value
.bv_val
= cookie_bv
->bv_val
;
1439 rc
= smbldap_search_ext(ldap_state
, base
, scope
, filter
, attrs
,
1440 0, controls
, NULL
, LDAP_NO_LIMIT
, res
);
1442 ber_free(cookie_be
, 1);
1443 ber_bvfree(cookie_bv
);
1446 DEBUG(3,("smbldap_search_paged: smbldap_search_ext(%s) "
1447 "failed with [%s]\n", filter
, ldap_err2string(rc
)));
1451 DEBUG(3,("smbldap_search_paged: search was successful\n"));
1453 rc
= ldap_parse_result(smbldap_get_ldap(ldap_state
), *res
, NULL
, NULL
,
1454 NULL
, NULL
, &rcontrols
, 0);
1456 DEBUG(3,("smbldap_search_paged: ldap_parse_result failed " \
1457 "with [%s]\n", ldap_err2string(rc
)));
1461 if (rcontrols
== NULL
)
1464 for (i
=0; rcontrols
[i
]; i
++) {
1466 if (strcmp(ADS_PAGE_CTL_OID
, rcontrols
[i
]->ldctl_oid
) != 0)
1469 cookie_be
= ber_init(&rcontrols
[i
]->ldctl_value
);
1470 ber_scanf(cookie_be
,"{iO}", &tmp
, &cookie_bv
);
1471 /* the berval is the cookie, but must be freed when it is all
1473 if (cookie_bv
->bv_len
)
1474 *cookie
=ber_bvdup(cookie_bv
);
1477 ber_bvfree(cookie_bv
);
1478 ber_free(cookie_be
, 1);
1481 ldap_controls_free(rcontrols
);
1486 int smbldap_modify(struct smbldap_state
*ldap_state
, const char *dn
, LDAPMod
*attrs
[])
1488 int rc
= LDAP_SERVER_DOWN
;
1490 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1491 size_t converted_size
;
1493 SMB_ASSERT(ldap_state
);
1495 DEBUG(5,("smbldap_modify: dn => [%s]\n", dn
));
1497 if (!push_utf8_talloc(talloc_tos(), &utf8_dn
, dn
, &converted_size
)) {
1498 return LDAP_NO_MEMORY
;
1501 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1504 char *ld_error
= NULL
;
1507 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1508 if (rc
!= LDAP_SUCCESS
) {
1512 rc
= ldap_modify_s(smbldap_get_ldap(ldap_state
), utf8_dn
,
1514 if (rc
== LDAP_SUCCESS
) {
1518 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1520 DEBUG(10, ("Failed to modify dn: %s, error: %d (%s) "
1521 "(%s)\n", dn
, ld_errno
,
1522 ldap_err2string(rc
),
1523 ld_error
? ld_error
: "unknown"));
1524 SAFE_FREE(ld_error
);
1526 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1529 ldap_unbind(smbldap_get_ldap(ldap_state
));
1530 ldap_state
->ldap_struct
= NULL
;
1533 TALLOC_FREE(utf8_dn
);
1534 return end_ldap_local_alarm(abs_endtime
, rc
);
1537 int smbldap_add(struct smbldap_state
*ldap_state
, const char *dn
, LDAPMod
*attrs
[])
1539 int rc
= LDAP_SERVER_DOWN
;
1541 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1542 size_t converted_size
;
1544 SMB_ASSERT(ldap_state
);
1546 DEBUG(5,("smbldap_add: dn => [%s]\n", dn
));
1548 if (!push_utf8_talloc(talloc_tos(), &utf8_dn
, dn
, &converted_size
)) {
1549 return LDAP_NO_MEMORY
;
1552 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1555 char *ld_error
= NULL
;
1558 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1559 if (rc
!= LDAP_SUCCESS
) {
1563 rc
= ldap_add_s(smbldap_get_ldap(ldap_state
), utf8_dn
, attrs
);
1564 if (rc
== LDAP_SUCCESS
) {
1568 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1570 DEBUG(10, ("Failed to add dn: %s, error: %d (%s) "
1571 "(%s)\n", dn
, ld_errno
,
1572 ldap_err2string(rc
),
1573 ld_error
? ld_error
: "unknown"));
1574 SAFE_FREE(ld_error
);
1576 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1579 ldap_unbind(smbldap_get_ldap(ldap_state
));
1580 ldap_state
->ldap_struct
= NULL
;
1583 TALLOC_FREE(utf8_dn
);
1584 return end_ldap_local_alarm(abs_endtime
, rc
);
1587 int smbldap_delete(struct smbldap_state
*ldap_state
, const char *dn
)
1589 int rc
= LDAP_SERVER_DOWN
;
1591 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1592 size_t converted_size
;
1594 SMB_ASSERT(ldap_state
);
1596 DEBUG(5,("smbldap_delete: dn => [%s]\n", dn
));
1598 if (!push_utf8_talloc(talloc_tos(), &utf8_dn
, dn
, &converted_size
)) {
1599 return LDAP_NO_MEMORY
;
1602 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1605 char *ld_error
= NULL
;
1608 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1609 if (rc
!= LDAP_SUCCESS
) {
1613 rc
= ldap_delete_s(smbldap_get_ldap(ldap_state
), utf8_dn
);
1614 if (rc
== LDAP_SUCCESS
) {
1618 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1620 DEBUG(10, ("Failed to delete dn: %s, error: %d (%s) "
1621 "(%s)\n", dn
, ld_errno
,
1622 ldap_err2string(rc
),
1623 ld_error
? ld_error
: "unknown"));
1624 SAFE_FREE(ld_error
);
1626 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1629 ldap_unbind(smbldap_get_ldap(ldap_state
));
1630 ldap_state
->ldap_struct
= NULL
;
1633 TALLOC_FREE(utf8_dn
);
1634 return end_ldap_local_alarm(abs_endtime
, rc
);
1637 int smbldap_extended_operation(struct smbldap_state
*ldap_state
,
1638 LDAP_CONST
char *reqoid
, struct berval
*reqdata
,
1639 LDAPControl
**serverctrls
, LDAPControl
**clientctrls
,
1640 char **retoidp
, struct berval
**retdatap
)
1642 int rc
= LDAP_SERVER_DOWN
;
1643 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1648 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1651 char *ld_error
= NULL
;
1654 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1655 if (rc
!= LDAP_SUCCESS
) {
1659 rc
= ldap_extended_operation_s(smbldap_get_ldap(ldap_state
),
1661 reqdata
, serverctrls
,
1662 clientctrls
, retoidp
, retdatap
);
1663 if (rc
== LDAP_SUCCESS
) {
1667 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1669 DEBUG(10, ("Extended operation failed with error: "
1670 "%d (%s) (%s)\n", ld_errno
,
1671 ldap_err2string(rc
),
1672 ld_error
? ld_error
: "unknown"));
1673 SAFE_FREE(ld_error
);
1675 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1678 ldap_unbind(smbldap_get_ldap(ldap_state
));
1679 ldap_state
->ldap_struct
= NULL
;
1682 return end_ldap_local_alarm(abs_endtime
, rc
);
1685 /*******************************************************************
1686 run the search by name.
1687 ******************************************************************/
1688 int smbldap_search_suffix (struct smbldap_state
*ldap_state
,
1689 const char *filter
, const char **search_attr
,
1690 LDAPMessage
** result
)
1692 return smbldap_search(ldap_state
, lp_ldap_suffix(),
1694 filter
, search_attr
, 0, result
);
1697 static void smbldap_idle_fn(struct tevent_context
*tevent_ctx
,
1698 struct tevent_timer
*te
,
1699 struct timeval now_abs
,
1702 struct smbldap_state
*state
= (struct smbldap_state
*)private_data
;
1704 TALLOC_FREE(state
->idle_event
);
1706 if (smbldap_get_ldap(state
) == NULL
) {
1707 DEBUG(10,("ldap connection not connected...\n"));
1711 if ((state
->last_use
+SMBLDAP_IDLE_TIME
) > time_mono(NULL
)) {
1712 DEBUG(10,("ldap connection not idle...\n"));
1714 /* this needs to be made monotonic clock aware inside tevent: */
1715 state
->idle_event
= tevent_add_timer(
1717 timeval_add(&now_abs
, SMBLDAP_IDLE_TIME
, 0),
1723 DEBUG(7,("ldap connection idle...closing connection\n"));
1724 smbldap_close(state
);
1727 /**********************************************************************
1729 *********************************************************************/
1731 void smbldap_free_struct(struct smbldap_state
**ldap_state
)
1733 smbldap_close(*ldap_state
);
1735 if ((*ldap_state
)->bind_secret
) {
1736 memset((*ldap_state
)->bind_secret
, '\0', strlen((*ldap_state
)->bind_secret
));
1739 SAFE_FREE((*ldap_state
)->bind_dn
);
1740 SAFE_FREE((*ldap_state
)->bind_secret
);
1741 smbldap_set_bind_callback(*ldap_state
, NULL
, NULL
);
1743 TALLOC_FREE(*ldap_state
);
1745 /* No need to free any further, as it is talloc()ed */
1748 static int smbldap_state_destructor(struct smbldap_state
*state
)
1750 smbldap_free_struct(&state
);
1755 /**********************************************************************
1756 Intitalise the 'general' ldap structures, on which ldap operations may be conducted
1757 *********************************************************************/
1759 NTSTATUS
smbldap_init(TALLOC_CTX
*mem_ctx
, struct tevent_context
*tevent_ctx
,
1760 const char *location
,
1762 const char *bind_dn
,
1763 const char *bind_secret
,
1764 struct smbldap_state
**smbldap_state
)
1766 *smbldap_state
= talloc_zero(mem_ctx
, struct smbldap_state
);
1767 if (!*smbldap_state
) {
1768 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
1769 return NT_STATUS_NO_MEMORY
;
1773 (*smbldap_state
)->uri
= talloc_strdup(mem_ctx
, location
);
1775 (*smbldap_state
)->uri
= "ldap://localhost";
1778 (*smbldap_state
)->tevent_context
= tevent_ctx
;
1780 if (bind_dn
&& bind_secret
) {
1781 smbldap_set_creds(*smbldap_state
, anon
, bind_dn
, bind_secret
);
1784 talloc_set_destructor(*smbldap_state
, smbldap_state_destructor
);
1785 return NT_STATUS_OK
;
1788 char *smbldap_talloc_dn(TALLOC_CTX
*mem_ctx
, LDAP
*ld
,
1791 char *utf8_dn
, *unix_dn
;
1792 size_t converted_size
;
1794 utf8_dn
= ldap_get_dn(ld
, entry
);
1796 DEBUG (5, ("smbldap_talloc_dn: ldap_get_dn failed\n"));
1799 if (!pull_utf8_talloc(mem_ctx
, &unix_dn
, utf8_dn
, &converted_size
)) {
1800 DEBUG (0, ("smbldap_talloc_dn: String conversion failure utf8 "
1801 "[%s]\n", utf8_dn
));
1804 ldap_memfree(utf8_dn
);
1808 /*******************************************************************
1809 Check if root-dse has a certain Control or Extension
1810 ********************************************************************/
1812 static bool smbldap_check_root_dse(LDAP
*ld
, const char **attrs
, const char *value
)
1814 LDAPMessage
*msg
= NULL
;
1815 LDAPMessage
*entry
= NULL
;
1816 char **values
= NULL
;
1817 int rc
, num_result
, num_values
, i
;
1818 bool result
= False
;
1821 DEBUG(3,("smbldap_check_root_dse: nothing to look for\n"));
1825 if (!strequal(attrs
[0], "supportedExtension") &&
1826 !strequal(attrs
[0], "supportedControl") &&
1827 !strequal(attrs
[0], "namingContexts")) {
1828 DEBUG(3,("smbldap_check_root_dse: no idea what to query root-dse for: %s ?\n", attrs
[0]));
1832 rc
= ldap_search_s(ld
, "", LDAP_SCOPE_BASE
,
1833 "(objectclass=*)", discard_const_p(char *, attrs
), 0 , &msg
);
1835 if (rc
!= LDAP_SUCCESS
) {
1836 DEBUG(3,("smbldap_check_root_dse: Could not search rootDSE\n"));
1840 num_result
= ldap_count_entries(ld
, msg
);
1842 if (num_result
!= 1) {
1843 DEBUG(3,("smbldap_check_root_dse: Expected one rootDSE, got %d\n", num_result
));
1847 entry
= ldap_first_entry(ld
, msg
);
1849 if (entry
== NULL
) {
1850 DEBUG(3,("smbldap_check_root_dse: Could not retrieve rootDSE\n"));
1854 values
= ldap_get_values(ld
, entry
, attrs
[0]);
1856 if (values
== NULL
) {
1857 DEBUG(5,("smbldap_check_root_dse: LDAP Server does not support any %s\n", attrs
[0]));
1861 num_values
= ldap_count_values(values
);
1863 if (num_values
== 0) {
1864 DEBUG(5,("smbldap_check_root_dse: LDAP Server does not have any %s\n", attrs
[0]));
1868 for (i
=0; i
<num_values
; i
++) {
1869 if (strcmp(values
[i
], value
) == 0)
1876 ldap_value_free(values
);
1884 /*******************************************************************
1885 Check if LDAP-Server supports a certain Control (OID in string format)
1886 ********************************************************************/
1888 bool smbldap_has_control(LDAP
*ld
, const char *control
)
1890 const char *attrs
[] = { "supportedControl", NULL
};
1891 return smbldap_check_root_dse(ld
, attrs
, control
);
1894 /*******************************************************************
1895 Check if LDAP-Server supports a certain Extension (OID in string format)
1896 ********************************************************************/
1898 bool smbldap_has_extension(LDAP
*ld
, const char *extension
)
1900 const char *attrs
[] = { "supportedExtension", NULL
};
1901 return smbldap_check_root_dse(ld
, attrs
, extension
);
1904 /*******************************************************************
1905 Check if LDAP-Server holds a given namingContext
1906 ********************************************************************/
1908 bool smbldap_has_naming_context(LDAP
*ld
, const char *naming_context
)
1910 const char *attrs
[] = { "namingContexts", NULL
};
1911 return smbldap_check_root_dse(ld
, attrs
, naming_context
);
1914 bool smbldap_set_creds(struct smbldap_state
*ldap_state
, bool anon
, const char *dn
, const char *secret
)
1916 ldap_state
->anonymous
= anon
;
1918 /* free any previously set credential */
1920 SAFE_FREE(ldap_state
->bind_dn
);
1921 smbldap_set_bind_callback(ldap_state
, NULL
, NULL
);
1923 if (ldap_state
->bind_secret
) {
1924 /* make sure secrets are zeroed out of memory */
1925 memset(ldap_state
->bind_secret
, '\0', strlen(ldap_state
->bind_secret
));
1926 SAFE_FREE(ldap_state
->bind_secret
);
1930 ldap_state
->bind_dn
= SMB_STRDUP(dn
);
1931 ldap_state
->bind_secret
= SMB_STRDUP(secret
);