📄 pdb_ldap.c
字号:
smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), temp); } else { smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), NULL); } } if (need_update(sampass, PDB_NTPASSWD)) { const uchar *nt_pw = pdb_get_nt_passwd(sampass); if (nt_pw) { pdb_sethexpwd(temp, nt_pw, pdb_get_acct_ctrl(sampass)); smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), temp); } else { smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), NULL); } } if (need_update(sampass, PDB_PWHISTORY)) { uint32 pwHistLen = 0; pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen); if (pwHistLen == 0) { /* Remove any password history from the LDAP store. */ memset(temp, '0', 64); /* NOTE !!!! '0' *NOT '\0' */ temp[64] = '\0'; } else { int i; uint32 currHistLen = 0; const uint8 *pwhist = pdb_get_pw_history(sampass, &currHistLen); if (pwhist != NULL) { /* We can only store (sizeof(pstring)-1)/64 password history entries. */ pwHistLen = MIN(pwHistLen, ((sizeof(temp)-1)/64)); for (i=0; i< pwHistLen && i < currHistLen; i++) { /* Store the salt. */ pdb_sethexpwd(&temp[i*64], &pwhist[i*PW_HISTORY_ENTRY_LEN], 0); /* Followed by the md5 hash of salt + md4 hash */ pdb_sethexpwd(&temp[(i*64)+32], &pwhist[(i*PW_HISTORY_ENTRY_LEN)+PW_HISTORY_SALT_LEN], 0); DEBUG(100, ("temp=%s\n", temp)); } } } smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_HISTORY), temp); } if (need_update(sampass, PDB_PASSLASTSET)) { slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass)); smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET), temp); } } if (need_update(sampass, PDB_HOURS)) { const uint8 *hours = pdb_get_hours(sampass); if (hours) { pdb_sethexhours(temp, hours); smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_HOURS), temp); } } if (need_update(sampass, PDB_ACCTCTRL)) smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO), pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), NEW_PW_FORMAT_SPACE_PADDED_LEN)); /* password lockout cache: - If we are now autolocking or clearing, we write to ldap - If we are clearing, we delete the cache entry - If the count is > 0, we update the cache This even means when autolocking, we cache, just in case the update doesn't work, and we have to cache the autolock flag */ if (need_update(sampass, PDB_BAD_PASSWORD_COUNT)) /* && need_update(sampass, PDB_BAD_PASSWORD_TIME)) */ { uint16 badcount = pdb_get_bad_password_count(sampass); time_t badtime = pdb_get_bad_password_time(sampass); uint32 pol; pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &pol); DEBUG(3, ("updating bad password fields, policy=%u, count=%u, time=%u\n", (unsigned int)pol, (unsigned int)badcount, (unsigned int)badtime)); if ((badcount >= pol) || (badcount == 0)) { DEBUG(7, ("making mods to update ldap, count=%u, time=%u\n", (unsigned int)badcount, (unsigned int)badtime)); slprintf (temp, sizeof (temp) - 1, "%li", (long)badcount); smbldap_make_mod( ldap_state->smbldap_state->ldap_struct, existing, mods, get_userattr_key2string( ldap_state->schema_ver, LDAP_ATTR_BAD_PASSWORD_COUNT), temp); slprintf (temp, sizeof (temp) - 1, "%li", badtime); smbldap_make_mod( ldap_state->smbldap_state->ldap_struct, existing, mods, get_userattr_key2string( ldap_state->schema_ver, LDAP_ATTR_BAD_PASSWORD_TIME), temp); } if (badcount == 0) { DEBUG(7, ("bad password count is reset, deleting login cache entry for %s\n", pdb_get_nt_username(sampass))); login_cache_delentry(sampass); } else { LOGIN_CACHE cache_entry; cache_entry.entry_timestamp = time(NULL); cache_entry.acct_ctrl = pdb_get_acct_ctrl(sampass); cache_entry.bad_password_count = badcount; cache_entry.bad_password_time = badtime; DEBUG(7, ("Updating bad password count and time in login cache\n")); login_cache_write(sampass, cache_entry); } } return True;}/********************************************************************** Connect to LDAP server for password enumeration.*********************************************************************/static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update, uint16 acb_mask){ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; int rc; pstring filter, suffix; const char **attr_list; BOOL machine_mask = False, user_mask = False; pstr_sprintf( filter, "(&%s%s)", "(uid=%u)", get_objclass_filter(ldap_state->schema_ver)); all_string_sub(filter, "%u", "*", sizeof(pstring)); machine_mask = ((acb_mask != 0) && (acb_mask & (ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))); user_mask = ((acb_mask != 0) && (acb_mask & ACB_NORMAL)); if (machine_mask) { pstrcpy(suffix, lp_ldap_machine_suffix()); } else if (user_mask) { pstrcpy(suffix, lp_ldap_user_suffix()); } else { pstrcpy(suffix, lp_ldap_suffix()); } DEBUG(10,("ldapsam_setsampwent: LDAP Query for acb_mask 0x%x will use suffix %s\n", acb_mask, suffix)); attr_list = get_userattr_list(ldap_state->schema_ver); rc = smbldap_search(ldap_state->smbldap_state, suffix, LDAP_SCOPE_SUBTREE, filter, attr_list, 0, &ldap_state->result); free_attr_list( attr_list ); if (rc != LDAP_SUCCESS) { DEBUG(0, ("ldapsam_setsampwent: LDAP search failed: %s\n", ldap_err2string(rc))); DEBUG(3, ("ldapsam_setsampwent: Query was: %s, %s\n", suffix, filter)); ldap_msgfree(ldap_state->result); ldap_state->result = NULL; return NT_STATUS_UNSUCCESSFUL; } DEBUG(2, ("ldapsam_setsampwent: %d entries in the base %s\n", ldap_count_entries(ldap_state->smbldap_state->ldap_struct, ldap_state->result), suffix)); ldap_state->entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->result); ldap_state->index = 0; return NT_STATUS_OK;}/********************************************************************** 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->result) { ldap_msgfree(ldap_state->result); ldap_state->result = NULL; }}/**********************************************************************Get the next entry in the LDAP password database.*********************************************************************/static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user){ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; BOOL bret = False; while (!bret) { if (!ldap_state->entry) return ret; ldap_state->index++; bret = init_sam_from_ldap(ldap_state, user, ldap_state->entry); ldap_state->entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->entry); } return NT_STATUS_OK;}static void append_attr(const char ***attr_list, const char *new_attr){ int i; if (new_attr == NULL) { return; } for (i=0; (*attr_list)[i] != NULL; i++) { ; } (*attr_list) = SMB_REALLOC_ARRAY((*attr_list), const char *, i+2); SMB_ASSERT((*attr_list) != NULL); (*attr_list)[i] = SMB_STRDUP(new_attr); (*attr_list)[i+1] = NULL;}/**********************************************************************Get SAM_ACCOUNT entry from LDAP by username.*********************************************************************/static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname){ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; LDAPMessage *result = NULL; LDAPMessage *entry = NULL; int count; const char ** attr_list; int rc; attr_list = get_userattr_list( ldap_state->schema_ver ); append_attr(&attr_list, get_userattr_key2string(ldap_state->schema_ver,LDAP_ATTR_MOD_TIMESTAMP)); rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result, attr_list); free_attr_list( attr_list ); if ( rc != LDAP_SUCCESS ) return NT_STATUS_NO_SUCH_USER; count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result); if (count < 1) { DEBUG(4, ("ldapsam_getsampwnam: Unable to locate user [%s] count=%d\n", sname, count)); ldap_msgfree(result); return NT_STATUS_NO_SUCH_USER; } else if (count > 1) { DEBUG(1, ("ldapsam_getsampwnam: Duplicate entries for this user [%s] Failing. count=%d\n", sname, count)); ldap_msgfree(result); return NT_STATUS_NO_SUCH_USER; } entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result); if (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); return NT_STATUS_NO_SUCH_USER; } pdb_set_backend_private_data(user, result, private_data_free_fn, my_methods, PDB_CHANGED); ret = NT_STATUS_OK; } else { ldap_msgfree(result); } return ret;}static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates *ldap_state, const DOM_SID *sid, LDAPMessage **result) { int rc = -1; const char ** attr_list; uint32 rid; switch ( ldap_state->schema_ver ) { case SCHEMAVER_SAMBASAMACCOUNT: attr_list = get_userattr_list(ldap_state->schema_ver); append_attr(&attr_list, get_userattr_key2string(ldap_state->schema_ver,LDAP_ATTR_MOD_TIMESTAMP)); rc = ldapsam_search_suffix_by_sid(ldap_state, sid, result, attr_list); free_attr_list( attr_list ); if ( rc != LDAP_SUCCESS ) return rc; break; case SCHEMAVER_SAMBAACCOUNT: if (!sid_peek_check_rid(&ldap_state->domain_sid, sid, &rid)) { return rc; } attr_list = get_userattr_list(ldap_state->schema_ver); rc = ldapsam_search_suffix_by_rid(ldap_state, rid, result, attr_list ); free_attr_list( attr_list ); if ( rc != LDAP_SUCCESS ) return rc; break; } return rc;}/********************************************************************** Get SAM_ACCOUNT entry from LDAP by SID.*********************************************************************/static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid){ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; LDAPMessage *result = NULL; LDAPMessage *entry = NULL; int count; int rc; fstring sid_string; rc = ldapsam_get_ldap_user_by_sid(ldap_state, sid, &result); if (rc != LDAP_SUCCESS) return NT_STATUS_NO_SUCH_USER; count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result); if (count < 1) { DEBUG(4, ("ldapsam_getsampwsid: Unable to locate SID [%s] count=%d\n", sid_to_string(sid_string, sid), count)); ldap_msgfree(result); return NT_STATUS_NO_SUCH_USER; } else if (count > 1) { DEBUG(1, ("ldapsam_getsampwsid: More than one user with SID [%s]. Failing. count=%d\n", sid_to_string(sid_string, sid), count)); ldap_msgfree(result); return NT_STATUS_NO_SUCH_USER; } entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result); if (!entry) { ldap_msgfree(result); return NT_STATUS_NO_SUCH_USER; } if (!init_sam_from_ldap(ldap_state, user, entry)) { DEBUG(1,("ldapsam_getsampwsid: init_sam_from_ldap failed!\n")); ldap_msgfree(result); return NT_STATUS_NO_SUCH_USER; } pdb_set_backend_private_data(user, result, private_data_free_fn, my_methods, PDB_CHANGED); return NT_STATUS_OK;} static BOOL ldapsam_can_pwchange_exop(struct smbldap_state *ldap_state){ return smbldap_has_extension(ldap_state, LDAP_EXOP_MODIFY_PASSWD);}/******************************************************************** Do the actual modification - also change a plaintext passord if it it set.**********************************************************************/static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods, SAM_ACCOUNT *newpwd, char *dn, LDAPMod **mods, int ldap_op, BOOL (*need_update)(const SAM_ACCOUNT *, enum pdb_elements)){ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; int rc; if (!my_methods || !newpwd || !dn) { return NT_STATUS_INVALID_PARAMETER; } if (!mods) { DEBUG(5,("ldapsam_modify_entry: mods is empty: nothing to modify\n"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -