diff -Nru samba-4.1.11+dfsg/debian/changelog samba-4.1.11+dfsg/debian/changelog --- samba-4.1.11+dfsg/debian/changelog 2014-12-04 06:51:50.000000000 +0000 +++ samba-4.1.11+dfsg/debian/changelog 2015-01-21 14:22:01.000000000 +0000 @@ -1,3 +1,17 @@ +samba (2:4.1.11+dfsg-1ubuntu4) vivid; urgency=medium + + * SECURITY UPDATE: elevation of privilege to AD Domain Controller + - debian/patches/CVE-2014-8143.patch: check for extended access rights + before allowing changes to userAccountControl in + librpc/idl/security.idl, source4/auth/session.c, + source4/dsdb/common/util.c, source4/dsdb/pydsdb.c, + source4/dsdb/samdb/ldb_modules/samldb.c, source4/dsdb/samdb/samdb.h, + source4/rpc_server/lsa/dcesrv_lsa.c, + source4/setup/schema_samba4.ldif. + - CVE-2014-8143 + + -- Marc Deslauriers Wed, 21 Jan 2015 09:19:12 -0500 + samba (2:4.1.11+dfsg-1ubuntu3) vivid; urgency=medium * No-change rebuild against current ldb. Note that I'm not claiming the diff -Nru samba-4.1.11+dfsg/debian/patches/CVE-2014-8143.patch samba-4.1.11+dfsg/debian/patches/CVE-2014-8143.patch --- samba-4.1.11+dfsg/debian/patches/CVE-2014-8143.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.1.11+dfsg/debian/patches/CVE-2014-8143.patch 2015-01-21 14:22:50.000000000 +0000 @@ -0,0 +1,389 @@ +Description: fix elevation of privilege to AD Domain Controller +Bug: https://bugzilla.samba.org/show_bug.cgi?id=10993 (private) +Origin: upstream, https://git.samba.org/?p=samba.git;a=commit;h=9e15786d093ac984262394510333cb3c3d512e1a +Origin: upstream, https://git.samba.org/?p=samba.git;a=commit;h=f2cb9b99235ebfdd0d53c3ebdaaac44f8b958311 +Origin: upstream, https://git.samba.org/?p=samba.git;a=commit;h=3c93b5772ef002569810b01c39faac8b34168f05 +Origin: upstream, https://git.samba.org/?p=samba.git;a=commit;h=5cc1c0ec403358d08e208a38feae11631510ab72 + +Index: samba-4.1.11+dfsg/librpc/idl/security.idl +=================================================================== +--- samba-4.1.11+dfsg.orig/librpc/idl/security.idl 2013-12-05 04:16:48.000000000 -0500 ++++ samba-4.1.11+dfsg/librpc/idl/security.idl 2015-01-21 09:18:26.769803680 -0500 +@@ -656,14 +656,21 @@ + const string GUID_DRS_CHANGE_RID_MASTER = "d58d5f36-0a98-11d1-adbb-00c04fd8d5cd"; + const string GUID_DRS_CHANGE_SCHEMA_MASTER = "e12b56b6-0a95-11d1-adbb-00c04fd8d5cd"; + const string GUID_DRS_GET_CHANGES = "1131f6aa-9c07-11d1-f79f-00c04fc2dcd2"; ++ const string GUID_DRS_REPL_SYNCRONIZE = "1131f6ab-9c07-11d1-f79f-00c04fc2dcd2"; ++ const string GUID_DRS_MANAGE_TOPOLOGY = "1131f6ac-9c07-11d1-f79f-00c04fc2dcd2"; + const string GUID_DRS_GET_ALL_CHANGES = "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2"; ++ const string GUID_DRS_RO_REPL_SECRET_SYNC = "1131f6ae-9c07-11d1-f79f-00c04fc2dcd2"; + const string GUID_DRS_GET_FILTERED_ATTRIBUTES = "89e95b76-444d-4c62-991a-0facbeda640c"; +- const string GUID_DRS_MANAGE_TOPOLOGY = "1131f6ac-9c07-11d1-f79f-00c04fc2dcd2"; + const string GUID_DRS_MONITOR_TOPOLOGY = "f98340fb-7c5b-4cdb-a00b-2ebdfa115a96"; +- const string GUID_DRS_REPL_SYNCRONIZE = "1131f6ab-9c07-11d1-f79f-00c04fc2dcd2"; +- const string GUID_DRS_RO_REPL_SECRET_SYNC = "1131f6ae-9c07-11d1-f79f-00c04fc2dcd2"; + const string GUID_DRS_USER_CHANGE_PASSWORD = "ab721a53-1e2f-11d0-9819-00aa0040529b"; + const string GUID_DRS_FORCE_CHANGE_PASSWORD = "00299570-246d-11d0-a768-00aa006e0529"; ++ const string GUID_DRS_UPDATE_PASSWORD_NOT_REQUIRED_BIT ++ = "280f369c-67c7-438e-ae98-1d46f3c6f541"; ++ const string GUID_DRS_UNEXPIRE_PASSWORD = "ccc2dc7d-a6ad-4a7a-8846-c04e3cc53501"; ++ const string GUID_DRS_ENABLE_PER_USER_REVERSIBLY_ENCRYPTED_PASSWORD ++ = "05c74c5e-4deb-43b4-bd9f-86664c2a7fd5"; ++ const string GUID_DRS_DS_INSTALL_REPLICA = "9923a32a-3607-11d2-b9be-0000f87a36b2"; ++ + + /***************************************************************/ + /* validated writes guids */ +Index: samba-4.1.11+dfsg/source4/auth/session.c +=================================================================== +--- samba-4.1.11+dfsg.orig/source4/auth/session.c 2013-06-13 05:21:02.000000000 -0400 ++++ samba-4.1.11+dfsg/source4/auth/session.c 2015-01-21 09:18:18.957731760 -0500 +@@ -204,6 +204,11 @@ + { + struct auth_session_info *session_info; + session_info = talloc_steal(mem_ctx, session_info_transport->session_info); ++ /* ++ * This is to allow us to check the type of this pointer using ++ * talloc_get_type() ++ */ ++ talloc_set_name(session_info, "struct auth_session_info"); + #ifdef HAVE_GSS_IMPORT_CRED + if (session_info_transport->exported_gssapi_credentials.length) { + struct cli_credentials *creds; +Index: samba-4.1.11+dfsg/source4/dsdb/common/util.c +=================================================================== +--- samba-4.1.11+dfsg.orig/source4/dsdb/common/util.c 2014-07-28 03:13:45.000000000 -0400 ++++ samba-4.1.11+dfsg/source4/dsdb/common/util.c 2015-01-21 09:18:23.425772895 -0500 +@@ -1043,8 +1043,8 @@ + /* + * Handle ldb_request in transaction + */ +-static int dsdb_autotransaction_request(struct ldb_context *sam_ldb, +- struct ldb_request *req) ++int dsdb_autotransaction_request(struct ldb_context *sam_ldb, ++ struct ldb_request *req) + { + int ret; + +Index: samba-4.1.11+dfsg/source4/dsdb/pydsdb.c +=================================================================== +--- samba-4.1.11+dfsg.orig/source4/dsdb/pydsdb.c 2013-12-05 04:16:48.000000000 -0500 ++++ samba-4.1.11+dfsg/source4/dsdb/pydsdb.c 2015-01-21 09:18:21.373754002 -0500 +@@ -1152,6 +1152,7 @@ + ADD_DSDB_FLAG(UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION); + ADD_DSDB_FLAG(UF_NO_AUTH_DATA_REQUIRED); + ADD_DSDB_FLAG(UF_PARTIAL_SECRETS_ACCOUNT); ++ ADD_DSDB_FLAG(UF_USE_AES_KEYS); + + /* groupType flags */ + ADD_DSDB_FLAG(GTYPE_SECURITY_BUILTIN_LOCAL_GROUP); +Index: samba-4.1.11+dfsg/source4/dsdb/samdb/ldb_modules/samldb.c +=================================================================== +--- samba-4.1.11+dfsg.orig/source4/dsdb/samdb/ldb_modules/samldb.c 2014-07-28 03:13:45.000000000 -0400 ++++ samba-4.1.11+dfsg/source4/dsdb/samdb/ldb_modules/samldb.c 2015-01-21 09:18:26.769803680 -0500 +@@ -33,6 +33,7 @@ + #include "includes.h" + #include "libcli/ldap/ldap_ndr.h" + #include "ldb_module.h" ++#include "auth/auth.h" + #include "dsdb/samdb/samdb.h" + #include "dsdb/samdb/ldb_modules/util.h" + #include "dsdb/samdb/ldb_modules/ridalloc.h" +@@ -944,6 +945,10 @@ + } + + static int samldb_prim_group_tester(struct samldb_ctx *ac, uint32_t rid); ++static int samldb_check_user_account_control_acl(struct samldb_ctx *ac, ++ struct dom_sid *sid, ++ uint32_t user_account_control, ++ uint32_t user_account_control_old); + + /* + * "Objectclass" trigger (MS-SAMR 3.1.1.8.1) +@@ -1039,7 +1044,6 @@ + el = ldb_msg_find_element(ac->msg, "userAccountControl"); + if (el != NULL) { + uint32_t user_account_control, account_type; +- + /* Step 1.3: "userAccountControl" -> "sAMAccountType" mapping */ + user_account_control = ldb_msg_find_attr_as_uint(ac->msg, + "userAccountControl", +@@ -1155,6 +1159,12 @@ + return ret; + } + } ++ ++ ret = samldb_check_user_account_control_acl(ac, NULL, ++ user_account_control, 0); ++ if (ret != LDB_SUCCESS) { ++ return ret; ++ } + } + break; + } +@@ -1442,6 +1452,172 @@ + return ret; + } + ++/** ++ * Validate that the restriction in point 5 of MS-SAMR 3.1.1.8.10 userAccountControl is honoured ++ * ++ */ ++static int samldb_check_user_account_control_acl(struct samldb_ctx *ac, ++ struct dom_sid *sid, ++ uint32_t user_account_control, ++ uint32_t user_account_control_old) ++{ ++ int i, ret = 0; ++ bool need_acl_check = false; ++ struct ldb_result *res; ++ const char * const sd_attrs[] = {"ntSecurityDescriptor", NULL}; ++ struct security_token *user_token; ++ struct security_descriptor *domain_sd; ++ struct ldb_dn *domain_dn = ldb_get_default_basedn(ldb_module_get_ctx(ac->module)); ++ const struct uac_to_guid { ++ uint32_t uac; ++ const char *oid; ++ const char *guid; ++ enum sec_privilege privilege; ++ bool delete_is_privileged; ++ const char *error_string; ++ } map[] = { ++ { ++ .uac = UF_PASSWD_NOTREQD, ++ .guid = GUID_DRS_UPDATE_PASSWORD_NOT_REQUIRED_BIT, ++ .error_string = "Adding the UF_PASSWD_NOTREQD bit in userAccountControl requires the Update-Password-Not-Required-Bit right that was not given on the Domain object" ++ }, ++ { ++ .uac = UF_DONT_EXPIRE_PASSWD, ++ .guid = GUID_DRS_UNEXPIRE_PASSWORD, ++ .error_string = "Adding the UF_DONT_EXPIRE_PASSWD bit in userAccountControl requires the Unexpire-Password right that was not given on the Domain object" ++ }, ++ { ++ .uac = UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED, ++ .guid = GUID_DRS_ENABLE_PER_USER_REVERSIBLY_ENCRYPTED_PASSWORD, ++ .error_string = "Adding the UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED bit in userAccountControl requires the Enable-Per-User-Reversibly-Encrypted-Password right that was not given on the Domain object" ++ }, ++ { ++ .uac = UF_SERVER_TRUST_ACCOUNT, ++ .guid = GUID_DRS_DS_INSTALL_REPLICA, ++ .error_string = "Adding the UF_SERVER_TRUST_ACCOUNT bit in userAccountControl requires the DS-Install-Replica right that was not given on the Domain object" ++ }, ++ { ++ .uac = UF_PARTIAL_SECRETS_ACCOUNT, ++ .guid = GUID_DRS_DS_INSTALL_REPLICA, ++ .error_string = "Adding the UF_PARTIAL_SECRETS_ACCOUNT bit in userAccountControl requires the DS-Install-Replica right that was not given on the Domain object" ++ }, ++ { ++ .uac = UF_INTERDOMAIN_TRUST_ACCOUNT, ++ .oid = DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID, ++ .error_string = "Updating the UF_INTERDOMAIN_TRUST_ACCOUNT bit in userAccountControl is not permitted over LDAP. This bit is restricted to the LSA CreateTrustedDomain interface", ++ .delete_is_privileged = true ++ }, ++ { ++ .uac = UF_TRUSTED_FOR_DELEGATION, ++ .privilege = SEC_PRIV_ENABLE_DELEGATION, ++ .delete_is_privileged = true, ++ .error_string = "Updating the UF_TRUSTED_FOR_DELEGATION bit in userAccountControl is not permitted without the SeEnableDelegationPrivilege" ++ }, ++ { ++ .uac = UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION, ++ .privilege = SEC_PRIV_ENABLE_DELEGATION, ++ .delete_is_privileged = true, ++ .error_string = "Updating the UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION bit in userAccountControl is not permitted without the SeEnableDelegationPrivilege" ++ } ++ ++ }; ++ ++ if (dsdb_module_am_system(ac->module)) { ++ return LDB_SUCCESS; ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(map); i++) { ++ if (user_account_control & map[i].uac) { ++ need_acl_check = true; ++ break; ++ } ++ } ++ if (need_acl_check == false) { ++ return LDB_SUCCESS; ++ } ++ ++ user_token = acl_user_token(ac->module); ++ if (user_token == NULL) { ++ return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; ++ } ++ ++ ret = dsdb_module_search_dn(ac->module, ac, &res, ++ domain_dn, ++ sd_attrs, ++ DSDB_FLAG_NEXT_MODULE | DSDB_SEARCH_SHOW_DELETED, ++ ac->req); ++ if (ret != LDB_SUCCESS) { ++ return ret; ++ } ++ if (res->count != 1) { ++ return ldb_module_operr(ac->module); ++ } ++ ++ ret = dsdb_get_sd_from_ldb_message(ldb_module_get_ctx(ac->module), ++ ac, res->msgs[0], &domain_sd); ++ ++ if (ret != LDB_SUCCESS) { ++ return ret; ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(map); i++) { ++ uint32_t this_uac_new = user_account_control & map[i].uac; ++ uint32_t this_uac_old = user_account_control_old & map[i].uac; ++ if (this_uac_new != this_uac_old) { ++ if (this_uac_old != 0) { ++ if (map[i].delete_is_privileged == false) { ++ continue; ++ } ++ } ++ if (map[i].oid) { ++ struct ldb_control *control = ldb_request_get_control(ac->req, map[i].oid); ++ if (control == NULL) { ++ ret = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; ++ } ++ } else if (map[i].privilege != SEC_PRIV_INVALID) { ++ bool have_priv = security_token_has_privilege(user_token, ++ map[i].privilege); ++ if (have_priv == false) { ++ ret = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; ++ } ++ } else { ++ ret = acl_check_extended_right(ac, domain_sd, ++ user_token, ++ map[i].guid, ++ SEC_ADS_CONTROL_ACCESS, ++ sid); ++ } ++ if (ret != LDB_SUCCESS) { ++ break; ++ } ++ } ++ } ++ if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { ++ switch (ac->req->operation) { ++ case LDB_ADD: ++ ldb_asprintf_errstring(ldb_module_get_ctx(ac->module), ++ "Failed to add %s: %s", ++ ldb_dn_get_linearized(ac->msg->dn), ++ map[i].error_string); ++ break; ++ case LDB_MODIFY: ++ ldb_asprintf_errstring(ldb_module_get_ctx(ac->module), ++ "Failed to modify %s: %s", ++ ldb_dn_get_linearized(ac->msg->dn), ++ map[i].error_string); ++ break; ++ default: ++ return ldb_module_operr(ac->module); ++ } ++ if (map[i].guid) { ++ dsdb_acl_debug(domain_sd, acl_user_token(ac->module), ++ domain_dn, ++ true, ++ 10); ++ } ++ } ++ return ret; ++} + + /** + * This function is called on LDB modify operations. It performs some additions/ +@@ -1453,10 +1629,11 @@ + uint32_t user_account_control, old_user_account_control, account_type; + struct ldb_message_element *el; + struct ldb_message *tmp_msg; ++ struct dom_sid *sid; + int ret; + struct ldb_result *res; + const char * const attrs[] = { "userAccountControl", "objectClass", +- "lockoutTime", NULL }; ++ "lockoutTime", "objectSid", NULL }; + unsigned int i; + bool is_computer = false, uac_generated = false; + +@@ -1646,6 +1823,17 @@ + el->values[0].length = strlen(tempstr); + } + ++ sid = samdb_result_dom_sid(res, res->msgs[0], "objectSid"); ++ if (sid == NULL) { ++ return ldb_module_operr(ac->module); ++ } ++ ++ ret = samldb_check_user_account_control_acl(ac, sid, user_account_control, ++ old_user_account_control); ++ if (ret != LDB_SUCCESS) { ++ return ret; ++ } ++ + return LDB_SUCCESS; + } + +Index: samba-4.1.11+dfsg/source4/dsdb/samdb/samdb.h +=================================================================== +--- samba-4.1.11+dfsg.orig/source4/dsdb/samdb/samdb.h 2014-07-28 03:13:45.000000000 -0400 ++++ samba-4.1.11+dfsg/source4/dsdb/samdb/samdb.h 2015-01-21 09:18:26.769803680 -0500 +@@ -135,6 +135,12 @@ + */ + #define DSDB_CONTROL_SEC_DESC_PROPAGATION_OID "1.3.6.1.4.1.7165.4.3.21" + ++/* ++ * passed when creating a interdomain trust account through LSA ++ * to relax constraints in the samldb ldb module. ++ */ ++#define DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID "1.3.6.1.4.1.7165.4.3.23" ++ + #define DSDB_EXTENDED_REPLICATED_OBJECTS_OID "1.3.6.1.4.1.7165.4.4.1" + struct dsdb_extended_replicated_object { + struct ldb_message *msg; +Index: samba-4.1.11+dfsg/source4/rpc_server/lsa/dcesrv_lsa.c +=================================================================== +--- samba-4.1.11+dfsg.orig/source4/rpc_server/lsa/dcesrv_lsa.c 2014-07-28 03:13:45.000000000 -0400 ++++ samba-4.1.11+dfsg/source4/rpc_server/lsa/dcesrv_lsa.c 2015-01-21 09:18:26.773803716 -0500 +@@ -790,6 +790,7 @@ + struct trustAuthInOutBlob *in, + struct ldb_dn **user_dn) + { ++ struct ldb_request *req; + struct ldb_message *msg; + struct ldb_dn *dn; + uint32_t i; +@@ -850,7 +851,19 @@ + } + + /* create the trusted_domain user account */ +- ret = ldb_add(sam_ldb, msg); ++ ret = ldb_build_add_req(&req, sam_ldb, mem_ctx, msg, NULL, NULL, ++ ldb_op_default_callback, NULL); ++ if (ret != LDB_SUCCESS) { ++ return NT_STATUS_NO_MEMORY; ++ } ++ ++ ret = ldb_request_add_control(req, DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID, ++ false, NULL); ++ if (ret != LDB_SUCCESS) { ++ return NT_STATUS_NO_MEMORY; ++ } ++ ++ ret = dsdb_autotransaction_request(sam_ldb, req); + if (ret != LDB_SUCCESS) { + DEBUG(0,("Failed to create user record %s: %s\n", + ldb_dn_get_linearized(msg->dn), +Index: samba-4.1.11+dfsg/source4/setup/schema_samba4.ldif +=================================================================== +--- samba-4.1.11+dfsg.orig/source4/setup/schema_samba4.ldif 2013-06-13 05:21:03.000000000 -0400 ++++ samba-4.1.11+dfsg/source4/setup/schema_samba4.ldif 2015-01-21 09:18:26.773803716 -0500 +@@ -197,6 +197,7 @@ + #Allocated: DSDB_CONTROL_DBCHECK_MODIFY_RO_REPLICA 1.3.6.1.4.1.7165.4.3.19.1 + #Allocated: DSDB_CONTROL_PASSWORD_BYPASS_LAST_SET_OID 1.3.6.1.4.1.7165.4.3.20 + #Allocated: DSDB_CONTROL_SEC_DESC_PROPAGATION_OID 1.3.6.1.4.1.7165.4.3.21 ++#Allocated: DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID 1.3.6.1.4.1.7165.4.3.23 + + # Extended 1.3.6.1.4.1.7165.4.4.x + #Allocated: DSDB_EXTENDED_REPLICATED_OBJECTS_OID 1.3.6.1.4.1.7165.4.4.1 diff -Nru samba-4.1.11+dfsg/debian/patches/series samba-4.1.11+dfsg/debian/patches/series --- samba-4.1.11+dfsg/debian/patches/series 2014-09-11 16:53:32.000000000 +0000 +++ samba-4.1.11+dfsg/debian/patches/series 2015-01-21 14:18:08.000000000 +0000 @@ -15,3 +15,4 @@ do-not-install-smbclient4-and-nmbclient4 xsltproc_dont_build_smb.conf.5.patch krb_zero_cursor.patch +CVE-2014-8143.patch