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"
30 /* Try not to hit the up or down server forever */
32 #define SMBLDAP_DONT_PING_TIME 10 /* ping only all 10 seconds */
33 #define SMBLDAP_NUM_RETRIES 8 /* retry only 8 times */
35 #define SMBLDAP_IDLE_TIME 150 /* After 2.5 minutes disconnect */
38 /*******************************************************************
39 Search an attribute and return the first value found.
40 ******************************************************************/
42 bool smbldap_get_single_attribute (LDAP
* ldap_struct
, LDAPMessage
* entry
,
43 const char *attribute
, char *value
,
54 if ((values
= ldap_get_values (ldap_struct
, entry
, attribute
)) == NULL
) {
55 DEBUG (10, ("smbldap_get_single_attribute: [%s] = [<does not exist>]\n", attribute
));
60 if (!convert_string(CH_UTF8
, CH_UNIX
,values
[0], -1, value
, max_len
, &size
)) {
61 DEBUG(1, ("smbldap_get_single_attribute: string conversion of [%s] = [%s] failed!\n",
62 attribute
, values
[0]));
63 ldap_value_free(values
);
67 ldap_value_free(values
);
68 #ifdef DEBUG_PASSWORDS
69 DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n", attribute
, value
));
74 char * smbldap_talloc_single_attribute(LDAP
*ldap_struct
, LDAPMessage
*entry
,
75 const char *attribute
,
80 size_t converted_size
;
82 if (attribute
== NULL
) {
86 values
= ldap_get_values(ldap_struct
, entry
, attribute
);
89 DEBUG(10, ("attribute %s does not exist\n", attribute
));
93 if (ldap_count_values(values
) != 1) {
94 DEBUG(10, ("attribute %s has %d values, expected only one\n",
95 attribute
, ldap_count_values(values
)));
96 ldap_value_free(values
);
100 if (!pull_utf8_talloc(mem_ctx
, &result
, values
[0], &converted_size
)) {
101 DEBUG(10, ("pull_utf8_talloc failed\n"));
102 ldap_value_free(values
);
106 ldap_value_free(values
);
108 #ifdef DEBUG_PASSWORDS
109 DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n",
115 char * smbldap_talloc_first_attribute(LDAP
*ldap_struct
, LDAPMessage
*entry
,
116 const char *attribute
,
121 size_t converted_size
;
123 if (attribute
== NULL
) {
127 values
= ldap_get_values(ldap_struct
, entry
, attribute
);
129 if (values
== NULL
) {
130 DEBUG(10, ("attribute %s does not exist\n", attribute
));
134 if (!pull_utf8_talloc(mem_ctx
, &result
, values
[0], &converted_size
)) {
135 DEBUG(10, ("pull_utf8_talloc failed\n"));
136 ldap_value_free(values
);
140 ldap_value_free(values
);
142 #ifdef DEBUG_PASSWORDS
143 DEBUG (100, ("smbldap_get_first_attribute: [%s] = [%s]\n",
149 char * smbldap_talloc_smallest_attribute(LDAP
*ldap_struct
, LDAPMessage
*entry
,
150 const char *attribute
,
155 size_t converted_size
;
158 if (attribute
== NULL
) {
162 values
= ldap_get_values(ldap_struct
, entry
, attribute
);
164 if (values
== NULL
) {
165 DEBUG(10, ("attribute %s does not exist\n", attribute
));
169 if (!pull_utf8_talloc(mem_ctx
, &result
, values
[0], &converted_size
)) {
170 DEBUG(10, ("pull_utf8_talloc failed\n"));
171 ldap_value_free(values
);
175 num_values
= ldap_count_values(values
);
177 for (i
=1; i
<num_values
; i
++) {
180 if (!pull_utf8_talloc(mem_ctx
, &tmp
, values
[i
],
182 DEBUG(10, ("pull_utf8_talloc failed\n"));
184 ldap_value_free(values
);
188 if (strcasecmp_m(tmp
, result
) < 0) {
196 ldap_value_free(values
);
198 #ifdef DEBUG_PASSWORDS
199 DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n",
205 bool smbldap_talloc_single_blob(TALLOC_CTX
*mem_ctx
, LDAP
*ld
,
206 LDAPMessage
*msg
, const char *attrib
,
209 struct berval
**values
;
211 values
= ldap_get_values_len(ld
, msg
, attrib
);
216 if (ldap_count_values_len(values
) != 1) {
217 DEBUG(10, ("Expected one value for %s, got %d\n", attrib
,
218 ldap_count_values_len(values
)));
222 *blob
= data_blob_talloc(mem_ctx
, values
[0]->bv_val
,
224 ldap_value_free_len(values
);
226 return (blob
->data
!= NULL
);
229 bool smbldap_pull_sid(LDAP
*ld
, LDAPMessage
*msg
, const char *attrib
,
235 if (!smbldap_talloc_single_blob(talloc_tos(), ld
, msg
, attrib
,
239 ret
= sid_parse((char *)blob
.data
, blob
.length
, sid
);
240 TALLOC_FREE(blob
.data
);
244 static int ldapmsg_destructor(LDAPMessage
**result
) {
245 ldap_msgfree(*result
);
249 void talloc_autofree_ldapmsg(TALLOC_CTX
*mem_ctx
, LDAPMessage
*result
)
251 LDAPMessage
**handle
;
253 if (result
== NULL
) {
257 handle
= talloc(mem_ctx
, LDAPMessage
*);
258 SMB_ASSERT(handle
!= NULL
);
261 talloc_set_destructor(handle
, ldapmsg_destructor
);
264 static int ldapmod_destructor(LDAPMod
***mod
) {
265 ldap_mods_free(*mod
, True
);
269 void talloc_autofree_ldapmod(TALLOC_CTX
*mem_ctx
, LDAPMod
**mod
)
277 handle
= talloc(mem_ctx
, LDAPMod
**);
278 SMB_ASSERT(handle
!= NULL
);
281 talloc_set_destructor(handle
, ldapmod_destructor
);
284 /************************************************************************
285 Routine to manage the LDAPMod structure array
286 manage memory used by the array, by each struct, and values
287 ***********************************************************************/
289 static void smbldap_set_mod_internal(LDAPMod
*** modlist
, int modop
, const char *attribute
, const char *value
, const DATA_BLOB
*blob
)
297 /* sanity checks on the mod values */
299 if (attribute
== NULL
|| *attribute
== '\0') {
303 #if 0 /* commented out after discussion with abartlet. Do not reenable.
304 left here so other do not re-add similar code --jerry */
305 if (value
== NULL
|| *value
== '\0')
310 mods
= SMB_MALLOC_P(LDAPMod
*);
312 smb_panic("smbldap_set_mod: out of memory!");
318 for (i
= 0; mods
[i
] != NULL
; ++i
) {
319 if (mods
[i
]->mod_op
== modop
&& strequal(mods
[i
]->mod_type
, attribute
))
323 if (mods
[i
] == NULL
) {
324 mods
= SMB_REALLOC_ARRAY (mods
, LDAPMod
*, i
+ 2);
326 smb_panic("smbldap_set_mod: out of memory!");
329 mods
[i
] = SMB_MALLOC_P(LDAPMod
);
330 if (mods
[i
] == NULL
) {
331 smb_panic("smbldap_set_mod: out of memory!");
334 mods
[i
]->mod_op
= modop
;
335 mods
[i
]->mod_values
= NULL
;
336 mods
[i
]->mod_type
= SMB_STRDUP(attribute
);
340 if (blob
&& (modop
& LDAP_MOD_BVALUES
)) {
342 if (mods
[i
]->mod_bvalues
!= NULL
) {
343 for (; mods
[i
]->mod_bvalues
[j
] != NULL
; j
++);
345 mods
[i
]->mod_bvalues
= SMB_REALLOC_ARRAY(mods
[i
]->mod_bvalues
, struct berval
*, j
+ 2);
347 if (mods
[i
]->mod_bvalues
== NULL
) {
348 smb_panic("smbldap_set_mod: out of memory!");
352 mods
[i
]->mod_bvalues
[j
] = SMB_MALLOC_P(struct berval
);
353 SMB_ASSERT(mods
[i
]->mod_bvalues
[j
] != NULL
);
355 mods
[i
]->mod_bvalues
[j
]->bv_val
= (char *)memdup(blob
->data
, blob
->length
);
356 SMB_ASSERT(mods
[i
]->mod_bvalues
[j
]->bv_val
!= NULL
);
357 mods
[i
]->mod_bvalues
[j
]->bv_len
= blob
->length
;
359 mods
[i
]->mod_bvalues
[j
+ 1] = NULL
;
360 } else if (value
!= NULL
) {
361 char *utf8_value
= NULL
;
362 size_t converted_size
;
365 if (mods
[i
]->mod_values
!= NULL
) {
366 for (; mods
[i
]->mod_values
[j
] != NULL
; j
++);
368 mods
[i
]->mod_values
= SMB_REALLOC_ARRAY(mods
[i
]->mod_values
, char *, j
+ 2);
370 if (mods
[i
]->mod_values
== NULL
) {
371 smb_panic("smbldap_set_mod: out of memory!");
375 if (!push_utf8_talloc(talloc_tos(), &utf8_value
, value
, &converted_size
)) {
376 smb_panic("smbldap_set_mod: String conversion failure!");
380 mods
[i
]->mod_values
[j
] = SMB_STRDUP(utf8_value
);
381 TALLOC_FREE(utf8_value
);
382 SMB_ASSERT(mods
[i
]->mod_values
[j
] != NULL
);
384 mods
[i
]->mod_values
[j
+ 1] = NULL
;
389 void smbldap_set_mod (LDAPMod
*** modlist
, int modop
, const char *attribute
, const char *value
)
391 smbldap_set_mod_internal(modlist
, modop
, attribute
, value
, NULL
);
394 void smbldap_set_mod_blob(LDAPMod
*** modlist
, int modop
, const char *attribute
, const DATA_BLOB
*value
)
396 smbldap_set_mod_internal(modlist
, modop
| LDAP_MOD_BVALUES
, attribute
, NULL
, value
);
399 /**********************************************************************
400 Set attribute to newval in LDAP, regardless of what value the
401 attribute had in LDAP before.
402 *********************************************************************/
404 static void smbldap_make_mod_internal(LDAP
*ldap_struct
, LDAPMessage
*existing
,
406 const char *attribute
, int op
,
408 const DATA_BLOB
*newblob
)
410 char oldval
[2048]; /* current largest allowed value is mungeddial */
412 DATA_BLOB oldblob
= data_blob_null
;
414 if (existing
!= NULL
) {
415 if (op
& LDAP_MOD_BVALUES
) {
416 existed
= smbldap_talloc_single_blob(talloc_tos(), ldap_struct
, existing
, attribute
, &oldblob
);
418 existed
= smbldap_get_single_attribute(ldap_struct
, existing
, attribute
, oldval
, sizeof(oldval
));
427 if (op
& LDAP_MOD_BVALUES
) {
428 equal
= (newblob
&& (data_blob_cmp(&oldblob
, newblob
) == 0));
430 /* all of our string attributes are case insensitive */
431 equal
= (newval
&& (strcasecmp_m(oldval
, newval
) == 0));
435 /* Believe it or not, but LDAP will deny a delete and
436 an add at the same time if the values are the
438 DEBUG(10,("smbldap_make_mod: attribute |%s| not changed.\n", attribute
));
442 /* There has been no value before, so don't delete it.
443 * Here's a possible race: We might end up with
444 * duplicate attributes */
445 /* By deleting exactly the value we found in the entry this
446 * should be race-free in the sense that the LDAP-Server will
447 * deny the complete operation if somebody changed the
448 * attribute behind our back. */
449 /* This will also allow modifying single valued attributes
450 * in Novell NDS. In NDS you have to first remove attribute and then
451 * you could add new value */
453 if (op
& LDAP_MOD_BVALUES
) {
454 DEBUG(10,("smbldap_make_mod: deleting attribute |%s| blob\n", attribute
));
455 smbldap_set_mod_blob(mods
, LDAP_MOD_DELETE
, attribute
, &oldblob
);
457 DEBUG(10,("smbldap_make_mod: deleting attribute |%s| values |%s|\n", attribute
, oldval
));
458 smbldap_set_mod(mods
, LDAP_MOD_DELETE
, attribute
, oldval
);
462 /* Regardless of the real operation (add or modify)
463 we add the new value here. We rely on deleting
464 the old value, should it exist. */
466 if (op
& LDAP_MOD_BVALUES
) {
467 if (newblob
&& newblob
->length
) {
468 DEBUG(10,("smbldap_make_mod: adding attribute |%s| blob\n", attribute
));
469 smbldap_set_mod_blob(mods
, LDAP_MOD_ADD
, attribute
, newblob
);
472 if ((newval
!= NULL
) && (strlen(newval
) > 0)) {
473 DEBUG(10,("smbldap_make_mod: adding attribute |%s| value |%s|\n", attribute
, newval
));
474 smbldap_set_mod(mods
, LDAP_MOD_ADD
, attribute
, newval
);
479 void smbldap_make_mod(LDAP
*ldap_struct
, LDAPMessage
*existing
,
481 const char *attribute
, const char *newval
)
483 smbldap_make_mod_internal(ldap_struct
, existing
, mods
, attribute
,
487 void smbldap_make_mod_blob(LDAP
*ldap_struct
, LDAPMessage
*existing
,
489 const char *attribute
, const DATA_BLOB
*newblob
)
491 smbldap_make_mod_internal(ldap_struct
, existing
, mods
, attribute
,
492 LDAP_MOD_BVALUES
, NULL
, newblob
);
495 /**********************************************************************
496 Some varients of the LDAP rebind code do not pass in the third 'arg'
497 pointer to a void*, so we try and work around it by assuming that the
498 value of the 'LDAP *' pointer is the same as the one we had passed in
499 **********************************************************************/
501 struct smbldap_state_lookup
{
503 struct smbldap_state
*smbldap_state
;
504 struct smbldap_state_lookup
*prev
, *next
;
507 static struct smbldap_state_lookup
*smbldap_state_lookup_list
;
509 static struct smbldap_state
*smbldap_find_state(LDAP
*ld
)
511 struct smbldap_state_lookup
*t
;
513 for (t
= smbldap_state_lookup_list
; t
; t
= t
->next
) {
515 return t
->smbldap_state
;
521 static void smbldap_delete_state(struct smbldap_state
*smbldap_state
)
523 struct smbldap_state_lookup
*t
;
525 for (t
= smbldap_state_lookup_list
; t
; t
= t
->next
) {
526 if (t
->smbldap_state
== smbldap_state
) {
527 DLIST_REMOVE(smbldap_state_lookup_list
, t
);
534 static void smbldap_store_state(LDAP
*ld
, struct smbldap_state
*smbldap_state
)
536 struct smbldap_state
*tmp_ldap_state
;
537 struct smbldap_state_lookup
*t
;
539 if ((tmp_ldap_state
= smbldap_find_state(ld
))) {
540 SMB_ASSERT(tmp_ldap_state
== smbldap_state
);
544 t
= SMB_XMALLOC_P(struct smbldap_state_lookup
);
547 DLIST_ADD_END(smbldap_state_lookup_list
, t
, struct smbldap_state_lookup
*);
549 t
->smbldap_state
= smbldap_state
;
552 /********************************************************************
553 start TLS on an existing LDAP connection
554 *******************************************************************/
556 int smb_ldap_start_tls(LDAP
*ldap_struct
, int version
)
558 #ifdef LDAP_OPT_X_TLS
562 if (lp_ldap_ssl() != LDAP_SSL_START_TLS
) {
566 #ifdef LDAP_OPT_X_TLS
567 if (version
!= LDAP_VERSION3
) {
568 DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
569 return LDAP_OPERATIONS_ERROR
;
572 if ((rc
= ldap_start_tls_s (ldap_struct
, NULL
, NULL
)) != LDAP_SUCCESS
) {
573 DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
574 ldap_err2string(rc
)));
578 DEBUG (3, ("StartTLS issued: using a TLS connection\n"));
581 DEBUG(0,("StartTLS not supported by LDAP client libraries!\n"));
582 return LDAP_OPERATIONS_ERROR
;
586 /********************************************************************
587 setup a connection to the LDAP server based on a uri
588 *******************************************************************/
590 static int smb_ldap_setup_conn(LDAP
**ldap_struct
, const char *uri
)
594 DEBUG(10, ("smb_ldap_setup_connection: %s\n", uri
));
596 #ifdef HAVE_LDAP_INITIALIZE
598 rc
= ldap_initialize(ldap_struct
, uri
);
600 DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc
)));
604 if (lp_ldap_follow_referral() != Auto
) {
605 rc
= ldap_set_option(*ldap_struct
, LDAP_OPT_REFERRALS
,
606 lp_ldap_follow_referral() ? LDAP_OPT_ON
: LDAP_OPT_OFF
);
607 if (rc
!= LDAP_SUCCESS
)
608 DEBUG(0, ("Failed to set LDAP_OPT_REFERRALS: %s\n",
609 ldap_err2string(rc
)));
615 /* Parse the string manually */
621 SMB_ASSERT(sizeof(protocol
)>10 && sizeof(host
)>254);
624 /* skip leading "URL:" (if any) */
625 if ( strnequal( uri
, "URL:", 4 ) ) {
629 sscanf(uri
, "%10[^:]://%254[^:/]:%d", protocol
, host
, &port
);
632 if (strequal(protocol
, "ldap")) {
634 } else if (strequal(protocol
, "ldaps")) {
637 DEBUG(0, ("unrecognised protocol (%s)!\n", protocol
));
641 if ((*ldap_struct
= ldap_init(host
, port
)) == NULL
) {
642 DEBUG(0, ("ldap_init failed !\n"));
643 return LDAP_OPERATIONS_ERROR
;
646 if (strequal(protocol
, "ldaps")) {
647 #ifdef LDAP_OPT_X_TLS
648 int tls
= LDAP_OPT_X_TLS_HARD
;
649 if (ldap_set_option (*ldap_struct
, LDAP_OPT_X_TLS
, &tls
) != LDAP_SUCCESS
)
651 DEBUG(0, ("Failed to setup a TLS session\n"));
654 DEBUG(3,("LDAPS option set...!\n"));
656 DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));
657 return LDAP_OPERATIONS_ERROR
;
658 #endif /* LDAP_OPT_X_TLS */
661 #endif /* HAVE_LDAP_INITIALIZE */
663 /* now set connection timeout */
664 #ifdef LDAP_X_OPT_CONNECT_TIMEOUT /* Netscape */
666 int ct
= lp_ldap_connection_timeout()*1000;
667 rc
= ldap_set_option(*ldap_struct
, LDAP_X_OPT_CONNECT_TIMEOUT
, &ct
);
668 if (rc
!= LDAP_SUCCESS
) {
669 DEBUG(0,("Failed to setup an ldap connection timeout %d: %s\n",
670 ct
, ldap_err2string(rc
)));
673 #elif defined (LDAP_OPT_NETWORK_TIMEOUT) /* OpenLDAP */
677 ct
.tv_sec
= lp_ldap_connection_timeout();
678 rc
= ldap_set_option(*ldap_struct
, LDAP_OPT_NETWORK_TIMEOUT
, &ct
);
679 if (rc
!= LDAP_SUCCESS
) {
680 DEBUG(0,("Failed to setup an ldap connection timeout %d: %s\n",
681 (int)ct
.tv_sec
, ldap_err2string(rc
)));
689 /********************************************************************
690 try to upgrade to Version 3 LDAP if not already, in either case return current
692 *******************************************************************/
694 static int smb_ldap_upgrade_conn(LDAP
*ldap_struct
, int *new_version
)
699 /* assume the worst */
700 *new_version
= LDAP_VERSION2
;
702 rc
= ldap_get_option(ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
707 if (version
== LDAP_VERSION3
) {
708 *new_version
= LDAP_VERSION3
;
713 version
= LDAP_VERSION3
;
714 rc
= ldap_set_option (ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
719 *new_version
= LDAP_VERSION3
;
723 /*******************************************************************
724 open a connection to the ldap server (just until the bind)
725 ******************************************************************/
727 int smb_ldap_setup_full_conn(LDAP
**ldap_struct
, const char *uri
)
731 rc
= smb_ldap_setup_conn(ldap_struct
, uri
);
736 rc
= smb_ldap_upgrade_conn(*ldap_struct
, &version
);
741 rc
= smb_ldap_start_tls(*ldap_struct
, version
);
749 /*******************************************************************
750 open a connection to the ldap server.
751 ******************************************************************/
752 static int smbldap_open_connection (struct smbldap_state
*ldap_state
)
755 int rc
= LDAP_SUCCESS
;
758 LDAP
**ldap_struct
= &ldap_state
->ldap_struct
;
760 rc
= smb_ldap_setup_conn(ldap_struct
, ldap_state
->uri
);
765 /* Store the LDAP pointer in a lookup list */
767 smbldap_store_state(*ldap_struct
, ldap_state
);
769 /* Upgrade to LDAPv3 if possible */
771 rc
= smb_ldap_upgrade_conn(*ldap_struct
, &version
);
776 /* Start TLS if required */
778 rc
= smb_ldap_start_tls(*ldap_struct
, version
);
783 /* Set alias dereferencing method */
784 deref
= lp_ldap_deref();
786 if (ldap_set_option (*ldap_struct
, LDAP_OPT_DEREF
, &deref
) != LDAP_OPT_SUCCESS
) {
787 DEBUG(1,("smbldap_open_connection: Failed to set dereferencing method: %d\n", deref
));
789 DEBUG(5,("Set dereferencing method: %d\n", deref
));
793 DEBUG(2, ("smbldap_open_connection: connection opened\n"));
797 /*******************************************************************
798 a rebind function for authenticated referrals
799 This version takes a void* that we can shove useful stuff in :-)
800 ******************************************************************/
801 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
803 static int rebindproc_with_state (LDAP
* ld
, char **whop
, char **credp
,
804 int *methodp
, int freeit
, void *arg
)
806 struct smbldap_state
*ldap_state
= arg
;
809 /** @TODO Should we be doing something to check what servers we rebind to?
810 Could we get a referral to a machine that we don't want to give our
811 username and password to? */
816 memset(*credp
, '\0', strlen(*credp
));
820 DEBUG(5,("rebind_proc_with_state: Rebinding as \"%s\"\n",
821 ldap_state
->bind_dn
?ldap_state
->bind_dn
:"[Anonymous bind]"));
823 if (ldap_state
->anonymous
) {
827 *whop
= SMB_STRDUP(ldap_state
->bind_dn
);
829 return LDAP_NO_MEMORY
;
831 *credp
= SMB_STRDUP(ldap_state
->bind_secret
);
834 return LDAP_NO_MEMORY
;
837 *methodp
= LDAP_AUTH_SIMPLE
;
840 clock_gettime_mono(&ts
);
841 ldap_state
->last_rebind
= convert_timespec_to_timeval(ts
);
845 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
847 /*******************************************************************
848 a rebind function for authenticated referrals
849 This version takes a void* that we can shove useful stuff in :-)
850 and actually does the connection.
851 ******************************************************************/
852 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
853 static int rebindproc_connect_with_state (LDAP
*ldap_struct
,
854 LDAP_CONST
char *url
,
856 ber_int_t msgid
, void *arg
)
858 struct smbldap_state
*ldap_state
=
859 (struct smbldap_state
*)arg
;
864 DEBUG(5,("rebindproc_connect_with_state: Rebinding to %s as \"%s\"\n",
865 url
, ldap_state
->bind_dn
?ldap_state
->bind_dn
:"[Anonymous bind]"));
867 /* call START_TLS again (ldaps:// is handled by the OpenLDAP library
868 * itself) before rebinding to another LDAP server to avoid to expose
869 * our credentials. At least *try* to secure the connection - Guenther */
871 smb_ldap_upgrade_conn(ldap_struct
, &version
);
872 smb_ldap_start_tls(ldap_struct
, version
);
874 /** @TODO Should we be doing something to check what servers we rebind to?
875 Could we get a referral to a machine that we don't want to give our
876 username and password to? */
878 rc
= ldap_simple_bind_s(ldap_struct
, ldap_state
->bind_dn
, ldap_state
->bind_secret
);
880 /* only set the last rebind timestamp when we did rebind after a
881 * non-read LDAP operation. That way we avoid the replication sleep
882 * after a simple redirected search operation - Guenther */
886 case LDAP_REQ_MODIFY
:
888 case LDAP_REQ_DELETE
:
890 case LDAP_REQ_EXTENDED
:
891 DEBUG(10,("rebindproc_connect_with_state: "
892 "setting last_rebind timestamp "
893 "(req: 0x%02x)\n", (unsigned int)request
));
894 clock_gettime_mono(&ts
);
895 ldap_state
->last_rebind
= convert_timespec_to_timeval(ts
);
898 ZERO_STRUCT(ldap_state
->last_rebind
);
904 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
906 /*******************************************************************
907 Add a rebind function for authenticated referrals
908 ******************************************************************/
909 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
911 # if LDAP_SET_REBIND_PROC_ARGS == 2
912 static int rebindproc (LDAP
*ldap_struct
, char **whop
, char **credp
,
913 int *method
, int freeit
)
915 struct smbldap_state
*ldap_state
= smbldap_find_state(ldap_struct
);
917 return rebindproc_with_state(ldap_struct
, whop
, credp
,
918 method
, freeit
, ldap_state
);
920 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
921 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
923 /*******************************************************************
924 a rebind function for authenticated referrals
925 this also does the connection, but no void*.
926 ******************************************************************/
927 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
928 # if LDAP_SET_REBIND_PROC_ARGS == 2
929 static int rebindproc_connect (LDAP
* ld
, LDAP_CONST
char *url
, int request
,
932 struct smbldap_state
*ldap_state
= smbldap_find_state(ld
);
934 return rebindproc_connect_with_state(ld
, url
, (ber_tag_t
)request
, msgid
,
937 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
938 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
940 /*******************************************************************
941 connect to the ldap server under system privilege.
942 ******************************************************************/
943 static int smbldap_connect_system(struct smbldap_state
*ldap_state
)
945 LDAP
*ldap_struct
= ldap_state
->ldap_struct
;
949 /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
950 (OpenLDAP) doesnt' seem to support it */
952 DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n",
953 ldap_state
->uri
, ldap_state
->bind_dn
));
955 #ifdef HAVE_LDAP_SET_REBIND_PROC
956 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
957 # if LDAP_SET_REBIND_PROC_ARGS == 2
958 ldap_set_rebind_proc(ldap_struct
, &rebindproc_connect
);
960 # if LDAP_SET_REBIND_PROC_ARGS == 3
961 ldap_set_rebind_proc(ldap_struct
, &rebindproc_connect_with_state
, (void *)ldap_state
);
963 #else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
964 # if LDAP_SET_REBIND_PROC_ARGS == 2
965 ldap_set_rebind_proc(ldap_struct
, &rebindproc
);
967 # if LDAP_SET_REBIND_PROC_ARGS == 3
968 ldap_set_rebind_proc(ldap_struct
, &rebindproc_with_state
, (void *)ldap_state
);
970 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
973 /* When there is an alternative bind callback is set,
974 attempt to use it to perform the bind */
975 if (ldap_state
->bind_callback
!= NULL
) {
976 /* We have to allow bind callback to be run under become_root/unbecome_root
977 to make sure within smbd the callback has proper write access to its resources,
978 like credential cache. This is similar to passdb case where this callback is supposed
979 to be used. When used outside smbd, become_root()/unbecome_root() are no-op.
982 rc
= ldap_state
->bind_callback(ldap_struct
, ldap_state
, ldap_state
->bind_callback_data
);
985 rc
= ldap_simple_bind_s(ldap_struct
, ldap_state
->bind_dn
, ldap_state
->bind_secret
);
988 if (rc
!= LDAP_SUCCESS
) {
989 char *ld_error
= NULL
;
990 ldap_get_option(ldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
992 DEBUG(ldap_state
->num_failures
? 2 : 0,
993 ("failed to bind to server %s with dn=\"%s\" Error: %s\n\t%s\n",
995 ldap_state
->bind_dn
? ldap_state
->bind_dn
: "[Anonymous bind]",
997 ld_error
? ld_error
: "(unknown)"));
999 ldap_state
->num_failures
++;
1003 ldap_state
->num_failures
= 0;
1004 ldap_state
->paged_results
= False
;
1006 ldap_get_option(ldap_state
->ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
1008 if (smbldap_has_control(ldap_state
->ldap_struct
, ADS_PAGE_CTL_OID
) && version
== 3) {
1009 ldap_state
->paged_results
= True
;
1012 DEBUG(3, ("ldap_connect_system: successful connection to the LDAP server\n"));
1013 DEBUGADD(10, ("ldap_connect_system: LDAP server %s support paged results\n",
1014 ldap_state
->paged_results
? "does" : "does not"));
1017 ldap_unbind(ldap_struct
);
1018 ldap_state
->ldap_struct
= NULL
;
1023 static void smbldap_idle_fn(struct tevent_context
*tevent_ctx
,
1024 struct timed_event
*te
,
1025 struct timeval now_abs
,
1026 void *private_data
);
1028 /**********************************************************************
1029 Connect to LDAP server (called before every ldap operation)
1030 *********************************************************************/
1031 static int smbldap_open(struct smbldap_state
*ldap_state
)
1034 bool reopen
= False
;
1035 SMB_ASSERT(ldap_state
);
1037 if ((ldap_state
->ldap_struct
!= NULL
) && ((ldap_state
->last_ping
+ SMBLDAP_DONT_PING_TIME
) < time_mono(NULL
))) {
1039 #ifdef HAVE_UNIXSOCKET
1040 struct sockaddr_un addr
;
1042 struct sockaddr addr
;
1044 socklen_t len
= sizeof(addr
);
1047 opt_rc
= ldap_get_option(ldap_state
->ldap_struct
, LDAP_OPT_DESC
, &sd
);
1048 if (opt_rc
== 0 && (getpeername(sd
, (struct sockaddr
*) &addr
, &len
)) < 0 )
1051 #ifdef HAVE_UNIXSOCKET
1052 if (opt_rc
== 0 && addr
.sun_family
== AF_UNIX
)
1056 /* the other end has died. reopen. */
1057 ldap_unbind(ldap_state
->ldap_struct
);
1058 ldap_state
->ldap_struct
= NULL
;
1059 ldap_state
->last_ping
= (time_t)0;
1061 ldap_state
->last_ping
= time_mono(NULL
);
1065 if (ldap_state
->ldap_struct
!= NULL
) {
1066 DEBUG(11,("smbldap_open: already connected to the LDAP server\n"));
1067 return LDAP_SUCCESS
;
1070 if ((rc
= smbldap_open_connection(ldap_state
))) {
1074 if ((rc
= smbldap_connect_system(ldap_state
))) {
1079 ldap_state
->last_ping
= time_mono(NULL
);
1080 ldap_state
->pid
= getpid();
1082 TALLOC_FREE(ldap_state
->idle_event
);
1084 if (ldap_state
->tevent_context
!= NULL
) {
1085 ldap_state
->idle_event
= tevent_add_timer(
1086 ldap_state
->tevent_context
, ldap_state
,
1087 timeval_current_ofs(SMBLDAP_IDLE_TIME
, 0),
1088 smbldap_idle_fn
, ldap_state
);
1091 DEBUG(4,("The LDAP server is successfully connected\n"));
1093 return LDAP_SUCCESS
;
1096 /**********************************************************************
1097 Disconnect from LDAP server
1098 *********************************************************************/
1099 static NTSTATUS
smbldap_close(struct smbldap_state
*ldap_state
)
1102 return NT_STATUS_INVALID_PARAMETER
;
1104 if (ldap_state
->ldap_struct
!= NULL
) {
1105 ldap_unbind(ldap_state
->ldap_struct
);
1106 ldap_state
->ldap_struct
= NULL
;
1109 smbldap_delete_state(ldap_state
);
1111 TALLOC_FREE(ldap_state
->idle_event
);
1113 DEBUG(5,("The connection to the LDAP server was closed\n"));
1114 /* maybe free the results here --metze */
1116 return NT_STATUS_OK
;
1119 static SIG_ATOMIC_T got_alarm
;
1121 static void gotalarm_sig(int dummy
)
1126 static time_t calc_ldap_abs_endtime(int ldap_to
)
1129 /* No timeout - don't
1135 /* Make the alarm time one second beyond
1136 the timout we're setting for the
1137 remote search timeout, to allow that
1138 to fire in preference. */
1140 return time_mono(NULL
)+ldap_to
+1;
1143 static int end_ldap_local_alarm(time_t absolute_endtime
, int rc
)
1145 if (absolute_endtime
) {
1147 CatchSignal(SIGALRM
, SIG_IGN
);
1149 /* Client timeout error code. */
1151 return LDAP_TIMEOUT
;
1157 static void setup_ldap_local_alarm(struct smbldap_state
*ldap_state
, time_t absolute_endtime
)
1159 time_t now
= time_mono(NULL
);
1161 if (absolute_endtime
) {
1163 CatchSignal(SIGALRM
, gotalarm_sig
);
1164 alarm(absolute_endtime
- now
);
1167 if (ldap_state
->pid
!= getpid()) {
1168 smbldap_close(ldap_state
);
1172 static void get_ldap_errs(struct smbldap_state
*ldap_state
, char **pp_ld_error
, int *p_ld_errno
)
1174 ldap_get_option(ldap_state
->ldap_struct
,
1175 LDAP_OPT_ERROR_NUMBER
, p_ld_errno
);
1177 ldap_get_option(ldap_state
->ldap_struct
,
1178 LDAP_OPT_ERROR_STRING
, pp_ld_error
);
1181 static int get_cached_ldap_connect(struct smbldap_state
*ldap_state
, time_t abs_endtime
)
1189 now
= time_mono(NULL
);
1190 ldap_state
->last_use
= now
;
1192 if (abs_endtime
&& now
> abs_endtime
) {
1193 smbldap_close(ldap_state
);
1194 return LDAP_TIMEOUT
;
1197 rc
= smbldap_open(ldap_state
);
1199 if (rc
== LDAP_SUCCESS
) {
1200 return LDAP_SUCCESS
;
1204 DEBUG(1, ("Connection to LDAP server failed for the "
1205 "%d try!\n", attempts
));
1207 if (rc
== LDAP_INSUFFICIENT_ACCESS
) {
1208 /* The fact that we are non-root or any other
1209 * access-denied condition will not change in the next
1210 * round of trying */
1215 smbldap_close(ldap_state
);
1216 return LDAP_TIMEOUT
;
1222 smbldap_close(ldap_state
);
1223 return LDAP_TIMEOUT
;
1228 /*********************************************************************
1229 ********************************************************************/
1231 static int smbldap_search_ext(struct smbldap_state
*ldap_state
,
1232 const char *base
, int scope
, const char *filter
,
1233 const char *attrs
[], int attrsonly
,
1234 LDAPControl
**sctrls
, LDAPControl
**cctrls
,
1235 int sizelimit
, LDAPMessage
**res
)
1237 int rc
= LDAP_SERVER_DOWN
;
1239 int to
= lp_ldap_timeout();
1240 time_t abs_endtime
= calc_ldap_abs_endtime(to
);
1241 struct timeval timeout
;
1242 struct timeval
*timeout_ptr
= NULL
;
1243 size_t converted_size
;
1245 SMB_ASSERT(ldap_state
);
1247 DEBUG(5,("smbldap_search_ext: base => [%s], filter => [%s], "
1248 "scope => [%d]\n", base
, filter
, scope
));
1250 if (ldap_state
->last_rebind
.tv_sec
> 0) {
1251 struct timeval tval
;
1256 clock_gettime_mono(&ts
);
1257 tval
= convert_timespec_to_timeval(ts
);
1259 tdiff
= usec_time_diff(&tval
, &ldap_state
->last_rebind
);
1260 tdiff
/= 1000; /* Convert to milliseconds. */
1262 sleep_time
= lp_ldap_replication_sleep()-(int)tdiff
;
1263 sleep_time
= MIN(sleep_time
, MAX_LDAP_REPLICATION_SLEEP_TIME
);
1265 if (sleep_time
> 0) {
1266 /* we wait for the LDAP replication */
1267 DEBUG(5,("smbldap_search_ext: waiting %d milliseconds "
1268 "for LDAP replication.\n",sleep_time
));
1269 smb_msleep(sleep_time
);
1270 DEBUG(5,("smbldap_search_ext: go on!\n"));
1272 ZERO_STRUCT(ldap_state
->last_rebind
);
1275 if (!push_utf8_talloc(talloc_tos(), &utf8_filter
, filter
, &converted_size
)) {
1276 return LDAP_NO_MEMORY
;
1279 /* Setup remote timeout for the ldap_search_ext_s call. */
1281 timeout
.tv_sec
= to
;
1282 timeout
.tv_usec
= 0;
1283 timeout_ptr
= &timeout
;
1286 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1289 char *ld_error
= NULL
;
1292 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1293 if (rc
!= LDAP_SUCCESS
) {
1297 rc
= ldap_search_ext_s(ldap_state
->ldap_struct
, base
, scope
,
1299 discard_const_p(char *, attrs
),
1300 attrsonly
, sctrls
, cctrls
, timeout_ptr
,
1302 if (rc
== LDAP_SUCCESS
) {
1306 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1308 DEBUG(10, ("Failed search for base: %s, error: %d (%s) "
1309 "(%s)\n", base
, ld_errno
,
1310 ldap_err2string(rc
),
1311 ld_error
? ld_error
: "unknown"));
1312 SAFE_FREE(ld_error
);
1314 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1317 ldap_unbind(ldap_state
->ldap_struct
);
1318 ldap_state
->ldap_struct
= NULL
;
1321 TALLOC_FREE(utf8_filter
);
1322 return end_ldap_local_alarm(abs_endtime
, rc
);
1325 int smbldap_search(struct smbldap_state
*ldap_state
,
1326 const char *base
, int scope
, const char *filter
,
1327 const char *attrs
[], int attrsonly
,
1330 return smbldap_search_ext(ldap_state
, base
, scope
, filter
, attrs
,
1331 attrsonly
, NULL
, NULL
, LDAP_NO_LIMIT
, res
);
1334 int smbldap_search_paged(struct smbldap_state
*ldap_state
,
1335 const char *base
, int scope
, const char *filter
,
1336 const char **attrs
, int attrsonly
, int pagesize
,
1337 LDAPMessage
**res
, void **cookie
)
1340 LDAPControl
**rcontrols
;
1341 LDAPControl
*controls
[2] = { NULL
, NULL
};
1342 BerElement
*cookie_be
= NULL
;
1343 struct berval
*cookie_bv
= NULL
;
1345 bool critical
= True
;
1349 DEBUG(3,("smbldap_search_paged: base => [%s], filter => [%s],"
1350 "scope => [%d], pagesize => [%d]\n",
1351 base
, filter
, scope
, pagesize
));
1353 cookie_be
= ber_alloc_t(LBER_USE_DER
);
1354 if (cookie_be
== NULL
) {
1355 DEBUG(0,("smbldap_create_page_control: ber_alloc_t returns "
1357 return LDAP_NO_MEMORY
;
1360 /* construct cookie */
1361 if (*cookie
!= NULL
) {
1362 ber_printf(cookie_be
, "{iO}", (ber_int_t
) pagesize
, *cookie
);
1363 ber_bvfree((struct berval
*)*cookie
); /* don't need it from last time */
1366 ber_printf(cookie_be
, "{io}", (ber_int_t
) pagesize
, "", 0);
1368 ber_flatten(cookie_be
, &cookie_bv
);
1370 pr
.ldctl_oid
= discard_const_p(char, ADS_PAGE_CTL_OID
);
1371 pr
.ldctl_iscritical
= (char) critical
;
1372 pr
.ldctl_value
.bv_len
= cookie_bv
->bv_len
;
1373 pr
.ldctl_value
.bv_val
= cookie_bv
->bv_val
;
1378 rc
= smbldap_search_ext(ldap_state
, base
, scope
, filter
, attrs
,
1379 0, controls
, NULL
, LDAP_NO_LIMIT
, res
);
1381 ber_free(cookie_be
, 1);
1382 ber_bvfree(cookie_bv
);
1385 DEBUG(3,("smbldap_search_paged: smbldap_search_ext(%s) "
1386 "failed with [%s]\n", filter
, ldap_err2string(rc
)));
1390 DEBUG(3,("smbldap_search_paged: search was successful\n"));
1392 rc
= ldap_parse_result(ldap_state
->ldap_struct
, *res
, NULL
, NULL
,
1393 NULL
, NULL
, &rcontrols
, 0);
1395 DEBUG(3,("smbldap_search_paged: ldap_parse_result failed " \
1396 "with [%s]\n", ldap_err2string(rc
)));
1400 if (rcontrols
== NULL
)
1403 for (i
=0; rcontrols
[i
]; i
++) {
1405 if (strcmp(ADS_PAGE_CTL_OID
, rcontrols
[i
]->ldctl_oid
) != 0)
1408 cookie_be
= ber_init(&rcontrols
[i
]->ldctl_value
);
1409 ber_scanf(cookie_be
,"{iO}", &tmp
, &cookie_bv
);
1410 /* the berval is the cookie, but must be freed when it is all
1412 if (cookie_bv
->bv_len
)
1413 *cookie
=ber_bvdup(cookie_bv
);
1416 ber_bvfree(cookie_bv
);
1417 ber_free(cookie_be
, 1);
1420 ldap_controls_free(rcontrols
);
1425 int smbldap_modify(struct smbldap_state
*ldap_state
, const char *dn
, LDAPMod
*attrs
[])
1427 int rc
= LDAP_SERVER_DOWN
;
1429 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1430 size_t converted_size
;
1432 SMB_ASSERT(ldap_state
);
1434 DEBUG(5,("smbldap_modify: dn => [%s]\n", dn
));
1436 if (!push_utf8_talloc(talloc_tos(), &utf8_dn
, dn
, &converted_size
)) {
1437 return LDAP_NO_MEMORY
;
1440 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1443 char *ld_error
= NULL
;
1446 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1447 if (rc
!= LDAP_SUCCESS
) {
1451 rc
= ldap_modify_s(ldap_state
->ldap_struct
, utf8_dn
, attrs
);
1452 if (rc
== LDAP_SUCCESS
) {
1456 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1458 DEBUG(10, ("Failed to modify dn: %s, error: %d (%s) "
1459 "(%s)\n", dn
, ld_errno
,
1460 ldap_err2string(rc
),
1461 ld_error
? ld_error
: "unknown"));
1462 SAFE_FREE(ld_error
);
1464 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1467 ldap_unbind(ldap_state
->ldap_struct
);
1468 ldap_state
->ldap_struct
= NULL
;
1471 TALLOC_FREE(utf8_dn
);
1472 return end_ldap_local_alarm(abs_endtime
, rc
);
1475 int smbldap_add(struct smbldap_state
*ldap_state
, const char *dn
, LDAPMod
*attrs
[])
1477 int rc
= LDAP_SERVER_DOWN
;
1479 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1480 size_t converted_size
;
1482 SMB_ASSERT(ldap_state
);
1484 DEBUG(5,("smbldap_add: dn => [%s]\n", dn
));
1486 if (!push_utf8_talloc(talloc_tos(), &utf8_dn
, dn
, &converted_size
)) {
1487 return LDAP_NO_MEMORY
;
1490 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1493 char *ld_error
= NULL
;
1496 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1497 if (rc
!= LDAP_SUCCESS
) {
1501 rc
= ldap_add_s(ldap_state
->ldap_struct
, utf8_dn
, attrs
);
1502 if (rc
== LDAP_SUCCESS
) {
1506 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1508 DEBUG(10, ("Failed to add dn: %s, error: %d (%s) "
1509 "(%s)\n", dn
, ld_errno
,
1510 ldap_err2string(rc
),
1511 ld_error
? ld_error
: "unknown"));
1512 SAFE_FREE(ld_error
);
1514 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1517 ldap_unbind(ldap_state
->ldap_struct
);
1518 ldap_state
->ldap_struct
= NULL
;
1521 TALLOC_FREE(utf8_dn
);
1522 return end_ldap_local_alarm(abs_endtime
, rc
);
1525 int smbldap_delete(struct smbldap_state
*ldap_state
, const char *dn
)
1527 int rc
= LDAP_SERVER_DOWN
;
1529 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1530 size_t converted_size
;
1532 SMB_ASSERT(ldap_state
);
1534 DEBUG(5,("smbldap_delete: dn => [%s]\n", dn
));
1536 if (!push_utf8_talloc(talloc_tos(), &utf8_dn
, dn
, &converted_size
)) {
1537 return LDAP_NO_MEMORY
;
1540 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1543 char *ld_error
= NULL
;
1546 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1547 if (rc
!= LDAP_SUCCESS
) {
1551 rc
= ldap_delete_s(ldap_state
->ldap_struct
, utf8_dn
);
1552 if (rc
== LDAP_SUCCESS
) {
1556 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1558 DEBUG(10, ("Failed to delete dn: %s, error: %d (%s) "
1559 "(%s)\n", dn
, ld_errno
,
1560 ldap_err2string(rc
),
1561 ld_error
? ld_error
: "unknown"));
1562 SAFE_FREE(ld_error
);
1564 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1567 ldap_unbind(ldap_state
->ldap_struct
);
1568 ldap_state
->ldap_struct
= NULL
;
1571 TALLOC_FREE(utf8_dn
);
1572 return end_ldap_local_alarm(abs_endtime
, rc
);
1575 int smbldap_extended_operation(struct smbldap_state
*ldap_state
,
1576 LDAP_CONST
char *reqoid
, struct berval
*reqdata
,
1577 LDAPControl
**serverctrls
, LDAPControl
**clientctrls
,
1578 char **retoidp
, struct berval
**retdatap
)
1580 int rc
= LDAP_SERVER_DOWN
;
1581 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1586 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1589 char *ld_error
= NULL
;
1592 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1593 if (rc
!= LDAP_SUCCESS
) {
1597 rc
= ldap_extended_operation_s(ldap_state
->ldap_struct
, reqoid
,
1598 reqdata
, serverctrls
,
1599 clientctrls
, retoidp
, retdatap
);
1600 if (rc
== LDAP_SUCCESS
) {
1604 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1606 DEBUG(10, ("Extended operation failed with error: "
1607 "%d (%s) (%s)\n", ld_errno
,
1608 ldap_err2string(rc
),
1609 ld_error
? ld_error
: "unknown"));
1610 SAFE_FREE(ld_error
);
1612 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1615 ldap_unbind(ldap_state
->ldap_struct
);
1616 ldap_state
->ldap_struct
= NULL
;
1619 return end_ldap_local_alarm(abs_endtime
, rc
);
1622 /*******************************************************************
1623 run the search by name.
1624 ******************************************************************/
1625 int smbldap_search_suffix (struct smbldap_state
*ldap_state
,
1626 const char *filter
, const char **search_attr
,
1627 LDAPMessage
** result
)
1629 return smbldap_search(ldap_state
, lp_ldap_suffix(), LDAP_SCOPE_SUBTREE
,
1630 filter
, search_attr
, 0, result
);
1633 static void smbldap_idle_fn(struct tevent_context
*tevent_ctx
,
1634 struct timed_event
*te
,
1635 struct timeval now_abs
,
1638 struct smbldap_state
*state
= (struct smbldap_state
*)private_data
;
1640 TALLOC_FREE(state
->idle_event
);
1642 if (state
->ldap_struct
== NULL
) {
1643 DEBUG(10,("ldap connection not connected...\n"));
1647 if ((state
->last_use
+SMBLDAP_IDLE_TIME
) > time_mono(NULL
)) {
1648 DEBUG(10,("ldap connection not idle...\n"));
1650 /* this needs to be made monotonic clock aware inside tevent: */
1651 state
->idle_event
= tevent_add_timer(
1653 timeval_add(&now_abs
, SMBLDAP_IDLE_TIME
, 0),
1659 DEBUG(7,("ldap connection idle...closing connection\n"));
1660 smbldap_close(state
);
1663 /**********************************************************************
1665 *********************************************************************/
1667 void smbldap_free_struct(struct smbldap_state
**ldap_state
)
1669 smbldap_close(*ldap_state
);
1671 if ((*ldap_state
)->bind_secret
) {
1672 memset((*ldap_state
)->bind_secret
, '\0', strlen((*ldap_state
)->bind_secret
));
1675 SAFE_FREE((*ldap_state
)->bind_dn
);
1676 SAFE_FREE((*ldap_state
)->bind_secret
);
1677 (*ldap_state
)->bind_callback
= NULL
;
1678 (*ldap_state
)->bind_callback_data
= NULL
;
1680 TALLOC_FREE(*ldap_state
);
1682 /* No need to free any further, as it is talloc()ed */
1685 static int smbldap_state_destructor(struct smbldap_state
*state
)
1687 smbldap_free_struct(&state
);
1692 /**********************************************************************
1693 Intitalise the 'general' ldap structures, on which ldap operations may be conducted
1694 *********************************************************************/
1696 NTSTATUS
smbldap_init(TALLOC_CTX
*mem_ctx
, struct tevent_context
*tevent_ctx
,
1697 const char *location
,
1699 const char *bind_dn
,
1700 const char *bind_secret
,
1701 struct smbldap_state
**smbldap_state
)
1703 *smbldap_state
= talloc_zero(mem_ctx
, struct smbldap_state
);
1704 if (!*smbldap_state
) {
1705 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
1706 return NT_STATUS_NO_MEMORY
;
1710 (*smbldap_state
)->uri
= talloc_strdup(mem_ctx
, location
);
1712 (*smbldap_state
)->uri
= "ldap://localhost";
1715 (*smbldap_state
)->tevent_context
= tevent_ctx
;
1717 if (bind_dn
&& bind_secret
) {
1718 smbldap_set_creds(*smbldap_state
, anon
, bind_dn
, bind_secret
);
1721 talloc_set_destructor(*smbldap_state
, smbldap_state_destructor
);
1722 return NT_STATUS_OK
;
1725 char *smbldap_talloc_dn(TALLOC_CTX
*mem_ctx
, LDAP
*ld
,
1728 char *utf8_dn
, *unix_dn
;
1729 size_t converted_size
;
1731 utf8_dn
= ldap_get_dn(ld
, entry
);
1733 DEBUG (5, ("smbldap_talloc_dn: ldap_get_dn failed\n"));
1736 if (!pull_utf8_talloc(mem_ctx
, &unix_dn
, utf8_dn
, &converted_size
)) {
1737 DEBUG (0, ("smbldap_talloc_dn: String conversion failure utf8 "
1738 "[%s]\n", utf8_dn
));
1741 ldap_memfree(utf8_dn
);
1745 /*******************************************************************
1746 Check if root-dse has a certain Control or Extension
1747 ********************************************************************/
1749 static bool smbldap_check_root_dse(LDAP
*ld
, const char **attrs
, const char *value
)
1751 LDAPMessage
*msg
= NULL
;
1752 LDAPMessage
*entry
= NULL
;
1753 char **values
= NULL
;
1754 int rc
, num_result
, num_values
, i
;
1755 bool result
= False
;
1758 DEBUG(3,("smbldap_check_root_dse: nothing to look for\n"));
1762 if (!strequal(attrs
[0], "supportedExtension") &&
1763 !strequal(attrs
[0], "supportedControl") &&
1764 !strequal(attrs
[0], "namingContexts")) {
1765 DEBUG(3,("smbldap_check_root_dse: no idea what to query root-dse for: %s ?\n", attrs
[0]));
1769 rc
= ldap_search_s(ld
, "", LDAP_SCOPE_BASE
,
1770 "(objectclass=*)", discard_const_p(char *, attrs
), 0 , &msg
);
1772 if (rc
!= LDAP_SUCCESS
) {
1773 DEBUG(3,("smbldap_check_root_dse: Could not search rootDSE\n"));
1777 num_result
= ldap_count_entries(ld
, msg
);
1779 if (num_result
!= 1) {
1780 DEBUG(3,("smbldap_check_root_dse: Expected one rootDSE, got %d\n", num_result
));
1784 entry
= ldap_first_entry(ld
, msg
);
1786 if (entry
== NULL
) {
1787 DEBUG(3,("smbldap_check_root_dse: Could not retrieve rootDSE\n"));
1791 values
= ldap_get_values(ld
, entry
, attrs
[0]);
1793 if (values
== NULL
) {
1794 DEBUG(5,("smbldap_check_root_dse: LDAP Server does not support any %s\n", attrs
[0]));
1798 num_values
= ldap_count_values(values
);
1800 if (num_values
== 0) {
1801 DEBUG(5,("smbldap_check_root_dse: LDAP Server does not have any %s\n", attrs
[0]));
1805 for (i
=0; i
<num_values
; i
++) {
1806 if (strcmp(values
[i
], value
) == 0)
1813 ldap_value_free(values
);
1821 /*******************************************************************
1822 Check if LDAP-Server supports a certain Control (OID in string format)
1823 ********************************************************************/
1825 bool smbldap_has_control(LDAP
*ld
, const char *control
)
1827 const char *attrs
[] = { "supportedControl", NULL
};
1828 return smbldap_check_root_dse(ld
, attrs
, control
);
1831 /*******************************************************************
1832 Check if LDAP-Server supports a certain Extension (OID in string format)
1833 ********************************************************************/
1835 bool smbldap_has_extension(LDAP
*ld
, const char *extension
)
1837 const char *attrs
[] = { "supportedExtension", NULL
};
1838 return smbldap_check_root_dse(ld
, attrs
, extension
);
1841 /*******************************************************************
1842 Check if LDAP-Server holds a given namingContext
1843 ********************************************************************/
1845 bool smbldap_has_naming_context(LDAP
*ld
, const char *naming_context
)
1847 const char *attrs
[] = { "namingContexts", NULL
};
1848 return smbldap_check_root_dse(ld
, attrs
, naming_context
);
1851 bool smbldap_set_creds(struct smbldap_state
*ldap_state
, bool anon
, const char *dn
, const char *secret
)
1853 ldap_state
->anonymous
= anon
;
1855 /* free any previously set credential */
1857 SAFE_FREE(ldap_state
->bind_dn
);
1858 ldap_state
->bind_callback
= NULL
;
1859 ldap_state
->bind_callback_data
= NULL
;
1861 if (ldap_state
->bind_secret
) {
1862 /* make sure secrets are zeroed out of memory */
1863 memset(ldap_state
->bind_secret
, '\0', strlen(ldap_state
->bind_secret
));
1864 SAFE_FREE(ldap_state
->bind_secret
);
1868 ldap_state
->bind_dn
= SMB_STRDUP(dn
);
1869 ldap_state
->bind_secret
= SMB_STRDUP(secret
);