s3-ldapsam: Fix Bug 6353: do not require script for renaming users with editposix...
authorGünther Deschner <gd@samba.org>
Wed, 13 May 2009 13:33:55 +0000 (15:33 +0200)
committerGünther Deschner <gd@samba.org>
Wed, 2 Sep 2009 10:42:01 +0000 (12:42 +0200)
Guenther

source3/passdb/pdb_ldap.c

index 2c8d0518d551d96aa391d145a4c28af95ec5e18b..e0ba3f7648bb607283fbc5c76c29fd5a5e35ebf6 100644 (file)
@@ -1983,7 +1983,6 @@ 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_del_groupmem(struct pdb_methods *my_methods,
@@ -2001,6 +2000,122 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
 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;
+       TALLOC_CTX *mem_ctx;
+
+       if (!old_acct || !newname) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       mem_ctx = talloc_new(NULL);
+       if (mem_ctx == NULL) {
+               DEBUG(0, ("talloc_new failed\n"));
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       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;
+       }
+       talloc_autofree_ldapmsg(mem_ctx, result);
+
+       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);
+       TALLOC_FREE(mem_ctx);
+
+       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;
@@ -2008,11 +2123,11 @@ static NTSTATUS ldapsam_rename_sam_account(struct pdb_methods *my_methods,
        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;
        }
 
@@ -2029,7 +2144,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 '$'.
@@ -6211,7 +6326,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;
@@ -6341,6 +6456,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;
                }
        }