[SCM] Samba Shared Repository - branch master updated

Günther Deschner gd at samba.org
Wed May 26 14:16:33 MDT 2010


The branch, master has been updated
       via  7fa2129... s3-lanman: parse encrypted and min_pwd_length in api_SetUserPassword().
       via  a17203b... s3-lanman: use samr for api_SetUserPassword().
      from  c1e8838... flags.h - fix comment for "GTYPE_SECURITY_UNIVERSAL_GROUP" constant

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 7fa2129db665331dcfd2f1849220ea3278252ce3
Author: Günther Deschner <gd at samba.org>
Date:   Tue May 11 02:24:43 2010 +0200

    s3-lanman: parse encrypted and min_pwd_length in api_SetUserPassword().
    
    Guenther

commit a17203ba651eb643580e98aa67955eb23a374a3e
Author: Günther Deschner <gd at samba.org>
Date:   Fri May 7 14:37:25 2010 +0200

    s3-lanman: use samr for api_SetUserPassword().
    
    Guenther

-----------------------------------------------------------------------

Summary of changes:
 source3/smbd/lanman.c |  183 ++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 145 insertions(+), 38 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c
index 0d5cda7..8c4d60c 100644
--- a/source3/smbd/lanman.c
+++ b/source3/smbd/lanman.c
@@ -36,6 +36,7 @@
 #include "../librpc/gen_ndr/srv_srvsvc.h"
 #include "../librpc/gen_ndr/rap.h"
 #include "../lib/util/binsearch.h"
+#include "../libcli/auth/libcli_auth.h"
 
 #ifdef CHECK_TYPES
 #undef CHECK_TYPES
@@ -2826,6 +2827,21 @@ static bool api_SetUserPassword(connection_struct *conn,uint16 vuid,
 	char *p = NULL;
 	fstring user;
 	fstring pass1,pass2;
+	TALLOC_CTX *mem_ctx = talloc_tos();
+	NTSTATUS status;
+	struct rpc_pipe_client *cli = NULL;
+	struct policy_handle connect_handle, domain_handle, user_handle;
+	struct lsa_String domain_name;
+	struct dom_sid2 *domain_sid;
+	struct lsa_String names;
+	struct samr_Ids rids;
+	struct samr_Ids types;
+	struct samr_Password old_lm_hash;
+	struct samr_Password new_lm_hash;
+	int errcode = NERR_badpass;
+	uint32_t rid;
+	int encrypted;
+	int min_pwd_length;
 
 	/* Skip 2 strings. */
 	p = skip_string(param,tpscnt,np);
@@ -2858,6 +2874,18 @@ static bool api_SetUserPassword(connection_struct *conn,uint16 vuid,
 	memcpy(pass1,p,16);
 	memcpy(pass2,p+16,16);
 
+	encrypted = get_safe_SVAL(param,tpscnt,p+32,0,-1);
+	if (encrypted == -1) {
+		errcode = W_ERROR_V(WERR_INVALID_PARAM);
+		goto out;
+	}
+
+	min_pwd_length = get_safe_SVAL(param,tpscnt,p+34,0,-1);
+	if (min_pwd_length == -1) {
+		errcode = W_ERROR_V(WERR_INVALID_PARAM);
+		goto out;
+	}
+
 	*rparam_len = 4;
 	*rparam = smb_realloc_limit(*rparam,*rparam_len);
 	if (!*rparam) {
@@ -2866,59 +2894,138 @@ static bool api_SetUserPassword(connection_struct *conn,uint16 vuid,
 
 	*rdata_len = 0;
 
-	SSVAL(*rparam,0,NERR_badpass);
-	SSVAL(*rparam,2,0);		/* converter word */
+	DEBUG(3,("Set password for <%s> (encrypted: %d, min_pwd_length: %d)\n",
+		user, encrypted, min_pwd_length));
 
-	DEBUG(3,("Set password for <%s>\n",user));
+	ZERO_STRUCT(connect_handle);
+	ZERO_STRUCT(domain_handle);
+	ZERO_STRUCT(user_handle);
 
-	/*
-	 * Attempt to verify the old password against smbpasswd entries
-	 * Win98 clients send old and new password in plaintext for this call.
-	 */
+	status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
+					rpc_samr_dispatch, conn->server_info,
+					&cli);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0,("api_SetUserPassword: could not connect to samr: %s\n",
+			  nt_errstr(status)));
+		errcode = W_ERROR_V(ntstatus_to_werror(status));
+		goto out;
+	}
 
-	{
-		struct auth_serversupplied_info *server_info = NULL;
-		DATA_BLOB password = data_blob(pass1, strlen(pass1)+1);
+	status = rpccli_samr_Connect2(cli, mem_ctx,
+				      global_myname(),
+				      SAMR_ACCESS_CONNECT_TO_SERVER |
+				      SAMR_ACCESS_ENUM_DOMAINS |
+				      SAMR_ACCESS_LOOKUP_DOMAIN,
+				      &connect_handle);
+	if (!NT_STATUS_IS_OK(status)) {
+		errcode = W_ERROR_V(ntstatus_to_werror(status));
+		goto out;
+	}
 
-		if (NT_STATUS_IS_OK(check_plaintext_password(user,password,&server_info))) {
+	init_lsa_String(&domain_name, get_global_sam_name());
 
-			become_root();
-			if (NT_STATUS_IS_OK(change_oem_password(server_info->sam_account, pass1, pass2, False, NULL))) {
-				SSVAL(*rparam,0,NERR_Success);
-			}
-			unbecome_root();
+	status = rpccli_samr_LookupDomain(cli, mem_ctx,
+					  &connect_handle,
+					  &domain_name,
+					  &domain_sid);
+	if (!NT_STATUS_IS_OK(status)) {
+		errcode = W_ERROR_V(ntstatus_to_werror(status));
+		goto out;
+	}
 
-			TALLOC_FREE(server_info);
-		}
-		data_blob_clear_free(&password);
+	status = rpccli_samr_OpenDomain(cli, mem_ctx,
+					&connect_handle,
+					SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
+					domain_sid,
+					&domain_handle);
+	if (!NT_STATUS_IS_OK(status)) {
+		errcode = W_ERROR_V(ntstatus_to_werror(status));
+		goto out;
 	}
 
-	/*
-	 * If the plaintext change failed, attempt
-	 * the old encrypted method. NT will generate this
-	 * after trying the samr method. Note that this
-	 * method is done as a last resort as this
-	 * password change method loses the NT password hash
-	 * and cannot change the UNIX password as no plaintext
-	 * is received.
-	 */
+	init_lsa_String(&names, user);
 
-	if(SVAL(*rparam,0) != NERR_Success) {
-		struct samu *hnd = NULL;
+	status = rpccli_samr_LookupNames(cli, mem_ctx,
+					 &domain_handle,
+					 1,
+					 &names,
+					 &rids,
+					 &types);
+	if (!NT_STATUS_IS_OK(status)) {
+		errcode = W_ERROR_V(ntstatus_to_werror(status));
+		goto out;
+	}
 
-		if (check_lanman_password(user,(unsigned char *)pass1,(unsigned char *)pass2, &hnd)) {
-			become_root();
-			if (change_lanman_password(hnd,(uchar *)pass2)) {
-				SSVAL(*rparam,0,NERR_Success);
-			}
-			unbecome_root();
-			TALLOC_FREE(hnd);
-		}
+	if (rids.count != 1) {
+		errcode = W_ERROR_V(WERR_NO_SUCH_USER);
+		goto out;
+	}
+	if (rids.count != types.count) {
+		errcode = W_ERROR_V(WERR_INVALID_PARAM);
+		goto out;
+	}
+	if (types.ids[0] != SID_NAME_USER) {
+		errcode = W_ERROR_V(WERR_INVALID_PARAM);
+		goto out;
+	}
+
+	rid = rids.ids[0];
+
+	status = rpccli_samr_OpenUser(cli, mem_ctx,
+				      &domain_handle,
+				      SAMR_USER_ACCESS_CHANGE_PASSWORD,
+				      rid,
+				      &user_handle);
+	if (!NT_STATUS_IS_OK(status)) {
+		errcode = W_ERROR_V(ntstatus_to_werror(status));
+		goto out;
+	}
+
+	if (encrypted == 0) {
+		E_deshash(pass1, old_lm_hash.hash);
+		E_deshash(pass2, new_lm_hash.hash);
+	} else {
+		ZERO_STRUCT(old_lm_hash);
+		ZERO_STRUCT(new_lm_hash);
+		memcpy(old_lm_hash.hash, pass1, MIN(strlen(pass1), 16));
+		memcpy(new_lm_hash.hash, pass1, MIN(strlen(pass2), 16));
+	}
+
+	status = rpccli_samr_ChangePasswordUser(cli, mem_ctx,
+						&user_handle,
+						true, /* lm_present */
+						&old_lm_hash,
+						&new_lm_hash,
+						false, /* nt_present */
+						NULL, /* old_nt_crypted */
+						NULL, /* new_nt_crypted */
+						false, /* cross1_present */
+						NULL, /* nt_cross */
+						false, /* cross2_present */
+						NULL); /* lm_cross */
+	if (!NT_STATUS_IS_OK(status)) {
+		errcode = W_ERROR_V(ntstatus_to_werror(status));
+		goto out;
+	}
+
+	errcode = NERR_Success;
+ out:
+
+	if (cli && is_valid_policy_hnd(&user_handle)) {
+		rpccli_samr_Close(cli, mem_ctx, &user_handle);
+	}
+	if (cli && is_valid_policy_hnd(&domain_handle)) {
+		rpccli_samr_Close(cli, mem_ctx, &domain_handle);
+	}
+	if (cli && is_valid_policy_hnd(&connect_handle)) {
+		rpccli_samr_Close(cli, mem_ctx, &connect_handle);
 	}
 
 	memset((char *)pass1,'\0',sizeof(fstring));
 	memset((char *)pass2,'\0',sizeof(fstring));	 
 
+	SSVAL(*rparam,0,errcode);
+	SSVAL(*rparam,2,0);		/* converter word */
 	return(True);
 }
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list