r13622: Allow to rename machine accounts in a Samba Domain. This still uses the
authorGünther Deschner <gd@samba.org>
Wed, 22 Feb 2006 10:28:02 +0000 (10:28 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:10:19 +0000 (11:10 -0500)
"rename user script" to do the rename of the posix machine account (this
might be changed later). Fixes #2331.

Guenther

source/lib/util_str.c
source/passdb/pdb_ldap.c
source/passdb/pdb_smbpasswd.c
source/passdb/pdb_tdb.c
source/printing/printing.c
source/rpc_server/srv_samr_nt.c

index e4aa5dbd51b7d2c3249ec1ddeb42bc7ad2943dab..e799556cd1ebb6ad87208561b429f38979331b7b 100644 (file)
@@ -923,7 +923,7 @@ BOOL string_set(char **dest,const char *src)
 **/
 
 void string_sub2(char *s,const char *pattern, const char *insert, size_t len, 
-                BOOL remove_unsafe_characters, BOOL replace_once)
+                BOOL remove_unsafe_characters, BOOL replace_once, BOOL allow_trailing_dollar)
 {
        char *p;
        ssize_t ls,lp,li, i;
@@ -955,6 +955,11 @@ void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
                        case '\'':
                        case ';':
                        case '$':
+                               /* allow a trailing $ (as in machine accounts) */
+                               if (allow_trailing_dollar && (i == li - 1 )) {
+                                       p[i] = insert[i];
+                                       break;
+                               }
                        case '%':
                        case '\r':
                        case '\n':
@@ -978,12 +983,12 @@ void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
 
 void string_sub_once(char *s, const char *pattern, const char *insert, size_t len)
 {
-       string_sub2( s, pattern, insert, len, True, True );
+       string_sub2( s, pattern, insert, len, True, True, False );
 }
 
 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
 {
-       string_sub2( s, pattern, insert, len, True, False );
+       string_sub2( s, pattern, insert, len, True, False, False );
 }
 
 void fstring_sub(char *s,const char *pattern,const char *insert)
index 89b958e915f6ba5fae5df35d37df6f0a4200c20f..a29097031aad26348ebe888633ebeb6af890db2f 100644 (file)
@@ -1837,8 +1837,11 @@ static NTSTATUS ldapsam_rename_sam_account(struct pdb_methods *my_methods,
        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);
+       /* we have to allow the account name to end with a '$' */
+       string_sub2(rename_script, "%unew", newname, sizeof(pstring), 
+                   True, False, True);
+       string_sub2(rename_script, "%uold", oldname, sizeof(pstring), 
+                   True, False, True);
        rc = smbrun(rename_script, NULL);
 
        DEBUG(rc ? 0 : 3,("Running the command `%s' gave %d\n", 
index f354d0c444ddf9c0a34d7aac81bd2b846143da4b..2cc6d5947eaa1c5b606cd6492e9f23febf080271 100644 (file)
@@ -1490,9 +1490,11 @@ static NTSTATUS smbpasswd_rename_sam_account (struct pdb_methods *my_methods,
        if (*rename_script) {
                int rename_ret;
 
-               pstring_sub(rename_script, "%unew", newname);
-               pstring_sub(rename_script, "%uold", 
-                           pdb_get_username(old_acct));
+               string_sub2(rename_script, "%unew", newname, sizeof(pstring), 
+                           True, False, True);
+               string_sub2(rename_script, "%uold", pdb_get_username(old_acct), 
+                           sizeof(pstring), True, False, True);
+
                rename_ret = smbrun(rename_script, NULL);
 
                DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rename_ret));
index 6c079a96f034a4839dc9f4cd478a4be57f6f095e..26b60dcc3caea025a47fcf7c59ef9d734052d5fc 100644 (file)
@@ -1200,9 +1200,10 @@ static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods,
        }
 
        /* rename the posix user */
-       
-       pstring_sub(rename_script, "%unew", newname);
-       pstring_sub(rename_script, "%uold", pdb_get_username(old_acct));
+       string_sub2(rename_script, "%unew", newname, sizeof(pstring), 
+                   True, False, True);
+       string_sub2(rename_script, "%uold", pdb_get_username(old_acct), 
+                   sizeof(pstring), True, False, True);
        rename_ret = smbrun(rename_script, NULL);
 
        DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rename_ret));
index 82b9a7f74e3f4641ed52dfc8b780ec700d17b6ca..315034879e3b1086586fa98234c9e88efb34fa51 100644 (file)
@@ -1447,11 +1447,13 @@ static void print_queue_update(int snum, BOOL force)
        /* don't strip out characters like '$' from the printername */
        
        pstrcpy( lpqcommand, lp_lpqcommand(snum));
-       string_sub2( lpqcommand, "%p", PRINTERNAME(snum), sizeof(lpqcommand), False, False );
+       string_sub2( lpqcommand, "%p", PRINTERNAME(snum), sizeof(lpqcommand), 
+                    False, False, False );
        standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) );
        
        pstrcpy( lprmcommand, lp_lprmcommand(snum));
-       string_sub2( lprmcommand, "%p", PRINTERNAME(snum), sizeof(lprmcommand), False, False );
+       string_sub2( lprmcommand, "%p", PRINTERNAME(snum), sizeof(lprmcommand), 
+                    False, False, False );
        standard_sub_snum( snum, lprmcommand, sizeof(lprmcommand) );
        
        /* 
index 5c2950b4917e6ed86448c99b5cf984b3f1387545..33de292d226e79a81507e7295e4d88f8ea8f0630 100644 (file)
@@ -3071,13 +3071,47 @@ static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, struct samu *pwd)
 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
                                 struct samu *pwd)
 {
+       fstring new_name;
        NTSTATUS status;
-
+       
        if (id21 == NULL) {
                DEBUG(5, ("set_user_info_21: NULL id21\n"));
                return NT_STATUS_INVALID_PARAMETER;
        }
+
+       /* we need to separately check for an account rename first */
+       if (rpcstr_pull(new_name, id21->uni_user_name.buffer, 
+                       sizeof(new_name), id21->uni_user_name.uni_str_len*2, 0) && 
+          (!strequal(new_name, pdb_get_username(pwd)))) {
+
+               /* check to see if the new username already exists.  Note: we can't
+                  reliably lock all backends, so there is potentially the 
+                  possibility that a user can be created in between this check and
+                  the rename.  The rename should fail, but may not get the
+                  exact same failure status code.  I think this is small enough
+                  of a window for this type of operation and the results are
+                  simply that the rename fails with a slightly different status
+                  code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
+
+               status = can_create(mem_ctx, new_name);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+
+               status = pdb_rename_sam_account(pwd, new_name);
+
+               if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(0,("set_user_info_21: failed to rename account: %s\n", 
+                               nt_errstr(status)));
+                       TALLOC_FREE(pwd);
+                       return status;
+               }
+
+               /* set the new username so that later 
+                  functions can work on the new account */
+               pdb_set_username(pwd, new_name, PDB_SET);
+       }
+
        copy_id21_to_sam_passwd(pwd, id21);
  
        /*