[Pkg-samba-maint] [samba] 16/26: CVE-2013-4408:s3:Ensure LookupNames replies arrays are range checked.

Ivo De Decker idd-guest at moszumanska.debian.org
Mon Dec 9 22:22:16 UTC 2013


This is an automated email from the git hooks/post-receive script.

idd-guest pushed a commit to branch samba_4.1
in repository samba.

commit c406802cf767929c7016041da51fb512094a7f30
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Nov 7 21:40:55 2013 -0800

    CVE-2013-4408:s3:Ensure LookupNames replies arrays are range checked.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=10185
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/lib/netapi/group.c                  | 82 +++++++++++++++++++++++++++++
 source3/lib/netapi/localgroup.c             |  8 ++-
 source3/lib/netapi/user.c                   | 56 ++++++++++++++++++++
 source3/libnet/libnet_join.c                | 16 ++++++
 source3/rpc_client/cli_lsarpc.c             | 18 +++++++
 source3/rpc_server/netlogon/srv_netlog_nt.c |  2 +-
 source3/rpcclient/cmd_lsarpc.c              |  6 ++-
 source3/rpcclient/cmd_samr.c                | 58 +++++++++++++++++++-
 source3/smbd/lanman.c                       |  8 +++
 source3/utils/net_rpc.c                     | 40 +++++++++++++-
 source3/utils/net_rpc_join.c                |  9 ++++
 source3/winbindd/winbindd_rpc.c             | 14 +----
 source4/libcli/util/clilsa.c                |  6 ++-
 source4/libnet/groupinfo.c                  |  9 ++--
 source4/libnet/groupman.c                   | 10 ++--
 source4/libnet/libnet_join.c                | 12 ++++-
 source4/libnet/libnet_lookup.c              |  5 ++
 source4/libnet/libnet_passwd.c              | 10 +++-
 source4/libnet/userinfo.c                   |  8 ++-
 source4/libnet/userman.c                    | 24 ++++-----
 source4/winbind/wb_async_helpers.c          | 13 ++++-
 21 files changed, 368 insertions(+), 46 deletions(-)

diff --git a/source3/lib/netapi/group.c b/source3/lib/netapi/group.c
index 9813f7e..69c7af4 100644
--- a/source3/lib/netapi/group.c
+++ b/source3/lib/netapi/group.c
@@ -309,6 +309,15 @@ WERROR NetGroupDel_r(struct libnetapi_ctx *ctx,
 		goto done;
 	}
 
+	if (rids.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
+	if (types.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
+
 	if (types.ids[0] != SID_NAME_DOM_GRP) {
 		werr = WERR_INVALID_DATATYPE;
 		goto done;
@@ -511,6 +520,14 @@ WERROR NetGroupSetInfo_r(struct libnetapi_ctx *ctx,
 		werr = ntstatus_to_werror(result);
 		goto done;
 	}
+	if (rids.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
+	if (types.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
 
 	if (types.ids[0] != SID_NAME_DOM_GRP) {
 		werr = WERR_INVALID_DATATYPE;
@@ -781,6 +798,14 @@ WERROR NetGroupGetInfo_r(struct libnetapi_ctx *ctx,
 		werr = ntstatus_to_werror(result);
 		goto done;
 	}
+	if (rids.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
+	if (types.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
 
 	if (types.ids[0] != SID_NAME_DOM_GRP) {
 		werr = WERR_INVALID_DATATYPE;
@@ -921,6 +946,14 @@ WERROR NetGroupAddUser_r(struct libnetapi_ctx *ctx,
 		werr = WERR_GROUPNOTFOUND;
 		goto done;
 	}
+	if (rids.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
+	if (types.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
 
 	if (types.ids[0] != SID_NAME_DOM_GRP) {
 		werr = WERR_GROUPNOTFOUND;
@@ -959,6 +992,14 @@ WERROR NetGroupAddUser_r(struct libnetapi_ctx *ctx,
 		werr = WERR_USER_NOT_FOUND;
 		goto done;
 	}
+	if (rids.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
+	if (types.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
 
 	if (types.ids[0] != SID_NAME_USER) {
 		werr = WERR_USER_NOT_FOUND;
@@ -1065,6 +1106,14 @@ WERROR NetGroupDelUser_r(struct libnetapi_ctx *ctx,
 		werr = WERR_GROUPNOTFOUND;
 		goto done;
 	}
+	if (rids.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
+	if (types.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
 
 	if (types.ids[0] != SID_NAME_DOM_GRP) {
 		werr = WERR_GROUPNOTFOUND;
@@ -1104,6 +1153,14 @@ WERROR NetGroupDelUser_r(struct libnetapi_ctx *ctx,
 		werr = WERR_USER_NOT_FOUND;
 		goto done;
 	}
+	if (rids.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
+	if (types.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
 
 	if (types.ids[0] != SID_NAME_USER) {
 		werr = WERR_USER_NOT_FOUND;
@@ -1515,6 +1572,14 @@ WERROR NetGroupGetUsers_r(struct libnetapi_ctx *ctx,
 		werr = ntstatus_to_werror(result);
 		goto done;
 	}
+	if (group_rids.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
+	if (name_types.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
 
 	status = dcerpc_samr_OpenGroup(b, talloc_tos(),
 				       &domain_handle,
@@ -1691,6 +1756,14 @@ WERROR NetGroupSetUsers_r(struct libnetapi_ctx *ctx,
 		werr = ntstatus_to_werror(result);
 		goto done;
 	}
+	if (group_rids.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
+	if (group_types.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
 
 	status = dcerpc_samr_OpenGroup(b, talloc_tos(),
 				       &domain_handle,
@@ -1769,6 +1842,15 @@ WERROR NetGroupSetUsers_r(struct libnetapi_ctx *ctx,
 		goto done;
 	}
 
+	if (r->in.num_entries != user_rids.count) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
+	if (r->in.num_entries != name_types.count) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
+
 	member_rids = user_rids.ids;
 
 	status = dcerpc_samr_QueryGroupMember(b, talloc_tos(),
diff --git a/source3/lib/netapi/localgroup.c b/source3/lib/netapi/localgroup.c
index 1a544ad..17cab68 100644
--- a/source3/lib/netapi/localgroup.c
+++ b/source3/lib/netapi/localgroup.c
@@ -58,6 +58,12 @@ static NTSTATUS libnetapi_samr_lookup_and_open_alias(TALLOC_CTX *mem_ctx,
 	if (!NT_STATUS_IS_OK(result)) {
 		return result;
 	}
+	if (user_rids.count != 1) {
+		return NT_STATUS_INVALID_NETWORK_RESPONSE;
+	}
+	if (name_types.count != 1) {
+		return NT_STATUS_INVALID_NETWORK_RESPONSE;
+	}
 
 	switch (name_types.ids[0]) {
 		case SID_NAME_ALIAS:
@@ -1041,7 +1047,7 @@ static NTSTATUS libnetapi_lsa_lookup_names3(TALLOC_CTX *mem_ctx,
 	NT_STATUS_NOT_OK_RETURN(result);
 
 	if (count != 1 || sids.count != 1) {
-		return NT_STATUS_NONE_MAPPED;
+		return NT_STATUS_INVALID_NETWORK_RESPONSE;
 	}
 
 	sid_copy(sid, sids.sids[0].sid);
diff --git a/source3/lib/netapi/user.c b/source3/lib/netapi/user.c
index df3914c..e699ad3 100644
--- a/source3/lib/netapi/user.c
+++ b/source3/lib/netapi/user.c
@@ -604,6 +604,14 @@ WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
 		werr = ntstatus_to_werror(result);
 		goto done;
 	}
+	if (user_rids.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
+	if (name_types.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
 
 	status = dcerpc_samr_OpenUser(b, talloc_tos(),
 				      &domain_handle,
@@ -1803,6 +1811,14 @@ WERROR NetUserGetInfo_r(struct libnetapi_ctx *ctx,
 		werr = ntstatus_to_werror(result);
 		goto done;
 	}
+	if (user_rids.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
+	if (name_types.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
 
 	status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
 							  domain_sid,
@@ -1968,6 +1984,14 @@ WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
 		werr = ntstatus_to_werror(result);
 		goto done;
 	}
+	if (user_rids.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
+	if (name_types.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
 
 	status = dcerpc_samr_OpenUser(b, talloc_tos(),
 				      &domain_handle,
@@ -3027,6 +3051,14 @@ WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx,
 		werr = ntstatus_to_werror(result);
 		goto done;
 	}
+	if (user_rids.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
+	if (name_types.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
 
 	status = dcerpc_samr_OpenUser(b, talloc_tos(),
 				      &domain_handle,
@@ -3202,6 +3234,14 @@ WERROR NetUserSetGroups_r(struct libnetapi_ctx *ctx,
 		werr = ntstatus_to_werror(result);
 		goto done;
 	}
+	if (user_rids.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
+	if (name_types.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
 
 	status = dcerpc_samr_OpenUser(b, talloc_tos(),
 				      &domain_handle,
@@ -3262,6 +3302,14 @@ WERROR NetUserSetGroups_r(struct libnetapi_ctx *ctx,
 		werr = ntstatus_to_werror(result);
 		goto done;
 	}
+	if (group_rids.count != r->in.num_entries) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
+	if (name_types.count != r->in.num_entries) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
 
 	member_rids = group_rids.ids;
 
@@ -3539,6 +3587,14 @@ WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx,
 		werr = ntstatus_to_werror(result);
 		goto done;
 	}
+	if (user_rids.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
+	if (name_types.count != 1) {
+		werr = WERR_BAD_NET_RESP;
+		goto done;
+	}
 
 	status = dcerpc_samr_OpenUser(b, talloc_tos(),
 				      &domain_handle,
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index dfe7283..29d1944 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -1023,6 +1023,14 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx,
 		status = result;
 		goto done;
 	}
+	if (user_rids.count != 1) {
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto done;
+	}
+	if (name_types.count != 1) {
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto done;
+	}
 
 	if (name_types.ids[0] != SID_NAME_USER) {
 		DEBUG(0,("%s is not a user account (type=%d)\n",
@@ -1416,6 +1424,14 @@ static NTSTATUS libnet_join_unjoindomain_rpc(TALLOC_CTX *mem_ctx,
 		status = result;
 		goto done;
 	}
+	if (user_rids.count != 1) {
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto done;
+	}
+	if (name_types.count != 1) {
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto done;
+	}
 
 	if (name_types.ids[0] != SID_NAME_USER) {
 		DEBUG(0, ("%s is not a user account (type=%d)\n", acct_name,
diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c
index 7cadd6e..974538b 100644
--- a/source3/rpc_client/cli_lsarpc.c
+++ b/source3/rpc_client/cli_lsarpc.c
@@ -662,9 +662,19 @@ NTSTATUS dcerpc_lsa_lookup_names_generic(struct dcerpc_binding_handle *h,
 		struct dom_sid *sid = &(*sids)[i];
 
 		if (use_lookupnames4) {
+			if (i >= sid_array3.count) {
+				*presult = NT_STATUS_INVALID_NETWORK_RESPONSE;
+				goto done;
+			}
+
 			dom_idx		= sid_array3.sids[i].sid_index;
 			(*types)[i]	= sid_array3.sids[i].sid_type;
 		} else {
+			if (i >= sid_array.count) {
+				*presult = NT_STATUS_INVALID_NETWORK_RESPONSE;
+				goto done;
+			}
+
 			dom_idx		= sid_array.sids[i].sid_index;
 			(*types)[i]	= sid_array.sids[i].sid_type;
 		}
@@ -677,6 +687,14 @@ NTSTATUS dcerpc_lsa_lookup_names_generic(struct dcerpc_binding_handle *h,
 			(*types)[i] = SID_NAME_UNKNOWN;
 			continue;
 		}
+		if (domains == NULL) {
+			*presult = NT_STATUS_INVALID_NETWORK_RESPONSE;
+			goto done;
+		}
+		if (dom_idx >= domains->count) {
+			*presult = NT_STATUS_INVALID_NETWORK_RESPONSE;
+			goto done;
+		}
 
 		if (use_lookupnames4) {
 			sid_copy(sid, sid_array3.sids[i].sid);
diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
index 6a6c125..e5ca474 100644
--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
@@ -580,7 +580,7 @@ static NTSTATUS samr_find_machine_account(TALLOC_CTX *mem_ctx,
 		status = NT_STATUS_NO_SUCH_USER;
 		goto out;
 	}
-	if (rids.count != types.count) {
+	if (types.count != 1) {
 		status = NT_STATUS_INVALID_PARAMETER;
 		goto out;
 	}
diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c
index a7ee4e4..5c28b1c 100644
--- a/source3/rpcclient/cmd_lsarpc.c
+++ b/source3/rpcclient/cmd_lsarpc.c
@@ -323,7 +323,7 @@ static NTSTATUS cmd_lsa_lookup_names4(struct rpc_pipe_client *cli,
 
 	uint32_t num_names;
 	struct lsa_String *names;
-	struct lsa_RefDomainList *domains;
+	struct lsa_RefDomainList *domains = NULL;
 	struct lsa_TransSidArray3 sids;
 	uint32_t count = 0;
 	int i;
@@ -361,6 +361,10 @@ static NTSTATUS cmd_lsa_lookup_names4(struct rpc_pipe_client *cli,
 		return result;
 	}
 
+	if (sids.count != num_names) {
+		return NT_STATUS_INVALID_NETWORK_RESPONSE;
+	}
+
 	for (i = 0; i < sids.count; i++) {
 		fstring sid_str;
 		sid_to_fstring(sid_str, sids.sids[i].sid);
diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c
index 022230b..5bc8c0b 100644
--- a/source3/rpcclient/cmd_samr.c
+++ b/source3/rpcclient/cmd_samr.c
@@ -385,7 +385,17 @@ static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli,
 		if (!NT_STATUS_IS_OK(status)) {
 			goto done;
 		}
+
 		if (NT_STATUS_IS_OK(result)) {
+			if (rids.count != 1) {
+				status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+				goto done;
+			}
+			if (types.count != 1) {
+				status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+				goto done;
+			}
+
 			status = dcerpc_samr_OpenUser(b, mem_ctx,
 						      &domain_pol,
 						      access_mask,
@@ -1453,6 +1463,15 @@ static NTSTATUS cmd_samr_delete_alias(struct rpc_pipe_client *cli,
 			goto done;
 		}
 		if (NT_STATUS_IS_OK(result)) {
+			if (rids.count != 1) {
+				status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+				goto done;
+			}
+			if (types.count != 1) {
+				status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+				goto done;
+			}
+
 			status = dcerpc_samr_OpenAlias(b, mem_ctx,
 						       &domain_pol,
 						       access_mask,
@@ -2115,6 +2134,14 @@ static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli,
 		status = result;
 		goto done;
 	}
+	if (rids.count != num_names) {
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto done;
+	}
+	if (name_types.count != num_names) {
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto done;
+	}
 
 	/* Display results */
 
@@ -2272,6 +2299,14 @@ static NTSTATUS cmd_samr_delete_dom_group(struct rpc_pipe_client *cli,
 			status = result;
 			goto done;
 		}
+		if (group_rids.count != 1) {
+			status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+			goto done;
+		}
+		if (name_types.count != 1) {
+			status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+			goto done;
+		}
 
 		status = dcerpc_samr_OpenGroup(b, mem_ctx,
 					       &domain_pol,
@@ -2375,6 +2410,14 @@ static NTSTATUS cmd_samr_delete_dom_user(struct rpc_pipe_client *cli,
 			status = result;
 			goto done;
 		}
+		if (user_rids.count != 1) {
+			status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+			goto done;
+		}
+		if (name_types.count != 1) {
+			status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+			goto done;
+		}
 
 		status = dcerpc_samr_OpenUser(b, mem_ctx,
 					      &domain_pol,
@@ -2763,6 +2806,14 @@ static NTSTATUS cmd_samr_chgpasswd(struct rpc_pipe_client *cli,
 		status = result;
 		goto done;
 	}
+	if (rids.count != 1) {
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto done;
+	}
+	if (types.count != 1) {
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto done;
+	}
 
 	status = dcerpc_samr_OpenUser(b, mem_ctx,
 				      &domain_pol,
@@ -3166,7 +3217,12 @@ static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli,
 		if (!NT_STATUS_IS_OK(result)) {
 			return result;
 		}
-
+		if (rids.count != 1) {
+			return NT_STATUS_INVALID_NETWORK_RESPONSE;
+		}
+		if (types.count != 1) {
+			return NT_STATUS_INVALID_NETWORK_RESPONSE;
+		}
 
 		status = dcerpc_samr_OpenUser(b, mem_ctx,
 					      &domain_pol,
diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c
index b5598a4..e6b9530 100644
--- a/source3/smbd/lanman.c
+++ b/source3/smbd/lanman.c
@@ -2629,6 +2629,14 @@ static bool api_NetUserGetGroups(struct smbd_server_connection *sconn,
 			  nt_errstr(result)));
 		goto close_domain;
 	}
+	if (rid.count != 1) {
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto close_domain;
+	}
+	if (type.count != 1) {
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto close_domain;
+	}
 
 	if (type.ids[0] != SID_NAME_USER) {
 		DEBUG(10, ("%s is a %s, not a user\n", UserName,
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
index 870ad22..e0c8eea 100644
--- a/source3/utils/net_rpc.c
+++ b/source3/utils/net_rpc.c
@@ -1667,6 +1667,14 @@ static NTSTATUS rpc_group_delete_internals(struct net_context *c,
 		d_fprintf(stderr, _("Lookup of '%s' failed\n"),argv[0]);
 		goto done;
 	}
+	if (group_rids.count != 1) {
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto done;
+	}
+	if (name_types.count != 1) {
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto done;
+	}
 
 	switch (name_types.ids[0])
 	{
@@ -2074,6 +2082,14 @@ static NTSTATUS rpc_add_groupmem(struct rpc_pipe_client *pipe_hnd,
 			  member);
 		goto done;
 	}
+	if (rids.count != 1) {
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto done;
+	}
+	if (rid_types.count != 1) {
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto done;
+	}
 
 	status = dcerpc_samr_OpenGroup(b, mem_ctx,
 				       &domain_pol,
@@ -2329,6 +2345,14 @@ static NTSTATUS rpc_del_groupmem(struct net_context *c,
 			  member);
 		goto done;
 	}
+	if (rids.count != 1) {
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto done;
+	}
+	if (rid_types.count != 1) {
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto done;
+	}
 
 	status = dcerpc_samr_OpenGroup(b, mem_ctx,
 				       &domain_pol,
@@ -3112,9 +3136,15 @@ static NTSTATUS rpc_group_members_internals(struct net_context *c,
 	if (rids.count != 1) {
 		d_fprintf(stderr, _("Couldn't find group %s\n"),
 			  argv[0]);
-		return result;
+		return NT_STATUS_INVALID_NETWORK_RESPONSE;
+	}
+	if (rid_types.count != 1) {
+		d_fprintf(stderr, _("Couldn't find group %s\n"),
+			  argv[0]);
+		return NT_STATUS_INVALID_NETWORK_RESPONSE;
 	}
 
+
 	if (rid_types.ids[0] == SID_NAME_DOM_GRP) {
 		return rpc_list_group_members(c, pipe_hnd, mem_ctx, domain_name,
 					      domain_sid, &domain_pol,
@@ -6064,6 +6094,14 @@ static NTSTATUS rpc_trustdom_del_internals(struct net_context *c,
 			acct_name, nt_errstr(result) );
 		goto done;
 	}
+	if (user_rids.count != 1) {
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto done;
+	}
+	if (name_types.count != 1) {
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto done;
+	}
 
 	status = dcerpc_samr_OpenUser(b, mem_ctx,
 				      &domain_pol,
diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c
index 7167cf9..56799cd 100644
--- a/source3/utils/net_rpc_join.c
+++ b/source3/utils/net_rpc_join.c
@@ -380,6 +380,15 @@ int net_rpc_join_newstyle(struct net_context *c, int argc, const char **argv)
 			    ("error looking up rid for user %s: %s/%s\n",
 			     acct_name, nt_errstr(status), nt_errstr(result)));
 
+	if (user_rids.count != 1) {
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto done;
+	}
+	if (name_types.count != 1) {
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto done;
+	}
+
 	if (name_types.ids[0] != SID_NAME_USER) {
 		DEBUG(0, ("%s is not a user account (type=%d)\n", acct_name, name_types.ids[0]));
 		goto done;
diff --git a/source3/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c
index 7345ea7..6b88c84 100644
--- a/source3/winbindd/winbindd_rpc.c
+++ b/source3/winbindd/winbindd_rpc.c
@@ -1063,7 +1063,7 @@ static NTSTATUS rpc_try_lookup_sids3(TALLOC_CTX *mem_ctx,
 				     struct lsa_TransNameArray **pnames)
 {
 	struct lsa_TransNameArray2 lsa_names2;
-	struct lsa_TransNameArray *names;
+	struct lsa_TransNameArray *names = *pnames;
 	uint32_t i, count;
 	NTSTATUS status, result;
 
@@ -1088,10 +1088,6 @@ static NTSTATUS rpc_try_lookup_sids3(TALLOC_CTX *mem_ctx,
 		return NT_STATUS_INVALID_NETWORK_RESPONSE;
 	}
 
-	names = talloc_zero(mem_ctx, struct lsa_TransNameArray);
-	if (names == NULL) {
-		return NT_STATUS_NO_MEMORY;
-	}
 	names->count = lsa_names2.count;
 	names->names = talloc_array(names, struct lsa_TranslatedName,
 				    names->count);
@@ -1114,7 +1110,6 @@ static NTSTATUS rpc_try_lookup_sids3(TALLOC_CTX *mem_ctx,
 			return NT_STATUS_INVALID_NETWORK_RESPONSE;
 		}
 	}
-	*pnames = names;
 	return result;
 }
 
@@ -1124,7 +1119,7 @@ NTSTATUS rpc_lookup_sids(TALLOC_CTX *mem_ctx,
 			 struct lsa_RefDomainList **pdomains,
 			 struct lsa_TransNameArray **pnames)
 {
-	struct lsa_TransNameArray *names;
+	struct lsa_TransNameArray *names = *pnames;
 	struct rpc_pipe_client *cli = NULL;
 	struct policy_handle lsa_policy;
 	uint32_t count;
@@ -1141,10 +1136,6 @@ NTSTATUS rpc_lookup_sids(TALLOC_CTX *mem_ctx,
 					    pdomains, pnames);
 	}
 
-	names = talloc_zero(mem_ctx, struct lsa_TransNameArray);
-	if (names == NULL) {
-		return NT_STATUS_NO_MEMORY;
-	}
 	status = dcerpc_lsa_LookupSids(cli->binding_handle, mem_ctx,
 				       &lsa_policy, sids, pdomains,
 				       names, LSA_LOOKUP_NAMES_ALL,
@@ -1172,6 +1163,5 @@ NTSTATUS rpc_lookup_sids(TALLOC_CTX *mem_ctx,
 		}
 	}
 
-	*pnames = names;
 	return result;
 }
diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c
index cc0dae5..0437352 100644
--- a/source4/libcli/util/clilsa.c
+++ b/source4/libcli/util/clilsa.c
@@ -335,7 +335,11 @@ NTSTATUS smblsa_lookup_name(struct smbcli_state *cli,
 	}
 	if (sids.count != 1) {
 		talloc_free(mem_ctx2);
-		return NT_STATUS_UNSUCCESSFUL;
+		return NT_STATUS_INVALID_NETWORK_RESPONSE;
+	}
+	if (domains->count != 1) {
+		talloc_free(mem_ctx2);
+		return NT_STATUS_INVALID_NETWORK_RESPONSE;
 	}
 
 	sid = domains->domains[0].sid;
diff --git a/source4/libnet/groupinfo.c b/source4/libnet/groupinfo.c
index 9060973..5c8b0f7 100644
--- a/source4/libnet/groupinfo.c
+++ b/source4/libnet/groupinfo.c
@@ -88,11 +88,14 @@ static void continue_groupinfo_lookup(struct tevent_req *subreq)
 		s->monitor_fn(&msg);
 	}
 	
-
 	/* have we actually got name resolved
 	   - we're looking for only one at the moment */
-	if (s->lookup.out.rids->count == 0) {
-		composite_error(c, NT_STATUS_NO_SUCH_USER);
+	if (s->lookup.out.rids->count != s->lookup.in.num_names) {
+		composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
+		return;
+	}
+	if (s->lookup.out.types->count != s->lookup.in.num_names) {
+		composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
 		return;
 	}
 
diff --git a/source4/libnet/groupman.c b/source4/libnet/groupman.c
index 9771ea5..59a3f35 100644
--- a/source4/libnet/groupman.c
+++ b/source4/libnet/groupman.c
@@ -219,13 +219,13 @@ static void continue_groupdel_name_found(struct tevent_req *subreq)
 
 	/* what to do when there's no group account to delete
 	   and what if there's more than one rid resolved */
-	if (!s->lookupname.out.rids->count) {
-		c->status = NT_STATUS_NO_SUCH_GROUP;
+	if (s->lookupname.out.rids->count != s->lookupname.in.num_names) {
+		c->status = NT_STATUS_INVALID_NETWORK_RESPONSE;
 		composite_error(c, c->status);
 		return;
-
-	} else if (!s->lookupname.out.rids->count > 1) {
-		c->status = NT_STATUS_INVALID_ACCOUNT_NAME;
+	}
+	if (s->lookupname.out.types->count != s->lookupname.in.num_names) {
+		c->status = NT_STATUS_INVALID_NETWORK_RESPONSE;
 		composite_error(c, c->status);
 		return;
 	}
diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c
index 0977403..8c1b57d 100644
--- a/source4/libnet/libnet_join.c
+++ b/source4/libnet/libnet_join.c
@@ -656,9 +656,17 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
 							      "samr_LookupNames for [%s] returns %d RIDs",
 							      r->in.account_name, ln.out.rids->count);
 			talloc_free(tmp_ctx);
-			return NT_STATUS_INVALID_PARAMETER;
+			return NT_STATUS_INVALID_NETWORK_RESPONSE;
 		}
-		
+
+		if (ln.out.types->count != 1) {
+			r->out.error_string = talloc_asprintf(mem_ctx,
+								"samr_LookupNames for [%s] returns %d RID TYPEs",
+								r->in.account_name, ln.out.types->count);
+			talloc_free(tmp_ctx);
+			return NT_STATUS_INVALID_NETWORK_RESPONSE;
+		}
+
 		/* prepare samr_OpenUser */
 		ZERO_STRUCTP(u_handle);
 		ou.in.domain_handle = &d_handle;
diff --git a/source4/libnet/libnet_lookup.c b/source4/libnet/libnet_lookup.c
index cf2d70c..77072b7 100644
--- a/source4/libnet/libnet_lookup.c
+++ b/source4/libnet/libnet_lookup.c
@@ -365,6 +365,11 @@ static void continue_name_found(struct tevent_req *subreq)
 	c->status = s->lookup.out.result;
 	if (!composite_is_ok(c)) return;
 
+	if (s->lookup.out.sids->count != s->lookup.in.num_names) {
+		composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
+		return;
+	}
+
 	composite_done(c);
 }
 
diff --git a/source4/libnet/libnet_passwd.c b/source4/libnet/libnet_passwd.c
index 861d746..77176bc 100644
--- a/source4/libnet/libnet_passwd.c
+++ b/source4/libnet/libnet_passwd.c
@@ -627,10 +627,18 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
 		r->samr.out.error_string = talloc_asprintf(mem_ctx,
 						"samr_LookupNames for [%s] returns %d RIDs",
 						r->samr.in.account_name, ln.out.rids->count);
-		status = NT_STATUS_INVALID_PARAMETER;
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
 		goto disconnect;	
 	}
 
+	if (ln.out.types->count != 1) {
+		r->samr.out.error_string = talloc_asprintf(mem_ctx,
+						"samr_LookupNames for [%s] returns %d RID TYPEs",
+						r->samr.in.account_name, ln.out.types->count);
+		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+		goto disconnect;
+	}
+
 	/* prepare samr_OpenUser */
 	ZERO_STRUCT(u_handle);
 	ou.in.domain_handle = &d_handle;
diff --git a/source4/libnet/userinfo.c b/source4/libnet/userinfo.c
index 75c46e4..9530f9e 100644
--- a/source4/libnet/userinfo.c
+++ b/source4/libnet/userinfo.c
@@ -90,8 +90,12 @@ static void continue_userinfo_lookup(struct tevent_req *subreq)
 
 	/* have we actually got name resolved
 	   - we're looking for only one at the moment */
-	if (s->lookup.out.rids->count == 0) {
-		composite_error(c, NT_STATUS_NO_SUCH_USER);
+	if (s->lookup.out.rids->count != s->lookup.in.num_names) {
+		composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
+		return;
+	}
+	if (s->lookup.out.types->count != s->lookup.in.num_names) {
+		composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
 		return;
 	}
 
diff --git a/source4/libnet/userman.c b/source4/libnet/userman.c
index c1ee017..a7301ea 100644
--- a/source4/libnet/userman.c
+++ b/source4/libnet/userman.c
@@ -237,14 +237,12 @@ static void continue_userdel_name_found(struct tevent_req *subreq)
 
 	/* what to do when there's no user account to delete
 	   and what if there's more than one rid resolved */
-	if (!s->lookupname.out.rids->count) {
-		c->status = NT_STATUS_NO_SUCH_USER;
-		composite_error(c, c->status);
+	if (s->lookupname.out.rids->count != s->lookupname.in.num_names) {
+		composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
 		return;
-
-	} else if (!s->lookupname.out.rids->count > 1) {
-		c->status = NT_STATUS_INVALID_ACCOUNT_NAME;
-		composite_error(c, c->status);
+	}
+	if (s->lookupname.out.types->count != s->lookupname.in.num_names) {
+		composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
 		return;
 	}
 
@@ -513,14 +511,12 @@ static void continue_usermod_name_found(struct tevent_req *subreq)
 
 	/* what to do when there's no user account to delete
 	   and what if there's more than one rid resolved */
-	if (!s->lookupname.out.rids->count) {
-		c->status = NT_STATUS_NO_SUCH_USER;
-		composite_error(c, c->status);
+	if (s->lookupname.out.rids->count != s->lookupname.in.num_names) {
+		composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
 		return;
-
-	} else if (!s->lookupname.out.rids->count > 1) {
-		c->status = NT_STATUS_INVALID_ACCOUNT_NAME;
-		composite_error(c, c->status);
+	}
+	if (s->lookupname.out.types->count != s->lookupname.in.num_names) {
+		composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
 		return;
 	}
 
diff --git a/source4/winbind/wb_async_helpers.c b/source4/winbind/wb_async_helpers.c
index e3de2eb..2a05f12 100644
--- a/source4/winbind/wb_async_helpers.c
+++ b/source4/winbind/wb_async_helpers.c
@@ -285,6 +285,12 @@ static void lsa_lookupnames_recv_sids(struct tevent_req *subreq)
 		return;
 	}
 
+	if (state->sids.count != state->num_names) {
+		composite_error(state->ctx,
+				NT_STATUS_INVALID_NETWORK_RESPONSE);
+		return;
+	}
+
 	state->result = talloc_array(state, struct wb_sid_object *,
 				     state->num_names);
 	if (composite_nomem(state->result, state->ctx)) return;
@@ -303,9 +309,14 @@ static void lsa_lookupnames_recv_sids(struct tevent_req *subreq)
 			continue;
 		}
 
+		if (domains == NULL) {
+			composite_error(state->ctx,
+					NT_STATUS_INVALID_NETWORK_RESPONSE);
+			return;
+		}
 		if (sid->sid_index >= domains->count) {
 			composite_error(state->ctx,
-					NT_STATUS_INVALID_PARAMETER);
+					NT_STATUS_INVALID_NETWORK_RESPONSE);
 			return;
 		}
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-samba/samba.git




More information about the Pkg-samba-maint mailing list