diff options
author | Andrew Bartlett <abartlet@samba.org> | 2002-10-26 01:47:38 +0000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2002-10-26 01:47:38 +0000 |
commit | 991f6ddac6fb358098cb4a751144b31d2ec4d60f (patch) | |
tree | 65907ddb4ea73d64cc4d9353c01e4e1f6e59bff2 /source3 | |
parent | dbfc2f42a2c4711f539364d3954b9b9c10dbddf5 (diff) | |
download | samba-991f6ddac6fb358098cb4a751144b31d2ec4d60f.tar.gz samba-991f6ddac6fb358098cb4a751144b31d2ec4d60f.tar.bz2 samba-991f6ddac6fb358098cb4a751144b31d2ec4d60f.zip |
One more step towards to better PDC.
This patch, from "Stefan (metze) Metzmacher" <metze@metzemix.de> implements an
LDAP connection cache. This removes the quite silly situation where every
single passdb operation involved a new LDAP connection.
The hope is that this will give us a decent performance boost in some usrmgr
related activities, and in the sid->name/sid->uid code.
The remaining things I think are 'todo' for pdb_ldap (in the near term) are:
- intergrate volker's next_rid patch for NUA accounts,
- add a 'trust ldap ids' option (remove Get_Pwnam() hit on enumerations).
- put the group mapping actually into ldap
- Schema fixes and do utf8 conversion
- server failover (try a second server for the rebind on fail)
- ensure we block between an 'add' and the ldap master replicating to our
local slave (mezte found this issue, kills domain joins)
Andrew Bartlett
(This used to be commit 3418da16456511490beb0d1045fff24576b48273)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/passdb/pdb_ldap.c | 538 |
1 files changed, 330 insertions, 208 deletions
diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 63c422abea..7be05d63b6 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -64,6 +64,7 @@ struct ldapsam_privates { LDAPMessage *entry; int index; + time_t last_ping; /* retrive-once info */ const char *uri; @@ -76,6 +77,7 @@ struct ldapsam_privates { char *bind_secret; }; +#define LDAPSAM_DONT_PING_TIME 10 /* ping only all 10 seconds */ static struct ldapsam_privates *static_ldap_state; @@ -152,7 +154,7 @@ static const char *attr[] = {"uid", "pwdLastSet", "logonTime", "userWorkstations", "rid", "primaryGroupID", "lmPassword", "ntPassword", "acctFlags", - "domain", "description", NULL }; + "domain", NULL }; /******************************************************************* open a connection to the ldap server. @@ -422,17 +424,220 @@ static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * l return True; } +/********************************************************************** +Connect to LDAP server +*********************************************************************/ +static NTSTATUS ldapsam_open(struct ldapsam_privates *ldap_state) +{ + if (!ldap_state) + return NT_STATUS_INVALID_PARAMETER; + + if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + LDAPSAM_DONT_PING_TIME) < time(NULL))) { + struct sockaddr_un addr; + socklen_t len; + int sd; + if (ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_DESC, &sd) == 0 && + getpeername(sd, (struct sockaddr *) &addr, &len) < 0) { + /* the other end has died. reopen. */ + ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL); + ldap_state->ldap_struct = NULL; + ldap_state->last_ping = (time_t)0; + } else { + ldap_state->last_ping = time(NULL); + } + } + + if (ldap_state->ldap_struct != NULL) { + DEBUG(5,("ldapsam_open: allready connected to the LDAP server\n")); + return NT_STATUS_OK; + } + + if (!ldapsam_open_connection(ldap_state, &ldap_state->ldap_struct)) { + return NT_STATUS_UNSUCCESSFUL; + } + if (!ldapsam_connect_system(ldap_state, ldap_state->ldap_struct)) { + ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL); + ldap_state->ldap_struct = NULL; + return NT_STATUS_UNSUCCESSFUL; + } + + + ldap_state->last_ping = time(NULL); + DEBUG(4,("The LDAP server is succesful connected\n")); + + return NT_STATUS_OK; +} + +/********************************************************************** +Disconnect from LDAP server +*********************************************************************/ +static NTSTATUS ldapsam_close(struct ldapsam_privates *ldap_state) +{ + if (!ldap_state) + return NT_STATUS_INVALID_PARAMETER; + + if (ldap_state->ldap_struct != NULL) { + ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL); + 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 int ldapsam_retry_open(struct ldapsam_privates *ldap_state, int *attempts) +{ + if (!ldap_state || !attempts) + return (-1); + + if (*attempts != 0) { + /* we retry after 0.5, 2, 4.5, 8, 12.5, 18, 24.5 seconds */ + msleep((((*attempts)*(*attempts))/2)*1000); + } + (*attempts)++; + + if (!NT_STATUS_IS_OK(ldapsam_open(ldap_state))){ + DEBUG(0,("Connection to LDAP Server failed for the %d try!\n",*attempts)); + return LDAP_SERVER_DOWN; + } + + return LDAP_SUCCESS; +} + + +static int ldapsam_search(struct ldapsam_privates *ldap_state, char *base, int scope, char *filter, char *attrs[], int attrsonly, LDAPMessage **res) +{ + int rc = LDAP_SERVER_DOWN; + int attempts = 0; + + if (!ldap_state) + return (-1); + + while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) { + + if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS) + continue; + + rc = ldap_search_s(ldap_state->ldap_struct, base, scope, filter, attrs, attrsonly, res); + } + + if (rc == LDAP_SERVER_DOWN) { + DEBUG(0,("%s: LDAP server is down!\n",__FUNCTION__)); + ldapsam_close(ldap_state); + } + + return rc; +} + +static int ldapsam_modify(struct ldapsam_privates *ldap_state, char *dn, LDAPMod *attrs[]) +{ + int rc = LDAP_SERVER_DOWN; + int attempts = 0; + + if (!ldap_state) + return (-1); + + while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) { + + if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS) + continue; + + rc = ldap_modify_s(ldap_state->ldap_struct, dn, attrs); + } + + if (rc == LDAP_SERVER_DOWN) { + DEBUG(0,("%s: LDAP server is down!\n",__FUNCTION__)); + ldapsam_close(ldap_state); + } + + return rc; +} + +static int ldapsam_add(struct ldapsam_privates *ldap_state, const char *dn, LDAPMod *attrs[]) +{ + int rc = LDAP_SERVER_DOWN; + int attempts = 0; + + if (!ldap_state) + return (-1); + + while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) { + + if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS) + continue; + + rc = ldap_add_s(ldap_state->ldap_struct, dn, attrs); + } + + if (rc == LDAP_SERVER_DOWN) { + DEBUG(0,("%s: LDAP server is down!\n",__FUNCTION__)); + ldapsam_close(ldap_state); + } + + return rc; +} + +static int ldapsam_delete(struct ldapsam_privates *ldap_state, char *dn) +{ + int rc = LDAP_SERVER_DOWN; + int attempts = 0; + + if (!ldap_state) + return (-1); + + while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) { + + if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS) + continue; + + rc = ldap_delete_s(ldap_state->ldap_struct, dn); + } + + if (rc == LDAP_SERVER_DOWN) { + DEBUG(0,("%s: LDAP server is down!\n",__FUNCTION__)); + ldapsam_close(ldap_state); + } + + return rc; +} + +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; + int attempts = 0; + + if (!ldap_state) + return (-1); + + while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) { + + if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS) + continue; + + rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid, reqdata, serverctrls, clientctrls, retoidp, retdatap); + } + + if (rc == LDAP_SERVER_DOWN) { + DEBUG(0,("%s: LDAP server is down!\n",__FUNCTION__)); + ldapsam_close(ldap_state); + } + + return rc; +} + /******************************************************************* run the search by name. ******************************************************************/ -static int ldapsam_search_one_user (struct ldapsam_privates *ldap_state, LDAP * ldap_struct, const char *filter, LDAPMessage ** result) +static int ldapsam_search_one_user (struct ldapsam_privates *ldap_state, const char *filter, LDAPMessage ** result) { int scope = LDAP_SCOPE_SUBTREE; int rc; DEBUG(2, ("ldapsam_search_one_user: searching for:[%s]\n", filter)); - rc = ldap_search_s(ldap_struct, lp_ldap_suffix (), scope, filter, (char **)attr, 0, result); + rc = ldapsam_search(ldap_state, lp_ldap_suffix (), scope, (char *)filter, (char **)attr, 0, result); if (rc != LDAP_SUCCESS) { DEBUG(0,("ldapsam_search_one_user: Problem during the LDAP search: %s\n", @@ -447,7 +652,7 @@ static int ldapsam_search_one_user (struct ldapsam_privates *ldap_state, LDAP * /******************************************************************* run the search by name. ******************************************************************/ -static int ldapsam_search_one_user_by_name (struct ldapsam_privates *ldap_state, LDAP * ldap_struct, const char *user, +static int ldapsam_search_one_user_by_name (struct ldapsam_privates *ldap_state, const char *user, LDAPMessage ** result) { pstring filter; @@ -464,14 +669,14 @@ static int ldapsam_search_one_user_by_name (struct ldapsam_privates *ldap_state, */ all_string_sub(filter, "%u", user, sizeof(pstring)); - return ldapsam_search_one_user(ldap_state, ldap_struct, filter, result); + return ldapsam_search_one_user(ldap_state, filter, result); } /******************************************************************* run the search by uid. ******************************************************************/ static int ldapsam_search_one_user_by_uid(struct ldapsam_privates *ldap_state, - LDAP * ldap_struct, int uid, + int uid, LDAPMessage ** result) { struct passwd *user; @@ -490,14 +695,14 @@ static int ldapsam_search_one_user_by_uid(struct ldapsam_privates *ldap_state, passwd_free(&user); - return ldapsam_search_one_user(ldap_state, ldap_struct, filter, result); + return ldapsam_search_one_user(ldap_state, filter, result); } /******************************************************************* run the search by rid. ******************************************************************/ static int ldapsam_search_one_user_by_rid (struct ldapsam_privates *ldap_state, - LDAP * ldap_struct, uint32 rid, + uint32 rid, LDAPMessage ** result) { pstring filter; @@ -506,10 +711,10 @@ static int ldapsam_search_one_user_by_rid (struct ldapsam_privates *ldap_state, /* check if the user rid exsists, if not, try searching on the uid */ snprintf(filter, sizeof(filter) - 1, "rid=%i", rid); - rc = ldapsam_search_one_user(ldap_state, ldap_struct, filter, result); + rc = ldapsam_search_one_user(ldap_state, filter, result); if (rc != LDAP_SUCCESS) - rc = ldapsam_search_one_user_by_uid(ldap_state, ldap_struct, + rc = ldapsam_search_one_user_by_uid(ldap_state, fallback_pdb_user_rid_to_uid(rid), result); @@ -621,7 +826,7 @@ Initialize SAM_ACCOUNT from an LDAP query *********************************************************************/ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, SAM_ACCOUNT * sampass, - LDAP * ldap_struct, LDAPMessage * entry) + LDAPMessage * entry) { time_t logon_time, logoff_time, @@ -643,8 +848,8 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, struct passwd *pw; uint32 user_rid, group_rid; - uint8 smblmpwd[16], - smbntpwd[16]; + uint8 smblmpwd[LM_HASH_LEN], + smbntpwd[NT_HASH_LEN]; uint16 acct_ctrl, logon_divs; uint32 hours_len; @@ -670,24 +875,34 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, workstations[0] = '\0'; - if (sampass == NULL || ldap_struct == NULL || entry == NULL) { + if (sampass == NULL || ldap_state == NULL || entry == NULL) { DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n")); return False; } - get_single_attribute(ldap_struct, entry, "uid", username); + if (ldap_state->ldap_struct == NULL) { + DEBUG(0, ("init_sam_from_ldap: ldap_state->ldap_struct is NULL!\n")); + return False; + } + + get_single_attribute(ldap_state->ldap_struct, entry, "uid", username); DEBUG(2, ("Entry found for user: %s\n", username)); pstrcpy(nt_username, username); pstrcpy(domain, lp_workgroup()); + + pdb_set_username(sampass, username, PDB_SET); + + pdb_set_domain(sampass, domain, PDB_DEFAULT); + pdb_set_nt_username(sampass, nt_username, PDB_SET); - get_single_attribute(ldap_struct, entry, "rid", temp); + get_single_attribute(ldap_state->ldap_struct, entry, "rid", temp); user_rid = (uint32)atol(temp); pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET); - if (!get_single_attribute(ldap_struct, entry, "primaryGroupID", temp)) { + if (!get_single_attribute(ldap_state->ldap_struct, entry, "primaryGroupID", temp)) { group_rid = 0; } else { group_rid = (uint32)atol(temp); @@ -731,42 +946,42 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, } } - if (!get_single_attribute(ldap_struct, entry, "pwdLastSet", temp)) { + if (!get_single_attribute(ldap_state->ldap_struct, entry, "pwdLastSet", temp)) { /* leave as default */ } else { pass_last_set_time = (time_t) atol(temp); pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET); } - if (!get_single_attribute(ldap_struct, entry, "logonTime", temp)) { + if (!get_single_attribute(ldap_state->ldap_struct, entry, "logonTime", temp)) { /* leave as default */ } else { logon_time = (time_t) atol(temp); pdb_set_logon_time(sampass, logon_time, PDB_SET); } - if (!get_single_attribute(ldap_struct, entry, "logoffTime", temp)) { + if (!get_single_attribute(ldap_state->ldap_struct, entry, "logoffTime", temp)) { /* leave as default */ } else { logoff_time = (time_t) atol(temp); pdb_set_logoff_time(sampass, logoff_time, PDB_SET); } - if (!get_single_attribute(ldap_struct, entry, "kickoffTime", temp)) { + if (!get_single_attribute(ldap_state->ldap_struct, entry, "kickoffTime", temp)) { /* leave as default */ } else { kickoff_time = (time_t) atol(temp); pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET); } - if (!get_single_attribute(ldap_struct, entry, "pwdCanChange", temp)) { + if (!get_single_attribute(ldap_state->ldap_struct, entry, "pwdCanChange", temp)) { /* leave as default */ } else { pass_can_change_time = (time_t) atol(temp); pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET); } - if (!get_single_attribute(ldap_struct, entry, "pwdMustChange", temp)) { + if (!get_single_attribute(ldap_state->ldap_struct, entry, "pwdMustChange", temp)) { /* leave as default */ } else { pass_must_change_time = (time_t) atol(temp); @@ -779,8 +994,8 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, * that fits your needs; using cn then displayName rather than 'userFullName' */ - if (!get_single_attribute(ldap_struct, entry, "cn", fullname)) { - if (!get_single_attribute(ldap_struct, entry, "displayName", fullname)) { + if (!get_single_attribute(ldap_state->ldap_struct, entry, "cn", fullname)) { + if (!get_single_attribute(ldap_state->ldap_struct, entry, "displayName", fullname)) { /* leave as default */ } else { pdb_set_fullname(sampass, fullname, PDB_SET); @@ -789,7 +1004,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_fullname(sampass, fullname, PDB_SET); } - if (!get_single_attribute(ldap_struct, entry, "homeDrive", dir_drive)) { + if (!get_single_attribute(ldap_state->ldap_struct, entry, "homeDrive", dir_drive)) { pdb_set_dir_drive(sampass, talloc_sub_specified(sampass->mem_ctx, lp_logon_drive(), username, domain, @@ -799,7 +1014,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_dir_drive(sampass, dir_drive, PDB_SET); } - if (!get_single_attribute(ldap_struct, entry, "smbHome", homedir)) { + if (!get_single_attribute(ldap_state->ldap_struct, entry, "smbHome", homedir)) { pdb_set_homedir(sampass, talloc_sub_specified(sampass->mem_ctx, lp_logon_home(), username, domain, @@ -809,7 +1024,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_homedir(sampass, homedir, PDB_SET); } - if (!get_single_attribute(ldap_struct, entry, "scriptPath", logon_script)) { + if (!get_single_attribute(ldap_state->ldap_struct, entry, "scriptPath", logon_script)) { pdb_set_logon_script(sampass, talloc_sub_specified(sampass->mem_ctx, lp_logon_script(), username, domain, @@ -819,7 +1034,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_logon_script(sampass, logon_script, PDB_SET); } - if (!get_single_attribute(ldap_struct, entry, "profilePath", profile_path)) { + if (!get_single_attribute(ldap_state->ldap_struct, entry, "profilePath", profile_path)) { pdb_set_profile_path(sampass, talloc_sub_specified(sampass->mem_ctx, lp_logon_path(), username, domain, @@ -829,13 +1044,13 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_profile_path(sampass, profile_path, PDB_SET); } - if (!get_single_attribute(ldap_struct, entry, "description", acct_desc)) { + if (!get_single_attribute(ldap_state->ldap_struct, entry, "description", acct_desc)) { /* leave as default */ } else { pdb_set_acct_desc(sampass, acct_desc, PDB_SET); } - if (!get_single_attribute(ldap_struct, entry, "userWorkstations", workstations)) { + if (!get_single_attribute(ldap_state->ldap_struct, entry, "userWorkstations", workstations)) { /* leave as default */; } else { pdb_set_workstations(sampass, workstations, PDB_SET); @@ -847,7 +1062,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, hours_len = 21; memset(hours, 0xff, hours_len); - if (!get_single_attribute (ldap_struct, entry, "lmPassword", temp)) { + if (!get_single_attribute (ldap_state->ldap_struct, entry, "lmPassword", temp)) { /* leave as default */ } else { pdb_gethexpwd(temp, smblmpwd); @@ -857,7 +1072,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, ZERO_STRUCT(smblmpwd); } - if (!get_single_attribute (ldap_struct, entry, "ntPassword", temp)) { + if (!get_single_attribute (ldap_state->ldap_struct, entry, "ntPassword", temp)) { /* leave as default */ } else { pdb_gethexpwd(temp, smbntpwd); @@ -867,7 +1082,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, ZERO_STRUCT(smbntpwd); } - if (!get_single_attribute (ldap_struct, entry, "acctFlags", temp)) { + if (!get_single_attribute (ldap_state->ldap_struct, entry, "acctFlags", temp)) { acct_ctrl |= ACB_NORMAL; } else { acct_ctrl = pdb_decode_acct_ctrl(temp); @@ -881,11 +1096,6 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_hours_len(sampass, hours_len, PDB_SET); pdb_set_logon_divs(sampass, logon_divs, PDB_SET); - pdb_set_username(sampass, username, PDB_SET); - - pdb_set_domain(sampass, domain, PDB_DEFAULT); - pdb_set_nt_username(sampass, nt_username, PDB_SET); - pdb_set_munged_dial(sampass, munged_dial, PDB_SET); /* pdb_set_unknown_3(sampass, unknown3, PDB_SET); */ @@ -1068,7 +1278,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, /********************************************************************** Connect to LDAP server and find the next available RID. *********************************************************************/ -static uint32 check_nua_rid_is_avail(struct ldapsam_privates *ldap_state, uint32 top_rid, LDAP *ldap_struct) +static uint32 check_nua_rid_is_avail(struct ldapsam_privates *ldap_state, uint32 top_rid) { LDAPMessage *result; uint32 final_rid = (top_rid & (~USER_RID_TYPE)) + RID_MULTIPLIER; @@ -1080,13 +1290,13 @@ static uint32 check_nua_rid_is_avail(struct ldapsam_privates *ldap_state, uint32 return 0; } - if (ldapsam_search_one_user_by_rid(ldap_state, ldap_struct, final_rid, &result) != LDAP_SUCCESS) { + if (ldapsam_search_one_user_by_rid(ldap_state, final_rid, &result) != LDAP_SUCCESS) { DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the confirmation search failed!\n", final_rid, final_rid)); ldap_msgfree(result); return 0; } - if (ldap_count_entries(ldap_struct, result) != 0) { + if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) { DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the RID is already in use!!\n", final_rid, final_rid)); ldap_msgfree(result); return 0; @@ -1100,14 +1310,14 @@ static uint32 check_nua_rid_is_avail(struct ldapsam_privates *ldap_state, uint32 /********************************************************************** Extract the RID from an LDAP entry *********************************************************************/ -static uint32 entry_to_user_rid(struct ldapsam_privates *ldap_state, LDAPMessage *entry, LDAP *ldap_struct) { +static uint32 entry_to_user_rid(struct ldapsam_privates *ldap_state, LDAPMessage *entry) { uint32 rid; SAM_ACCOUNT *user = NULL; if (!NT_STATUS_IS_OK(pdb_init_sam(&user))) { return 0; } - if (init_sam_from_ldap(ldap_state, user, ldap_struct, entry)) { + if (init_sam_from_ldap(ldap_state, user, entry)) { rid = pdb_get_user_rid(user); } else { rid =0; @@ -1123,7 +1333,7 @@ static uint32 entry_to_user_rid(struct ldapsam_privates *ldap_state, LDAPMessage /********************************************************************** Connect to LDAP server and find the next available RID. *********************************************************************/ -static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state, LDAP *ldap_struct) +static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state) { int rc; pstring filter; @@ -1144,7 +1354,7 @@ static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state, LDAP *ldap #endif DEBUG(2, ("ldapsam_get_next_available_nua_rid: searching for:[%s]\n", final_filter)); - rc = ldap_search_s(ldap_struct, lp_ldap_suffix(), + rc = ldapsam_search(ldap_state, lp_ldap_suffix(), LDAP_SCOPE_SUBTREE, final_filter, (char **)attr, 0, &result); @@ -1158,7 +1368,7 @@ static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state, LDAP *ldap return 0; } - count = ldap_count_entries(ldap_struct, result); + count = ldap_count_entries(ldap_state->ldap_struct, result); DEBUG(2, ("search_top_nua_rid: %d entries in the base!\n", count)); if (count == 0) { @@ -1171,13 +1381,13 @@ static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state, LDAP *ldap } free(final_filter); - entry = ldap_first_entry(ldap_struct,result); + entry = ldap_first_entry(ldap_state->ldap_struct,result); - top_rid = entry_to_user_rid(ldap_state, entry, ldap_struct); + top_rid = entry_to_user_rid(ldap_state, entry); - while ((entry = ldap_next_entry(ldap_struct, entry))) { + while ((entry = ldap_next_entry(ldap_state->ldap_struct, entry))) { - rid = entry_to_user_rid(ldap_state, entry, ldap_struct); + rid = entry_to_user_rid(ldap_state, entry); if (rid > top_rid) { top_rid = rid; } @@ -1195,24 +1405,14 @@ static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state, LDAP *ldap Connect to LDAP server and find the next available RID. *********************************************************************/ static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state) { - LDAP *ldap_struct; uint32 next_nua_rid; uint32 top_nua_rid; - if (!ldapsam_open_connection(ldap_state, &ldap_struct)) { - return 0; - } - if (!ldapsam_connect_system(ldap_state, ldap_struct)) { - ldap_unbind(ldap_struct); - return 0; - } - - top_nua_rid = search_top_nua_rid(ldap_state, ldap_struct); + top_nua_rid = search_top_nua_rid(ldap_state); next_nua_rid = check_nua_rid_is_avail(ldap_state, - top_nua_rid, ldap_struct); + top_nua_rid); - ldap_unbind(ldap_struct); return next_nua_rid; } @@ -1221,23 +1421,14 @@ Connect to LDAP server for password enumeration *********************************************************************/ static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update) { - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; int rc; pstring filter; - if (!ldapsam_open_connection(ldap_state, &ldap_state->ldap_struct)) { - return ret; - } - if (!ldapsam_connect_system(ldap_state, ldap_state->ldap_struct)) { - ldap_unbind(ldap_state->ldap_struct); - return ret; - } - pstrcpy(filter, lp_ldap_filter()); all_string_sub(filter, "%u", "*", sizeof(pstring)); - rc = ldap_search_s(ldap_state->ldap_struct, lp_ldap_suffix(), + rc = ldapsam_search(ldap_state, lp_ldap_suffix(), LDAP_SCOPE_SUBTREE, filter, (char **)attr, 0, &ldap_state->result); @@ -1245,10 +1436,8 @@ static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update) DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc))); DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter)); ldap_msgfree(ldap_state->result); - ldap_unbind(ldap_state->ldap_struct); - ldap_state->ldap_struct = NULL; ldap_state->result = NULL; - return ret; + return NT_STATUS_UNSUCCESSFUL; } DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n", @@ -1268,10 +1457,8 @@ End enumeration of the LDAP password list static void ldapsam_endsampwent(struct pdb_methods *my_methods) { struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; - if (ldap_state->ldap_struct && ldap_state->result) { + if (ldap_state->result) { ldap_msgfree(ldap_state->result); - ldap_unbind(ldap_state->ldap_struct); - ldap_state->ldap_struct = NULL; ldap_state->result = NULL; } } @@ -1294,8 +1481,7 @@ static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT return ret; ldap_state->index++; - bret = init_sam_from_ldap(ldap_state, user, ldap_state->ldap_struct, - ldap_state->entry); + bret = init_sam_from_ldap(ldap_state, user, ldap_state->entry); ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct, ldap_state->entry); @@ -1311,41 +1497,29 @@ static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT { NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; - LDAP *ldap_struct; LDAPMessage *result; LDAPMessage *entry; - if (!ldapsam_open_connection(ldap_state, &ldap_struct)) - return ret; - if (!ldapsam_connect_system(ldap_state, ldap_struct)) { - ldap_unbind(ldap_struct); - return ret; - } - if (ldapsam_search_one_user_by_name(ldap_state, ldap_struct, sname, &result) != LDAP_SUCCESS) { - ldap_unbind(ldap_struct); - return ret; + if (ldapsam_search_one_user_by_name(ldap_state, sname, &result) != LDAP_SUCCESS) { + return NT_STATUS_UNSUCCESSFUL; } - if (ldap_count_entries(ldap_struct, result) < 1) { + if (ldap_count_entries(ldap_state->ldap_struct, result) < 1) { DEBUG(4, ("We don't find this user [%s] count=%d\n", sname, - ldap_count_entries(ldap_struct, result))); - ldap_unbind(ldap_struct); - return ret; + ldap_count_entries(ldap_state->ldap_struct, result))); + return NT_STATUS_UNSUCCESSFUL; } - entry = ldap_first_entry(ldap_struct, result); + entry = ldap_first_entry(ldap_state->ldap_struct, result); if (entry) { - if (!init_sam_from_ldap(ldap_state, user, ldap_struct, entry)) { + if (!init_sam_from_ldap(ldap_state, user, entry)) { DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname)); ldap_msgfree(result); - ldap_unbind(ldap_struct); - return ret; + return NT_STATUS_UNSUCCESSFUL; } ldap_msgfree(result); - ldap_unbind(ldap_struct); ret = NT_STATUS_OK; } else { ldap_msgfree(result); - ldap_unbind(ldap_struct); } return ret; } @@ -1357,44 +1531,31 @@ static NTSTATUS ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT { NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; - LDAP *ldap_struct; LDAPMessage *result; LDAPMessage *entry; - if (!ldapsam_open_connection(ldap_state, &ldap_struct)) - return ret; - - if (!ldapsam_connect_system(ldap_state, ldap_struct)) { - ldap_unbind(ldap_struct); - return ret; - } - if (ldapsam_search_one_user_by_rid(ldap_state, ldap_struct, rid, &result) != LDAP_SUCCESS) { - ldap_unbind(ldap_struct); - return ret; + if (ldapsam_search_one_user_by_rid(ldap_state, rid, &result) != LDAP_SUCCESS) { + return NT_STATUS_UNSUCCESSFUL; } - if (ldap_count_entries(ldap_struct, result) < 1) { + if (ldap_count_entries(ldap_state->ldap_struct, result) < 1) { DEBUG(4, ("We don't find this rid [%i] count=%d\n", rid, - ldap_count_entries(ldap_struct, result))); - ldap_unbind(ldap_struct); - return ret; + ldap_count_entries(ldap_state->ldap_struct, result))); + return NT_STATUS_UNSUCCESSFUL; } - entry = ldap_first_entry(ldap_struct, result); + entry = ldap_first_entry(ldap_state->ldap_struct, result); if (entry) { - if (!init_sam_from_ldap(ldap_state, user, ldap_struct, entry)) { + if (!init_sam_from_ldap(ldap_state, user, entry)) { DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n")); ldap_msgfree(result); - ldap_unbind(ldap_struct); - return ret; + return NT_STATUS_UNSUCCESSFUL; } ldap_msgfree(result); - ldap_unbind(ldap_struct); ret = NT_STATUS_OK; } else { ldap_msgfree(result); - ldap_unbind(ldap_struct); } return ret; } @@ -1412,12 +1573,12 @@ Do the actual modification - also change a plaittext passord if it it set. **********************************************************************/ -static NTSTATUS ldapsam_modify_entry(LDAP *ldap_struct,SAM_ACCOUNT *newpwd,char *dn,LDAPMod **mods,int ldap_op, BOOL pdb_add) +static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,SAM_ACCOUNT *newpwd,char *dn,LDAPMod **mods,int ldap_op, BOOL pdb_add) { - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; int rc; - if (!ldap_struct || !newpwd || !dn) { + if (!my_methods || !newpwd || !dn) { return NT_STATUS_INVALID_PARAMETER; } @@ -1429,34 +1590,34 @@ static NTSTATUS ldapsam_modify_entry(LDAP *ldap_struct,SAM_ACCOUNT *newpwd,char { case LDAP_MOD_ADD: make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "account"); - if((rc = ldap_add_s(ldap_struct,dn,mods))!=LDAP_SUCCESS) { + if((rc = ldapsam_add(ldap_state,dn,mods))!=LDAP_SUCCESS) { char *ld_error; - ldap_get_option(ldap_struct, LDAP_OPT_ERROR_STRING, + ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); DEBUG(0, ("failed to add user with uid = %s with: %s\n\t%s\n", pdb_get_username(newpwd), ldap_err2string(rc), ld_error)); free(ld_error); - return ret; + return NT_STATUS_UNSUCCESSFUL; } break; case LDAP_MOD_REPLACE: - if((rc = ldap_modify_s(ldap_struct,dn,mods))!=LDAP_SUCCESS) { + if((rc = ldapsam_modify(ldap_state,dn,mods))!=LDAP_SUCCESS) { char *ld_error; - ldap_get_option(ldap_struct, LDAP_OPT_ERROR_STRING, + ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); DEBUG(0, ("failed to modify user with uid = %s with: %s\n\t%s\n", pdb_get_username(newpwd), ldap_err2string(rc), ld_error)); free(ld_error); - return ret; + return NT_STATUS_UNSUCCESSFUL; } break; default: DEBUG(0,("Wrong LDAP operation type: %d!\n",ldap_op)); - return ret; + return NT_STATUS_UNSUCCESSFUL; } } @@ -1472,7 +1633,7 @@ static NTSTATUS ldapsam_modify_entry(LDAP *ldap_struct,SAM_ACCOUNT *newpwd,char if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) { DEBUG(0,("ber_alloc_t returns NULL\n")); - return ret; + return NT_STATUS_UNSUCCESSFUL; } ber_printf (ber, "{"); ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID,dn); @@ -1481,12 +1642,12 @@ static NTSTATUS ldapsam_modify_entry(LDAP *ldap_struct,SAM_ACCOUNT *newpwd,char if ((rc = ber_flatten (ber, &bv))<0) { DEBUG(0,("ber_flatten returns a value <0\n")); - return ret; + return NT_STATUS_UNSUCCESSFUL; } ber_free(ber,1); - - if ((rc = ldap_extended_operation_s(ldap_struct, LDAP_EXOP_X_MODIFY_PASSWD, + + if ((rc = ldapsam_extended_operation(ldap_state, LDAP_EXOP_X_MODIFY_PASSWD, bv, NULL, NULL, &retoid, &retdata))!=LDAP_SUCCESS) { DEBUG(0,("LDAP Password could not be changed for user %s: %s\n", pdb_get_username(newpwd),ldap_err2string(rc))); @@ -1509,60 +1670,46 @@ Delete entry from LDAP for username *********************************************************************/ static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct) { - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; const char *sname; int rc; char *dn; - LDAP *ldap_struct; LDAPMessage *entry; LDAPMessage *result; if (!sam_acct) { DEBUG(0, ("sam_acct was NULL!\n")); - return ret; + return NT_STATUS_UNSUCCESSFUL; } sname = pdb_get_username(sam_acct); - if (!ldapsam_open_connection(ldap_state, &ldap_struct)) - return ret; - DEBUG (3, ("Deleting user %s from LDAP.\n", sname)); - - if (!ldapsam_connect_system(ldap_state, ldap_struct)) { - ldap_unbind (ldap_struct); - DEBUG(0, ("Failed to delete user %s from LDAP.\n", sname)); - return ret; - } - rc = ldapsam_search_one_user_by_name(ldap_state, ldap_struct, sname, &result); - if (ldap_count_entries (ldap_struct, result) == 0) { + rc = ldapsam_search_one_user_by_name(ldap_state, sname, &result); + if (ldap_count_entries (ldap_state->ldap_struct, result) == 0) { DEBUG (0, ("User doesn't exit!\n")); ldap_msgfree (result); - ldap_unbind (ldap_struct); - return ret; + return NT_STATUS_UNSUCCESSFUL; } - entry = ldap_first_entry (ldap_struct, result); - dn = ldap_get_dn (ldap_struct, entry); + entry = ldap_first_entry (ldap_state->ldap_struct, result); + dn = ldap_get_dn (ldap_state->ldap_struct, entry); ldap_msgfree(result); - rc = ldap_delete_s (ldap_struct, dn); + rc = ldapsam_delete(ldap_state, dn); ldap_memfree (dn); if (rc != LDAP_SUCCESS) { char *ld_error; - ldap_get_option (ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); + ldap_get_option (ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); DEBUG (0,("failed to delete user with uid = %s with: %s\n\t%s\n", sname, ldap_err2string (rc), ld_error)); free (ld_error); - ldap_unbind (ldap_struct); - return ret; + return NT_STATUS_UNSUCCESSFUL; } DEBUG (2,("successfully deleted uid = %s from the LDAP database\n", sname)); - ldap_unbind (ldap_struct); return NT_STATUS_OK; } @@ -1575,7 +1722,6 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_A struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; int rc; char *dn; - LDAP *ldap_struct; LDAPMessage *result; LDAPMessage *entry; LDAPMod **mods; @@ -1583,8 +1729,7 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_A if (!init_ldap_from_sam(ldap_state, &mods, LDAP_MOD_REPLACE, False, newpwd)) { DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n")); ldap_msgfree(result); - ldap_unbind(ldap_struct); - return ret; + return NT_STATUS_UNSUCCESSFUL; } if (mods == NULL) { @@ -1592,33 +1737,23 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_A return NT_STATUS_OK; } - if (!ldapsam_open_connection(ldap_state, &ldap_struct)) /* open a connection to the server */ - return ret; - - if (!ldapsam_connect_system(ldap_state, ldap_struct)) { /* connect as system account */ - ldap_unbind(ldap_struct); - return ret; - } + rc = ldapsam_search_one_user_by_name(ldap_state, pdb_get_username(newpwd), &result); - rc = ldapsam_search_one_user_by_name(ldap_state, ldap_struct, - pdb_get_username(newpwd), &result); - - if (ldap_count_entries(ldap_struct, result) == 0) { + if (ldap_count_entries(ldap_state->ldap_struct, result) == 0) { DEBUG(0, ("No user to modify!\n")); ldap_msgfree(result); - ldap_unbind(ldap_struct); - return ret; + return NT_STATUS_UNSUCCESSFUL; } - entry = ldap_first_entry(ldap_struct, result); - dn = ldap_get_dn(ldap_struct, entry); + entry = ldap_first_entry(ldap_state->ldap_struct, result); + dn = ldap_get_dn(ldap_state->ldap_struct, entry); ldap_msgfree(result); - if (NT_STATUS_IS_ERR(ldapsam_modify_entry(ldap_struct,newpwd,dn,mods,LDAP_MOD_REPLACE, False))) { + ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, False); + if (NT_STATUS_IS_ERR(ret)) { DEBUG(0,("failed to modify user with uid = %s\n", pdb_get_username(newpwd))); ldap_mods_free(mods,1); - ldap_unbind(ldap_struct); return ret; } @@ -1627,7 +1762,6 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_A ("successfully modified uid = %s in the LDAP database\n", pdb_get_username(newpwd))); ldap_mods_free(mods, 1); - ldap_unbind(ldap_struct); return NT_STATUS_OK; } @@ -1640,7 +1774,6 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; int rc; pstring filter; - LDAP *ldap_struct = NULL; LDAPMessage *result = NULL; pstring dn; LDAPMod **mods = NULL; @@ -1650,35 +1783,26 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO const char *username = pdb_get_username(newpwd); if (!username || !*username) { DEBUG(0, ("Cannot add user without a username!\n")); - return ret; - } - - if (!ldapsam_open_connection(ldap_state, &ldap_struct)) /* open a connection to the server */ - return ret; - - if (!ldapsam_connect_system(ldap_state, ldap_struct)) { /* connect as system account */ - ldap_unbind(ldap_struct); - return ret; + return NT_STATUS_UNSUCCESSFUL; } - rc = ldapsam_search_one_user_by_name (ldap_state, ldap_struct, username, &result); + rc = ldapsam_search_one_user_by_name (ldap_state, username, &result); - if (ldap_count_entries(ldap_struct, result) != 0) { + if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) { DEBUG(0,("User already in the base, with samba properties\n")); ldap_msgfree(result); - ldap_unbind(ldap_struct); - return ret; + return NT_STATUS_UNSUCCESSFUL; } ldap_msgfree(result); slprintf (filter, sizeof (filter) - 1, "uid=%s", username); - rc = ldapsam_search_one_user(ldap_state, ldap_struct, filter, &result); - num_result = ldap_count_entries(ldap_struct, result); + rc = ldapsam_search_one_user(ldap_state, filter, &result); + num_result = ldap_count_entries(ldap_state->ldap_struct, result); if (num_result > 1) { DEBUG (0, ("More than one user with that uid exists: bailing out!\n")); ldap_msgfree(result); - return ret; + return NT_STATUS_UNSUCCESSFUL; } /* Check if we need to update an existing entry */ @@ -1688,8 +1812,8 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO DEBUG(3,("User exists without samba properties: adding them\n")); ldap_op = LDAP_MOD_REPLACE; - entry = ldap_first_entry (ldap_struct, result); - tmp = ldap_get_dn (ldap_struct, entry); + entry = ldap_first_entry (ldap_state->ldap_struct, result); + tmp = ldap_get_dn (ldap_state->ldap_struct, entry); slprintf (dn, sizeof (dn) - 1, "%s", tmp); ldap_memfree (tmp); } else { @@ -1708,28 +1832,26 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO if (!init_ldap_from_sam(ldap_state, &mods, ldap_op, True, newpwd)) { DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n")); ldap_mods_free(mods, 1); - ldap_unbind(ldap_struct); - return ret; + return NT_STATUS_UNSUCCESSFUL; } if (mods == NULL) { DEBUG(0,("mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd))); - return ret; + return NT_STATUS_UNSUCCESSFUL; } make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "sambaAccount"); - if (NT_STATUS_IS_ERR(ldapsam_modify_entry(ldap_struct,newpwd,dn,mods,ldap_op, True))) { + ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,ldap_op, True); + if (NT_STATUS_IS_ERR(ret)) { DEBUG(0,("failed to modify/add user with uid = %s (dn = %s)\n", pdb_get_username(newpwd),dn)); ldap_mods_free(mods,1); - ldap_unbind(ldap_struct); return ret; } DEBUG(2,("added: uid = %s in the LDAP database\n", pdb_get_username(newpwd))); ldap_mods_free(mods, 1); - ldap_unbind(ldap_struct); return NT_STATUS_OK; } @@ -1789,14 +1911,14 @@ static void free_private_data(void **vp) { struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp; - if ((*ldap_state)->ldap_struct) { - ldap_unbind((*ldap_state)->ldap_struct); - } + ldapsam_close(*ldap_state); if ((*ldap_state)->bind_secret) { memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret)); } + ldapsam_close(*ldap_state); + SAFE_FREE((*ldap_state)->bind_dn); SAFE_FREE((*ldap_state)->bind_secret); |