The branch, v3-2-test has been updated via eaf14c701b08e9eff5b94bf57af68cb29142d7fc (commit) from 5d1d650d192d4782421b5c3c2be1b632d4318279 (commit)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-2-test - Log ----------------------------------------------------------------- commit eaf14c701b08e9eff5b94bf57af68cb29142d7fc Author: Jeremy Allison <[EMAIL PROTECTED]> Date: Mon Nov 12 15:02:50 2007 -0800 Remove all pstrings from smbd/chgpasswd.c. Jeremy. ----------------------------------------------------------------------- Summary of changes: source/lib/util_str.c | 64 +++++++++++----- source/libsmb/smbencrypt.c | 36 ++++++--- source/rpc_server/srv_samr_nt.c | 58 ++++++++------- source/smbd/chgpasswd.c | 157 ++++++++++++++++++++++----------------- 4 files changed, 191 insertions(+), 124 deletions(-) Changeset truncated at 500 lines: diff --git a/source/lib/util_str.c b/source/lib/util_str.c index f1078c6..6d429e3 100644 --- a/source/lib/util_str.c +++ b/source/lib/util_str.c @@ -1254,22 +1254,27 @@ char *realloc_string_sub(char *string, const char *pattern, return string; } -/* Same as string_sub, but returns a talloc'ed string */ +/* + * Internal guts of talloc_string_sub and talloc_all_string_sub. + * 'filter' differentiates between them. + */ -char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src, - const char *pattern, const char *insert) +static char *talloc_string_sub_internal(TALLOC_CTX *mem_ctx, const char *src, + const char *pattern, const char *insert, bool filter) { char *p, *in; char *s; char *string; ssize_t ls,lp,li,ld, i; - if (!insert || !pattern || !*pattern || !src || !*src) + if (!insert || !pattern || !*pattern || !src || !*src) { return NULL; + } string = talloc_strdup(mem_ctx, src); if (string == NULL) { - DEBUG(0, ("talloc_strdup failed\n")); + DEBUG(0, ("talloc_string_sub_internal: " + "talloc_strdup failed\n")); return NULL; } @@ -1277,27 +1282,30 @@ char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src, in = SMB_STRDUP(insert); if (!in) { - DEBUG(0, ("talloc_string_sub: out of memory!\n")); + DEBUG(0, ("talloc_string_sub_internal: ENOMEM\n")); return NULL; } ls = (ssize_t)strlen(s); lp = (ssize_t)strlen(pattern); li = (ssize_t)strlen(insert); ld = li - lp; - for (i=0;i<li;i++) { - switch (in[i]) { - case '`': - case '"': - case '\'': - case ';': - case '$': - case '%': - case '\r': - case '\n': - in[i] = '_'; - default: - /* ok */ - break; + + if (filter) { + for (i=0;i<li;i++) { + switch (in[i]) { + case '`': + case '"': + case '\'': + case ';': + case '$': + case '%': + case '\r': + case '\n': + in[i] = '_'; + default: + /* ok */ + break; + } } } @@ -1325,6 +1333,14 @@ char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src, return string; } +/* Same as string_sub, but returns a talloc'ed string */ + +char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src, + const char *pattern, const char *insert) +{ + return talloc_string_sub_internal(mem_ctx, src, pattern, insert, true); +} + /** Similar to string_sub() but allows for any character to be substituted. Use with caution! @@ -1367,6 +1383,14 @@ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len) } } +char *talloc_all_string_sub(TALLOC_CTX *ctx, + const char *src, + const char *pattern, + const char *insert) +{ + return talloc_string_sub_internal(ctx, src, pattern, insert, false); +} + /** Similar to all_string_sub but for unicode strings. Return a new allocated unicode string. diff --git a/source/libsmb/smbencrypt.c b/source/libsmb/smbencrypt.c index 20eddff..77ff063 100644 --- a/source/libsmb/smbencrypt.c +++ b/source/libsmb/smbencrypt.c @@ -522,12 +522,17 @@ bool encode_pw_buffer(uint8 buffer[516], const char *password, int string_flags) returned password including termination. ************************************************************/ -bool decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd, - int new_pwrd_size, uint32 *new_pw_len, - int string_flags) +bool decode_pw_buffer(TALLOC_CTX *ctx, + uint8 in_buffer[516], + char **pp_new_pwrd, + uint32 *new_pw_len, + int string_flags) { int byte_len=0; + *pp_new_pwrd = NULL; + *new_pw_len = 0; + /* the incoming buffer can be any alignment. */ string_flags |= STR_NOALIGN; @@ -550,22 +555,31 @@ bool decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd, if ( (byte_len < 0) || (byte_len > 512)) { DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", byte_len)); DEBUG(0, ("decode_pw_buffer: check that 'encrypt passwords = yes'\n")); - return False; + return false; } - /* decode into the return buffer. Buffer length supplied */ - *new_pw_len = pull_string(NULL, 0, new_pwrd, - &in_buffer[512 - byte_len], new_pwrd_size, - byte_len, string_flags); + /* decode into the return buffer. */ + *new_pw_len = pull_string_talloc(ctx, + NULL, + 0, + pp_new_pwrd, + &in_buffer[512 - byte_len], + byte_len, + string_flags); + + if (!*pp_new_pwrd || *new_pw_len == 0) { + DEBUG(0, ("decode_pw_buffer: pull_string_talloc failed\n")); + return false; + } #ifdef DEBUG_PASSWORD DEBUG(100,("decode_pw_buffer: new_pwrd: ")); - dump_data(100, (uint8 *)new_pwrd, *new_pw_len); + dump_data(100, (uint8 *)*pp_new_pwrd, *new_pw_len); DEBUG(100,("multibyte len:%d\n", *new_pw_len)); DEBUG(100,("original char len:%d\n", byte_len/2)); #endif - - return True; + + return true; } /*********************************************************** diff --git a/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c index 9aabaf0..3cc8f01 100644 --- a/source/rpc_server/srv_samr_nt.c +++ b/source/rpc_server/srv_samr_nt.c @@ -3275,33 +3275,37 @@ static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21, static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx, SAM_USER_INFO_23 *id23, struct samu *pwd) { - pstring plaintext_buf; - uint32 len; + char *plaintext_buf = NULL; + uint32 len = 0; uint16 acct_ctrl; NTSTATUS status; - + if (id23 == NULL) { DEBUG(5, ("set_user_info_23: NULL id23\n")); return NT_STATUS_INVALID_PARAMETER; } - + DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n", pdb_get_username(pwd))); acct_ctrl = pdb_get_acct_ctrl(pwd); - if (!decode_pw_buffer(id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) { + if (!decode_pw_buffer(mem_ctx, + id23->pass, + &plaintext_buf, + &len, + STR_UNICODE)) { TALLOC_FREE(pwd); return NT_STATUS_INVALID_PARAMETER; } - + if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) { TALLOC_FREE(pwd); return NT_STATUS_ACCESS_DENIED; } - + copy_id23_to_sam_passwd(pwd, id23); - + /* if it's a trust account, don't update /etc/passwd */ if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) || ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) || @@ -3320,16 +3324,16 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx, SAM_USER_INFO_23 *id23, if ((passwd = Get_Pwnam(pdb_get_username(pwd))) == NULL) { DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n")); } - + if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) { TALLOC_FREE(pwd); return NT_STATUS_ACCESS_DENIED; } } } - - ZERO_STRUCT(plaintext_buf); - + + memset(plaintext_buf, '\0', strlen(plaintext_buf)); + if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) && (!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx, pwd)))) { @@ -3341,7 +3345,7 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx, SAM_USER_INFO_23 *id23, TALLOC_FREE(pwd); return status; } - + TALLOC_FREE(pwd); return NT_STATUS_OK; @@ -3353,12 +3357,12 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx, SAM_USER_INFO_23 *id23, static bool set_user_info_pw(uint8 *pass, struct samu *pwd) { - uint32 len; - pstring plaintext_buf; + uint32 len = 0; + char *plaintext_buf = NULL; uint32 acct_ctrl; time_t last_set_time; enum pdb_value_state last_set_state; - + DEBUG(5, ("Attempting administrator password change for user %s\n", pdb_get_username(pwd))); @@ -3368,9 +3372,11 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd) last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET); last_set_time = pdb_get_pass_last_set_time(pwd); - ZERO_STRUCT(plaintext_buf); - - if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) { + if (!decode_pw_buffer(talloc_tos(), + pass, + &plaintext_buf, + &len, + STR_UNICODE)) { TALLOC_FREE(pwd); return False; } @@ -3379,7 +3385,7 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd) TALLOC_FREE(pwd); return False; } - + /* if it's a trust account, don't update /etc/passwd */ if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) || ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) || @@ -3399,21 +3405,21 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd) if ((passwd = Get_Pwnam(pdb_get_username(pwd))) == NULL) { DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n")); } - + if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) { TALLOC_FREE(pwd); return False; } } } - - ZERO_STRUCT(plaintext_buf); - + + memset(plaintext_buf, '\0', strlen(plaintext_buf)); + /* restore last set time as this is an admin change, not a user pw change */ pdb_set_pass_last_set_time (pwd, last_set_time, last_set_state); - + DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n")); - + /* update the SAMBA password */ if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) { TALLOC_FREE(pwd); diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c index 6e7ef20..aef5adb 100644 --- a/source/smbd/chgpasswd.c +++ b/source/smbd/chgpasswd.c @@ -25,7 +25,7 @@ * user who is attempting to change the password. */ -/* +/* * This code was copied/borrowed and stolen from various sources. * The primary source was the poppasswd.c from the authors of POPMail. This software * was included as a client to change passwords using the 'passwd' program @@ -50,12 +50,12 @@ extern struct passdb_ops pdb_ops; static NTSTATUS check_oem_password(const char *user, - uchar password_encrypted_with_lm_hash[516], + uchar password_encrypted_with_lm_hash[516], const uchar old_lm_hash_encrypted[16], - uchar password_encrypted_with_nt_hash[516], + uchar password_encrypted_with_nt_hash[516], const uchar old_nt_hash_encrypted[16], - struct samu **hnd, char *new_passwd, - int new_passwd_size); + struct samu **hnd, + char **pp_new_passwd); #if ALLOW_CHANGE_PASSWORD @@ -231,7 +231,7 @@ static int dochild(int master, const char *slavedev, const struct passwd *pass, static int expect(int master, char *issue, char *expected) { - pstring buffer; + char buffer[1024]; int attempts, timeout, nread, len; bool match = False; @@ -450,13 +450,14 @@ while we were waiting\n", WTERMSIG(wstat))); return (chstat); } -bool chgpasswd(const char *name, const struct passwd *pass, +bool chgpasswd(const char *name, const struct passwd *pass, const char *oldpass, const char *newpass, bool as_root) { - pstring passwordprogram; - pstring chatsequence; + char *passwordprogram = NULL; + char *chatsequence = NULL; size_t i; size_t len; + TALLOC_CTX *ctx = talloc_tos(); if (!oldpass) { oldpass = ""; @@ -477,7 +478,7 @@ bool chgpasswd(const char *name, const struct passwd *pass, return (False); /* inform the user */ } - /* + /* * Check the old and new passwords don't contain any control * characters. */ @@ -497,7 +498,7 @@ bool chgpasswd(const char *name, const struct passwd *pass, return False; } } - + #ifdef WITH_PAM if (lp_pam_password_change()) { bool ret; @@ -510,7 +511,7 @@ bool chgpasswd(const char *name, const struct passwd *pass, } else { ret = smb_pam_passchange(name, oldpass, newpass); } - + if (as_root) unbecome_root(); @@ -522,20 +523,18 @@ bool chgpasswd(const char *name, const struct passwd *pass, if (pass == NULL) { DEBUG(0, ("chgpasswd: user %s doesn't exist in the UNIX password database.\n", name)); - return False; + return false; } - pstrcpy(passwordprogram, lp_passwd_program()); - pstrcpy(chatsequence, lp_passwd_chat()); - - if (!*chatsequence) { - DEBUG(2, ("chgpasswd: Null chat sequence - no password changing\n")); - return (False); - } - - if (!*passwordprogram) { + passwordprogram = talloc_strdup(ctx, lp_passwd_program()); + if (!passwordprogram || !*passwordprogram) { DEBUG(2, ("chgpasswd: Null password program - no password changing\n")); - return (False); + return false; + } + chatsequence = talloc_strdup(ctx, lp_passwd_chat()); + if (!chatsequence || !*chatsequence) { + DEBUG(2, ("chgpasswd: Null chat sequence - no password changing\n")); + return false; } if (as_root) { @@ -543,20 +542,38 @@ bool chgpasswd(const char *name, const struct passwd *pass, if (strstr_m(passwordprogram, "%u") == NULL) { DEBUG(0,("chgpasswd: Running as root the 'passwd program' parameter *MUST* contain \ the string %%u, and the given string %s does not.\n", passwordprogram )); - return False; + return false; } } - pstring_sub(passwordprogram, "%u", name); + passwordprogram = talloc_string_sub(ctx, passwordprogram, "%u", name); + if (!passwordprogram) { + return false; + } + /* note that we do NOT substitute the %o and %n in the password program as this would open up a security hole where the user could use a new password containing shell escape characters */ - pstring_sub(chatsequence, "%u", name); - all_string_sub(chatsequence, "%o", oldpass, sizeof(pstring)); - all_string_sub(chatsequence, "%n", newpass, sizeof(pstring)); - return (chat_with_program - (passwordprogram, pass, chatsequence, as_root)); + chatsequence = talloc_string_sub(ctx, chatsequence, "%u", name); + 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); } #else /* ALLOW_CHANGE_PASSWORD */ @@ -695,9 +712,9 @@ bool change_lanman_password(struct samu *sampass, uchar *pass2) if (!pdb_set_pass_last_set_time (sampass, time(NULL), PDB_CHANGED)) { TALLOC_FREE(sampass); /* Not quite sure what this one qualifies as, but this will do */ - return False; + return False; } - + /* Now flush the sam_passwd struct to persistent storage */ ret = NT_STATUS_IS_OK(pdb_update_sam_account (sampass)); @@ -709,29 +726,32 @@ bool change_lanman_password(struct samu *sampass, uchar *pass2) ************************************************************/ -- Samba Shared Repository