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 if (version
!= LDAP_VERSION3
) {
616 DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
617 return LDAP_OPERATIONS_ERROR
;
620 if ((rc
= ldap_start_tls_s (ldap_struct
, NULL
, NULL
)) != LDAP_SUCCESS
) {
621 DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
622 ldap_err2string(rc
)));
626 DEBUG (3, ("StartTLS issued: using a TLS connection\n"));
629 DEBUG(0,("StartTLS not supported by LDAP client libraries!\n"));
630 return LDAP_OPERATIONS_ERROR
;
634 /********************************************************************
635 setup a connection to the LDAP server based on a uri
636 *******************************************************************/
638 static int smb_ldap_setup_conn(LDAP
**ldap_struct
, const char *uri
)
642 DEBUG(10, ("smb_ldap_setup_connection: %s\n", uri
));
644 #ifdef HAVE_LDAP_INITIALIZE
646 rc
= ldap_initialize(ldap_struct
, uri
);
648 DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc
)));
652 if (lp_ldap_follow_referral() != Auto
) {
653 rc
= ldap_set_option(*ldap_struct
, LDAP_OPT_REFERRALS
,
654 lp_ldap_follow_referral() ? LDAP_OPT_ON
: LDAP_OPT_OFF
);
655 if (rc
!= LDAP_SUCCESS
)
656 DEBUG(0, ("Failed to set LDAP_OPT_REFERRALS: %s\n",
657 ldap_err2string(rc
)));
663 /* Parse the string manually */
669 SMB_ASSERT(sizeof(protocol
)>10 && sizeof(host
)>254);
672 /* skip leading "URL:" (if any) */
673 if ( strnequal( uri
, "URL:", 4 ) ) {
677 sscanf(uri
, "%10[^:]://%254[^:/]:%d", protocol
, host
, &port
);
680 if (strequal(protocol
, "ldap")) {
682 } else if (strequal(protocol
, "ldaps")) {
685 DEBUG(0, ("unrecognised protocol (%s)!\n", protocol
));
689 if ((*ldap_struct
= ldap_init(host
, port
)) == NULL
) {
690 DEBUG(0, ("ldap_init failed !\n"));
691 return LDAP_OPERATIONS_ERROR
;
694 if (strequal(protocol
, "ldaps")) {
695 #ifdef LDAP_OPT_X_TLS
696 int tls
= LDAP_OPT_X_TLS_HARD
;
697 if (ldap_set_option (*ldap_struct
, LDAP_OPT_X_TLS
, &tls
) != LDAP_SUCCESS
)
699 DEBUG(0, ("Failed to setup a TLS session\n"));
702 DEBUG(3,("LDAPS option set...!\n"));
704 DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));
705 return LDAP_OPERATIONS_ERROR
;
706 #endif /* LDAP_OPT_X_TLS */
709 #endif /* HAVE_LDAP_INITIALIZE */
711 /* now set connection timeout */
712 #ifdef LDAP_X_OPT_CONNECT_TIMEOUT /* Netscape */
714 int ct
= lp_ldap_connection_timeout()*1000;
715 rc
= ldap_set_option(*ldap_struct
, LDAP_X_OPT_CONNECT_TIMEOUT
, &ct
);
716 if (rc
!= LDAP_SUCCESS
) {
717 DEBUG(0,("Failed to setup an ldap connection timeout %d: %s\n",
718 ct
, ldap_err2string(rc
)));
721 #elif defined (LDAP_OPT_NETWORK_TIMEOUT) /* OpenLDAP */
725 ct
.tv_sec
= lp_ldap_connection_timeout();
726 rc
= ldap_set_option(*ldap_struct
, LDAP_OPT_NETWORK_TIMEOUT
, &ct
);
727 if (rc
!= LDAP_SUCCESS
) {
728 DEBUG(0,("Failed to setup an ldap connection timeout %d: %s\n",
729 (int)ct
.tv_sec
, ldap_err2string(rc
)));
737 /********************************************************************
738 try to upgrade to Version 3 LDAP if not already, in either case return current
740 *******************************************************************/
742 static int smb_ldap_upgrade_conn(LDAP
*ldap_struct
, int *new_version
)
747 /* assume the worst */
748 *new_version
= LDAP_VERSION2
;
750 rc
= ldap_get_option(ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
755 if (version
== LDAP_VERSION3
) {
756 *new_version
= LDAP_VERSION3
;
761 version
= LDAP_VERSION3
;
762 rc
= ldap_set_option (ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
767 *new_version
= LDAP_VERSION3
;
771 /*******************************************************************
772 open a connection to the ldap server (just until the bind)
773 ******************************************************************/
775 int smbldap_setup_full_conn(LDAP
**ldap_struct
, const char *uri
)
779 rc
= smb_ldap_setup_conn(ldap_struct
, uri
);
784 rc
= smb_ldap_upgrade_conn(*ldap_struct
, &version
);
789 rc
= smbldap_start_tls(*ldap_struct
, version
);
797 /*******************************************************************
798 open a connection to the ldap server.
799 ******************************************************************/
800 static int smbldap_open_connection (struct smbldap_state
*ldap_state
)
803 int rc
= LDAP_SUCCESS
;
806 LDAP
**ldap_struct
= &ldap_state
->ldap_struct
;
808 rc
= smb_ldap_setup_conn(ldap_struct
, ldap_state
->uri
);
813 /* Store the LDAP pointer in a lookup list */
815 smbldap_store_state(*ldap_struct
, ldap_state
);
817 /* Upgrade to LDAPv3 if possible */
819 rc
= smb_ldap_upgrade_conn(*ldap_struct
, &version
);
824 /* Start TLS if required */
826 rc
= smbldap_start_tls(*ldap_struct
, version
);
831 /* Set alias dereferencing method */
832 deref
= lp_ldap_deref();
834 if (ldap_set_option (*ldap_struct
, LDAP_OPT_DEREF
, &deref
) != LDAP_OPT_SUCCESS
) {
835 DEBUG(1,("smbldap_open_connection: Failed to set dereferencing method: %d\n", deref
));
837 DEBUG(5,("Set dereferencing method: %d\n", deref
));
841 DEBUG(2, ("smbldap_open_connection: connection opened\n"));
845 /*******************************************************************
846 a rebind function for authenticated referrals
847 This version takes a void* that we can shove useful stuff in :-)
848 ******************************************************************/
849 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
851 static int rebindproc_with_state (LDAP
* ld
, char **whop
, char **credp
,
852 int *methodp
, int freeit
, void *arg
)
854 struct smbldap_state
*ldap_state
= arg
;
857 /** @TODO Should we be doing something to check what servers we rebind to?
858 Could we get a referral to a machine that we don't want to give our
859 username and password to? */
864 memset(*credp
, '\0', strlen(*credp
));
868 DEBUG(5,("rebind_proc_with_state: Rebinding as \"%s\"\n",
869 ldap_state
->bind_dn
?ldap_state
->bind_dn
:"[Anonymous bind]"));
871 if (ldap_state
->anonymous
) {
875 *whop
= SMB_STRDUP(ldap_state
->bind_dn
);
877 return LDAP_NO_MEMORY
;
879 *credp
= SMB_STRDUP(ldap_state
->bind_secret
);
882 return LDAP_NO_MEMORY
;
885 *methodp
= LDAP_AUTH_SIMPLE
;
888 clock_gettime_mono(&ts
);
889 ldap_state
->last_rebind
= convert_timespec_to_timeval(ts
);
893 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
895 /*******************************************************************
896 a rebind function for authenticated referrals
897 This version takes a void* that we can shove useful stuff in :-)
898 and actually does the connection.
899 ******************************************************************/
900 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
901 static int rebindproc_connect_with_state (LDAP
*ldap_struct
,
902 LDAP_CONST
char *url
,
904 ber_int_t msgid
, void *arg
)
906 struct smbldap_state
*ldap_state
=
907 (struct smbldap_state
*)arg
;
912 DEBUG(5,("rebindproc_connect_with_state: Rebinding to %s as \"%s\"\n",
913 url
, ldap_state
->bind_dn
?ldap_state
->bind_dn
:"[Anonymous bind]"));
915 /* call START_TLS again (ldaps:// is handled by the OpenLDAP library
916 * itself) before rebinding to another LDAP server to avoid to expose
917 * our credentials. At least *try* to secure the connection - Guenther */
919 smb_ldap_upgrade_conn(ldap_struct
, &version
);
920 smbldap_start_tls(ldap_struct
, version
);
922 /** @TODO Should we be doing something to check what servers we rebind to?
923 Could we get a referral to a machine that we don't want to give our
924 username and password to? */
926 rc
= ldap_simple_bind_s(ldap_struct
, ldap_state
->bind_dn
, ldap_state
->bind_secret
);
928 /* only set the last rebind timestamp when we did rebind after a
929 * non-read LDAP operation. That way we avoid the replication sleep
930 * after a simple redirected search operation - Guenther */
934 case LDAP_REQ_MODIFY
:
936 case LDAP_REQ_DELETE
:
938 case LDAP_REQ_EXTENDED
:
939 DEBUG(10,("rebindproc_connect_with_state: "
940 "setting last_rebind timestamp "
941 "(req: 0x%02x)\n", (unsigned int)request
));
942 clock_gettime_mono(&ts
);
943 ldap_state
->last_rebind
= convert_timespec_to_timeval(ts
);
946 ZERO_STRUCT(ldap_state
->last_rebind
);
952 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
954 /*******************************************************************
955 Add a rebind function for authenticated referrals
956 ******************************************************************/
957 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
959 # if LDAP_SET_REBIND_PROC_ARGS == 2
960 static int rebindproc (LDAP
*ldap_struct
, char **whop
, char **credp
,
961 int *method
, int freeit
)
963 struct smbldap_state
*ldap_state
= smbldap_find_state(ldap_struct
);
965 return rebindproc_with_state(ldap_struct
, whop
, credp
,
966 method
, freeit
, ldap_state
);
968 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
969 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
971 /*******************************************************************
972 a rebind function for authenticated referrals
973 this also does the connection, but no void*.
974 ******************************************************************/
975 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
976 # if LDAP_SET_REBIND_PROC_ARGS == 2
977 static int rebindproc_connect (LDAP
* ld
, LDAP_CONST
char *url
, int request
,
980 struct smbldap_state
*ldap_state
= smbldap_find_state(ld
);
982 return rebindproc_connect_with_state(ld
, url
, (ber_tag_t
)request
, msgid
,
985 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
986 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
988 /*******************************************************************
989 connect to the ldap server under system privilege.
990 ******************************************************************/
991 static int smbldap_connect_system(struct smbldap_state
*ldap_state
)
993 LDAP
*ldap_struct
= smbldap_get_ldap(ldap_state
);
997 /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
998 (OpenLDAP) doesn't seem to support it */
1000 DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n",
1001 ldap_state
->uri
, ldap_state
->bind_dn
));
1003 #ifdef HAVE_LDAP_SET_REBIND_PROC
1004 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
1005 # if LDAP_SET_REBIND_PROC_ARGS == 2
1006 ldap_set_rebind_proc(ldap_struct
, &rebindproc_connect
);
1008 # if LDAP_SET_REBIND_PROC_ARGS == 3
1009 ldap_set_rebind_proc(ldap_struct
, &rebindproc_connect_with_state
, (void *)ldap_state
);
1011 #else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
1012 # if LDAP_SET_REBIND_PROC_ARGS == 2
1013 ldap_set_rebind_proc(ldap_struct
, &rebindproc
);
1015 # if LDAP_SET_REBIND_PROC_ARGS == 3
1016 ldap_set_rebind_proc(ldap_struct
, &rebindproc_with_state
, (void *)ldap_state
);
1018 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
1021 /* When there is an alternative bind callback is set,
1022 attempt to use it to perform the bind */
1023 if (ldap_state
->bind_callback
!= NULL
) {
1024 /* We have to allow bind callback to be run under become_root/unbecome_root
1025 to make sure within smbd the callback has proper write access to its resources,
1026 like credential cache. This is similar to passdb case where this callback is supposed
1027 to be used. When used outside smbd, become_root()/unbecome_root() are no-op.
1030 rc
= ldap_state
->bind_callback(ldap_struct
, ldap_state
, ldap_state
->bind_callback_data
);
1033 rc
= ldap_simple_bind_s(ldap_struct
, ldap_state
->bind_dn
, ldap_state
->bind_secret
);
1036 if (rc
!= LDAP_SUCCESS
) {
1037 char *ld_error
= NULL
;
1038 ldap_get_option(smbldap_get_ldap(ldap_state
),
1039 LDAP_OPT_ERROR_STRING
,
1041 DEBUG(ldap_state
->num_failures
? 2 : 0,
1042 ("failed to bind to server %s with dn=\"%s\" Error: %s\n\t%s\n",
1044 ldap_state
->bind_dn
? ldap_state
->bind_dn
: "[Anonymous bind]",
1045 ldap_err2string(rc
),
1046 ld_error
? ld_error
: "(unknown)"));
1047 SAFE_FREE(ld_error
);
1048 ldap_state
->num_failures
++;
1052 ldap_state
->num_failures
= 0;
1053 ldap_state
->paged_results
= False
;
1055 ldap_get_option(smbldap_get_ldap(ldap_state
),
1056 LDAP_OPT_PROTOCOL_VERSION
, &version
);
1058 if (smbldap_has_control(smbldap_get_ldap(ldap_state
), ADS_PAGE_CTL_OID
)
1060 ldap_state
->paged_results
= True
;
1063 DEBUG(3, ("ldap_connect_system: successful connection to the LDAP server\n"));
1064 DEBUGADD(10, ("ldap_connect_system: LDAP server %s support paged results\n",
1065 ldap_state
->paged_results
? "does" : "does not"));
1068 ldap_unbind(ldap_struct
);
1069 ldap_state
->ldap_struct
= NULL
;
1074 static void smbldap_idle_fn(struct tevent_context
*tevent_ctx
,
1075 struct tevent_timer
*te
,
1076 struct timeval now_abs
,
1077 void *private_data
);
1079 /**********************************************************************
1080 Connect to LDAP server (called before every ldap operation)
1081 *********************************************************************/
1082 static int smbldap_open(struct smbldap_state
*ldap_state
)
1085 bool reopen
= False
;
1086 SMB_ASSERT(ldap_state
);
1088 if ((smbldap_get_ldap(ldap_state
) != NULL
) &&
1089 ((ldap_state
->last_ping
+ SMBLDAP_DONT_PING_TIME
) <
1092 #ifdef HAVE_UNIXSOCKET
1093 struct sockaddr_un addr
;
1095 struct sockaddr_storage addr
;
1097 socklen_t len
= sizeof(addr
);
1100 opt_rc
= ldap_get_option(smbldap_get_ldap(ldap_state
),
1101 LDAP_OPT_DESC
, &sd
);
1102 if (opt_rc
== 0 && (getpeername(sd
, (struct sockaddr
*) &addr
, &len
)) < 0 )
1105 #ifdef HAVE_UNIXSOCKET
1106 if (opt_rc
== 0 && addr
.sun_family
== AF_UNIX
)
1110 /* the other end has died. reopen. */
1111 ldap_unbind(smbldap_get_ldap(ldap_state
));
1112 ldap_state
->ldap_struct
= NULL
;
1113 ldap_state
->last_ping
= (time_t)0;
1115 ldap_state
->last_ping
= time_mono(NULL
);
1119 if (smbldap_get_ldap(ldap_state
) != NULL
) {
1120 DEBUG(11,("smbldap_open: already connected to the LDAP server\n"));
1121 return LDAP_SUCCESS
;
1124 if ((rc
= smbldap_open_connection(ldap_state
))) {
1128 if ((rc
= smbldap_connect_system(ldap_state
))) {
1133 ldap_state
->last_ping
= time_mono(NULL
);
1134 ldap_state
->pid
= getpid();
1136 TALLOC_FREE(ldap_state
->idle_event
);
1138 if (ldap_state
->tevent_context
!= NULL
) {
1139 ldap_state
->idle_event
= tevent_add_timer(
1140 ldap_state
->tevent_context
, ldap_state
,
1141 timeval_current_ofs(SMBLDAP_IDLE_TIME
, 0),
1142 smbldap_idle_fn
, ldap_state
);
1145 DEBUG(4,("The LDAP server is successfully connected\n"));
1147 return LDAP_SUCCESS
;
1150 /**********************************************************************
1151 Disconnect from LDAP server
1152 *********************************************************************/
1153 static NTSTATUS
smbldap_close(struct smbldap_state
*ldap_state
)
1156 return NT_STATUS_INVALID_PARAMETER
;
1158 if (smbldap_get_ldap(ldap_state
) != NULL
) {
1159 ldap_unbind(smbldap_get_ldap(ldap_state
));
1160 ldap_state
->ldap_struct
= NULL
;
1163 smbldap_delete_state(ldap_state
);
1165 TALLOC_FREE(ldap_state
->idle_event
);
1167 DEBUG(5,("The connection to the LDAP server was closed\n"));
1168 /* maybe free the results here --metze */
1170 return NT_STATUS_OK
;
1173 static SIG_ATOMIC_T got_alarm
;
1175 static void gotalarm_sig(int dummy
)
1180 static time_t calc_ldap_abs_endtime(int ldap_to
)
1183 /* No timeout - don't
1189 /* Make the alarm time one second beyond
1190 the timout we're setting for the
1191 remote search timeout, to allow that
1192 to fire in preference. */
1194 return time_mono(NULL
)+ldap_to
+1;
1197 static int end_ldap_local_alarm(time_t absolute_endtime
, int rc
)
1199 if (absolute_endtime
) {
1201 CatchSignal(SIGALRM
, SIG_IGN
);
1203 /* Client timeout error code. */
1205 return LDAP_TIMEOUT
;
1211 static void setup_ldap_local_alarm(struct smbldap_state
*ldap_state
, time_t absolute_endtime
)
1213 time_t now
= time_mono(NULL
);
1215 if (absolute_endtime
) {
1217 CatchSignal(SIGALRM
, gotalarm_sig
);
1218 alarm(absolute_endtime
- now
);
1221 if (ldap_state
->pid
!= getpid()) {
1222 smbldap_close(ldap_state
);
1226 static void get_ldap_errs(struct smbldap_state
*ldap_state
, char **pp_ld_error
, int *p_ld_errno
)
1228 ldap_get_option(smbldap_get_ldap(ldap_state
),
1229 LDAP_OPT_ERROR_NUMBER
, p_ld_errno
);
1231 ldap_get_option(smbldap_get_ldap(ldap_state
),
1232 LDAP_OPT_ERROR_STRING
, pp_ld_error
);
1235 static int get_cached_ldap_connect(struct smbldap_state
*ldap_state
, time_t abs_endtime
)
1243 now
= time_mono(NULL
);
1244 ldap_state
->last_use
= now
;
1246 if (abs_endtime
&& now
> abs_endtime
) {
1247 smbldap_close(ldap_state
);
1248 return LDAP_TIMEOUT
;
1251 rc
= smbldap_open(ldap_state
);
1253 if (rc
== LDAP_SUCCESS
) {
1254 return LDAP_SUCCESS
;
1258 DEBUG(1, ("Connection to LDAP server failed for the "
1259 "%d try!\n", attempts
));
1261 if (rc
== LDAP_INSUFFICIENT_ACCESS
) {
1262 /* The fact that we are non-root or any other
1263 * access-denied condition will not change in the next
1264 * round of trying */
1269 smbldap_close(ldap_state
);
1270 return LDAP_TIMEOUT
;
1276 smbldap_close(ldap_state
);
1277 return LDAP_TIMEOUT
;
1282 /*********************************************************************
1283 ********************************************************************/
1285 static int smbldap_search_ext(struct smbldap_state
*ldap_state
,
1286 const char *base
, int scope
, const char *filter
,
1287 const char *attrs
[], int attrsonly
,
1288 LDAPControl
**sctrls
, LDAPControl
**cctrls
,
1289 int sizelimit
, LDAPMessage
**res
)
1291 int rc
= LDAP_SERVER_DOWN
;
1293 int to
= lp_ldap_timeout();
1294 time_t abs_endtime
= calc_ldap_abs_endtime(to
);
1295 struct timeval timeout
;
1296 struct timeval
*timeout_ptr
= NULL
;
1297 size_t converted_size
;
1299 SMB_ASSERT(ldap_state
);
1301 DEBUG(5,("smbldap_search_ext: base => [%s], filter => [%s], "
1302 "scope => [%d]\n", base
, filter
, scope
));
1304 if (ldap_state
->last_rebind
.tv_sec
> 0) {
1305 struct timeval tval
;
1310 clock_gettime_mono(&ts
);
1311 tval
= convert_timespec_to_timeval(ts
);
1313 tdiff
= usec_time_diff(&tval
, &ldap_state
->last_rebind
);
1314 tdiff
/= 1000; /* Convert to milliseconds. */
1316 sleep_time
= lp_ldap_replication_sleep()-(int)tdiff
;
1317 sleep_time
= MIN(sleep_time
, MAX_LDAP_REPLICATION_SLEEP_TIME
);
1319 if (sleep_time
> 0) {
1320 /* we wait for the LDAP replication */
1321 DEBUG(5,("smbldap_search_ext: waiting %d milliseconds "
1322 "for LDAP replication.\n",sleep_time
));
1323 smb_msleep(sleep_time
);
1324 DEBUG(5,("smbldap_search_ext: go on!\n"));
1326 ZERO_STRUCT(ldap_state
->last_rebind
);
1329 if (!push_utf8_talloc(talloc_tos(), &utf8_filter
, filter
, &converted_size
)) {
1330 return LDAP_NO_MEMORY
;
1333 /* Setup remote timeout for the ldap_search_ext_s call. */
1335 timeout
.tv_sec
= to
;
1336 timeout
.tv_usec
= 0;
1337 timeout_ptr
= &timeout
;
1340 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1343 char *ld_error
= NULL
;
1346 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1347 if (rc
!= LDAP_SUCCESS
) {
1351 rc
= ldap_search_ext_s(smbldap_get_ldap(ldap_state
),
1354 discard_const_p(char *, attrs
),
1355 attrsonly
, sctrls
, cctrls
, timeout_ptr
,
1357 if (rc
== LDAP_SUCCESS
) {
1361 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1363 DEBUG(10, ("Failed search for base: %s, error: %d (%s) "
1364 "(%s)\n", base
, ld_errno
,
1365 ldap_err2string(rc
),
1366 ld_error
? ld_error
: "unknown"));
1367 SAFE_FREE(ld_error
);
1369 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1372 ldap_unbind(smbldap_get_ldap(ldap_state
));
1373 ldap_state
->ldap_struct
= NULL
;
1376 TALLOC_FREE(utf8_filter
);
1377 return end_ldap_local_alarm(abs_endtime
, rc
);
1380 int smbldap_search(struct smbldap_state
*ldap_state
,
1381 const char *base
, int scope
, const char *filter
,
1382 const char *attrs
[], int attrsonly
,
1385 return smbldap_search_ext(ldap_state
, base
, scope
, filter
, attrs
,
1386 attrsonly
, NULL
, NULL
, LDAP_NO_LIMIT
, res
);
1389 int smbldap_search_paged(struct smbldap_state
*ldap_state
,
1390 const char *base
, int scope
, const char *filter
,
1391 const char **attrs
, int attrsonly
, int pagesize
,
1392 LDAPMessage
**res
, void **cookie
)
1395 LDAPControl
**rcontrols
;
1396 LDAPControl
*controls
[2] = { NULL
, NULL
};
1397 BerElement
*cookie_be
= NULL
;
1398 struct berval
*cookie_bv
= NULL
;
1400 bool critical
= True
;
1404 DEBUG(3,("smbldap_search_paged: base => [%s], filter => [%s],"
1405 "scope => [%d], pagesize => [%d]\n",
1406 base
, filter
, scope
, pagesize
));
1408 cookie_be
= ber_alloc_t(LBER_USE_DER
);
1409 if (cookie_be
== NULL
) {
1410 DEBUG(0,("smbldap_create_page_control: ber_alloc_t returns "
1412 return LDAP_NO_MEMORY
;
1415 /* construct cookie */
1416 if (*cookie
!= NULL
) {
1417 ber_printf(cookie_be
, "{iO}", (ber_int_t
) pagesize
, *cookie
);
1418 ber_bvfree((struct berval
*)*cookie
); /* don't need it from last time */
1421 ber_printf(cookie_be
, "{io}", (ber_int_t
) pagesize
, "", 0);
1423 ber_flatten(cookie_be
, &cookie_bv
);
1425 pr
.ldctl_oid
= discard_const_p(char, ADS_PAGE_CTL_OID
);
1426 pr
.ldctl_iscritical
= (char) critical
;
1427 pr
.ldctl_value
.bv_len
= cookie_bv
->bv_len
;
1428 pr
.ldctl_value
.bv_val
= cookie_bv
->bv_val
;
1433 rc
= smbldap_search_ext(ldap_state
, base
, scope
, filter
, attrs
,
1434 0, controls
, NULL
, LDAP_NO_LIMIT
, res
);
1436 ber_free(cookie_be
, 1);
1437 ber_bvfree(cookie_bv
);
1440 DEBUG(3,("smbldap_search_paged: smbldap_search_ext(%s) "
1441 "failed with [%s]\n", filter
, ldap_err2string(rc
)));
1445 DEBUG(3,("smbldap_search_paged: search was successful\n"));
1447 rc
= ldap_parse_result(smbldap_get_ldap(ldap_state
), *res
, NULL
, NULL
,
1448 NULL
, NULL
, &rcontrols
, 0);
1450 DEBUG(3,("smbldap_search_paged: ldap_parse_result failed " \
1451 "with [%s]\n", ldap_err2string(rc
)));
1455 if (rcontrols
== NULL
)
1458 for (i
=0; rcontrols
[i
]; i
++) {
1460 if (strcmp(ADS_PAGE_CTL_OID
, rcontrols
[i
]->ldctl_oid
) != 0)
1463 cookie_be
= ber_init(&rcontrols
[i
]->ldctl_value
);
1464 ber_scanf(cookie_be
,"{iO}", &tmp
, &cookie_bv
);
1465 /* the berval is the cookie, but must be freed when it is all
1467 if (cookie_bv
->bv_len
)
1468 *cookie
=ber_bvdup(cookie_bv
);
1471 ber_bvfree(cookie_bv
);
1472 ber_free(cookie_be
, 1);
1475 ldap_controls_free(rcontrols
);
1480 int smbldap_modify(struct smbldap_state
*ldap_state
, const char *dn
, LDAPMod
*attrs
[])
1482 int rc
= LDAP_SERVER_DOWN
;
1484 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1485 size_t converted_size
;
1487 SMB_ASSERT(ldap_state
);
1489 DEBUG(5,("smbldap_modify: dn => [%s]\n", dn
));
1491 if (!push_utf8_talloc(talloc_tos(), &utf8_dn
, dn
, &converted_size
)) {
1492 return LDAP_NO_MEMORY
;
1495 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1498 char *ld_error
= NULL
;
1501 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1502 if (rc
!= LDAP_SUCCESS
) {
1506 rc
= ldap_modify_s(smbldap_get_ldap(ldap_state
), utf8_dn
,
1508 if (rc
== LDAP_SUCCESS
) {
1512 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1514 DEBUG(10, ("Failed to modify dn: %s, error: %d (%s) "
1515 "(%s)\n", dn
, ld_errno
,
1516 ldap_err2string(rc
),
1517 ld_error
? ld_error
: "unknown"));
1518 SAFE_FREE(ld_error
);
1520 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1523 ldap_unbind(smbldap_get_ldap(ldap_state
));
1524 ldap_state
->ldap_struct
= NULL
;
1527 TALLOC_FREE(utf8_dn
);
1528 return end_ldap_local_alarm(abs_endtime
, rc
);
1531 int smbldap_add(struct smbldap_state
*ldap_state
, const char *dn
, LDAPMod
*attrs
[])
1533 int rc
= LDAP_SERVER_DOWN
;
1535 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1536 size_t converted_size
;
1538 SMB_ASSERT(ldap_state
);
1540 DEBUG(5,("smbldap_add: dn => [%s]\n", dn
));
1542 if (!push_utf8_talloc(talloc_tos(), &utf8_dn
, dn
, &converted_size
)) {
1543 return LDAP_NO_MEMORY
;
1546 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1549 char *ld_error
= NULL
;
1552 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1553 if (rc
!= LDAP_SUCCESS
) {
1557 rc
= ldap_add_s(smbldap_get_ldap(ldap_state
), utf8_dn
, attrs
);
1558 if (rc
== LDAP_SUCCESS
) {
1562 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1564 DEBUG(10, ("Failed to add dn: %s, error: %d (%s) "
1565 "(%s)\n", dn
, ld_errno
,
1566 ldap_err2string(rc
),
1567 ld_error
? ld_error
: "unknown"));
1568 SAFE_FREE(ld_error
);
1570 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1573 ldap_unbind(smbldap_get_ldap(ldap_state
));
1574 ldap_state
->ldap_struct
= NULL
;
1577 TALLOC_FREE(utf8_dn
);
1578 return end_ldap_local_alarm(abs_endtime
, rc
);
1581 int smbldap_delete(struct smbldap_state
*ldap_state
, const char *dn
)
1583 int rc
= LDAP_SERVER_DOWN
;
1585 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1586 size_t converted_size
;
1588 SMB_ASSERT(ldap_state
);
1590 DEBUG(5,("smbldap_delete: dn => [%s]\n", dn
));
1592 if (!push_utf8_talloc(talloc_tos(), &utf8_dn
, dn
, &converted_size
)) {
1593 return LDAP_NO_MEMORY
;
1596 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1599 char *ld_error
= NULL
;
1602 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1603 if (rc
!= LDAP_SUCCESS
) {
1607 rc
= ldap_delete_s(smbldap_get_ldap(ldap_state
), utf8_dn
);
1608 if (rc
== LDAP_SUCCESS
) {
1612 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1614 DEBUG(10, ("Failed to delete dn: %s, error: %d (%s) "
1615 "(%s)\n", dn
, ld_errno
,
1616 ldap_err2string(rc
),
1617 ld_error
? ld_error
: "unknown"));
1618 SAFE_FREE(ld_error
);
1620 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1623 ldap_unbind(smbldap_get_ldap(ldap_state
));
1624 ldap_state
->ldap_struct
= NULL
;
1627 TALLOC_FREE(utf8_dn
);
1628 return end_ldap_local_alarm(abs_endtime
, rc
);
1631 int smbldap_extended_operation(struct smbldap_state
*ldap_state
,
1632 LDAP_CONST
char *reqoid
, struct berval
*reqdata
,
1633 LDAPControl
**serverctrls
, LDAPControl
**clientctrls
,
1634 char **retoidp
, struct berval
**retdatap
)
1636 int rc
= LDAP_SERVER_DOWN
;
1637 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1642 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1645 char *ld_error
= NULL
;
1648 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1649 if (rc
!= LDAP_SUCCESS
) {
1653 rc
= ldap_extended_operation_s(smbldap_get_ldap(ldap_state
),
1655 reqdata
, serverctrls
,
1656 clientctrls
, retoidp
, retdatap
);
1657 if (rc
== LDAP_SUCCESS
) {
1661 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1663 DEBUG(10, ("Extended operation failed with error: "
1664 "%d (%s) (%s)\n", ld_errno
,
1665 ldap_err2string(rc
),
1666 ld_error
? ld_error
: "unknown"));
1667 SAFE_FREE(ld_error
);
1669 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1672 ldap_unbind(smbldap_get_ldap(ldap_state
));
1673 ldap_state
->ldap_struct
= NULL
;
1676 return end_ldap_local_alarm(abs_endtime
, rc
);
1679 /*******************************************************************
1680 run the search by name.
1681 ******************************************************************/
1682 int smbldap_search_suffix (struct smbldap_state
*ldap_state
,
1683 const char *filter
, const char **search_attr
,
1684 LDAPMessage
** result
)
1686 return smbldap_search(ldap_state
, lp_ldap_suffix(talloc_tos()),
1688 filter
, search_attr
, 0, result
);
1691 static void smbldap_idle_fn(struct tevent_context
*tevent_ctx
,
1692 struct tevent_timer
*te
,
1693 struct timeval now_abs
,
1696 struct smbldap_state
*state
= (struct smbldap_state
*)private_data
;
1698 TALLOC_FREE(state
->idle_event
);
1700 if (smbldap_get_ldap(state
) == NULL
) {
1701 DEBUG(10,("ldap connection not connected...\n"));
1705 if ((state
->last_use
+SMBLDAP_IDLE_TIME
) > time_mono(NULL
)) {
1706 DEBUG(10,("ldap connection not idle...\n"));
1708 /* this needs to be made monotonic clock aware inside tevent: */
1709 state
->idle_event
= tevent_add_timer(
1711 timeval_add(&now_abs
, SMBLDAP_IDLE_TIME
, 0),
1717 DEBUG(7,("ldap connection idle...closing connection\n"));
1718 smbldap_close(state
);
1721 /**********************************************************************
1723 *********************************************************************/
1725 void smbldap_free_struct(struct smbldap_state
**ldap_state
)
1727 smbldap_close(*ldap_state
);
1729 if ((*ldap_state
)->bind_secret
) {
1730 memset((*ldap_state
)->bind_secret
, '\0', strlen((*ldap_state
)->bind_secret
));
1733 SAFE_FREE((*ldap_state
)->bind_dn
);
1734 SAFE_FREE((*ldap_state
)->bind_secret
);
1735 smbldap_set_bind_callback(*ldap_state
, NULL
, NULL
);
1737 TALLOC_FREE(*ldap_state
);
1739 /* No need to free any further, as it is talloc()ed */
1742 static int smbldap_state_destructor(struct smbldap_state
*state
)
1744 smbldap_free_struct(&state
);
1749 /**********************************************************************
1750 Intitalise the 'general' ldap structures, on which ldap operations may be conducted
1751 *********************************************************************/
1753 NTSTATUS
smbldap_init(TALLOC_CTX
*mem_ctx
, struct tevent_context
*tevent_ctx
,
1754 const char *location
,
1756 const char *bind_dn
,
1757 const char *bind_secret
,
1758 struct smbldap_state
**smbldap_state
)
1760 *smbldap_state
= talloc_zero(mem_ctx
, struct smbldap_state
);
1761 if (!*smbldap_state
) {
1762 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
1763 return NT_STATUS_NO_MEMORY
;
1767 (*smbldap_state
)->uri
= talloc_strdup(mem_ctx
, location
);
1769 (*smbldap_state
)->uri
= "ldap://localhost";
1772 (*smbldap_state
)->tevent_context
= tevent_ctx
;
1774 if (bind_dn
&& bind_secret
) {
1775 smbldap_set_creds(*smbldap_state
, anon
, bind_dn
, bind_secret
);
1778 talloc_set_destructor(*smbldap_state
, smbldap_state_destructor
);
1779 return NT_STATUS_OK
;
1782 char *smbldap_talloc_dn(TALLOC_CTX
*mem_ctx
, LDAP
*ld
,
1785 char *utf8_dn
, *unix_dn
;
1786 size_t converted_size
;
1788 utf8_dn
= ldap_get_dn(ld
, entry
);
1790 DEBUG (5, ("smbldap_talloc_dn: ldap_get_dn failed\n"));
1793 if (!pull_utf8_talloc(mem_ctx
, &unix_dn
, utf8_dn
, &converted_size
)) {
1794 DEBUG (0, ("smbldap_talloc_dn: String conversion failure utf8 "
1795 "[%s]\n", utf8_dn
));
1798 ldap_memfree(utf8_dn
);
1802 /*******************************************************************
1803 Check if root-dse has a certain Control or Extension
1804 ********************************************************************/
1806 static bool smbldap_check_root_dse(LDAP
*ld
, const char **attrs
, const char *value
)
1808 LDAPMessage
*msg
= NULL
;
1809 LDAPMessage
*entry
= NULL
;
1810 char **values
= NULL
;
1811 int rc
, num_result
, num_values
, i
;
1812 bool result
= False
;
1815 DEBUG(3,("smbldap_check_root_dse: nothing to look for\n"));
1819 if (!strequal(attrs
[0], "supportedExtension") &&
1820 !strequal(attrs
[0], "supportedControl") &&
1821 !strequal(attrs
[0], "namingContexts")) {
1822 DEBUG(3,("smbldap_check_root_dse: no idea what to query root-dse for: %s ?\n", attrs
[0]));
1826 rc
= ldap_search_s(ld
, "", LDAP_SCOPE_BASE
,
1827 "(objectclass=*)", discard_const_p(char *, attrs
), 0 , &msg
);
1829 if (rc
!= LDAP_SUCCESS
) {
1830 DEBUG(3,("smbldap_check_root_dse: Could not search rootDSE\n"));
1834 num_result
= ldap_count_entries(ld
, msg
);
1836 if (num_result
!= 1) {
1837 DEBUG(3,("smbldap_check_root_dse: Expected one rootDSE, got %d\n", num_result
));
1841 entry
= ldap_first_entry(ld
, msg
);
1843 if (entry
== NULL
) {
1844 DEBUG(3,("smbldap_check_root_dse: Could not retrieve rootDSE\n"));
1848 values
= ldap_get_values(ld
, entry
, attrs
[0]);
1850 if (values
== NULL
) {
1851 DEBUG(5,("smbldap_check_root_dse: LDAP Server does not support any %s\n", attrs
[0]));
1855 num_values
= ldap_count_values(values
);
1857 if (num_values
== 0) {
1858 DEBUG(5,("smbldap_check_root_dse: LDAP Server does not have any %s\n", attrs
[0]));
1862 for (i
=0; i
<num_values
; i
++) {
1863 if (strcmp(values
[i
], value
) == 0)
1870 ldap_value_free(values
);
1878 /*******************************************************************
1879 Check if LDAP-Server supports a certain Control (OID in string format)
1880 ********************************************************************/
1882 bool smbldap_has_control(LDAP
*ld
, const char *control
)
1884 const char *attrs
[] = { "supportedControl", NULL
};
1885 return smbldap_check_root_dse(ld
, attrs
, control
);
1888 /*******************************************************************
1889 Check if LDAP-Server supports a certain Extension (OID in string format)
1890 ********************************************************************/
1892 bool smbldap_has_extension(LDAP
*ld
, const char *extension
)
1894 const char *attrs
[] = { "supportedExtension", NULL
};
1895 return smbldap_check_root_dse(ld
, attrs
, extension
);
1898 /*******************************************************************
1899 Check if LDAP-Server holds a given namingContext
1900 ********************************************************************/
1902 bool smbldap_has_naming_context(LDAP
*ld
, const char *naming_context
)
1904 const char *attrs
[] = { "namingContexts", NULL
};
1905 return smbldap_check_root_dse(ld
, attrs
, naming_context
);
1908 bool smbldap_set_creds(struct smbldap_state
*ldap_state
, bool anon
, const char *dn
, const char *secret
)
1910 ldap_state
->anonymous
= anon
;
1912 /* free any previously set credential */
1914 SAFE_FREE(ldap_state
->bind_dn
);
1915 smbldap_set_bind_callback(ldap_state
, NULL
, NULL
);
1917 if (ldap_state
->bind_secret
) {
1918 /* make sure secrets are zeroed out of memory */
1919 memset(ldap_state
->bind_secret
, '\0', strlen(ldap_state
->bind_secret
));
1920 SAFE_FREE(ldap_state
->bind_secret
);
1924 ldap_state
->bind_dn
= SMB_STRDUP(dn
);
1925 ldap_state
->bind_secret
= SMB_STRDUP(secret
);