The Samba-Bugzilla – Attachment 5255 Details for
Bug 6411
changing user-password to one containing special characters does not work
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
fix for samba 3.4.5 now also works for %n in old password
samba-3.4.5-fix-chgpasswd-token-handling.diff (text/plain), 6.87 KB, created by
Carsten Dumke
on 2010-02-02 03:49:06 UTC
(
hide
)
Description:
fix for samba 3.4.5 now also works for %n in old password
Filename:
MIME Type:
Creator:
Carsten Dumke
Created:
2010-02-02 03:49:06 UTC
Size:
6.87 KB
patch
obsolete
>diff -Nurbd samba-3.4.5.orig/source3/smbd/chgpasswd.c samba-3.4.5/source3/smbd/chgpasswd.c >--- samba-3.4.5.orig/source3/smbd/chgpasswd.c 2010-01-18 12:38:09.000000000 +0100 >+++ samba-3.4.5/source3/smbd/chgpasswd.c 2010-01-29 16:45:02.000000000 +0100 >@@ -239,20 +239,160 @@ > return (True); > } > >-static int expect(int master, char *issue, char *expected) >+static char *expand_pass_pattern(char *target, size_t target_len, >+ const char *source, >+ const char *pattern_old_pass, >+ const char *old_pass, >+ const char *pattern_new_pass, >+ const char *new_pass) >+{ >+ /* we expand target in portions of chunk_size */ >+ size_t chunk_size = 10; >+ size_t chars_to_copy = 0; >+ size_t skip_source_chars = 0; >+ size_t old_pass_len = 0; >+ size_t new_pass_len = 0; >+ size_t pattern_old_pass_len = 0; >+ size_t pattern_new_pass_len = 0; >+ size_t target_size = target_len; >+ size_t target_used = 0; >+ char *target_start = target; >+ char *pattern_starter_found; >+ char pattern_starter = '\0'; >+ char empty[] = ""; >+ const char *chars_source; >+ TALLOC_CTX *ctx = talloc_tos(); >+ >+ if ((target == NULL) || (target_len == 0)) { >+ return; >+ } >+ if (source == NULL) { >+ source = empty; >+ } >+ if (pattern_old_pass != NULL) { >+ pattern_old_pass_len = strlen(pattern_old_pass); >+ pattern_starter = *pattern_old_pass; >+ } >+ if (pattern_new_pass != NULL) { >+ pattern_new_pass_len = strlen(pattern_new_pass); >+ pattern_starter = *pattern_new_pass; >+ } >+ if (old_pass != NULL) { >+ old_pass_len = strlen(old_pass); >+ } >+ else { >+ old_pass = empty; >+ } >+ if (new_pass != NULL) { >+ new_pass_len = strlen(new_pass); >+ } >+ else { >+ new_pass = empty; >+ } >+ >+ while (*source) { >+ /* find possible start of pattern in source */ >+ pattern_starter_found = strchr(source, pattern_starter); >+ chars_source = source; >+ if (pattern_starter_found == NULL) { >+ /* pattern not found - copy whole source */ >+ chars_to_copy = strlen(source); >+ } >+ else { >+ chars_to_copy = pattern_starter_found - chars_source; >+ } >+ skip_source_chars = chars_to_copy; >+ >+ if (chars_to_copy == 0) { >+ /* current source char may start a pattern */ >+ if ((pattern_old_pass) && (*pattern_old_pass) >+ && (strncmp(source, pattern_old_pass, >+ pattern_old_pass_len) == 0)) { >+ /* insert old password */ >+ chars_source = old_pass; >+ chars_to_copy = old_pass_len; >+ skip_source_chars = pattern_old_pass_len; >+ } >+ else if ((pattern_new_pass) && (*pattern_new_pass) >+ && (strncmp(source, pattern_new_pass, >+ pattern_new_pass_len) == 0)) { >+ /* insert new password */ >+ chars_source = new_pass; >+ chars_to_copy = new_pass_len; >+ skip_source_chars = pattern_new_pass_len; >+ } >+ else { >+ /* no pattern matched - copy char to target */ >+ chars_to_copy = 1; >+ skip_source_chars = chars_to_copy; >+ } >+ } >+ while (chars_to_copy > target_len) { >+ target_used = target - target_start; >+ target_size += chunk_size; >+ target_start = talloc_realloc(ctx, target_start, char, >+ target_size); >+ if (!target_start) { >+ DEBUG(1,("expand_pass_pattern: talloc fail\n")); >+ return NULL; >+ } >+ target = target_start + target_used; >+ target_len = target_size - target_used; >+ } >+ strncpy(target, chars_source , chars_to_copy); >+ target_len -= chars_to_copy; >+ target += chars_to_copy; >+ source += skip_source_chars; >+ } >+ /* terminate target */ >+ if (target_len == 0) { >+ target_used = target - target_start; >+ target_size += chunk_size; >+ target_start = talloc_realloc(ctx, target_start, char, >+ target_size); >+ if (!target_start) { >+ DEBUG(1,("expand_pass_pattern: talloc fail\n")); >+ return NULL; >+ } >+ target = target_start + target_used; >+ target_len = target_size - target_used; >+ } >+ *target = '\0'; >+ return target_start; >+} >+ >+static int expect(int master, const char *issue, const char *expected, >+ const char *oldpass, const char *newpass) > { > char buffer[1024]; > int attempts, timeout, nread; > size_t len; > bool match = False; >+ char *newissue; >+ size_t newissue_len; >+ >+ /* >+ * We know we're safe allowing "unsafe" characters here >+ * as we know there are no embedded control characters. >+ */ >+ newissue = talloc(talloc_tos(), char); >+ newissue = expand_pass_pattern(newissue, sizeof(char), issue, >+ "%o", oldpass, >+ "%n", newpass); >+ >+ if (!newissue) { >+ DEBUG(1,("expect: talloc fail\n")); >+ return false; >+ } >+ newissue_len = strlen(newissue); > > for (attempts = 0; attempts < 2; attempts++) { > NTSTATUS status; >- if (!strequal(issue, ".")) { >+ if (!strequal(newissue, ".")) { > if (lp_passwd_chat_debug()) >- DEBUG(100, ("expect: sending [%s]\n", issue)); >+ DEBUG(100, ("expect: sending [%s]\n", newissue)); > >- if ((len = sys_write(master, issue, strlen(issue))) != strlen(issue)) { >+ if ((len = sys_write(master, newissue, newissue_len)) != newissue_len) { > DEBUG(2,("expect: (short) write returned %d\n", > (int)len )); > return False; >@@ -308,6 +448,7 @@ > return False; > } > } >+ talloc_free(newissue); > > DEBUG(10,("expect: returning %s\n", match ? "True" : "False" )); > return match; >@@ -321,7 +462,8 @@ > all_string_sub(buf, "\\t", "\t", 0); > } > >-static int talktochild(int master, const char *seq) >+static int talktochild(int master, const char *seq, >+ const char *oldpass, const char *newpass) > { > TALLOC_CTX *frame = talloc_stackframe(); > int count = 0; >@@ -338,7 +480,7 @@ > pwd_sub(expected); > count++; > >- if (!expect(master, issue, expected)) { >+ if (!expect(master, issue, expected, oldpass, newpass)) { > DEBUG(3, ("Response %d incorrect\n", count)); > TALLOC_FREE(frame); > return false; >@@ -361,7 +503,7 @@ > TALLOC_FREE(frame); > return false; > } >- if (!expect(master, issue, expected)) { >+ if (!expect(master, issue, expected, oldpass, newpass)) { > TALLOC_FREE(frame); > return False; > } >@@ -371,7 +513,8 @@ > } > > static bool chat_with_program(char *passwordprogram, const struct passwd *pass, >- char *chatsequence, bool as_root) >+ char *chatsequence, bool as_root, >+ const char *oldpass, const char *newpass) > { > char *slavedev = NULL; > int master; >@@ -410,7 +553,7 @@ > /* Don't need this anymore in parent. */ > SAFE_FREE(slavedev); > >- if ((chstat = talktochild(master, chatsequence)) == False) { >+ if ((chstat = talktochild(master, chatsequence, oldpass, newpass)) == False) { > DEBUG(3, ("chat_with_program: Child failed to change password: %s\n", pass->pw_name)); > kill(pid, SIGKILL); /* be sure to end this process */ > } >@@ -605,21 +748,12 @@ > if (!chatsequence) { > return false; > } >- chatsequence = talloc_all_string_sub(ctx, >- chatsequence, >- "%o", >- oldpass); >- if (!chatsequence) { >- return false; >- } >- chatsequence = talloc_all_string_sub(ctx, >- chatsequence, >- "%n", >- newpass); > return chat_with_program(passwordprogram, > pass, > chatsequence, >- as_root); >+ as_root, >+ oldpass, >+ newpass); > } > > #else /* ALLOW_CHANGE_PASSWORD */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 6411
:
4208
|
4213
|
4238
|
4239
| 5255 |
5797
|
5799