The branch, v4-1-test has been updated via 180bca8 VERSION: Bump version up to 4.1.4. via ff99526 Merge tag 'samba-4.1.3' into v4-1-test via 6898c4d VERSION: Disable git snapshots for the 4.1.3 release. via 98833dc WHATSNEW: Add release notes for Samba 4.1.3. via b89e14d CVE-2012-6150: Fail authentication for single group name which cannot be converted to sid via d96f88c CVE-2013-4408:s3:Ensure LookupRids() replies arrays are range checked. via c406802 CVE-2013-4408:s3:Ensure LookupNames replies arrays are range checked. via ca5d6f5 CVE-2013-4408:s3:Ensure LookupSids replies arrays are range checked. via 066c6e3 CVE-2013-4408:s3:Ensure we always check call_id when validating an RPC reply. via da5dfc7 CVE-2013-4408:s3:ctdb_conn: add some length verification to ctdb_packet_more() via bdb643e CVE-2013-4408:libcli/util: add some size verification to tstream_read_pdu_blob_done() via c4e31ea CVE-2013-4408:s3:util_tsock: add some overflow detection to tstream_read_packet_done() via 0ba0b27 CVE-2013-4408:async_sock: add some overflow detection to read_packet_handler() via f71b390 CVE-2013-4408:s4:dcerpc_sock: check for invalid frag_len within sock_complete_packet() via db102cd CVE-2013-4408:s4:dcerpc_smb2: check for invalid frag_len in send_read_request_continue() via e5954aa CVE-2013-4408:s4:dcerpc_smb: check for invalid frag_len in send_read_request_continue() via 730027c CVE-2013-4408:s4:dcerpc: check for invalid frag_len in ncacn_pull() via f557bfe CVE-2013-4408:s3:rpc_client: verify frag_len at least contains the header size via 895ce91 CVE-2013-4408:s3:rpc_client: check for invalid frag_len in dcerpc_pull_ncacn_packet() via c4a1b2e CVE-2013-4408:librpc: check for invalid frag_len within dcerpc_read_ncacn_packet_next_vector() via 78b4989 CVE-2013-4408:librpc: check for invalid frag_len within dcerpc_read_ncacn_packet_done() via dbe7531 VERSION: Bump version number up to 4.1.3... from bfdf098 smbd: Fix bug 10284
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v4-1-test - Log ----------------------------------------------------------------- commit 180bca8cd5612f2db1d4d01446af8b7d66c68e27 Author: Karolin Seeger <ksee...@samba.org> Date: Mon Dec 9 07:10:31 2013 +0100 VERSION: Bump version up to 4.1.4. Signed-off-by: Karolin Seeger <ksee...@samba.org> commit ff99526b5cd8b85de7d8e20fbe35c17935e2b0e7 Merge: bfdf0984af539d40bcbfec75b1ee65a2808857a4 6898c4dbf993889a804e77dd6cb32e0be50f653f Author: Karolin Seeger <ksee...@samba.org> Date: Mon Dec 9 07:10:12 2013 +0100 Merge tag 'samba-4.1.3' into v4-1-test samba: tag release samba-4.1.3 ----------------------------------------------------------------------- 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 eb748e8..bb7cd3e 100644 --- a/VERSION +++ b/VERSION @@ -25,7 +25,7 @@ ######################################################## SAMBA_VERSION_MAJOR=4 SAMBA_VERSION_MINOR=1 -SAMBA_VERSION_RELEASE=3 +SAMBA_VERSION_RELEASE=4 ######################################################## # If a official release has a serious bug # diff --git a/WHATSNEW.txt b/WHATSNEW.txt index 5e5cfab..75db247 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -1,4 +1,97 @@ ============================= + Release Notes for Samba 4.1.3 + 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.1.2: +-------------------- + +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.1 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.1.2 November 22, 2013 ============================= @@ -87,8 +180,8 @@ database (https://bugzilla.samba.org/). ====================================================================== -Release notes for older releases follow: ----------------------------------------- +---------------------------------------------------------------------- + ============================= Release Notes for Samba 4.1.1 diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 59dde88..74b2cb7 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -667,6 +667,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 9f85556..98cf97e 100644 --- a/nsswitch/pam_winbind.c +++ b/nsswitch/pam_winbind.c @@ -1163,6 +1163,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 17977ed..3f0310a 100644 --- a/nsswitch/wbinfo.c +++ b/nsswitch/wbinfo.c @@ -1391,11 +1391,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 90930eb..40071d4 100644 --- a/source3/lib/ctdb_conn.c +++ b/source3/lib/ctdb_conn.c @@ -233,6 +233,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 9813f7e..b806fc4 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; @@ -1515,6 +1580,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, @@ -1559,6 +1632,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++) { @@ -1691,6 +1772,14 @@ WERROR NetGroupSetUsers_r(struct libnetapi_ctx *ctx, werr = ntstatus_to_werror(result); goto done; } + if (group_rids.count != 1) { + werr = WERR_BAD_NET_RESP; + goto done; + } + if (group_types.count != 1) { + werr = WERR_BAD_NET_RESP; + goto done; + } status = dcerpc_samr_OpenGroup(b, talloc_tos(), &domain_handle, @@ -1769,6 +1858,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 1a544ad..17cab68 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 df3914c..a971e2d 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