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" },
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)
-{
- 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]) < 0) {
+ 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_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(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;
+}
+
+ static int ldapmsg_destructor(LDAPMessage **result) {
ldap_msgfree(*result);
return 0;
}
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;
}
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;
if (value != NULL) {
char *utf8_value = NULL;
+ size_t converted_size;
j = 0;
if (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;
+ if (!push_utf8_talloc(talloc_tos(), &utf8_value, value, &converted_size)) {
+ smb_panic("smbldap_set_mod: String conversion failure!");
+ /* notreached. */
}
-
- 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;
}
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;
}
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;
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;
}
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;
}
- 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,
+ 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))) {
+#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();
- 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, NULL,
+ timeval_current_ofs(SMBLDAP_IDLE_TIME, 0),
+ smbldap_idle_fn, ldap_state);
+ }
+
+ DEBUG(4,("The LDAP server is successfully 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);
char *utf8_filter;
time_t endtime = time(NULL)+lp_ldap_timeout();
struct timeval timeout;
+ size_t converted_size;
SMB_ASSERT(ldap_state);
if (ldap_state->last_rebind.tv_sec > 0) {
struct timeval tval;
- SMB_BIG_INT tdiff = 0;
+ int64_t tdiff = 0;
int sleep_time = 0;
ZERO_STRUCT(tval);
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;
}
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);
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);
int attempts = 0;
char *utf8_dn;
time_t endtime = time(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 attempts = 0;
char *utf8_dn;
time_t endtime = time(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 attempts = 0;
char *utf8_dn;
time_t endtime = time(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;
}
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;
+ }
}
}
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,
+ 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,
+ 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 *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_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 *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 "
+ 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(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;
}