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 (attribute
== NULL
) {
415 /* This can actually happen for ldapsam_compat where we for
416 * example don't have a password history */
420 if (existing
!= NULL
) {
421 if (op
& LDAP_MOD_BVALUES
) {
422 existed
= smbldap_talloc_single_blob(talloc_tos(), ldap_struct
, existing
, attribute
, &oldblob
);
424 existed
= smbldap_get_single_attribute(ldap_struct
, existing
, attribute
, oldval
, sizeof(oldval
));
433 if (op
& LDAP_MOD_BVALUES
) {
434 equal
= (newblob
&& (data_blob_cmp(&oldblob
, newblob
) == 0));
436 /* all of our string attributes are case insensitive */
437 equal
= (newval
&& (strcasecmp_m(oldval
, newval
) == 0));
441 /* Believe it or not, but LDAP will deny a delete and
442 an add at the same time if the values are the
444 DEBUG(10,("smbldap_make_mod: attribute |%s| not changed.\n", attribute
));
448 /* There has been no value before, so don't delete it.
449 * Here's a possible race: We might end up with
450 * duplicate attributes */
451 /* By deleting exactly the value we found in the entry this
452 * should be race-free in the sense that the LDAP-Server will
453 * deny the complete operation if somebody changed the
454 * attribute behind our back. */
455 /* This will also allow modifying single valued attributes
456 * in Novell NDS. In NDS you have to first remove attribute and then
457 * you could add new value */
459 if (op
& LDAP_MOD_BVALUES
) {
460 DEBUG(10,("smbldap_make_mod: deleting attribute |%s| blob\n", attribute
));
461 smbldap_set_mod_blob(mods
, LDAP_MOD_DELETE
, attribute
, &oldblob
);
463 DEBUG(10,("smbldap_make_mod: deleting attribute |%s| values |%s|\n", attribute
, oldval
));
464 smbldap_set_mod(mods
, LDAP_MOD_DELETE
, attribute
, oldval
);
468 /* Regardless of the real operation (add or modify)
469 we add the new value here. We rely on deleting
470 the old value, should it exist. */
472 if (op
& LDAP_MOD_BVALUES
) {
473 if (newblob
&& newblob
->length
) {
474 DEBUG(10,("smbldap_make_mod: adding attribute |%s| blob\n", attribute
));
475 smbldap_set_mod_blob(mods
, LDAP_MOD_ADD
, attribute
, newblob
);
478 if ((newval
!= NULL
) && (strlen(newval
) > 0)) {
479 DEBUG(10,("smbldap_make_mod: adding attribute |%s| value |%s|\n", attribute
, newval
));
480 smbldap_set_mod(mods
, LDAP_MOD_ADD
, attribute
, newval
);
485 void smbldap_make_mod(LDAP
*ldap_struct
, LDAPMessage
*existing
,
487 const char *attribute
, const char *newval
)
489 smbldap_make_mod_internal(ldap_struct
, existing
, mods
, attribute
,
493 void smbldap_make_mod_blob(LDAP
*ldap_struct
, LDAPMessage
*existing
,
495 const char *attribute
, const DATA_BLOB
*newblob
)
497 smbldap_make_mod_internal(ldap_struct
, existing
, mods
, attribute
,
498 LDAP_MOD_BVALUES
, NULL
, newblob
);
501 /**********************************************************************
502 Some varients of the LDAP rebind code do not pass in the third 'arg'
503 pointer to a void*, so we try and work around it by assuming that the
504 value of the 'LDAP *' pointer is the same as the one we had passed in
505 **********************************************************************/
507 struct smbldap_state_lookup
{
509 struct smbldap_state
*smbldap_state
;
510 struct smbldap_state_lookup
*prev
, *next
;
513 static struct smbldap_state_lookup
*smbldap_state_lookup_list
;
515 static struct smbldap_state
*smbldap_find_state(LDAP
*ld
)
517 struct smbldap_state_lookup
*t
;
519 for (t
= smbldap_state_lookup_list
; t
; t
= t
->next
) {
521 return t
->smbldap_state
;
527 static void smbldap_delete_state(struct smbldap_state
*smbldap_state
)
529 struct smbldap_state_lookup
*t
;
531 for (t
= smbldap_state_lookup_list
; t
; t
= t
->next
) {
532 if (t
->smbldap_state
== smbldap_state
) {
533 DLIST_REMOVE(smbldap_state_lookup_list
, t
);
540 static void smbldap_store_state(LDAP
*ld
, struct smbldap_state
*smbldap_state
)
542 struct smbldap_state
*tmp_ldap_state
;
543 struct smbldap_state_lookup
*t
;
545 if ((tmp_ldap_state
= smbldap_find_state(ld
))) {
546 SMB_ASSERT(tmp_ldap_state
== smbldap_state
);
550 t
= SMB_XMALLOC_P(struct smbldap_state_lookup
);
553 DLIST_ADD_END(smbldap_state_lookup_list
, t
, struct smbldap_state_lookup
*);
555 t
->smbldap_state
= smbldap_state
;
558 /********************************************************************
559 start TLS on an existing LDAP connection
560 *******************************************************************/
562 int smb_ldap_start_tls(LDAP
*ldap_struct
, int version
)
564 #ifdef LDAP_OPT_X_TLS
568 if (lp_ldap_ssl() != LDAP_SSL_START_TLS
) {
572 #ifdef LDAP_OPT_X_TLS
573 if (version
!= LDAP_VERSION3
) {
574 DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
575 return LDAP_OPERATIONS_ERROR
;
578 if ((rc
= ldap_start_tls_s (ldap_struct
, NULL
, NULL
)) != LDAP_SUCCESS
) {
579 DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
580 ldap_err2string(rc
)));
584 DEBUG (3, ("StartTLS issued: using a TLS connection\n"));
587 DEBUG(0,("StartTLS not supported by LDAP client libraries!\n"));
588 return LDAP_OPERATIONS_ERROR
;
592 /********************************************************************
593 setup a connection to the LDAP server based on a uri
594 *******************************************************************/
596 static int smb_ldap_setup_conn(LDAP
**ldap_struct
, const char *uri
)
600 DEBUG(10, ("smb_ldap_setup_connection: %s\n", uri
));
602 #ifdef HAVE_LDAP_INITIALIZE
604 rc
= ldap_initialize(ldap_struct
, uri
);
606 DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc
)));
610 if (lp_ldap_follow_referral() != Auto
) {
611 rc
= ldap_set_option(*ldap_struct
, LDAP_OPT_REFERRALS
,
612 lp_ldap_follow_referral() ? LDAP_OPT_ON
: LDAP_OPT_OFF
);
613 if (rc
!= LDAP_SUCCESS
)
614 DEBUG(0, ("Failed to set LDAP_OPT_REFERRALS: %s\n",
615 ldap_err2string(rc
)));
621 /* Parse the string manually */
627 SMB_ASSERT(sizeof(protocol
)>10 && sizeof(host
)>254);
630 /* skip leading "URL:" (if any) */
631 if ( strnequal( uri
, "URL:", 4 ) ) {
635 sscanf(uri
, "%10[^:]://%254[^:/]:%d", protocol
, host
, &port
);
638 if (strequal(protocol
, "ldap")) {
640 } else if (strequal(protocol
, "ldaps")) {
643 DEBUG(0, ("unrecognised protocol (%s)!\n", protocol
));
647 if ((*ldap_struct
= ldap_init(host
, port
)) == NULL
) {
648 DEBUG(0, ("ldap_init failed !\n"));
649 return LDAP_OPERATIONS_ERROR
;
652 if (strequal(protocol
, "ldaps")) {
653 #ifdef LDAP_OPT_X_TLS
654 int tls
= LDAP_OPT_X_TLS_HARD
;
655 if (ldap_set_option (*ldap_struct
, LDAP_OPT_X_TLS
, &tls
) != LDAP_SUCCESS
)
657 DEBUG(0, ("Failed to setup a TLS session\n"));
660 DEBUG(3,("LDAPS option set...!\n"));
662 DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));
663 return LDAP_OPERATIONS_ERROR
;
664 #endif /* LDAP_OPT_X_TLS */
667 #endif /* HAVE_LDAP_INITIALIZE */
669 /* now set connection timeout */
670 #ifdef LDAP_X_OPT_CONNECT_TIMEOUT /* Netscape */
672 int ct
= lp_ldap_connection_timeout()*1000;
673 rc
= ldap_set_option(*ldap_struct
, LDAP_X_OPT_CONNECT_TIMEOUT
, &ct
);
674 if (rc
!= LDAP_SUCCESS
) {
675 DEBUG(0,("Failed to setup an ldap connection timeout %d: %s\n",
676 ct
, ldap_err2string(rc
)));
679 #elif defined (LDAP_OPT_NETWORK_TIMEOUT) /* OpenLDAP */
683 ct
.tv_sec
= lp_ldap_connection_timeout();
684 rc
= ldap_set_option(*ldap_struct
, LDAP_OPT_NETWORK_TIMEOUT
, &ct
);
685 if (rc
!= LDAP_SUCCESS
) {
686 DEBUG(0,("Failed to setup an ldap connection timeout %d: %s\n",
687 (int)ct
.tv_sec
, ldap_err2string(rc
)));
695 /********************************************************************
696 try to upgrade to Version 3 LDAP if not already, in either case return current
698 *******************************************************************/
700 static int smb_ldap_upgrade_conn(LDAP
*ldap_struct
, int *new_version
)
705 /* assume the worst */
706 *new_version
= LDAP_VERSION2
;
708 rc
= ldap_get_option(ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
713 if (version
== LDAP_VERSION3
) {
714 *new_version
= LDAP_VERSION3
;
719 version
= LDAP_VERSION3
;
720 rc
= ldap_set_option (ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
725 *new_version
= LDAP_VERSION3
;
729 /*******************************************************************
730 open a connection to the ldap server (just until the bind)
731 ******************************************************************/
733 int smb_ldap_setup_full_conn(LDAP
**ldap_struct
, const char *uri
)
737 rc
= smb_ldap_setup_conn(ldap_struct
, uri
);
742 rc
= smb_ldap_upgrade_conn(*ldap_struct
, &version
);
747 rc
= smb_ldap_start_tls(*ldap_struct
, version
);
755 /*******************************************************************
756 open a connection to the ldap server.
757 ******************************************************************/
758 static int smbldap_open_connection (struct smbldap_state
*ldap_state
)
761 int rc
= LDAP_SUCCESS
;
764 LDAP
**ldap_struct
= &ldap_state
->ldap_struct
;
766 rc
= smb_ldap_setup_conn(ldap_struct
, ldap_state
->uri
);
771 /* Store the LDAP pointer in a lookup list */
773 smbldap_store_state(*ldap_struct
, ldap_state
);
775 /* Upgrade to LDAPv3 if possible */
777 rc
= smb_ldap_upgrade_conn(*ldap_struct
, &version
);
782 /* Start TLS if required */
784 rc
= smb_ldap_start_tls(*ldap_struct
, version
);
789 /* Set alias dereferencing method */
790 deref
= lp_ldap_deref();
792 if (ldap_set_option (*ldap_struct
, LDAP_OPT_DEREF
, &deref
) != LDAP_OPT_SUCCESS
) {
793 DEBUG(1,("smbldap_open_connection: Failed to set dereferencing method: %d\n", deref
));
795 DEBUG(5,("Set dereferencing method: %d\n", deref
));
799 DEBUG(2, ("smbldap_open_connection: connection opened\n"));
803 /*******************************************************************
804 a rebind function for authenticated referrals
805 This version takes a void* that we can shove useful stuff in :-)
806 ******************************************************************/
807 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
809 static int rebindproc_with_state (LDAP
* ld
, char **whop
, char **credp
,
810 int *methodp
, int freeit
, void *arg
)
812 struct smbldap_state
*ldap_state
= arg
;
815 /** @TODO Should we be doing something to check what servers we rebind to?
816 Could we get a referral to a machine that we don't want to give our
817 username and password to? */
822 memset(*credp
, '\0', strlen(*credp
));
826 DEBUG(5,("rebind_proc_with_state: Rebinding as \"%s\"\n",
827 ldap_state
->bind_dn
?ldap_state
->bind_dn
:"[Anonymous bind]"));
829 if (ldap_state
->anonymous
) {
833 *whop
= SMB_STRDUP(ldap_state
->bind_dn
);
835 return LDAP_NO_MEMORY
;
837 *credp
= SMB_STRDUP(ldap_state
->bind_secret
);
840 return LDAP_NO_MEMORY
;
843 *methodp
= LDAP_AUTH_SIMPLE
;
846 clock_gettime_mono(&ts
);
847 ldap_state
->last_rebind
= convert_timespec_to_timeval(ts
);
851 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
853 /*******************************************************************
854 a rebind function for authenticated referrals
855 This version takes a void* that we can shove useful stuff in :-)
856 and actually does the connection.
857 ******************************************************************/
858 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
859 static int rebindproc_connect_with_state (LDAP
*ldap_struct
,
860 LDAP_CONST
char *url
,
862 ber_int_t msgid
, void *arg
)
864 struct smbldap_state
*ldap_state
=
865 (struct smbldap_state
*)arg
;
870 DEBUG(5,("rebindproc_connect_with_state: Rebinding to %s as \"%s\"\n",
871 url
, ldap_state
->bind_dn
?ldap_state
->bind_dn
:"[Anonymous bind]"));
873 /* call START_TLS again (ldaps:// is handled by the OpenLDAP library
874 * itself) before rebinding to another LDAP server to avoid to expose
875 * our credentials. At least *try* to secure the connection - Guenther */
877 smb_ldap_upgrade_conn(ldap_struct
, &version
);
878 smb_ldap_start_tls(ldap_struct
, version
);
880 /** @TODO Should we be doing something to check what servers we rebind to?
881 Could we get a referral to a machine that we don't want to give our
882 username and password to? */
884 rc
= ldap_simple_bind_s(ldap_struct
, ldap_state
->bind_dn
, ldap_state
->bind_secret
);
886 /* only set the last rebind timestamp when we did rebind after a
887 * non-read LDAP operation. That way we avoid the replication sleep
888 * after a simple redirected search operation - Guenther */
892 case LDAP_REQ_MODIFY
:
894 case LDAP_REQ_DELETE
:
896 case LDAP_REQ_EXTENDED
:
897 DEBUG(10,("rebindproc_connect_with_state: "
898 "setting last_rebind timestamp "
899 "(req: 0x%02x)\n", (unsigned int)request
));
900 clock_gettime_mono(&ts
);
901 ldap_state
->last_rebind
= convert_timespec_to_timeval(ts
);
904 ZERO_STRUCT(ldap_state
->last_rebind
);
910 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
912 /*******************************************************************
913 Add a rebind function for authenticated referrals
914 ******************************************************************/
915 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
917 # if LDAP_SET_REBIND_PROC_ARGS == 2
918 static int rebindproc (LDAP
*ldap_struct
, char **whop
, char **credp
,
919 int *method
, int freeit
)
921 struct smbldap_state
*ldap_state
= smbldap_find_state(ldap_struct
);
923 return rebindproc_with_state(ldap_struct
, whop
, credp
,
924 method
, freeit
, ldap_state
);
926 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
927 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
929 /*******************************************************************
930 a rebind function for authenticated referrals
931 this also does the connection, but no void*.
932 ******************************************************************/
933 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
934 # if LDAP_SET_REBIND_PROC_ARGS == 2
935 static int rebindproc_connect (LDAP
* ld
, LDAP_CONST
char *url
, int request
,
938 struct smbldap_state
*ldap_state
= smbldap_find_state(ld
);
940 return rebindproc_connect_with_state(ld
, url
, (ber_tag_t
)request
, msgid
,
943 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
944 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
946 /*******************************************************************
947 connect to the ldap server under system privilege.
948 ******************************************************************/
949 static int smbldap_connect_system(struct smbldap_state
*ldap_state
)
951 LDAP
*ldap_struct
= ldap_state
->ldap_struct
;
955 /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
956 (OpenLDAP) doesnt' seem to support it */
958 DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n",
959 ldap_state
->uri
, ldap_state
->bind_dn
));
961 #ifdef HAVE_LDAP_SET_REBIND_PROC
962 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
963 # if LDAP_SET_REBIND_PROC_ARGS == 2
964 ldap_set_rebind_proc(ldap_struct
, &rebindproc_connect
);
966 # if LDAP_SET_REBIND_PROC_ARGS == 3
967 ldap_set_rebind_proc(ldap_struct
, &rebindproc_connect_with_state
, (void *)ldap_state
);
969 #else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
970 # if LDAP_SET_REBIND_PROC_ARGS == 2
971 ldap_set_rebind_proc(ldap_struct
, &rebindproc
);
973 # if LDAP_SET_REBIND_PROC_ARGS == 3
974 ldap_set_rebind_proc(ldap_struct
, &rebindproc_with_state
, (void *)ldap_state
);
976 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
979 /* When there is an alternative bind callback is set,
980 attempt to use it to perform the bind */
981 if (ldap_state
->bind_callback
!= NULL
) {
982 /* We have to allow bind callback to be run under become_root/unbecome_root
983 to make sure within smbd the callback has proper write access to its resources,
984 like credential cache. This is similar to passdb case where this callback is supposed
985 to be used. When used outside smbd, become_root()/unbecome_root() are no-op.
988 rc
= ldap_state
->bind_callback(ldap_struct
, ldap_state
, ldap_state
->bind_callback_data
);
991 rc
= ldap_simple_bind_s(ldap_struct
, ldap_state
->bind_dn
, ldap_state
->bind_secret
);
994 if (rc
!= LDAP_SUCCESS
) {
995 char *ld_error
= NULL
;
996 ldap_get_option(ldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
998 DEBUG(ldap_state
->num_failures
? 2 : 0,
999 ("failed to bind to server %s with dn=\"%s\" Error: %s\n\t%s\n",
1001 ldap_state
->bind_dn
? ldap_state
->bind_dn
: "[Anonymous bind]",
1002 ldap_err2string(rc
),
1003 ld_error
? ld_error
: "(unknown)"));
1004 SAFE_FREE(ld_error
);
1005 ldap_state
->num_failures
++;
1009 ldap_state
->num_failures
= 0;
1010 ldap_state
->paged_results
= False
;
1012 ldap_get_option(ldap_state
->ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
1014 if (smbldap_has_control(ldap_state
->ldap_struct
, ADS_PAGE_CTL_OID
) && version
== 3) {
1015 ldap_state
->paged_results
= True
;
1018 DEBUG(3, ("ldap_connect_system: successful connection to the LDAP server\n"));
1019 DEBUGADD(10, ("ldap_connect_system: LDAP server %s support paged results\n",
1020 ldap_state
->paged_results
? "does" : "does not"));
1023 ldap_unbind(ldap_struct
);
1024 ldap_state
->ldap_struct
= NULL
;
1029 static void smbldap_idle_fn(struct tevent_context
*tevent_ctx
,
1030 struct timed_event
*te
,
1031 struct timeval now_abs
,
1032 void *private_data
);
1034 /**********************************************************************
1035 Connect to LDAP server (called before every ldap operation)
1036 *********************************************************************/
1037 static int smbldap_open(struct smbldap_state
*ldap_state
)
1040 bool reopen
= False
;
1041 SMB_ASSERT(ldap_state
);
1043 if ((ldap_state
->ldap_struct
!= NULL
) && ((ldap_state
->last_ping
+ SMBLDAP_DONT_PING_TIME
) < time_mono(NULL
))) {
1045 #ifdef HAVE_UNIXSOCKET
1046 struct sockaddr_un addr
;
1048 struct sockaddr addr
;
1050 socklen_t len
= sizeof(addr
);
1053 opt_rc
= ldap_get_option(ldap_state
->ldap_struct
, LDAP_OPT_DESC
, &sd
);
1054 if (opt_rc
== 0 && (getpeername(sd
, (struct sockaddr
*) &addr
, &len
)) < 0 )
1057 #ifdef HAVE_UNIXSOCKET
1058 if (opt_rc
== 0 && addr
.sun_family
== AF_UNIX
)
1062 /* the other end has died. reopen. */
1063 ldap_unbind(ldap_state
->ldap_struct
);
1064 ldap_state
->ldap_struct
= NULL
;
1065 ldap_state
->last_ping
= (time_t)0;
1067 ldap_state
->last_ping
= time_mono(NULL
);
1071 if (ldap_state
->ldap_struct
!= NULL
) {
1072 DEBUG(11,("smbldap_open: already connected to the LDAP server\n"));
1073 return LDAP_SUCCESS
;
1076 if ((rc
= smbldap_open_connection(ldap_state
))) {
1080 if ((rc
= smbldap_connect_system(ldap_state
))) {
1085 ldap_state
->last_ping
= time_mono(NULL
);
1086 ldap_state
->pid
= getpid();
1088 TALLOC_FREE(ldap_state
->idle_event
);
1090 if (ldap_state
->tevent_context
!= NULL
) {
1091 ldap_state
->idle_event
= tevent_add_timer(
1092 ldap_state
->tevent_context
, ldap_state
,
1093 timeval_current_ofs(SMBLDAP_IDLE_TIME
, 0),
1094 smbldap_idle_fn
, ldap_state
);
1097 DEBUG(4,("The LDAP server is successfully connected\n"));
1099 return LDAP_SUCCESS
;
1102 /**********************************************************************
1103 Disconnect from LDAP server
1104 *********************************************************************/
1105 static NTSTATUS
smbldap_close(struct smbldap_state
*ldap_state
)
1108 return NT_STATUS_INVALID_PARAMETER
;
1110 if (ldap_state
->ldap_struct
!= NULL
) {
1111 ldap_unbind(ldap_state
->ldap_struct
);
1112 ldap_state
->ldap_struct
= NULL
;
1115 smbldap_delete_state(ldap_state
);
1117 TALLOC_FREE(ldap_state
->idle_event
);
1119 DEBUG(5,("The connection to the LDAP server was closed\n"));
1120 /* maybe free the results here --metze */
1122 return NT_STATUS_OK
;
1125 static SIG_ATOMIC_T got_alarm
;
1127 static void gotalarm_sig(int dummy
)
1132 static time_t calc_ldap_abs_endtime(int ldap_to
)
1135 /* No timeout - don't
1141 /* Make the alarm time one second beyond
1142 the timout we're setting for the
1143 remote search timeout, to allow that
1144 to fire in preference. */
1146 return time_mono(NULL
)+ldap_to
+1;
1149 static int end_ldap_local_alarm(time_t absolute_endtime
, int rc
)
1151 if (absolute_endtime
) {
1153 CatchSignal(SIGALRM
, SIG_IGN
);
1155 /* Client timeout error code. */
1157 return LDAP_TIMEOUT
;
1163 static void setup_ldap_local_alarm(struct smbldap_state
*ldap_state
, time_t absolute_endtime
)
1165 time_t now
= time_mono(NULL
);
1167 if (absolute_endtime
) {
1169 CatchSignal(SIGALRM
, gotalarm_sig
);
1170 alarm(absolute_endtime
- now
);
1173 if (ldap_state
->pid
!= getpid()) {
1174 smbldap_close(ldap_state
);
1178 static void get_ldap_errs(struct smbldap_state
*ldap_state
, char **pp_ld_error
, int *p_ld_errno
)
1180 ldap_get_option(ldap_state
->ldap_struct
,
1181 LDAP_OPT_ERROR_NUMBER
, p_ld_errno
);
1183 ldap_get_option(ldap_state
->ldap_struct
,
1184 LDAP_OPT_ERROR_STRING
, pp_ld_error
);
1187 static int get_cached_ldap_connect(struct smbldap_state
*ldap_state
, time_t abs_endtime
)
1195 now
= time_mono(NULL
);
1196 ldap_state
->last_use
= now
;
1198 if (abs_endtime
&& now
> abs_endtime
) {
1199 smbldap_close(ldap_state
);
1200 return LDAP_TIMEOUT
;
1203 rc
= smbldap_open(ldap_state
);
1205 if (rc
== LDAP_SUCCESS
) {
1206 return LDAP_SUCCESS
;
1210 DEBUG(1, ("Connection to LDAP server failed for the "
1211 "%d try!\n", attempts
));
1213 if (rc
== LDAP_INSUFFICIENT_ACCESS
) {
1214 /* The fact that we are non-root or any other
1215 * access-denied condition will not change in the next
1216 * round of trying */
1221 smbldap_close(ldap_state
);
1222 return LDAP_TIMEOUT
;
1228 smbldap_close(ldap_state
);
1229 return LDAP_TIMEOUT
;
1234 /*********************************************************************
1235 ********************************************************************/
1237 static int smbldap_search_ext(struct smbldap_state
*ldap_state
,
1238 const char *base
, int scope
, const char *filter
,
1239 const char *attrs
[], int attrsonly
,
1240 LDAPControl
**sctrls
, LDAPControl
**cctrls
,
1241 int sizelimit
, LDAPMessage
**res
)
1243 int rc
= LDAP_SERVER_DOWN
;
1245 int to
= lp_ldap_timeout();
1246 time_t abs_endtime
= calc_ldap_abs_endtime(to
);
1247 struct timeval timeout
;
1248 struct timeval
*timeout_ptr
= NULL
;
1249 size_t converted_size
;
1251 SMB_ASSERT(ldap_state
);
1253 DEBUG(5,("smbldap_search_ext: base => [%s], filter => [%s], "
1254 "scope => [%d]\n", base
, filter
, scope
));
1256 if (ldap_state
->last_rebind
.tv_sec
> 0) {
1257 struct timeval tval
;
1262 clock_gettime_mono(&ts
);
1263 tval
= convert_timespec_to_timeval(ts
);
1265 tdiff
= usec_time_diff(&tval
, &ldap_state
->last_rebind
);
1266 tdiff
/= 1000; /* Convert to milliseconds. */
1268 sleep_time
= lp_ldap_replication_sleep()-(int)tdiff
;
1269 sleep_time
= MIN(sleep_time
, MAX_LDAP_REPLICATION_SLEEP_TIME
);
1271 if (sleep_time
> 0) {
1272 /* we wait for the LDAP replication */
1273 DEBUG(5,("smbldap_search_ext: waiting %d milliseconds "
1274 "for LDAP replication.\n",sleep_time
));
1275 smb_msleep(sleep_time
);
1276 DEBUG(5,("smbldap_search_ext: go on!\n"));
1278 ZERO_STRUCT(ldap_state
->last_rebind
);
1281 if (!push_utf8_talloc(talloc_tos(), &utf8_filter
, filter
, &converted_size
)) {
1282 return LDAP_NO_MEMORY
;
1285 /* Setup remote timeout for the ldap_search_ext_s call. */
1287 timeout
.tv_sec
= to
;
1288 timeout
.tv_usec
= 0;
1289 timeout_ptr
= &timeout
;
1292 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1295 char *ld_error
= NULL
;
1298 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1299 if (rc
!= LDAP_SUCCESS
) {
1303 rc
= ldap_search_ext_s(ldap_state
->ldap_struct
, base
, scope
,
1305 discard_const_p(char *, attrs
),
1306 attrsonly
, sctrls
, cctrls
, timeout_ptr
,
1308 if (rc
== LDAP_SUCCESS
) {
1312 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1314 DEBUG(10, ("Failed search for base: %s, error: %d (%s) "
1315 "(%s)\n", base
, ld_errno
,
1316 ldap_err2string(rc
),
1317 ld_error
? ld_error
: "unknown"));
1318 SAFE_FREE(ld_error
);
1320 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1323 ldap_unbind(ldap_state
->ldap_struct
);
1324 ldap_state
->ldap_struct
= NULL
;
1327 TALLOC_FREE(utf8_filter
);
1328 return end_ldap_local_alarm(abs_endtime
, rc
);
1331 int smbldap_search(struct smbldap_state
*ldap_state
,
1332 const char *base
, int scope
, const char *filter
,
1333 const char *attrs
[], int attrsonly
,
1336 return smbldap_search_ext(ldap_state
, base
, scope
, filter
, attrs
,
1337 attrsonly
, NULL
, NULL
, LDAP_NO_LIMIT
, res
);
1340 int smbldap_search_paged(struct smbldap_state
*ldap_state
,
1341 const char *base
, int scope
, const char *filter
,
1342 const char **attrs
, int attrsonly
, int pagesize
,
1343 LDAPMessage
**res
, void **cookie
)
1346 LDAPControl
**rcontrols
;
1347 LDAPControl
*controls
[2] = { NULL
, NULL
};
1348 BerElement
*cookie_be
= NULL
;
1349 struct berval
*cookie_bv
= NULL
;
1351 bool critical
= True
;
1355 DEBUG(3,("smbldap_search_paged: base => [%s], filter => [%s],"
1356 "scope => [%d], pagesize => [%d]\n",
1357 base
, filter
, scope
, pagesize
));
1359 cookie_be
= ber_alloc_t(LBER_USE_DER
);
1360 if (cookie_be
== NULL
) {
1361 DEBUG(0,("smbldap_create_page_control: ber_alloc_t returns "
1363 return LDAP_NO_MEMORY
;
1366 /* construct cookie */
1367 if (*cookie
!= NULL
) {
1368 ber_printf(cookie_be
, "{iO}", (ber_int_t
) pagesize
, *cookie
);
1369 ber_bvfree((struct berval
*)*cookie
); /* don't need it from last time */
1372 ber_printf(cookie_be
, "{io}", (ber_int_t
) pagesize
, "", 0);
1374 ber_flatten(cookie_be
, &cookie_bv
);
1376 pr
.ldctl_oid
= discard_const_p(char, ADS_PAGE_CTL_OID
);
1377 pr
.ldctl_iscritical
= (char) critical
;
1378 pr
.ldctl_value
.bv_len
= cookie_bv
->bv_len
;
1379 pr
.ldctl_value
.bv_val
= cookie_bv
->bv_val
;
1384 rc
= smbldap_search_ext(ldap_state
, base
, scope
, filter
, attrs
,
1385 0, controls
, NULL
, LDAP_NO_LIMIT
, res
);
1387 ber_free(cookie_be
, 1);
1388 ber_bvfree(cookie_bv
);
1391 DEBUG(3,("smbldap_search_paged: smbldap_search_ext(%s) "
1392 "failed with [%s]\n", filter
, ldap_err2string(rc
)));
1396 DEBUG(3,("smbldap_search_paged: search was successful\n"));
1398 rc
= ldap_parse_result(ldap_state
->ldap_struct
, *res
, NULL
, NULL
,
1399 NULL
, NULL
, &rcontrols
, 0);
1401 DEBUG(3,("smbldap_search_paged: ldap_parse_result failed " \
1402 "with [%s]\n", ldap_err2string(rc
)));
1406 if (rcontrols
== NULL
)
1409 for (i
=0; rcontrols
[i
]; i
++) {
1411 if (strcmp(ADS_PAGE_CTL_OID
, rcontrols
[i
]->ldctl_oid
) != 0)
1414 cookie_be
= ber_init(&rcontrols
[i
]->ldctl_value
);
1415 ber_scanf(cookie_be
,"{iO}", &tmp
, &cookie_bv
);
1416 /* the berval is the cookie, but must be freed when it is all
1418 if (cookie_bv
->bv_len
)
1419 *cookie
=ber_bvdup(cookie_bv
);
1422 ber_bvfree(cookie_bv
);
1423 ber_free(cookie_be
, 1);
1426 ldap_controls_free(rcontrols
);
1431 int smbldap_modify(struct smbldap_state
*ldap_state
, const char *dn
, LDAPMod
*attrs
[])
1433 int rc
= LDAP_SERVER_DOWN
;
1435 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1436 size_t converted_size
;
1438 SMB_ASSERT(ldap_state
);
1440 DEBUG(5,("smbldap_modify: dn => [%s]\n", dn
));
1442 if (!push_utf8_talloc(talloc_tos(), &utf8_dn
, dn
, &converted_size
)) {
1443 return LDAP_NO_MEMORY
;
1446 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1449 char *ld_error
= NULL
;
1452 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1453 if (rc
!= LDAP_SUCCESS
) {
1457 rc
= ldap_modify_s(ldap_state
->ldap_struct
, utf8_dn
, attrs
);
1458 if (rc
== LDAP_SUCCESS
) {
1462 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1464 DEBUG(10, ("Failed to modify dn: %s, error: %d (%s) "
1465 "(%s)\n", dn
, ld_errno
,
1466 ldap_err2string(rc
),
1467 ld_error
? ld_error
: "unknown"));
1468 SAFE_FREE(ld_error
);
1470 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1473 ldap_unbind(ldap_state
->ldap_struct
);
1474 ldap_state
->ldap_struct
= NULL
;
1477 TALLOC_FREE(utf8_dn
);
1478 return end_ldap_local_alarm(abs_endtime
, rc
);
1481 int smbldap_add(struct smbldap_state
*ldap_state
, const char *dn
, LDAPMod
*attrs
[])
1483 int rc
= LDAP_SERVER_DOWN
;
1485 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1486 size_t converted_size
;
1488 SMB_ASSERT(ldap_state
);
1490 DEBUG(5,("smbldap_add: dn => [%s]\n", dn
));
1492 if (!push_utf8_talloc(talloc_tos(), &utf8_dn
, dn
, &converted_size
)) {
1493 return LDAP_NO_MEMORY
;
1496 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1499 char *ld_error
= NULL
;
1502 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1503 if (rc
!= LDAP_SUCCESS
) {
1507 rc
= ldap_add_s(ldap_state
->ldap_struct
, utf8_dn
, attrs
);
1508 if (rc
== LDAP_SUCCESS
) {
1512 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1514 DEBUG(10, ("Failed to add 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(ldap_state
->ldap_struct
);
1524 ldap_state
->ldap_struct
= NULL
;
1527 TALLOC_FREE(utf8_dn
);
1528 return end_ldap_local_alarm(abs_endtime
, rc
);
1531 int smbldap_delete(struct smbldap_state
*ldap_state
, const char *dn
)
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_delete: 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_delete_s(ldap_state
->ldap_struct
, utf8_dn
);
1558 if (rc
== LDAP_SUCCESS
) {
1562 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1564 DEBUG(10, ("Failed to delete 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(ldap_state
->ldap_struct
);
1574 ldap_state
->ldap_struct
= NULL
;
1577 TALLOC_FREE(utf8_dn
);
1578 return end_ldap_local_alarm(abs_endtime
, rc
);
1581 int smbldap_extended_operation(struct smbldap_state
*ldap_state
,
1582 LDAP_CONST
char *reqoid
, struct berval
*reqdata
,
1583 LDAPControl
**serverctrls
, LDAPControl
**clientctrls
,
1584 char **retoidp
, struct berval
**retdatap
)
1586 int rc
= LDAP_SERVER_DOWN
;
1587 time_t abs_endtime
= calc_ldap_abs_endtime(lp_ldap_timeout());
1592 setup_ldap_local_alarm(ldap_state
, abs_endtime
);
1595 char *ld_error
= NULL
;
1598 rc
= get_cached_ldap_connect(ldap_state
, abs_endtime
);
1599 if (rc
!= LDAP_SUCCESS
) {
1603 rc
= ldap_extended_operation_s(ldap_state
->ldap_struct
, reqoid
,
1604 reqdata
, serverctrls
,
1605 clientctrls
, retoidp
, retdatap
);
1606 if (rc
== LDAP_SUCCESS
) {
1610 get_ldap_errs(ldap_state
, &ld_error
, &ld_errno
);
1612 DEBUG(10, ("Extended operation failed with error: "
1613 "%d (%s) (%s)\n", ld_errno
,
1614 ldap_err2string(rc
),
1615 ld_error
? ld_error
: "unknown"));
1616 SAFE_FREE(ld_error
);
1618 if (ld_errno
!= LDAP_SERVER_DOWN
) {
1621 ldap_unbind(ldap_state
->ldap_struct
);
1622 ldap_state
->ldap_struct
= NULL
;
1625 return end_ldap_local_alarm(abs_endtime
, rc
);
1628 /*******************************************************************
1629 run the search by name.
1630 ******************************************************************/
1631 int smbldap_search_suffix (struct smbldap_state
*ldap_state
,
1632 const char *filter
, const char **search_attr
,
1633 LDAPMessage
** result
)
1635 return smbldap_search(ldap_state
, lp_ldap_suffix(), LDAP_SCOPE_SUBTREE
,
1636 filter
, search_attr
, 0, result
);
1639 static void smbldap_idle_fn(struct tevent_context
*tevent_ctx
,
1640 struct timed_event
*te
,
1641 struct timeval now_abs
,
1644 struct smbldap_state
*state
= (struct smbldap_state
*)private_data
;
1646 TALLOC_FREE(state
->idle_event
);
1648 if (state
->ldap_struct
== NULL
) {
1649 DEBUG(10,("ldap connection not connected...\n"));
1653 if ((state
->last_use
+SMBLDAP_IDLE_TIME
) > time_mono(NULL
)) {
1654 DEBUG(10,("ldap connection not idle...\n"));
1656 /* this needs to be made monotonic clock aware inside tevent: */
1657 state
->idle_event
= tevent_add_timer(
1659 timeval_add(&now_abs
, SMBLDAP_IDLE_TIME
, 0),
1665 DEBUG(7,("ldap connection idle...closing connection\n"));
1666 smbldap_close(state
);
1669 /**********************************************************************
1671 *********************************************************************/
1673 void smbldap_free_struct(struct smbldap_state
**ldap_state
)
1675 smbldap_close(*ldap_state
);
1677 if ((*ldap_state
)->bind_secret
) {
1678 memset((*ldap_state
)->bind_secret
, '\0', strlen((*ldap_state
)->bind_secret
));
1681 SAFE_FREE((*ldap_state
)->bind_dn
);
1682 SAFE_FREE((*ldap_state
)->bind_secret
);
1683 (*ldap_state
)->bind_callback
= NULL
;
1684 (*ldap_state
)->bind_callback_data
= NULL
;
1686 TALLOC_FREE(*ldap_state
);
1688 /* No need to free any further, as it is talloc()ed */
1691 static int smbldap_state_destructor(struct smbldap_state
*state
)
1693 smbldap_free_struct(&state
);
1698 /**********************************************************************
1699 Intitalise the 'general' ldap structures, on which ldap operations may be conducted
1700 *********************************************************************/
1702 NTSTATUS
smbldap_init(TALLOC_CTX
*mem_ctx
, struct tevent_context
*tevent_ctx
,
1703 const char *location
,
1705 const char *bind_dn
,
1706 const char *bind_secret
,
1707 struct smbldap_state
**smbldap_state
)
1709 *smbldap_state
= talloc_zero(mem_ctx
, struct smbldap_state
);
1710 if (!*smbldap_state
) {
1711 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
1712 return NT_STATUS_NO_MEMORY
;
1716 (*smbldap_state
)->uri
= talloc_strdup(mem_ctx
, location
);
1718 (*smbldap_state
)->uri
= "ldap://localhost";
1721 (*smbldap_state
)->tevent_context
= tevent_ctx
;
1723 if (bind_dn
&& bind_secret
) {
1724 smbldap_set_creds(*smbldap_state
, anon
, bind_dn
, bind_secret
);
1727 talloc_set_destructor(*smbldap_state
, smbldap_state_destructor
);
1728 return NT_STATUS_OK
;
1731 char *smbldap_talloc_dn(TALLOC_CTX
*mem_ctx
, LDAP
*ld
,
1734 char *utf8_dn
, *unix_dn
;
1735 size_t converted_size
;
1737 utf8_dn
= ldap_get_dn(ld
, entry
);
1739 DEBUG (5, ("smbldap_talloc_dn: ldap_get_dn failed\n"));
1742 if (!pull_utf8_talloc(mem_ctx
, &unix_dn
, utf8_dn
, &converted_size
)) {
1743 DEBUG (0, ("smbldap_talloc_dn: String conversion failure utf8 "
1744 "[%s]\n", utf8_dn
));
1747 ldap_memfree(utf8_dn
);
1751 /*******************************************************************
1752 Check if root-dse has a certain Control or Extension
1753 ********************************************************************/
1755 static bool smbldap_check_root_dse(LDAP
*ld
, const char **attrs
, const char *value
)
1757 LDAPMessage
*msg
= NULL
;
1758 LDAPMessage
*entry
= NULL
;
1759 char **values
= NULL
;
1760 int rc
, num_result
, num_values
, i
;
1761 bool result
= False
;
1764 DEBUG(3,("smbldap_check_root_dse: nothing to look for\n"));
1768 if (!strequal(attrs
[0], "supportedExtension") &&
1769 !strequal(attrs
[0], "supportedControl") &&
1770 !strequal(attrs
[0], "namingContexts")) {
1771 DEBUG(3,("smbldap_check_root_dse: no idea what to query root-dse for: %s ?\n", attrs
[0]));
1775 rc
= ldap_search_s(ld
, "", LDAP_SCOPE_BASE
,
1776 "(objectclass=*)", discard_const_p(char *, attrs
), 0 , &msg
);
1778 if (rc
!= LDAP_SUCCESS
) {
1779 DEBUG(3,("smbldap_check_root_dse: Could not search rootDSE\n"));
1783 num_result
= ldap_count_entries(ld
, msg
);
1785 if (num_result
!= 1) {
1786 DEBUG(3,("smbldap_check_root_dse: Expected one rootDSE, got %d\n", num_result
));
1790 entry
= ldap_first_entry(ld
, msg
);
1792 if (entry
== NULL
) {
1793 DEBUG(3,("smbldap_check_root_dse: Could not retrieve rootDSE\n"));
1797 values
= ldap_get_values(ld
, entry
, attrs
[0]);
1799 if (values
== NULL
) {
1800 DEBUG(5,("smbldap_check_root_dse: LDAP Server does not support any %s\n", attrs
[0]));
1804 num_values
= ldap_count_values(values
);
1806 if (num_values
== 0) {
1807 DEBUG(5,("smbldap_check_root_dse: LDAP Server does not have any %s\n", attrs
[0]));
1811 for (i
=0; i
<num_values
; i
++) {
1812 if (strcmp(values
[i
], value
) == 0)
1819 ldap_value_free(values
);
1827 /*******************************************************************
1828 Check if LDAP-Server supports a certain Control (OID in string format)
1829 ********************************************************************/
1831 bool smbldap_has_control(LDAP
*ld
, const char *control
)
1833 const char *attrs
[] = { "supportedControl", NULL
};
1834 return smbldap_check_root_dse(ld
, attrs
, control
);
1837 /*******************************************************************
1838 Check if LDAP-Server supports a certain Extension (OID in string format)
1839 ********************************************************************/
1841 bool smbldap_has_extension(LDAP
*ld
, const char *extension
)
1843 const char *attrs
[] = { "supportedExtension", NULL
};
1844 return smbldap_check_root_dse(ld
, attrs
, extension
);
1847 /*******************************************************************
1848 Check if LDAP-Server holds a given namingContext
1849 ********************************************************************/
1851 bool smbldap_has_naming_context(LDAP
*ld
, const char *naming_context
)
1853 const char *attrs
[] = { "namingContexts", NULL
};
1854 return smbldap_check_root_dse(ld
, attrs
, naming_context
);
1857 bool smbldap_set_creds(struct smbldap_state
*ldap_state
, bool anon
, const char *dn
, const char *secret
)
1859 ldap_state
->anonymous
= anon
;
1861 /* free any previously set credential */
1863 SAFE_FREE(ldap_state
->bind_dn
);
1864 ldap_state
->bind_callback
= NULL
;
1865 ldap_state
->bind_callback_data
= NULL
;
1867 if (ldap_state
->bind_secret
) {
1868 /* make sure secrets are zeroed out of memory */
1869 memset(ldap_state
->bind_secret
, '\0', strlen(ldap_state
->bind_secret
));
1870 SAFE_FREE(ldap_state
->bind_secret
);
1874 ldap_state
->bind_dn
= SMB_STRDUP(dn
);
1875 ldap_state
->bind_secret
= SMB_STRDUP(secret
);