Copyright (C) Shahms King 2001
Copyright (C) Andrew Bartlett 2002-2003
Copyright (C) Stefan (metze) Metzmacher 2002-2003
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
*/
#include "includes.h"
#include "smbldap.h"
-
-#ifndef LDAP_OPT_SUCCESS
-#define LDAP_OPT_SUCCESS 0
-#endif
+#include "secrets.h"
+#include "../libcli/security/security.h"
/* Try not to hit the up or down server forever */
{ LDAP_ATTR_LOGON_TIME, "sambaLogonTime" },
{ LDAP_ATTR_LOGOFF_TIME, "sambaLogoffTime" },
{ LDAP_ATTR_KICKOFF_TIME, "sambaKickoffTime" },
+ { LDAP_ATTR_DISPLAY_NAME, "displayName" },
{ LDAP_ATTR_HOME_DRIVE, "sambaHomeDrive" },
{ LDAP_ATTR_HOME_PATH, "sambaHomePath" },
{ LDAP_ATTR_LOGON_SCRIPT, "sambaLogonScript" },
const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key )
{
int i = 0;
-
+
while ( table[i].attrib != LDAP_ATTR_LIST_END ) {
if ( table[i].attrib == key )
return table[i].name;
i++;
}
-
+
return NULL;
}
{
const char **names;
int i = 0;
-
+
while ( table[i].attrib != LDAP_ATTR_LIST_END )
i++;
i++;
- names = TALLOC_ARRAY( mem_ctx, const char*, i );
+ names = talloc_array( mem_ctx, const char*, i );
if ( !names ) {
DEBUG(0,("get_attr_list: out of memory\n"));
return NULL;
i++;
}
names[i] = NULL;
-
+
return names;
}
Search an attribute and return the first value found.
******************************************************************/
- BOOL smbldap_get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
+ bool smbldap_get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
const char *attribute, char *value,
int max_len)
{
char **values;
-
+ size_t size = 0;
+
if ( !attribute )
return False;
-
+
value[0] = '\0';
if ((values = ldap_get_values (ldap_struct, entry, attribute)) == NULL) {
DEBUG (10, ("smbldap_get_single_attribute: [%s] = [<does not exist>]\n", attribute));
-
+
return False;
}
-
- if (convert_string(CH_UTF8, CH_UNIX,values[0], -1, value, max_len, False) == (size_t)-1) {
+
+ if (!convert_string(CH_UTF8, CH_UNIX,values[0], -1, value, max_len, &size)) {
DEBUG(1, ("smbldap_get_single_attribute: string conversion of [%s] = [%s] failed!\n",
attribute, values[0]));
ldap_value_free(values);
return False;
}
-
+
ldap_value_free(values);
#ifdef DEBUG_PASSWORDS
DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n", attribute, value));
return True;
}
- BOOL smbldap_get_single_pstring (LDAP * ldap_struct, LDAPMessage * entry,
- const char *attribute, pstring value)
-{
- return smbldap_get_single_attribute(ldap_struct, entry,
- attribute, value,
- sizeof(pstring));
-}
-
char * smbldap_talloc_single_attribute(LDAP *ldap_struct, LDAPMessage *entry,
const char *attribute,
TALLOC_CTX *mem_ctx)
{
char **values;
char *result;
+ size_t converted_size;
if (attribute == NULL) {
return NULL;
return NULL;
}
- if (pull_utf8_talloc(mem_ctx, &result, values[0]) == (size_t)-1) {
+ if (!pull_utf8_talloc(mem_ctx, &result, values[0], &converted_size)) {
DEBUG(10, ("pull_utf8_talloc failed\n"));
ldap_value_free(values);
return NULL;
return result;
}
- static int ldapmsg_destructor(void *p) {
- LDAPMessage **result = talloc_get_type_abort(p, LDAPMessage *);
+ char * smbldap_talloc_first_attribute(LDAP *ldap_struct, LDAPMessage *entry,
+ const char *attribute,
+ TALLOC_CTX *mem_ctx)
+{
+ char **values;
+ char *result;
+ size_t converted_size;
+
+ if (attribute == NULL) {
+ return NULL;
+ }
+
+ values = ldap_get_values(ldap_struct, entry, attribute);
+
+ if (values == NULL) {
+ DEBUG(10, ("attribute %s does not exist\n", attribute));
+ return NULL;
+ }
+
+ if (!pull_utf8_talloc(mem_ctx, &result, values[0], &converted_size)) {
+ DEBUG(10, ("pull_utf8_talloc failed\n"));
+ ldap_value_free(values);
+ return NULL;
+ }
+
+ ldap_value_free(values);
+
+#ifdef DEBUG_PASSWORDS
+ DEBUG (100, ("smbldap_get_first_attribute: [%s] = [%s]\n",
+ attribute, result));
+#endif
+ return result;
+}
+
+ char * smbldap_talloc_smallest_attribute(LDAP *ldap_struct, LDAPMessage *entry,
+ const char *attribute,
+ TALLOC_CTX *mem_ctx)
+{
+ char **values;
+ char *result;
+ size_t converted_size;
+ int i, num_values;
+
+ if (attribute == NULL) {
+ return NULL;
+ }
+
+ values = ldap_get_values(ldap_struct, entry, attribute);
+
+ if (values == NULL) {
+ DEBUG(10, ("attribute %s does not exist\n", attribute));
+ return NULL;
+ }
+
+ if (!pull_utf8_talloc(mem_ctx, &result, values[0], &converted_size)) {
+ DEBUG(10, ("pull_utf8_talloc failed\n"));
+ ldap_value_free(values);
+ return NULL;
+ }
+
+ num_values = ldap_count_values(values);
+
+ for (i=1; i<num_values; i++) {
+ char *tmp;
+
+ if (!pull_utf8_talloc(mem_ctx, &tmp, values[i],
+ &converted_size)) {
+ DEBUG(10, ("pull_utf8_talloc failed\n"));
+ TALLOC_FREE(result);
+ ldap_value_free(values);
+ return NULL;
+ }
+
+ if (strcasecmp_m(tmp, result) < 0) {
+ TALLOC_FREE(result);
+ result = tmp;
+ } else {
+ TALLOC_FREE(tmp);
+ }
+ }
+
+ ldap_value_free(values);
+
+#ifdef DEBUG_PASSWORDS
+ DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n",
+ attribute, result));
+#endif
+ return result;
+}
+
+ bool smbldap_talloc_single_blob(TALLOC_CTX *mem_ctx, LDAP *ld,
+ LDAPMessage *msg, const char *attrib,
+ DATA_BLOB *blob)
+{
+ struct berval **values;
+
+ values = ldap_get_values_len(ld, msg, attrib);
+ if (!values) {
+ return false;
+ }
+
+ if (ldap_count_values_len(values) != 1) {
+ DEBUG(10, ("Expected one value for %s, got %d\n", attrib,
+ ldap_count_values_len(values)));
+ return false;
+ }
+
+ *blob = data_blob_talloc(mem_ctx, values[0]->bv_val,
+ values[0]->bv_len);
+ ldap_value_free_len(values);
+
+ return (blob->data != NULL);
+}
+
+ bool smbldap_pull_sid(LDAP *ld, LDAPMessage *msg, const char *attrib,
+ struct dom_sid *sid)
+{
+ DATA_BLOB blob;
+ bool ret;
+
+ if (!smbldap_talloc_single_blob(talloc_tos(), ld, msg, attrib,
+ &blob)) {
+ return false;
+ }
+ ret = sid_parse((char *)blob.data, blob.length, sid);
+ TALLOC_FREE(blob.data);
+ return ret;
+}
+
+ static int ldapmsg_destructor(LDAPMessage **result) {
ldap_msgfree(*result);
return 0;
}
return;
}
- handle = TALLOC_P(mem_ctx, LDAPMessage *);
+ handle = talloc(mem_ctx, LDAPMessage *);
SMB_ASSERT(handle != NULL);
*handle = result;
talloc_set_destructor(handle, ldapmsg_destructor);
}
- static int ldapmod_destructor(void *p) {
- LDAPMod ***result = talloc_get_type_abort(p, LDAPMod **);
- ldap_mods_free(*result, True);
+ static int ldapmod_destructor(LDAPMod ***mod) {
+ ldap_mods_free(*mod, True);
return 0;
}
return;
}
- handle = TALLOC_P(mem_ctx, LDAPMod **);
+ handle = talloc(mem_ctx, LDAPMod **);
SMB_ASSERT(handle != NULL);
*handle = mod;
manage memory used by the array, by each struct, and values
***********************************************************************/
- void smbldap_set_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value)
+static void smbldap_set_mod_internal(LDAPMod *** modlist, int modop, const char *attribute, const char *value, const DATA_BLOB *blob)
{
LDAPMod **mods;
int i;
if (mods == NULL) {
mods = SMB_MALLOC_P(LDAPMod *);
if (mods == NULL) {
- smb_panic("smbldap_set_mod: out of memory!\n");
+ smb_panic("smbldap_set_mod: out of memory!");
/* notreached. */
- abort();
}
mods[0] = NULL;
}
if (mods[i] == NULL) {
mods = SMB_REALLOC_ARRAY (mods, LDAPMod *, i + 2);
if (mods == NULL) {
- smb_panic("smbldap_set_mod: out of memory!\n");
+ smb_panic("smbldap_set_mod: out of memory!");
/* notreached. */
- abort();
}
mods[i] = SMB_MALLOC_P(LDAPMod);
if (mods[i] == NULL) {
- smb_panic("smbldap_set_mod: out of memory!\n");
+ smb_panic("smbldap_set_mod: out of memory!");
/* notreached. */
- abort();
}
mods[i]->mod_op = modop;
mods[i]->mod_values = NULL;
mods[i + 1] = NULL;
}
- if (value != NULL) {
+ if (blob && (modop & LDAP_MOD_BVALUES)) {
+ j = 0;
+ if (mods[i]->mod_bvalues != NULL) {
+ for (; mods[i]->mod_bvalues[j] != NULL; j++);
+ }
+ mods[i]->mod_bvalues = SMB_REALLOC_ARRAY(mods[i]->mod_bvalues, struct berval *, j + 2);
+
+ if (mods[i]->mod_bvalues == NULL) {
+ smb_panic("smbldap_set_mod: out of memory!");
+ /* notreached. */
+ }
+
+ mods[i]->mod_bvalues[j] = SMB_MALLOC_P(struct berval);
+ SMB_ASSERT(mods[i]->mod_bvalues[j] != NULL);
+
+ mods[i]->mod_bvalues[j]->bv_val = (char *)memdup(blob->data, blob->length);
+ SMB_ASSERT(mods[i]->mod_bvalues[j]->bv_val != NULL);
+ mods[i]->mod_bvalues[j]->bv_len = blob->length;
+
+ mods[i]->mod_bvalues[j + 1] = NULL;
+ } else if (value != NULL) {
char *utf8_value = NULL;
+ size_t converted_size;
j = 0;
if (mods[i]->mod_values != NULL) {
for (; mods[i]->mod_values[j] != NULL; j++);
}
mods[i]->mod_values = SMB_REALLOC_ARRAY(mods[i]->mod_values, char *, j + 2);
-
+
if (mods[i]->mod_values == NULL) {
- smb_panic("smbldap_set_mod: out of memory!\n");
+ smb_panic("smbldap_set_mod: out of memory!");
/* notreached. */
- abort();
}
- if (push_utf8_allocate(&utf8_value, value) == (size_t)-1) {
- smb_panic("smbldap_set_mod: String conversion failure!\n");
+ if (!push_utf8_talloc(talloc_tos(), &utf8_value, value, &converted_size)) {
+ smb_panic("smbldap_set_mod: String conversion failure!");
/* notreached. */
- abort();
}
- mods[i]->mod_values[j] = utf8_value;
+ mods[i]->mod_values[j] = SMB_STRDUP(utf8_value);
+ TALLOC_FREE(utf8_value);
+ SMB_ASSERT(mods[i]->mod_values[j] != NULL);
mods[i]->mod_values[j + 1] = NULL;
}
*modlist = mods;
}
+ void smbldap_set_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value)
+{
+ smbldap_set_mod_internal(modlist, modop, attribute, value, NULL);
+}
+
+ void smbldap_set_mod_blob(LDAPMod *** modlist, int modop, const char *attribute, const DATA_BLOB *value)
+{
+ smbldap_set_mod_internal(modlist, modop | LDAP_MOD_BVALUES, attribute, NULL, value);
+}
+
/**********************************************************************
Set attribute to newval in LDAP, regardless of what value the
attribute had in LDAP before.
*********************************************************************/
- void smbldap_make_mod(LDAP *ldap_struct, LDAPMessage *existing,
- LDAPMod ***mods,
- const char *attribute, const char *newval)
+static void smbldap_make_mod_internal(LDAP *ldap_struct, LDAPMessage *existing,
+ LDAPMod ***mods,
+ const char *attribute, int op,
+ const char *newval,
+ const DATA_BLOB *newblob)
{
char oldval[2048]; /* current largest allowed value is mungeddial */
- BOOL existed;
+ bool existed;
+ DATA_BLOB oldblob = data_blob_null;
if (attribute == NULL) {
/* This can actually happen for ldapsam_compat where we for
}
if (existing != NULL) {
- existed = smbldap_get_single_attribute(ldap_struct, existing, attribute, oldval, sizeof(oldval));
+ if (op & LDAP_MOD_BVALUES) {
+ existed = smbldap_talloc_single_blob(talloc_tos(), ldap_struct, existing, attribute, &oldblob);
+ } else {
+ existed = smbldap_get_single_attribute(ldap_struct, existing, attribute, oldval, sizeof(oldval));
+ }
} else {
existed = False;
*oldval = '\0';
}
- /* all of our string attributes are case insensitive */
-
- if (existed && newval && (StrCaseCmp(oldval, newval) == 0)) {
-
- /* Believe it or not, but LDAP will deny a delete and
- an add at the same time if the values are the
- same... */
- DEBUG(10,("smbldap_make_mod: attribute |%s| not changed.\n", attribute));
- return;
- }
-
if (existed) {
+ bool equal = false;
+ if (op & LDAP_MOD_BVALUES) {
+ equal = (newblob && (data_blob_cmp(&oldblob, newblob) == 0));
+ } else {
+ /* all of our string attributes are case insensitive */
+ equal = (newval && (strcasecmp_m(oldval, newval) == 0));
+ }
+
+ if (equal) {
+ /* Believe it or not, but LDAP will deny a delete and
+ an add at the same time if the values are the
+ same... */
+ DEBUG(10,("smbldap_make_mod: attribute |%s| not changed.\n", attribute));
+ return;
+ }
+
/* There has been no value before, so don't delete it.
* Here's a possible race: We might end up with
* duplicate attributes */
/* This will also allow modifying single valued attributes
* in Novell NDS. In NDS you have to first remove attribute and then
* you could add new value */
-
- DEBUG(10,("smbldap_make_mod: deleting attribute |%s| values |%s|\n", attribute, oldval));
- smbldap_set_mod(mods, LDAP_MOD_DELETE, attribute, oldval);
+
+ if (op & LDAP_MOD_BVALUES) {
+ DEBUG(10,("smbldap_make_mod: deleting attribute |%s| blob\n", attribute));
+ smbldap_set_mod_blob(mods, LDAP_MOD_DELETE, attribute, &oldblob);
+ } else {
+ DEBUG(10,("smbldap_make_mod: deleting attribute |%s| values |%s|\n", attribute, oldval));
+ smbldap_set_mod(mods, LDAP_MOD_DELETE, attribute, oldval);
+ }
}
/* Regardless of the real operation (add or modify)
we add the new value here. We rely on deleting
the old value, should it exist. */
- if ((newval != NULL) && (strlen(newval) > 0)) {
- DEBUG(10,("smbldap_make_mod: adding attribute |%s| value |%s|\n", attribute, newval));
- smbldap_set_mod(mods, LDAP_MOD_ADD, attribute, newval);
+ if (op & LDAP_MOD_BVALUES) {
+ if (newblob && newblob->length) {
+ DEBUG(10,("smbldap_make_mod: adding attribute |%s| blob\n", attribute));
+ smbldap_set_mod_blob(mods, LDAP_MOD_ADD, attribute, newblob);
+ }
+ } else {
+ if ((newval != NULL) && (strlen(newval) > 0)) {
+ DEBUG(10,("smbldap_make_mod: adding attribute |%s| value |%s|\n", attribute, newval));
+ smbldap_set_mod(mods, LDAP_MOD_ADD, attribute, newval);
+ }
}
}
+ void smbldap_make_mod(LDAP *ldap_struct, LDAPMessage *existing,
+ LDAPMod ***mods,
+ const char *attribute, const char *newval)
+{
+ smbldap_make_mod_internal(ldap_struct, existing, mods, attribute,
+ 0, newval, NULL);
+}
+
+ void smbldap_make_mod_blob(LDAP *ldap_struct, LDAPMessage *existing,
+ LDAPMod ***mods,
+ const char *attribute, const DATA_BLOB *newblob)
+{
+ smbldap_make_mod_internal(ldap_struct, existing, mods, attribute,
+ LDAP_MOD_BVALUES, NULL, newblob);
+}
+
/**********************************************************************
Some varients of the LDAP rebind code do not pass in the third 'arg'
pointer to a void*, so we try and work around it by assuming that the
{
struct smbldap_state *tmp_ldap_state;
struct smbldap_state_lookup *t;
- struct smbldap_state_lookup *tmp;
-
+
if ((tmp_ldap_state = smbldap_find_state(ld))) {
SMB_ASSERT(tmp_ldap_state == smbldap_state);
return;
t = SMB_XMALLOC_P(struct smbldap_state_lookup);
ZERO_STRUCTP(t);
-
- DLIST_ADD_END(smbldap_state_lookup_list, t, tmp);
+
+ DLIST_ADD_END(smbldap_state_lookup_list, t, struct smbldap_state_lookup *);
t->ld = ld;
t->smbldap_state = smbldap_state;
}
int smb_ldap_start_tls(LDAP *ldap_struct, int version)
{
+#ifdef LDAP_OPT_X_TLS
int rc;
-
+#endif
+
if (lp_ldap_ssl() != LDAP_SSL_START_TLS) {
return LDAP_SUCCESS;
}
-
+
#ifdef LDAP_OPT_X_TLS
if (version != LDAP_VERSION3) {
DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
setup a connection to the LDAP server based on a uri
*******************************************************************/
-int smb_ldap_setup_conn(LDAP **ldap_struct, const char *uri)
+static int smb_ldap_setup_conn(LDAP **ldap_struct, const char *uri)
{
int rc;
DEBUG(10, ("smb_ldap_setup_connection: %s\n", uri));
-
+
#ifdef HAVE_LDAP_INITIALIZE
-
+
rc = ldap_initialize(ldap_struct, uri);
if (rc) {
DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc)));
+ return rc;
}
- return rc;
+ if (lp_ldap_follow_referral() != Auto) {
+ rc = ldap_set_option(*ldap_struct, LDAP_OPT_REFERRALS,
+ lp_ldap_follow_referral() ? LDAP_OPT_ON : LDAP_OPT_OFF);
+ if (rc != LDAP_SUCCESS)
+ DEBUG(0, ("Failed to set LDAP_OPT_REFERRALS: %s\n",
+ ldap_err2string(rc)));
+ }
+
+ return LDAP_SUCCESS;
#else
/* Parse the string manually */
if ( strnequal( uri, "URL:", 4 ) ) {
uri += 4;
}
-
+
sscanf(uri, "%10[^:]://%254[^:/]:%d", protocol, host, &port);
-
+
if (port == 0) {
if (strequal(protocol, "ldap")) {
port = LDAP_PORT;
DEBUG(0, ("unrecognised protocol (%s)!\n", protocol));
}
}
-
+
if ((*ldap_struct = ldap_init(host, port)) == NULL) {
DEBUG(0, ("ldap_init failed !\n"));
return LDAP_OPERATIONS_ERROR;
}
-
+
if (strequal(protocol, "ldaps")) {
#ifdef LDAP_OPT_X_TLS
int tls = LDAP_OPT_X_TLS_HARD;
{
DEBUG(0, ("Failed to setup a TLS session\n"));
}
-
+
DEBUG(3,("LDAPS option set...!\n"));
#else
DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));
return LDAP_OPERATIONS_ERROR;
#endif /* LDAP_OPT_X_TLS */
}
-
}
#endif /* HAVE_LDAP_INITIALIZE */
+
+ /* now set connection timeout */
+#ifdef LDAP_X_OPT_CONNECT_TIMEOUT /* Netscape */
+ {
+ int ct = lp_ldap_connection_timeout()*1000;
+ rc = ldap_set_option(*ldap_struct, LDAP_X_OPT_CONNECT_TIMEOUT, &ct);
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(0,("Failed to setup an ldap connection timeout %d: %s\n",
+ ct, ldap_err2string(rc)));
+ }
+ }
+#elif defined (LDAP_OPT_NETWORK_TIMEOUT) /* OpenLDAP */
+ {
+ struct timeval ct;
+ ct.tv_usec = 0;
+ ct.tv_sec = lp_ldap_connection_timeout();
+ rc = ldap_set_option(*ldap_struct, LDAP_OPT_NETWORK_TIMEOUT, &ct);
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(0,("Failed to setup an ldap connection timeout %d: %s\n",
+ (int)ct.tv_sec, ldap_err2string(rc)));
+ }
+ }
+#endif
+
return LDAP_SUCCESS;
}
version
*******************************************************************/
-int smb_ldap_upgrade_conn(LDAP *ldap_struct, int *new_version)
+static int smb_ldap_upgrade_conn(LDAP *ldap_struct, int *new_version)
{
int version;
int rc;
-
+
/* assume the worst */
*new_version = LDAP_VERSION2;
if (rc) {
return rc;
}
-
+
*new_version = LDAP_VERSION3;
return LDAP_SUCCESS;
}
{
int rc = LDAP_SUCCESS;
int version;
+ int deref;
LDAP **ldap_struct = &ldap_state->ldap_struct;
rc = smb_ldap_setup_conn(ldap_struct, ldap_state->uri);
if (rc) {
return rc;
}
-
+
+ /* Set alias dereferencing method */
+ deref = lp_ldap_deref();
+ if (deref != -1) {
+ if (ldap_set_option (*ldap_struct, LDAP_OPT_DEREF, &deref) != LDAP_OPT_SUCCESS) {
+ DEBUG(1,("smbldap_open_connection: Failed to set dereferencing method: %d\n", deref));
+ } else {
+ DEBUG(5,("Set dereferencing method: %d\n", deref));
+ }
+ }
+
DEBUG(2, ("smbldap_open_connection: connection opened\n"));
return rc;
}
int *methodp, int freeit, void *arg)
{
struct smbldap_state *ldap_state = arg;
-
+ struct timespec ts;
+
/** @TODO Should we be doing something to check what servers we rebind to?
Could we get a referral to a machine that we don't want to give our
username and password to? */
-
+
if (freeit) {
SAFE_FREE(*whop);
- memset(*credp, '\0', strlen(*credp));
+ if (*credp) {
+ memset(*credp, '\0', strlen(*credp));
+ }
SAFE_FREE(*credp);
} else {
DEBUG(5,("rebind_proc_with_state: Rebinding as \"%s\"\n",
- ldap_state->bind_dn));
+ ldap_state->bind_dn?ldap_state->bind_dn:"[Anonymous bind]"));
- *whop = SMB_STRDUP(ldap_state->bind_dn);
- if (!*whop) {
- return LDAP_NO_MEMORY;
- }
- *credp = SMB_STRDUP(ldap_state->bind_secret);
- if (!*credp) {
- SAFE_FREE(*whop);
- return LDAP_NO_MEMORY;
+ if (ldap_state->anonymous) {
+ *whop = NULL;
+ *credp = NULL;
+ } else {
+ *whop = SMB_STRDUP(ldap_state->bind_dn);
+ if (!*whop) {
+ return LDAP_NO_MEMORY;
+ }
+ *credp = SMB_STRDUP(ldap_state->bind_secret);
+ if (!*credp) {
+ SAFE_FREE(*whop);
+ return LDAP_NO_MEMORY;
+ }
}
*methodp = LDAP_AUTH_SIMPLE;
}
- GetTimeOfDay(&ldap_state->last_rebind);
-
+ clock_gettime_mono(&ts);
+ ldap_state->last_rebind = convert_timespec_to_timeval(ts);
+
return 0;
}
#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
ber_tag_t request,
ber_int_t msgid, void *arg)
{
- struct smbldap_state *ldap_state = arg;
+ struct smbldap_state *ldap_state =
+ (struct smbldap_state *)arg;
int rc;
+ struct timespec ts;
int version;
DEBUG(5,("rebindproc_connect_with_state: Rebinding to %s as \"%s\"\n",
- url, ldap_state->bind_dn));
+ url, ldap_state->bind_dn?ldap_state->bind_dn:"[Anonymous bind]"));
/* call START_TLS again (ldaps:// is handled by the OpenLDAP library
* itself) before rebinding to another LDAP server to avoid to expose
DEBUG(10,("rebindproc_connect_with_state: "
"setting last_rebind timestamp "
"(req: 0x%02x)\n", (unsigned int)request));
- GetTimeOfDay(&ldap_state->last_rebind);
+ clock_gettime_mono(&ts);
+ ldap_state->last_rebind = convert_timespec_to_timeval(ts);
break;
default:
ZERO_STRUCT(ldap_state->last_rebind);
return rebindproc_with_state(ldap_struct, whop, credp,
method, freeit, ldap_state);
-
}
# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_struct)
{
int rc;
- char *ldap_dn;
- char *ldap_secret;
int version;
- /* get the password */
- if (!fetch_ldap_pw(&ldap_dn, &ldap_secret)) {
- DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
- return LDAP_INVALID_CREDENTIALS;
- }
+ if (!ldap_state->anonymous && !ldap_state->bind_dn) {
+ char *bind_dn = NULL;
+ char *bind_secret = NULL;
- ldap_state->bind_dn = ldap_dn;
- ldap_state->bind_secret = ldap_secret;
+ /* get the default dn and password only if they are not set already */
+ if (!fetch_ldap_pw(&bind_dn, &bind_secret)) {
+ DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
+ return LDAP_INVALID_CREDENTIALS;
+ }
+ smbldap_set_creds(ldap_state, false, bind_dn, bind_secret);
+ SAFE_FREE(bind_dn);
+ memset(bind_secret, '\0', strlen(bind_secret));
+ SAFE_FREE(bind_secret);
+ }
/* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
(OpenLDAP) doesnt' seem to support it */
-
+
DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n",
- ldap_state->uri, ldap_dn));
+ ldap_state->uri, ldap_state->bind_dn));
#ifdef HAVE_LDAP_SET_REBIND_PROC
#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
#endif
- rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
+ rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
if (rc != LDAP_SUCCESS) {
char *ld_error = NULL;
DEBUG(ldap_state->num_failures ? 2 : 0,
("failed to bind to server %s with dn=\"%s\" Error: %s\n\t%s\n",
ldap_state->uri,
- ldap_dn ? ldap_dn : "(unknown)", ldap_err2string(rc),
+ ldap_state->bind_dn ? ldap_state->bind_dn : "[Anonymous bind]",
+ ldap_err2string(rc),
ld_error ? ld_error : "(unknown)"));
SAFE_FREE(ld_error);
ldap_state->num_failures++;
ldap_state->paged_results = True;
}
- DEBUG(3, ("ldap_connect_system: succesful connection to the LDAP server\n"));
+ DEBUG(3, ("ldap_connect_system: successful connection to the LDAP server\n"));
DEBUGADD(10, ("ldap_connect_system: LDAP server %s support paged results\n",
ldap_state->paged_results ? "does" : "does not"));
return rc;
}
+static void smbldap_idle_fn(struct event_context *event_ctx,
+ struct timed_event *te,
+ struct timeval now_abs,
+ void *private_data);
+
/**********************************************************************
Connect to LDAP server (called before every ldap operation)
*********************************************************************/
static int smbldap_open(struct smbldap_state *ldap_state)
{
int rc, opt_rc;
- BOOL reopen = False;
+ bool reopen = False;
SMB_ASSERT(ldap_state);
-
-#ifndef NO_LDAP_SECURITY
- if (geteuid() != 0) {
- DEBUG(0, ("smbldap_open: cannot access LDAP when not root..\n"));
- return LDAP_INSUFFICIENT_ACCESS;
- }
-#endif
- if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + SMBLDAP_DONT_PING_TIME) < time(NULL))) {
+ if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + SMBLDAP_DONT_PING_TIME) < time_mono(NULL))) {
#ifdef HAVE_UNIXSOCKET
struct sockaddr_un addr;
ldap_state->ldap_struct = NULL;
ldap_state->last_ping = (time_t)0;
} else {
- ldap_state->last_ping = time(NULL);
+ ldap_state->last_ping = time_mono(NULL);
}
}
}
- ldap_state->last_ping = time(NULL);
+ ldap_state->last_ping = time_mono(NULL);
ldap_state->pid = sys_getpid();
- DEBUG(4,("The LDAP server is succesfully connected\n"));
+
+ TALLOC_FREE(ldap_state->idle_event);
+
+ if (ldap_state->event_context != NULL) {
+ ldap_state->idle_event = event_add_timed(
+ ldap_state->event_context, ldap_state,
+ timeval_current_ofs(SMBLDAP_IDLE_TIME, 0),
+ smbldap_idle_fn, ldap_state);
+ }
+
+ DEBUG(4,("The LDAP server is successfully connected\n"));
return LDAP_SUCCESS;
}
{
if (!ldap_state)
return NT_STATUS_INVALID_PARAMETER;
-
+
if (ldap_state->ldap_struct != NULL) {
ldap_unbind(ldap_state->ldap_struct);
ldap_state->ldap_struct = NULL;
}
smbldap_delete_state(ldap_state);
-
+
+ TALLOC_FREE(ldap_state->idle_event);
+
DEBUG(5,("The connection to the LDAP server was closed\n"));
/* maybe free the results here --metze */
-
-
return NT_STATUS_OK;
}
-static BOOL got_alarm;
+static bool got_alarm;
static void (*old_handler)(int);
static int another_ldap_try(struct smbldap_state *ldap_state, int *rc,
int *attempts, time_t endtime)
{
- time_t now = time(NULL);
+ time_t now = time_mono(NULL);
int open_rc = LDAP_SERVER_DOWN;
if (*rc != LDAP_SERVER_DOWN)
int rc = LDAP_SERVER_DOWN;
int attempts = 0;
char *utf8_filter;
- time_t endtime = time(NULL)+lp_ldap_timeout();
+ time_t endtime = time_mono(NULL)+lp_ldap_timeout();
struct timeval timeout;
+ size_t converted_size;
SMB_ASSERT(ldap_state);
-
+
DEBUG(5,("smbldap_search_ext: base => [%s], filter => [%s], "
"scope => [%d]\n", base, filter, scope));
if (ldap_state->last_rebind.tv_sec > 0) {
struct timeval tval;
- SMB_BIG_INT tdiff = 0;
+ struct timespec ts;
+ int64_t tdiff = 0;
int sleep_time = 0;
- ZERO_STRUCT(tval);
- GetTimeOfDay(&tval);
+ clock_gettime_mono(&ts);
+ tval = convert_timespec_to_timeval(ts);
tdiff = usec_time_diff(&tval, &ldap_state->last_rebind);
tdiff /= 1000; /* Convert to milliseconds. */
ZERO_STRUCT(ldap_state->last_rebind);
}
- if (push_utf8_allocate(&utf8_filter, filter) == (size_t)-1) {
+ if (!push_utf8_talloc(talloc_tos(), &utf8_filter, filter, &converted_size)) {
return LDAP_NO_MEMORY;
}
* just a bit more kind to the server. VL. */
got_alarm = 0;
- CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
+ CatchSignal(SIGALRM, gotalarm_sig);
alarm(lp_ldap_timeout());
/* End setup timeout. */
while (another_ldap_try(ldap_state, &rc, &attempts, endtime)) {
rc = ldap_search_ext_s(ldap_state->ldap_struct, base, scope,
utf8_filter,
- CONST_DISCARD(char **, attrs),
+ discard_const_p(char *, attrs),
attrsonly, sctrls, cctrls, &timeout,
sizelimit, res);
if (rc != LDAP_SUCCESS) {
char *ld_error = NULL;
+ int ld_errno;
+
+ ldap_get_option(ldap_state->ldap_struct,
+ LDAP_OPT_ERROR_NUMBER, &ld_errno);
+
ldap_get_option(ldap_state->ldap_struct,
LDAP_OPT_ERROR_STRING, &ld_error);
- DEBUG(10,("Failed search for base: %s, error: %s "
- "(%s)\n", base, ldap_err2string(rc),
- ld_error ? ld_error : "unknown"));
+ DEBUG(10, ("Failed search for base: %s, error: %d (%s) "
+ "(%s)\n", base, ld_errno,
+ ldap_err2string(rc),
+ ld_error ? ld_error : "unknown"));
SAFE_FREE(ld_error);
+
+ if (ld_errno == LDAP_SERVER_DOWN) {
+ ldap_unbind(ldap_state->ldap_struct);
+ ldap_state->ldap_struct = NULL;
+ }
}
}
- SAFE_FREE(utf8_filter);
+ TALLOC_FREE(utf8_filter);
/* Teardown timeout. */
- CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
+ CatchSignal(SIGALRM, SIG_IGN);
alarm(0);
if (got_alarm != 0)
BerElement *cookie_be = NULL;
struct berval *cookie_bv = NULL;
int tmp = 0, i, rc;
- BOOL critical = True;
+ bool critical = True;
*res = NULL;
/* construct cookie */
if (*cookie != NULL) {
ber_printf(cookie_be, "{iO}", (ber_int_t) pagesize, *cookie);
- ber_bvfree(*cookie); /* don't need it from last time */
+ ber_bvfree((struct berval *)*cookie); /* don't need it from last time */
*cookie = NULL;
} else {
ber_printf(cookie_be, "{io}", (ber_int_t) pagesize, "", 0);
}
ber_flatten(cookie_be, &cookie_bv);
- pr.ldctl_oid = CONST_DISCARD(char *, ADS_PAGE_CTL_OID);
+ pr.ldctl_oid = discard_const_p(char, ADS_PAGE_CTL_OID);
pr.ldctl_iscritical = (char) critical;
pr.ldctl_value.bv_len = cookie_bv->bv_len;
pr.ldctl_value.bv_val = cookie_bv->bv_val;
goto done;
}
- DEBUG(3,("smbldap_search_paged: search was successfull\n"));
+ DEBUG(3,("smbldap_search_paged: search was successful\n"));
rc = ldap_parse_result(ldap_state->ldap_struct, *res, NULL, NULL,
NULL, NULL, &rcontrols, 0);
int rc = LDAP_SERVER_DOWN;
int attempts = 0;
char *utf8_dn;
- time_t endtime = time(NULL)+lp_ldap_timeout();
+ time_t endtime = time_mono(NULL)+lp_ldap_timeout();
+ size_t converted_size;
SMB_ASSERT(ldap_state);
DEBUG(5,("smbldap_modify: dn => [%s]\n", dn ));
- if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
+ if (!push_utf8_talloc(talloc_tos(), &utf8_dn, dn, &converted_size)) {
return LDAP_NO_MEMORY;
}
rc = ldap_modify_s(ldap_state->ldap_struct, utf8_dn, attrs);
if (rc != LDAP_SUCCESS) {
char *ld_error = NULL;
+ int ld_errno;
+
+ ldap_get_option(ldap_state->ldap_struct,
+ LDAP_OPT_ERROR_NUMBER, &ld_errno);
+
ldap_get_option(ldap_state->ldap_struct,
LDAP_OPT_ERROR_STRING, &ld_error);
- DEBUG(10,("Failed to modify dn: %s, error: %s "
- "(%s)\n", dn, ldap_err2string(rc),
- ld_error ? ld_error : "unknown"));
+ DEBUG(10, ("Failed to modify dn: %s, error: %d (%s) "
+ "(%s)\n", dn, ld_errno,
+ ldap_err2string(rc),
+ ld_error ? ld_error : "unknown"));
SAFE_FREE(ld_error);
+
+ if (ld_errno == LDAP_SERVER_DOWN) {
+ ldap_unbind(ldap_state->ldap_struct);
+ ldap_state->ldap_struct = NULL;
+ }
}
}
-
- SAFE_FREE(utf8_dn);
+
+ TALLOC_FREE(utf8_dn);
return rc;
}
int rc = LDAP_SERVER_DOWN;
int attempts = 0;
char *utf8_dn;
- time_t endtime = time(NULL)+lp_ldap_timeout();
-
+ time_t endtime = time_mono(NULL)+lp_ldap_timeout();
+ size_t converted_size;
+
SMB_ASSERT(ldap_state);
DEBUG(5,("smbldap_add: dn => [%s]\n", dn ));
- if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
+ if (!push_utf8_talloc(talloc_tos(), &utf8_dn, dn, &converted_size)) {
return LDAP_NO_MEMORY;
}
rc = ldap_add_s(ldap_state->ldap_struct, utf8_dn, attrs);
if (rc != LDAP_SUCCESS) {
char *ld_error = NULL;
+ int ld_errno;
+
+ ldap_get_option(ldap_state->ldap_struct,
+ LDAP_OPT_ERROR_NUMBER, &ld_errno);
+
ldap_get_option(ldap_state->ldap_struct,
LDAP_OPT_ERROR_STRING, &ld_error);
- DEBUG(10,("Failed to add dn: %s, error: %s "
- "(%s)\n", dn, ldap_err2string(rc),
- ld_error ? ld_error : "unknown"));
+ DEBUG(10, ("Failed to add dn: %s, error: %d (%s) "
+ "(%s)\n", dn, ld_errno,
+ ldap_err2string(rc),
+ ld_error ? ld_error : "unknown"));
SAFE_FREE(ld_error);
+
+ if (ld_errno == LDAP_SERVER_DOWN) {
+ ldap_unbind(ldap_state->ldap_struct);
+ ldap_state->ldap_struct = NULL;
+ }
}
}
-
- SAFE_FREE(utf8_dn);
+
+ TALLOC_FREE(utf8_dn);
return rc;
}
int rc = LDAP_SERVER_DOWN;
int attempts = 0;
char *utf8_dn;
- time_t endtime = time(NULL)+lp_ldap_timeout();
-
+ time_t endtime = time_mono(NULL)+lp_ldap_timeout();
+ size_t converted_size;
+
SMB_ASSERT(ldap_state);
DEBUG(5,("smbldap_delete: dn => [%s]\n", dn ));
- if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
+ if (!push_utf8_talloc(talloc_tos(), &utf8_dn, dn, &converted_size)) {
return LDAP_NO_MEMORY;
}
rc = ldap_delete_s(ldap_state->ldap_struct, utf8_dn);
if (rc != LDAP_SUCCESS) {
char *ld_error = NULL;
+ int ld_errno;
+
+ ldap_get_option(ldap_state->ldap_struct,
+ LDAP_OPT_ERROR_NUMBER, &ld_errno);
+
ldap_get_option(ldap_state->ldap_struct,
LDAP_OPT_ERROR_STRING, &ld_error);
- DEBUG(10,("Failed to delete dn: %s, error: %s "
- "(%s)\n", dn, ldap_err2string(rc),
- ld_error ? ld_error : "unknown"));
+ DEBUG(10, ("Failed to delete dn: %s, error: %d (%s) "
+ "(%s)\n", dn, ld_errno,
+ ldap_err2string(rc),
+ ld_error ? ld_error : "unknown"));
SAFE_FREE(ld_error);
+
+ if (ld_errno == LDAP_SERVER_DOWN) {
+ ldap_unbind(ldap_state->ldap_struct);
+ ldap_state->ldap_struct = NULL;
+ }
}
}
-
- SAFE_FREE(utf8_dn);
+
+ TALLOC_FREE(utf8_dn);
return rc;
}
{
int rc = LDAP_SERVER_DOWN;
int attempts = 0;
- time_t endtime = time(NULL)+lp_ldap_timeout();
-
+ time_t endtime = time_mono(NULL)+lp_ldap_timeout();
+
if (!ldap_state)
return (-1);
clientctrls, retoidp, retdatap);
if (rc != LDAP_SUCCESS) {
char *ld_error = NULL;
+ int ld_errno;
+
+ ldap_get_option(ldap_state->ldap_struct,
+ LDAP_OPT_ERROR_NUMBER, &ld_errno);
+
ldap_get_option(ldap_state->ldap_struct,
LDAP_OPT_ERROR_STRING, &ld_error);
- DEBUG(10,("Extended operation failed with error: %s "
- "(%s)\n", ldap_err2string(rc),
- ld_error ? ld_error : "unknown"));
+ DEBUG(10, ("Extended operation failed with error: "
+ "%d (%s) (%s)\n", ld_errno,
+ ldap_err2string(rc),
+ ld_error ? ld_error : "unknown"));
SAFE_FREE(ld_error);
+
+ if (ld_errno == LDAP_SERVER_DOWN) {
+ ldap_unbind(ldap_state->ldap_struct);
+ ldap_state->ldap_struct = NULL;
+ }
}
}
-
+
return rc;
}
filter, search_attr, 0, result);
}
-static void smbldap_idle_fn(void **data, time_t *interval, time_t now)
+static void smbldap_idle_fn(struct event_context *event_ctx,
+ struct timed_event *te,
+ struct timeval now_abs,
+ void *private_data)
{
- struct smbldap_state *state = (struct smbldap_state *)(*data);
+ struct smbldap_state *state = (struct smbldap_state *)private_data;
+
+ TALLOC_FREE(state->idle_event);
if (state->ldap_struct == NULL) {
DEBUG(10,("ldap connection not connected...\n"));
return;
}
-
- if ((state->last_use+SMBLDAP_IDLE_TIME) > now) {
+
+ if ((state->last_use+SMBLDAP_IDLE_TIME) > time_mono(NULL)) {
DEBUG(10,("ldap connection not idle...\n"));
+
+ /* this needs to be made monotonic clock aware inside tevent: */
+ state->idle_event = event_add_timed(
+ event_ctx, state,
+ timeval_add(&now_abs, SMBLDAP_IDLE_TIME, 0),
+ smbldap_idle_fn,
+ private_data);
return;
}
-
+
DEBUG(7,("ldap connection idle...closing connection\n"));
smbldap_close(state);
}
void smbldap_free_struct(struct smbldap_state **ldap_state)
{
smbldap_close(*ldap_state);
-
+
if ((*ldap_state)->bind_secret) {
memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
}
SAFE_FREE((*ldap_state)->bind_dn);
SAFE_FREE((*ldap_state)->bind_secret);
- smb_unregister_idle_event((*ldap_state)->event_id);
-
- *ldap_state = NULL;
+ TALLOC_FREE(*ldap_state);
/* No need to free any further, as it is talloc()ed */
}
+static int smbldap_state_destructor(struct smbldap_state *state)
+{
+ smbldap_free_struct(&state);
+ return 0;
+}
+
/**********************************************************************
Intitalise the 'general' ldap structures, on which ldap operations may be conducted
*********************************************************************/
-NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, const char *location, struct smbldap_state **smbldap_state)
+NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, struct event_context *event_ctx,
+ const char *location,
+ struct smbldap_state **smbldap_state)
{
- *smbldap_state = TALLOC_ZERO_P(mem_ctx, struct smbldap_state);
+ *smbldap_state = talloc_zero(mem_ctx, struct smbldap_state);
if (!*smbldap_state) {
DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
return NT_STATUS_NO_MEMORY;
(*smbldap_state)->uri = "ldap://localhost";
}
- (*smbldap_state)->event_id =
- smb_register_idle_event(smbldap_idle_fn, (void *)(*smbldap_state),
- SMBLDAP_IDLE_TIME);
-
- if ((*smbldap_state)->event_id == SMB_EVENT_ID_INVALID) {
- DEBUG(0,("Failed to register LDAP idle event!\n"));
- return NT_STATUS_INVALID_HANDLE;
- }
+ (*smbldap_state)->event_context = event_ctx;
+ talloc_set_destructor(*smbldap_state, smbldap_state_destructor);
return NT_STATUS_OK;
}
-/*******************************************************************
- Return a copy of the DN for a LDAPMessage. Convert from utf8 to CH_UNIX.
-********************************************************************/
-char *smbldap_get_dn(LDAP *ld, LDAPMessage *entry)
-{
- char *utf8_dn, *unix_dn;
-
- utf8_dn = ldap_get_dn(ld, entry);
- if (!utf8_dn) {
- DEBUG (5, ("smbldap_get_dn: ldap_get_dn failed\n"));
- return NULL;
- }
- if (pull_utf8_allocate(&unix_dn, utf8_dn) == (size_t)-1) {
- DEBUG (0, ("smbldap_get_dn: String conversion failure utf8 [%s]\n", utf8_dn));
- return NULL;
- }
- ldap_memfree(utf8_dn);
- return unix_dn;
-}
-
- const char *smbldap_talloc_dn(TALLOC_CTX *mem_ctx, LDAP *ld,
- LDAPMessage *entry)
+ char *smbldap_talloc_dn(TALLOC_CTX *mem_ctx, LDAP *ld,
+ LDAPMessage *entry)
{
char *utf8_dn, *unix_dn;
+ size_t converted_size;
utf8_dn = ldap_get_dn(ld, entry);
if (!utf8_dn) {
- DEBUG (5, ("smbldap_get_dn: ldap_get_dn failed\n"));
+ DEBUG (5, ("smbldap_talloc_dn: ldap_get_dn failed\n"));
return NULL;
}
- if (pull_utf8_talloc(mem_ctx, &unix_dn, utf8_dn) == (size_t)-1) {
- DEBUG (0, ("smbldap_get_dn: String conversion failure utf8 "
+ if (!pull_utf8_talloc(mem_ctx, &unix_dn, utf8_dn, &converted_size)) {
+ DEBUG (0, ("smbldap_talloc_dn: String conversion failure utf8 "
"[%s]\n", utf8_dn));
return NULL;
}
Check if root-dse has a certain Control or Extension
********************************************************************/
-static BOOL smbldap_check_root_dse(LDAP *ld, const char **attrs, const char *value)
+static bool smbldap_check_root_dse(LDAP *ld, const char **attrs, const char *value)
{
LDAPMessage *msg = NULL;
LDAPMessage *entry = NULL;
char **values = NULL;
int rc, num_result, num_values, i;
- BOOL result = False;
+ bool result = False;
if (!attrs[0]) {
DEBUG(3,("smbldap_check_root_dse: nothing to look for\n"));
}
rc = ldap_search_s(ld, "", LDAP_SCOPE_BASE,
- "(objectclass=*)", CONST_DISCARD(char **, attrs), 0 , &msg);
+ "(objectclass=*)", discard_const_p(char *, attrs), 0 , &msg);
if (rc != LDAP_SUCCESS) {
DEBUG(3,("smbldap_check_root_dse: Could not search rootDSE\n"));
Check if LDAP-Server supports a certain Control (OID in string format)
********************************************************************/
-BOOL smbldap_has_control(LDAP *ld, const char *control)
+bool smbldap_has_control(LDAP *ld, const char *control)
{
const char *attrs[] = { "supportedControl", NULL };
return smbldap_check_root_dse(ld, attrs, control);
Check if LDAP-Server supports a certain Extension (OID in string format)
********************************************************************/
-BOOL smbldap_has_extension(LDAP *ld, const char *extension)
+bool smbldap_has_extension(LDAP *ld, const char *extension)
{
const char *attrs[] = { "supportedExtension", NULL };
return smbldap_check_root_dse(ld, attrs, extension);
Check if LDAP-Server holds a given namingContext
********************************************************************/
-BOOL smbldap_has_naming_context(LDAP *ld, const char *naming_context)
+bool smbldap_has_naming_context(LDAP *ld, const char *naming_context)
{
const char *attrs[] = { "namingContexts", NULL };
return smbldap_check_root_dse(ld, attrs, naming_context);
}
+
+bool smbldap_set_creds(struct smbldap_state *ldap_state, bool anon, const char *dn, const char *secret)
+{
+ ldap_state->anonymous = anon;
+
+ /* free any previously set credential */
+
+ SAFE_FREE(ldap_state->bind_dn);
+ if (ldap_state->bind_secret) {
+ /* make sure secrets are zeroed out of memory */
+ memset(ldap_state->bind_secret, '\0', strlen(ldap_state->bind_secret));
+ SAFE_FREE(ldap_state->bind_secret);
+ }
+
+ if ( ! anon) {
+ ldap_state->bind_dn = SMB_STRDUP(dn);
+ ldap_state->bind_secret = SMB_STRDUP(secret);
+ }
+
+ return True;
+}