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,
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/>.
*/
{ LDAP_ATTR_LOGOFF_TIME, "logoffTime" },
{ LDAP_ATTR_KICKOFF_TIME, "kickoffTime" },
{ LDAP_ATTR_CN, "cn" },
+ { LDAP_ATTR_SN, "sn" },
{ LDAP_ATTR_DISPLAY_NAME, "displayName" },
{ LDAP_ATTR_HOME_PATH, "smbHome" },
{ LDAP_ATTR_HOME_DRIVE, "homeDrive" },
{ LDAP_ATTR_LOGOFF_TIME, "sambaLogoffTime" },
{ LDAP_ATTR_KICKOFF_TIME, "sambaKickoffTime" },
{ LDAP_ATTR_CN, "cn" },
+ { LDAP_ATTR_SN, "sn" },
{ LDAP_ATTR_DISPLAY_NAME, "displayName" },
{ LDAP_ATTR_HOME_DRIVE, "sambaHomeDrive" },
{ LDAP_ATTR_HOME_PATH, "sambaHomePath" },
{ 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" },
Return the list of attribute names from a mapping table
**********************************************************************/
- const char** get_attr_list( ATTRIB_MAP_ENTRY table[] )
+ const char** get_attr_list( TALLOC_CTX *mem_ctx, ATTRIB_MAP_ENTRY table[] )
{
const char **names;
int i = 0;
i++;
i++;
- names = SMB_MALLOC_ARRAY( 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 = 0;
while ( table[i].attrib != LDAP_ATTR_LIST_END ) {
- names[i] = SMB_STRDUP( table[i].name );
+ names[i] = talloc_strdup( names, table[i].name );
i++;
}
names[i] = NULL;
return names;
}
-/*********************************************************************
- Cleanup
- ********************************************************************/
-
- void free_attr_list( const char **list )
-{
- int i = 0;
-
- if ( !list )
- return;
-
- while ( list[i] ) {
- /* SAFE_FREE generates a warning here that can't be gotten rid
- * of with CONST_DISCARD */
- if (list[i] != NULL) {
- free(CONST_DISCARD(char *, list[i]));
- }
- i+=1;
- }
-
- SAFE_FREE( list );
-}
-
/*******************************************************************
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)
{
return True;
}
- BOOL smbldap_get_single_pstring (LDAP * ldap_struct, LDAPMessage * entry,
- const char *attribute, pstring value)
+ char * smbldap_talloc_single_attribute(LDAP *ldap_struct, LDAPMessage *entry,
+ const char *attribute,
+ TALLOC_CTX *mem_ctx)
{
- return smbldap_get_single_attribute(ldap_struct, entry,
- attribute, value,
- sizeof(pstring));
+ char **values;
+ char *result;
+
+ 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 (ldap_count_values(values) != 1) {
+ DEBUG(10, ("attribute %s has %d values, expected only one\n",
+ attribute, ldap_count_values(values)));
+ ldap_value_free(values);
+ return NULL;
+ }
+
+ if (pull_utf8_talloc(mem_ctx, &result, values[0]) == (size_t)-1) {
+ DEBUG(10, ("pull_utf8_talloc failed\n"));
+ ldap_value_free(values);
+ return NULL;
+ }
+
+ ldap_value_free(values);
+
+#ifdef DEBUG_PASSWORDS
+ DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n",
+ attribute, result));
+#endif
+ return result;
+}
+
+ static int ldapmsg_destructor(LDAPMessage **result) {
+ ldap_msgfree(*result);
+ return 0;
+}
+
+ void talloc_autofree_ldapmsg(TALLOC_CTX *mem_ctx, LDAPMessage *result)
+{
+ LDAPMessage **handle;
+
+ if (result == NULL) {
+ return;
+ }
+
+ handle = TALLOC_P(mem_ctx, LDAPMessage *);
+ SMB_ASSERT(handle != NULL);
+
+ *handle = result;
+ talloc_set_destructor(handle, ldapmsg_destructor);
+}
+
+ static int ldapmod_destructor(LDAPMod ***mod) {
+ ldap_mods_free(*mod, True);
+ return 0;
+}
+
+ void talloc_autofree_ldapmod(TALLOC_CTX *mem_ctx, LDAPMod **mod)
+{
+ LDAPMod ***handle;
+
+ if (mod == NULL) {
+ return;
+ }
+
+ handle = TALLOC_P(mem_ctx, LDAPMod **);
+ SMB_ASSERT(handle != NULL);
+
+ *handle = mod;
+ talloc_set_destructor(handle, ldapmod_destructor);
}
/************************************************************************
if (mods == NULL) {
mods = SMB_MALLOC_P(LDAPMod *);
if (mods == NULL) {
- DEBUG(0, ("make_a_mod: out of memory!\n"));
- return;
+ smb_panic("smbldap_set_mod: out of memory!");
+ /* notreached. */
}
mods[0] = NULL;
}
if (mods[i] == NULL) {
mods = SMB_REALLOC_ARRAY (mods, LDAPMod *, i + 2);
if (mods == NULL) {
- DEBUG(0, ("make_a_mod: out of memory!\n"));
- return;
+ smb_panic("smbldap_set_mod: out of memory!");
+ /* notreached. */
}
mods[i] = SMB_MALLOC_P(LDAPMod);
if (mods[i] == NULL) {
- DEBUG(0, ("make_a_mod: out of memory!\n"));
- return;
+ smb_panic("smbldap_set_mod: out of memory!");
+ /* notreached. */
}
mods[i]->mod_op = modop;
mods[i]->mod_values = NULL;
mods[i]->mod_values = SMB_REALLOC_ARRAY(mods[i]->mod_values, char *, j + 2);
if (mods[i]->mod_values == NULL) {
- DEBUG (0, ("make_a_mod: Memory allocation failure!\n"));
- return;
+ smb_panic("smbldap_set_mod: out of memory!");
+ /* notreached. */
}
if (push_utf8_allocate(&utf8_value, value) == (size_t)-1) {
- DEBUG (0, ("make_a_mod: String conversion failure!\n"));
- return;
+ smb_panic("smbldap_set_mod: String conversion failure!");
+ /* notreached. */
}
mods[i]->mod_values[j] = utf8_value;
const char *attribute, const char *newval)
{
char oldval[2048]; /* current largest allowed value is mungeddial */
- BOOL existed;
+ bool existed;
if (attribute == NULL) {
/* This can actually happen for ldapsam_compat where we for
{
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);
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;
}
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;
}
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;
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
username and password to? */
rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
-
- GetTimeOfDay(&ldap_state->last_rebind);
+
+ /* only set the last rebind timestamp when we did rebind after a
+ * non-read LDAP operation. That way we avoid the replication sleep
+ * after a simple redirected search operation - Guenther */
+
+ switch (request) {
+
+ case LDAP_REQ_MODIFY:
+ case LDAP_REQ_ADD:
+ case LDAP_REQ_DELETE:
+ case LDAP_REQ_MODDN:
+ case LDAP_REQ_EXTENDED:
+ DEBUG(10,("rebindproc_connect_with_state: "
+ "setting last_rebind timestamp "
+ "(req: 0x%02x)\n", (unsigned int)request));
+ GetTimeOfDay(&ldap_state->last_rebind);
+ break;
+ default:
+ ZERO_STRUCT(ldap_state->last_rebind);
+ break;
+ }
return rc;
}
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) {
- 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(&ldap_state->bind_dn, &ldap_state->bind_secret)) {
+ DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
+ return LDAP_INVALID_CREDENTIALS;
+ }
+ }
/* 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)
# if LDAP_SET_REBIND_PROC_ARGS == 2
ldap_set_rebind_proc(ldap_struct, &rebindproc_connect);
ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state);
# endif
#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_get_option(ldap_state->ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);
- if (smbldap_has_control(ldap_state, ADS_PAGE_CTL_OID) && version == 3) {
+ if (smbldap_has_control(ldap_state->ldap_struct, ADS_PAGE_CTL_OID) && version == 3) {
ldap_state->paged_results = True;
}
return rc;
}
+static void smbldap_idle_fn(struct event_context *event_ctx,
+ struct timed_event *te,
+ const struct timeval *now,
+ 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 ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + SMBLDAP_DONT_PING_TIME) < time(NULL))) {
+#ifdef HAVE_UNIXSOCKET
struct sockaddr_un addr;
+#else
+ struct sockaddr addr;
+#endif
socklen_t len = sizeof(addr);
int sd;
#endif
if (reopen) {
/* the other end has died. reopen. */
- ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
+ ldap_unbind(ldap_state->ldap_struct);
ldap_state->ldap_struct = NULL;
ldap_state->last_ping = (time_t)0;
} else {
}
if ((rc = smbldap_connect_system(ldap_state, ldap_state->ldap_struct))) {
- ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
+ ldap_unbind(ldap_state->ldap_struct);
ldap_state->ldap_struct = NULL;
return rc;
}
ldap_state->last_ping = time(NULL);
ldap_state->pid = sys_getpid();
+
+ TALLOC_FREE(ldap_state->idle_event);
+
+ if (ldap_state->event_context != NULL) {
+ ldap_state->idle_event = event_add_timed(
+ ldap_state->event_context, NULL,
+ timeval_current_ofs(SMBLDAP_IDLE_TIME, 0),
+ "smbldap_idle_fn", smbldap_idle_fn, ldap_state);
+ }
+
DEBUG(4,("The LDAP server is succesfully connected\n"));
return LDAP_SUCCESS;
return NT_STATUS_INVALID_PARAMETER;
if (ldap_state->ldap_struct != NULL) {
- ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
+ ldap_unbind(ldap_state->ldap_struct);
ldap_state->ldap_struct = NULL;
}
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);
return True;
}
+ if (open_rc == LDAP_INSUFFICIENT_ACCESS) {
+ /* The fact that we are non-root or any other
+ * access-denied condition will not change in the next
+ * round of trying */
+ *rc = open_rc;
+ break;
+ }
+
if (got_alarm) {
*rc = LDAP_TIMEOUT;
break;
alarm(lp_ldap_timeout());
/* End setup timeout. */
- while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
+ 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),
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: %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);
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);
return LDAP_NO_MEMORY;
}
- while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
+ while (another_ldap_try(ldap_state, &rc, &attempts, endtime)) {
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: %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);
return rc;
return LDAP_NO_MEMORY;
}
- while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
+ while (another_ldap_try(ldap_state, &rc, &attempts, endtime)) {
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: %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);
return rc;
return LDAP_NO_MEMORY;
}
- while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
+ while (another_ldap_try(ldap_state, &rc, &attempts, endtime)) {
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: %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);
return rc;
if (!ldap_state)
return (-1);
- while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
+ while (another_ldap_try(ldap_state, &rc, &attempts, endtime)) {
rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid,
reqdata, serverctrls,
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: "
+ "%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;
}
/*******************************************************************
run the search by name.
******************************************************************/
-int smbldap_search_suffix (struct smbldap_state *ldap_state, const char *filter,
- const char **search_attr, LDAPMessage ** result)
+int smbldap_search_suffix (struct smbldap_state *ldap_state,
+ const char *filter, const char **search_attr,
+ LDAPMessage ** result)
{
- int scope = LDAP_SCOPE_SUBTREE;
- int rc;
-
- rc = smbldap_search(ldap_state, lp_ldap_suffix(), scope, filter, search_attr, 0, result);
-
- if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
- &ld_error);
- DEBUG(0,("smbldap_search_suffix: Problem during the LDAP search: %s (%s)\n",
- ld_error?ld_error:"(unknown)", ldap_err2string (rc)));
- SAFE_FREE(ld_error);
- }
-
- return rc;
+ return smbldap_search(ldap_state, lp_ldap_suffix(), LDAP_SCOPE_SUBTREE,
+ 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,
+ const struct timeval *now,
+ 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) > now->tv_sec) {
DEBUG(10,("ldap connection not idle...\n"));
+
+ state->idle_event = event_add_timed(
+ event_ctx, NULL,
+ timeval_add(now, SMBLDAP_IDLE_TIME, 0),
+ "smbldap_idle_fn", smbldap_idle_fn,
+ private_data);
return;
}
SAFE_FREE((*ldap_state)->bind_dn);
SAFE_FREE((*ldap_state)->bind_secret);
- smb_unregister_idle_event((*ldap_state)->event_id);
+ TALLOC_FREE((*ldap_state)->idle_event);
*ldap_state = NULL;
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);
if (!*smbldap_state) {
(*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;
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;
return unix_dn;
}
+ const char *smbldap_talloc_dn(TALLOC_CTX *mem_ctx, 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_talloc(mem_ctx, &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;
+}
+
/*******************************************************************
Check if root-dse has a certain Control or Extension
********************************************************************/
-static BOOL smbldap_check_root_dse(struct smbldap_state *ldap_state, 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"));
return False;
}
- rc = ldap_search_s(ldap_state->ldap_struct, "", LDAP_SCOPE_BASE,
+ rc = ldap_search_s(ld, "", LDAP_SCOPE_BASE,
"(objectclass=*)", CONST_DISCARD(char **, attrs), 0 , &msg);
if (rc != LDAP_SUCCESS) {
return False;
}
- num_result = ldap_count_entries(ldap_state->ldap_struct, msg);
+ num_result = ldap_count_entries(ld, msg);
if (num_result != 1) {
DEBUG(3,("smbldap_check_root_dse: Expected one rootDSE, got %d\n", num_result));
goto done;
}
- entry = ldap_first_entry(ldap_state->ldap_struct, msg);
+ entry = ldap_first_entry(ld, msg);
if (entry == NULL) {
DEBUG(3,("smbldap_check_root_dse: Could not retrieve rootDSE\n"));
goto done;
}
- values = ldap_get_values(ldap_state->ldap_struct, entry, attrs[0]);
+ values = ldap_get_values(ld, entry, attrs[0]);
if (values == NULL) {
DEBUG(5,("smbldap_check_root_dse: LDAP Server does not support any %s\n", attrs[0]));
Check if LDAP-Server supports a certain Control (OID in string format)
********************************************************************/
-BOOL smbldap_has_control(struct smbldap_state *ldap_state, const char *control)
+bool smbldap_has_control(LDAP *ld, const char *control)
{
const char *attrs[] = { "supportedControl", NULL };
- return smbldap_check_root_dse(ldap_state, attrs, control);
+ return smbldap_check_root_dse(ld, attrs, control);
}
/*******************************************************************
Check if LDAP-Server supports a certain Extension (OID in string format)
********************************************************************/
-BOOL smbldap_has_extension(struct smbldap_state *ldap_state, const char *extension)
+bool smbldap_has_extension(LDAP *ld, const char *extension)
{
const char *attrs[] = { "supportedExtension", NULL };
- return smbldap_check_root_dse(ldap_state, attrs, extension);
+ return smbldap_check_root_dse(ld, attrs, extension);
}
/*******************************************************************
Check if LDAP-Server holds a given namingContext
********************************************************************/
-BOOL smbldap_has_naming_context(struct smbldap_state *ldap_state, 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(ldap_state, attrs, naming_context);
+ 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;
}