source3/passdb/pdb_ldap.c | 124 +++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 119 insertions(+), 5 deletions(-) diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 2d3b91f..56d14e1 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -1965,24 +1965,137 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, struc /*************************************************************************** Renames a struct samu - - The "rename user script" has full responsibility for changing everything ***************************************************************************/ static NTSTATUS ldapsam_rename_sam_account(struct pdb_methods *my_methods, struct samu *old_acct, const char *newname) { + NTSTATUS status; + int rc; + struct ldapsam_privates *ldap_state = + (struct ldapsam_privates *)my_methods->private_data; + uint32_t num_result; + const char **attr_list = NULL; + LDAPMessage *result = NULL; + LDAPMessage *entry = NULL; + const char *old_dn = NULL; + const char *new_rdn = NULL; + + if (!old_acct || !newname) { + return NT_STATUS_INVALID_PARAMETER; + } + + attr_list = get_userattr_list(talloc_tos(), ldap_state->schema_ver); + + rc = ldapsam_search_suffix_by_name(ldap_state, + pdb_get_username(old_acct), + &result, attr_list); + if (rc != LDAP_SUCCESS) { + status = NT_STATUS_UNSUCCESSFUL; + goto out; + } + + num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, + result); + if (num_result < 1) { + status = NT_STATUS_NO_SUCH_USER; + goto out; + } + + if (num_result > 2) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto out; + } + + entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, + result); + old_dn = smbldap_talloc_dn(talloc_tos(), + ldap_state->smbldap_state->ldap_struct, + entry); + if (!old_dn) { + status = NT_STATUS_NO_MEMORY; + goto out; + } + + rc = ldapsam_search_suffix_by_name(ldap_state, newname, &result, + attr_list); + if (rc != LDAP_SUCCESS) { + status = NT_STATUS_UNSUCCESSFUL; + goto out; + } + + num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, + result); + if (num_result != 0) { + status = NT_STATUS_USER_EXISTS; + goto out; + } + + new_rdn = talloc_asprintf(talloc_tos(), "uid=%s", newname); + if (!new_rdn) { + status = NT_STATUS_NO_MEMORY; + goto out; + } + + rc = ldap_rename_s(ldap_state->smbldap_state->ldap_struct, + old_dn, new_rdn, NULL, + 1 /* deleteoldrdn */, + NULL, NULL); + if (rc != LDAP_SUCCESS) { + char *ld_error = NULL; + int ld_errno; + + ldap_get_option(ldap_state->smbldap_state->ldap_struct, + LDAP_OPT_ERROR_NUMBER, &ld_errno); + + ldap_get_option(ldap_state->smbldap_state->ldap_struct, + LDAP_OPT_ERROR_STRING, &ld_error); + DEBUG(10, ("Failed to rename dn: %s, error: %d (%s) " + "(%s)\n", old_dn, ld_errno, + ldap_err2string(rc), + ld_error ? ld_error : "unknown")); + SAFE_FREE(ld_error); + + status = NT_STATUS_UNSUCCESSFUL; + goto out; + } + + status = NT_STATUS_OK; + + out: + TALLOC_FREE(attr_list); + + if (result) { + ldap_msgfree(result); + } + if (entry) { + ldap_msgfree(entry); + } + + return status; +} + +/*************************************************************************** + Renames a struct samu + - The "rename user script" has full responsibility for changing everything +***************************************************************************/ + +static NTSTATUS ldapsam_rename_sam_account_script(struct pdb_methods *my_methods, + struct samu *old_acct, + const char *newname) +{ const char *oldname; int rc; char *rename_script = NULL; fstring oldname_lower, newname_lower; if (!old_acct) { - DEBUG(0, ("ldapsam_rename_sam_account: old_acct was NULL!\n")); + DEBUG(0, ("ldapsam_rename_sam_account_script: old_acct was NULL!\n")); return NT_STATUS_INVALID_PARAMETER; } if (!newname) { - DEBUG(0, ("ldapsam_rename_sam_account: newname was NULL!\n")); + DEBUG(0, ("ldapsam_rename_sam_account_script: newname was NULL!\n")); return NT_STATUS_INVALID_PARAMETER; } @@ -1999,7 +2112,7 @@ static NTSTATUS ldapsam_rename_sam_account(struct pdb_methods *my_methods, return NT_STATUS_ACCESS_DENIED; } - DEBUG (3, ("ldapsam_rename_sam_account: Renaming user %s to %s.\n", + DEBUG (3, ("ldapsam_rename_sam_account_script: Renaming user %s to %s.\n", oldname, newname)); /* We have to allow the account name to end with a '$'. @@ -6133,7 +6246,7 @@ static NTSTATUS pdb_init_ldapsam_common(struct pdb_methods **pdb_method, const c (*pdb_method)->add_sam_account = ldapsam_add_sam_account; (*pdb_method)->update_sam_account = ldapsam_update_sam_account; (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account; - (*pdb_method)->rename_sam_account = ldapsam_rename_sam_account; + (*pdb_method)->rename_sam_account = ldapsam_rename_sam_account_script; (*pdb_method)->getgrsid = ldapsam_getgrsid; (*pdb_method)->getgrgid = ldapsam_getgrgid; @@ -6263,6 +6376,7 @@ NTSTATUS pdb_init_ldapsam(struct pdb_methods **pdb_method, const char *location) (*pdb_method)->add_groupmem = ldapsam_add_groupmem; (*pdb_method)->del_groupmem = ldapsam_del_groupmem; (*pdb_method)->set_unix_primary_group = ldapsam_set_primary_group; + (*pdb_method)->rename_sam_account = ldapsam_rename_sam_account; } }