[SCM] Samba Shared Repository - branch master updated

Günther Deschner gd at samba.org
Mon May 31 07:31:24 MDT 2010


The branch, master has been updated
       via  9864164... s3-netlogon: use LSA in _netr_NetrEnumerateTrustedDomains.
       via  4bb7e91... s3-netlogon: use SAMR in _netr_ServerAuthenticate3.
       via  db5730c... s3-samr: give the system user a free pass for _samr_QueryUserInfo{2} level 18.
       via  3f24f8d... s3-auth: add "system" bool flag to auth_serversupplied_info.
       via  a780581... s3-netlogon: use SAMR in _netr_ServerPasswordSet{2}.
      from  62708fb... s3:ntlmssp Move ntlmssp_sign.c from source3 to common code.

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


- Log -----------------------------------------------------------------
commit 98641648d8ec66a0c3e07a73e4275005bfa25811
Author: Günther Deschner <gd at samba.org>
Date:   Fri May 28 15:31:35 2010 +0200

    s3-netlogon: use LSA in _netr_NetrEnumerateTrustedDomains.
    
    Guenther

commit 4bb7e91cfd9071e570c56bca36d35202d01ca80d
Author: Günther Deschner <gd at samba.org>
Date:   Fri May 28 14:22:08 2010 +0200

    s3-netlogon: use SAMR in _netr_ServerAuthenticate3.
    
    Guenther

commit db5730cac4d6e0b64913bce21147352344077e2b
Author: Günther Deschner <gd at samba.org>
Date:   Fri May 28 14:21:15 2010 +0200

    s3-samr: give the system user a free pass for _samr_QueryUserInfo{2} level 18.
    
    Guenther

commit 3f24f8d2c69be1db28cb1ffb866d45b520d9544d
Author: Günther Deschner <gd at samba.org>
Date:   Fri May 28 14:19:28 2010 +0200

    s3-auth: add "system" bool flag to auth_serversupplied_info.
    
    Guenther

commit a7805811c432adb9b0e82039858269c2154521ae
Author: Günther Deschner <gd at samba.org>
Date:   Fri May 28 12:39:12 2010 +0200

    s3-netlogon: use SAMR in _netr_ServerPasswordSet{2}.
    
    Guenther

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

Summary of changes:
 source3/auth/auth_util.c           |   11 +-
 source3/include/auth.h             |    1 +
 source3/rpc_server/srv_netlog_nt.c |  466 +++++++++++++++++++++++-------------
 source3/rpc_server/srv_samr_nt.c   |    5 +
 4 files changed, 320 insertions(+), 163 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 1f9bc7b..74d8873 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -765,16 +765,24 @@ static NTSTATUS make_new_server_info_system(TALLOC_CTX *mem_ctx,
 					    struct auth_serversupplied_info **server_info)
 {
 	struct passwd *pwd;
+	NTSTATUS status;
 
 	pwd = getpwuid_alloc(mem_ctx, sec_initial_uid());
 	if (pwd == NULL) {
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	return make_serverinfo_from_username(mem_ctx,
+	status = make_serverinfo_from_username(mem_ctx,
 					     pwd->pw_name,
 					     false,
 					     server_info);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	(*server_info)->system = true;
+
+	return NT_STATUS_OK;
 }
 
 /****************************************************************************
@@ -829,6 +837,7 @@ struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx,
 	}
 
 	dst->guest = src->guest;
+	dst->system = src->system;
 	dst->utok.uid = src->utok.uid;
 	dst->utok.gid = src->utok.gid;
 	dst->utok.ngroups = src->utok.ngroups;
diff --git a/source3/include/auth.h b/source3/include/auth.h
index ed422c2..69a91d2 100644
--- a/source3/include/auth.h
+++ b/source3/include/auth.h
@@ -42,6 +42,7 @@ struct auth_usersupplied_info {
 
 struct auth_serversupplied_info {
 	bool guest;
+	bool system;
 
 	struct dom_sid *sids; 	/* These SIDs are preliminary between
 			   check_ntlm_password and the token creation. */
diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c
index f0b9bab..4bd176c 100644
--- a/source3/rpc_server/srv_netlog_nt.c
+++ b/source3/rpc_server/srv_netlog_nt.c
@@ -27,6 +27,11 @@
 #include "includes.h"
 #include "../libcli/auth/schannel.h"
 #include "../librpc/gen_ndr/srv_netlogon.h"
+#include "../librpc/gen_ndr/srv_samr.h"
+#include "../librpc/gen_ndr/srv_lsa.h"
+#include "../librpc/gen_ndr/cli_samr.h"
+#include "../librpc/gen_ndr/cli_lsa.h"
+#include "rpc_client/cli_lsarpc.h"
 #include "librpc/gen_ndr/messaging.h"
 #include "../lib/crypto/md4.h"
 
@@ -389,39 +394,77 @@ NTSTATUS _netr_NetrEnumerateTrustedDomains(pipes_struct *p,
 {
 	NTSTATUS status;
 	DATA_BLOB blob;
-	struct trustdom_info **domains;
-	uint32_t num_domains;
-	const char **trusted_domains;
+	int num_domains = 0;
+	const char **trusted_domains = NULL;
+	struct lsa_DomainList domain_list;
+	struct rpc_pipe_client *cli = NULL;
+	struct policy_handle pol;
+	uint32_t enum_ctx = 0;
 	int i;
+	uint32_t max_size = (uint32_t)-1;
 
 	DEBUG(6,("_netr_NetrEnumerateTrustedDomains: %d\n", __LINE__));
 
-	/* set up the Trusted Domain List response */
-
-	become_root();
-	status = pdb_enum_trusteddoms(p->mem_ctx, &num_domains, &domains);
-	unbecome_root();
-
+	status = rpc_pipe_open_internal(p->mem_ctx, &ndr_table_lsarpc.syntax_id,
+					rpc_lsarpc_dispatch, p->server_info,
+					&cli);
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
 	}
 
-	trusted_domains = talloc_zero_array(p->mem_ctx, const char *, num_domains + 1);
+	trusted_domains = talloc_zero_array(p->mem_ctx, const char *, num_domains);
 	if (!trusted_domains) {
-		return NT_STATUS_NO_MEMORY;
+		status = NT_STATUS_NO_MEMORY;
+		goto out;
 	}
 
-	for (i = 0; i < num_domains; i++) {
-		trusted_domains[i] = talloc_strdup(trusted_domains, domains[i]->name);
-		if (!trusted_domains[i]) {
-			TALLOC_FREE(trusted_domains);
-			return NT_STATUS_NO_MEMORY;
+	status = rpccli_lsa_open_policy2(cli, p->mem_ctx,
+					 true,
+					 LSA_POLICY_VIEW_LOCAL_INFORMATION,
+					 &pol);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto out;
+	}
+
+	status = STATUS_MORE_ENTRIES;
+
+	while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
+
+		/* Lookup list of trusted domains */
+
+		status = rpccli_lsa_EnumTrustDom(cli, p->mem_ctx,
+						 &pol,
+						 &enum_ctx,
+						 &domain_list,
+						 max_size);
+		if (!NT_STATUS_IS_OK(status) &&
+		    !NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES) &&
+		    !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
+			goto out;
+		}
+
+		for (i = 0; i < domain_list.count; i++) {
+			if (!add_string_to_array(p->mem_ctx, domain_list.domains[i].name.string,
+						 &trusted_domains, &num_domains)) {
+				status = NT_STATUS_NO_MEMORY;
+				goto out;
+			}
 		}
 	}
 
+	/* multi sz terminate */
+	trusted_domains = talloc_realloc(p->mem_ctx, trusted_domains, const char *, num_domains + 1);
+	if (trusted_domains == NULL) {
+		status = NT_STATUS_NO_MEMORY;
+		goto out;
+	}
+
+	trusted_domains[num_domains+1] = NULL;
+
 	if (!push_reg_multi_sz(trusted_domains, &blob, trusted_domains)) {
 		TALLOC_FREE(trusted_domains);
-		return NT_STATUS_NO_MEMORY;
+		status = NT_STATUS_NO_MEMORY;
+		goto out;
 	}
 
 	r->out.trusted_domains_blob->data = blob.data;
@@ -429,7 +472,118 @@ NTSTATUS _netr_NetrEnumerateTrustedDomains(pipes_struct *p,
 
 	DEBUG(6,("_netr_NetrEnumerateTrustedDomains: %d\n", __LINE__));
 
-	return NT_STATUS_OK;
+	status = NT_STATUS_OK;
+
+ out:
+	if (cli && is_valid_policy_hnd(&pol)) {
+		rpccli_lsa_Close(cli, p->mem_ctx, &pol);
+	}
+
+	return status;
+}
+
+/*************************************************************************
+ *************************************************************************/
+
+static NTSTATUS samr_find_machine_account(TALLOC_CTX *mem_ctx,
+					  struct rpc_pipe_client *cli,
+					  const char *account_name,
+					  uint32_t access_mask,
+					  struct dom_sid2 **domain_sid_p,
+					  uint32_t *user_rid_p,
+					  struct policy_handle *user_handle)
+{
+	NTSTATUS status;
+	struct policy_handle connect_handle, domain_handle;
+	struct lsa_String domain_name;
+	struct dom_sid2 *domain_sid;
+	struct lsa_String names;
+	struct samr_Ids rids;
+	struct samr_Ids types;
+	uint32_t rid;
+
+	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)) {
+		goto out;
+	}
+
+	init_lsa_String(&domain_name, get_global_sam_name());
+
+	status = rpccli_samr_LookupDomain(cli, mem_ctx,
+					  &connect_handle,
+					  &domain_name,
+					  &domain_sid);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto out;
+	}
+
+	status = rpccli_samr_OpenDomain(cli, mem_ctx,
+					&connect_handle,
+					SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
+					domain_sid,
+					&domain_handle);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto out;
+	}
+
+	init_lsa_String(&names, account_name);
+
+	status = rpccli_samr_LookupNames(cli, mem_ctx,
+					 &domain_handle,
+					 1,
+					 &names,
+					 &rids,
+					 &types);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto out;
+	}
+
+	if (rids.count != 1) {
+		status = NT_STATUS_NO_SUCH_USER;
+		goto out;
+	}
+	if (rids.count != types.count) {
+		status = NT_STATUS_INVALID_PARAMETER;
+		goto out;
+	}
+	if (types.ids[0] != SID_NAME_USER) {
+		status = NT_STATUS_NO_SUCH_USER;
+		goto out;
+	}
+
+	rid = rids.ids[0];
+
+	status = rpccli_samr_OpenUser(cli, mem_ctx,
+				      &domain_handle,
+				      access_mask,
+				      rid,
+				      user_handle);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto out;
+	}
+
+	if (user_rid_p) {
+		*user_rid_p = rid;
+	}
+
+	if (domain_sid_p) {
+		*domain_sid_p = domain_sid;
+	}
+
+ out:
+	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);
+	}
+
+	return status;
 }
 
 /******************************************************************
@@ -439,11 +593,15 @@ NTSTATUS _netr_NetrEnumerateTrustedDomains(pipes_struct *p,
 static NTSTATUS get_md4pw(struct samr_Password *md4pw, const char *mach_acct,
 			  enum netr_SchannelType sec_chan_type, struct dom_sid *sid)
 {
-	struct samu *sampass = NULL;
-	const uint8 *pass;
-	bool ret;
-	uint32 acct_ctrl;
-
+	NTSTATUS status;
+	TALLOC_CTX *mem_ctx;
+	struct rpc_pipe_client *cli = NULL;
+	struct policy_handle user_handle;
+	uint32_t user_rid;
+	struct dom_sid *domain_sid;
+	uint32_t acct_ctrl;
+	union samr_UserInfo *info;
+	struct auth_serversupplied_info *server_info;
 #if 0
 	char addr[INET6_ADDRSTRLEN];
 
@@ -464,26 +622,50 @@ static NTSTATUS get_md4pw(struct samr_Password *md4pw, const char *mach_acct,
 	}
 #endif /* 0 */
 
-	if ( !(sampass = samu_new( NULL )) ) {
-		return NT_STATUS_NO_MEMORY;
+	mem_ctx = talloc_new(talloc_tos());
+	if (mem_ctx == NULL) {
+		status = NT_STATUS_NO_MEMORY;
+		goto out;
+	}
+
+	status = make_server_info_system(mem_ctx, &server_info);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto out;
+	}
+
+	ZERO_STRUCT(user_handle);
+
+	status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
+					rpc_samr_dispatch, server_info,
+					&cli);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto out;
 	}
 
-	/* JRA. This is ok as it is only used for generating the challenge. */
 	become_root();
-	ret = pdb_getsampwnam(sampass, mach_acct);
+	status = samr_find_machine_account(mem_ctx, cli, mach_acct,
+					   SEC_FLAG_MAXIMUM_ALLOWED,
+					   &domain_sid, &user_rid,
+					   &user_handle);
 	unbecome_root();
+	if (!NT_STATUS_IS_OK(status)) {
+		goto out;
+	}
 
- 	if (!ret) {
- 		DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
-		TALLOC_FREE(sampass);
-		return NT_STATUS_ACCESS_DENIED;
+	status = rpccli_samr_QueryUserInfo2(cli, mem_ctx,
+					    &user_handle,
+					    UserControlInformation,
+					    &info);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto out;
 	}
 
-	acct_ctrl = pdb_get_acct_ctrl(sampass);
+	acct_ctrl = info->info16.acct_flags;
+
 	if (acct_ctrl & ACB_DISABLED) {
 		DEBUG(0,("get_md4pw: Workstation %s: account is disabled\n", mach_acct));
-		TALLOC_FREE(sampass);
-		return NT_STATUS_ACCOUNT_DISABLED;
+		status = NT_STATUS_ACCOUNT_DISABLED;
+		goto out;
 	}
 
 	if (!(acct_ctrl & ACB_SVRTRUST) &&
@@ -491,8 +673,8 @@ static NTSTATUS get_md4pw(struct samr_Password *md4pw, const char *mach_acct,
 	    !(acct_ctrl & ACB_DOMTRUST))
 	{
 		DEBUG(0,("get_md4pw: Workstation %s: account is not a trust account\n", mach_acct));
-		TALLOC_FREE(sampass);
-		return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
+		status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
+		goto out;
 	}
 
 	switch (sec_chan_type) {
@@ -500,46 +682,58 @@ static NTSTATUS get_md4pw(struct samr_Password *md4pw, const char *mach_acct,
 			if (!(acct_ctrl & ACB_SVRTRUST)) {
 				DEBUG(0,("get_md4pw: Workstation %s: BDC secure channel requested "
 					 "but not a server trust account\n", mach_acct));
-				TALLOC_FREE(sampass);
-				return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
+				status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
+				goto out;
 			}
 			break;
 		case SEC_CHAN_WKSTA:
 			if (!(acct_ctrl & ACB_WSTRUST)) {
 				DEBUG(0,("get_md4pw: Workstation %s: WORKSTATION secure channel requested "
 					 "but not a workstation trust account\n", mach_acct));
-				TALLOC_FREE(sampass);
-				return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
+				status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
+				goto out;
 			}
 			break;
 		case SEC_CHAN_DOMAIN:
 			if (!(acct_ctrl & ACB_DOMTRUST)) {
 				DEBUG(0,("get_md4pw: Workstation %s: DOMAIN secure channel requested "
 					 "but not a interdomain trust account\n", mach_acct));
-				TALLOC_FREE(sampass);
-				return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
+				status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
+				goto out;
 			}
 			break;
 		default:
 			break;
 	}
 
-	if ((pass = pdb_get_nt_passwd(sampass)) == NULL) {
+	become_root();
+	status = rpccli_samr_QueryUserInfo2(cli, mem_ctx,
+					    &user_handle,
+					    UserInternal1Information,
+					    &info);
+	unbecome_root();
+	if (!NT_STATUS_IS_OK(status)) {
+		goto out;
+	}
+	if (info->info18.nt_pwd_active == 0) {
 		DEBUG(0,("get_md4pw: Workstation %s: account does not have a password\n", mach_acct));
-		TALLOC_FREE(sampass);
-		return NT_STATUS_LOGON_FAILURE;
+		status = NT_STATUS_LOGON_FAILURE;
+		goto out;
 	}
 
-	memcpy(md4pw->hash, pass, 16);
-	dump_data(5, md4pw->hash, 16);
+	/* samr gives out nthash unencrypted (!) */
+	memcpy(md4pw->hash, info->info18.nt_pwd.hash, 16);
 
-	sid_copy(sid, pdb_get_user_sid(sampass));
+	sid_compose(sid, domain_sid, user_rid);
 
-	TALLOC_FREE(sampass);
-
-	return NT_STATUS_OK;
+ out:
+	if (cli && is_valid_policy_hnd(&user_handle)) {
+		rpccli_samr_Close(cli, mem_ctx, &user_handle);
+	}
 
+	talloc_free(mem_ctx);
 
+	return status;
 }
 
 /*************************************************************************
@@ -829,114 +1023,82 @@ static NTSTATUS netr_creds_server_step_check(pipes_struct *p,
 /*************************************************************************
  *************************************************************************/
 
-static NTSTATUS netr_find_machine_account(TALLOC_CTX *mem_ctx,
-					  const char *account_name,
-					  struct samu **sampassp)
+static NTSTATUS netr_set_machine_account_password(TALLOC_CTX *mem_ctx,
+						  struct auth_serversupplied_info *server_info,
+						  const char *account_name,
+						  struct samr_Password *nt_hash)
 {
-	struct samu *sampass;
-	bool ret = false;
+	NTSTATUS status;
+	struct rpc_pipe_client *cli = NULL;
+	struct policy_handle user_handle;
 	uint32_t acct_ctrl;
+	union samr_UserInfo *info;
+	struct samr_UserInfo18 info18;
+	DATA_BLOB in,out;
 
-	sampass = samu_new(mem_ctx);
-	if (!sampass) {
-		return NT_STATUS_NO_MEMORY;
-	}
+	ZERO_STRUCT(user_handle);
 
-	become_root();
-	ret = pdb_getsampwnam(sampass, account_name);
-	unbecome_root();
+	status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
+					rpc_samr_dispatch, server_info,
+					&cli);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto out;
+	}
 
-	if (!ret) {
-		TALLOC_FREE(sampass);
-		return NT_STATUS_ACCESS_DENIED;
+	status = samr_find_machine_account(mem_ctx, cli, account_name,
+					   SEC_FLAG_MAXIMUM_ALLOWED,
+					   NULL, NULL,
+					   &user_handle);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto out;
 	}
 
-	/* Ensure the account exists and is a machine account. */
+	status = rpccli_samr_QueryUserInfo2(cli, mem_ctx,


-- 
Samba Shared Repository


More information about the samba-cvs mailing list