The branch, v4-0-test has been updated via db8b33d VERSION: Bump version up to 4.0.14 via d580670 Merge tag 'samba-4.0.13' into v4-0-test via b0574ae VERSION: Disable git snapshots for the 4.0.13 release. via 73546c1 WHATSNEW: Add release notes for Samba 4.0.13. via c114323 CVE-2012-6150: fail authentication for single group name which cannot be converted to sid via 09060b5 CVE-2013-4408:s3:Ensure LookupRids() replies arrays are range checked. via d6a4813 CVE-2013-4408:s3:Ensure LookupNames replies arrays are range checked. via acab72e CVE-2013-4408:s3:Ensure LookupSids replies arrays are range checked. via dd126bf CVE-2013-4408:s3:Ensure we always check call_id when validating an RPC reply. via f1e2d2d CVE-2013-4408:s3:ctdb_conn: add some length verification to ctdb_packet_more() via b705738 CVE-2013-4408:libcli/util: add some size verification to tstream_read_pdu_blob_done() via 29bd4d1 CVE-2013-4408:s3:util_tsock: add some overflow detection to tstream_read_packet_done() via 06b043c CVE-2013-4408:async_sock: add some overflow detection to read_packet_handler() via 05cd093 CVE-2013-4408:s4:dcerpc_sock: check for invalid frag_len within sock_complete_packet() via 53afd58 CVE-2013-4408:s4:dcerpc_smb2: check for invalid frag_len in send_read_request_continue() via 0703abf CVE-2013-4408:s4:dcerpc_smb: check for invalid frag_len in send_read_request_continue() via 654b02e CVE-2013-4408:s4:dcerpc: check for invalid frag_len in ncacn_pull() via 2da4314 CVE-2013-4408:s3:rpc_client: verify frag_len at least contains the header size via 7eb27f2 CVE-2013-4408:s3:rpc_client: check for invalid frag_len in dcerpc_pull_ncacn_packet() via 9d994c2 CVE-2013-4408:librpc: check for invalid frag_len within dcerpc_read_ncacn_packet_next_vector() via e209606 CVE-2013-4408:librpc: check for invalid frag_len within dcerpc_read_ncacn_packet_done() via 0ba9d8f VERSION: Bump version number up to 4.0.13... from c880a38 smbd: Fix bug 10284
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v4-0-test - Log ----------------------------------------------------------------- commit db8b33d99eeb2c75724f58e7e87c3f36d9405012 Author: Karolin Seeger <ksee...@samba.org> Date: Mon Dec 9 07:09:02 2013 +0100 VERSION: Bump version up to 4.0.14 Signed-off-by: Karolin Seeger <ksee...@samba.org> commit d580670ebacacac8fbcaf1f0dce93b56868643af Merge: c880a384a9063cb970483185dc114792a75eaeae b0574ae788d3379915996fb5bd0db2721f0634cd Author: Karolin Seeger <ksee...@samba.org> Date: Mon Dec 9 07:08:22 2013 +0100 Merge tag 'samba-4.0.13' into v4-0-test samba: tag release samba-4.0.13 ----------------------------------------------------------------------- Summary of changes: VERSION | 2 +- WHATSNEW.txt | 97 ++++++++++++++++++++++++++- lib/async_req/async_sock.c | 5 ++ libcli/util/tstream.c | 5 ++ librpc/rpc/dcerpc_util.c | 14 ++++ nsswitch/libwbclient/wbc_sid.c | 7 ++ nsswitch/pam_winbind.c | 6 ++ nsswitch/wbinfo.c | 23 ++++++- source3/lib/ctdb_conn.c | 5 ++ source3/lib/netapi/group.c | 98 +++++++++++++++++++++++++++ source3/lib/netapi/localgroup.c | 8 ++- source3/lib/netapi/user.c | 72 ++++++++++++++++++++ source3/lib/util_tsock.c | 5 ++ source3/libnet/libnet_join.c | 16 +++++ source3/librpc/rpc/dcerpc_helpers.c | 4 + source3/rpc_client/cli_lsarpc.c | 35 +++++++++- source3/rpc_client/cli_pipe.c | 41 +++++++++-- source3/rpc_server/netlogon/srv_netlog_nt.c | 2 +- source3/rpcclient/cmd_lsarpc.c | 13 +++- source3/rpcclient/cmd_samr.c | 66 ++++++++++++++++++- source3/smbd/lanman.c | 8 ++ source3/utils/net_rpc.c | 47 ++++++++++++- source3/utils/net_rpc_join.c | 9 +++ source3/winbindd/wb_lookupsids.c | 3 + source3/winbindd/winbindd_msrpc.c | 10 ++- source3/winbindd/winbindd_rpc.c | 54 +++++++++++---- source4/libcli/util/clilsa.c | 22 ++++++- source4/libnet/groupinfo.c | 9 ++- source4/libnet/groupman.c | 10 ++-- source4/libnet/libnet_join.c | 12 +++- source4/libnet/libnet_lookup.c | 5 ++ source4/libnet/libnet_passwd.c | 10 +++- source4/libnet/userinfo.c | 8 ++- source4/libnet/userman.c | 24 +++---- source4/librpc/rpc/dcerpc.c | 4 + source4/librpc/rpc/dcerpc_smb.c | 6 ++ source4/librpc/rpc/dcerpc_smb2.c | 6 ++ source4/librpc/rpc/dcerpc_sock.c | 6 ++ source4/winbind/wb_async_helpers.c | 26 +++++++- 39 files changed, 734 insertions(+), 69 deletions(-) Changeset truncated at 500 lines: diff --git a/VERSION b/VERSION index 0639a26..3b27e8c 100644 --- a/VERSION +++ b/VERSION @@ -25,7 +25,7 @@ ######################################################## SAMBA_VERSION_MAJOR=4 SAMBA_VERSION_MINOR=0 -SAMBA_VERSION_RELEASE=13 +SAMBA_VERSION_RELEASE=14 ######################################################## # If a official release has a serious bug # diff --git a/WHATSNEW.txt b/WHATSNEW.txt index 3ae3b2f..50ba8aa 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -1,4 +1,97 @@ ============================== + Release Notes for Samba 4.0.13 + December 9, 2013 + ============================== + + +This is a security release in order to address +CVE-2013-4408 (DCE-RPC fragment length field is incorrectly checked) and +CVE-2012-6150 (pam_winbind login without require_membership_of restrictions). + +o CVE-2013-4408: + Samba versions 3.4.0 and above (versions 3.4.0 - 3.4.17, 3.5.0 - + 3.5.22, 3.6.0 - 3.6.21, 4.0.0 - 4.0.12 and including 4.1.2) are + vulnerable to buffer overrun exploits in the client processing of + DCE-RPC packets. This is due to incorrect checking of the DCE-RPC + fragment length in the client code. + + This is a critical vulnerability as the DCE-RPC client code is part of + the winbindd authentication and identity mapping daemon, which is + commonly configured as part of many server installations (when joined + to an Active Directory Domain). A malicious Active Directory Domain + Controller or man-in-the-middle attacker impersonating an Active + Directory Domain Controller could achieve root-level access by + compromising the winbindd process. + + Samba server versions 3.4.0 - 3.4.17 and versions 3.5.0 - 3.5.22 are + also vulnerable to a denial of service attack (server crash) due to a + similar error in the server code of those versions. + + Samba server versions 3.6.0 and above (including all 3.6.x versions, + all 4.0.x versions and 4.1.x) are not vulnerable to this problem. + + In addition range checks were missing on arguments returned from calls + to the DCE-RPC functions LookupSids (lsa and samr), LookupNames (lsa and samr) + and LookupRids (samr) which could also cause similar problems. + + As this was found during an internal audit of the Samba code there are + no currently known exploits for this problem (as of December 9th 2013). + +o CVE-2012-6150: + Winbind allows for the further restriction of authenticated PAM logins using + the require_membership_of parameter. System administrators may specify a list + of SIDs or groups for which an authenticated user must be a member of. If an + authenticated user does not belong to any of the entries, then login should + fail. Invalid group name entries are ignored. + + Samba versions 3.3.10, 3.4.3, 3.5.0 and later incorrectly allow login from + authenticated users if the require_membership_of parameter specifies only + invalid group names. + + This is a vulnerability with low impact. All require_membership_of group + names must be invalid for this bug to be encountered. + + +Changes since 4.0.12: +--------------------- + +o Jeremy Allison <j...@samba.org> + * BUG 10185: CVE-2013-4408: Correctly check DCE-RPC fragment length field. + + +o Stefan Metzmacher <me...@samba.org> + * BUG 10185: CVE-2013-4408: Correctly check DCE-RPC fragment length field. + + +o Noel Power <noel.po...@suse.com> + * BUGs 10300, 10306: CVE-2012-6150: Fail authentication if user isn't + member of *any* require_membership_of specified groups. + + +###################################################################### +Reporting bugs & Development Discussion +####################################### + +Please discuss this release on the samba-technical mailing list or by +joining the #samba-technical IRC channel on irc.freenode.net. + +If you do report problems then please try to send high quality +feedback. If you don't provide vital information to help us track down +the problem then you will probably be ignored. All bug reports should +be filed under the Samba 4.0 product in the project's Bugzilla +database (https://bugzilla.samba.org/). + + +====================================================================== +== Our Code, Our Bugs, Our Responsibility. +== The Samba Team +====================================================================== + + +Release notes for older releases follow: +---------------------------------------- + + ============================== Release Notes for Samba 4.0.12 November 19, 2013 ============================== @@ -76,8 +169,8 @@ database (https://bugzilla.samba.org/). ====================================================================== -Release notes for older releases follow: ----------------------------------------- +---------------------------------------------------------------------- + ============================== Release Notes for Samba 4.0.11 diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 9909bc6..e4fa4f6 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -640,6 +640,11 @@ static void read_packet_handler(struct tevent_context *ev, 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; diff --git a/libcli/util/tstream.c b/libcli/util/tstream.c index 12cef9b..dd830e2 100644 --- a/libcli/util/tstream.c +++ b/libcli/util/tstream.c @@ -129,6 +129,11 @@ static void tstream_read_pdu_blob_done(struct tevent_req *subreq) 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; diff --git a/librpc/rpc/dcerpc_util.c b/librpc/rpc/dcerpc_util.c index de292c8..0b9cca3 100644 --- a/librpc/rpc/dcerpc_util.c +++ b/librpc/rpc/dcerpc_util.c @@ -223,6 +223,15 @@ static int dcerpc_read_ncacn_packet_next_vector(struct tstream_context *stream, ofs = state->buffer.length; + if (frag_len < ofs) { + /* + * something is wrong, let the caller deal with it + */ + *_vector = NULL; + *_count = 0; + return 0; + } + state->buffer.data = talloc_realloc(state, state->buffer.data, uint8_t, frag_len); @@ -292,6 +301,11 @@ static void dcerpc_read_ncacn_packet_done(struct tevent_req *subreq) return; } + if (state->pkt->frag_length != state->buffer.length) { + tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR); + return; + } + tevent_req_done(req); } diff --git a/nsswitch/libwbclient/wbc_sid.c b/nsswitch/libwbclient/wbc_sid.c index bab6933..82ac339 100644 --- a/nsswitch/libwbclient/wbc_sid.c +++ b/nsswitch/libwbclient/wbc_sid.c @@ -421,6 +421,13 @@ wbcErr wbcLookupSids(const struct wbcDomainSid *sids, int num_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; } diff --git a/nsswitch/pam_winbind.c b/nsswitch/pam_winbind.c index 1cc6b83..e33a055 100644 --- a/nsswitch/pam_winbind.c +++ b/nsswitch/pam_winbind.c @@ -1184,6 +1184,12 @@ static bool winbind_name_list_to_sid_string_list(struct pwb_context *ctx, _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 ',' diff --git a/nsswitch/wbinfo.c b/nsswitch/wbinfo.c index abe4844..e3eabca 100644 --- a/nsswitch/wbinfo.c +++ b/nsswitch/wbinfo.c @@ -1386,11 +1386,28 @@ static bool wbinfo_lookup_sids(const char *arg) } 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); + } } wbcFreeMemory(names); wbcFreeMemory(domains); diff --git a/source3/lib/ctdb_conn.c b/source3/lib/ctdb_conn.c index a96615f..313bd79 100644 --- a/source3/lib/ctdb_conn.c +++ b/source3/lib/ctdb_conn.c @@ -220,6 +220,11 @@ static ssize_t ctdb_packet_more(uint8_t *buf, size_t buflen, void *p) return 0; } memcpy(&len, buf, sizeof(len)); + + if (len < sizeof(uint32_t)) { + return -1; + } + return (len - sizeof(uint32_t)); } diff --git a/source3/lib/netapi/group.c b/source3/lib/netapi/group.c index 710ec37..b743440 100644 --- a/source3/lib/netapi/group.c +++ b/source3/lib/netapi/group.c @@ -309,6 +309,15 @@ WERROR NetGroupDel_r(struct libnetapi_ctx *ctx, goto done; } + if (rids.count != 1) { + werr = WERR_BAD_NET_RESP; + goto done; + } + if (types.count != 1) { + werr = WERR_BAD_NET_RESP; + goto done; + } + if (types.ids[0] != SID_NAME_DOM_GRP) { werr = WERR_INVALID_DATATYPE; goto done; @@ -386,6 +395,14 @@ 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++) { @@ -511,6 +528,14 @@ WERROR NetGroupSetInfo_r(struct libnetapi_ctx *ctx, werr = ntstatus_to_werror(result); goto done; } + if (rids.count != 1) { + werr = WERR_BAD_NET_RESP; + goto done; + } + if (types.count != 1) { + werr = WERR_BAD_NET_RESP; + goto done; + } if (types.ids[0] != SID_NAME_DOM_GRP) { werr = WERR_INVALID_DATATYPE; @@ -781,6 +806,14 @@ WERROR NetGroupGetInfo_r(struct libnetapi_ctx *ctx, werr = ntstatus_to_werror(result); goto done; } + if (rids.count != 1) { + werr = WERR_BAD_NET_RESP; + goto done; + } + if (types.count != 1) { + werr = WERR_BAD_NET_RESP; + goto done; + } if (types.ids[0] != SID_NAME_DOM_GRP) { werr = WERR_INVALID_DATATYPE; @@ -921,6 +954,14 @@ WERROR NetGroupAddUser_r(struct libnetapi_ctx *ctx, werr = WERR_GROUPNOTFOUND; goto done; } + if (rids.count != 1) { + werr = WERR_BAD_NET_RESP; + goto done; + } + if (types.count != 1) { + werr = WERR_BAD_NET_RESP; + goto done; + } if (types.ids[0] != SID_NAME_DOM_GRP) { werr = WERR_GROUPNOTFOUND; @@ -959,6 +1000,14 @@ WERROR NetGroupAddUser_r(struct libnetapi_ctx *ctx, werr = WERR_USER_NOT_FOUND; goto done; } + if (rids.count != 1) { + werr = WERR_BAD_NET_RESP; + goto done; + } + if (types.count != 1) { + werr = WERR_BAD_NET_RESP; + goto done; + } if (types.ids[0] != SID_NAME_USER) { werr = WERR_USER_NOT_FOUND; @@ -1065,6 +1114,14 @@ WERROR NetGroupDelUser_r(struct libnetapi_ctx *ctx, werr = WERR_GROUPNOTFOUND; goto done; } + if (rids.count != 1) { + werr = WERR_BAD_NET_RESP; + goto done; + } + if (types.count != 1) { + werr = WERR_BAD_NET_RESP; + goto done; + } if (types.ids[0] != SID_NAME_DOM_GRP) { werr = WERR_GROUPNOTFOUND; @@ -1104,6 +1161,14 @@ WERROR NetGroupDelUser_r(struct libnetapi_ctx *ctx, werr = WERR_USER_NOT_FOUND; goto done; } + if (rids.count != 1) { + werr = WERR_BAD_NET_RESP; + goto done; + } + if (types.count != 1) { + werr = WERR_BAD_NET_RESP; + goto done; + } if (types.ids[0] != SID_NAME_USER) { werr = WERR_USER_NOT_FOUND; @@ -1514,6 +1579,14 @@ WERROR NetGroupGetUsers_r(struct libnetapi_ctx *ctx, werr = ntstatus_to_werror(result); goto done; } + if (group_rids.count != 1) { + werr = WERR_BAD_NET_RESP; + goto done; + } + if (name_types.count != 1) { + werr = WERR_BAD_NET_RESP; + goto done; + } status = dcerpc_samr_OpenGroup(b, talloc_tos(), &domain_handle, @@ -1558,6 +1631,14 @@ WERROR NetGroupGetUsers_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 < names.count; i++) { @@ -1689,6 +1770,14 @@ WERROR NetGroupSetUsers_r(struct libnetapi_ctx *ctx, werr = ntstatus_to_werror(result); goto done; } + if (group_rids.count != 1) { + werr = WERR_BAD_NET_RESP; + goto done; + } + if (group_types.count != 1) { + werr = WERR_BAD_NET_RESP; + goto done; + } status = dcerpc_samr_OpenGroup(b, talloc_tos(), &domain_handle, @@ -1767,6 +1856,15 @@ WERROR NetGroupSetUsers_r(struct libnetapi_ctx *ctx, goto done; } + if (r->in.num_entries != user_rids.count) { + werr = WERR_BAD_NET_RESP; + goto done; + } + if (r->in.num_entries != name_types.count) { + werr = WERR_BAD_NET_RESP; + goto done; + } + member_rids = user_rids.ids; status = dcerpc_samr_QueryGroupMember(b, talloc_tos(), diff --git a/source3/lib/netapi/localgroup.c b/source3/lib/netapi/localgroup.c index 816afc2..88d2baf 100644 --- a/source3/lib/netapi/localgroup.c +++ b/source3/lib/netapi/localgroup.c @@ -58,6 +58,12 @@ static NTSTATUS libnetapi_samr_lookup_and_open_alias(TALLOC_CTX *mem_ctx, if (!NT_STATUS_IS_OK(result)) { return result; } + if (user_rids.count != 1) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + if (name_types.count != 1) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } switch (name_types.ids[0]) { case SID_NAME_ALIAS: @@ -1041,7 +1047,7 @@ static NTSTATUS libnetapi_lsa_lookup_names3(TALLOC_CTX *mem_ctx, NT_STATUS_NOT_OK_RETURN(result); if (count != 1 || sids.count != 1) { - return NT_STATUS_NONE_MAPPED; + return NT_STATUS_INVALID_NETWORK_RESPONSE; } sid_copy(sid, sids.sids[0].sid); diff --git a/source3/lib/netapi/user.c b/source3/lib/netapi/user.c index 3003a39..1908c86 100644 --- a/source3/lib/netapi/user.c +++ b/source3/lib/netapi/user.c @@ -604,6 +604,14 @@ WERROR NetUserDel_r(struct libnetapi_ctx *ctx, werr = ntstatus_to_werror(result); goto done; } + if (user_rids.count != 1) { + werr = WERR_BAD_NET_RESP; + goto done; -- Samba Shared Repository