diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/lib/util_str.c | 11 | ||||
-rw-r--r-- | source3/passdb/pdb_ldap.c | 7 | ||||
-rw-r--r-- | source3/passdb/pdb_smbpasswd.c | 8 | ||||
-rw-r--r-- | source3/passdb/pdb_tdb.c | 7 | ||||
-rw-r--r-- | source3/printing/printing.c | 6 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr_nt.c | 38 |
6 files changed, 62 insertions, 15 deletions
diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index e4aa5dbd51..e799556cd1 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -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) diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 89b958e915..a29097031a 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -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", diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c index f354d0c444..2cc6d5947e 100644 --- a/source3/passdb/pdb_smbpasswd.c +++ b/source3/passdb/pdb_smbpasswd.c @@ -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)); diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index 6c079a96f0..26b60dcc3c 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -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)); diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 82b9a7f74e..315034879e 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -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) ); /* diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 5c2950b491..33de292d22 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -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); /* |