📄 pdb_ldap.c
字号:
/* may be password change below however */ } else { switch(ldap_op) { case LDAP_MOD_ADD: smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_ACCOUNT); rc = smbldap_add(ldap_state->smbldap_state, dn, mods); break; case LDAP_MOD_REPLACE: rc = smbldap_modify(ldap_state->smbldap_state, dn ,mods); break; default: DEBUG(0,("ldapsam_modify_entry: Wrong LDAP operation type: %d!\n", ldap_op)); return NT_STATUS_INVALID_PARAMETER; } if (rc!=LDAP_SUCCESS) { char *ld_error = NULL; ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); DEBUG(1, ("ldapsam_modify_entry: 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?ld_error:"unknown")); SAFE_FREE(ld_error); return NT_STATUS_UNSUCCESSFUL; } } if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) && (lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_OFF) && need_update(newpwd, PDB_PLAINTEXT_PW) && (pdb_get_plaintext_passwd(newpwd)!=NULL)) { BerElement *ber; struct berval *bv; char *retoid = NULL; struct berval *retdata = NULL; char *utf8_password; char *utf8_dn; if (!ldap_state->is_nds_ldap) { if (!ldapsam_can_pwchange_exop(ldap_state->smbldap_state)) { DEBUG(2, ("ldap password change requested, but LDAP " "server does not support it -- ignoring\n")); return NT_STATUS_OK; } } if (push_utf8_allocate(&utf8_password, pdb_get_plaintext_passwd(newpwd)) == (size_t)-1) { return NT_STATUS_NO_MEMORY; } if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) { return NT_STATUS_NO_MEMORY; } if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) { DEBUG(0,("ber_alloc_t returns NULL\n")); SAFE_FREE(utf8_password); return NT_STATUS_UNSUCCESSFUL; } ber_printf (ber, "{"); ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, utf8_dn); ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, utf8_password); ber_printf (ber, "N}"); if ((rc = ber_flatten (ber, &bv))<0) { DEBUG(0,("ldapsam_modify_entry: ber_flatten returns a value <0\n")); ber_free(ber,1); SAFE_FREE(utf8_dn); SAFE_FREE(utf8_password); return NT_STATUS_UNSUCCESSFUL; } SAFE_FREE(utf8_dn); SAFE_FREE(utf8_password); ber_free(ber, 1); if (!ldap_state->is_nds_ldap) { rc = smbldap_extended_operation(ldap_state->smbldap_state, LDAP_EXOP_MODIFY_PASSWD, bv, NULL, NULL, &retoid, &retdata); } else { rc = pdb_nds_set_password(ldap_state->smbldap_state, dn, pdb_get_plaintext_passwd(newpwd)); } if (rc != LDAP_SUCCESS) { char *ld_error = NULL; if (rc == LDAP_OBJECT_CLASS_VIOLATION) { DEBUG(3, ("Could not set userPassword " "attribute due to an objectClass " "violation -- ignoring\n")); ber_bvfree(bv); return NT_STATUS_OK; } ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); DEBUG(0,("ldapsam_modify_entry: LDAP Password could not be changed for user %s: %s\n\t%s\n", pdb_get_username(newpwd), ldap_err2string(rc), ld_error?ld_error:"unknown")); SAFE_FREE(ld_error); ber_bvfree(bv); return NT_STATUS_UNSUCCESSFUL; } else { DEBUG(3,("ldapsam_modify_entry: LDAP Password changed for user %s\n",pdb_get_username(newpwd)));#ifdef DEBUG_PASSWORD DEBUG(100,("ldapsam_modify_entry: LDAP Password changed to %s\n",pdb_get_plaintext_passwd(newpwd)));#endif if (retdata) ber_bvfree(retdata); if (retoid) ldap_memfree(retoid); } ber_bvfree(bv); } return NT_STATUS_OK;}/********************************************************************** Delete entry from LDAP for username.*********************************************************************/static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct){ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; const char *sname; int rc; LDAPMessage *result = NULL; NTSTATUS ret; const char **attr_list; fstring objclass; if (!sam_acct) { DEBUG(0, ("ldapsam_delete_sam_account: sam_acct was NULL!\n")); return NT_STATUS_INVALID_PARAMETER; } sname = pdb_get_username(sam_acct); DEBUG (3, ("ldapsam_delete_sam_account: Deleting user %s from LDAP.\n", sname)); attr_list= get_userattr_delete_list( ldap_state->schema_ver ); rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result, attr_list); if (rc != LDAP_SUCCESS) { free_attr_list( attr_list ); return NT_STATUS_NO_SUCH_USER; } switch ( ldap_state->schema_ver ) { case SCHEMAVER_SAMBASAMACCOUNT: fstrcpy( objclass, LDAP_OBJ_SAMBASAMACCOUNT ); break; case SCHEMAVER_SAMBAACCOUNT: fstrcpy( objclass, LDAP_OBJ_SAMBAACCOUNT ); break; default: fstrcpy( objclass, "UNKNOWN" ); DEBUG(0,("ldapsam_delete_sam_account: Unknown schema version specified!\n")); break; } ret = ldapsam_delete_entry(ldap_state, result, objclass, attr_list ); ldap_msgfree(result); free_attr_list( attr_list ); return ret;}/********************************************************************** Helper function to determine for update_sam_account whether we need LDAP modification.*********************************************************************/static BOOL element_is_changed(const SAM_ACCOUNT *sampass, enum pdb_elements element){ return IS_SAM_CHANGED(sampass, element);}/********************************************************************** Update SAM_ACCOUNT.*********************************************************************/static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd){ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; int rc = 0; char *dn; LDAPMessage *result = NULL; LDAPMessage *entry = NULL; LDAPMod **mods = NULL; const char **attr_list; result = pdb_get_backend_private_data(newpwd, my_methods); if (!result) { attr_list = get_userattr_list(ldap_state->schema_ver); rc = ldapsam_search_suffix_by_name(ldap_state, pdb_get_username(newpwd), &result, attr_list ); free_attr_list( attr_list ); if (rc != LDAP_SUCCESS) { return NT_STATUS_UNSUCCESSFUL; } pdb_set_backend_private_data(newpwd, result, private_data_free_fn, my_methods, PDB_CHANGED); } if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) == 0) { DEBUG(0, ("ldapsam_update_sam_account: No user to modify!\n")); return NT_STATUS_UNSUCCESSFUL; } entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result); dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry); if (!dn) { return NT_STATUS_UNSUCCESSFUL; } DEBUG(4, ("ldapsam_update_sam_account: user %s to be modified has dn: %s\n", pdb_get_username(newpwd), dn)); if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd, element_is_changed)) { DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n")); SAFE_FREE(dn); if (mods != NULL) ldap_mods_free(mods,True); return NT_STATUS_UNSUCCESSFUL; } if (mods == NULL) { DEBUG(4,("ldapsam_update_sam_account: mods is empty: nothing to update for user: %s\n", pdb_get_username(newpwd))); SAFE_FREE(dn); return NT_STATUS_OK; } ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, element_is_changed); ldap_mods_free(mods,True); SAFE_FREE(dn); if (!NT_STATUS_IS_OK(ret)) { char *ld_error = NULL; ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); DEBUG(0,("ldapsam_update_sam_account: failed to modify user with uid = %s, error: %s (%s)\n", pdb_get_username(newpwd), ld_error?ld_error:"(unknwon)", ldap_err2string(rc))); SAFE_FREE(ld_error); return ret; } DEBUG(2, ("ldapsam_update_sam_account: successfully modified uid = %s in the LDAP database\n", pdb_get_username(newpwd))); return NT_STATUS_OK;}/*************************************************************************** Renames a SAM_ACCOUNT - The "rename user script" has full responsibility for changing everything***************************************************************************/static NTSTATUS ldapsam_rename_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *old_acct, const char *newname){ const char *oldname; int rc; pstring rename_script; if (!old_acct) { DEBUG(0, ("ldapsam_rename_sam_account: old_acct was NULL!\n")); return NT_STATUS_INVALID_PARAMETER; } if (!newname) { DEBUG(0, ("ldapsam_rename_sam_account: newname was NULL!\n")); return NT_STATUS_INVALID_PARAMETER; } oldname = pdb_get_username(old_acct); /* rename the posix user */ pstrcpy(rename_script, lp_renameuser_script()); if (!(*rename_script)) return NT_STATUS_ACCESS_DENIED; DEBUG (3, ("ldapsam_rename_sam_account: Renaming user %s to %s.\n", oldname, newname)); pstring_sub(rename_script, "%unew", newname); pstring_sub(rename_script, "%uold", oldname); rc = smbrun(rename_script, NULL); DEBUG(rc ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rc)); if (rc) return NT_STATUS_UNSUCCESSFUL; return NT_STATUS_OK;}/********************************************************************** Helper function to determine for update_sam_account whether we need LDAP modification. *********************************************************************/static BOOL element_is_set_or_changed(const SAM_ACCOUNT *sampass, enum pdb_elements element){ return (IS_SAM_SET(sampass, element) || IS_SAM_CHANGED(sampass, element));}/********************************************************************** Add SAM_ACCOUNT to LDAP.*********************************************************************/static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd){ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; int rc; LDAPMessage *result = NULL; LDAPMessage *entry = NULL; pstring dn; LDAPMod **mods = NULL; int ldap_op = LDAP_MOD_REPLACE; uint32 num_result; const char **attr_list; char *escape_user; const char *username = pdb_get_username(newpwd); const DOM_SID *sid = pdb_get_user_sid(newpwd); pstring filter; fstring sid_string; if (!username || !*username) { DEBUG(0, ("ldapsam_add_sam_account: Cannot add user without a username!\n")); return NT_STATUS_INVALID_PARAMETER; } /* free this list after the second search or in case we exit on failure */ attr_list = get_userattr_list(ldap_state->schema_ver); rc = ldapsam_search_suffix_by_name (ldap_state, username, &result, attr_list); if (rc != LDAP_SUCCESS) { free_attr_list( attr_list ); return NT_STATUS_UNSUCCESSFUL; } if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 0) { DEBUG(0,("ldapsam_add_sam_account: User '%s' already in the base, with samba attributes\n", username)); ldap_msgfree(result); free_attr_list( attr_list ); return NT_STATUS_UNSUCCESSFUL; } ldap_msgfree(result); result = NULL; if (element_is_set_or_changed(newpwd, PDB_USERSID)) { rc = ldapsam_get_ldap_user_by_sid(ldap_state, sid, &result); if (rc == LDAP_SUCCESS) { if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 0) { DEBUG(0,("ldapsam_add_sam_account: SID '%s' already in the base, with samba attributes\n", sid_to_string(sid_string, sid))); free_attr_list( attr_list ); ldap_msgfree(result); return NT_STATUS_UNSUCCESSFUL; } ldap_msgfree(result); } } /* does the entry already exist but without a samba attributes? we need to return the samba attributes here */ escape_user = escape_ldap_string_alloc( username ); pstrcpy( filter, "(uid=%u)" ); all_string_sub( filter, "%u", escape_user, sizeof(filter) ); SAFE_FREE( escape_user ); rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr_list, &result); if ( rc != LDAP_SUCCESS ) { free_attr_list( attr_list ); return NT_STATUS_UNSUCCESSFUL; } num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result); if (num_result > 1) { DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n")); free_attr_list( attr_list ); ldap_msgfree(result); return NT_STATUS_UN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -