char *bind_dn;
char *bind_secret;
+
+ unsigned int num_failures;
};
#define LDAPSAM_DONT_PING_TIME 10 /* ping only all 10 seconds */
int version;
BOOL ldap_v3 = False;
-#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
+#ifdef HAVE_LDAP_INITIALIZE
DEBUG(10, ("ldapsam_open_connection: %s\n", ldap_state->uri));
if ((rc = ldap_initialize(ldap_struct, ldap_state->uri)) != LDAP_SUCCESS) {
rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
if (rc != LDAP_SUCCESS) {
- char *ld_error;
+ char *ld_error = NULL;
ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
&ld_error);
- DEBUG(0,
+ DEBUG(ldap_state->num_failures ? 2 : 0,
("failed to bind to server with dn= %s Error: %s\n\t%s\n",
- ldap_dn, ldap_err2string(rc),
+ ldap_dn ? ld_error : "(unknown)", ldap_err2string(rc),
ld_error));
- free(ld_error);
+ SAFE_FREE(ld_error);
+ ldap_state->num_failures++;
return rc;
}
-
- DEBUG(2, ("ldap_connect_system: succesful connection to the LDAP server\n"));
+
+ ldap_state->num_failures = 0;
+
+ DEBUG(3, ("ldap_connect_system: succesful connection to the LDAP server\n"));
return rc;
}
if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + LDAPSAM_DONT_PING_TIME) < time(NULL))) {
struct sockaddr_un addr;
- socklen_t len;
+ socklen_t len = sizeof(addr);
int sd;
if (ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_DESC, &sd) == 0 &&
getpeername(sd, (struct sockaddr *) &addr, &len) < 0) {
SMB_ASSERT(ldap_state && attempts);
if (*attempts != 0) {
- /* we retry after 0.5, 2, 4.5, 8, 12.5, 18, 24.5 seconds */
- msleep((((*attempts)*(*attempts))/2)*1000);
+ unsigned int sleep_time;
+ uint8 rand_byte = 128; /* a reasonable place to start */
+
+ generate_random_buffer(&rand_byte, 1, False);
+
+ sleep_time = (((*attempts)*(*attempts))/2)*rand_byte*2;
+ /* we retry after (0.5, 1, 2, 3, 4.5, 6) seconds
+ on average.
+ */
+ DEBUG(3, ("Sleeping for %u milliseconds before reconnecting\n",
+ sleep_time));
+ msleep(sleep_time);
}
(*attempts)++;
if ((rc = ldapsam_open(ldap_state))) {
- DEBUG(0,("Connection to LDAP Server failed for the %d try!\n",*attempts));
+ DEBUG(1,("Connection to LDAP Server failed for the %d try!\n",*attempts));
return rc;
}
continue;
rc = ldap_search_s(ldap_state->ldap_struct, base, scope,
- filter, attrs, attrsonly, res);
+ filter, (char **)attrs, attrsonly, res);
}
if (rc == LDAP_SERVER_DOWN) {
return rc;
}
+#ifdef LDAP_EXOP_X_MODIFY_PASSWD
static int ldapsam_extended_operation(struct ldapsam_privates *ldap_state, LDAP_CONST char *reqoid, struct berval *reqdata, LDAPControl **serverctrls, LDAPControl **clientctrls, char **retoidp, struct berval **retdatap)
{
int rc = LDAP_SERVER_DOWN;
return rc;
}
+#endif
/*******************************************************************
run the search by name.
rc = ldapsam_search(ldap_state, lp_ldap_suffix (), scope, filter, attr, 0, result);
if (rc != LDAP_SUCCESS) {
- char *ld_error;
+ char *ld_error = NULL;
ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
&ld_error);
DEBUG(0,("ldapsam_search_one_user: Problem during the LDAP search: %s (%s)\n",
- ld_error, ldap_err2string (rc)));
+ ld_error?ld_error:"(unknown)", ldap_err2string (rc)));
DEBUG(3,("ldapsam_search_one_user: Query was: %s, %s\n", lp_ldap_suffix(),
filter));
SAFE_FREE(ld_error);
ldap_mods_free(mods, 1);
if (rc != LDAP_SUCCESS) {
- char *ld_error;
+ char *ld_error = NULL;
ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
&ld_error);
DEBUG(0, ("could not delete attributes for %s, error: %s (%s)\n",
- dn, ldap_err2string(rc), ld_error));
+ dn, ldap_err2string(rc), ld_error?ld_error:"unknown"));
SAFE_FREE(ld_error);
ldap_memfree(dn);
return NT_STATUS_UNSUCCESSFUL;
* If we are updating the record AND the attribute is CHANGED.
* If we are adding the record AND it is SET or CHANGED (ie not default)
*********************************************************************/
+#ifdef LDAP_EXOP_X_MODIFY_PASSWD
static BOOL need_ldap_mod(BOOL pdb_add, const SAM_ACCOUNT * sampass, enum pdb_elements element) {
if (pdb_add) {
return (!IS_SAM_DEFAULT(sampass, element));
return IS_SAM_CHANGED(sampass, element);
}
}
+#endif
/**********************************************************************
Set attribute to newval in LDAP, regardless of what value the
*********************************************************************/
static void make_ldap_mod(LDAP *ldap_struct, LDAPMessage *existing,
LDAPMod ***mods,
- const SAM_ACCOUNT *sampass,
- BOOL (*need_update)(const SAM_ACCOUNT *,
- enum pdb_elements),
- enum pdb_elements element,
const char *attribute, const char *newval)
{
char **values = NULL;
- if (!need_update(sampass, element)) {
- return;
- }
-
if (existing != NULL) {
values = ldap_get_values(ldap_struct, existing, attribute);
}
* took out adding "objectclass: sambaAccount"
* do this on a per-mod basis
*/
- make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update,
- PDB_USERNAME, "uid", pdb_get_username(sampass));
+ if (need_update(sampass, PDB_USERNAME))
+ make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ "uid", pdb_get_username(sampass));
+
DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass)));
rid = pdb_get_user_rid(sampass);
rid = ldapsam_get_next_available_nua_rid(ldap_state);
if (rid == 0) {
DEBUG(0, ("NO user RID specified on account %s, and "
- "findining next available NUA RID failed, "
+ "finding next available NUA RID failed, "
"cannot store!\n",
pdb_get_username(sampass)));
ldap_mods_free(*mods, 1);
}
slprintf(temp, sizeof(temp) - 1, "%i", rid);
- make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update,
- PDB_USERSID, "rid", temp);
+
+ if (need_update(sampass, PDB_USERSID))
+ make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ "rid", temp);
rid = pdb_get_group_rid(sampass);
}
slprintf(temp, sizeof(temp) - 1, "%i", rid);
- make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update,
- PDB_GROUPSID, "primaryGroupID", temp);
+
+ if (need_update(sampass, PDB_GROUPSID))
+ make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ "primaryGroupID", temp);
/* displayName, cn, and gecos should all be the same
* most easily accomplished by giving them the same OID
* it does not exist.
*/
- make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update,
- PDB_FULLNAME, "displayName",
- pdb_get_fullname(sampass));
+ if (need_update(sampass, PDB_FULLNAME))
+ make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ "displayName", pdb_get_fullname(sampass));
- make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update,
- PDB_ACCTDESC, "description",
- pdb_get_acct_desc(sampass));
+ if (need_update(sampass, PDB_ACCTDESC))
+ make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ "description", pdb_get_acct_desc(sampass));
- make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update,
- PDB_WORKSTATIONS, "userWorkstations",
- pdb_get_workstations(sampass));
+ if (need_update(sampass, PDB_WORKSTATIONS))
+ make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ "userWorkstations", pdb_get_workstations(sampass));
- make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update,
- PDB_SMBHOME, "smbHome",
- pdb_get_homedir(sampass));
+ if (need_update(sampass, PDB_SMBHOME))
+ make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ "smbHome", pdb_get_homedir(sampass));
- make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update,
- PDB_DRIVE, "homeDrive",
- pdb_get_dir_drive(sampass));
+ if (need_update(sampass, PDB_DRIVE))
+ make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ "homeDrive", pdb_get_dir_drive(sampass));
- make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update,
- PDB_LOGONSCRIPT, "scriptPath",
- pdb_get_logon_script(sampass));
+ if (need_update(sampass, PDB_LOGONSCRIPT))
+ make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ "scriptPath", pdb_get_logon_script(sampass));
- make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update,
- PDB_PROFILE, "profilePath",
- pdb_get_profile_path(sampass));
+ if (need_update(sampass, PDB_PROFILE))
+ make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ "profilePath", pdb_get_profile_path(sampass));
slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass));
- make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update,
- PDB_LOGONTIME, "logonTime", temp);
+
+ if (need_update(sampass, PDB_LOGONTIME))
+ make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ "logonTime", temp);
slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
- make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update,
- PDB_LOGOFFTIME, "logoffTime", temp);
+
+ if (need_update(sampass, PDB_LOGOFFTIME))
+ make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ "logoffTime", temp);
slprintf (temp, sizeof (temp) - 1, "%li",
pdb_get_kickoff_time(sampass));
- make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update,
- PDB_KICKOFFTIME, "kickoffTime", temp);
+
+ if (need_update(sampass, PDB_KICKOFFTIME))
+ make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ "kickoffTime", temp);
slprintf (temp, sizeof (temp) - 1, "%li",
pdb_get_pass_can_change_time(sampass));
- make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update,
- PDB_CANCHANGETIME, "pwdCanChange", temp);
+
+ if (need_update(sampass, PDB_CANCHANGETIME))
+ make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ "pwdCanChange", temp);
slprintf (temp, sizeof (temp) - 1, "%li",
pdb_get_pass_must_change_time(sampass));
- make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update,
- PDB_MUSTCHANGETIME, "pwdMustChange", temp);
+
+ if (need_update(sampass, PDB_MUSTCHANGETIME))
+ make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ "pwdMustChange", temp);
if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))||
(lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) {
pdb_sethexpwd (temp, pdb_get_lanman_passwd(sampass),
pdb_get_acct_ctrl(sampass));
- make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update,
- PDB_LMPASSWD, "lmPassword", temp);
+
+ if (need_update(sampass, PDB_LMPASSWD))
+ make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ "lmPassword", temp);
pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass),
pdb_get_acct_ctrl(sampass));
- make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update,
- PDB_NTPASSWD, "ntPassword", temp);
+
+ if (need_update(sampass, PDB_NTPASSWD))
+ make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ "ntPassword", temp);
slprintf (temp, sizeof (temp) - 1, "%li",
pdb_get_pass_last_set_time(sampass));
- make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update,
- PDB_PASSLASTSET, "pwdLastSet", temp);
+
+ if (need_update(sampass, PDB_PASSLASTSET))
+ make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ "pwdLastSet", temp);
}
/* FIXME: Hours stuff goes in LDAP */
- make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, need_update,
- PDB_ACCTCTRL, "acctFlags",
- pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass),
- NEW_PW_FORMAT_SPACE_PADDED_LEN));
+
+ if (need_update(sampass, PDB_ACCTCTRL))
+ make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ "acctFlags",
+ pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass),
+ NEW_PW_FORMAT_SPACE_PADDED_LEN));
+
return True;
}
}
if (rc!=LDAP_SUCCESS) {
- char *ld_error;
+ char *ld_error = NULL;
ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
&ld_error);
DEBUG(1,
("failed to %s user dn= %s with: %s\n\t%s\n",
ldap_op == LDAP_MOD_ADD ? "add" : "modify",
dn, ldap_err2string(rc),
- ld_error));
- free(ld_error);
+ ld_error?ld_error:"unknown"));
+ SAFE_FREE(ld_error);
return NT_STATUS_UNSUCCESSFUL;
}
}
ldap_mods_free(mods,1);
if (!NT_STATUS_IS_OK(ret)) {
- char *ld_error;
+ char *ld_error = NULL;
ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
&ld_error);
DEBUG(0,("failed to modify user with uid = %s, error: %s (%s)\n",
- pdb_get_username(newpwd), ld_error, ldap_err2string(rc)));
+ pdb_get_username(newpwd), ld_error?ld_error:"(unknwon)", ldap_err2string(rc)));
SAFE_FREE(ld_error);
return ret;
}
element_is_set_or_changed)) {
DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
ldap_msgfree(result);
- ldap_mods_free(mods, 1);
return NT_STATUS_UNSUCCESSFUL;
}
filter, group_attr, 0, result);
if (rc != LDAP_SUCCESS) {
- char *ld_error;
+ char *ld_error = NULL;
ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
&ld_error);
DEBUG(0, ("ldapsam_search_one_group: "
"Problem during the LDAP search: LDAP error: %s (%s)",
- ld_error, ldap_err2string(rc)));
+ ld_error?ld_error:"(unknown)", ldap_err2string(rc)));
DEBUG(3, ("ldapsam_search_one_group: Query was: %s, %s\n",
lp_ldap_suffix(), filter));
SAFE_FREE(ld_error);
return True;
}
-static BOOL init_ldap_from_group(struct ldapsam_privates *ldap_state,
- LDAPMod ***mods, int ldap_op,
+static BOOL init_ldap_from_group(LDAP *ldap_struct,
+ LDAPMessage *existing,
+ LDAPMod ***mods,
const GROUP_MAP *map)
{
pstring tmp;
*mods = NULL;
sid_to_string(tmp, &map->sid);
- make_a_mod(mods, ldap_op, "ntSid", tmp);
-
+ make_ldap_mod(ldap_struct, existing, mods, "ntSid", tmp);
snprintf(tmp, sizeof(tmp)-1, "%i", map->sid_name_use);
- make_a_mod(mods, ldap_op, "ntGroupType", tmp);
+ make_ldap_mod(ldap_struct, existing, mods, "ntGroupType", tmp);
- make_a_mod(mods, ldap_op, "displayName", map->nt_name);
- make_a_mod(mods, ldap_op, "description", map->comment);
+ make_ldap_mod(ldap_struct, existing, mods, "displayName", map->nt_name);
+ make_ldap_mod(ldap_struct, existing, mods, "description", map->comment);
return True;
}
tmp = ldap_get_dn(ldap_state->ldap_struct, entry);
pstrcpy(dn, tmp);
ldap_memfree(tmp);
- ldap_msgfree(result);
- if (!init_ldap_from_group(ldap_state, &mods, LDAP_MOD_ADD, map)) {
+ if (!init_ldap_from_group(ldap_state->ldap_struct,
+ result, &mods, map)) {
DEBUG(0, ("init_ldap_from_group failed!\n"));
ldap_mods_free(mods, 1);
+ ldap_msgfree(result);
return NT_STATUS_UNSUCCESSFUL;
}
+ ldap_msgfree(result);
+
if (mods == NULL) {
DEBUG(0, ("mods is empty\n"));
return NT_STATUS_UNSUCCESSFUL;
ldap_mods_free(mods, 1);
if (rc != LDAP_SUCCESS) {
- char *ld_error;
+ char *ld_error = NULL;
ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
&ld_error);
DEBUG(0, ("failed to add group %i error: %s (%s)\n", map->gid,
- ld_error, ldap_err2string(rc)));
+ ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
SAFE_FREE(ld_error);
return NT_STATUS_UNSUCCESSFUL;
}
LDAPMessage *entry;
LDAPMod **mods;
- if (!init_ldap_from_group(ldap_state, &mods, LDAP_MOD_REPLACE, map)) {
- DEBUG(0, ("init_ldap_from_group failed\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (mods == NULL) {
- DEBUG(4, ("mods is empty: nothing to do\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
if (rc != LDAP_SUCCESS) {
- ldap_mods_free(mods, 1);
return NT_STATUS_UNSUCCESSFUL;
}
if (ldap_count_entries(ldap_state->ldap_struct, result) == 0) {
DEBUG(0, ("No group to modify!\n"));
ldap_msgfree(result);
- ldap_mods_free(mods, 1);
return NT_STATUS_UNSUCCESSFUL;
}
entry = ldap_first_entry(ldap_state->ldap_struct, result);
dn = ldap_get_dn(ldap_state->ldap_struct, entry);
- ldap_msgfree(result);
+
+ if (!init_ldap_from_group(ldap_state->ldap_struct,
+ result, &mods, map)) {
+ DEBUG(0, ("init_ldap_from_group failed\n"));
+ ldap_msgfree(result);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ ldap_msgfree(result);
+
+ if (mods == NULL) {
+ DEBUG(4, ("mods is empty: nothing to do\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
rc = ldapsam_modify(ldap_state, dn, mods);
ldap_mods_free(mods, 1);
if (rc != LDAP_SUCCESS) {
- char *ld_error;
+ char *ld_error = NULL;
ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
&ld_error);
DEBUG(0, ("failed to modify group %i error: %s (%s)\n", map->gid,
- ld_error, ldap_err2string(rc)));
+ ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
SAFE_FREE(ld_error);
}