[SCM] Samba Shared Repository - branch v3-2-test updated - initial-v3-2-unstable-305-geaf14c7

Jeremy Allison jra at samba.org
Mon Nov 12 23:03:27 GMT 2007


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 <jra at samba.org>
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


More information about the samba-cvs mailing list