Here is a diff to roll in some security fixes for Samba. CVE-2013-4408 / CVE-2012-6150 -- DCE-RPC fragment length field is incorrectly checked, pam_winbind login without require_membership_of restrictions.
CVE-2013-4475 / CVE-2013-4476 -- ACLs are not checked on opening an alternate data stream on a file or directory, Private key in key.pem world readable. I didn't bother trying to weed out which files are relevant for the CVE-2013-4408 / CVE-2012-6150 patch and which ones are not; it's just easier putting the whole patch in. Any further testing welcome. OK? Index: Makefile =================================================================== RCS file: /home/cvs/ports/net/samba/Makefile,v retrieving revision 1.189 diff -u -p -u -p -r1.189 Makefile --- Makefile 5 Dec 2013 13:08:50 -0000 1.189 +++ Makefile 28 Jan 2014 03:25:57 -0000 @@ -9,7 +9,7 @@ DISTNAME= samba-3.6.15 PKGNAME-main= ${DISTNAME} FULLPKGNAME-docs= ${DISTNAME:S/-/-docs-/} FULLPKGPATH-docs= net/samba,-docs -REVISION-main= 3 +REVISION-main= 4 SHARED_LIBS= smbclient 3.0 \ smbsharemodes 1.0 \ Index: patches/patch-lib_async_req_async_sock_c =================================================================== RCS file: patches/patch-lib_async_req_async_sock_c diff -N patches/patch-lib_async_req_async_sock_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-lib_async_req_async_sock_c 28 Jan 2014 07:17:12 -0000 @@ -0,0 +1,15 @@ +$OpenBSD$ +--- lib/async_req/async_sock.c.orig Wed May 8 04:16:26 2013 ++++ lib/async_req/async_sock.c Tue Jan 28 02:16:43 2014 +@@ -635,6 +635,11 @@ static void read_packet_handler(struct tevent_context + return; + } + ++ if (total + more < total) { ++ tevent_req_error(req, EMSGSIZE); ++ return; ++ } ++ + tmp = talloc_realloc(state, state->buf, uint8_t, total+more); + if (tevent_req_nomem(tmp, req)) { + return; Index: patches/patch-libcli_util_tstream_c =================================================================== RCS file: patches/patch-libcli_util_tstream_c diff -N patches/patch-libcli_util_tstream_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-libcli_util_tstream_c 28 Jan 2014 07:17:12 -0000 @@ -0,0 +1,15 @@ +$OpenBSD$ +--- libcli/util/tstream.c.orig Wed May 8 04:16:26 2013 ++++ libcli/util/tstream.c Tue Jan 28 02:16:43 2014 +@@ -129,6 +129,11 @@ static void tstream_read_pdu_blob_done(struct tevent_r + return; + } + ++ if (new_buf_size <= old_buf_size) { ++ tevent_req_nterror(req, NT_STATUS_INVALID_BUFFER_SIZE); ++ return; ++ } ++ + buf = talloc_realloc(state, state->pdu_blob.data, uint8_t, new_buf_size); + if (tevent_req_nomem(buf, req)) { + return; Index: patches/patch-librpc_idl_dcerpc_idl =================================================================== RCS file: patches/patch-librpc_idl_dcerpc_idl diff -N patches/patch-librpc_idl_dcerpc_idl --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-librpc_idl_dcerpc_idl 28 Jan 2014 07:17:11 -0000 @@ -0,0 +1,11 @@ +$OpenBSD$ +--- librpc/idl/dcerpc.idl.orig Wed May 8 04:16:26 2013 ++++ librpc/idl/dcerpc.idl Tue Jan 28 02:16:43 2014 +@@ -467,6 +467,7 @@ interface dcerpc + const uint8 DCERPC_DREP_OFFSET = 4; + const uint8 DCERPC_FRAG_LEN_OFFSET = 8; + const uint8 DCERPC_AUTH_LEN_OFFSET = 10; ++ const uint8 DCERPC_CALL_ID_OFFSET = 12; + + /* little-endian flag */ + const uint8 DCERPC_DREP_LE = 0x10; Index: patches/patch-librpc_rpc_dcerpc_util_c =================================================================== RCS file: patches/patch-librpc_rpc_dcerpc_util_c diff -N patches/patch-librpc_rpc_dcerpc_util_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-librpc_rpc_dcerpc_util_c 28 Jan 2014 07:17:11 -0000 @@ -0,0 +1,19 @@ +$OpenBSD$ +--- librpc/rpc/dcerpc_util.c.orig Tue Jan 28 02:16:43 2014 ++++ librpc/rpc/dcerpc_util.c Tue Jan 28 02:16:43 2014 +@@ -48,6 +48,15 @@ uint16_t dcerpc_get_frag_length(const DATA_BLOB *blob) + } + } + ++uint32_t dcerpc_get_call_id(const DATA_BLOB *blob) ++{ ++ if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) { ++ return IVAL(blob->data, DCERPC_CALL_ID_OFFSET); ++ } else { ++ return RIVAL(blob->data, DCERPC_CALL_ID_OFFSET); ++ } ++} ++ + void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v) + { + if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) { Index: patches/patch-librpc_rpc_rpc_common_h =================================================================== RCS file: patches/patch-librpc_rpc_rpc_common_h diff -N patches/patch-librpc_rpc_rpc_common_h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-librpc_rpc_rpc_common_h 28 Jan 2014 07:17:11 -0000 @@ -0,0 +1,11 @@ +$OpenBSD$ +--- librpc/rpc/rpc_common.h.orig Wed May 8 04:16:26 2013 ++++ librpc/rpc/rpc_common.h Tue Jan 28 02:16:43 2014 +@@ -135,6 +135,7 @@ enum dcerpc_transport_t dcerpc_transport_by_tower(cons + + void dcerpc_set_frag_length(DATA_BLOB *blob, uint16_t v); + uint16_t dcerpc_get_frag_length(const DATA_BLOB *blob); ++uint32_t dcerpc_get_call_id(const DATA_BLOB *blob); + void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v); + uint8_t dcerpc_get_endian_flag(DATA_BLOB *blob); + Index: patches/patch-nsswitch_libwbclient_wbc_sid_c =================================================================== RCS file: patches/patch-nsswitch_libwbclient_wbc_sid_c diff -N patches/patch-nsswitch_libwbclient_wbc_sid_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-nsswitch_libwbclient_wbc_sid_c 28 Jan 2014 07:17:25 -0000 @@ -0,0 +1,17 @@ +$OpenBSD$ +--- nsswitch/libwbclient/wbc_sid.c.orig Wed May 8 04:16:26 2013 ++++ nsswitch/libwbclient/wbc_sid.c Tue Jan 28 02:16:43 2014 +@@ -421,6 +421,13 @@ wbcErr wbcLookupSids(const struct wbcDomainSid *sids, + for (i=0; i<num_names; i++) { + + names[i].domain_index = strtoul(p, &q, 10); ++ if (names[i].domain_index < 0) { ++ goto wbc_err_invalid; ++ } ++ if (names[i].domain_index >= num_domains) { ++ goto wbc_err_invalid; ++ } ++ + if (*q != ' ') { + goto wbc_err_invalid; + } Index: patches/patch-nsswitch_pam_winbind_c =================================================================== RCS file: patches/patch-nsswitch_pam_winbind_c diff -N patches/patch-nsswitch_pam_winbind_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-nsswitch_pam_winbind_c 28 Jan 2014 07:17:11 -0000 @@ -0,0 +1,16 @@ +$OpenBSD$ +--- nsswitch/pam_winbind.c.orig Wed May 8 04:16:26 2013 ++++ nsswitch/pam_winbind.c Tue Jan 28 02:16:44 2014 +@@ -1184,6 +1184,12 @@ static bool winbind_name_list_to_sid_string_list(struc + _make_remark_format(ctx, PAM_TEXT_INFO, _("Cannot convert group %s " + "to sid, please contact your administrator to see " + "if group %s is valid."), search_location, search_location); ++ ++ /* If no valid groups were converted we should fail outright */ ++ if (name_list != NULL && strlen(sid_list_buffer) == 0) { ++ result = false; ++ goto out; ++ } + /* + * The lookup of the last name failed.. + * It results in require_member_of_sid ends with ',' Index: patches/patch-nsswitch_wbinfo_c =================================================================== RCS file: /home/cvs/ports/net/samba/patches/patch-nsswitch_wbinfo_c,v retrieving revision 1.3 diff -u -p -u -p -r1.3 patch-nsswitch_wbinfo_c --- patches/patch-nsswitch_wbinfo_c 10 Apr 2012 22:01:20 -0000 1.3 +++ patches/patch-nsswitch_wbinfo_c 28 Jan 2014 07:17:11 -0000 @@ -1,13 +1,35 @@ $OpenBSD: patch-nsswitch_wbinfo_c,v 1.3 2012/04/10 22:01:20 sthen Exp $ ---- nsswitch/wbinfo.c.orig Sat Apr 7 14:23:20 2012 -+++ nsswitch/wbinfo.c Tue Apr 10 22:56:36 2012 -@@ -27,9 +27,6 @@ - #include "libwbclient/wbclient.h" - #include "lib/popt/popt.h" - #include "../libcli/auth/libcli_auth.h" --#if (_SAMBA_BUILD_) >= 4 --#include "lib/cmdline/popt_common.h" --#endif +--- nsswitch/wbinfo.c.orig Mon Jan 27 22:29:29 2014 ++++ nsswitch/wbinfo.c Tue Jan 28 02:16:43 2014 +@@ -1377,11 +1377,28 @@ static bool wbinfo_lookup_sids(const char *arg) + } - #ifdef DBGC_CLASS - #undef DBGC_CLASS + for (i=0; i<num_sids; i++) { ++ const char *domain = NULL; ++ + wbcSidToStringBuf(&sids[i], sidstr, sizeof(sidstr)); + +- d_printf("%s -> %s\\%s %d\n", sidstr, +- domains[names[i].domain_index].short_name, +- names[i].name, names[i].type); ++ if (names[i].domain_index >= num_domains) { ++ domain = "<none>"; ++ } else if (names[i].domain_index < 0) { ++ domain = "<none>"; ++ } else { ++ domain = domains[names[i].domain_index].short_name; ++ } ++ ++ if (names[i].type == WBC_SID_NAME_DOMAIN) { ++ d_printf("%s -> %s %d\n", sidstr, ++ domain, ++ names[i].type); ++ } else { ++ d_printf("%s -> %s%c%s %d\n", sidstr, ++ domain, ++ winbind_separator(), ++ names[i].name, names[i].type); ++ } + } + return true; + } Index: patches/patch-nsswitch_wbinfo_c.orig =================================================================== RCS file: patches/patch-nsswitch_wbinfo_c.orig diff -N patches/patch-nsswitch_wbinfo_c.orig --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-nsswitch_wbinfo_c.orig 10 Apr 2012 22:01:20 -0000 @@ -0,0 +1,13 @@ +$OpenBSD: patch-nsswitch_wbinfo_c,v 1.3 2012/04/10 22:01:20 sthen Exp $ +--- nsswitch/wbinfo.c.orig Sat Apr 7 14:23:20 2012 ++++ nsswitch/wbinfo.c Tue Apr 10 22:56:36 2012 +@@ -27,9 +27,6 @@ + #include "libwbclient/wbclient.h" + #include "lib/popt/popt.h" + #include "../libcli/auth/libcli_auth.h" +-#if (_SAMBA_BUILD_) >= 4 +-#include "lib/cmdline/popt_common.h" +-#endif + + #ifdef DBGC_CLASS + #undef DBGC_CLASS Index: patches/patch-source3_lib_netapi_group_c =================================================================== RCS file: patches/patch-source3_lib_netapi_group_c diff -N patches/patch-source3_lib_netapi_group_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source3_lib_netapi_group_c 28 Jan 2014 07:17:13 -0000 @@ -0,0 +1,34 @@ +$OpenBSD$ +--- source3/lib/netapi/group.c.orig Tue Jan 28 02:16:43 2014 ++++ source3/lib/netapi/group.c Tue Jan 28 02:16:43 2014 +@@ -395,7 +395,15 @@ WERROR NetGroupDel_r(struct libnetapi_ctx *ctx, + werr = ntstatus_to_werror(result); + goto done; + } ++ if (names.count != rid_array->count) { ++ werr = WERR_BAD_NET_RESP; ++ goto done; + } ++ if (member_types.count != rid_array->count) { ++ werr = WERR_BAD_NET_RESP; ++ goto done; ++ } ++ } + + for (i=0; i < rid_array->count; i++) { + +@@ -1621,6 +1629,14 @@ WERROR NetGroupGetUsers_r(struct libnetapi_ctx *ctx, + } + if (!NT_STATUS_IS_OK(result)) { + werr = ntstatus_to_werror(result); ++ goto done; ++ } ++ if (names.count != rid_array->count) { ++ werr = WERR_BAD_NET_RESP; ++ goto done; ++ } ++ if (member_types.count != rid_array->count) { ++ werr = WERR_BAD_NET_RESP; + goto done; + } + Index: patches/patch-source3_lib_netapi_localgroup_c =================================================================== RCS file: patches/patch-source3_lib_netapi_localgroup_c diff -N patches/patch-source3_lib_netapi_localgroup_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source3_lib_netapi_localgroup_c 28 Jan 2014 07:17:13 -0000 @@ -0,0 +1,25 @@ +$OpenBSD$ +--- source3/lib/netapi/localgroup.c.orig Wed May 8 04:16:26 2013 ++++ source3/lib/netapi/localgroup.c Tue Jan 28 02:16:43 2014 +@@ -58,6 +58,12 @@ static NTSTATUS libnetapi_samr_lookup_and_open_alias(T + 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 + 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: patches/patch-source3_lib_netapi_user_c =================================================================== RCS file: patches/patch-source3_lib_netapi_user_c diff -N patches/patch-source3_lib_netapi_user_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source3_lib_netapi_user_c 28 Jan 2014 07:17:13 -0000 @@ -0,0 +1,33 @@ +$OpenBSD$ +--- source3/lib/netapi/user.c.orig Tue Jan 28 02:16:43 2014 ++++ source3/lib/netapi/user.c Tue Jan 28 02:16:43 2014 +@@ -3113,6 +3113,14 @@ WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx, + werr = ntstatus_to_werror(result); + goto done; + } ++ if (names.count != rid_array->count) { ++ werr = WERR_BAD_NET_RESP; ++ goto done; ++ } ++ if (types.count != rid_array->count) { ++ werr = WERR_BAD_NET_RESP; ++ goto done; ++ } + + for (i=0; i < names.count; i++) { + status = add_GROUP_USERS_INFO_X_buffer(ctx, +@@ -3714,6 +3722,14 @@ WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *c + } + if (!NT_STATUS_IS_OK(result)) { + werr = ntstatus_to_werror(result); ++ goto done; ++ } ++ if (names.count != num_rids) { ++ werr = WERR_BAD_NET_RESP; ++ goto done; ++ } ++ if (types.count != num_rids) { ++ werr = WERR_BAD_NET_RESP; + goto done; + } + Index: patches/patch-source3_lib_util_tsock_c =================================================================== RCS file: patches/patch-source3_lib_util_tsock_c diff -N patches/patch-source3_lib_util_tsock_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source3_lib_util_tsock_c 28 Jan 2014 07:17:13 -0000 @@ -0,0 +1,15 @@ +$OpenBSD$ +--- source3/lib/util_tsock.c.orig Wed May 8 04:16:26 2013 ++++ source3/lib/util_tsock.c Tue Jan 28 02:16:43 2014 +@@ -110,6 +110,11 @@ static void tstream_read_packet_done(struct tevent_req + return; + } + ++ if (total + more < total) { ++ tevent_req_error(req, EMSGSIZE); ++ return; ++ } ++ + tmp = talloc_realloc(state, state->buf, uint8_t, total+more); + if (tevent_req_nomem(tmp, req)) { + return; Index: patches/patch-source3_libnet_libnet_join_c =================================================================== RCS file: patches/patch-source3_libnet_libnet_join_c diff -N patches/patch-source3_libnet_libnet_join_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source3_libnet_libnet_join_c 28 Jan 2014 07:17:12 -0000 @@ -0,0 +1,33 @@ +$OpenBSD$ +--- source3/libnet/libnet_join.c.orig Wed May 8 04:16:26 2013 ++++ source3/libnet/libnet_join.c Tue Jan 28 02:16:43 2014 +@@ -996,6 +996,14 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_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", +@@ -1365,6 +1373,14 @@ static NTSTATUS libnet_join_unjoindomain_rpc(TALLOC_CT + } + if (!NT_STATUS_IS_OK(result)) { + 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; + } + Index: patches/patch-source3_librpc_rpc_dcerpc_helpers_c =================================================================== RCS file: patches/patch-source3_librpc_rpc_dcerpc_helpers_c diff -N patches/patch-source3_librpc_rpc_dcerpc_helpers_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source3_librpc_rpc_dcerpc_helpers_c 28 Jan 2014 07:17:12 -0000 @@ -0,0 +1,14 @@ +$OpenBSD$ +--- source3/librpc/rpc/dcerpc_helpers.c.orig Wed May 8 04:16:26 2013 ++++ source3/librpc/rpc/dcerpc_helpers.c Tue Jan 28 02:16:43 2014 +@@ -129,6 +129,10 @@ NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx, + NDR_PRINT_DEBUG(ncacn_packet, r); + } + ++ if (r->frag_length != blob->length) { ++ return NT_STATUS_RPC_PROTOCOL_ERROR; ++ } ++ + return NT_STATUS_OK; + } + Index: patches/patch-source3_rpc_client_cli_lsarpc_c =================================================================== RCS file: patches/patch-source3_rpc_client_cli_lsarpc_c diff -N patches/patch-source3_rpc_client_cli_lsarpc_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source3_rpc_client_cli_lsarpc_c 28 Jan 2014 07:17:12 -0000 @@ -0,0 +1,38 @@ +$OpenBSD$ +--- source3/rpc_client/cli_lsarpc.c.orig Tue Jan 28 02:16:43 2014 ++++ source3/rpc_client/cli_lsarpc.c Tue Jan 28 02:16:43 2014 +@@ -662,9 +662,19 @@ NTSTATUS dcerpc_lsa_lookup_names_generic(struct dcerpc + 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; + } +@@ -676,6 +686,14 @@ NTSTATUS dcerpc_lsa_lookup_names_generic(struct dcerpc + ZERO_STRUCTP(sid); + (*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) { Index: patches/patch-source3_rpc_client_cli_pipe_c =================================================================== RCS file: patches/patch-source3_rpc_client_cli_pipe_c diff -N patches/patch-source3_rpc_client_cli_pipe_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source3_rpc_client_cli_pipe_c 28 Jan 2014 07:17:12 -0000 @@ -0,0 +1,142 @@ +$OpenBSD$ +--- source3/rpc_client/cli_pipe.c.orig Tue Jan 28 02:16:43 2014 ++++ source3/rpc_client/cli_pipe.c Tue Jan 28 02:16:43 2014 +@@ -235,6 +235,7 @@ struct get_complete_frag_state { + struct event_context *ev; + struct rpc_pipe_client *cli; + uint16_t frag_len; ++ uint32_t call_id; + DATA_BLOB *pdu; + }; + +@@ -244,6 +245,7 @@ static void get_complete_frag_got_rest(struct tevent_r + static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_pipe_client *cli, ++ uint32_t call_id, + DATA_BLOB *pdu) + { + struct tevent_req *req, *subreq; +@@ -259,6 +261,7 @@ static struct tevent_req *get_complete_frag_send(TALLO + state->ev = ev; + state->cli = cli; + state->frag_len = RPC_HEADER_LEN; ++ state->call_id = call_id; + state->pdu = pdu; + + received = pdu->length; +@@ -286,6 +289,11 @@ static struct tevent_req *get_complete_frag_send(TALLO + return tevent_req_post(req, ev); + } + ++ if (state->call_id != dcerpc_get_call_id(pdu)) { ++ tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); ++ return tevent_req_post(req, ev); ++ } ++ + /* + * Ensure we have frag_len bytes of data. + */ +@@ -338,6 +346,11 @@ static void get_complete_frag_got_header(struct tevent + return; + } + ++ if (state->call_id != dcerpc_get_call_id(state->pdu)) { ++ tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); ++ return; ++ } ++ + if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) { + tevent_req_nterror(req, NT_STATUS_NO_MEMORY); + return; +@@ -698,6 +711,7 @@ struct rpc_api_pipe_state { + struct event_context *ev; + struct rpc_pipe_client *cli; + uint8_t expected_pkt_type; ++ uint32_t call_id; + + DATA_BLOB incoming_frag; + struct ncacn_packet *pkt; +@@ -716,7 +730,8 @@ static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX + struct event_context *ev, + struct rpc_pipe_client *cli, + DATA_BLOB *data, /* Outgoing PDU */ +- uint8_t expected_pkt_type) ++ uint8_t expected_pkt_type, ++ uint32_t call_id) + { + struct tevent_req *req, *subreq; + struct rpc_api_pipe_state *state; +@@ -730,6 +745,7 @@ static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX + state->ev = ev; + state->cli = cli; + state->expected_pkt_type = expected_pkt_type; ++ state->call_id = call_id; + state->incoming_frag = data_blob_null; + state->reply_pdu = data_blob_null; + state->reply_pdu_offset = 0; +@@ -829,6 +845,7 @@ static void rpc_api_pipe_trans_done(struct tevent_req + + /* Ensure we have enough data for a pdu. */ + subreq = get_complete_frag_send(state, state->ev, state->cli, ++ state->call_id, + &state->incoming_frag); + if (tevent_req_nomem(subreq, req)) { + return; +@@ -948,6 +965,7 @@ static void rpc_api_pipe_got_pdu(struct tevent_req *su + } + + subreq = get_complete_frag_send(state, state->ev, state->cli, ++ state->call_id, + &state->incoming_frag); + if (tevent_req_nomem(subreq, req)) { + return; +@@ -1300,7 +1318,8 @@ struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *m + if (is_last_frag) { + subreq = rpc_api_pipe_send(state, ev, state->cli, + &state->rpc_out, +- DCERPC_PKT_RESPONSE); ++ DCERPC_PKT_RESPONSE, ++ state->call_id); + if (subreq == NULL) { + goto fail; + } +@@ -1436,7 +1455,8 @@ static void rpc_api_pipe_req_write_done(struct tevent_ + if (is_last_frag) { + subreq = rpc_api_pipe_send(state, state->ev, state->cli, + &state->rpc_out, +- DCERPC_PKT_RESPONSE); ++ DCERPC_PKT_RESPONSE, ++ state->call_id); + if (tevent_req_nomem(subreq, req)) { + return; + } +@@ -1675,7 +1695,7 @@ struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ + } + + subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out, +- DCERPC_PKT_BIND_ACK); ++ DCERPC_PKT_BIND_ACK, state->rpc_call_id); + if (subreq == NULL) { + goto fail; + } +@@ -1873,7 +1893,8 @@ static NTSTATUS rpc_bind_next_send(struct tevent_req * + } + + subreq = rpc_api_pipe_send(state, state->ev, state->cli, +- &state->rpc_out, DCERPC_PKT_ALTER_RESP); ++ &state->rpc_out, DCERPC_PKT_ALTER_RESP, ++ state->rpc_call_id); + if (subreq == NULL) { + return NT_STATUS_NO_MEMORY; + } +@@ -1905,7 +1926,8 @@ static NTSTATUS rpc_bind_finish_send(struct tevent_req + } + + subreq = rpc_api_pipe_send(state, state->ev, state->cli, +- &state->rpc_out, DCERPC_PKT_AUTH3); ++ &state->rpc_out, DCERPC_PKT_AUTH3, ++ state->rpc_call_id); + if (subreq == NULL) { + return NT_STATUS_NO_MEMORY; + } Index: patches/patch-source3_rpc_server_netlogon_srv_netlog_nt_c =================================================================== RCS file: patches/patch-source3_rpc_server_netlogon_srv_netlog_nt_c diff -N patches/patch-source3_rpc_server_netlogon_srv_netlog_nt_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source3_rpc_server_netlogon_srv_netlog_nt_c 28 Jan 2014 07:17:12 -0000 @@ -0,0 +1,12 @@ +$OpenBSD$ +--- source3/rpc_server/netlogon/srv_netlog_nt.c.orig Wed May 8 04:16:26 2013 ++++ source3/rpc_server/netlogon/srv_netlog_nt.c Tue Jan 28 02:16:43 2014 +@@ -586,7 +586,7 @@ static NTSTATUS samr_find_machine_account(TALLOC_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: patches/patch-source3_rpcclient_cmd_lsarpc_c =================================================================== RCS file: patches/patch-source3_rpcclient_cmd_lsarpc_c diff -N patches/patch-source3_rpcclient_cmd_lsarpc_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source3_rpcclient_cmd_lsarpc_c 28 Jan 2014 07:17:12 -0000 @@ -0,0 +1,23 @@ +$OpenBSD$ +--- source3/rpcclient/cmd_lsarpc.c.orig Tue Jan 28 02:16:43 2014 ++++ source3/rpcclient/cmd_lsarpc.c Tue Jan 28 02:16:43 2014 +@@ -323,7 +323,7 @@ static NTSTATUS cmd_lsa_lookup_names4(struct rpc_pipe_ + + 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; +@@ -359,6 +359,10 @@ static NTSTATUS cmd_lsa_lookup_names4(struct rpc_pipe_ + } + if (!NT_STATUS_IS_OK(result)) { + return result; ++ } ++ ++ if (sids.count != num_names) { ++ return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + for (i = 0; i < sids.count; i++) { Index: patches/patch-source3_rpcclient_cmd_samr_c =================================================================== RCS file: patches/patch-source3_rpcclient_cmd_samr_c diff -N patches/patch-source3_rpcclient_cmd_samr_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source3_rpcclient_cmd_samr_c 28 Jan 2014 07:17:12 -0000 @@ -0,0 +1,18 @@ +$OpenBSD$ +--- source3/rpcclient/cmd_samr.c.orig Tue Jan 28 02:16:43 2014 ++++ source3/rpcclient/cmd_samr.c Tue Jan 28 02:16:43 2014 +@@ -2220,6 +2220,14 @@ static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_c + goto done; + + /* Display results */ ++ if (num_rids != names.count) { ++ status = NT_STATUS_INVALID_NETWORK_RESPONSE; ++ goto done; ++ } ++ if (num_rids != types.count) { ++ status = NT_STATUS_INVALID_NETWORK_RESPONSE; ++ goto done; ++ } + + for (i = 0; i < num_rids; i++) { + printf("rid 0x%x: %s (%d)\n", Index: patches/patch-source3_smbd_lanman_c =================================================================== RCS file: patches/patch-source3_smbd_lanman_c diff -N patches/patch-source3_smbd_lanman_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source3_smbd_lanman_c 28 Jan 2014 07:17:13 -0000 @@ -0,0 +1,18 @@ +$OpenBSD$ +--- source3/smbd/lanman.c.orig Wed May 8 04:16:26 2013 ++++ source3/smbd/lanman.c Tue Jan 28 02:16:43 2014 +@@ -2628,6 +2628,14 @@ static bool api_NetUserGetGroups(struct smbd_server_co + 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: patches/patch-source3_smbd_open_c =================================================================== RCS file: patches/patch-source3_smbd_open_c diff -N patches/patch-source3_smbd_open_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source3_smbd_open_c 28 Jan 2014 07:17:12 -0000 @@ -0,0 +1,78 @@ +$OpenBSD$ +--- source3/smbd/open.c.orig Wed May 8 04:16:26 2013 ++++ source3/smbd/open.c Tue Jan 28 02:16:16 2014 +@@ -152,6 +152,48 @@ NTSTATUS smbd_check_open_rights(struct connection_stru + } + + /**************************************************************************** ++ Ensure when opening a base file for a stream open that we have permissions ++ to do so given the access mask on the base file. ++****************************************************************************/ ++ ++static NTSTATUS check_base_file_access(struct connection_struct *conn, ++ struct smb_filename *smb_fname, ++ uint32_t access_mask) ++{ ++ uint32_t access_granted = 0; ++ NTSTATUS status; ++ ++ status = smbd_calculate_access_mask(conn, smb_fname, ++ false, ++ access_mask, ++ &access_mask); ++ if (!NT_STATUS_IS_OK(status)) { ++ DEBUG(10, ("smbd_calculate_access_mask " ++ "on file %s returned %s\n", ++ smb_fname_str_dbg(smb_fname), ++ nt_errstr(status))); ++ return status; ++ } ++ ++ if (access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) { ++ uint32_t dosattrs; ++ if (!CAN_WRITE(conn)) { ++ return NT_STATUS_ACCESS_DENIED; ++ } ++ dosattrs = dos_mode(conn, smb_fname); ++ if (IS_DOS_READONLY(dosattrs)) { ++ return NT_STATUS_ACCESS_DENIED; ++ } ++ } ++ ++ ++ return smbd_check_open_rights(conn, ++ smb_fname, ++ access_mask, ++ &access_granted); ++} ++ ++/**************************************************************************** + fd support routines - attempt to do a dos_open. + ****************************************************************************/ + +@@ -3226,6 +3268,25 @@ static NTSTATUS create_file_unixpath(connection_struct + if (SMB_VFS_STAT(conn, smb_fname_base) == -1) { + DEBUG(10, ("Unable to stat stream: %s\n", + smb_fname_str_dbg(smb_fname_base))); ++ } else { ++ /* ++ * https://bugzilla.samba.org/show_bug.cgi?id=10229 ++ * We need to check if the requested access mask ++ * could be used to open the underlying file (if ++ * it existed), as we're passing in zero for the ++ * access mask to the base filename. ++ */ ++ status = check_base_file_access(conn, ++ smb_fname_base, ++ access_mask); ++ ++ if (!NT_STATUS_IS_OK(status)) { ++ DEBUG(10, ("Permission check " ++ "for base %s failed: " ++ "%s\n", smb_fname->base_name, ++ nt_errstr(status))); ++ goto fail; ++ } + } + + /* Open the base file. */ Index: patches/patch-source3_utils_net_rpc_c =================================================================== RCS file: patches/patch-source3_utils_net_rpc_c diff -N patches/patch-source3_utils_net_rpc_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source3_utils_net_rpc_c 28 Jan 2014 07:17:12 -0000 @@ -0,0 +1,17 @@ +$OpenBSD$ +--- source3/utils/net_rpc.c.orig Tue Jan 28 02:16:43 2014 ++++ source3/utils/net_rpc.c Tue Jan 28 02:16:43 2014 +@@ -2889,7 +2889,12 @@ static NTSTATUS rpc_list_group_members(struct net_cont + if (!NT_STATUS_IS_OK(result)) { + return result; + } +- ++ if (names.count != this_time) { ++ return NT_STATUS_INVALID_NETWORK_RESPONSE; ++ } ++ if (types.count != this_time) { ++ return NT_STATUS_INVALID_NETWORK_RESPONSE; ++ } + /* We only have users as members, but make the output + the same as the output of alias members */ + Index: patches/patch-source3_utils_net_rpc_join_c =================================================================== RCS file: patches/patch-source3_utils_net_rpc_join_c diff -N patches/patch-source3_utils_net_rpc_join_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source3_utils_net_rpc_join_c 28 Jan 2014 07:17:12 -0000 @@ -0,0 +1,19 @@ +$OpenBSD$ +--- source3/utils/net_rpc_join.c.orig Wed May 8 04:16:26 2013 ++++ source3/utils/net_rpc_join.c Tue Jan 28 02:16:43 2014 +@@ -367,6 +367,15 @@ int net_rpc_join_newstyle(struct net_context *c, int a + ("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: patches/patch-source3_winbindd_wb_lookupsids_c =================================================================== RCS file: patches/patch-source3_winbindd_wb_lookupsids_c diff -N patches/patch-source3_winbindd_wb_lookupsids_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source3_winbindd_wb_lookupsids_c 28 Jan 2014 07:17:13 -0000 @@ -0,0 +1,13 @@ +$OpenBSD$ +--- source3/winbindd/wb_lookupsids.c.orig Wed May 8 04:16:26 2013 ++++ source3/winbindd/wb_lookupsids.c Tue Jan 28 02:16:43 2014 +@@ -402,6 +402,9 @@ static bool wb_lookupsids_move_name(struct lsa_RefDoma + uint32_t src_domain_index, dst_domain_index; + + src_domain_index = src_name->sid_index; ++ if (src_domain_index >= src_domains->count) { ++ return false; ++ } + src_domain = &src_domains->domains[src_domain_index]; + + if (!wb_lookupsids_find_dom_idx( Index: patches/patch-source3_winbindd_winbindd_msrpc_c =================================================================== RCS file: patches/patch-source3_winbindd_winbindd_msrpc_c diff -N patches/patch-source3_winbindd_winbindd_msrpc_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source3_winbindd_winbindd_msrpc_c 28 Jan 2014 07:17:13 -0000 @@ -0,0 +1,25 @@ +$OpenBSD$ +--- source3/winbindd/winbindd_msrpc.c.orig Wed May 8 04:16:26 2013 ++++ source3/winbindd/winbindd_msrpc.c Tue Jan 28 02:16:43 2014 +@@ -744,13 +744,19 @@ static NTSTATUS msrpc_lookup_groupmem(struct winbindd_ + /* Copy result into array. The talloc system will take + care of freeing the temporary arrays later on. */ + +- if (tmp_names.count != tmp_types.count) { +- return NT_STATUS_UNSUCCESSFUL; ++ if (tmp_names.count != num_lookup_rids) { ++ return NT_STATUS_INVALID_NETWORK_RESPONSE; + } ++ if (tmp_types.count != num_lookup_rids) { ++ return NT_STATUS_INVALID_NETWORK_RESPONSE; ++ } + + for (r=0; r<tmp_names.count; r++) { + if (tmp_types.ids[r] == SID_NAME_UNKNOWN) { + continue; ++ } ++ if (total_names >= *num_names) { ++ break; + } + (*names)[total_names] = fill_domain_username_talloc( + mem_ctx, domain->name, Index: patches/patch-source3_winbindd_winbindd_rpc_c =================================================================== RCS file: patches/patch-source3_winbindd_winbindd_rpc_c diff -N patches/patch-source3_winbindd_winbindd_rpc_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source3_winbindd_winbindd_rpc_c 28 Jan 2014 07:17:13 -0000 @@ -0,0 +1,25 @@ +$OpenBSD$ +--- source3/winbindd/winbindd_rpc.c.orig Tue Jan 28 02:16:43 2014 ++++ source3/winbindd/winbindd_rpc.c Tue Jan 28 02:16:43 2014 +@@ -871,13 +871,19 @@ NTSTATUS rpc_lookup_groupmem(TALLOC_CTX *mem_ctx, + + /* Copy result into array. The talloc system will take + care of freeing the temporary arrays later on. */ +- if (tmp_names.count != tmp_types.count) { +- return NT_STATUS_UNSUCCESSFUL; ++ if (tmp_names.count != num_names) { ++ return NT_STATUS_INVALID_NETWORK_RESPONSE; + } ++ if (tmp_types.count != num_names) { ++ return NT_STATUS_INVALID_NETWORK_RESPONSE; ++ } + + for (r = 0; r < tmp_names.count; r++) { + if (tmp_types.ids[r] == SID_NAME_UNKNOWN) { + continue; ++ } ++ if (total_names >= num_names) { ++ break; + } + names[total_names] = fill_domain_username_talloc(names, + domain_name, Index: patches/patch-source4_libcli_util_clilsa_c =================================================================== RCS file: patches/patch-source4_libcli_util_clilsa_c diff -N patches/patch-source4_libcli_util_clilsa_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source4_libcli_util_clilsa_c 28 Jan 2014 07:17:11 -0000 @@ -0,0 +1,16 @@ +$OpenBSD$ +--- source4/libcli/util/clilsa.c.orig Tue Jan 28 02:16:43 2014 ++++ source4/libcli/util/clilsa.c Tue Jan 28 02:16:43 2014 +@@ -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: patches/patch-source4_libnet_groupinfo_c =================================================================== RCS file: patches/patch-source4_libnet_groupinfo_c diff -N patches/patch-source4_libnet_groupinfo_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source4_libnet_groupinfo_c 28 Jan 2014 07:17:11 -0000 @@ -0,0 +1,23 @@ +$OpenBSD$ +--- source4/libnet/groupinfo.c.orig Wed May 8 04:16:26 2013 ++++ source4/libnet/groupinfo.c Tue Jan 28 02:16:43 2014 +@@ -87,12 +87,16 @@ static void continue_groupinfo_lookup(struct tevent_re + + 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: patches/patch-source4_libnet_groupman_c =================================================================== RCS file: patches/patch-source4_libnet_groupman_c diff -N patches/patch-source4_libnet_groupman_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source4_libnet_groupman_c 28 Jan 2014 07:17:11 -0000 @@ -0,0 +1,22 @@ +$OpenBSD$ +--- source4/libnet/groupman.c.orig Wed May 8 04:16:26 2013 ++++ source4/libnet/groupman.c Tue Jan 28 02:16:43 2014 +@@ -212,13 +212,13 @@ static void continue_groupdel_name_found(struct tevent + + /* 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: patches/patch-source4_libnet_libnet_join_c =================================================================== RCS file: patches/patch-source4_libnet_libnet_join_c diff -N patches/patch-source4_libnet_libnet_join_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source4_libnet_libnet_join_c 28 Jan 2014 07:17:11 -0000 @@ -0,0 +1,23 @@ +$OpenBSD$ +--- source4/libnet/libnet_join.c.orig Wed May 8 04:16:26 2013 ++++ source4/libnet/libnet_join.c Tue Jan 28 02:16:43 2014 +@@ -656,9 +656,17 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, + "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: patches/patch-source4_libnet_libnet_lookup_c =================================================================== RCS file: patches/patch-source4_libnet_libnet_lookup_c diff -N patches/patch-source4_libnet_libnet_lookup_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source4_libnet_libnet_lookup_c 28 Jan 2014 07:17:11 -0000 @@ -0,0 +1,15 @@ +$OpenBSD$ +--- source4/libnet/libnet_lookup.c.orig Wed May 8 04:16:26 2013 ++++ source4/libnet/libnet_lookup.c Tue Jan 28 02:16:43 2014 +@@ -363,6 +363,11 @@ static void continue_name_found(struct tevent_req *sub + 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: patches/patch-source4_libnet_libnet_passwd_c =================================================================== RCS file: patches/patch-source4_libnet_libnet_passwd_c diff -N patches/patch-source4_libnet_libnet_passwd_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source4_libnet_libnet_passwd_c 28 Jan 2014 07:17:11 -0000 @@ -0,0 +1,21 @@ +$OpenBSD$ +--- source4/libnet/libnet_passwd.c.orig Wed May 8 04:16:26 2013 ++++ source4/libnet/libnet_passwd.c Tue Jan 28 02:16:43 2014 +@@ -627,8 +627,16 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_ + 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 */ Index: patches/patch-source4_libnet_userinfo_c =================================================================== RCS file: patches/patch-source4_libnet_userinfo_c diff -N patches/patch-source4_libnet_userinfo_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source4_libnet_userinfo_c 28 Jan 2014 07:17:11 -0000 @@ -0,0 +1,19 @@ +$OpenBSD$ +--- source4/libnet/userinfo.c.orig Wed May 8 04:16:26 2013 ++++ source4/libnet/userinfo.c Tue Jan 28 02:16:43 2014 +@@ -90,8 +90,13 @@ static void continue_userinfo_lookup(struct tevent_req + + /* 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: patches/patch-source4_libnet_userman_c =================================================================== RCS file: patches/patch-source4_libnet_userman_c diff -N patches/patch-source4_libnet_userman_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source4_libnet_userman_c 28 Jan 2014 07:17:11 -0000 @@ -0,0 +1,43 @@ +$OpenBSD$ +--- source4/libnet/userman.c.orig Wed May 8 04:16:26 2013 ++++ source4/libnet/userman.c Tue Jan 28 02:16:43 2014 +@@ -236,14 +236,12 @@ static void continue_userdel_name_found(struct tevent_ + + /* 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_ + + /* 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: patches/patch-source4_librpc_rpc_dcerpc_c =================================================================== RCS file: patches/patch-source4_librpc_rpc_dcerpc_c diff -N patches/patch-source4_librpc_rpc_dcerpc_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source4_librpc_rpc_dcerpc_c 28 Jan 2014 07:17:11 -0000 @@ -0,0 +1,14 @@ +$OpenBSD$ +--- source4/librpc/rpc/dcerpc.c.orig Wed May 8 04:16:26 2013 ++++ source4/librpc/rpc/dcerpc.c Tue Jan 28 02:16:43 2014 +@@ -658,6 +658,10 @@ static NTSTATUS ncacn_pull(struct dcecli_connection *c + return ndr_map_error2ntstatus(ndr_err); + } + ++ if (pkt->frag_length != blob->length) { ++ return NT_STATUS_RPC_PROTOCOL_ERROR; ++ } ++ + return NT_STATUS_OK; + } + Index: patches/patch-source4_librpc_rpc_dcerpc_smb2_c =================================================================== RCS file: patches/patch-source4_librpc_rpc_dcerpc_smb2_c diff -N patches/patch-source4_librpc_rpc_dcerpc_smb2_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source4_librpc_rpc_dcerpc_smb2_c 28 Jan 2014 07:17:11 -0000 @@ -0,0 +1,16 @@ +$OpenBSD$ +--- source4/librpc/rpc/dcerpc_smb2.c.orig Wed May 8 04:16:26 2013 ++++ source4/librpc/rpc/dcerpc_smb2.c Tue Jan 28 02:16:43 2014 +@@ -170,6 +170,12 @@ static NTSTATUS send_read_request_continue(struct dcec + + if (state->data.length >= 16) { + uint16_t frag_length = dcerpc_get_frag_length(&state->data); ++ ++ if (frag_length < state->data.length) { ++ talloc_free(state); ++ return NT_STATUS_RPC_PROTOCOL_ERROR; ++ } ++ + io.in.length = frag_length - state->data.length; + } else { + io.in.length = 0x2000; Index: patches/patch-source4_librpc_rpc_dcerpc_smb_c =================================================================== RCS file: patches/patch-source4_librpc_rpc_dcerpc_smb_c diff -N patches/patch-source4_librpc_rpc_dcerpc_smb_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source4_librpc_rpc_dcerpc_smb_c 28 Jan 2014 07:17:11 -0000 @@ -0,0 +1,16 @@ +$OpenBSD$ +--- source4/librpc/rpc/dcerpc_smb.c.orig Wed May 8 04:16:26 2013 ++++ source4/librpc/rpc/dcerpc_smb.c Tue Jan 28 02:16:43 2014 +@@ -160,6 +160,12 @@ static NTSTATUS send_read_request_continue(struct dcec + } else { + uint32_t frag_length = blob->length>=16? + dcerpc_get_frag_length(blob):0x2000; ++ ++ if (frag_length < state->data.length) { ++ talloc_free(state); ++ return NT_STATUS_RPC_PROTOCOL_ERROR; ++ } ++ + state->received = blob->length; + state->data = data_blob_talloc(state, NULL, frag_length); + if (!state->data.data) { Index: patches/patch-source4_librpc_rpc_dcerpc_sock_c =================================================================== RCS file: patches/patch-source4_librpc_rpc_dcerpc_sock_c diff -N patches/patch-source4_librpc_rpc_dcerpc_sock_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source4_librpc_rpc_dcerpc_sock_c 28 Jan 2014 07:17:11 -0000 @@ -0,0 +1,16 @@ +$OpenBSD$ +--- source4/librpc/rpc/dcerpc_sock.c.orig Wed May 8 04:16:26 2013 ++++ source4/librpc/rpc/dcerpc_sock.c Tue Jan 28 02:16:43 2014 +@@ -102,6 +102,12 @@ static NTSTATUS sock_complete_packet(void *private_dat + return STATUS_MORE_ENTRIES; + } + *size = dcerpc_get_frag_length(&blob); ++ if (*size < blob.length) { ++ /* ++ * something is wrong, let the caller deal with it ++ */ ++ *size = blob.length; ++ } + if (*size > blob.length) { + return STATUS_MORE_ENTRIES; + } Index: patches/patch-source4_winbind_wb_async_helpers_c =================================================================== RCS file: patches/patch-source4_winbind_wb_async_helpers_c diff -N patches/patch-source4_winbind_wb_async_helpers_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-source4_winbind_wb_async_helpers_c 28 Jan 2014 07:17:11 -0000 @@ -0,0 +1,32 @@ +$OpenBSD$ +--- source4/winbind/wb_async_helpers.c.orig Tue Jan 28 02:16:43 2014 ++++ source4/winbind/wb_async_helpers.c Tue Jan 28 02:16:43 2014 +@@ -283,6 +283,12 @@ static void lsa_lookupnames_recv_sids(struct tevent_re + 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_re + 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; + } + -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.