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.

Reply via email to