diff options
author | Jeremy Allison <jra@samba.org> | 2013-11-07 21:40:55 -0800 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2013-12-09 07:05:46 +0100 |
commit | 0dc618189469bf389a583eb346ddc6acaad1c644 (patch) | |
tree | c2a788305792a22c554009077b5ffc9695bd5bbd | |
parent | b0ba4a562112fc707f540e1ff7c8e55ea02479c9 (diff) | |
download | samba-0dc618189469bf389a583eb346ddc6acaad1c644.tar.gz samba-0dc618189469bf389a583eb346ddc6acaad1c644.tar.xz samba-0dc618189469bf389a583eb346ddc6acaad1c644.zip |
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@samba.org>
Signed-off-by: Jeremy Allison <jra@samba.org>
-rw-r--r-- | source3/lib/netapi/group.c | 82 | ||||
-rw-r--r-- | source3/lib/netapi/localgroup.c | 8 | ||||
-rw-r--r-- | source3/lib/netapi/user.c | 56 | ||||
-rw-r--r-- | source3/libnet/libnet_join.c | 16 | ||||
-rw-r--r-- | source3/rpc_client/cli_lsarpc.c | 18 | ||||
-rw-r--r-- | source3/rpc_server/netlogon/srv_netlog_nt.c | 2 | ||||
-rw-r--r-- | source3/rpcclient/cmd_lsarpc.c | 6 | ||||
-rw-r--r-- | source3/rpcclient/cmd_samr.c | 58 | ||||
-rw-r--r-- | source3/smbd/lanman.c | 8 | ||||
-rw-r--r-- | source3/utils/net_rpc.c | 40 | ||||
-rw-r--r-- | source3/winbindd/winbindd_rpc.c | 14 | ||||
-rw-r--r-- | source4/libcli/util/clilsa.c | 6 | ||||
-rw-r--r-- | source4/libnet/groupinfo.c | 9 | ||||
-rw-r--r-- | source4/libnet/groupman.c | 10 | ||||
-rw-r--r-- | source4/libnet/libnet_join.c | 12 | ||||
-rw-r--r-- | source4/libnet/libnet_lookup.c | 5 | ||||
-rw-r--r-- | source4/libnet/libnet_passwd.c | 10 | ||||
-rw-r--r-- | source4/libnet/userinfo.c | 8 | ||||
-rw-r--r-- | source4/libnet/userman.c | 24 | ||||
-rw-r--r-- | source4/winbind/wb_async_helpers.c | 13 |
20 files changed, 359 insertions, 46 deletions
diff --git a/source3/lib/netapi/group.c b/source3/lib/netapi/group.c index 38ed6df84d2..ea0414614d4 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 6501eddcc63..241970da3c8 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 a2d6c79789d..72d4a8bdc39 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 4200c2d4740..c1eccda1af1 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -1027,6 +1027,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", @@ -1422,6 +1430,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 7cadd6edacd..974538b87bd 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 53eff5fcb4a..c83963393f6 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 0fb371990c4..9117ce65597 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 022230becb5..5bc8c0b57b8 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 51d5fbf2233..5e6a8a05603 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 7c5e1e115ad..a11ad3df928 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -1836,6 +1836,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]) { @@ -2243,6 +2251,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, @@ -2499,6 +2515,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, @@ -3284,9 +3308,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, @@ -6236,6 +6266,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/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c index 7345ea798ed..6b88c8413c5 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 cc0dae5984f..0437352e757 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 9060973e02e..5c8b0f734ca 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 9771ea54966..59a3f35d62c 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 09774038fb3..8c1b57ddde1 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 cf2d70c41df..77072b7ecce 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 861d746fd11..77176bc16c7 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 75c46e477d7..9530f9efdb5 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 c1ee0179902..a7301eab6c6 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 e3de2eb38ea..2a05f124656 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; } |