summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/lib/util_str.c11
-rw-r--r--source3/passdb/pdb_ldap.c7
-rw-r--r--source3/passdb/pdb_smbpasswd.c8
-rw-r--r--source3/passdb/pdb_tdb.c7
-rw-r--r--source3/printing/printing.c6
-rw-r--r--source3/rpc_server/srv_samr_nt.c38
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);
/*