CVE-2013-4408:s3:Ensure LookupNames replies arrays are range checked.
authorJeremy Allison <jra@samba.org>
Tue, 19 Nov 2013 22:04:19 +0000 (14:04 -0800)
committerKarolin Seeger <kseeger@samba.org>
Thu, 5 Dec 2013 10:11:52 +0000 (11:11 +0100)
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>
21 files changed:
source3/lib/netapi/group.c
source3/lib/netapi/localgroup.c
source3/lib/netapi/user.c
source3/libnet/libnet_join.c
source3/rpc_client/cli_lsarpc.c
source3/rpc_server/netlogon/srv_netlog_nt.c
source3/rpcclient/cmd_lsarpc.c
source3/rpcclient/cmd_samr.c
source3/smbd/lanman.c
source3/utils/net_rpc.c
source3/utils/net_rpc_join.c
source3/winbindd/winbindd_rpc.c
source4/libcli/util/clilsa.c
source4/libnet/groupinfo.c
source4/libnet/groupman.c
source4/libnet/libnet_join.c
source4/libnet/libnet_lookup.c
source4/libnet/libnet_passwd.c
source4/libnet/userinfo.c
source4/libnet/userman.c
source4/winbind/wb_async_helpers.c

index 4295d9f7bbf7ba52f8b9b9f3fd2df2c021601eef..360640f53962e8cee468400a5b2dc9951de1f97f 100644 (file)
@@ -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;
@@ -1514,6 +1571,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,
@@ -1689,6 +1754,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,
@@ -1767,6 +1840,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(),
index 49ba74ec1722bb6a35abab62b7cc85d9302f7dd0..d9c3c8ebea9dfa64ebb629371505fdc9b868135c 100644 (file)
@@ -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);
index 653ece1385409ae1df26f8398bb9ba1785095821..d16d2261ba13bf6f91eb0daea408f2fd72fdcba7 100644 (file)
@@ -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,
@@ -1967,6 +1983,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,
@@ -3026,6 +3050,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,
@@ -3201,6 +3233,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,
@@ -3261,6 +3301,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;
        num_member_rids = group_rids.count;
@@ -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,
index e84682dae2b1f82bf2119383e094c8d178502df2..d665d729a8b08ee9f54c0921b98a5c4953f961b0 100644 (file)
@@ -997,6 +997,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",
@@ -1376,6 +1384,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,
index e7e8236012f7d7f43d439fb8d88f70c2e1eaa99e..dd1f6925475d82fad16a2efb2c4bec786bd10531 100644 (file)
@@ -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);
index 3fd93bcb2805cec1820cbd80d5aca7e288ab249f..3b1cdcff287c626f371d80f507cab9fb38572b13 100644 (file)
@@ -586,7 +586,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;
        }
index 9893a7c6d308b8e648ce40fc5d0012b360d18779..83b76e99832f18503829721db29f0c65d702181d 100644 (file)
@@ -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);
index 727c9d1456039386fcf0e42dcfe59b06f83d8ed4..0a6dede65c2afbba439428de01f4f13729962756 100644 (file)
@@ -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,
@@ -1450,6 +1460,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,
@@ -2112,6 +2131,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 */
 
@@ -2269,6 +2296,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,
@@ -2372,6 +2407,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,
@@ -2758,6 +2801,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,
@@ -3161,7 +3212,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,
index f56ea30c0eb3c3d28f0052bebe160a5a73e92ed5..aef12df9d2d9547dffd2614e3fac6a443d4bddbc 100644 (file)
@@ -2628,6 +2628,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,
index c0d52edde2d3458129db9066aadd39f17652f4af..582f4500a65d41ba03e415fbf61a20822dc66b89 100644 (file)
@@ -1656,6 +1656,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])
        {
@@ -2063,6 +2071,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,
@@ -2318,6 +2334,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,
@@ -3101,9 +3125,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,
@@ -6018,6 +6048,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,
index f2309f65ecd937e989bc426bc6e746291f02d0ef..b1d6e91b572b1ec0c937bad29d7f8dc9b17b99d3 100644 (file)
@@ -367,6 +367,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;
index ad4ce443a5294343bb68ec15dcbebab119e5eb48..344f2dc6280b51937db77e7cfd55f196f4964a5a 100644 (file)
@@ -1039,7 +1039,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;
 
@@ -1064,10 +1064,6 @@ static NTSTATUS rpc_try_lookup_sids3(TALLOC_CTX *mem_ctx,
                return NT_STATUS_INVALID_NETWORK_RESPONSE;
        }
 
-       names = TALLOC_ZERO_P(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);
@@ -1090,7 +1086,6 @@ static NTSTATUS rpc_try_lookup_sids3(TALLOC_CTX *mem_ctx,
                        return NT_STATUS_INVALID_NETWORK_RESPONSE;
                }
        }
-       *pnames = names;
        return result;
 }
 
@@ -1100,7 +1095,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;
@@ -1117,10 +1112,6 @@ NTSTATUS rpc_lookup_sids(TALLOC_CTX *mem_ctx,
                                            pdomains, pnames);
        }
 
-       names = TALLOC_ZERO_P(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,
@@ -1148,6 +1139,5 @@ NTSTATUS rpc_lookup_sids(TALLOC_CTX *mem_ctx,
                }
        }
 
-       *pnames = names;
        return result;
 }
index d705abdca49593bff55333e1bb7f92cc7ade9bfa..7fe3fe3a4927ebd20230ef070e26351879accd02 100644 (file)
@@ -329,7 +329,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;
index 44c21eed3fb82c9aa2b2790288dc63bad8306bc4..2b7963c8eebd446494289fafe33c32d5dd73f46e 100644 (file)
@@ -87,12 +87,16 @@ 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;
        }
 
        /* TODO: find proper status code for more than one rid found */
index c8762f4f1468d15d055b2ba9b7b50ecc13abaa9c..c8e0e060b72f82997dd08742542c11041023bde5 100644 (file)
@@ -212,13 +212,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;
        }
index 6e76df43e3d6d6b8d2f02f2cb92e12ea2b985078..81ec4031b40e56d41821f21552de201351acd262 100644 (file)
@@ -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;
index f9379405d08a1da1e1ca94cfd12f1f05dc2bc5f2..204978b2bb100d69a58c1cdbee146d6b93a9c581 100644 (file)
@@ -363,6 +363,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);
 }
 
index 861d746fd118c8db2ce1a2be6f4285c765856c2d..77176bc16c7b6028776969e3397ad1505a560ae9 100644 (file)
@@ -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;
index 8d9c8419971c4ed74f4c9ded8680791e5b976a62..c77e9bfa941f1368e4bf9e3eb26d4c2ce479421a 100644 (file)
@@ -90,8 +90,13 @@ 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;
        }
 
        /* TODO: find proper status code for more than one rid found */
index 0f586b1d43cbd1b978e43c3a39f3534be89ba0c1..b4399ce292ef2f0ff7c187f8cd8f9737c4dfb64d 100644 (file)
@@ -236,14 +236,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;
        }
 
@@ -511,14 +509,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;
        }
 
index 01ff4a42e99cd9b80919d8eda5dfec0a158647da..bb6dd27f48c822753a2bceb0a90b995e4680b765 100644 (file)
@@ -283,6 +283,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;
@@ -301,9 +307,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;
                }