From 40a97f0f8886685682f41215b9204f25769e873f Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Fri, 8 May 2015 14:13:58 +0200 Subject: [PATCH] Backport patches from upstream 1.12.5 prerelease - contains many fixes --- 0001-PAM-do-not-reject-abruptly.patch | 222 ++ ...w-option-pam_account_expired_message.patch | 157 + ...ll-services-about-account-expiration.patch | 62 + ...ck-return-value-of-confdb_get_string.patch | 33 + ...ame-default-timeout-for-SRV-queries-.patch | 57 + 0006-FO-Use-SRV-TTL-in-fail-over-code.patch | 1020 ++++++ 0007-SDAP-refactor-pwexpire-policy.patch | 204 ++ ...ange-phase-of-pw-expire-policy-check.patch | 258 ++ ...name_file_dummy-if-there-is-an-error.patch | 53 + ...xisting-user-mapping-on-empty-defaul.patch | 6 +- ..._child-initialized-ccname_file_dummy.patch | 33 + ...convert-GeneralizedTime-to-unix-time.patch | 244 ++ ...h-keys-when-account-naturally-expire.patch | 725 +++++ ...x-minor-neglect-in-is_account_locked.patch | 32 + ...fresh-refresh-all-domains-in-backend.patch | 224 ++ ...p_handle_acct_req_send-remove-be_req.patch | 185 ++ ...e_refresh-refactor-netgroups-refresh.patch | 224 ++ 0018-be_refresh-add-sdap_refresh_init.patch | 143 + 0019-be_refresh-support-users.patch | 159 + 0020-be_refresh-support-groups.patch | 160 + ...-debug-message-why-ldb_modify-failed.patch | 257 ++ 0022-ldap_child-fix-coverity-warning.patch | 58 + ...-ENOENT-when-doing-initgroups-by-UPN.patch | 79 + ...b5-and-SSSD-use-different-expansions.patch | 40 + ...d-missing-strings-for-error-messages.patch | 51 + 0026-test-Check-ERR_LAST.patch | 78 + ...n_name-as-the-key-for-the-PAM-initgr.patch | 73 + ...nitgr_check_timeout-add-debug-output.patch | 37 + ...at-missing-sub-domain-users-as-error.patch | 37 + ...e-sure-extdom-expo-data-is-available.patch | 30 + ...ix-warning-may-be-used-uninitialized.patch | 35 + ...esolve-group-members-during-tokenGro.patch | 297 ++ ...PA-idviews-check-if-view-name-is-set.patch | 50 + ...etup-with-empty-default-and-no-confi.patch | 8 +- ...IPA-make-sure-output-variable-is-set.patch | 29 + ...set-EINVAL-if-dn-can-t-be-linearized.patch | 26 + ...stead-of-leaving-array-element-unini.patch | 38 + 0038-LDAP-remove-unused-code.patch | 39 + ...create-request-with-0-attribute-valu.patch | 42 + ...ll-unit-tests-to-cmocka-1.0-or-later.patch | 2795 +++++++++++++++++ 0041-RPM-BuildRequire-libcmocka-1.0.patch | 30 + ...mocka-tests-if-cmocka-1.0-or-newer-i.patch | 40 + ...y-handle-binary-objectGuid-attribute.patch | 549 ++++ ...SRV-query-every-time-if-its-TTL-is-0.patch | 118 + ...rror-codes-when-validating-HBAC-rule.patch | 315 ++ 0046-IPA-Drop-useless-sysdb-parameter.patch | 154 + ...alformed-HBAC-rules-as-fatal-if-deny.patch | 183 ++ ...te-the-ipa_hbac_treat_deny_as-option.patch | 37 + 0049-LDAP-fix-a-typo-in-debug-message.patch | 30 + 0050-MAN-Update-ppolicy-description.patch | 40 + ...no-with-enabled-sss-default-nss-plug.patch | 76 + ...-value-of-ad_gpo_store_policy_settin.patch | 30 + 0053-enumeration-fix-talloc-context.patch | 51 + 0054-sudo-sanitize-filter-values.patch | 61 + 0055-SDAP-Do-not-set-gid-0-twice.patch | 49 + ...tract-filtering-AD-group-to-function.patch | 239 ++ ...-SDAP-Filter-ad-groups-in-initgroups.patch | 50 + ...Disconnect-before-closing-the-handle.patch | 7 +- ...d-end-the-transaction-on-the-same-ne.patch | 7 +- ...l-semanage-if-the-context-actually-c.patch | 18 +- ...ers-had-no-effect-for-retrieving-sud.patch | 121 + 0062-AD-Clean-up-ad_access_gpo.patch | 59 + ...ys-get-domain-specific-ID-connection.patch | 69 + ...ays-look-up-GPOs-from-machine-domain.patch | 217 ++ ...e-cmocka-1.0-API-in-test_sysdb_utils.patch | 38 + ...expire-to-the-default-sysdb_search_o.patch | 32 + ...o-save-override-data-for-the-default.patch | 47 + ...trs_add_string_safe-to-add-group-mem.patch | 37 + ...osts-in-groups-found-by-uuid-as-well.patch | 64 + ...ovider-make-user-grp-res-more-robust.patch | 117 + ...allow-initgroups-by-SID-for-AD-users.patch | 205 ++ 0072-IPA-fix-segfault-in-ipa_s2n_exop.patch | 31 + ...ix-Cannot-allocate-memory-with-FQDNs.patch | 36 + ...Do-not-ignore-missing-attrs-for-GPOs.patch | 57 + ...sts-Use-different-prepared-buffers-f.patch | 65 + ...-id-mapping-with-disabled-subdomains.patch | 65 + ...nitgroups-if-extdom-exop-supports-it.patch | 99 + ...nitgr-expire-timestamp-conditionally.patch | 104 + ...nhance-ipa_initgr_get_overrides_send.patch | 198 ++ ...verrides-during-initgroups-in-sever-.patch | 115 + ...-not-add-domain-name-unconditionally.patch | 61 + ...for-overrides-before-calling-backend.patch | 101 + ...initgroups-by-UUID-for-FreeIPA-users.patch | 266 ++ ...dependencies-between-sssd-krb5-commo.patch | 61 + ...Remove-unused-libraries-for-pysss.so.patch | 10 +- ...> 0086-BUILD-Remove-unused-variables.patch | 6 +- ...-Remove-detection-of-type-Py_ssize_t.patch | 6 +- ...ve-python-wrapper-sss_python_set_new.patch | 6 +- ...ve-python-wrapper-sss_python_set_add.patch | 6 +- ...-python-wrapper-sss_python_set_check.patch | 6 +- ...atibility-macro-PyModule_AddIntMacro.patch | 6 +- ...on-wrapper-sss_python_unicode_from_s.patch | 6 +- ...se-python-config-for-detection-FLAGS.patch | 6 +- ...e-new-convention-for-python-packages.patch | 8 +- ...python-bindings-to-separate-packages.patch | 10 +- ...ibility-to-build-python-2-3-bindings.patch | 20 +- ...-tests-with-all-supported-python-ver.patch | 14 +- ...Replace-python_-macros-with-python2_.patch | 8 +- ...hon3-bindings-on-available-platforms.patch | 8 +- sssd.spec | 124 +- 100 files changed, 12794 insertions(+), 105 deletions(-) create mode 100644 0001-PAM-do-not-reject-abruptly.patch create mode 100644 0002-PAM-new-option-pam_account_expired_message.patch create mode 100644 0003-PAM-warn-all-services-about-account-expiration.patch create mode 100644 0004-PAM-check-return-value-of-confdb_get_string.patch create mode 100644 0005-resolv-Use-the-same-default-timeout-for-SRV-queries-.patch create mode 100644 0006-FO-Use-SRV-TTL-in-fail-over-code.patch create mode 100644 0007-SDAP-refactor-pwexpire-policy.patch create mode 100644 0008-SDAP-enable-change-phase-of-pw-expire-policy-check.patch create mode 100644 0009-LDAP-unlink-ccname_file_dummy-if-there-is-an-error.patch rename 0016-selinux-Delete-existing-user-mapping-on-empty-defaul.patch => 0010-selinux-Delete-existing-user-mapping-on-empty-defaul.patch (95%) create mode 100644 0011-ldap_child-initialized-ccname_file_dummy.patch create mode 100644 0012-UTIL-convert-GeneralizedTime-to-unix-time.patch create mode 100644 0013-SDAP-Lock-out-ssh-keys-when-account-naturally-expire.patch create mode 100644 0014-SDAP-fix-minor-neglect-in-is_account_locked.patch create mode 100644 0015-be_refresh-refresh-all-domains-in-backend.patch create mode 100644 0016-sdap_handle_acct_req_send-remove-be_req.patch create mode 100644 0017-be_refresh-refactor-netgroups-refresh.patch create mode 100644 0018-be_refresh-add-sdap_refresh_init.patch create mode 100644 0019-be_refresh-support-users.patch create mode 100644 0020-be_refresh-support-groups.patch create mode 100644 0021-Log-reason-in-debug-message-why-ldb_modify-failed.patch create mode 100644 0022-ldap_child-fix-coverity-warning.patch create mode 100644 0023-NSS-Handle-ENOENT-when-doing-initgroups-by-UPN.patch create mode 100644 0024-MAN-libkrb5-and-SSSD-use-different-expansions.patch create mode 100644 0025-DEBUG-Add-missing-strings-for-error-messages.patch create mode 100644 0026-test-Check-ERR_LAST.patch create mode 100644 0027-PAM-use-the-logon_name-as-the-key-for-the-PAM-initgr.patch create mode 100644 0028-pam_initgr_check_timeout-add-debug-output.patch create mode 100644 0029-ipa-do-not-treat-missing-sub-domain-users-as-error.patch create mode 100644 0030-ipa-make-sure-extdom-expo-data-is-available.patch create mode 100644 0031-ipa_selinux-Fix-warning-may-be-used-uninitialized.patch create mode 100644 0032-LDAP-AD-do-not-resolve-group-members-during-tokenGro.patch create mode 100644 0033-IPA-idviews-check-if-view-name-is-set.patch rename 0017-selinux-Handle-setup-with-empty-default-and-no-confi.patch => 0034-selinux-Handle-setup-with-empty-default-and-no-confi.patch (92%) create mode 100644 0035-IPA-make-sure-output-variable-is-set.patch create mode 100644 0036-IPA-set-EINVAL-if-dn-can-t-be-linearized.patch create mode 100644 0037-GPO-error-out-instead-of-leaving-array-element-unini.patch create mode 100644 0038-LDAP-remove-unused-code.patch create mode 100644 0039-memberof-Do-not-create-request-with-0-attribute-valu.patch create mode 100644 0040-tests-convert-all-unit-tests-to-cmocka-1.0-or-later.patch create mode 100644 0041-RPM-BuildRequire-libcmocka-1.0.patch create mode 100644 0042-build-Only-run-cmocka-tests-if-cmocka-1.0-or-newer-i.patch create mode 100644 0043-sdap-properly-handle-binary-objectGuid-attribute.patch create mode 100644 0044-Resolv-re-read-SRV-query-every-time-if-its-TTL-is-0.patch create mode 100644 0045-IPA-Use-custom-error-codes-when-validating-HBAC-rule.patch create mode 100644 0046-IPA-Drop-useless-sysdb-parameter.patch create mode 100644 0047-IPA-Only-treat-malformed-HBAC-rules-as-fatal-if-deny.patch create mode 100644 0048-IPA-Deprecate-the-ipa_hbac_treat_deny_as-option.patch create mode 100644 0049-LDAP-fix-a-typo-in-debug-message.patch create mode 100644 0050-MAN-Update-ppolicy-description.patch create mode 100644 0051-CLIENT-Clear-errno-with-enabled-sss-default-nss-plug.patch create mode 100644 0052-GPO-Check-return-value-of-ad_gpo_store_policy_settin.patch create mode 100644 0053-enumeration-fix-talloc-context.patch create mode 100644 0054-sudo-sanitize-filter-values.patch create mode 100644 0055-SDAP-Do-not-set-gid-0-twice.patch create mode 100644 0056-SDAP-Extract-filtering-AD-group-to-function.patch create mode 100644 0057-SDAP-Filter-ad-groups-in-initgroups.patch rename 0018-selinux-Disconnect-before-closing-the-handle.patch => 0058-selinux-Disconnect-before-closing-the-handle.patch (89%) rename 0019-selinux-Begin-and-end-the-transaction-on-the-same-ne.patch => 0059-selinux-Begin-and-end-the-transaction-on-the-same-ne.patch (91%) rename 0020-selinux-Only-call-semanage-if-the-context-actually-c.patch => 0060-selinux-Only-call-semanage-if-the-context-actually-c.patch (90%) create mode 100644 0061-Option-filter_users-had-no-effect-for-retrieving-sud.patch create mode 100644 0062-AD-Clean-up-ad_access_gpo.patch create mode 100644 0063-AD-Always-get-domain-specific-ID-connection.patch create mode 100644 0064-AD-GPO-Always-look-up-GPOs-from-machine-domain.patch create mode 100644 0065-tests-Use-cmocka-1.0-API-in-test_sysdb_utils.patch create mode 100644 0066-sysdb-Add-cache_expire-to-the-default-sysdb_search_o.patch create mode 100644 0067-IPA-do-not-try-to-save-override-data-for-the-default.patch create mode 100644 0068-IPA-use-sysdb_attrs_add_string_safe-to-add-group-mem.patch create mode 100644 0069-IPA-check-ghosts-in-groups-found-by-uuid-as-well.patch create mode 100644 0070-simple-access-provider-make-user-grp-res-more-robust.patch create mode 100644 0071-IPA-allow-initgroups-by-SID-for-AD-users.patch create mode 100644 0072-IPA-fix-segfault-in-ipa_s2n_exop.patch create mode 100644 0073-autofs-fix-Cannot-allocate-memory-with-FQDNs.patch create mode 100644 0074-GPO-Do-not-ignore-missing-attrs-for-GPOs.patch create mode 100644 0075-sss_nss_idmap-tests-Use-different-prepared-buffers-f.patch create mode 100644 0076-SDAP-Fix-id-mapping-with-disabled-subdomains.patch create mode 100644 0077-IPA-do-initgroups-if-extdom-exop-supports-it.patch create mode 100644 0078-IPA-update-initgr-expire-timestamp-conditionally.patch create mode 100644 0079-IPA-enhance-ipa_initgr_get_overrides_send.patch create mode 100644 0080-IPA-search-for-overrides-during-initgroups-in-sever-.patch create mode 100644 0081-IPA-do-not-add-domain-name-unconditionally.patch create mode 100644 0082-NSS-check-for-overrides-before-calling-backend.patch create mode 100644 0083-IPA-allow-initgroups-by-UUID-for-FreeIPA-users.patch create mode 100644 0084-SPEC-Fix-cyclic-dependencies-between-sssd-krb5-commo.patch rename 0001-BUILD-Remove-unused-libraries-for-pysss.so.patch => 0085-BUILD-Remove-unused-libraries-for-pysss.so.patch (69%) rename 0002-BUILD-Remove-unused-variables.patch => 0086-BUILD-Remove-unused-variables.patch (87%) rename 0003-BUILD-Remove-detection-of-type-Py_ssize_t.patch => 0087-BUILD-Remove-detection-of-type-Py_ssize_t.patch (93%) rename 0004-UTIL-Remove-python-wrapper-sss_python_set_new.patch => 0088-UTIL-Remove-python-wrapper-sss_python_set_new.patch (95%) rename 0005-UTIL-Remove-python-wrapper-sss_python_set_add.patch => 0089-UTIL-Remove-python-wrapper-sss_python_set_add.patch (95%) rename 0006-UTIL-Remove-python-wrapper-sss_python_set_check.patch => 0090-UTIL-Remove-python-wrapper-sss_python_set_check.patch (95%) rename 0007-UTIL-Remove-compatibility-macro-PyModule_AddIntMacro.patch => 0091-UTIL-Remove-compatibility-macro-PyModule_AddIntMacro.patch (92%) rename 0008-UTIL-Remove-python-wrapper-sss_python_unicode_from_s.patch => 0092-UTIL-Remove-python-wrapper-sss_python_unicode_from_s.patch (97%) rename 0009-BUILD-Use-python-config-for-detection-FLAGS.patch => 0093-BUILD-Use-python-config-for-detection-FLAGS.patch (97%) rename 0010-SPEC-Use-new-convention-for-python-packages.patch => 0094-SPEC-Use-new-convention-for-python-packages.patch (90%) rename 0011-SPEC-Move-python-bindings-to-separate-packages.patch => 0095-SPEC-Move-python-bindings-to-separate-packages.patch (90%) rename 0012-BUILD-Add-possibility-to-build-python-2-3-bindings.patch => 0096-BUILD-Add-possibility-to-build-python-2-3-bindings.patch (96%) rename 0013-TESTS-Run-python-tests-with-all-supported-python-ver.patch => 0097-TESTS-Run-python-tests-with-all-supported-python-ver.patch (92%) rename 0014-SPEC-Replace-python_-macros-with-python2_.patch => 0098-SPEC-Replace-python_-macros-with-python2_.patch (92%) rename 0015-SPEC-Build-python3-bindings-on-available-platforms.patch => 0099-SPEC-Build-python3-bindings-on-available-platforms.patch (98%) diff --git a/0001-PAM-do-not-reject-abruptly.patch b/0001-PAM-do-not-reject-abruptly.patch new file mode 100644 index 0000000..b92d9b4 --- /dev/null +++ b/0001-PAM-do-not-reject-abruptly.patch @@ -0,0 +1,222 @@ +From 325a3a1015a8ce239efa07b2371f2f8db8bf395e Mon Sep 17 00:00:00 2001 +From: Pavel Reichl +Date: Wed, 11 Feb 2015 19:38:16 -0500 +Subject: [PATCH 01/99] PAM: do not reject abruptly + +If account has expired then pass message. + +Resolves: +https://fedorahosted.org/sssd/ticket/2050 + +Reviewed-by: Sumit Bose +(cherry picked from commit a61d6d01a4e89ec14175af135e84f1cac55af748) +--- + src/responder/pam/pamsrv_cmd.c | 53 ++++++++++++++++++++++++++++++++++ + src/sss_client/pam_sss.c | 64 +++++++++++++++++++++++++++++++++++++++++- + src/sss_client/sss_cli.h | 18 +++++++++--- + 3 files changed, 130 insertions(+), 5 deletions(-) + +diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c +index 90cdbec519587a0d5dd680bfe3a991d896d6c008..c874cae61960ffa17dbe8aab7b96b792d65ac618 100644 +--- a/src/responder/pam/pamsrv_cmd.c ++++ b/src/responder/pam/pamsrv_cmd.c +@@ -44,6 +44,54 @@ enum pam_verbosity { + + static void pam_reply(struct pam_auth_req *preq); + ++static errno_t pack_user_info_account_expired(TALLOC_CTX *mem_ctx, ++ const char *user_error_message, ++ size_t *resp_len, ++ uint8_t **_resp) ++{ ++ uint32_t resp_type = SSS_PAM_USER_INFO_ACCOUNT_EXPIRED; ++ size_t err_len; ++ uint8_t *resp; ++ size_t p; ++ ++ err_len = strlen(user_error_message); ++ *resp_len = 2 * sizeof(uint32_t) + err_len; ++ resp = talloc_size(mem_ctx, *resp_len); ++ if (resp == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n"); ++ return ENOMEM; ++ } ++ ++ p = 0; ++ SAFEALIGN_SET_UINT32(&resp[p], resp_type, &p); ++ SAFEALIGN_SET_UINT32(&resp[p], err_len, &p); ++ safealign_memcpy(&resp[p], user_error_message, err_len, &p); ++ if (p != *resp_len) { ++ DEBUG(SSSDBG_FATAL_FAILURE, "Size mismatch\n"); ++ } ++ ++ *_resp = resp; ++ return EOK; ++} ++ ++static void inform_account_expired(struct pam_data* pd) ++{ ++ size_t msg_len; ++ uint8_t *msg; ++ errno_t ret; ++ ++ ret = pack_user_info_account_expired(pd, "", &msg_len, &msg); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_CRIT_FAILURE, ++ "pack_user_info_account_expired failed.\n"); ++ } else { ++ ret = pam_add_response(pd, SSS_PAM_USER_INFO, msg_len, msg); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); ++ } ++ } ++} ++ + static bool is_domain_requested(struct pam_data *pd, const char *domain_name) + { + int i; +@@ -609,6 +657,11 @@ static void pam_reply(struct pam_auth_req *preq) + goto done; + } + ++ if (pd->pam_status == PAM_ACCT_EXPIRED && pd->service != NULL && ++ strcasecmp(pd->service, "sshd") == 0) { ++ inform_account_expired(pd); ++ } ++ + ret = filter_responses(pctx->rctx->cdb, pd->resp_list); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "filter_responses failed, not fatal.\n"); +diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c +index fdf6c9e6da75c9f7eaa7c00d9a5792fbdd97eabc..59529796c682416d49c7f92f5feea3b0ace8d2d4 100644 +--- a/src/sss_client/pam_sss.c ++++ b/src/sss_client/pam_sss.c +@@ -60,6 +60,9 @@ + #define OPT_RETRY_KEY "retry=" + #define OPT_DOMAINS_KEY "domains=" + ++#define EXP_ACC_MSG _("Your account has expired. ") ++#define SRV_MSG _("Server message: ") ++ + struct pam_items { + const char* pam_service; + const char* pam_user; +@@ -797,6 +800,63 @@ static int user_info_otp_chpass(pam_handle_t *pamh) + return PAM_SUCCESS; + } + ++static int user_info_account_expired(pam_handle_t *pamh, size_t buflen, ++ uint8_t *buf) ++{ ++ int ret; ++ uint32_t msg_len; ++ char *user_msg; ++ size_t bufsize = 0; ++ ++ /* resp_type and length of message are expected to be in buf */ ++ if (buflen < 2* sizeof(uint32_t)) { ++ D(("User info response data is too short")); ++ return PAM_BUF_ERR; ++ } ++ ++ /* msg_len = legth of message */ ++ memcpy(&msg_len, buf + sizeof(uint32_t), sizeof(uint32_t)); ++ ++ if (buflen != 2* sizeof(uint32_t) + msg_len) { ++ D(("User info response data has the wrong size")); ++ return PAM_BUF_ERR; ++ } ++ ++ bufsize = strlen(EXP_ACC_MSG) + 1; ++ ++ if (msg_len > 0) { ++ bufsize += strlen(SRV_MSG) + msg_len; ++ } ++ ++ user_msg = (char *)malloc(sizeof(char) * bufsize); ++ if (!user_msg) { ++ D(("Out of memory.")); ++ return PAM_SYSTEM_ERR; ++ } ++ ++ ret = snprintf(user_msg, bufsize, "%s%s%.*s", ++ EXP_ACC_MSG, ++ msg_len > 0 ? SRV_MSG : "", ++ msg_len, ++ msg_len > 0 ? (char *)(buf + 2 * sizeof(uint32_t)) : "" ); ++ if (ret < 0 || ret > bufsize) { ++ D(("snprintf failed.")); ++ ++ free(user_msg); ++ return PAM_SYSTEM_ERR; ++ } ++ ++ ret = do_pam_conversation(pamh, PAM_TEXT_INFO, user_msg, NULL, NULL); ++ free(user_msg); ++ if (ret != PAM_SUCCESS) { ++ D(("do_pam_conversation failed.")); ++ ++ return PAM_SYSTEM_ERR; ++ } ++ ++ return PAM_SUCCESS; ++} ++ + static int user_info_chpass_error(pam_handle_t *pamh, size_t buflen, + uint8_t *buf) + { +@@ -852,7 +912,6 @@ static int user_info_chpass_error(pam_handle_t *pamh, size_t buflen, + return PAM_SUCCESS; + } + +- + static int eval_user_info_response(pam_handle_t *pamh, size_t buflen, + uint8_t *buf) + { +@@ -888,6 +947,9 @@ static int eval_user_info_response(pam_handle_t *pamh, size_t buflen, + case SSS_PAM_USER_INFO_CHPASS_ERROR: + ret = user_info_chpass_error(pamh, buflen, buf); + break; ++ case SSS_PAM_USER_INFO_ACCOUNT_EXPIRED: ++ ret = user_info_account_expired(pamh, buflen, buf); ++ break; + default: + D(("Unknown user info type [%d]", type)); + ret = PAM_SYSTEM_ERR; +diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h +index 6286077fcf25aead1dfcba5c6483e4ff8ae63b9f..d508a0671cd1b3ee087e0967f7015628ceabe20f 100644 +--- a/src/sss_client/sss_cli.h ++++ b/src/sss_client/sss_cli.h +@@ -461,15 +461,25 @@ enum user_info_type { + * indicates that no message is following. + * @param String with the specified + * length. */ ++ + SSS_PAM_USER_INFO_GRACE_LOGIN, /**< Warn the user that the password is + * expired and inform about the remaining + * number of grace logins. + * @param The number of remaining grace + * logins as uint32_t */ +- SSS_PAM_USER_INFO_EXPIRE_WARN /**< Warn the user that the password will +- * expire soon. +- * @param Number of seconds before the user's +- * password will expire. */ ++ SSS_PAM_USER_INFO_EXPIRE_WARN, /**< Warn the user that the password will ++ * expire soon. ++ * @param Number of seconds before the ++ * user's password will expire. */ ++ ++ SSS_PAM_USER_INFO_ACCOUNT_EXPIRED, /**< Tell the user that the account ++ * has expired and optionally give ++ * a reason. ++ * @param Size of the message as ++ * unsigned 32-bit integer value. A ++ * value of 0 indicates that no message ++ * is following. @param String with the ++ * specified length. */ + }; + /** + * @} +-- +2.4.0 + diff --git a/0002-PAM-new-option-pam_account_expired_message.patch b/0002-PAM-new-option-pam_account_expired_message.patch new file mode 100644 index 0000000..1866639 --- /dev/null +++ b/0002-PAM-new-option-pam_account_expired_message.patch @@ -0,0 +1,157 @@ +From a81b2ae67c7b011c74c0d37df5bdaef2ef2bbb4a Mon Sep 17 00:00:00 2001 +From: Pavel Reichl +Date: Thu, 19 Feb 2015 11:17:36 -0500 +Subject: [PATCH 02/99] PAM: new option pam_account_expired_message + +This option sets string to be printed when authenticating using SSH +keys and account is expired. + +Resolves: +https://fedorahosted.org/sssd/ticket/2050 + +Reviewed-by: Sumit Bose +(cherry picked from commit e039f1aefecc65a7b3c2d4a13a612bff1dd367c8) +--- + src/confdb/confdb.h | 1 + + src/config/SSSDConfig/__init__.py.in | 1 + + src/config/etc/sssd.api.conf | 1 + + src/man/sssd.conf.5.xml | 21 +++++++++++++++++++++ + src/responder/pam/pamsrv_cmd.c | 14 ++++++++++---- + src/sss_client/pam_sss.c | 2 +- + 6 files changed, 35 insertions(+), 5 deletions(-) + +diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h +index b5c4999a3179a6f1303d31f24f2ca5680cf69ac6..19c56402069f9a7001188e91f77db8ad8525d690 100644 +--- a/src/confdb/confdb.h ++++ b/src/confdb/confdb.h +@@ -114,6 +114,7 @@ + #define CONFDB_PAM_PWD_EXPIRATION_WARNING "pam_pwd_expiration_warning" + #define CONFDB_PAM_TRUSTED_USERS "pam_trusted_users" + #define CONFDB_PAM_PUBLIC_DOMAINS "pam_public_domains" ++#define CONFDB_PAM_ACCOUNT_EXPIRED_MESSAGE "pam_account_expired_message" + + /* SUDO */ + #define CONFDB_SUDO_CONF_ENTRY "config/sudo" +diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in +index aad0b2ce422b009f1bc95f3377bad34af4495776..dbbffebf38977e526cf2944510a2f60da7edf33a 100644 +--- a/src/config/SSSDConfig/__init__.py.in ++++ b/src/config/SSSDConfig/__init__.py.in +@@ -88,6 +88,7 @@ option_strings = { + 'pam_pwd_expiration_warning' : _('How many days before password expiration a warning should be displayed'), + 'pam_trusted_users' : _('List of trusted uids or user\'s name'), + 'pam_public_domains' : _('List of domains accessible even for untrusted users.'), ++ 'pam_account_expired_message' : _('Message printed when user account is expired.'), + + # [sudo] + 'sudo_timed' : _('Whether to evaluate the time-based attributes in sudo rules'), +diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf +index 3503635e07bbd0511349a9b5b9d05c30c6825bf3..4fa542704fbd3af065843e777b84b6305ec3e78b 100644 +--- a/src/config/etc/sssd.api.conf ++++ b/src/config/etc/sssd.api.conf +@@ -58,6 +58,7 @@ pam_pwd_expiration_warning = int, None, false + get_domains_timeout = int, None, false + pam_trusted_users = str, None, false + pam_public_domains = str, None, false ++pam_account_expired_message = str, None, false + + [sudo] + # sudo service +diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml +index 90545245eb68e4b45b4b49b5935e47867bffb794..bb4c1d3c65818d8d949482569868e14cf60c5db5 100644 +--- a/src/man/sssd.conf.5.xml ++++ b/src/man/sssd.conf.5.xml +@@ -933,6 +933,27 @@ fallback_homedir = /home/%u + + + ++ ++ pam_account_expired_message (string) ++ ++ ++ If user is authenticating using SSH keys and ++ account is expired then by default ++ 'Permission denied' is output. This output will ++ be changed to content of this variable if it is ++ set. ++ ++ ++ example: ++ ++pam_account_expired_message = Account expired, please call help desk. ++ ++ ++ ++ Default: none ++ ++ ++ + + + +diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c +index c874cae61960ffa17dbe8aab7b96b792d65ac618..a9c1b49d7ccf361404b02fb4c4a8ae260f9498cc 100644 +--- a/src/responder/pam/pamsrv_cmd.c ++++ b/src/responder/pam/pamsrv_cmd.c +@@ -74,13 +74,14 @@ static errno_t pack_user_info_account_expired(TALLOC_CTX *mem_ctx, + return EOK; + } + +-static void inform_account_expired(struct pam_data* pd) ++static void inform_account_expired(struct pam_data* pd, ++ const char *pam_message) + { + size_t msg_len; + uint8_t *msg; + errno_t ret; + +- ret = pack_user_info_account_expired(pd, "", &msg_len, &msg); ++ ret = pack_user_info_account_expired(pd, pam_message, &msg_len, &msg); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "pack_user_info_account_expired failed.\n"); +@@ -544,6 +545,7 @@ static void pam_reply(struct pam_auth_req *preq) + uint32_t user_info_type; + time_t exp_date = -1; + time_t delay_until = -1; ++ char* pam_account_expired_message; + + pd = preq->pd; + cctx = preq->cctx; +@@ -620,7 +622,7 @@ static void pam_reply(struct pam_auth_req *preq) + ret = gettimeofday(&tv, NULL); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "gettimeofday failed [%d][%s].\n", +- errno, strerror(errno)); ++ errno, strerror(errno)); + goto done; + } + tv.tv_sec += pd->response_delay; +@@ -659,7 +661,11 @@ static void pam_reply(struct pam_auth_req *preq) + + if (pd->pam_status == PAM_ACCT_EXPIRED && pd->service != NULL && + strcasecmp(pd->service, "sshd") == 0) { +- inform_account_expired(pd); ++ ret = confdb_get_string(pctx->rctx->cdb, pd, CONFDB_PAM_CONF_ENTRY, ++ CONFDB_PAM_ACCOUNT_EXPIRED_MESSAGE, "", ++ &pam_account_expired_message); ++ ++ inform_account_expired(pd, pam_account_expired_message); + } + + ret = filter_responses(pctx->rctx->cdb, pd->resp_list); +diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c +index 59529796c682416d49c7f92f5feea3b0ace8d2d4..28a36d5af95297b394a74f39d6614f48831bb901 100644 +--- a/src/sss_client/pam_sss.c ++++ b/src/sss_client/pam_sss.c +@@ -60,7 +60,7 @@ + #define OPT_RETRY_KEY "retry=" + #define OPT_DOMAINS_KEY "domains=" + +-#define EXP_ACC_MSG _("Your account has expired. ") ++#define EXP_ACC_MSG _("Permission denied. ") + #define SRV_MSG _("Server message: ") + + struct pam_items { +-- +2.4.0 + diff --git a/0003-PAM-warn-all-services-about-account-expiration.patch b/0003-PAM-warn-all-services-about-account-expiration.patch new file mode 100644 index 0000000..0c07aa8 --- /dev/null +++ b/0003-PAM-warn-all-services-about-account-expiration.patch @@ -0,0 +1,62 @@ +From 09c9dfa2c3f183dfd2704e4dfd488521b793ae3a Mon Sep 17 00:00:00 2001 +From: Pavel Reichl +Date: Thu, 19 Feb 2015 11:50:54 -0500 +Subject: [PATCH 03/99] PAM: warn all services about account expiration + +if pam_verbose is above one then output warning about account +expiration for all services. + +Resolves: +https://fedorahosted.org/sssd/ticket/2050 + +Reviewed-by: Sumit Bose +(cherry picked from commit f3c2dc1f9ccdf456fd78ed96197b9bf404cc29fc) +--- + src/responder/pam/pamsrv_cmd.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c +index a9c1b49d7ccf361404b02fb4c4a8ae260f9498cc..ab8369b0f9b1f3ed9256fc16396f095818d36bbf 100644 +--- a/src/responder/pam/pamsrv_cmd.c ++++ b/src/responder/pam/pamsrv_cmd.c +@@ -546,11 +546,20 @@ static void pam_reply(struct pam_auth_req *preq) + time_t exp_date = -1; + time_t delay_until = -1; + char* pam_account_expired_message; ++ int pam_verbosity; + + pd = preq->pd; + cctx = preq->cctx; + pctx = talloc_get_type(preq->cctx->rctx->pvt_ctx, struct pam_ctx); + ++ ret = confdb_get_int(pctx->rctx->cdb, CONFDB_PAM_CONF_ENTRY, ++ CONFDB_PAM_VERBOSITY, DEFAULT_PAM_VERBOSITY, ++ &pam_verbosity); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_CRIT_FAILURE, ++ "Failed to read PAM verbosity, not fatal.\n"); ++ pam_verbosity = DEFAULT_PAM_VERBOSITY; ++ } + + DEBUG(SSSDBG_FUNC_DATA, + "pam_reply called with result [%d].\n", pd->pam_status); +@@ -659,8 +668,14 @@ static void pam_reply(struct pam_auth_req *preq) + goto done; + } + +- if (pd->pam_status == PAM_ACCT_EXPIRED && pd->service != NULL && +- strcasecmp(pd->service, "sshd") == 0) { ++ /* Account expiration warning is printed for sshd. If pam_verbosity ++ * is equal or above PAM_VERBOSITY_INFO then all services are informed ++ * about account expiration. ++ */ ++ if (pd->pam_status == PAM_ACCT_EXPIRED && ++ ((pd->service != NULL && strcasecmp(pd->service, "sshd") == 0) || ++ pam_verbosity >= PAM_VERBOSITY_INFO)) { ++ + ret = confdb_get_string(pctx->rctx->cdb, pd, CONFDB_PAM_CONF_ENTRY, + CONFDB_PAM_ACCOUNT_EXPIRED_MESSAGE, "", + &pam_account_expired_message); +-- +2.4.0 + diff --git a/0004-PAM-check-return-value-of-confdb_get_string.patch b/0004-PAM-check-return-value-of-confdb_get_string.patch new file mode 100644 index 0000000..56ef495 --- /dev/null +++ b/0004-PAM-check-return-value-of-confdb_get_string.patch @@ -0,0 +1,33 @@ +From 45b7cadbbd81df4a6aba39de97eb1522774bcc60 Mon Sep 17 00:00:00 2001 +From: Pavel Reichl +Date: Wed, 25 Feb 2015 05:38:38 -0500 +Subject: [PATCH 04/99] PAM: check return value of confdb_get_string + +Coverity found this neglect. + +Reviewed-by: Jakub Hrozek +(cherry picked from commit c5290f2175845f2c5e3f35ce279b6f52b1d51275) +--- + src/responder/pam/pamsrv_cmd.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c +index ab8369b0f9b1f3ed9256fc16396f095818d36bbf..86e763f825096edc0c07adbe2e02820e5f2bdac9 100644 +--- a/src/responder/pam/pamsrv_cmd.c ++++ b/src/responder/pam/pamsrv_cmd.c +@@ -679,6 +679,12 @@ static void pam_reply(struct pam_auth_req *preq) + ret = confdb_get_string(pctx->rctx->cdb, pd, CONFDB_PAM_CONF_ENTRY, + CONFDB_PAM_ACCOUNT_EXPIRED_MESSAGE, "", + &pam_account_expired_message); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "Failed to get expiration message: %d:[%s].\n", ++ ret, sss_strerror(ret)); ++ goto done; ++ } + + inform_account_expired(pd, pam_account_expired_message); + } +-- +2.4.0 + diff --git a/0005-resolv-Use-the-same-default-timeout-for-SRV-queries-.patch b/0005-resolv-Use-the-same-default-timeout-for-SRV-queries-.patch new file mode 100644 index 0000000..a70b848 --- /dev/null +++ b/0005-resolv-Use-the-same-default-timeout-for-SRV-queries-.patch @@ -0,0 +1,57 @@ +From 9d68909e27641410dced44865aff0a11f77597ef Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Tue, 3 Mar 2015 11:39:39 +0100 +Subject: [PATCH 05/99] resolv: Use the same default timeout for SRV queries as + previously +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When we changed the resolver code to use the TTL values from the DNS +queries instead of harcoded ones, we changed the default value by +accident. + +Add a separate SRV TTL that is backwards-compatible with the old +harcoded value. + +Reviewed-by: Pavel Březina +(cherry picked from commit eafbc66c2ff6365478e62a8df3fd005bf80e5c7b) +--- + src/resolv/async_resolv.c | 4 +++- + src/resolv/async_resolv.h | 4 ++++ + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/resolv/async_resolv.c b/src/resolv/async_resolv.c +index 85c4d99a4ef3c5071353f176c78caba115286fe4..80e4922c576ce52ab895d62c822706e9e46024a0 100644 +--- a/src/resolv/async_resolv.c ++++ b/src/resolv/async_resolv.c +@@ -1776,8 +1776,10 @@ resolv_getsrv_done(void *arg, int status, int timeouts, unsigned char *abuf, int + state->reply_list = reply_list; + ok = resolv_get_ttl(abuf, alen, &state->ttl); + if (ok == false) { +- state->ttl = RESOLV_DEFAULT_TTL; ++ DEBUG(SSSDBG_MINOR_FAILURE, "Could not read TTL, using the default..\n"); ++ state->ttl = RESOLV_DEFAULT_SRV_TTL; + } ++ DEBUG(SSSDBG_TRACE_LIBS, "Using TTL [%"PRIu32"]\n", state->ttl); + + tevent_req_done(req); + return; +diff --git a/src/resolv/async_resolv.h b/src/resolv/async_resolv.h +index 9b08f12ae159d377b50b9ddfe9f71397a461635d..14cbdc5023705b164ccb775991b7790accc1f2cc 100644 +--- a/src/resolv/async_resolv.h ++++ b/src/resolv/async_resolv.h +@@ -42,6 +42,10 @@ + #define RESOLV_DEFAULT_TTL 7200 + #endif /* RESOLV_DEFAULT_TTL */ + ++#ifndef RESOLV_DEFAULT_SRV_TTL ++#define RESOLV_DEFAULT_SRV_TTL 14400 ++#endif /* RESOLV_DEFAULT_SRV_TTL */ ++ + #include "util/util.h" + + /* +-- +2.4.0 + diff --git a/0006-FO-Use-SRV-TTL-in-fail-over-code.patch b/0006-FO-Use-SRV-TTL-in-fail-over-code.patch new file mode 100644 index 0000000..716a023 --- /dev/null +++ b/0006-FO-Use-SRV-TTL-in-fail-over-code.patch @@ -0,0 +1,1020 @@ +From 097f92a95c5155176280591c35afd7f5a6b1d5be Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Fri, 12 Dec 2014 17:10:40 +0100 +Subject: [PATCH 06/99] FO: Use SRV TTL in fail over code +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Resolves: +https://fedorahosted.org/sssd/ticket/1884 + +Removes the hardcoded SRV TTL timeout and uses TTL from the DNS instead. + +Reviewed-by: Pavel Březina +(cherry picked from commit 8df69bbc58c2f4d3f0b34be9756d9ddf24b1db6d) +--- + Makefile.am | 19 ++ + src/providers/ad/ad_srv.c | 8 +- + src/providers/ad/ad_srv.h | 1 + + src/providers/data_provider_fo.c | 1 - + src/providers/fail_over.c | 8 +- + src/providers/fail_over.h | 1 - + src/providers/fail_over_srv.c | 27 +- + src/providers/fail_over_srv.h | 4 + + src/providers/ipa/ipa_srv.c | 6 + + src/providers/ipa/ipa_srv.h | 1 + + src/tests/cmocka/test_fo_srv.c | 599 +++++++++++++++++++++++++++++++++++++++ + 11 files changed, 666 insertions(+), 9 deletions(-) + create mode 100644 src/tests/cmocka/test_fo_srv.c + +diff --git a/Makefile.am b/Makefile.am +index 29d148c4a0cbda6882b4a619d6c71d2efcc8fb43..254930387aa9dda981c1539616e2912447c2b1d6 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -218,6 +218,7 @@ if HAVE_CMOCKA + test_copy_ccache \ + test_copy_keytab \ + test_child_common \ ++ test_fo_srv \ + $(NULL) + + if HAVE_LIBRESOLV +@@ -2209,6 +2210,24 @@ test_resolv_fake_LDADD = \ + $(NULL) + endif # HAVE_LIBRESOLV + ++test_fo_srv_SOURCES = \ ++ src/tests/cmocka/test_fo_srv.c \ ++ src/providers/fail_over.c \ ++ src/providers/fail_over_srv.c \ ++ $(NULL) ++test_fo_srv_CFLAGS = \ ++ $(AM_CFLAGS) \ ++ $(NULL) ++test_fo_srv_LDADD = \ ++ $(CMOCKA_LIBS) \ ++ $(POPT_LIBS) \ ++ $(TALLOC_LIBS) \ ++ $(CARES_LIBS) \ ++ $(DHASH_LIBS) \ ++ $(SSSD_INTERNAL_LTLIBS) \ ++ libsss_test_common.la \ ++ $(NULL) ++ + endif # HAVE_CMOCKA + + noinst_PROGRAMS = pam_test_client +diff --git a/src/providers/ad/ad_srv.c b/src/providers/ad/ad_srv.c +index ac9dfa187213e6cdb9cdc3440f013e5b73e11fc4..910f82dd049902c01bdb14edf0cdf44b18c94b0b 100644 +--- a/src/providers/ad/ad_srv.c ++++ b/src/providers/ad/ad_srv.c +@@ -176,7 +176,7 @@ static void ad_get_dc_servers_done(struct tevent_req *subreq) + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ad_get_dc_servers_state); + +- ret = fo_discover_srv_recv(state, subreq, &domain, ++ ret = fo_discover_srv_recv(state, subreq, &domain, NULL, + &state->servers, &state->num_servers); + talloc_zfree(subreq); + if (ret != EOK) { +@@ -616,6 +616,7 @@ struct ad_srv_plugin_state { + + const char *site; + char *dns_domain; ++ uint32_t ttl; + char *forest; + struct fo_server_info *primary_servers; + size_t num_primary_servers; +@@ -837,6 +838,7 @@ static void ad_srv_plugin_servers_done(struct tevent_req *subreq) + state = tevent_req_data(req, struct ad_srv_plugin_state); + + ret = fo_discover_servers_recv(state, subreq, &state->dns_domain, ++ &state->ttl, + &state->primary_servers, + &state->num_primary_servers, + &state->backup_servers, +@@ -874,6 +876,7 @@ static void ad_srv_plugin_servers_done(struct tevent_req *subreq) + errno_t ad_srv_plugin_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + char **_dns_domain, ++ uint32_t *_ttl, + struct fo_server_info **_primary_servers, + size_t *_num_primary_servers, + struct fo_server_info **_backup_servers, +@@ -904,6 +907,9 @@ errno_t ad_srv_plugin_recv(TALLOC_CTX *mem_ctx, + *_dns_domain = talloc_steal(mem_ctx, state->dns_domain); + } + ++ if (_ttl) { ++ *_ttl = state->ttl; ++ } + + return EOK; + } +diff --git a/src/providers/ad/ad_srv.h b/src/providers/ad/ad_srv.h +index be3ac2826186008a4db6333e5d27e408aaed2e51..ae5efe44755fa09f74064014cce749e35b1831da 100644 +--- a/src/providers/ad/ad_srv.h ++++ b/src/providers/ad/ad_srv.h +@@ -42,6 +42,7 @@ struct tevent_req *ad_srv_plugin_send(TALLOC_CTX *mem_ctx, + errno_t ad_srv_plugin_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + char **_dns_domain, ++ uint32_t *_ttl, + struct fo_server_info **_primary_servers, + size_t *_num_primary_servers, + struct fo_server_info **_backup_servers, +diff --git a/src/providers/data_provider_fo.c b/src/providers/data_provider_fo.c +index ef1f0b2ed3c0164414c6c4c4dad29804d542c886..dab796d4647a552c2fd1c626c490278de91c2e81 100644 +--- a/src/providers/data_provider_fo.c ++++ b/src/providers/data_provider_fo.c +@@ -70,7 +70,6 @@ static int be_fo_get_options(struct be_ctx *ctx, + opts->service_resolv_timeout = dp_opt_get_int(ctx->be_res->opts, + DP_RES_OPT_RESOLVER_TIMEOUT); + opts->retry_timeout = 30; +- opts->srv_retry_timeout = 14400; + opts->srv_retry_neg_timeout = 15; + opts->family_order = ctx->be_res->family_order; + +diff --git a/src/providers/fail_over.c b/src/providers/fail_over.c +index c16c70ddb0c16a744c237e25e7ab4b356eaff2be..8142081526d7902946e756ec05774c471126545e 100644 +--- a/src/providers/fail_over.c ++++ b/src/providers/fail_over.c +@@ -117,6 +117,7 @@ struct srv_data { + struct fo_server *meta; + + int srv_lookup_status; ++ int ttl; + struct timeval last_status_change; + }; + +@@ -149,7 +150,6 @@ fo_context_init(TALLOC_CTX *mem_ctx, struct fo_options *opts) + return NULL; + } + +- ctx->opts->srv_retry_timeout = opts->srv_retry_timeout; + ctx->opts->srv_retry_neg_timeout = opts->srv_retry_neg_timeout; + ctx->opts->retry_timeout = opts->retry_timeout; + ctx->opts->family_order = opts->family_order; +@@ -272,7 +272,7 @@ get_srv_data_status(struct srv_data *data) + if (data->srv_lookup_status == SRV_RESOLVE_ERROR) { + timeout = data->meta->service->ctx->opts->srv_retry_neg_timeout; + } else { +- timeout = data->meta->service->ctx->opts->srv_retry_timeout; ++ timeout = data->ttl; + } + + if (timeout && STATUS_DIFF(data, tv) > timeout) { +@@ -1285,8 +1285,9 @@ resolve_srv_done(struct tevent_req *subreq) + size_t num_backup_servers = 0; + char *dns_domain = NULL; + int ret; ++ uint32_t ttl; + +- ret = state->fo_ctx->srv_recv_fn(state, subreq, &dns_domain, ++ ret = state->fo_ctx->srv_recv_fn(state, subreq, &dns_domain, &ttl, + &primary_servers, &num_primary_servers, + &backup_servers, &num_backup_servers); + talloc_free(subreq); +@@ -1300,6 +1301,7 @@ resolve_srv_done(struct tevent_req *subreq) + goto done; + } + ++ state->meta->srv_data->ttl = ttl; + talloc_zfree(state->meta->srv_data->dns_domain); + state->meta->srv_data->dns_domain = talloc_steal(state->meta->srv_data, + dns_domain); +diff --git a/src/providers/fail_over.h b/src/providers/fail_over.h +index b1ec6a23c5e475c7df4fce21626a53df96fe62e8..d44ad2ff145dc6b3617e6f2ea665c7d82d923ddb 100644 +--- a/src/providers/fail_over.h ++++ b/src/providers/fail_over.h +@@ -78,7 +78,6 @@ struct fo_server; + * try when looking up the service. + */ + struct fo_options { +- time_t srv_retry_timeout; + time_t srv_retry_neg_timeout; + time_t retry_timeout; + int service_resolv_timeout; +diff --git a/src/providers/fail_over_srv.c b/src/providers/fail_over_srv.c +index 5c06d28767b8afbc4e573a7881e7855f35747460..5f474eaee4f359cb6c4af3896b7ba18413eb4995 100644 +--- a/src/providers/fail_over_srv.c ++++ b/src/providers/fail_over_srv.c +@@ -30,6 +30,7 @@ struct fo_discover_srv_state { + char *dns_domain; + struct fo_server_info *servers; + size_t num_servers; ++ uint32_t ttl; + }; + + static void fo_discover_srv_done(struct tevent_req *subreq); +@@ -83,7 +84,7 @@ static void fo_discover_srv_done(struct tevent_req *subreq) + state = tevent_req_data(req, struct fo_discover_srv_state); + + ret = resolv_discover_srv_recv(state, subreq, +- &reply_list, NULL, &state->dns_domain); ++ &reply_list, &state->ttl, &state->dns_domain); + talloc_zfree(subreq); + if (ret == ENOENT) { + ret = ERR_SRV_NOT_FOUND; +@@ -143,6 +144,7 @@ done: + errno_t fo_discover_srv_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + char **_dns_domain, ++ uint32_t *_ttl, + struct fo_server_info **_servers, + size_t *_num_servers) + { +@@ -159,6 +161,10 @@ errno_t fo_discover_srv_recv(TALLOC_CTX *mem_ctx, + *_servers = talloc_steal(mem_ctx, state->servers); + } + ++ if (_ttl != NULL) { ++ *_ttl = state->ttl; ++ } ++ + if (_num_servers != NULL) { + *_num_servers = state->num_servers; + } +@@ -175,6 +181,7 @@ struct fo_discover_servers_state { + const char *backup_domain; + + char *dns_domain; ++ uint32_t ttl; + struct fo_server_info *primary_servers; + size_t num_primary_servers; + struct fo_server_info *backup_servers; +@@ -212,6 +219,7 @@ struct tevent_req *fo_discover_servers_send(TALLOC_CTX *mem_ctx, + state->backup_servers = NULL; + state->num_backup_servers = 0; + state->dns_domain = NULL; ++ state->ttl = 0; + + ret = EOK; + goto immediately; +@@ -289,6 +297,7 @@ static void fo_discover_servers_primary_done(struct tevent_req *subreq) + + ret = fo_discover_srv_recv(state, subreq, + &state->dns_domain, ++ &state->ttl, + &state->primary_servers, + &state->num_primary_servers); + talloc_zfree(subreq); +@@ -361,7 +370,7 @@ static void fo_discover_servers_backup_done(struct tevent_req *subreq) + state = tevent_req_data(req, struct fo_discover_servers_state); + + ret = fo_discover_srv_recv(state, subreq, NULL, +- &state->backup_servers, ++ NULL, &state->backup_servers, + &state->num_backup_servers); + talloc_zfree(subreq); + if (ret != EOK) { +@@ -385,6 +394,7 @@ static void fo_discover_servers_backup_done(struct tevent_req *subreq) + errno_t fo_discover_servers_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + char **_dns_domain, ++ uint32_t *_ttl, + struct fo_server_info **_primary_servers, + size_t *_num_primary_servers, + struct fo_server_info **_backup_servers, +@@ -415,6 +425,10 @@ errno_t fo_discover_servers_recv(TALLOC_CTX *mem_ctx, + *_dns_domain = talloc_steal(mem_ctx, state->dns_domain); + } + ++ if (_ttl) { ++ *_ttl = state->ttl; ++ } ++ + + return EOK; + } +@@ -436,6 +450,7 @@ struct fo_resolve_srv_dns_state { + const char *discovery_domain; + + char *dns_domain; ++ uint32_t ttl; + struct fo_server_info *servers; + size_t num_servers; + }; +@@ -644,7 +659,8 @@ static void fo_resolve_srv_dns_done(struct tevent_req *subreq) + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct fo_resolve_srv_dns_state); + +- ret = fo_discover_srv_recv(state, subreq, &state->dns_domain, ++ ret = fo_discover_srv_recv(state, subreq, ++ &state->dns_domain, &state->ttl, + &state->servers, &state->num_servers); + talloc_zfree(subreq); + if (ret != EOK) { +@@ -663,6 +679,7 @@ done: + errno_t fo_resolve_srv_dns_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + char **_dns_domain, ++ uint32_t *_ttl, + struct fo_server_info **_primary_servers, + size_t *_num_primary_servers, + struct fo_server_info **_backup_servers, +@@ -694,5 +711,9 @@ errno_t fo_resolve_srv_dns_recv(TALLOC_CTX *mem_ctx, + *_dns_domain = talloc_steal(mem_ctx, state->dns_domain); + } + ++ if (_ttl) { ++ *_ttl = state->ttl; ++ } ++ + return EOK; + } +diff --git a/src/providers/fail_over_srv.h b/src/providers/fail_over_srv.h +index c4b50ba33ab8370c62e8af48aca62de69f0f5627..fe4088e029ee05a77f699a9dee389f160615527b 100644 +--- a/src/providers/fail_over_srv.h ++++ b/src/providers/fail_over_srv.h +@@ -65,6 +65,7 @@ typedef errno_t + (*fo_srv_lookup_plugin_recv_t)(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + char **_dns_domain, ++ uint32_t *_ttl, + struct fo_server_info **_primary_servers, + size_t *_num_primary_servers, + struct fo_server_info **_backup_servers, +@@ -80,6 +81,7 @@ struct tevent_req *fo_discover_srv_send(TALLOC_CTX *mem_ctx, + errno_t fo_discover_srv_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + char **_dns_domain, ++ uint32_t *_ttl, + struct fo_server_info **_servers, + size_t *_num_servers); + +@@ -94,6 +96,7 @@ struct tevent_req *fo_discover_servers_send(TALLOC_CTX *mem_ctx, + errno_t fo_discover_servers_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + char **_dns_domain, ++ uint32_t *_ttl, + struct fo_server_info **_primary_servers, + size_t *_num_primary_servers, + struct fo_server_info **_backup_servers, +@@ -121,6 +124,7 @@ struct tevent_req *fo_resolve_srv_dns_send(TALLOC_CTX *mem_ctx, + errno_t fo_resolve_srv_dns_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + char **_dns_domain, ++ uint32_t *_ttl, + struct fo_server_info **_primary_servers, + size_t *_num_primary_servers, + struct fo_server_info **_backup_servers, +diff --git a/src/providers/ipa/ipa_srv.c b/src/providers/ipa/ipa_srv.c +index 4be5f3317f4d8ad0e4cd09a3093122b3f710a0b2..7477711347bfe4936a324baa1d0c1c23c3877679 100644 +--- a/src/providers/ipa/ipa_srv.c ++++ b/src/providers/ipa/ipa_srv.c +@@ -69,6 +69,7 @@ fail: + + struct ipa_srv_plugin_state { + char *dns_domain; ++ uint32_t ttl; + struct fo_server_info *primary_servers; + size_t num_primary_servers; + struct fo_server_info *backup_servers; +@@ -164,6 +165,7 @@ static void ipa_srv_plugin_done(struct tevent_req *subreq) + state = tevent_req_data(req, struct ipa_srv_plugin_state); + + ret = fo_discover_servers_recv(state, subreq, &state->dns_domain, ++ &state->ttl, + &state->primary_servers, + &state->num_primary_servers, + &state->backup_servers, +@@ -183,6 +185,7 @@ static void ipa_srv_plugin_done(struct tevent_req *subreq) + errno_t ipa_srv_plugin_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + char **_dns_domain, ++ uint32_t *_ttl, + struct fo_server_info **_primary_servers, + size_t *_num_primary_servers, + struct fo_server_info **_backup_servers, +@@ -213,6 +216,9 @@ errno_t ipa_srv_plugin_recv(TALLOC_CTX *mem_ctx, + *_dns_domain = talloc_steal(mem_ctx, state->dns_domain); + } + ++ if (_ttl) { ++ *_ttl = state->ttl; ++ } + + return EOK; + } +diff --git a/src/providers/ipa/ipa_srv.h b/src/providers/ipa/ipa_srv.h +index 1bfd2eeaebec6ae9d2826aa76060746a32a634fc..d089c9f64714b8adc8e789d2a35766fbf339d7fa 100644 +--- a/src/providers/ipa/ipa_srv.h ++++ b/src/providers/ipa/ipa_srv.h +@@ -39,6 +39,7 @@ struct tevent_req *ipa_srv_plugin_send(TALLOC_CTX *mem_ctx, + errno_t ipa_srv_plugin_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + char **_dns_domain, ++ uint32_t *_ttl, + struct fo_server_info **_primary_servers, + size_t *_num_primary_servers, + struct fo_server_info **_backup_servers, +diff --git a/src/tests/cmocka/test_fo_srv.c b/src/tests/cmocka/test_fo_srv.c +new file mode 100644 +index 0000000000000000000000000000000000000000..3ee308bd5967f44abda1980e7bff8e0a5c00dde0 +--- /dev/null ++++ b/src/tests/cmocka/test_fo_srv.c +@@ -0,0 +1,599 @@ ++/* ++ Authors: ++ Jakub Hrozek ++ ++ Copyright (C) 2014 Red Hat ++ ++ SSSD tests: Resolver tests using a fake resolver library ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "providers/fail_over_srv.h" ++#include "tests/cmocka/common_mock.h" ++#include "tests/cmocka/common_mock_resp.h" ++ ++#define TEST_RESOLV_TIMEOUT 5 ++#define TEST_FO_TIMEOUT 3000 ++#define TEST_SRV_TTL 500 ++#define TEST_SRV_SHORT_TTL 2 ++ ++static TALLOC_CTX *global_mock_context = NULL; ++ ++enum host_database default_host_dbs[] = { DB_FILES, DB_DNS, DB_SENTINEL }; ++ ++struct resolv_ctx { ++ int foo; ++}; ++ ++/* mock resolver interface. The resolver test is separate */ ++int resolv_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, ++ int timeout, struct resolv_ctx **ctxp) ++{ ++ *ctxp = talloc(mem_ctx, struct resolv_ctx); ++ return EOK; ++} ++ ++struct tevent_req * ++resolv_gethostbyname_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, ++ struct resolv_ctx *ctx, const char *name, ++ enum restrict_family family_order, ++ enum host_database *db) ++{ ++ return test_req_succeed_send(mem_ctx, ev); ++} ++ ++int resolv_gethostbyname_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, ++ int *status, int *timeouts, ++ struct resolv_hostent **rhostent) ++{ ++ return test_request_recv(req); ++} ++ ++const char *resolv_strerror(int ares_code) ++{ ++ return NULL; ++} ++ ++struct tevent_req *resolv_discover_srv_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct resolv_ctx *resolv_ctx, ++ const char *service, ++ const char *protocol, ++ const char **discovery_domains) ++{ ++ return test_req_succeed_send(mem_ctx, ev); ++} ++ ++errno_t resolv_discover_srv_recv(TALLOC_CTX *mem_ctx, ++ struct tevent_req *req, ++ struct ares_srv_reply **_reply_list, ++ uint32_t *_ttl, ++ char **_dns_domain) ++{ ++ struct ares_srv_reply *reply_list; ++ uint32_t ttl; ++ char *dns_domain; ++ ++ /* Need to always consume all mocked values */ ++ reply_list = sss_mock_ptr_type(struct ares_srv_reply *); ++ ttl = sss_mock_ptr_type(uint32_t); ++ dns_domain = sss_mock_ptr_type(char *); ++ ++ if (_reply_list != NULL) { ++ *_reply_list = reply_list; ++ } ++ ++ if (_ttl != NULL) { ++ *_ttl = ttl; ++ } ++ ++ if (_dns_domain != NULL) { ++ *_dns_domain = dns_domain; ++ } ++ ++ return test_request_recv(req); ++} ++ ++struct ares_srv_reply *pop_lowest_prio(struct ares_srv_reply **r) ++{ ++ struct ares_srv_reply *lowest; ++ struct ares_srv_reply *iter; ++ struct ares_srv_reply *prev; ++ ++ lowest = *r; ++ iter = lowest; ++ while (iter != NULL) { ++ if (iter->priority < lowest->priority) { ++ lowest = iter; ++ } ++ ++ iter = iter->next; ++ } ++ ++ prev = NULL; ++ iter = *r; ++ while (iter != lowest) { ++ prev = iter; ++ iter = iter->next; ++ } ++ ++ /* iter points to the lowest prio. Prev points to the item before */ ++ if (prev) { ++ prev->next = lowest->next; ++ } else { ++ *r = lowest->next; ++ } ++ ++ return lowest; ++} ++ ++int resolv_sort_srv_reply(struct ares_srv_reply **reply) ++{ ++ struct ares_srv_reply *r; ++ struct ares_srv_reply *lowest; ++ struct ares_srv_reply *sorted = NULL; ++ struct ares_srv_reply *sorted_head = NULL; ++ ++ r = *reply; ++ if (r == NULL || r->next == NULL) { ++ return EOK; ++ } ++ ++ do { ++ lowest = pop_lowest_prio(&r); ++ if (sorted) { ++ sorted->next = lowest; ++ sorted = sorted->next; ++ } else { ++ sorted = lowest; ++ sorted_head = sorted; ++ } ++ } while (r != NULL); ++ ++ *reply = sorted_head; ++ return EOK; ++} ++ ++struct tevent_req *resolv_get_domain_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct resolv_ctx *resolv_ctx, ++ const char *hostname, ++ enum host_database *host_dbs, ++ enum restrict_family family_order) ++{ ++ return test_req_succeed_send(mem_ctx, ev); ++} ++ ++errno_t resolv_get_domain_recv(TALLOC_CTX *mem_ctx, ++ struct tevent_req *req, ++ char **_dns_domain) ++{ ++ return test_request_recv(req); ++} ++ ++/* The unit test */ ++struct test_fo_srv_ctx { ++ struct resolv_ctx *resolv; ++ struct fo_ctx *fo_ctx; ++ struct fo_resolve_srv_dns_ctx *srv_ctx; ++ struct fo_service *fo_svc; ++ struct sss_test_ctx *ctx; ++}; ++ ++int test_fo_srv_data_cmp(void *ud1, void *ud2) ++{ ++ return strcasecmp((char*) ud1, (char*) ud2); ++} ++ ++void test_fo_srv_setup(void **state) ++{ ++ struct test_fo_srv_ctx *test_ctx; ++ errno_t ret; ++ struct fo_options fopts; ++ bool ok; ++ ++ assert_true(leak_check_setup()); ++ global_mock_context = talloc_new(global_talloc_context); ++ assert_non_null(global_mock_context); ++ ++ test_ctx = talloc_zero(global_mock_context, ++ struct test_fo_srv_ctx); ++ assert_non_null(test_ctx); ++ ++ test_ctx->ctx = create_ev_test_ctx(test_ctx); ++ assert_non_null(test_ctx->ctx); ++ ++ ret = resolv_init(test_ctx, test_ctx->ctx->ev, ++ TEST_RESOLV_TIMEOUT, &test_ctx->resolv); ++ assert_non_null(test_ctx->resolv); ++ ++ memset(&fopts, 0, sizeof(fopts)); ++ fopts.retry_timeout = TEST_FO_TIMEOUT; ++ fopts.family_order = IPV4_FIRST; ++ ++ test_ctx->fo_ctx = fo_context_init(test_ctx, &fopts); ++ assert_non_null(test_ctx->fo_ctx); ++ ++ test_ctx->srv_ctx = fo_resolve_srv_dns_ctx_init(test_ctx, test_ctx->resolv, ++ IPV4_FIRST, default_host_dbs, ++ "client.sssd.com", "sssd.local"); ++ assert_non_null(test_ctx->srv_ctx); ++ ++ ok = fo_set_srv_lookup_plugin(test_ctx->fo_ctx, ++ fo_resolve_srv_dns_send, ++ fo_resolve_srv_dns_recv, ++ test_ctx->srv_ctx); ++ assert_true(ok); ++ ++ ret = fo_new_service(test_ctx->fo_ctx, "ldap", ++ test_fo_srv_data_cmp, ++ &test_ctx->fo_svc); ++ assert_int_equal(ret, ERR_OK); ++ ++ *state = test_ctx; ++} ++ ++void test_fo_srv_teardown(void **state) ++{ ++ struct test_fo_srv_ctx *test_ctx = ++ talloc_get_type(*state, struct test_fo_srv_ctx); ++ ++ talloc_free(test_ctx); ++ talloc_free(global_mock_context); ++ assert_true(leak_check_teardown()); ++} ++ ++/* reply_list and dns_domain must be a talloc context so it can be used as ++ * talloc_steal argument later ++ */ ++static void mock_srv_results(struct ares_srv_reply *reply_list, ++ uint32_t ttl, ++ char *dns_domain) ++{ ++ will_return(resolv_discover_srv_recv, reply_list); ++ will_return(resolv_discover_srv_recv, ttl); ++ will_return(resolv_discover_srv_recv, dns_domain); ++} ++ ++static void check_server(struct fo_server *srv, int port, const char *name) ++{ ++ assert_non_null(srv); ++ assert_true(fo_is_srv_lookup(srv)); ++ assert_int_equal(fo_get_server_port(srv), port); ++ assert_string_equal(fo_get_server_name(srv), name); ++} ++ ++static void test_fo_srv_done1(struct tevent_req *req); ++static void test_fo_srv_done2(struct tevent_req *req); ++static void test_fo_srv_done3(struct tevent_req *req); ++static void test_fo_srv_done4(struct tevent_req *req); ++ ++void test_fo_srv(void **state) ++{ ++ errno_t ret; ++ struct tevent_req *req; ++ struct test_fo_srv_ctx *test_ctx = ++ talloc_get_type(*state, struct test_fo_srv_ctx); ++ struct ares_srv_reply *s1; ++ struct ares_srv_reply *s2; ++ char *dns_domain; ++ ++ s1 = talloc_zero(test_ctx, struct ares_srv_reply); ++ assert_non_null(s1); ++ s1->host = talloc_strdup(s1, "ldap1.sssd.com"); ++ assert_non_null(s1->host); ++ s1->weight = 100; ++ s1->priority = 1; ++ s1->port = 389; ++ ++ s2 = talloc_zero(test_ctx, struct ares_srv_reply); ++ assert_non_null(s2); ++ s2->host = talloc_strdup(s2, "ldap2.sssd.com"); ++ assert_non_null(s2->host); ++ s2->weight = 100; ++ s2->priority = 2; ++ s2->port = 389; ++ ++ s1->next = s2; ++ ++ dns_domain = talloc_strdup(test_ctx, "sssd.com"); ++ assert_non_null(dns_domain); ++ ++ mock_srv_results(s1, TEST_SRV_TTL, dns_domain); ++ ++ ret = fo_add_srv_server(test_ctx->fo_svc, "_ldap", "sssd.com", ++ "sssd.local", "tcp", test_ctx); ++ assert_int_equal(ret, ERR_OK); ++ ++ req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev, ++ test_ctx->resolv, test_ctx->fo_ctx, ++ test_ctx->fo_svc); ++ assert_non_null(req); ++ tevent_req_set_callback(req, test_fo_srv_done1, test_ctx); ++ ++ ret = test_ev_loop(test_ctx->ctx); ++ assert_int_equal(ret, ERR_OK); ++} ++ ++static void test_fo_srv_done1(struct tevent_req *req) ++{ ++ struct test_fo_srv_ctx *test_ctx = \ ++ tevent_req_callback_data(req, struct test_fo_srv_ctx); ++ struct fo_server *srv; ++ errno_t ret; ++ ++ ret = fo_resolve_service_recv(req, &srv); ++ talloc_zfree(req); ++ assert_int_equal(ret, ERR_OK); ++ ++ /* ldap1.sssd.com has lower priority, it must always be first */ ++ check_server(srv, 389, "ldap1.sssd.com"); ++ ++ /* Mark the server as working and request the service again. The same server ++ * must be returned */ ++ fo_set_server_status(srv, SERVER_WORKING); ++ ++ req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev, ++ test_ctx->resolv, test_ctx->fo_ctx, ++ test_ctx->fo_svc); ++ assert_non_null(req); ++ tevent_req_set_callback(req, test_fo_srv_done2, test_ctx); ++} ++ ++static void test_fo_srv_done2(struct tevent_req *req) ++{ ++ struct test_fo_srv_ctx *test_ctx = \ ++ tevent_req_callback_data(req, struct test_fo_srv_ctx); ++ struct fo_server *srv; ++ errno_t ret; ++ ++ ret = fo_resolve_service_recv(req, &srv); ++ talloc_zfree(req); ++ assert_int_equal(ret, ERR_OK); ++ ++ /* Must be ldap1 again */ ++ check_server(srv, 389, "ldap1.sssd.com"); ++ ++ /* Mark it at wrong, next lookup should yield ldap2 */ ++ fo_set_server_status(srv, SERVER_NOT_WORKING); ++ ++ req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev, ++ test_ctx->resolv, test_ctx->fo_ctx, ++ test_ctx->fo_svc); ++ assert_non_null(req); ++ tevent_req_set_callback(req, test_fo_srv_done3, test_ctx); ++} ++ ++static void test_fo_srv_done3(struct tevent_req *req) ++{ ++ struct test_fo_srv_ctx *test_ctx = \ ++ tevent_req_callback_data(req, struct test_fo_srv_ctx); ++ struct fo_server *srv; ++ errno_t ret; ++ ++ ret = fo_resolve_service_recv(req, &srv); ++ talloc_zfree(req); ++ assert_int_equal(ret, ERR_OK); ++ ++ /* Must be ldap2 now */ ++ check_server(srv, 389, "ldap2.sssd.com"); ++ ++ /* Mark is at wrong, next lookup must reach the end of the server list */ ++ fo_set_server_status(srv, SERVER_NOT_WORKING); ++ ++ req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev, ++ test_ctx->resolv, test_ctx->fo_ctx, ++ test_ctx->fo_svc); ++ assert_non_null(req); ++ tevent_req_set_callback(req, test_fo_srv_done4, test_ctx); ++} ++ ++static void test_fo_srv_done4(struct tevent_req *req) ++{ ++ struct test_fo_srv_ctx *test_ctx = \ ++ tevent_req_callback_data(req, struct test_fo_srv_ctx); ++ struct fo_server *srv; ++ errno_t ret; ++ ++ ret = fo_resolve_service_recv(req, &srv); ++ talloc_zfree(req); ++ /* No servers are left..*/ ++ assert_int_equal(ret, ENOENT); ++ ++ test_ctx->ctx->error = ERR_OK; ++ test_ctx->ctx->done = true; ++} ++ ++/* Make sure that two queries more than TTL seconds apart resolve ++ * into two different lists ++ */ ++static void test_fo_srv_before(struct tevent_req *req); ++static void test_fo_srv_after(struct tevent_req *req); ++ ++void test_fo_srv_ttl_change(void **state) ++{ ++ errno_t ret; ++ struct tevent_req *req; ++ struct test_fo_srv_ctx *test_ctx = ++ talloc_get_type(*state, struct test_fo_srv_ctx); ++ struct ares_srv_reply *s1; ++ struct ares_srv_reply *s2; ++ char *dns_domain; ++ ++ s1 = talloc_zero(test_ctx, struct ares_srv_reply); ++ assert_non_null(s1); ++ s1->host = talloc_strdup(s1, "ldap1.sssd.com"); ++ assert_non_null(s1->host); ++ s1->weight = 100; ++ s1->priority = 1; ++ s1->port = 389; ++ ++ s2 = talloc_zero(test_ctx, struct ares_srv_reply); ++ assert_non_null(s2); ++ s2->host = talloc_strdup(s2, "ldap2.sssd.com"); ++ assert_non_null(s2->host); ++ s2->weight = 100; ++ s2->priority = 2; ++ s2->port = 389; ++ ++ s1->next = s2; ++ ++ dns_domain = talloc_strdup(test_ctx, "sssd.com"); ++ assert_non_null(dns_domain); ++ ++ mock_srv_results(s1, TEST_SRV_SHORT_TTL, dns_domain); ++ ++ ret = fo_add_srv_server(test_ctx->fo_svc, "_ldap", "sssd.com", ++ "sssd.local", "tcp", test_ctx); ++ assert_int_equal(ret, ERR_OK); ++ ++ ret = fo_add_server(test_ctx->fo_svc, "ldap1.sssd.com", ++ 389, (void *) discard_const("ldap://ldap1.sssd.com"), ++ true); ++ assert_int_equal(ret, ERR_OK); ++ ++ req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev, ++ test_ctx->resolv, test_ctx->fo_ctx, ++ test_ctx->fo_svc); ++ assert_non_null(req); ++ tevent_req_set_callback(req, test_fo_srv_before, test_ctx); ++ ++ ret = test_ev_loop(test_ctx->ctx); ++ assert_int_equal(ret, ERR_OK); ++} ++ ++static void test_fo_srv_before(struct tevent_req *req) ++{ ++ struct test_fo_srv_ctx *test_ctx = \ ++ tevent_req_callback_data(req, struct test_fo_srv_ctx); ++ struct fo_server *srv; ++ struct ares_srv_reply *s1; ++ struct ares_srv_reply *s2; ++ char *dns_domain; ++ errno_t ret; ++ ++ ret = fo_resolve_service_recv(req, &srv); ++ talloc_zfree(req); ++ assert_int_equal(ret, ERR_OK); ++ ++ DEBUG(SSSDBG_TRACE_FUNC, "Before TTL change\n"); ++ ++ check_server(srv, 389, "ldap1.sssd.com"); ++ fo_set_server_status(srv, SERVER_WORKING); ++ ++ /* Simulate changing the DNS environment. Change the host names */ ++ s1 = talloc_zero(test_ctx, struct ares_srv_reply); ++ assert_non_null(s1); ++ s1->host = talloc_strdup(s1, "ldap2.sssd.com"); ++ assert_non_null(s1->host); ++ s1->weight = 100; ++ s1->priority = 2; ++ s1->port = 389; ++ ++ s2 = talloc_zero(test_ctx, struct ares_srv_reply); ++ assert_non_null(s2); ++ s2->host = talloc_strdup(s2, "ldap3.sssd.com"); ++ assert_non_null(s2->host); ++ s2->weight = 100; ++ s2->priority = 1; ++ s2->port = 389; ++ ++ s1->next = s2; ++ ++ dns_domain = talloc_strdup(test_ctx, "sssd.com"); ++ assert_non_null(dns_domain); ++ ++ mock_srv_results(s1, TEST_SRV_SHORT_TTL, dns_domain); ++ sleep(TEST_SRV_SHORT_TTL + 1); ++ ++ req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev, ++ test_ctx->resolv, test_ctx->fo_ctx, ++ test_ctx->fo_svc); ++ assert_non_null(req); ++ tevent_req_set_callback(req, test_fo_srv_after, test_ctx); ++} ++ ++static void test_fo_srv_after(struct tevent_req *req) ++{ ++ struct test_fo_srv_ctx *test_ctx = \ ++ tevent_req_callback_data(req, struct test_fo_srv_ctx); ++ struct fo_server *srv; ++ errno_t ret; ++ ++ ret = fo_resolve_service_recv(req, &srv); ++ talloc_zfree(req); ++ assert_int_equal(ret, ERR_OK); ++ ++ /* Must be a different server now */ ++ check_server(srv, 389, "ldap3.sssd.com"); ++ ++ test_ctx->ctx->error = ERR_OK; ++ test_ctx->ctx->done = true; ++} ++ ++int main(int argc, const char *argv[]) ++{ ++ int rv; ++ poptContext pc; ++ int opt; ++ struct poptOption long_options[] = { ++ POPT_AUTOHELP ++ SSSD_DEBUG_OPTS ++ POPT_TABLEEND ++ }; ++ ++ const UnitTest tests[] = { ++ unit_test_setup_teardown(test_fo_srv, ++ test_fo_srv_setup, ++ test_fo_srv_teardown), ++ unit_test_setup_teardown(test_fo_srv_ttl_change, ++ test_fo_srv_setup, ++ test_fo_srv_teardown), ++ }; ++ ++ /* Set debug level to invalid value so we can deside if -d 0 was used. */ ++ debug_level = SSSDBG_INVALID; ++ ++ pc = poptGetContext(argv[0], argc, argv, long_options, 0); ++ while((opt = poptGetNextOpt(pc)) != -1) { ++ switch(opt) { ++ default: ++ fprintf(stderr, "\nInvalid option %s: %s\n\n", ++ poptBadOption(pc, 0), poptStrerror(opt)); ++ poptPrintUsage(pc, stderr, 0); ++ return 1; ++ } ++ } ++ poptFreeContext(pc); ++ ++ DEBUG_CLI_INIT(debug_level); ++ ++ /* Even though normally the tests should clean up after themselves ++ * they might not after a failed run. Remove the old db to be sure */ ++ tests_set_cwd(); ++ ++ rv = run_tests(tests); ++ return rv; ++} +-- +2.4.0 + diff --git a/0007-SDAP-refactor-pwexpire-policy.patch b/0007-SDAP-refactor-pwexpire-policy.patch new file mode 100644 index 0000000..5392a26 --- /dev/null +++ b/0007-SDAP-refactor-pwexpire-policy.patch @@ -0,0 +1,204 @@ +From 8b353dd2b90b7ab222acdea726ab7e8681752237 Mon Sep 17 00:00:00 2001 +From: Pavel Reichl +Date: Mon, 16 Feb 2015 18:56:25 -0500 +Subject: [PATCH 07/99] SDAP: refactor pwexpire policy + +Move part of pwexpire policy code to a separate function. + +Relates to: +https://fedorahosted.org/sssd/ticket/2167 + +Reviewed-by: Sumit Bose +(cherry picked from commit cdaa29d2c5724a4c72bfa0f42284ccfac3d5a464) +--- + Makefile.am | 1 + + src/providers/ldap/ldap_auth.c | 76 ++++++++++++++++++++++++------------------ + src/providers/ldap/ldap_auth.h | 46 +++++++++++++++++++++++++ + 3 files changed, 91 insertions(+), 32 deletions(-) + create mode 100644 src/providers/ldap/ldap_auth.h + +diff --git a/Makefile.am b/Makefile.am +index 254930387aa9dda981c1539616e2912447c2b1d6..9fe60d656403e09595ced5f623f381afbd3b2a43 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -563,6 +563,7 @@ dist_noinst_HEADERS = \ + src/providers/ldap/sdap_autofs.h \ + src/providers/ldap/sdap_id_op.h \ + src/providers/ldap/ldap_opts.h \ ++ src/providers/ldap/ldap_auth.h \ + src/providers/ldap/sdap_range.h \ + src/providers/ldap/sdap_users.h \ + src/providers/ldap/sdap_dyndns.h \ +diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c +index 5a40c1359f138c42eb915e873fe21a50ab038e81..4035aaf58c23291eb8115ef320758ba7666ed4e2 100644 +--- a/src/providers/ldap/ldap_auth.c ++++ b/src/providers/ldap/ldap_auth.c +@@ -46,16 +46,10 @@ + #include "providers/ldap/ldap_common.h" + #include "providers/ldap/sdap_async.h" + #include "providers/ldap/sdap_async_private.h" ++#include "providers/ldap/ldap_auth.h" + + #define LDAP_PWEXPIRE_WARNING_TIME 0 + +-enum pwexpire { +- PWEXPIRE_NONE = 0, +- PWEXPIRE_LDAP_PASSWORD_POLICY, +- PWEXPIRE_KERBEROS, +- PWEXPIRE_SHADOW +-}; +- + static errno_t add_expired_warning(struct pam_data *pd, long exp_time) + { + int ret; +@@ -248,10 +242,41 @@ done: + return ret; + } + +-static errno_t find_password_expiration_attributes(TALLOC_CTX *mem_ctx, +- const struct ldb_message *msg, +- struct dp_option *opts, +- enum pwexpire *type, void **data) ++errno_t check_pwexpire_policy(enum pwexpire pw_expire_type, ++ void *pw_expire_data, ++ struct pam_data *pd, ++ int pwd_expiration_warning) ++{ ++ errno_t ret; ++ ++ switch (pw_expire_type) { ++ case PWEXPIRE_SHADOW: ++ ret = check_pwexpire_shadow(pw_expire_data, time(NULL), pd); ++ break; ++ case PWEXPIRE_KERBEROS: ++ ret = check_pwexpire_kerberos(pw_expire_data, time(NULL), pd, ++ pwd_expiration_warning); ++ break; ++ case PWEXPIRE_LDAP_PASSWORD_POLICY: ++ ret = check_pwexpire_ldap(pd, pw_expire_data, ++ pwd_expiration_warning); ++ break; ++ case PWEXPIRE_NONE: ++ ret = EOK; ++ break; ++ default: ++ DEBUG(SSSDBG_CRIT_FAILURE, "Unknown password expiration type.\n"); ++ ret = EINVAL; ++ } ++ ++ return ret; ++} ++ ++static errno_t ++find_password_expiration_attributes(TALLOC_CTX *mem_ctx, ++ const struct ldb_message *msg, ++ struct dp_option *opts, ++ enum pwexpire *type, void **data) + { + const char *mark; + const char *val; +@@ -492,7 +517,7 @@ static int get_user_dn_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, + return EOK; + } + +-static int get_user_dn(TALLOC_CTX *memctx, ++int get_user_dn(TALLOC_CTX *memctx, + struct sss_domain_info *domain, + struct sdap_options *opts, + const char *username, +@@ -998,7 +1023,7 @@ static void sdap_auth4chpass_done(struct tevent_req *req) + case PWEXPIRE_NONE: + break; + default: +- DEBUG(SSSDBG_CRIT_FAILURE, "Unknow pasword expiration type.\n"); ++ DEBUG(SSSDBG_CRIT_FAILURE, "Unknown password expiration type.\n"); + state->pd->pam_status = PAM_SYSTEM_ERR; + goto done; + } +@@ -1247,25 +1272,12 @@ static void sdap_pam_auth_done(struct tevent_req *req) + talloc_zfree(req); + + if (ret == EOK) { +- switch (pw_expire_type) { +- case PWEXPIRE_SHADOW: +- ret = check_pwexpire_shadow(pw_expire_data, time(NULL), state->pd); +- break; +- case PWEXPIRE_KERBEROS: +- ret = check_pwexpire_kerberos(pw_expire_data, time(NULL), +- state->pd, +- be_ctx->domain->pwd_expiration_warning); +- break; +- case PWEXPIRE_LDAP_PASSWORD_POLICY: +- ret = check_pwexpire_ldap(state->pd, pw_expire_data, +- be_ctx->domain->pwd_expiration_warning); +- break; +- case PWEXPIRE_NONE: +- break; +- default: +- DEBUG(SSSDBG_CRIT_FAILURE, "Unknow pasword expiration type.\n"); +- state->pd->pam_status = PAM_SYSTEM_ERR; +- goto done; ++ ret = check_pwexpire_policy(pw_expire_type, pw_expire_data, state->pd, ++ be_ctx->domain->pwd_expiration_warning); ++ if (ret == EINVAL) { ++ /* Unknown password expiration type. */ ++ state->pd->pam_status = PAM_SYSTEM_ERR; ++ goto done; + } + } + +diff --git a/src/providers/ldap/ldap_auth.h b/src/providers/ldap/ldap_auth.h +new file mode 100644 +index 0000000000000000000000000000000000000000..5fbddd7087dc65ab8bd1df5fb57492d2fc26d0bb +--- /dev/null ++++ b/src/providers/ldap/ldap_auth.h +@@ -0,0 +1,46 @@ ++/* ++ SSSD ++ ++ Copyright (C) Pavel Reichl 2015 ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . ++*/ ++ ++#ifndef _LDAP_AUTH_H_ ++#define _LDAP_AUTH_H_ ++ ++#include "config.h" ++ ++enum pwexpire { ++ PWEXPIRE_NONE = 0, ++ PWEXPIRE_LDAP_PASSWORD_POLICY, ++ PWEXPIRE_KERBEROS, ++ PWEXPIRE_SHADOW ++}; ++ ++int get_user_dn(TALLOC_CTX *memctx, ++ struct sss_domain_info *domain, ++ struct sdap_options *opts, ++ const char *username, ++ char **user_dn, ++ enum pwexpire *user_pw_expire_type, ++ void **user_pw_expire_data); ++ ++errno_t check_pwexpire_policy(enum pwexpire pw_expire_type, ++ void *pw_expire_data, ++ struct pam_data *pd, ++ errno_t checkb); ++ ++ ++#endif /* _LDAP_AUTH_H_ */ +-- +2.4.0 + diff --git a/0008-SDAP-enable-change-phase-of-pw-expire-policy-check.patch b/0008-SDAP-enable-change-phase-of-pw-expire-policy-check.patch new file mode 100644 index 0000000..a2a0913 --- /dev/null +++ b/0008-SDAP-enable-change-phase-of-pw-expire-policy-check.patch @@ -0,0 +1,258 @@ +From d3f82e944dc5dab3812700a245deec4aa3245b21 Mon Sep 17 00:00:00 2001 +From: Pavel Reichl +Date: Wed, 18 Feb 2015 01:03:40 -0500 +Subject: [PATCH 08/99] SDAP: enable change phase of pw expire policy check + +Implement new option which does checking password expiration policy +in accounting phase. + +This allows SSSD to issue shadow expiration warning even if alternate +authentication method is used. + +Resolves: +https://fedorahosted.org/sssd/ticket/2167 + +Reviewed-by: Sumit Bose +(cherry picked from commit c9b0071bfcb8eb8c71e40248de46d23aceecc0f3) +--- + src/man/sssd-ldap.5.xml | 27 +++++++++++++++++ + src/providers/ldap/ldap_access.c | 12 ++++++++ + src/providers/ldap/ldap_auth.c | 1 + + src/providers/ldap/ldap_init.c | 9 ++++++ + src/providers/ldap/sdap_access.c | 62 +++++++++++++++++++++++++++++++++++++++- + src/providers/ldap/sdap_access.h | 6 ++++ + src/util/util_errors.h | 3 ++ + 7 files changed, 119 insertions(+), 1 deletion(-) + +diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml +index 5b36f69a679a1362290d8fea1f4c8fc29cc548d8..9fbc47487f3513a84e14b70ad85e32d08d1b9c6f 100644 +--- a/src/man/sssd-ldap.5.xml ++++ b/src/man/sssd-ldap.5.xml +@@ -1959,6 +1959,33 @@ ldap_access_filter = (employeeType=admin) + ldap_account_expire_policy + + ++ pwd_expire_policy_reject, ++ pwd_expire_policy_warn, ++ pwd_expire_policy_renew: ++ ++ These options are useful if users are interested ++ in being warned that password is about to expire ++ and authentication is based on using a different ++ method than passwords - for example SSH keys. ++ ++ ++ The difference between these options is the action ++ taken if user password is expired: ++ pwd_expire_policy_reject - user is denied to log in, ++ pwd_expire_policy_warn - user is still able to log in, ++ pwd_expire_policy_renew - user is prompted to change ++ his password immediately. ++ ++ ++ Note If user password is expired no explicit message ++ is prompted by SSSD. ++ ++ ++ Please note that 'access_provider = ldap' must ++ be set for this feature to work. Also 'ldap_pwd_policy' ++ must be set to an appropriate password policy. ++ ++ + authorized_service: use + the authorizedService attribute to determine + access +diff --git a/src/providers/ldap/ldap_access.c b/src/providers/ldap/ldap_access.c +index 1913cd9a92342cc985d5c098f224c4fe8c58d465..7ebdb20c06c5bb5f588071761c201ad566944d7e 100644 +--- a/src/providers/ldap/ldap_access.c ++++ b/src/providers/ldap/ldap_access.c +@@ -96,6 +96,18 @@ static void sdap_access_done(struct tevent_req *req) + case ERR_ACCOUNT_EXPIRED: + pam_status = PAM_ACCT_EXPIRED; + break; ++ case ERR_PASSWORD_EXPIRED: ++ pam_status = PAM_PERM_DENIED; ++ break; ++ case ERR_PASSWORD_EXPIRED_REJECT: ++ pam_status = PAM_PERM_DENIED; ++ break; ++ case ERR_PASSWORD_EXPIRED_WARN: ++ pam_status = PAM_SUCCESS; ++ break; ++ case ERR_PASSWORD_EXPIRED_RENEW: ++ pam_status = PAM_NEW_AUTHTOK_REQD; ++ break; + default: + DEBUG(SSSDBG_CRIT_FAILURE, "Error retrieving access check result.\n"); + pam_status = PAM_SYSTEM_ERR; +diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c +index 4035aaf58c23291eb8115ef320758ba7666ed4e2..bdcc4505dc82cf3ca4bec9ce71ec6a9c28dd54e8 100644 +--- a/src/providers/ldap/ldap_auth.c ++++ b/src/providers/ldap/ldap_auth.c +@@ -47,6 +47,7 @@ + #include "providers/ldap/sdap_async.h" + #include "providers/ldap/sdap_async_private.h" + #include "providers/ldap/ldap_auth.h" ++#include "providers/ldap/sdap_access.h" + + #define LDAP_PWEXPIRE_WARNING_TIME 0 + +diff --git a/src/providers/ldap/ldap_init.c b/src/providers/ldap/ldap_init.c +index 44333a9a3a45de16aaaf83fecaea4817cebc90d4..8d5619779d38c0df5ec4761b4409c71e8976686c 100644 +--- a/src/providers/ldap/ldap_init.c ++++ b/src/providers/ldap/ldap_init.c +@@ -423,6 +423,15 @@ int sssm_ldap_access_init(struct be_ctx *bectx, + access_ctx->access_rule[c] = LDAP_ACCESS_HOST; + } else if (strcasecmp(order_list[c], LDAP_ACCESS_LOCK_NAME) == 0) { + access_ctx->access_rule[c] = LDAP_ACCESS_LOCKOUT; ++ } else if (strcasecmp(order_list[c], ++ LDAP_ACCESS_EXPIRE_POLICY_REJECT_NAME) == 0) { ++ access_ctx->access_rule[c] = LDAP_ACCESS_EXPIRE_POLICY_REJECT; ++ } else if (strcasecmp(order_list[c], ++ LDAP_ACCESS_EXPIRE_POLICY_WARN_NAME) == 0) { ++ access_ctx->access_rule[c] = LDAP_ACCESS_EXPIRE_POLICY_WARN; ++ } else if (strcasecmp(order_list[c], ++ LDAP_ACCESS_EXPIRE_POLICY_RENEW_NAME) == 0) { ++ access_ctx->access_rule[c] = LDAP_ACCESS_EXPIRE_POLICY_RENEW; + } else { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unexpected access rule name [%s].\n", order_list[c]); +diff --git a/src/providers/ldap/sdap_access.c b/src/providers/ldap/sdap_access.c +index a6c882cae634f080b200fe75f51867e39192bcd9..dd2fb6b92bc83ee36fc396d26e3d0d7e78021d71 100644 +--- a/src/providers/ldap/sdap_access.c ++++ b/src/providers/ldap/sdap_access.c +@@ -39,10 +39,16 @@ + #include "providers/ldap/sdap_async.h" + #include "providers/data_provider.h" + #include "providers/dp_backend.h" ++#include "providers/ldap/ldap_auth.h" + + #define PERMANENTLY_LOCKED_ACCOUNT "000001010000Z" + #define MALFORMED_FILTER "Malformed access control filter [%s]\n" + ++static errno_t perform_pwexpire_policy(TALLOC_CTX *mem_ctx, ++ struct sss_domain_info *domain, ++ struct pam_data *pd, ++ struct sdap_options *opts); ++ + static errno_t sdap_save_user_cache_bool(struct sss_domain_info *domain, + const char *username, + const char *attr_name, +@@ -237,6 +243,30 @@ static errno_t sdap_access_check_next_rule(struct sdap_access_req_ctx *state, + state->pd, state->user_entry); + break; + ++ case LDAP_ACCESS_EXPIRE_POLICY_REJECT: ++ ret = perform_pwexpire_policy(state, state->domain, state->pd, ++ state->access_ctx->id_ctx->opts); ++ if (ret == ERR_PASSWORD_EXPIRED) { ++ ret = ERR_PASSWORD_EXPIRED_REJECT; ++ } ++ break; ++ ++ case LDAP_ACCESS_EXPIRE_POLICY_WARN: ++ ret = perform_pwexpire_policy(state, state->domain, state->pd, ++ state->access_ctx->id_ctx->opts); ++ if (ret == ERR_PASSWORD_EXPIRED) { ++ ret = ERR_PASSWORD_EXPIRED_WARN; ++ } ++ break; ++ ++ case LDAP_ACCESS_EXPIRE_POLICY_RENEW: ++ ret = perform_pwexpire_policy(state, state->domain, state->pd, ++ state->access_ctx->id_ctx->opts); ++ if (ret == ERR_PASSWORD_EXPIRED) { ++ ret = ERR_PASSWORD_EXPIRED_RENEW; ++ } ++ break; ++ + case LDAP_ACCESS_SERVICE: + ret = sdap_access_service( state->pd, state->user_entry); + break; +@@ -651,7 +681,6 @@ static errno_t sdap_account_expired_nds(struct pam_data *pd, + return EOK; + } + +- + static errno_t sdap_account_expired(struct sdap_access_ctx *access_ctx, + struct pam_data *pd, + struct ldb_message *user_entry) +@@ -702,6 +731,37 @@ static errno_t sdap_account_expired(struct sdap_access_ctx *access_ctx, + return ret; + } + ++static errno_t perform_pwexpire_policy(TALLOC_CTX *mem_ctx, ++ struct sss_domain_info *domain, ++ struct pam_data *pd, ++ struct sdap_options *opts) ++{ ++ enum pwexpire pw_expire_type; ++ void *pw_expire_data; ++ errno_t ret; ++ char *dn; ++ ++ ret = get_user_dn(mem_ctx, domain, opts, pd->user, &dn, &pw_expire_type, ++ &pw_expire_data); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "get_user_dn returned %d:[%s].\n", ++ ret, sss_strerror(ret)); ++ goto done; ++ } ++ ++ ret = check_pwexpire_policy(pw_expire_type, pw_expire_data, pd, ++ domain->pwd_expiration_warning); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "check_pwexpire_policy returned %d:[%s].\n", ++ ret, sss_strerror(ret)); ++ goto done; ++ } ++ ++done: ++ return ret; ++} ++ + struct sdap_access_filter_req_ctx { + const char *username; + const char *filter; +diff --git a/src/providers/ldap/sdap_access.h b/src/providers/ldap/sdap_access.h +index f085e619961198b887d65ed5ee0bc5cdd90d1b20..a8c6639109bd7e6dcb325a5e8d080f743ec56d97 100644 +--- a/src/providers/ldap/sdap_access.h ++++ b/src/providers/ldap/sdap_access.h +@@ -39,6 +39,9 @@ + + #define LDAP_ACCESS_FILTER_NAME "filter" + #define LDAP_ACCESS_EXPIRE_NAME "expire" ++#define LDAP_ACCESS_EXPIRE_POLICY_REJECT_NAME "pwd_expire_policy_reject" ++#define LDAP_ACCESS_EXPIRE_POLICY_WARN_NAME "pwd_expire_policy_warn" ++#define LDAP_ACCESS_EXPIRE_POLICY_RENEW_NAME "pwd_expire_policy_renew" + #define LDAP_ACCESS_SERVICE_NAME "authorized_service" + #define LDAP_ACCESS_HOST_NAME "host" + #define LDAP_ACCESS_LOCK_NAME "lockout" +@@ -57,6 +60,9 @@ enum ldap_access_rule { + LDAP_ACCESS_SERVICE, + LDAP_ACCESS_HOST, + LDAP_ACCESS_LOCKOUT, ++ LDAP_ACCESS_EXPIRE_POLICY_REJECT, ++ LDAP_ACCESS_EXPIRE_POLICY_WARN, ++ LDAP_ACCESS_EXPIRE_POLICY_RENEW, + LDAP_ACCESS_LAST + }; + +diff --git a/src/util/util_errors.h b/src/util/util_errors.h +index 39455dc8adfe8784bd3f06382d701b7f9e97f004..97e210e31dc6501860d1490966369a0d3ebe2cc2 100644 +--- a/src/util/util_errors.h ++++ b/src/util/util_errors.h +@@ -64,6 +64,9 @@ enum sssd_errors { + ERR_NETWORK_IO, + ERR_ACCOUNT_EXPIRED, + ERR_PASSWORD_EXPIRED, ++ ERR_PASSWORD_EXPIRED_REJECT, ++ ERR_PASSWORD_EXPIRED_WARN, ++ ERR_PASSWORD_EXPIRED_RENEW, + ERR_ACCESS_DENIED, + ERR_SRV_NOT_FOUND, + ERR_SRV_LOOKUP_ERROR, +-- +2.4.0 + diff --git a/0009-LDAP-unlink-ccname_file_dummy-if-there-is-an-error.patch b/0009-LDAP-unlink-ccname_file_dummy-if-there-is-an-error.patch new file mode 100644 index 0000000..db178f3 --- /dev/null +++ b/0009-LDAP-unlink-ccname_file_dummy-if-there-is-an-error.patch @@ -0,0 +1,53 @@ +From 0b5036e4c652e6983a3352c045c8701d6573587b Mon Sep 17 00:00:00 2001 +From: Daniel Hjorth +Date: Wed, 25 Feb 2015 13:07:35 -0700 +Subject: [PATCH 09/99] LDAP: unlink ccname_file_dummy if there is an error + +https://fedorahosted.org/sssd/ticket/2592 + +If there is an error after ccname_file_dummy is created but before it is +renamed then the file isn't removed. This can cause a lot of files to be +created and take up inodes in a filesystem. + +Reviewed-by: Jakub Hrozek +Reviewed-by: Sumit Bose +(cherry picked from commit 2b20ff2e33ad3993a9cad910c4b4b828513613df) +--- + src/providers/ldap/ldap_child.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/src/providers/ldap/ldap_child.c b/src/providers/ldap/ldap_child.c +index e9aebf5a6319b5d848aadfb27061099fc153a7f6..774cff9c2d942b589e69933d3f201f6245fa904d 100644 +--- a/src/providers/ldap/ldap_child.c ++++ b/src/providers/ldap/ldap_child.c +@@ -489,16 +489,26 @@ static krb5_error_code ldap_child_get_tgt_sync(TALLOC_CTX *memctx, + "rename failed [%d][%s].\n", ret, strerror(ret)); + goto done; + } ++ ccname_file_dummy = NULL; + + krberr = 0; + *ccname_out = talloc_steal(memctx, ccname); + *expire_time_out = my_creds.times.endtime - kdc_time_offset; + + done: +- talloc_free(tmp_ctx); + if (krberr != 0) KRB5_SYSLOG(krberr); + if (keytab) krb5_kt_close(context, keytab); + if (context) krb5_free_context(context); ++ if (ccname_file_dummy) { ++ DEBUG(SSSDBG_TRACE_INTERNAL, "Unlinking [%s]\n", ccname_file_dummy); ++ ret = unlink(ccname_file_dummy); ++ if (ret == -1) { ++ ret = errno; ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "Unlink failed [%d][%s].\n", ret, strerror(ret)); ++ } ++ } ++ talloc_free(tmp_ctx); + return krberr; + } + +-- +2.4.0 + diff --git a/0016-selinux-Delete-existing-user-mapping-on-empty-defaul.patch b/0010-selinux-Delete-existing-user-mapping-on-empty-defaul.patch similarity index 95% rename from 0016-selinux-Delete-existing-user-mapping-on-empty-defaul.patch rename to 0010-selinux-Delete-existing-user-mapping-on-empty-defaul.patch index b1eb32e..cc31981 100644 --- a/0016-selinux-Delete-existing-user-mapping-on-empty-defaul.patch +++ b/0010-selinux-Delete-existing-user-mapping-on-empty-defaul.patch @@ -1,7 +1,7 @@ -From e991859590d4b598193f192674fca0ded1914bae Mon Sep 17 00:00:00 2001 +From 90efb3c2a48146d7b6cc81fe8422e9024144402a Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Fri, 13 Feb 2015 17:57:35 +0100 -Subject: [PATCH 16/17] selinux: Delete existing user mapping on empty default +Subject: [PATCH 10/99] selinux: Delete existing user mapping on empty default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -77,5 +77,5 @@ index 63d4b929786d4b8cc0d40f0c65009673c7309094..3756557a5e28624e6437e805ca8a387d return ret; } -- -2.3.3 +2.4.0 diff --git a/0011-ldap_child-initialized-ccname_file_dummy.patch b/0011-ldap_child-initialized-ccname_file_dummy.patch new file mode 100644 index 0000000..eb4c4d5 --- /dev/null +++ b/0011-ldap_child-initialized-ccname_file_dummy.patch @@ -0,0 +1,33 @@ +From 21c627fbbbb64ec23460758b382ffc863c14e61f Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 6 Mar 2015 11:27:36 +0100 +Subject: [PATCH 11/99] ldap_child: initialized ccname_file_dummy + +ccname_file_dummy is used in the done-block which is called before +ccname_file_dummy is set to a value. This patch initializes +ccname_file_dummy to NULL. + +Related to https://fedorahosted.org/sssd/ticket/2592 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit cc0f9a541c5ecdad750a86b2de9baa1f07403e9e) +--- + src/providers/ldap/ldap_child.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/providers/ldap/ldap_child.c b/src/providers/ldap/ldap_child.c +index 774cff9c2d942b589e69933d3f201f6245fa904d..8f034affa48095b6e512c866f8a3c33465e5c595 100644 +--- a/src/providers/ldap/ldap_child.c ++++ b/src/providers/ldap/ldap_child.c +@@ -272,7 +272,7 @@ static krb5_error_code ldap_child_get_tgt_sync(TALLOC_CTX *memctx, + int kdc_time_offset_usec; + int ret; + TALLOC_CTX *tmp_ctx; +- char *ccname_file_dummy; ++ char *ccname_file_dummy = NULL; + char *ccname_file; + mode_t old_umask; + +-- +2.4.0 + diff --git a/0012-UTIL-convert-GeneralizedTime-to-unix-time.patch b/0012-UTIL-convert-GeneralizedTime-to-unix-time.patch new file mode 100644 index 0000000..4a2a595 --- /dev/null +++ b/0012-UTIL-convert-GeneralizedTime-to-unix-time.patch @@ -0,0 +1,244 @@ +From 3cace03ac7a2c4ff6d3469a3d3128c79a1882e43 Mon Sep 17 00:00:00 2001 +From: Pavel Reichl +Date: Tue, 20 Jan 2015 16:27:41 -0500 +Subject: [PATCH 12/99] UTIL: convert GeneralizedTime to unix time + +New utility function *sss_utc_to_time_t* to convert GeneralizedTime to +unix time. + +Reviewed-by: Jakub Hrozek +--- + Makefile.am | 9 +++++--- + src/tests/util-tests.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++ + src/util/util.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++ + src/util/util.h | 3 +++ + src/util/util_errors.c | 1 + + src/util/util_errors.h | 1 + + 6 files changed, 121 insertions(+), 3 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index 9fe60d656403e09595ced5f623f381afbd3b2a43..210ef6ffe6ebc4772fc80bed25f2a31208c020f3 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -1540,15 +1540,18 @@ simple_access_tests_LDADD = \ + libsss_test_common.la + + util_tests_SOURCES = \ +- src/tests/util-tests.c ++ src/tests/util-tests.c \ ++ $(NULL) + util_tests_CFLAGS = \ + $(AM_CFLAGS) \ +- $(CHECK_CFLAGS) ++ $(CHECK_CFLAGS) \ ++ $(NULL) + util_tests_LDADD = \ + $(SSSD_LIBS) \ + $(CHECK_LIBS) \ + $(SSSD_INTERNAL_LTLIBS) \ +- libsss_test_common.la ++ libsss_test_common.la \ ++ $(NULL) + + safe_format_tests_SOURCES = \ + src/tests/safe-format-tests.c +diff --git a/src/tests/util-tests.c b/src/tests/util-tests.c +index 08e8b8d263c46618a0cdfb2203684305fa6dddc6..21eb02f14a7225ae9b9de4aa7f958b73f84a066d 100644 +--- a/src/tests/util-tests.c ++++ b/src/tests/util-tests.c +@@ -28,6 +28,8 @@ + #include + #include + #include ++#include ++ + #include "util/util.h" + #include "util/sss_utf8.h" + #include "util/murmurhash3.h" +@@ -1000,6 +1002,54 @@ START_TEST(test_known_service) + } + END_TEST + ++static void convert_time_tz(const char* tz) ++{ ++ errno_t ret, ret2; ++ time_t unix_time; ++ const char *orig_tz = NULL; ++ ++ orig_tz = getenv("TZ"); ++ if (orig_tz == NULL) { ++ orig_tz = ""; ++ } ++ ++ if (tz) { ++ ret = setenv("TZ", tz, 1); ++ fail_if(ret == -1); ++ } ++ ++ ret = sss_utc_to_time_t("20140801115742Z", "%Y%m%d%H%M%SZ", &unix_time); ++ ++ /* restore */ ++ if (orig_tz != NULL) { ++ ret2 = setenv("TZ", orig_tz, 1); ++ fail_if(ret2 == -1); ++ } ++ fail_unless(ret == EOK && difftime(1406894262, unix_time) == 0); ++} ++ ++START_TEST(test_convert_time) ++{ ++ const char *format = "%Y%m%d%H%M%SZ"; ++ time_t unix_time; ++ errno_t ret; ++ ++ ret = sss_utc_to_time_t("20150127133540P", format, &unix_time); ++ fail_unless(ret == ERR_TIMESPEC_NOT_SUPPORTED); ++ ret = sss_utc_to_time_t("0Z", format, &unix_time); ++ fail_unless(ret == EINVAL); ++ ret = sss_utc_to_time_t("000001010000Z", format, &unix_time); ++ fail_unless(ret == EINVAL); ++ ++ /* test that results are still same no matter what timezone is set */ ++ convert_time_tz(NULL); ++ ++ convert_time_tz("GST-1"); ++ ++ convert_time_tz("GST-2"); ++} ++END_TEST ++ + Suite *util_suite(void) + { + Suite *s = suite_create("util"); +@@ -1046,10 +1096,17 @@ Suite *util_suite(void) + tcase_add_test(tc_atomicio, test_atomicio_read_exact_sized_file); + tcase_add_test(tc_atomicio, test_atomicio_read_from_empty_file); + ++ TCase *tc_convert_time = tcase_create("convert_time"); ++ tcase_add_checked_fixture(tc_convert_time, ++ ck_leak_check_setup, ++ ck_leak_check_teardown); ++ tcase_add_test(tc_convert_time, test_convert_time); ++ + suite_add_tcase (s, tc_util); + suite_add_tcase (s, tc_utf8); + suite_add_tcase (s, tc_mh3); + suite_add_tcase (s, tc_atomicio); ++ suite_add_tcase (s, tc_convert_time); + + return s; + } +diff --git a/src/util/util.c b/src/util/util.c +index 2acb8604ac0c2bc7b83ee578c7bbead9a7fd44b3..c4d8bf91f89c34b21f272a9f722eabf551aba9be 100644 +--- a/src/util/util.c ++++ b/src/util/util.c +@@ -18,6 +18,7 @@ + along with this program. If not, see . + */ + ++#include "config.h" + #include + #include + #include +@@ -26,6 +27,7 @@ + #include + #include + #include ++#include + + #include "util/util.h" + #include "util/sss_utf8.h" +@@ -880,3 +882,54 @@ done: + + return ret; + } ++ ++/* Convert GeneralizedTime (http://en.wikipedia.org/wiki/GeneralizedTime) ++ * to unix time (seconds since epoch). Use UTC time zone. ++ */ ++errno_t sss_utc_to_time_t(const char *str, const char *format, time_t *_unix_time) ++{ ++ char *end; ++ struct tm tm; ++ size_t len; ++ time_t ut; ++ ++ if (str == NULL) { ++ return EINVAL; ++ } ++ ++ len = strlen(str); ++ if (str[len-1] != 'Z') { ++ DEBUG(SSSDBG_TRACE_INTERNAL, ++ "%s does not seem to be in UTZ time zone.\n", str); ++ return ERR_TIMESPEC_NOT_SUPPORTED; ++ } ++ ++ memset(&tm, 0, sizeof(tm)); ++ ++ end = strptime(str, format, &tm); ++ /* not all characters from format were matched */ ++ if (end == NULL) { ++ DEBUG(SSSDBG_TRACE_INTERNAL, ++ "String [%s] failed to match format [%s].\n", str, format); ++ return EINVAL; ++ } ++ ++ /* str is 'longer' than format */ ++ if (*end != '\0') { ++ DEBUG(SSSDBG_TRACE_INTERNAL, ++ "String [%s] is longer than format [%s].\n", str, format); ++ return EINVAL; ++ } ++ ++ ut = mktime(&tm); ++ if (ut == -1) { ++ DEBUG(SSSDBG_TRACE_INTERNAL, ++ "mktime failed to convert [%s].\n", str); ++ return EINVAL; ++ } ++ ++ tzset(); ++ ut -= timezone; ++ *_unix_time = ut; ++ return EOK; ++} +diff --git a/src/util/util.h b/src/util/util.h +index bf3a9a057aed77e93949370f8651af2631d91432..22a67a55855282441379477236a323362c8bdb4d 100644 +--- a/src/util/util.h ++++ b/src/util/util.h +@@ -636,4 +636,7 @@ int set_seuser(const char *login_name, const char *seuser_name, + const char *mlsrange); + int del_seuser(const char *login_name); + ++/* convert time from generalized form to unix time */ ++errno_t sss_utc_to_time_t(const char *str, const char *format, time_t *unix_time); ++ + #endif /* __SSSD_UTIL_H__ */ +diff --git a/src/util/util_errors.c b/src/util/util_errors.c +index 16d16fc777fc3344db8a3bdfeb3633bd5db48530..bfae5cd189902ed82ba8b7db29e85a309e4bd19c 100644 +--- a/src/util/util_errors.c ++++ b/src/util/util_errors.c +@@ -65,6 +65,7 @@ struct err_string error_to_str[] = { + { "LDAP search returned a referral" }, /* ERR_REFERRAL */ + { "Error setting SELinux user context" }, /* ERR_SELINUX_CONTEXT */ + { "Username format not allowed by re_expression" }, /* ERR_REGEX_NOMATCH */ ++ { "Time specification not supported" }, /* ERR_TIMESPEC_NOT_SUPPORTED */ + }; + + +diff --git a/src/util/util_errors.h b/src/util/util_errors.h +index 97e210e31dc6501860d1490966369a0d3ebe2cc2..069d4b78aa5ed6c756affdacab99c7141b7849e4 100644 +--- a/src/util/util_errors.h ++++ b/src/util/util_errors.h +@@ -90,6 +90,7 @@ enum sssd_errors { + ERR_REFERRAL, + ERR_SELINUX_CONTEXT, + ERR_REGEX_NOMATCH, ++ ERR_TIMESPEC_NOT_SUPPORTED, + ERR_LAST /* ALWAYS LAST */ + }; + +-- +2.4.0 + diff --git a/0013-SDAP-Lock-out-ssh-keys-when-account-naturally-expire.patch b/0013-SDAP-Lock-out-ssh-keys-when-account-naturally-expire.patch new file mode 100644 index 0000000..a583f1e --- /dev/null +++ b/0013-SDAP-Lock-out-ssh-keys-when-account-naturally-expire.patch @@ -0,0 +1,725 @@ +From 8ebc05498460ce28eff012649c892b248c53632f Mon Sep 17 00:00:00 2001 +From: Pavel Reichl +Date: Tue, 20 Jan 2015 18:34:44 -0500 +Subject: [PATCH 13/99] SDAP: Lock out ssh keys when account naturally expires + +Resolves: +https://fedorahosted.org/sssd/ticket/2534 + +Reviewed-by: Jakub Hrozek +--- + Makefile.am | 13 +- + src/man/sssd-ldap.5.xml | 14 ++ + src/providers/ldap/ldap_init.c | 2 + + src/providers/ldap/sdap_access.c | 316 ++++++++++++++++++++++++++++----------- + src/providers/ldap/sdap_access.h | 3 + + 5 files changed, 254 insertions(+), 94 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index 210ef6ffe6ebc4772fc80bed25f2a31208c020f3..5099043549a46c15a9d7f6a581c864cbbe3137b5 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -2409,16 +2409,21 @@ libsss_ldap_common_la_SOURCES = \ + src/providers/ldap/sdap_domain.c \ + src/providers/ldap/sdap.c \ + src/util/user_info_msg.c \ +- src/util/sss_ldap.c ++ src/util/sss_ldap.c \ ++ $(NULL) + libsss_ldap_common_la_CFLAGS = \ +- $(KRB5_CFLAGS) ++ $(KRB5_CFLAGS) \ ++ $(NULL) + libsss_ldap_common_la_LIBADD = \ + $(OPENLDAP_LIBS) \ + $(KRB5_LIBS) \ + libsss_krb5_common.la \ +- libsss_idmap.la ++ libsss_idmap.la \ ++ libsss_util.la \ ++ $(NULL) + libsss_ldap_common_la_LDFLAGS = \ +- -avoid-version ++ -avoid-version \ ++ $(NULL) + + if BUILD_SUDO + libsss_ldap_common_la_SOURCES += \ +diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml +index 9fbc47487f3513a84e14b70ad85e32d08d1b9c6f..00da3964af7619f19525e76c4f1292586dd60f54 100644 +--- a/src/man/sssd-ldap.5.xml ++++ b/src/man/sssd-ldap.5.xml +@@ -1955,6 +1955,20 @@ ldap_access_filter = (employeeType=admin) + be set for this feature to work. + + ++ ppolicy: use account locking. ++ If set, this option denies access in case that ldap ++ attribute 'pwdAccountLockedTime' is present and has ++ value of '000001010000Z' or represents any time in the past. ++ The value of 'pwdAccountLockedTime' attribute ++ must end with 'Z' as only UTC time zone is ++ currently suported. Please see the option ++ ldap_pwdlockout_dn. ++ ++ Please note that 'access_provider = ldap' must ++ be set for this feature to work. ++ ++ ++ + expire: use + ldap_account_expire_policy + +diff --git a/src/providers/ldap/ldap_init.c b/src/providers/ldap/ldap_init.c +index 8d5619779d38c0df5ec4761b4409c71e8976686c..cebd548a4f787c2ddda56a1c5e74a60fa78d83ec 100644 +--- a/src/providers/ldap/ldap_init.c ++++ b/src/providers/ldap/ldap_init.c +@@ -432,6 +432,8 @@ int sssm_ldap_access_init(struct be_ctx *bectx, + } else if (strcasecmp(order_list[c], + LDAP_ACCESS_EXPIRE_POLICY_RENEW_NAME) == 0) { + access_ctx->access_rule[c] = LDAP_ACCESS_EXPIRE_POLICY_RENEW; ++ } else if (strcasecmp(order_list[c], LDAP_ACCESS_PPOLICY_NAME) == 0) { ++ access_ctx->access_rule[c] = LDAP_ACCESS_PPOLICY; + } else { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unexpected access rule name [%s].\n", order_list[c]); +diff --git a/src/providers/ldap/sdap_access.c b/src/providers/ldap/sdap_access.c +index dd2fb6b92bc83ee36fc396d26e3d0d7e78021d71..4a45ff419be9a31224e00cf0fb4ea021953bbbc3 100644 +--- a/src/providers/ldap/sdap_access.c ++++ b/src/providers/ldap/sdap_access.c +@@ -32,6 +32,7 @@ + #include + + #include "util/util.h" ++#include "util/strtonum.h" + #include "db/sysdb.h" + #include "providers/ldap/ldap_common.h" + #include "providers/ldap/sdap.h" +@@ -44,6 +45,12 @@ + #define PERMANENTLY_LOCKED_ACCOUNT "000001010000Z" + #define MALFORMED_FILTER "Malformed access control filter [%s]\n" + ++enum sdap_pwpolicy_mode { ++ PWP_LOCKOUT_ONLY, ++ PWP_LOCKOUT_EXPIRE, ++ PWP_SENTINEL, ++}; ++ + static errno_t perform_pwexpire_policy(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + struct pam_data *pd, +@@ -59,14 +66,15 @@ static errno_t sdap_get_basedn_user_entry(struct ldb_message *user_entry, + const char **_basedn); + + static struct tevent_req * +-sdap_access_lock_send(TALLOC_CTX *mem_ctx, +- struct tevent_context *ev, +- struct be_ctx *be_ctx, +- struct sss_domain_info *domain, +- struct sdap_access_ctx *access_ctx, +- struct sdap_id_conn_ctx *conn, +- const char *username, +- struct ldb_message *user_entry); ++sdap_access_ppolicy_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct be_ctx *be_ctx, ++ struct sss_domain_info *domain, ++ struct sdap_access_ctx *access_ctx, ++ struct sdap_id_conn_ctx *conn, ++ const char *username, ++ struct ldb_message *user_entry, ++ enum sdap_pwpolicy_mode pwpol_mod); + + static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, +@@ -79,7 +87,7 @@ static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx, + + static errno_t sdap_access_filter_recv(struct tevent_req *req); + +-static errno_t sdap_access_lock_recv(struct tevent_req *req); ++static errno_t sdap_access_ppolicy_recv(struct tevent_req *req); + + static errno_t sdap_account_expired(struct sdap_access_ctx *access_ctx, + struct pam_data *pd, +@@ -205,14 +213,34 @@ static errno_t sdap_access_check_next_rule(struct sdap_access_req_ctx *state, + return EOK; + + case LDAP_ACCESS_LOCKOUT: +- subreq = sdap_access_lock_send(state, state->ev, state->be_ctx, +- state->domain, +- state->access_ctx, +- state->conn, +- state->pd->user, +- state->user_entry); ++ subreq = sdap_access_ppolicy_send(state, state->ev, state->be_ctx, ++ state->domain, ++ state->access_ctx, ++ state->conn, ++ state->pd->user, ++ state->user_entry, ++ PWP_LOCKOUT_ONLY); + if (subreq == NULL) { +- DEBUG(SSSDBG_CRIT_FAILURE, "sdap_access_lock_send failed.\n"); ++ DEBUG(SSSDBG_CRIT_FAILURE, "sdap_access_ppolicy_send failed.\n"); ++ return ENOMEM; ++ } ++ ++ state->ac_type = SDAP_ACCESS_CONTROL_PPOLICY_LOCK; ++ ++ tevent_req_set_callback(subreq, sdap_access_done, req); ++ return EAGAIN; ++ ++ case LDAP_ACCESS_PPOLICY: ++ subreq = sdap_access_ppolicy_send(state, state->ev, state->be_ctx, ++ state->domain, ++ state->access_ctx, ++ state->conn, ++ state->pd->user, ++ state->user_entry, ++ PWP_LOCKOUT_EXPIRE); ++ if (subreq == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, ++ "sdap_access_ppolicy_send failed.\n"); + return ENOMEM; + } + +@@ -302,7 +330,7 @@ static void sdap_access_done(struct tevent_req *subreq) + ret = sdap_access_filter_recv(subreq); + break; + case SDAP_ACCESS_CONTROL_PPOLICY_LOCK: +- ret = sdap_access_lock_recv(subreq); ++ ret = sdap_access_ppolicy_recv(subreq); + break; + default: + ret = EINVAL; +@@ -779,8 +807,8 @@ struct sdap_access_filter_req_ctx { + + static errno_t sdap_access_decide_offline(bool cached_ac); + static int sdap_access_filter_retry(struct tevent_req *req); +-static void sdap_access_lock_connect_done(struct tevent_req *subreq); +-static errno_t sdap_access_lock_get_lockout_step(struct tevent_req *req); ++static void sdap_access_ppolicy_connect_done(struct tevent_req *subreq); ++static errno_t sdap_access_ppolicy_get_lockout_step(struct tevent_req *req); + static void sdap_access_filter_connect_done(struct tevent_req *subreq); + static void sdap_access_filter_done(struct tevent_req *req); + static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx, +@@ -1255,12 +1283,12 @@ static errno_t sdap_access_host(struct ldb_message *user_entry) + return ret; + } + +-static void sdap_access_lock_get_lockout_done(struct tevent_req *subreq); +-static int sdap_access_lock_retry(struct tevent_req *req); +-static errno_t sdap_access_lock_step(struct tevent_req *req); +-static void sdap_access_lock_step_done(struct tevent_req *subreq); ++static void sdap_access_ppolicy_get_lockout_done(struct tevent_req *subreq); ++static int sdap_access_ppolicy_retry(struct tevent_req *req); ++static errno_t sdap_access_ppolicy_step(struct tevent_req *req); ++static void sdap_access_ppolicy_step_done(struct tevent_req *subreq); + +-struct sdap_access_lock_req_ctx { ++struct sdap_access_ppolicy_req_ctx { + const char *username; + const char *filter; + struct tevent_context *ev; +@@ -1276,24 +1304,26 @@ struct sdap_access_lock_req_ctx { + /* default DNs to ppolicy */ + const char **ppolicy_dns; + unsigned int ppolicy_dns_index; ++ enum sdap_pwpolicy_mode pwpol_mode; + }; + + static struct tevent_req * +-sdap_access_lock_send(TALLOC_CTX *mem_ctx, +- struct tevent_context *ev, +- struct be_ctx *be_ctx, +- struct sss_domain_info *domain, +- struct sdap_access_ctx *access_ctx, +- struct sdap_id_conn_ctx *conn, +- const char *username, +- struct ldb_message *user_entry) ++sdap_access_ppolicy_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct be_ctx *be_ctx, ++ struct sss_domain_info *domain, ++ struct sdap_access_ctx *access_ctx, ++ struct sdap_id_conn_ctx *conn, ++ const char *username, ++ struct ldb_message *user_entry, ++ enum sdap_pwpolicy_mode pwpol_mode) + { +- struct sdap_access_lock_req_ctx *state; ++ struct sdap_access_ppolicy_req_ctx *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_create(mem_ctx, +- &state, struct sdap_access_lock_req_ctx); ++ &state, struct sdap_access_ppolicy_req_ctx); + if (req == NULL) { + return NULL; + } +@@ -1306,9 +1336,10 @@ sdap_access_lock_send(TALLOC_CTX *mem_ctx, + state->access_ctx = access_ctx; + state->domain = domain; + state->ppolicy_dns_index = 0; ++ state->pwpol_mode = pwpol_mode; + + DEBUG(SSSDBG_TRACE_FUNC, +- "Performing access lock check for user [%s]\n", username); ++ "Performing access ppolicy check for user [%s]\n", username); + + state->cached_access = ldb_msg_find_attr_as_bool( + user_entry, SYSDB_LDAP_ACCESS_CACHED_LOCKOUT, false); +@@ -1326,7 +1357,7 @@ sdap_access_lock_send(TALLOC_CTX *mem_ctx, + goto done; + } + +- DEBUG(SSSDBG_TRACE_FUNC, "Checking lock against LDAP\n"); ++ DEBUG(SSSDBG_TRACE_FUNC, "Checking ppolicy against LDAP\n"); + + state->sdap_op = sdap_id_op_create(state, + state->conn->conn_cache); +@@ -1336,7 +1367,7 @@ sdap_access_lock_send(TALLOC_CTX *mem_ctx, + goto done; + } + +- ret = sdap_access_lock_retry(req); ++ ret = sdap_access_ppolicy_retry(req); + if (ret != EOK) { + goto done; + } +@@ -1353,21 +1384,22 @@ done: + return req; + } + +-static int sdap_access_lock_retry(struct tevent_req *req) ++static int sdap_access_ppolicy_retry(struct tevent_req *req) + { +- struct sdap_access_lock_req_ctx *state; ++ struct sdap_access_ppolicy_req_ctx *state; + struct tevent_req *subreq; + int ret; + +- state = tevent_req_data(req, struct sdap_access_lock_req_ctx); ++ state = tevent_req_data(req, struct sdap_access_ppolicy_req_ctx); + subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret); + if (!subreq) { + DEBUG(SSSDBG_OP_FAILURE, +- "sdap_id_op_connect_send failed: %d (%s)\n", ret, strerror(ret)); ++ "sdap_id_op_connect_send failed: %d (%s)\n", ++ ret, sss_strerror(ret)); + return ret; + } + +- tevent_req_set_callback(subreq, sdap_access_lock_connect_done, req); ++ tevent_req_set_callback(subreq, sdap_access_ppolicy_connect_done, req); + return EOK; + } + +@@ -1394,15 +1426,15 @@ get_default_ppolicy_dns(TALLOC_CTX *mem_ctx, struct sdap_domain *sdom) + return ppolicy_dns; + } + +-static void sdap_access_lock_connect_done(struct tevent_req *subreq) ++static void sdap_access_ppolicy_connect_done(struct tevent_req *subreq) + { + struct tevent_req *req; +- struct sdap_access_lock_req_ctx *state; ++ struct sdap_access_ppolicy_req_ctx *state; + int ret, dp_error; + const char *ppolicy_dn; + + req = tevent_req_callback_data(subreq, struct tevent_req); +- state = tevent_req_data(req, struct sdap_access_lock_req_ctx); ++ state = tevent_req_data(req, struct sdap_access_ppolicy_req_ctx); + + ret = sdap_id_op_connect_recv(subreq, &dp_error); + talloc_zfree(subreq); +@@ -1428,7 +1460,7 @@ static void sdap_access_lock_connect_done(struct tevent_req *subreq) + state->ppolicy_dns = talloc_array(state, const char*, 2); + if (state->ppolicy_dns == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Could not allocate ppolicy_dns.\n"); +- tevent_req_error(req, ERR_ACCESS_DENIED); ++ tevent_req_error(req, ERR_INTERNAL); + return; + } + +@@ -1442,7 +1474,7 @@ static void sdap_access_lock_connect_done(struct tevent_req *subreq) + + state->ppolicy_dns = get_default_ppolicy_dns(state, state->opts->sdom); + if (state->ppolicy_dns == NULL) { +- tevent_req_error(req, ERR_ACCESS_DENIED); ++ tevent_req_error(req, ERR_INTERNAL); + return; + } + } +@@ -1450,28 +1482,33 @@ static void sdap_access_lock_connect_done(struct tevent_req *subreq) + /* Connection to LDAP succeeded + * Send 'pwdLockout' request + */ +- ret = sdap_access_lock_get_lockout_step(req); ++ ret = sdap_access_ppolicy_get_lockout_step(req); + if (ret != EOK && ret != EAGAIN) { + DEBUG(SSSDBG_CRIT_FAILURE, +- "sdap_access_lock_get_lockout_step failed: [%d][%s]\n", +- ret, strerror(ret)); +- tevent_req_error(req, ERR_ACCESS_DENIED); ++ "sdap_access_ppolicy_get_lockout_step failed: [%d][%s]\n", ++ ret, sss_strerror(ret)); ++ tevent_req_error(req, ERR_INTERNAL); + return; + } ++ ++ if (ret == EOK) { ++ tevent_req_done(req); ++ } + } + + static errno_t +-sdap_access_lock_get_lockout_step(struct tevent_req *req) ++sdap_access_ppolicy_get_lockout_step(struct tevent_req *req) + { + const char *attrs[] = { SYSDB_LDAP_ACCESS_LOCKOUT, NULL }; +- struct sdap_access_lock_req_ctx *state; ++ struct sdap_access_ppolicy_req_ctx *state; + struct tevent_req *subreq; + errno_t ret; + +- state = tevent_req_data(req, struct sdap_access_lock_req_ctx); ++ state = tevent_req_data(req, struct sdap_access_ppolicy_req_ctx); + + /* no more DNs to try */ + if (state->ppolicy_dns[state->ppolicy_dns_index] == NULL) { ++ DEBUG(SSSDBG_TRACE_FUNC, "No more DNs to try.\n"); + ret = EOK; + goto done; + } +@@ -1493,14 +1530,13 @@ sdap_access_lock_get_lockout_step(struct tevent_req *req) + false); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Could not start LDAP communication\n"); +- tevent_req_error(req, EIO); + ret = EIO; + goto done; + } + + /* try next basedn */ + state->ppolicy_dns_index++; +- tevent_req_set_callback(subreq, sdap_access_lock_get_lockout_done, req); ++ tevent_req_set_callback(subreq, sdap_access_ppolicy_get_lockout_done, req); + + ret = EAGAIN; + +@@ -1508,17 +1544,17 @@ done: + return ret; + } + +-static void sdap_access_lock_get_lockout_done(struct tevent_req *subreq) ++static void sdap_access_ppolicy_get_lockout_done(struct tevent_req *subreq) + { + int ret, tret, dp_error; + size_t num_results; + bool pwdLockout = false; + struct sysdb_attrs **results; + struct tevent_req *req; +- struct sdap_access_lock_req_ctx *state; ++ struct sdap_access_ppolicy_req_ctx *state; + + req = tevent_req_callback_data(subreq, struct tevent_req); +- state = tevent_req_data(req, struct sdap_access_lock_req_ctx); ++ state = tevent_req_data(req, struct sdap_access_ppolicy_req_ctx); + + ret = sdap_get_generic_recv(subreq, state, &num_results, &results); + talloc_zfree(subreq); +@@ -1536,7 +1572,7 @@ static void sdap_access_lock_get_lockout_done(struct tevent_req *subreq) + /* Didn't find ppolicy attribute */ + if (num_results < 1) { + /* Try using next $search_base */ +- ret = sdap_access_lock_get_lockout_step(req); ++ ret = sdap_access_ppolicy_get_lockout_step(req); + if (ret == EOK) { + /* No more search bases to try */ + DEBUG(SSSDBG_CONF_SETTINGS, +@@ -1545,8 +1581,9 @@ static void sdap_access_lock_get_lockout_done(struct tevent_req *subreq) + } else { + if (ret != EAGAIN) { + DEBUG(SSSDBG_CRIT_FAILURE, +- "sdap_access_lock_get_lockout_step failed: [%d][%s]\n", +- ret, strerror(ret)); ++ "sdap_access_ppolicy_get_lockout_step failed: " ++ "[%d][%s]\n", ++ ret, sss_strerror(ret)); + } + goto done; + } +@@ -1567,7 +1604,7 @@ static void sdap_access_lock_get_lockout_done(struct tevent_req *subreq) + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + "Error reading %s: [%s]\n", SYSDB_LDAP_ACCESS_LOCKOUT, +- strerror(ret)); ++ sss_strerror(ret)); + ret = ERR_INTERNAL; + goto done; + } +@@ -1578,11 +1615,11 @@ static void sdap_access_lock_get_lockout_done(struct tevent_req *subreq) + "Password policy is enabled on LDAP server.\n"); + + /* ppolicy is enabled => find out if account is locked */ +- ret = sdap_access_lock_step(req); ++ ret = sdap_access_ppolicy_step(req); + if (ret != EOK && ret != EAGAIN) { + DEBUG(SSSDBG_CRIT_FAILURE, +- "sdap_access_lock_step failed: [%d][%s].\n", +- ret, strerror(ret)); ++ "sdap_access_ppolicy_step failed: [%d][%s].\n", ++ ret, sss_strerror(ret)); + } + goto done; + } else { +@@ -1623,14 +1660,16 @@ done: + } + } + +-errno_t sdap_access_lock_step(struct tevent_req *req) ++errno_t sdap_access_ppolicy_step(struct tevent_req *req) + { + errno_t ret; + struct tevent_req *subreq; +- struct sdap_access_lock_req_ctx *state; +- const char *attrs[] = { SYSDB_LDAP_ACCESS_LOCKED_TIME, NULL }; ++ struct sdap_access_ppolicy_req_ctx *state; ++ const char *attrs[] = { SYSDB_LDAP_ACCESS_LOCKED_TIME, ++ SYSDB_LDAP_ACESS_LOCKOUT_DURATION, ++ NULL }; + +- state = tevent_req_data(req, struct sdap_access_lock_req_ctx); ++ state = tevent_req_data(req, struct sdap_access_ppolicy_req_ctx); + + subreq = sdap_get_generic_send(state, + state->ev, +@@ -1645,30 +1684,114 @@ errno_t sdap_access_lock_step(struct tevent_req *req) + false); + + if (subreq == NULL) { +- DEBUG(SSSDBG_CRIT_FAILURE, "sdap_access_lock_send failed.\n"); ++ DEBUG(SSSDBG_CRIT_FAILURE, "sdap_access_ppolicy_send failed.\n"); + ret = ENOMEM; + goto done; + } + +- tevent_req_set_callback(subreq, sdap_access_lock_step_done, req); ++ tevent_req_set_callback(subreq, sdap_access_ppolicy_step_done, req); + ret = EAGAIN; + + done: + return ret; + } + +-static void sdap_access_lock_step_done(struct tevent_req *subreq) ++static errno_t ++is_account_locked(const char *pwdAccountLockedTime, ++ const char *pwdAccountLockedDurationTime, ++ enum sdap_pwpolicy_mode pwpol_mode, ++ const char *username, ++ bool *_locked) ++{ ++ errno_t ret; ++ time_t lock_time; ++ time_t duration; ++ time_t now; ++ bool locked; ++ ++ /* Default action is to consider account to be locked. */ ++ locked = true; ++ ++ /* account is permanently locked */ ++ if (strcasecmp(pwdAccountLockedTime, ++ PERMANENTLY_LOCKED_ACCOUNT) == 0) { ++ ret = EOK; ++ goto done; ++ } ++ ++ switch(pwpol_mode) { ++ case PWP_LOCKOUT_ONLY: ++ /* We do *not* care about exact value of account locked time, we ++ * only *do* care if the value is equal to ++ * PERMANENTLY_LOCKED_ACCOUNT, which means that account is locked ++ * permanently. ++ */ ++ DEBUG(SSSDBG_TRACE_FUNC, ++ "Account of: %s is beeing blocked by password policy, " ++ "but value: [%s] value is ignored by SSSD.\n", ++ username, pwdAccountLockedTime); ++ locked = false; ++ break; ++ case PWP_LOCKOUT_EXPIRE: ++ /* Account may be locked out from natural reasons (too many attempts, ++ * expired password). In this case, pwdAccountLockedTime is also set, ++ * to the time of lock out. ++ */ ++ ret = sss_utc_to_time_t(pwdAccountLockedTime, "%Y%m%d%H%M%SZ", ++ &lock_time); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_TRACE_FUNC, "sss_utc_to_time_t failed with %d:%s.\n", ++ ret, sss_strerror(ret)); ++ goto done; ++ } ++ ++ now = time(NULL); ++ ++ /* Account was NOT locked in past. */ ++ if (difftime(lock_time, now) > 0.0) { ++ locked = false; ++ } else if (pwdAccountLockedDurationTime != NULL) { ++ errno = 0; ++ duration = strtouint32(pwdAccountLockedDurationTime, NULL, 0); ++ if (errno) { ++ ret = errno; ++ goto done; ++ } ++ /* Lockout has expired */ ++ if (duration != 0 && difftime(now, lock_time) > duration) { ++ locked = false; ++ } ++ } ++ break; ++ case PWP_SENTINEL: ++ default: ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "Unexpected value of password policy mode: %d.\n", pwpol_mode); ++ } ++ ++ ret = EOK; ++ ++done: ++ if (ret == EOK) { ++ *_locked = locked; ++ } ++ ++ return ret; ++} ++ ++static void sdap_access_ppolicy_step_done(struct tevent_req *subreq) + { + int ret, tret, dp_error; + size_t num_results; + bool locked = false; + const char *pwdAccountLockedTime; ++ const char *pwdAccountLockedDurationTime; + struct sysdb_attrs **results; + struct tevent_req *req; +- struct sdap_access_lock_req_ctx *state; ++ struct sdap_access_ppolicy_req_ctx *state; + + req = tevent_req_callback_data(subreq, struct tevent_req); +- state = tevent_req_data(req, struct sdap_access_lock_req_ctx); ++ state = tevent_req_data(req, struct sdap_access_ppolicy_req_ctx); + + ret = sdap_get_generic_recv(subreq, state, &num_results, &results); + talloc_zfree(subreq); +@@ -1677,7 +1800,7 @@ static void sdap_access_lock_step_done(struct tevent_req *subreq) + if (ret != EOK) { + if (dp_error == DP_ERR_OK) { + /* retry */ +- tret = sdap_access_lock_retry(req); ++ tret = sdap_access_ppolicy_retry(req); + if (tret == EOK) { + return; + } +@@ -1700,7 +1823,7 @@ static void sdap_access_lock_step_done(struct tevent_req *subreq) + if (num_results < 1) { + DEBUG(SSSDBG_CONF_SETTINGS, + "User [%s] was not found with the specified filter. " +- "Denying access.\n", state->username); ++ "Denying access.\n", state->username); + } else if (results == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "num_results > 0, but results is NULL\n"); + ret = ERR_INTERNAL; +@@ -1713,22 +1836,35 @@ static void sdap_access_lock_step_done(struct tevent_req *subreq) + ret = ERR_INTERNAL; + goto done; + } else { /* Ok, we got a single reply */ ++ ret = sysdb_attrs_get_string(results[0], SYSDB_LDAP_ACESS_LOCKOUT_DURATION, ++ &pwdAccountLockedDurationTime); ++ if (ret != EOK) { ++ /* This attribute might not be set even if account is locked */ ++ pwdAccountLockedDurationTime = NULL; ++ } ++ + ret = sysdb_attrs_get_string(results[0], SYSDB_LDAP_ACCESS_LOCKED_TIME, + &pwdAccountLockedTime); + if (ret == EOK) { +- /* We do *not* care about exact value of account locked time, we +- * only *do* care if the value is equal to +- * PERMANENTLY_LOCKED_ACCOUNT, which means that account is locked +- * permanently. +- */ +- if (strcasecmp(pwdAccountLockedTime, +- PERMANENTLY_LOCKED_ACCOUNT) == 0) { ++ ++ ret = is_account_locked(pwdAccountLockedTime, ++ pwdAccountLockedDurationTime, ++ state->pwpol_mode, ++ state->username, ++ &locked); ++ if (ret != EOK) { ++ if (ret == ERR_TIMESPEC_NOT_SUPPORTED) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "timezone specifier in ppolicy is not supported\n"); ++ } else { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "is_account_locked failed: %d:[%s].\n", ++ ret, sss_strerror(ret)); ++ } ++ ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "Account will be considered to be locked.\n"); + locked = true; +- } else { +- DEBUG(SSSDBG_TRACE_FUNC, +- "Account of: %s is beeing blocked by password policy, " +- "but value: [%s] value is ignored by SSSD.\n", +- state->username, pwdAccountLockedTime); + } + } else { + /* Attribute SYSDB_LDAP_ACCESS_LOCKED_TIME in not be present unless +@@ -1774,7 +1910,7 @@ done: + } + } + +-static errno_t sdap_access_lock_recv(struct tevent_req *req) ++static errno_t sdap_access_ppolicy_recv(struct tevent_req *req) + { + TEVENT_REQ_RETURN_ON_ERROR(req); + +diff --git a/src/providers/ldap/sdap_access.h b/src/providers/ldap/sdap_access.h +index a8c6639109bd7e6dcb325a5e8d080f743ec56d97..6e637be5653a71415b917d115a61eaa0b6ccea9a 100644 +--- a/src/providers/ldap/sdap_access.h ++++ b/src/providers/ldap/sdap_access.h +@@ -35,6 +35,7 @@ + #define SYSDB_LDAP_ACCESS_CACHED_LOCKOUT "ldap_access_lockout_allow" + /* names of ppolicy attributes */ + #define SYSDB_LDAP_ACCESS_LOCKED_TIME "pwdAccountLockedTime" ++#define SYSDB_LDAP_ACESS_LOCKOUT_DURATION "pwdLockoutDuration" + #define SYSDB_LDAP_ACCESS_LOCKOUT "pwdLockout" + + #define LDAP_ACCESS_FILTER_NAME "filter" +@@ -45,6 +46,7 @@ + #define LDAP_ACCESS_SERVICE_NAME "authorized_service" + #define LDAP_ACCESS_HOST_NAME "host" + #define LDAP_ACCESS_LOCK_NAME "lockout" ++#define LDAP_ACCESS_PPOLICY_NAME "ppolicy" + + #define LDAP_ACCOUNT_EXPIRE_SHADOW "shadow" + #define LDAP_ACCOUNT_EXPIRE_AD "ad" +@@ -63,6 +65,7 @@ enum ldap_access_rule { + LDAP_ACCESS_EXPIRE_POLICY_REJECT, + LDAP_ACCESS_EXPIRE_POLICY_WARN, + LDAP_ACCESS_EXPIRE_POLICY_RENEW, ++ LDAP_ACCESS_PPOLICY, + LDAP_ACCESS_LAST + }; + +-- +2.4.0 + diff --git a/0014-SDAP-fix-minor-neglect-in-is_account_locked.patch b/0014-SDAP-fix-minor-neglect-in-is_account_locked.patch new file mode 100644 index 0000000..7aea00e --- /dev/null +++ b/0014-SDAP-fix-minor-neglect-in-is_account_locked.patch @@ -0,0 +1,32 @@ +From 371c5f40199b6389bd3cbfd05654b2213caecfc1 Mon Sep 17 00:00:00 2001 +From: Pavel Reichl +Date: Fri, 6 Mar 2015 04:38:05 -0500 +Subject: [PATCH 14/99] SDAP: fix minor neglect in is_account_locked() + +It would be better to return explicit error code, although access is +still denied and error message printed. + +Relates: +https://fedorahosted.org/sssd/ticket/2534 + +Reviewed-by: Jakub Hrozek +--- + src/providers/ldap/sdap_access.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/providers/ldap/sdap_access.c b/src/providers/ldap/sdap_access.c +index 4a45ff419be9a31224e00cf0fb4ea021953bbbc3..0b251121335841b357e55deac608f50e24311285 100644 +--- a/src/providers/ldap/sdap_access.c ++++ b/src/providers/ldap/sdap_access.c +@@ -1767,6 +1767,8 @@ is_account_locked(const char *pwdAccountLockedTime, + default: + DEBUG(SSSDBG_MINOR_FAILURE, + "Unexpected value of password policy mode: %d.\n", pwpol_mode); ++ ret = EINVAL; ++ goto done; + } + + ret = EOK; +-- +2.4.0 + diff --git a/0015-be_refresh-refresh-all-domains-in-backend.patch b/0015-be_refresh-refresh-all-domains-in-backend.patch new file mode 100644 index 0000000..d3b6716 --- /dev/null +++ b/0015-be_refresh-refresh-all-domains-in-backend.patch @@ -0,0 +1,224 @@ +From 20b08bcfd6740316f528ca84d3a69be9a6535945 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pavel=20B=C5=99ezina?= +Date: Fri, 13 Feb 2015 13:16:04 +0100 +Subject: [PATCH 15/99] be_refresh: refresh all domains in backend + +Reviewed-by: Jakub Hrozek +(cherry picked from commit b0d3164ca2bd842e176268c26935c5ce54f7f76e) +--- + src/providers/dp_refresh.c | 82 ++++++++++++++++++++++++--------------- + src/providers/dp_refresh.h | 1 + + src/providers/ldap/ldap_common.h | 1 + + src/providers/ldap/sdap_refresh.c | 15 +++++-- + 4 files changed, 64 insertions(+), 35 deletions(-) + +diff --git a/src/providers/dp_refresh.c b/src/providers/dp_refresh.c +index 817b6213ca47bba3fa34ce28fdcd1621d349b651..bd02d0cd99f9a061109f0c17797c6e018d602dc5 100644 +--- a/src/providers/dp_refresh.c ++++ b/src/providers/dp_refresh.c +@@ -117,6 +117,7 @@ typedef errno_t + + + struct be_refresh_cb { ++ const char *name; + bool enabled; + be_refresh_get_values_t get_values; + be_refresh_send_t send_fn; +@@ -137,6 +138,7 @@ struct be_refresh_ctx *be_refresh_ctx_init(TALLOC_CTX *mem_ctx) + return NULL; + } + ++ ctx->callbacks[BE_REFRESH_TYPE_NETGROUPS].name = "netgroups"; + ctx->callbacks[BE_REFRESH_TYPE_NETGROUPS].get_values \ + = be_refresh_get_netgroups; + +@@ -171,6 +173,8 @@ struct be_refresh_state { + struct be_ctx *be_ctx; + struct be_refresh_ctx *ctx; + struct be_refresh_cb *cb; ++ ++ struct sss_domain_info *domain; + enum be_refresh_type index; + time_t period; + }; +@@ -197,6 +201,7 @@ struct tevent_req *be_refresh_send(TALLOC_CTX *mem_ctx, + + state->ev = ev; + state->be_ctx = be_ctx; ++ state->domain = be_ctx->domain; + state->period = be_ptask_get_period(be_ptask); + state->ctx = talloc_get_type(pvt, struct be_refresh_ctx); + if (state->ctx == NULL) { +@@ -235,47 +240,62 @@ static errno_t be_refresh_step(struct tevent_req *req) + + state = tevent_req_data(req, struct be_refresh_state); + +- state->cb = &state->ctx->callbacks[state->index]; +- while (state->index != BE_REFRESH_TYPE_SENTINEL && !state->cb->enabled) { +- state->index++; ++ while (state->domain != NULL) { ++ /* find first enabled callback */ + state->cb = &state->ctx->callbacks[state->index]; +- } ++ while (state->index != BE_REFRESH_TYPE_SENTINEL && !state->cb->enabled) { ++ state->index++; ++ state->cb = &state->ctx->callbacks[state->index]; ++ } + +- if (state->index == BE_REFRESH_TYPE_SENTINEL) { +- ret = EOK; +- goto done; +- } ++ /* if not found than continue with next domain */ ++ if (state->index == BE_REFRESH_TYPE_SENTINEL) { ++ state->domain = get_next_domain(state->domain, false); ++ continue; ++ } + +- if (state->cb->get_values == NULL || state->cb->send_fn == NULL +- || state->cb->recv_fn == NULL) { +- ret = EINVAL; +- goto done; +- } ++ if (state->cb->get_values == NULL || state->cb->send_fn == NULL ++ || state->cb->recv_fn == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid parameters!\n"); ++ ret = ERR_INTERNAL; ++ goto done; ++ } + +- ret = state->cb->get_values(state, state->be_ctx->domain, state->period, +- &values); +- if (ret != EOK) { +- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to obtain DN list [%d]: %s\n", +- ret, sss_strerror(ret)); +- goto done; +- } ++ ret = state->cb->get_values(state, state->domain, state->period, ++ &values); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to obtain DN list [%d]: %s\n", ++ ret, sss_strerror(ret)); ++ goto done; ++ } + +- subreq = state->cb->send_fn(state, state->ev, state->be_ctx, +- values, state->cb->pvt); +- if (subreq == NULL) { +- ret = ENOMEM; +- goto done; +- } ++ DEBUG(SSSDBG_TRACE_FUNC, "Refreshing %s in domain %s\n", ++ state->cb->name, state->domain->name); ++ ++ subreq = state->cb->send_fn(state, state->ev, state->be_ctx, ++ state->domain, values, state->cb->pvt); ++ if (subreq == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } + +- /* make the list disappear with subreq */ +- talloc_steal(subreq, values); ++ /* make the list disappear with subreq */ ++ talloc_steal(subreq, values); + +- tevent_req_set_callback(subreq, be_refresh_done, req); ++ tevent_req_set_callback(subreq, be_refresh_done, req); ++ ++ state->index++; ++ ret = EAGAIN; ++ goto done; ++ } + +- state->index++; +- ret = EAGAIN; ++ ret = EOK; + + done: ++ if (ret != EOK && ret != EAGAIN) { ++ talloc_free(values); ++ } ++ + return ret; + } + +diff --git a/src/providers/dp_refresh.h b/src/providers/dp_refresh.h +index 0c4d4a08e935b269f53867b0fe9946eabe521a4f..d7c775fff78455cc016a0419ee4b9b00ba8ec3f7 100644 +--- a/src/providers/dp_refresh.h ++++ b/src/providers/dp_refresh.h +@@ -36,6 +36,7 @@ typedef struct tevent_req * + (*be_refresh_send_t)(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct be_ctx *be_ctx, ++ struct sss_domain_info *domain, + char **values, + void *pvt); + +diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h +index 889d5b118861e4ea3f51ab8a8ea5c5947e2560b9..c377b7c2a5303c5b1cd53778b17b249b7dd38080 100644 +--- a/src/providers/ldap/ldap_common.h ++++ b/src/providers/ldap/ldap_common.h +@@ -327,6 +327,7 @@ sdap_id_ctx_new(TALLOC_CTX *mem_ctx, struct be_ctx *bectx, + struct tevent_req *sdap_refresh_netgroups_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct be_ctx *be_ctx, ++ struct sss_domain_info *domain, + char **names, + void *pvt); + +diff --git a/src/providers/ldap/sdap_refresh.c b/src/providers/ldap/sdap_refresh.c +index fb2dbc781d9faa7e218339aa3ef0424e9bd59d7d..0b9753ee5b5de45c09eec7025f2f70c51d72ecde 100644 +--- a/src/providers/ldap/sdap_refresh.c ++++ b/src/providers/ldap/sdap_refresh.c +@@ -27,6 +27,7 @@ + struct sdap_refresh_netgroups_state { + struct tevent_context *ev; + struct sdap_id_ctx *id_ctx; ++ struct sdap_domain *sdom; + char **names; + size_t index; + }; +@@ -37,6 +38,7 @@ static void sdap_refresh_netgroups_done(struct tevent_req *subreq); + struct tevent_req *sdap_refresh_netgroups_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct be_ctx *be_ctx, ++ struct sss_domain_info *domain, + char **names, + void *pvt) + { +@@ -51,13 +53,19 @@ struct tevent_req *sdap_refresh_netgroups_send(TALLOC_CTX *mem_ctx, + return NULL; + } + ++ if (names == NULL) { ++ ret = EOK; ++ goto immediately; ++ } ++ + state->ev = ev; + state->id_ctx = talloc_get_type(pvt, struct sdap_id_ctx); + state->names = names; + state->index = 0; + +- if (names == NULL) { +- ret = EOK; ++ state->sdom = sdap_domain_get(state->id_ctx->opts, domain); ++ if (state->sdom == NULL) { ++ ret = ERR_DOMAIN_NOT_FOUND; + goto immediately; + } + +@@ -107,8 +115,7 @@ static errno_t sdap_refresh_netgroups_step(struct tevent_req *req) + DEBUG(SSSDBG_TRACE_FUNC, "Issuing refresh of netgroup %s\n", name); + + subreq = ldap_netgroup_get_send(state, state->ev, state->id_ctx, +- state->id_ctx->opts->sdom, +- state->id_ctx->conn, ++ state->sdom, state->id_ctx->conn, + name, true); + if (subreq == NULL) { + ret = ENOMEM; +-- +2.4.0 + diff --git a/0016-sdap_handle_acct_req_send-remove-be_req.patch b/0016-sdap_handle_acct_req_send-remove-be_req.patch new file mode 100644 index 0000000..976ea04 --- /dev/null +++ b/0016-sdap_handle_acct_req_send-remove-be_req.patch @@ -0,0 +1,185 @@ +From 4d0286e4f7701974f8f7c3ead76a2ab5a93f6ffe Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pavel=20B=C5=99ezina?= +Date: Fri, 13 Feb 2015 13:49:17 +0100 +Subject: [PATCH 16/99] sdap_handle_acct_req_send: remove be_req + +be_req was used only as a talloc context for subreq. This memory context +was replace by state of the parent request which is more suitable for +tevent coding style. + +This change will allow us to use this function in be_refresh where +none be_req is available. + +Reviewed-by: Jakub Hrozek +(cherry picked from commit a849d848d53f305a90613a74c1767a42b250deda) +--- + src/providers/ad/ad_id.c | 2 +- + src/providers/ipa/ipa_id.c | 2 +- + src/providers/ldap/ldap_common.h | 2 +- + src/providers/ldap/ldap_id.c | 24 ++++++++++-------------- + 4 files changed, 13 insertions(+), 17 deletions(-) + +diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c +index 995a7127795b8fe0839b05d3dcbe56cca531598a..ab3934727085fa94ee5bb09ffe0c62546650c42b 100644 +--- a/src/providers/ad/ad_id.c ++++ b/src/providers/ad/ad_id.c +@@ -120,7 +120,7 @@ ad_handle_acct_info_step(struct tevent_req *req) + noexist_delete = true; + } + +- subreq = sdap_handle_acct_req_send(state, state->breq, ++ subreq = sdap_handle_acct_req_send(state, state->ctx->be, + state->ar, state->ctx, + state->sdom, + state->conn[state->cindex], +diff --git a/src/providers/ipa/ipa_id.c b/src/providers/ipa/ipa_id.c +index cc6abcf8721e3f05526bf62063f0cbdc7c1c257b..384e39a31022b1ec47c3d1abf19e8630762a5da6 100644 +--- a/src/providers/ipa/ipa_id.c ++++ b/src/providers/ipa/ipa_id.c +@@ -744,7 +744,7 @@ static errno_t ipa_id_get_account_info_get_original_step(struct tevent_req *req, + struct ipa_id_get_account_info_state); + struct tevent_req *subreq; + +- subreq = sdap_handle_acct_req_send(state, state->be_req, ar, ++ subreq = sdap_handle_acct_req_send(state, state->ctx->be, ar, + state->ipa_ctx->sdap_id_ctx, + state->ipa_ctx->sdap_id_ctx->opts->sdom, + state->ipa_ctx->sdap_id_ctx->conn, true); +diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h +index c377b7c2a5303c5b1cd53778b17b249b7dd38080..f8b4e014223b33da84f436a2be853139059f40e7 100644 +--- a/src/providers/ldap/ldap_common.h ++++ b/src/providers/ldap/ldap_common.h +@@ -104,7 +104,7 @@ int sdap_id_setup_tasks(struct be_ctx *be_ctx, + + struct tevent_req * + sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, +- struct be_req *breq, ++ struct be_ctx *be_ctx, + struct be_acct_req *ar, + struct sdap_id_ctx *id_ctx, + struct sdap_domain *sdom, +diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c +index af90fd06154fedd655de525d040ec24dd6ede3cc..6de5b72a8b66cd95b16d25a2c37dc21a57695de3 100644 +--- a/src/providers/ldap/ldap_id.c ++++ b/src/providers/ldap/ldap_id.c +@@ -1310,7 +1310,6 @@ void sdap_account_info_handler(struct be_req *breq) + + /* A generic LDAP account info handler */ + struct sdap_handle_acct_req_state { +- struct be_req *breq; + struct be_acct_req *ar; + const char *err; + int dp_error; +@@ -1321,7 +1320,7 @@ static void sdap_handle_acct_req_done(struct tevent_req *subreq); + + struct tevent_req * + sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, +- struct be_req *breq, ++ struct be_ctx *be_ctx, + struct be_acct_req *ar, + struct sdap_id_ctx *id_ctx, + struct sdap_domain *sdom, +@@ -1330,11 +1329,9 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, + { + struct tevent_req *req; + struct tevent_req *subreq; +- struct be_ctx *be_ctx; + struct sdap_handle_acct_req_state *state; + errno_t ret; + +- be_ctx = be_req_get_be_ctx(breq); + + req = tevent_req_create(mem_ctx, &state, + struct sdap_handle_acct_req_state); +@@ -1342,7 +1339,6 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, + ret = ENOMEM; + goto done; + } +- state->breq = breq; + state->ar = ar; + + if (ar == NULL) { +@@ -1362,7 +1358,7 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, + goto done; + } + +- subreq = users_get_send(breq, be_ctx->ev, id_ctx, ++ subreq = users_get_send(state, be_ctx->ev, id_ctx, + sdom, conn, + ar->filter_value, + ar->filter_type, +@@ -1382,7 +1378,7 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, + goto done; + } + +- subreq = groups_get_send(breq, be_ctx->ev, id_ctx, ++ subreq = groups_get_send(state, be_ctx->ev, id_ctx, + sdom, conn, + ar->filter_value, + ar->filter_type, +@@ -1402,7 +1398,7 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, + goto done; + } + +- subreq = groups_by_user_send(breq, be_ctx->ev, id_ctx, ++ subreq = groups_by_user_send(state, be_ctx->ev, id_ctx, + sdom, conn, + ar->filter_value, + ar->extra_value, +@@ -1416,7 +1412,7 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, + goto done; + } + +- subreq = ldap_netgroup_get_send(breq, be_ctx->ev, id_ctx, ++ subreq = ldap_netgroup_get_send(state, be_ctx->ev, id_ctx, + sdom, conn, + ar->filter_value, + noexist_delete); +@@ -1439,7 +1435,7 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, + goto done; + } + +- subreq = services_get_send(breq, be_ctx->ev, id_ctx, ++ subreq = services_get_send(state, be_ctx->ev, id_ctx, + sdom, conn, + ar->filter_value, + ar->extra_value, +@@ -1454,7 +1450,7 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, + goto done; + } + +- subreq = get_user_and_group_send(breq, be_ctx->ev, id_ctx, ++ subreq = get_user_and_group_send(state, be_ctx->ev, id_ctx, + sdom, conn, + ar->filter_value, + ar->filter_type, +@@ -1469,7 +1465,7 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, + goto done; + } + +- subreq = get_user_and_group_send(breq, be_ctx->ev, id_ctx, ++ subreq = get_user_and_group_send(state, be_ctx->ev, id_ctx, + sdom, conn, + ar->filter_value, + ar->filter_type, +@@ -1485,7 +1481,7 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, + goto done; + } + +- subreq = get_user_and_group_send(breq, be_ctx->ev, id_ctx, ++ subreq = get_user_and_group_send(state, be_ctx->ev, id_ctx, + sdom, conn, + ar->filter_value, + ar->filter_type, +@@ -1617,7 +1613,7 @@ void sdap_handle_account_info(struct be_req *breq, struct sdap_id_ctx *ctx, + EINVAL, "Invalid private data"); + } + +- req = sdap_handle_acct_req_send(breq, breq, ar, ctx, ++ req = sdap_handle_acct_req_send(breq, ctx->be, ar, ctx, + ctx->opts->sdom, conn, true); + if (req == NULL) { + return sdap_handler_done(breq, DP_ERR_FATAL, ENOMEM, "Out of memory"); +-- +2.4.0 + diff --git a/0017-be_refresh-refactor-netgroups-refresh.patch b/0017-be_refresh-refactor-netgroups-refresh.patch new file mode 100644 index 0000000..3cf4392 --- /dev/null +++ b/0017-be_refresh-refactor-netgroups-refresh.patch @@ -0,0 +1,224 @@ +From dd9dfa7ddc257b09a73252fffe7cb4d002f5990a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pavel=20B=C5=99ezina?= +Date: Mon, 16 Feb 2015 13:42:02 +0100 +Subject: [PATCH 17/99] be_refresh: refactor netgroups refresh + +This is a preparation to support other object types without +introducing duplicated code. + +Reviewed-by: Jakub Hrozek +(cherry picked from commit ab0eda3622b828df2bfb7850c96d1395f614eb13) +--- + src/providers/ldap/sdap_refresh.c | 109 +++++++++++++++++++++++++++----------- + 1 file changed, 77 insertions(+), 32 deletions(-) + +diff --git a/src/providers/ldap/sdap_refresh.c b/src/providers/ldap/sdap_refresh.c +index 0b9753ee5b5de45c09eec7025f2f70c51d72ecde..29055359fc7855f6ad84bf55ea334d0932c0a8d1 100644 +--- a/src/providers/ldap/sdap_refresh.c ++++ b/src/providers/ldap/sdap_refresh.c +@@ -24,30 +24,34 @@ + #include "providers/ldap/sdap.h" + #include "providers/ldap/ldap_common.h" + +-struct sdap_refresh_netgroups_state { ++struct sdap_refresh_state { + struct tevent_context *ev; ++ struct be_ctx *be_ctx; ++ struct be_acct_req *account_req; + struct sdap_id_ctx *id_ctx; + struct sdap_domain *sdom; ++ const char *type; + char **names; + size_t index; + }; + +-static errno_t sdap_refresh_netgroups_step(struct tevent_req *req); +-static void sdap_refresh_netgroups_done(struct tevent_req *subreq); ++static errno_t sdap_refresh_step(struct tevent_req *req); ++static void sdap_refresh_done(struct tevent_req *subreq); + +-struct tevent_req *sdap_refresh_netgroups_send(TALLOC_CTX *mem_ctx, +- struct tevent_context *ev, +- struct be_ctx *be_ctx, +- struct sss_domain_info *domain, +- char **names, +- void *pvt) ++static struct tevent_req *sdap_refresh_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct be_ctx *be_ctx, ++ struct sss_domain_info *domain, ++ int entry_type, ++ char **names, ++ void *pvt) + { +- struct sdap_refresh_netgroups_state *state = NULL; ++ struct sdap_refresh_state *state = NULL; + struct tevent_req *req = NULL; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, +- struct sdap_refresh_netgroups_state); ++ struct sdap_refresh_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); + return NULL; +@@ -59,6 +63,7 @@ struct tevent_req *sdap_refresh_netgroups_send(TALLOC_CTX *mem_ctx, + } + + state->ev = ev; ++ state->be_ctx = be_ctx; + state->id_ctx = talloc_get_type(pvt, struct sdap_id_ctx); + state->names = names; + state->index = 0; +@@ -69,13 +74,34 @@ struct tevent_req *sdap_refresh_netgroups_send(TALLOC_CTX *mem_ctx, + goto immediately; + } + +- ret = sdap_refresh_netgroups_step(req); ++ switch (entry_type) { ++ case BE_REQ_NETGROUP: ++ state->type = "netgroup"; ++ break; ++ default: ++ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid entry type [%d]!\n", entry_type); ++ } ++ ++ state->account_req = talloc_zero(state, struct be_acct_req); ++ if (state->account_req == NULL) { ++ ret = ENOMEM; ++ goto immediately; ++ } ++ ++ state->account_req->entry_type = entry_type; ++ state->account_req->attr_type = BE_ATTR_CORE; ++ state->account_req->filter_type = BE_FILTER_NAME; ++ state->account_req->extra_value = NULL; ++ state->account_req->domain = domain->name; ++ /* filter will be filled later */ ++ ++ ret = sdap_refresh_step(req); + if (ret == EOK) { + DEBUG(SSSDBG_TRACE_FUNC, "Nothing to refresh\n"); + goto immediately; + } else if (ret != EAGAIN) { +- DEBUG(SSSDBG_CRIT_FAILURE, "sdap_refresh_netgroups_step() failed " +- "[%d]: %s\n", ret, sss_strerror(ret)); ++ DEBUG(SSSDBG_CRIT_FAILURE, "sdap_refresh_step() failed " ++ "[%d]: %s\n", ret, sss_strerror(ret)); + goto immediately; + } + +@@ -92,37 +118,37 @@ immediately: + return req; + } + +-static errno_t sdap_refresh_netgroups_step(struct tevent_req *req) ++static errno_t sdap_refresh_step(struct tevent_req *req) + { +- struct sdap_refresh_netgroups_state *state = NULL; ++ struct sdap_refresh_state *state = NULL; + struct tevent_req *subreq = NULL; +- const char *name = NULL; + errno_t ret; + +- state = tevent_req_data(req, struct sdap_refresh_netgroups_state); ++ state = tevent_req_data(req, struct sdap_refresh_state); + + if (state->names == NULL) { + ret = EOK; + goto done; + } + +- name = state->names[state->index]; +- if (name == NULL) { ++ state->account_req->filter_value = state->names[state->index]; ++ if (state->account_req->filter_value == NULL) { + ret = EOK; + goto done; + } + +- DEBUG(SSSDBG_TRACE_FUNC, "Issuing refresh of netgroup %s\n", name); ++ DEBUG(SSSDBG_TRACE_FUNC, "Issuing refresh of %s %s\n", ++ state->type, state->account_req->filter_value); + +- subreq = ldap_netgroup_get_send(state, state->ev, state->id_ctx, +- state->sdom, state->id_ctx->conn, +- name, true); ++ subreq = sdap_handle_acct_req_send(state, state->be_ctx, ++ state->account_req, state->id_ctx, ++ state->sdom, state->id_ctx->conn, true); + if (subreq == NULL) { + ret = ENOMEM; + goto done; + } + +- tevent_req_set_callback(subreq, sdap_refresh_netgroups_done, req); ++ tevent_req_set_callback(subreq, sdap_refresh_done, req); + + state->index++; + ret = EAGAIN; +@@ -131,25 +157,28 @@ done: + return ret; + } + +-static void sdap_refresh_netgroups_done(struct tevent_req *subreq) ++static void sdap_refresh_done(struct tevent_req *subreq) + { ++ struct sdap_refresh_state *state = NULL; + struct tevent_req *req = NULL; ++ const char *err_msg = NULL; + errno_t dp_error; + int sdap_ret; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); ++ state = tevent_req_data(req, struct sdap_refresh_state); + +- ret = ldap_netgroup_get_recv(subreq, &dp_error, &sdap_ret); ++ ret = sdap_handle_acct_req_recv(subreq, &dp_error, &err_msg, &sdap_ret); + talloc_zfree(subreq); + if (ret != EOK) { +- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to refresh netgroup [dp_error: %d, " +- "sdap_ret: %d, errno: %d]: %s\n", +- dp_error, sdap_ret, ret, sss_strerror(ret)); ++ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to refresh %s [dp_error: %d, " ++ "sdap_ret: %d, errno: %d]: %s\n", state->type, ++ dp_error, sdap_ret, ret, err_msg); + goto done; + } + +- ret = sdap_refresh_netgroups_step(req); ++ ret = sdap_refresh_step(req); + if (ret == EAGAIN) { + return; + } +@@ -163,9 +192,25 @@ done: + tevent_req_done(req); + } + +-errno_t sdap_refresh_netgroups_recv(struct tevent_req *req) ++static errno_t sdap_refresh_recv(struct tevent_req *req) + { + TEVENT_REQ_RETURN_ON_ERROR(req); + + return EOK; + } ++ ++struct tevent_req *sdap_refresh_netgroups_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct be_ctx *be_ctx, ++ struct sss_domain_info *domain, ++ char **names, ++ void *pvt) ++{ ++ return sdap_refresh_send(mem_ctx, ev, be_ctx, domain, ++ BE_REQ_NETGROUP, names, pvt); ++} ++ ++errno_t sdap_refresh_netgroups_recv(struct tevent_req *req) ++{ ++ return sdap_refresh_recv(req); ++} +-- +2.4.0 + diff --git a/0018-be_refresh-add-sdap_refresh_init.patch b/0018-be_refresh-add-sdap_refresh_init.patch new file mode 100644 index 0000000..abdb217 --- /dev/null +++ b/0018-be_refresh-add-sdap_refresh_init.patch @@ -0,0 +1,143 @@ +From 4c714a37865979f03c56d82d5984558a63c392da Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pavel=20B=C5=99ezina?= +Date: Thu, 19 Feb 2015 12:04:09 +0100 +Subject: [PATCH 18/99] be_refresh: add sdap_refresh_init + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 17531a398cc9084036cb08d69fe876a8f12707bb) +--- + src/providers/ad/ad_init.c | 7 ++----- + src/providers/ipa/ipa_init.c | 7 ++----- + src/providers/ldap/ldap_common.h | 10 ++-------- + src/providers/ldap/ldap_init.c | 7 ++----- + src/providers/ldap/sdap_refresh.c | 32 +++++++++++++++++++++++++------- + 5 files changed, 33 insertions(+), 30 deletions(-) + +diff --git a/src/providers/ad/ad_init.c b/src/providers/ad/ad_init.c +index 2636b1aba6f005325416e2500b0fd9fb24081260..3d12f382c613883a8f88442c7b1602470deb105d 100644 +--- a/src/providers/ad/ad_init.c ++++ b/src/providers/ad/ad_init.c +@@ -260,12 +260,9 @@ sssm_ad_id_init(struct be_ctx *bectx, + } + + /* setup periodical refresh of expired records */ +- ret = be_refresh_add_cb(bectx->refresh_ctx, BE_REFRESH_TYPE_NETGROUPS, +- sdap_refresh_netgroups_send, +- sdap_refresh_netgroups_recv, +- ad_ctx->sdap_id_ctx); ++ ret = sdap_refresh_init(bectx->refresh_ctx, ad_ctx->sdap_id_ctx); + if (ret != EOK && ret != EEXIST) { +- DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of netgroups " ++ DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh " + "will not work [%d]: %s\n", ret, strerror(ret)); + } + +diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c +index 160d15cac42a1c1083722d656d369442e6ee4dd8..4b26e8baad4d0592729aec9a0b188ae89973fa98 100644 +--- a/src/providers/ipa/ipa_init.c ++++ b/src/providers/ipa/ipa_init.c +@@ -354,12 +354,9 @@ int sssm_ipa_id_init(struct be_ctx *bectx, + } + + /* setup periodical refresh of expired records */ +- ret = be_refresh_add_cb(bectx->refresh_ctx, BE_REFRESH_TYPE_NETGROUPS, +- sdap_refresh_netgroups_send, +- sdap_refresh_netgroups_recv, +- sdap_ctx); ++ ret = sdap_refresh_init(bectx->refresh_ctx, sdap_ctx); + if (ret != EOK && ret != EEXIST) { +- DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of netgroups " ++ DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh " + "will not work [%d]: %s\n", ret, strerror(ret)); + } + +diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h +index f8b4e014223b33da84f436a2be853139059f40e7..bf69489a79e903a98878edb53d372d2242df2b0f 100644 +--- a/src/providers/ldap/ldap_common.h ++++ b/src/providers/ldap/ldap_common.h +@@ -324,13 +324,7 @@ struct sdap_id_ctx * + sdap_id_ctx_new(TALLOC_CTX *mem_ctx, struct be_ctx *bectx, + struct sdap_service *sdap_service); + +-struct tevent_req *sdap_refresh_netgroups_send(TALLOC_CTX *mem_ctx, +- struct tevent_context *ev, +- struct be_ctx *be_ctx, +- struct sss_domain_info *domain, +- char **names, +- void *pvt); +- +-errno_t sdap_refresh_netgroups_recv(struct tevent_req *req); ++errno_t sdap_refresh_init(struct be_refresh_ctx *refresh_ctx, ++ struct sdap_id_ctx *id_ctx); + + #endif /* _LDAP_COMMON_H_ */ +diff --git a/src/providers/ldap/ldap_init.c b/src/providers/ldap/ldap_init.c +index cebd548a4f787c2ddda56a1c5e74a60fa78d83ec..247e20ef766ae595d5c63d3a765a8a7c1912f8d9 100644 +--- a/src/providers/ldap/ldap_init.c ++++ b/src/providers/ldap/ldap_init.c +@@ -179,12 +179,9 @@ static int ldap_id_init_internal(struct be_ctx *bectx, + } + + /* setup periodical refresh of expired records */ +- ret = be_refresh_add_cb(bectx->refresh_ctx, BE_REFRESH_TYPE_NETGROUPS, +- sdap_refresh_netgroups_send, +- sdap_refresh_netgroups_recv, +- ctx); ++ ret = sdap_refresh_init(bectx->refresh_ctx, ctx); + if (ret != EOK && ret != EEXIST) { +- DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of netgroups " ++ DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh " + "will not work [%d]: %s\n", ret, strerror(ret)); + } + +diff --git a/src/providers/ldap/sdap_refresh.c b/src/providers/ldap/sdap_refresh.c +index 29055359fc7855f6ad84bf55ea334d0932c0a8d1..e300e28b68aa87957a607259b6439ceca0796e7e 100644 +--- a/src/providers/ldap/sdap_refresh.c ++++ b/src/providers/ldap/sdap_refresh.c +@@ -199,18 +199,36 @@ static errno_t sdap_refresh_recv(struct tevent_req *req) + return EOK; + } + +-struct tevent_req *sdap_refresh_netgroups_send(TALLOC_CTX *mem_ctx, +- struct tevent_context *ev, +- struct be_ctx *be_ctx, +- struct sss_domain_info *domain, +- char **names, +- void *pvt) ++static struct tevent_req * ++sdap_refresh_netgroups_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct be_ctx *be_ctx, ++ struct sss_domain_info *domain, ++ char **names, ++ void *pvt) + { + return sdap_refresh_send(mem_ctx, ev, be_ctx, domain, + BE_REQ_NETGROUP, names, pvt); + } + +-errno_t sdap_refresh_netgroups_recv(struct tevent_req *req) ++static errno_t sdap_refresh_netgroups_recv(struct tevent_req *req) + { + return sdap_refresh_recv(req); + } ++ ++errno_t sdap_refresh_init(struct be_refresh_ctx *refresh_ctx, ++ struct sdap_id_ctx *id_ctx) ++{ ++ errno_t ret; ++ ++ ret = be_refresh_add_cb(refresh_ctx, BE_REFRESH_TYPE_NETGROUPS, ++ sdap_refresh_netgroups_send, ++ sdap_refresh_netgroups_recv, ++ id_ctx); ++ if (ret != EOK && ret != EEXIST) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of netgroups " ++ "will not work [%d]: %s\n", ret, strerror(ret)); ++ } ++ ++ return ret; ++} +-- +2.4.0 + diff --git a/0019-be_refresh-support-users.patch b/0019-be_refresh-support-users.patch new file mode 100644 index 0000000..b2da7a2 --- /dev/null +++ b/0019-be_refresh-support-users.patch @@ -0,0 +1,159 @@ +From 40f5e40aa0bb9aa6b80b547e9643bebf53f7620a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pavel=20B=C5=99ezina?= +Date: Thu, 19 Feb 2015 12:00:52 +0100 +Subject: [PATCH 19/99] be_refresh: support users + +Resolves: +https://fedorahosted.org/sssd/ticket/2346 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit e77d6366ff9e49dbbb607f1709f1ae4190b99489) +--- + src/db/sysdb.c | 7 +++++++ + src/db/sysdb.h | 2 ++ + src/providers/dp_refresh.c | 23 +++++++++++++++++++++++ + src/providers/dp_refresh.h | 1 + + src/providers/ldap/sdap_refresh.c | 29 +++++++++++++++++++++++++++++ + 5 files changed, 62 insertions(+) + +diff --git a/src/db/sysdb.c b/src/db/sysdb.c +index 61a2240016b5cb77e6fbbc3286fd1a194c5a0b48..2bb4a41aa4a9e6201ac27ac8d9a1803c1fb5c43e 100644 +--- a/src/db/sysdb.c ++++ b/src/db/sysdb.c +@@ -172,6 +172,13 @@ struct ldb_dn *sysdb_user_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, + return dn; + } + ++struct ldb_dn *sysdb_user_base_dn(TALLOC_CTX *mem_ctx, ++ struct sss_domain_info *dom) ++{ ++ return ldb_dn_new_fmt(mem_ctx, dom->sysdb->ldb, ++ SYSDB_TMPL_USER_BASE, dom->name); ++} ++ + struct ldb_dn *sysdb_group_dn(TALLOC_CTX *mem_ctx, + struct sss_domain_info *dom, const char *name) + { +diff --git a/src/db/sysdb.h b/src/db/sysdb.h +index cf6028acb806d5d4eedf4cf0680cf4ac9fd6368d..ce1b45be984b65c61d8c09dee2bdf7f2e461494e 100644 +--- a/src/db/sysdb.h ++++ b/src/db/sysdb.h +@@ -383,6 +383,8 @@ errno_t sysdb_get_rdn(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx, + const char *dn, char **_name, char **_val); + struct ldb_dn *sysdb_user_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, + const char *name); ++struct ldb_dn *sysdb_user_base_dn(TALLOC_CTX *mem_ctx, ++ struct sss_domain_info *dom); + struct ldb_dn *sysdb_group_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, + const char *name); + struct ldb_dn *sysdb_netgroup_dn(TALLOC_CTX *mem_ctx, +diff --git a/src/providers/dp_refresh.c b/src/providers/dp_refresh.c +index bd02d0cd99f9a061109f0c17797c6e018d602dc5..f599618e074e6c0ef29363f014ec0ec422de3a55 100644 +--- a/src/providers/dp_refresh.c ++++ b/src/providers/dp_refresh.c +@@ -89,6 +89,26 @@ done: + return ret; + } + ++static errno_t be_refresh_get_users(TALLOC_CTX *mem_ctx, ++ struct sss_domain_info *domain, ++ time_t period, ++ char ***_values) ++{ ++ struct ldb_dn *base_dn = NULL; ++ errno_t ret; ++ ++ base_dn = sysdb_user_base_dn(mem_ctx, domain); ++ if (base_dn == NULL) { ++ return ENOMEM; ++ } ++ ++ ret = be_refresh_get_values(mem_ctx, domain, period, SYSDB_USER_CLASS, ++ base_dn, SYSDB_NAME, _values); ++ ++ talloc_free(base_dn); ++ return ret; ++} ++ + static errno_t be_refresh_get_netgroups(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + time_t period, +@@ -138,6 +158,9 @@ struct be_refresh_ctx *be_refresh_ctx_init(TALLOC_CTX *mem_ctx) + return NULL; + } + ++ ctx->callbacks[BE_REFRESH_TYPE_USERS].name = "users"; ++ ctx->callbacks[BE_REFRESH_TYPE_USERS].get_values = be_refresh_get_users; ++ + ctx->callbacks[BE_REFRESH_TYPE_NETGROUPS].name = "netgroups"; + ctx->callbacks[BE_REFRESH_TYPE_NETGROUPS].get_values \ + = be_refresh_get_netgroups; +diff --git a/src/providers/dp_refresh.h b/src/providers/dp_refresh.h +index d7c775fff78455cc016a0419ee4b9b00ba8ec3f7..a0d42734b64e16184a3a2cdfe45057003ddec6cc 100644 +--- a/src/providers/dp_refresh.h ++++ b/src/providers/dp_refresh.h +@@ -44,6 +44,7 @@ typedef errno_t + (*be_refresh_recv_t)(struct tevent_req *req); + + enum be_refresh_type { ++ BE_REFRESH_TYPE_USERS, + BE_REFRESH_TYPE_NETGROUPS, + BE_REFRESH_TYPE_SENTINEL + }; +diff --git a/src/providers/ldap/sdap_refresh.c b/src/providers/ldap/sdap_refresh.c +index e300e28b68aa87957a607259b6439ceca0796e7e..8fff9d49297b4efe3f4673003859242dd9192070 100644 +--- a/src/providers/ldap/sdap_refresh.c ++++ b/src/providers/ldap/sdap_refresh.c +@@ -75,6 +75,9 @@ static struct tevent_req *sdap_refresh_send(TALLOC_CTX *mem_ctx, + } + + switch (entry_type) { ++ case BE_REQ_USER: ++ state->type = "user"; ++ break; + case BE_REQ_NETGROUP: + state->type = "netgroup"; + break; +@@ -200,6 +203,23 @@ static errno_t sdap_refresh_recv(struct tevent_req *req) + } + + static struct tevent_req * ++sdap_refresh_users_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct be_ctx *be_ctx, ++ struct sss_domain_info *domain, ++ char **names, ++ void *pvt) ++{ ++ return sdap_refresh_send(mem_ctx, ev, be_ctx, domain, ++ BE_REQ_USER, names, pvt); ++} ++ ++static errno_t sdap_refresh_users_recv(struct tevent_req *req) ++{ ++ return sdap_refresh_recv(req); ++} ++ ++static struct tevent_req * + sdap_refresh_netgroups_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct be_ctx *be_ctx, +@@ -221,6 +241,15 @@ errno_t sdap_refresh_init(struct be_refresh_ctx *refresh_ctx, + { + errno_t ret; + ++ ret = be_refresh_add_cb(refresh_ctx, BE_REFRESH_TYPE_USERS, ++ sdap_refresh_users_send, ++ sdap_refresh_users_recv, ++ id_ctx); ++ if (ret != EOK && ret != EEXIST) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of users " ++ "will not work [%d]: %s\n", ret, strerror(ret)); ++ } ++ + ret = be_refresh_add_cb(refresh_ctx, BE_REFRESH_TYPE_NETGROUPS, + sdap_refresh_netgroups_send, + sdap_refresh_netgroups_recv, +-- +2.4.0 + diff --git a/0020-be_refresh-support-groups.patch b/0020-be_refresh-support-groups.patch new file mode 100644 index 0000000..2df24d6 --- /dev/null +++ b/0020-be_refresh-support-groups.patch @@ -0,0 +1,160 @@ +From 0a26dd82639cd3fc80433d19f4bb7363db7975e2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pavel=20B=C5=99ezina?= +Date: Thu, 19 Feb 2015 12:10:23 +0100 +Subject: [PATCH 20/99] be_refresh: support groups + +Resolves: +https://fedorahosted.org/sssd/ticket/2346 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 61c8d13e55ebafc28da1b0b5ad9ae578d687e288) +--- + src/db/sysdb.c | 8 ++++++++ + src/db/sysdb.h | 2 ++ + src/providers/dp_refresh.c | 23 +++++++++++++++++++++++ + src/providers/dp_refresh.h | 1 + + src/providers/ldap/sdap_refresh.c | 29 +++++++++++++++++++++++++++++ + 5 files changed, 63 insertions(+) + +diff --git a/src/db/sysdb.c b/src/db/sysdb.c +index 2bb4a41aa4a9e6201ac27ac8d9a1803c1fb5c43e..6be5e8026c6d24c03f133242a62acec759a24780 100644 +--- a/src/db/sysdb.c ++++ b/src/db/sysdb.c +@@ -198,6 +198,14 @@ struct ldb_dn *sysdb_group_dn(TALLOC_CTX *mem_ctx, + return dn; + } + ++struct ldb_dn *sysdb_group_base_dn(TALLOC_CTX *mem_ctx, ++ struct sss_domain_info *dom) ++{ ++ return ldb_dn_new_fmt(mem_ctx, dom->sysdb->ldb, ++ SYSDB_TMPL_GROUP_BASE, dom->name); ++} ++ ++ + struct ldb_dn *sysdb_netgroup_dn(TALLOC_CTX *mem_ctx, + struct sss_domain_info *dom, const char *name) + { +diff --git a/src/db/sysdb.h b/src/db/sysdb.h +index ce1b45be984b65c61d8c09dee2bdf7f2e461494e..1362f377837d25815b04b4929a2895ee3a6485a9 100644 +--- a/src/db/sysdb.h ++++ b/src/db/sysdb.h +@@ -387,6 +387,8 @@ struct ldb_dn *sysdb_user_base_dn(TALLOC_CTX *mem_ctx, + struct sss_domain_info *dom); + struct ldb_dn *sysdb_group_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, + const char *name); ++struct ldb_dn *sysdb_group_base_dn(TALLOC_CTX *mem_ctx, ++ struct sss_domain_info *dom); + struct ldb_dn *sysdb_netgroup_dn(TALLOC_CTX *mem_ctx, + struct sss_domain_info *dom, const char *name); + struct ldb_dn *sysdb_netgroup_base_dn(TALLOC_CTX *mem_ctx, +diff --git a/src/providers/dp_refresh.c b/src/providers/dp_refresh.c +index f599618e074e6c0ef29363f014ec0ec422de3a55..169ef71edfa4aaf59a199bd1f005f62323e58b87 100644 +--- a/src/providers/dp_refresh.c ++++ b/src/providers/dp_refresh.c +@@ -109,6 +109,26 @@ static errno_t be_refresh_get_users(TALLOC_CTX *mem_ctx, + return ret; + } + ++static errno_t be_refresh_get_groups(TALLOC_CTX *mem_ctx, ++ struct sss_domain_info *domain, ++ time_t period, ++ char ***_values) ++{ ++ struct ldb_dn *base_dn = NULL; ++ errno_t ret; ++ ++ base_dn = sysdb_group_base_dn(mem_ctx, domain); ++ if (base_dn == NULL) { ++ return ENOMEM; ++ } ++ ++ ret = be_refresh_get_values(mem_ctx, domain, period, SYSDB_GROUP_CLASS, ++ base_dn, SYSDB_NAME, _values); ++ ++ talloc_free(base_dn); ++ return ret; ++} ++ + static errno_t be_refresh_get_netgroups(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + time_t period, +@@ -161,6 +181,9 @@ struct be_refresh_ctx *be_refresh_ctx_init(TALLOC_CTX *mem_ctx) + ctx->callbacks[BE_REFRESH_TYPE_USERS].name = "users"; + ctx->callbacks[BE_REFRESH_TYPE_USERS].get_values = be_refresh_get_users; + ++ ctx->callbacks[BE_REFRESH_TYPE_GROUPS].name = "groups"; ++ ctx->callbacks[BE_REFRESH_TYPE_GROUPS].get_values = be_refresh_get_groups; ++ + ctx->callbacks[BE_REFRESH_TYPE_NETGROUPS].name = "netgroups"; + ctx->callbacks[BE_REFRESH_TYPE_NETGROUPS].get_values \ + = be_refresh_get_netgroups; +diff --git a/src/providers/dp_refresh.h b/src/providers/dp_refresh.h +index a0d42734b64e16184a3a2cdfe45057003ddec6cc..89ccfcfb49c4cee18d3fa0f83ce6314a49ee1302 100644 +--- a/src/providers/dp_refresh.h ++++ b/src/providers/dp_refresh.h +@@ -45,6 +45,7 @@ typedef errno_t + + enum be_refresh_type { + BE_REFRESH_TYPE_USERS, ++ BE_REFRESH_TYPE_GROUPS, + BE_REFRESH_TYPE_NETGROUPS, + BE_REFRESH_TYPE_SENTINEL + }; +diff --git a/src/providers/ldap/sdap_refresh.c b/src/providers/ldap/sdap_refresh.c +index 8fff9d49297b4efe3f4673003859242dd9192070..bda50aeb3e44510f3afc1a10cb09336a6eec26ec 100644 +--- a/src/providers/ldap/sdap_refresh.c ++++ b/src/providers/ldap/sdap_refresh.c +@@ -78,6 +78,9 @@ static struct tevent_req *sdap_refresh_send(TALLOC_CTX *mem_ctx, + case BE_REQ_USER: + state->type = "user"; + break; ++ case BE_REQ_GROUP: ++ state->type = "group"; ++ break; + case BE_REQ_NETGROUP: + state->type = "netgroup"; + break; +@@ -220,6 +223,23 @@ static errno_t sdap_refresh_users_recv(struct tevent_req *req) + } + + static struct tevent_req * ++sdap_refresh_groups_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct be_ctx *be_ctx, ++ struct sss_domain_info *domain, ++ char **names, ++ void *pvt) ++{ ++ return sdap_refresh_send(mem_ctx, ev, be_ctx, domain, ++ BE_REQ_GROUP, names, pvt); ++} ++ ++static errno_t sdap_refresh_groups_recv(struct tevent_req *req) ++{ ++ return sdap_refresh_recv(req); ++} ++ ++static struct tevent_req * + sdap_refresh_netgroups_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct be_ctx *be_ctx, +@@ -250,6 +270,15 @@ errno_t sdap_refresh_init(struct be_refresh_ctx *refresh_ctx, + "will not work [%d]: %s\n", ret, strerror(ret)); + } + ++ ret = be_refresh_add_cb(refresh_ctx, BE_REFRESH_TYPE_GROUPS, ++ sdap_refresh_groups_send, ++ sdap_refresh_groups_recv, ++ id_ctx); ++ if (ret != EOK && ret != EEXIST) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of groups " ++ "will not work [%d]: %s\n", ret, strerror(ret)); ++ } ++ + ret = be_refresh_add_cb(refresh_ctx, BE_REFRESH_TYPE_NETGROUPS, + sdap_refresh_netgroups_send, + sdap_refresh_netgroups_recv, +-- +2.4.0 + diff --git a/0021-Log-reason-in-debug-message-why-ldb_modify-failed.patch b/0021-Log-reason-in-debug-message-why-ldb_modify-failed.patch new file mode 100644 index 0000000..59adae5 --- /dev/null +++ b/0021-Log-reason-in-debug-message-why-ldb_modify-failed.patch @@ -0,0 +1,257 @@ +From 182675e355aa1013f847d47d21a251250962e61f Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik +Date: Tue, 10 Mar 2015 16:35:03 +0100 +Subject: [PATCH 21/99] Log reason in debug message why ldb_modify failed + +Reviewed-by: Sumit Bose +(cherry picked from commit 04d138472cc086fb7961f0d378852b09961b1a33) +--- + src/confdb/confdb.c | 6 +++++- + src/db/sysdb.c | 5 +++++ + src/db/sysdb_gpo.c | 6 ++++-- + src/db/sysdb_idmap.c | 4 ++-- + src/db/sysdb_ops.c | 28 +++++++++++++++++++++++++++- + src/db/sysdb_services.c | 10 ++++++++++ + src/db/sysdb_sudo.c | 5 +++++ + src/db/sysdb_views.c | 14 ++++++++++---- + 8 files changed, 68 insertions(+), 10 deletions(-) + +diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c +index f94de308ec8245b33b4a69af16dd99d17db8db9a..dd93410cfcac3040d5a72329929f99f43fc592f1 100644 +--- a/src/confdb/confdb.c ++++ b/src/confdb/confdb.c +@@ -200,6 +200,9 @@ int confdb_add_param(struct confdb_ctx *cdb, + + ret = ldb_modify(cdb->ldb, msg); + if (ret != LDB_SUCCESS) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "ldb_modify failed: [%s](%d)[%s]\n", ++ ldb_strerror(ret), ret, ldb_errstring(cdb->ldb)); + ret = EIO; + goto done; + } +@@ -348,7 +351,8 @@ int confdb_set_string(struct confdb_ctx *cdb, + lret = ldb_modify(cdb->ldb, msg); + if (lret != LDB_SUCCESS) { + DEBUG(SSSDBG_MINOR_FAILURE, +- "ldb_modify failed: [%s]\n", ldb_strerror(lret)); ++ "ldb_modify failed: [%s](%d)[%s]\n", ++ ldb_strerror(lret), lret, ldb_errstring(cdb->ldb)); + ret = EIO; + goto done; + } +diff --git a/src/db/sysdb.c b/src/db/sysdb.c +index 6be5e8026c6d24c03f133242a62acec759a24780..9da655759c0c35d52854b668693195b3360c5f8b 100644 +--- a/src/db/sysdb.c ++++ b/src/db/sysdb.c +@@ -1636,6 +1636,11 @@ errno_t sysdb_set_bool(struct sysdb_ctx *sysdb, + lret = ldb_add(sysdb->ldb, msg); + } + ++ if (lret != LDB_SUCCESS) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "ldb operation failed: [%s](%d)[%s]\n", ++ ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb)); ++ } + ret = sysdb_error_to_errno(lret); + + done: +diff --git a/src/db/sysdb_gpo.c b/src/db/sysdb_gpo.c +index 2fb9b748d750b92dc990b8175869262b666306db..595051bae44c110210c76de2b583319ac42864a2 100644 +--- a/src/db/sysdb_gpo.c ++++ b/src/db/sysdb_gpo.c +@@ -208,7 +208,8 @@ sysdb_gpo_store_gpo(struct sss_domain_info *domain, + lret = ldb_modify(domain->sysdb->ldb, update_msg); + if (lret != LDB_SUCCESS) { + DEBUG(SSSDBG_MINOR_FAILURE, +- "Failed to modify GPO: [%s]\n", ldb_strerror(lret)); ++ "Failed to modify GPO: [%s](%d)[%s]\n", ++ ldb_strerror(lret), lret, ldb_errstring(domain->sysdb->ldb)); + ret = sysdb_error_to_errno(lret); + goto done; + } +@@ -500,7 +501,8 @@ sysdb_gpo_store_gpo_result_setting(struct sss_domain_info *domain, + lret = ldb_modify(domain->sysdb->ldb, update_msg); + if (lret != LDB_SUCCESS) { + DEBUG(SSSDBG_MINOR_FAILURE, +- "Failed to modify GPO Result: [%s]\n", ldb_strerror(lret)); ++ "Failed to modify GPO Result: [%s](%d)[%s]\n", ++ ldb_strerror(lret), lret, ldb_errstring(domain->sysdb->ldb)); + ret = sysdb_error_to_errno(lret); + goto done; + } +diff --git a/src/db/sysdb_idmap.c b/src/db/sysdb_idmap.c +index 2c3634d1cc86818007700a43dc6b919c9bf7030e..2aa00ef83f182a77b0e9b94ba8a80ef71af6518c 100644 +--- a/src/db/sysdb_idmap.c ++++ b/src/db/sysdb_idmap.c +@@ -247,8 +247,8 @@ sysdb_idmap_store_mapping(struct sss_domain_info *domain, + lret = ldb_modify(domain->sysdb->ldb, update_msg); + if (lret != LDB_SUCCESS) { + DEBUG(SSSDBG_MINOR_FAILURE, +- "Failed to update mapping: [%s]\n", +- ldb_strerror(lret)); ++ "Failed to update mapping: [%s](%d)[%s]\n", ++ ldb_strerror(lret), lret, ldb_errstring(domain->sysdb->ldb)); + ret = sysdb_error_to_errno(lret); + goto done; + } +diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c +index 6085762dcc5585114dd3049dd3a365856cb6b190..06d24f220afc28b39f3856f3f0170818e11d9cf9 100644 +--- a/src/db/sysdb_ops.c ++++ b/src/db/sysdb_ops.c +@@ -707,7 +707,8 @@ int sysdb_set_entry_attr(struct sysdb_ctx *sysdb, + lret = ldb_modify(sysdb->ldb, msg); + if (lret != LDB_SUCCESS) { + DEBUG(SSSDBG_MINOR_FAILURE, +- "ldb_modify failed: [%s]\n", ldb_strerror(lret)); ++ "ldb_modify failed: [%s](%d)[%s]\n", ++ ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb)); + } + + ret = sysdb_error_to_errno(lret); +@@ -969,6 +970,11 @@ int sysdb_get_new_id(struct sss_domain_info *domain, + } + + ret = ldb_modify(domain->sysdb->ldb, msg); ++ if (ret != LDB_SUCCESS) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "ldb_modify failed: [%s](%d)[%s]\n", ++ ldb_strerror(ret), ret, ldb_errstring(domain->sysdb->ldb)); ++ } + ret = sysdb_error_to_errno(ret); + + *_id = new_id; +@@ -1139,6 +1145,12 @@ sysdb_remove_ghost_from_group(struct sss_domain_info *dom, + + + ret = sss_ldb_modify_permissive(dom->sysdb->ldb, msg); ++ if (ret != LDB_SUCCESS) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "sss_ldb_modify_permissive failed: [%s](%d)[%s]\n", ++ ldb_strerror(ret), ret, ldb_errstring(dom->sysdb->ldb)); ++ } ++ + ret = sysdb_error_to_errno(ret); + if (ret != EOK) { + goto done; +@@ -1706,6 +1718,11 @@ int sysdb_mod_group_member(struct sss_domain_info *domain, + } + + ret = ldb_modify(domain->sysdb->ldb, msg); ++ if (ret != LDB_SUCCESS) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "ldb_modify failed: [%s](%d)[%s]\n", ++ ldb_strerror(ret), ret, ldb_errstring(domain->sysdb->ldb)); ++ } + ret = sysdb_error_to_errno(ret); + + fail: +@@ -2750,6 +2767,12 @@ int sysdb_delete_user(struct sss_domain_info *domain, + if (ret) goto fail; + + ret = ldb_modify(domain->sysdb->ldb, msg); ++ if (ret != LDB_SUCCESS) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "ldb_modify failed: [%s](%d)[%s]\n", ++ ldb_strerror(ret), ret, ++ ldb_errstring(domain->sysdb->ldb)); ++ } + ret = sysdb_error_to_errno(ret); + if (ret != EOK) { + goto fail; +@@ -3479,6 +3502,9 @@ errno_t sysdb_remove_attrs(struct sss_domain_info *domain, + */ + lret = ldb_modify(domain->sysdb->ldb, msg); + if (lret != LDB_SUCCESS && lret != LDB_ERR_NO_SUCH_ATTRIBUTE) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "ldb_modify failed: [%s](%d)[%s]\n", ++ ldb_strerror(lret), lret, ldb_errstring(domain->sysdb->ldb)); + ret = sysdb_error_to_errno(lret); + goto done; + } +diff --git a/src/db/sysdb_services.c b/src/db/sysdb_services.c +index 5f2315e72735dd4ccc1ecf7962d9cd54b38e4279..37f7ec5ff7e36605acd3b259c1622f1b1086a388 100644 +--- a/src/db/sysdb_services.c ++++ b/src/db/sysdb_services.c +@@ -590,6 +590,11 @@ sysdb_svc_update(struct sysdb_ctx *sysdb, + } + + lret = ldb_modify(sysdb->ldb, msg); ++ if (lret != LDB_SUCCESS) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "ldb_modify failed: [%s](%d)[%s]\n", ++ ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb)); ++ } + ret = sysdb_error_to_errno(lret); + + done: +@@ -623,6 +628,11 @@ sysdb_svc_remove_alias(struct sysdb_ctx *sysdb, + if (ret != EOK) goto done; + + lret = ldb_modify(sysdb->ldb, msg); ++ if (lret != LDB_SUCCESS) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "ldb_modify failed: [%s](%d)[%s]\n", ++ ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb)); ++ } + ret = sysdb_error_to_errno(lret); + + done: +diff --git a/src/db/sysdb_sudo.c b/src/db/sysdb_sudo.c +index d62234f9b18cff44e935bfef6dda612a98f09e5a..4c50d32c779732a5fb78f23f4344ba4ba0825e84 100644 +--- a/src/db/sysdb_sudo.c ++++ b/src/db/sysdb_sudo.c +@@ -521,6 +521,11 @@ static errno_t sysdb_sudo_set_refresh_time(struct sss_domain_info *domain, + lret = ldb_add(domain->sysdb->ldb, msg); + } + ++ if (lret != LDB_SUCCESS) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "ldb operation failed: [%s](%d)[%s]\n", ++ ldb_strerror(lret), lret, ldb_errstring(domain->sysdb->ldb)); ++ } + ret = sysdb_error_to_errno(lret); + + done: +diff --git a/src/db/sysdb_views.c b/src/db/sysdb_views.c +index 21c64c4818d0946785921edbe7c4047d09b0f2a2..945f16ac1753e3b4dfa0c799b00ad177b24d438c 100644 +--- a/src/db/sysdb_views.c ++++ b/src/db/sysdb_views.c +@@ -165,8 +165,10 @@ errno_t sysdb_update_view_name(struct sysdb_ctx *sysdb, + ret = ldb_add(sysdb->ldb, msg); + } + if (ret != LDB_SUCCESS) { +- DEBUG(SSSDBG_FATAL_FAILURE, "Failed to %s view container\n", +- view_container_exists ? "modify" : "add"); ++ DEBUG(SSSDBG_FATAL_FAILURE, ++ "Failed to %s view container [%s](%d)[%s]\n", ++ view_container_exists ? "modify" : "add", ++ ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb)); + ret = sysdb_error_to_errno(ret); + goto done; + } +@@ -282,7 +284,9 @@ errno_t sysdb_invalidate_overrides(struct sysdb_ctx *sysdb) + + ret = ldb_modify(sysdb->ldb, msg); + if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) { +- DEBUG(SSSDBG_OP_FAILURE, "ldb_modify failed.\n"); ++ DEBUG(SSSDBG_OP_FAILURE, ++ "ldb_modify failed: [%s](%d)[%s]\n", ++ ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb)); + ret = sysdb_error_to_errno(ret); + goto done; + } +@@ -303,7 +307,9 @@ errno_t sysdb_invalidate_overrides(struct sysdb_ctx *sysdb) + + ret = ldb_modify(sysdb->ldb, msg); + if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) { +- DEBUG(SSSDBG_OP_FAILURE, "ldb_modify failed.\n"); ++ DEBUG(SSSDBG_OP_FAILURE, ++ "ldb_modify failed: [%s](%d)[%s]\n", ++ ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb)); + ret = sysdb_error_to_errno(ret); + goto done; + } +-- +2.4.0 + diff --git a/0022-ldap_child-fix-coverity-warning.patch b/0022-ldap_child-fix-coverity-warning.patch new file mode 100644 index 0000000..d6699da --- /dev/null +++ b/0022-ldap_child-fix-coverity-warning.patch @@ -0,0 +1,58 @@ +From 7e6f4793f18a2d549b1d1a8c7b6217468b293bc6 Mon Sep 17 00:00:00 2001 +From: Pavel Reichl +Date: Mon, 9 Mar 2015 05:45:20 -0400 +Subject: [PATCH 22/99] ldap_child: fix coverity warning +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In ldap_child_get_tgt_sync() variable 'ret' got overriden in done +section without ever before being read. + +Reviewed-by: Lukáš Slebodník +(cherry picked from commit 6ccda8691123bb27f5f2a88a0c80174af3e0fd0a) +--- + src/providers/ldap/ldap_child.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/src/providers/ldap/ldap_child.c b/src/providers/ldap/ldap_child.c +index 8f034affa48095b6e512c866f8a3c33465e5c595..82481d6e75c86f7be49625a669691b235589d9a7 100644 +--- a/src/providers/ldap/ldap_child.c ++++ b/src/providers/ldap/ldap_child.c +@@ -391,14 +391,20 @@ static krb5_error_code ldap_child_get_tgt_sync(TALLOC_CTX *memctx, + ccname_file = talloc_asprintf(tmp_ctx, "%s/ccache_%s", + DB_PATH, realm_name); + if (ccname_file == NULL) { +- ret = ENOMEM; ++ krberr = ENOMEM; ++ DEBUG(SSSDBG_CRIT_FAILURE, ++ "talloc_asprintf failed: %s:[%d].\n", ++ strerror(krberr), krberr); + goto done; + } + + ccname_file_dummy = talloc_asprintf(tmp_ctx, "%s/ccache_%s_XXXXXX", + DB_PATH, realm_name); + if (ccname_file_dummy == NULL) { +- ret = ENOMEM; ++ krberr = ENOMEM; ++ DEBUG(SSSDBG_CRIT_FAILURE, ++ "talloc_asprintf failed: %s:[%d].\n", ++ strerror(krberr), krberr); + goto done; + } + +@@ -407,6 +413,10 @@ static krb5_error_code ldap_child_get_tgt_sync(TALLOC_CTX *memctx, + umask(old_umask); + if (fd == -1) { + ret = errno; ++ DEBUG(SSSDBG_CRIT_FAILURE, ++ "mkstemp failed: %s:[%d].\n", ++ strerror(ret), ret); ++ krberr = KRB5KRB_ERR_GENERIC; + goto done; + } + /* We only care about creating a unique file name here, we don't +-- +2.4.0 + diff --git a/0023-NSS-Handle-ENOENT-when-doing-initgroups-by-UPN.patch b/0023-NSS-Handle-ENOENT-when-doing-initgroups-by-UPN.patch new file mode 100644 index 0000000..8236a1d --- /dev/null +++ b/0023-NSS-Handle-ENOENT-when-doing-initgroups-by-UPN.patch @@ -0,0 +1,79 @@ +From d8006abd55f2ce0698e09213b8374e9071e70016 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Mon, 9 Mar 2015 17:25:48 +0100 +Subject: [PATCH 23/99] NSS: Handle ENOENT when doing initgroups by UPN + +https://fedorahosted.org/sssd/ticket/2598 + +We need to return an empty result in cases an initgroups lookup by UPN +doesn't return anything. Please note testing with "id user" is not +sufficient as id calls a getpwnam first. + +Reviewed-by: Pavel Reichl +--- + src/responder/nss/nsssrv_cmd.c | 46 +++++++++++++++++++++++++----------------- + 1 file changed, 28 insertions(+), 18 deletions(-) + +diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c +index 19a6121d8cf0ccc1d6f9af797b2ac58a36df9e36..4c0e9414d2cdebe61fd91de06f4900f00904ef22 100644 +--- a/src/responder/nss/nsssrv_cmd.c ++++ b/src/responder/nss/nsssrv_cmd.c +@@ -4062,27 +4062,37 @@ static int nss_cmd_initgroups_search(struct nss_dom_ctx *dctx) + + if (cmdctx->name_is_upn) { + ret = sysdb_search_user_by_upn(cmdctx, dom, name, user_attrs, &msg); +- if (ret != EOK && ret != ENOENT) { ++ if (ret == ENOENT) { ++ dctx->res = talloc_zero(cmdctx, struct ldb_result); ++ if (dctx->res == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); ++ return ENOMEM; ++ } ++ ++ dctx->res->count = 0; ++ dctx->res->msgs = NULL; ++ ret = EOK; ++ } else if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_by_upn failed.\n"); + return ret; +- } ++ } else { ++ sysdb_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); ++ if (sysdb_name == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "Sysdb entry does not have a name.\n"); ++ return EINVAL; ++ } + +- sysdb_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); +- if (sysdb_name == NULL) { +- DEBUG(SSSDBG_OP_FAILURE, +- "Sysdb entry does not have a name.\n"); +- return EINVAL; +- } +- +- ret = sysdb_initgroups(cmdctx, dom, sysdb_name, &dctx->res); +- if (ret == EOK && DOM_HAS_VIEWS(dom)) { +- for (c = 0; c < dctx->res->count; c++) { +- ret = sysdb_add_overrides_to_object(dom, dctx->res->msgs[c], +- NULL, NULL); +- if (ret != EOK) { +- DEBUG(SSSDBG_OP_FAILURE, +- "sysdb_add_overrides_to_object failed.\n"); +- return ret; ++ ret = sysdb_initgroups(cmdctx, dom, sysdb_name, &dctx->res); ++ if (ret == EOK && DOM_HAS_VIEWS(dom)) { ++ for (c = 0; c < dctx->res->count; c++) { ++ ret = sysdb_add_overrides_to_object(dom, dctx->res->msgs[c], ++ NULL, NULL); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "sysdb_add_overrides_to_object failed.\n"); ++ return ret; ++ } + } + } + } +-- +2.4.0 + diff --git a/0024-MAN-libkrb5-and-SSSD-use-different-expansions.patch b/0024-MAN-libkrb5-and-SSSD-use-different-expansions.patch new file mode 100644 index 0000000..836fa10 --- /dev/null +++ b/0024-MAN-libkrb5-and-SSSD-use-different-expansions.patch @@ -0,0 +1,40 @@ +From e66ff0a610aa9342f16e61018963b2c7f1d60812 Mon Sep 17 00:00:00 2001 +From: Pavel Reichl +Date: Wed, 14 Jan 2015 12:06:01 -0500 +Subject: [PATCH 24/99] MAN: libkrb5 and SSSD use different expansions + +Users often wrongly use SSSD expansions in libkrb5 expansion template +for principals. State explicitly it won't work. + +Resolves: +https://fedorahosted.org/sssd/ticket/2528 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 33b8bf140b1d82d2626eeeaaea29af49dcdb3c99) +--- + src/man/sssd-krb5.5.xml | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/src/man/sssd-krb5.5.xml b/src/man/sssd-krb5.5.xml +index a774dce35fb6271fdb1c015adba4ff8576465010..9f61f8f707c6a97548919e8a67c37c9b135c756c 100644 +--- a/src/man/sssd-krb5.5.xml ++++ b/src/man/sssd-krb5.5.xml +@@ -222,6 +222,15 @@ + defined by krb5.conf. + + ++ NOTE: Please be aware that libkrb5 ccache expansion ++ template from ++ ++ krb5.conf ++ 5 ++ ++ uses different expansion sequences than SSSD. ++ ++ + Default: (from libkrb5) + + +-- +2.4.0 + diff --git a/0025-DEBUG-Add-missing-strings-for-error-messages.patch b/0025-DEBUG-Add-missing-strings-for-error-messages.patch new file mode 100644 index 0000000..238034d --- /dev/null +++ b/0025-DEBUG-Add-missing-strings-for-error-messages.patch @@ -0,0 +1,51 @@ +From b54376696a0f41b8187718c3589307dd1d9d1d4f Mon Sep 17 00:00:00 2001 +From: Michal Zidek +Date: Tue, 10 Mar 2015 17:30:48 +0100 +Subject: [PATCH 25/99] DEBUG: Add missing strings for error messages +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We had more error codes than corresponding +messages. Also order of two messages was +wrong. + +Reviewed-by: Lukáš Slebodník +--- + src/util/util_errors.c | 3 +++ + src/util/util_errors.h | 2 +- + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/util/util_errors.c b/src/util/util_errors.c +index bfae5cd189902ed82ba8b7db29e85a309e4bd19c..180d2e713b3cefdfdaabd9b3acc736c2aeaccbdf 100644 +--- a/src/util/util_errors.c ++++ b/src/util/util_errors.c +@@ -42,6 +42,9 @@ struct err_string error_to_str[] = { + { "Network I/O Error" }, /* ERR_NETWORK_IO */ + { "Account Expired" }, /* ERR_ACCOUNT_EXPIRED */ + { "Password Expired" }, /* ERR_PASSWORD_EXPIRED */ ++ { "Password Expired (reject access)" }, /* ERR_PASSWORD_EXPIRED_REJECT */ ++ { "Password Expired (warn user)" }, /* ERR_PASSWORD_EXPIRED_WARN */ ++ { "Password Expired (ask for new password)" }, /* ERR_PASSWORD_EXPIRED_RENEW */ + { "Host Access Denied" }, /* ERR_ACCESS_DENIED */ + { "SRV record not found" }, /* ERR_SRV_NOT_FOUND */ + { "SRV lookup error" }, /* ERR_SRV_LOOKUP_ERROR */ +diff --git a/src/util/util_errors.h b/src/util/util_errors.h +index 069d4b78aa5ed6c756affdacab99c7141b7849e4..5ebce631d4520944b387d20028e4f32613c1d3a8 100644 +--- a/src/util/util_errors.h ++++ b/src/util/util_errors.h +@@ -53,10 +53,10 @@ enum sssd_errors { + ERR_INVALID_CRED_TYPE, + ERR_NO_CREDS, + ERR_CREDS_EXPIRED, ++ ERR_CREDS_EXPIRED_CCACHE, + ERR_CREDS_INVALID, + ERR_NO_CACHED_CREDS, + ERR_CACHED_CREDS_EXPIRED, +- ERR_CREDS_EXPIRED_CCACHE, + ERR_AUTH_DENIED, + ERR_AUTH_FAILED, + ERR_CHPASS_DENIED, +-- +2.4.0 + diff --git a/0026-test-Check-ERR_LAST.patch b/0026-test-Check-ERR_LAST.patch new file mode 100644 index 0000000..93967e4 --- /dev/null +++ b/0026-test-Check-ERR_LAST.patch @@ -0,0 +1,78 @@ +From c82b150d9599e212a71996d3f987f9b236833fe4 Mon Sep 17 00:00:00 2001 +From: Michal Zidek +Date: Tue, 10 Mar 2015 18:38:10 +0100 +Subject: [PATCH 26/99] test: Check ERR_LAST +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Check if number of error codes and messages is the same. + +Reviewed-by: Lukáš Slebodník +--- + src/tests/util-tests.c | 10 ++++++++++ + src/util/util_errors.c | 1 + + src/util/util_errors.h | 2 +- + 3 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/src/tests/util-tests.c b/src/tests/util-tests.c +index 21eb02f14a7225ae9b9de4aa7f958b73f84a066d..7ee40dbca6b87b18c876caaa2a535b08d708415d 100644 +--- a/src/tests/util-tests.c ++++ b/src/tests/util-tests.c +@@ -1050,6 +1050,12 @@ START_TEST(test_convert_time) + } + END_TEST + ++START_TEST(test_sss_strerror_err_last) ++{ ++ ck_assert_str_eq(sss_strerror(ERR_LAST), "ERR_LAST"); ++} ++END_TEST ++ + Suite *util_suite(void) + { + Suite *s = suite_create("util"); +@@ -1102,11 +1108,15 @@ Suite *util_suite(void) + ck_leak_check_teardown); + tcase_add_test(tc_convert_time, test_convert_time); + ++ TCase *tc_sss_strerror = tcase_create("sss_strerror"); ++ tcase_add_test(tc_sss_strerror, test_sss_strerror_err_last); ++ + suite_add_tcase (s, tc_util); + suite_add_tcase (s, tc_utf8); + suite_add_tcase (s, tc_mh3); + suite_add_tcase (s, tc_atomicio); + suite_add_tcase (s, tc_convert_time); ++ suite_add_tcase (s, tc_sss_strerror); + + return s; + } +diff --git a/src/util/util_errors.c b/src/util/util_errors.c +index 180d2e713b3cefdfdaabd9b3acc736c2aeaccbdf..dad988bce2515c3614a19205f038053152916a16 100644 +--- a/src/util/util_errors.c ++++ b/src/util/util_errors.c +@@ -69,6 +69,7 @@ struct err_string error_to_str[] = { + { "Error setting SELinux user context" }, /* ERR_SELINUX_CONTEXT */ + { "Username format not allowed by re_expression" }, /* ERR_REGEX_NOMATCH */ + { "Time specification not supported" }, /* ERR_TIMESPEC_NOT_SUPPORTED */ ++ { "ERR_LAST" } /* ERR_LAST */ + }; + + +diff --git a/src/util/util_errors.h b/src/util/util_errors.h +index 5ebce631d4520944b387d20028e4f32613c1d3a8..5d657c707dabc74cf5771af2b601500ba2664ee0 100644 +--- a/src/util/util_errors.h ++++ b/src/util/util_errors.h +@@ -97,7 +97,7 @@ enum sssd_errors { + #define SSSD_ERR_BASE(err) ((err) & ~ERR_MASK) + #define SSSD_ERR_IDX(err) ((err) & ERR_MASK) + #define IS_SSSD_ERROR(err) \ +- ((SSSD_ERR_BASE(err) == ERR_BASE) && ((err) < ERR_LAST)) ++ ((SSSD_ERR_BASE(err) == ERR_BASE) && ((err) <= ERR_LAST)) + + #define ERR_OK 0 + /* Backwards compat */ +-- +2.4.0 + diff --git a/0027-PAM-use-the-logon_name-as-the-key-for-the-PAM-initgr.patch b/0027-PAM-use-the-logon_name-as-the-key-for-the-PAM-initgr.patch new file mode 100644 index 0000000..682c898 --- /dev/null +++ b/0027-PAM-use-the-logon_name-as-the-key-for-the-PAM-initgr.patch @@ -0,0 +1,73 @@ +From e9457990c14446fc46b72f7f927e6d5fc776d490 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Thu, 5 Mar 2015 15:10:43 +0100 +Subject: [PATCH 27/99] PAM: use the logon_name as the key for the PAM initgr + cache + +Currently the name member of the pam_data struct is used as a key but it +can change during a request. Especially for sub-domain users the name is +changed from the short to the fully-qualified version before the cache +entry is created. As a result the cache searches are always done with +the short name while the entry was written with the fully-qualified name. + +The logon_name member of the pam_data struct contains the name which was +send by the PAM client and is never changed during the request. + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 7bbf9d1d054f0571fa90ff5dd400a6f4a5a7f6c8) +--- + src/responder/pam/pamsrv_cmd.c | 16 +++------------- + 1 file changed, 3 insertions(+), 13 deletions(-) + +diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c +index 86e763f825096edc0c07adbe2e02820e5f2bdac9..0b54402729e77f22391c6bd17fd8c937ddea3592 100644 +--- a/src/responder/pam/pamsrv_cmd.c ++++ b/src/responder/pam/pamsrv_cmd.c +@@ -1140,7 +1140,8 @@ static int pam_check_user_search(struct pam_auth_req *preq) + * the number of updates within a reasonable timeout + */ + if (preq->check_provider) { +- ret = pam_initgr_check_timeout(pctx->id_table, name); ++ ret = pam_initgr_check_timeout(pctx->id_table, ++ preq->pd->logon_name); + if (ret != EOK + && ret != ENOENT) { + DEBUG(SSSDBG_OP_FAILURE, +@@ -1334,7 +1335,6 @@ static void pam_check_user_dp_callback(uint16_t err_maj, uint32_t err_min, + int ret; + struct pam_ctx *pctx = + talloc_get_type(preq->cctx->rctx->pvt_ctx, struct pam_ctx); +- char *name; + + if (err_maj) { + DEBUG(SSSDBG_OP_FAILURE, +@@ -1346,17 +1346,8 @@ static void pam_check_user_dp_callback(uint16_t err_maj, uint32_t err_min, + ret = pam_check_user_search(preq); + if (ret == EOK) { + /* Make sure we don't go to the ID provider too often */ +- name = preq->domain->case_sensitive ? +- talloc_strdup(preq, preq->pd->user) : +- sss_tc_utf8_str_tolower(preq, preq->pd->user); +- if (!name) { +- ret = ENOMEM; +- goto done; +- } +- + ret = pam_initgr_cache_set(pctx->rctx->ev, pctx->id_table, +- name, pctx->id_timeout); +- talloc_free(name); ++ preq->pd->logon_name, pctx->id_timeout); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Could not save initgr timestamp. " +@@ -1371,7 +1362,6 @@ static void pam_check_user_dp_callback(uint16_t err_maj, uint32_t err_min, + + ret = pam_check_user_done(preq, ret); + +-done: + if (ret) { + preq->pd->pam_status = PAM_SYSTEM_ERR; + pam_reply(preq); +-- +2.4.0 + diff --git a/0028-pam_initgr_check_timeout-add-debug-output.patch b/0028-pam_initgr_check_timeout-add-debug-output.patch new file mode 100644 index 0000000..9c2dd98 --- /dev/null +++ b/0028-pam_initgr_check_timeout-add-debug-output.patch @@ -0,0 +1,37 @@ +From d505e55f761124fa4cce7e0bc5ea27fbfb8f2ddb Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Thu, 5 Mar 2015 15:26:35 +0100 +Subject: [PATCH 28/99] pam_initgr_check_timeout: add debug output + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 10da5ea89b2b963e5e0bb0e0113d118e3bdea892) +--- + src/responder/pam/pam_helpers.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/responder/pam/pam_helpers.c b/src/responder/pam/pam_helpers.c +index 1b94f7adf34b3c1f02c302c6161de4ef6e296cc1..586888cae48ced8d6a6f47234fbec0ef89dd84d2 100644 +--- a/src/responder/pam/pam_helpers.c ++++ b/src/responder/pam/pam_helpers.c +@@ -140,14 +140,18 @@ errno_t pam_initgr_check_timeout(hash_table_t *id_table, + hret = hash_lookup(id_table, &key, &val); + if (hret != HASH_SUCCESS + && hret != HASH_ERROR_KEY_NOT_FOUND) { ++ DEBUG(SSSDBG_TRACE_ALL, "Error searching user [%s] in PAM cache.\n", ++ name); + return EIO; + } else if (hret == HASH_ERROR_KEY_NOT_FOUND) { ++ DEBUG(SSSDBG_TRACE_ALL, "User [%s] not found in PAM cache.\n", name); + return ENOENT; + } + + /* If there's a value here, then the cache + * entry is still valid. + */ ++ DEBUG(SSSDBG_TRACE_INTERNAL, "User [%s] found in PAM cache.\n", name); + return EOK; + } + +-- +2.4.0 + diff --git a/0029-ipa-do-not-treat-missing-sub-domain-users-as-error.patch b/0029-ipa-do-not-treat-missing-sub-domain-users-as-error.patch new file mode 100644 index 0000000..21e62e1 --- /dev/null +++ b/0029-ipa-do-not-treat-missing-sub-domain-users-as-error.patch @@ -0,0 +1,37 @@ +From 8d13b13f8f5bbcdac7161d55d60cb5eedaccd95c Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Wed, 4 Mar 2015 15:05:11 +0100 +Subject: [PATCH 29/99] ipa: do not treat missing sub-domain users as error + +Resolves: https://fedorahosted.org/sssd/ticket/2444 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 3e9712c2fdbba8f9cd25886943331e76e0b2cedd) +--- + src/providers/ipa/ipa_s2n_exop.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c +index 18f2a867df3ad705008537843ea94e38dab0006e..d5e94806115df8fc6c6fcb9af9782f51119ba7f0 100644 +--- a/src/providers/ipa/ipa_s2n_exop.c ++++ b/src/providers/ipa/ipa_s2n_exop.c +@@ -147,9 +147,13 @@ static void ipa_s2n_exop_done(struct sdap_op *op, + sss_ldap_err2string(result), result, errmsg); + + if (result != LDAP_SUCCESS) { +- DEBUG(SSSDBG_OP_FAILURE, "ldap_extended_operation failed, " \ +- "server logs might contain more details.\n"); +- ret = ERR_NETWORK_IO; ++ if (result == LDAP_NO_SUCH_OBJECT) { ++ ret = ENOENT; ++ } else { ++ DEBUG(SSSDBG_OP_FAILURE, "ldap_extended_operation failed, server " \ ++ "logs might contain more details.\n"); ++ ret = ERR_NETWORK_IO; ++ } + goto done; + } + +-- +2.4.0 + diff --git a/0030-ipa-make-sure-extdom-expo-data-is-available.patch b/0030-ipa-make-sure-extdom-expo-data-is-available.patch new file mode 100644 index 0000000..4fd5789 --- /dev/null +++ b/0030-ipa-make-sure-extdom-expo-data-is-available.patch @@ -0,0 +1,30 @@ +From 052e37d891612ea4637c6de99cc4982383d65947 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Wed, 4 Mar 2015 14:08:09 +0100 +Subject: [PATCH 30/99] ipa: make sure extdom expo data is available + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 7ee9ac32485483beece872d6fcb3096fa77a004b) +--- + src/providers/ipa/ipa_s2n_exop.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c +index d5e94806115df8fc6c6fcb9af9782f51119ba7f0..d3502443c59b96fa854fff199833cf1239a8955e 100644 +--- a/src/providers/ipa/ipa_s2n_exop.c ++++ b/src/providers/ipa/ipa_s2n_exop.c +@@ -165,6 +165,11 @@ static void ipa_s2n_exop_done(struct sdap_op *op, + ret = ERR_NETWORK_IO; + goto done; + } ++ if (retdata == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Missing exop result data.\n"); ++ ret = EINVAL; ++ goto done; ++ } + + state->retoid = talloc_strdup(state, retoid); + if (state->retoid == NULL) { +-- +2.4.0 + diff --git a/0031-ipa_selinux-Fix-warning-may-be-used-uninitialized.patch b/0031-ipa_selinux-Fix-warning-may-be-used-uninitialized.patch new file mode 100644 index 0000000..0b1ece1 --- /dev/null +++ b/0031-ipa_selinux-Fix-warning-may-be-used-uninitialized.patch @@ -0,0 +1,35 @@ +From befd8f4639ecef8185e82092beae801d68fa7eae Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik +Date: Fri, 13 Mar 2015 12:38:29 +0100 +Subject: [PATCH 31/99] ipa_selinux: Fix warning may be used uninitialized + +src/providers/ipa/ipa_selinux.c: In function 'ipa_selinux_handler_done': +src/providers/ipa/ipa_selinux.c:927:16: error: 'sci' may be used uninitialized in this function [-Werror=maybe-uninitialized] + state->sci = sci; + ^ +src/providers/ipa/ipa_selinux.c:333:33: note: 'sci' was declared here + struct selinux_child_input *sci; + ^ +cc1: all warnings being treated as errors + +Reviewed-by: Jakub Hrozek +--- + src/providers/ipa/ipa_selinux.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/providers/ipa/ipa_selinux.c b/src/providers/ipa/ipa_selinux.c +index 00c793a2643b51e59884730fa4f0ba3c7ed1bea6..19bda3c461c712efebc61265dd8f69ab50be5f2a 100644 +--- a/src/providers/ipa/ipa_selinux.c ++++ b/src/providers/ipa/ipa_selinux.c +@@ -330,7 +330,7 @@ static void ipa_selinux_handler_done(struct tevent_req *req) + struct sysdb_attrs **hbac_rules = 0; + struct sysdb_attrs **best_match_maps; + struct map_order_ctx *map_order_ctx; +- struct selinux_child_input *sci; ++ struct selinux_child_input *sci = NULL; + struct tevent_req *child_req; + + ret = ipa_get_selinux_recv(req, breq, &map_count, &maps, +-- +2.4.0 + diff --git a/0032-LDAP-AD-do-not-resolve-group-members-during-tokenGro.patch b/0032-LDAP-AD-do-not-resolve-group-members-during-tokenGro.patch new file mode 100644 index 0000000..22a1d82 --- /dev/null +++ b/0032-LDAP-AD-do-not-resolve-group-members-during-tokenGro.patch @@ -0,0 +1,297 @@ +From b8d9eca0d9469c1209161b31a0109d8e4ea2868c Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Mon, 9 Mar 2015 16:36:29 +0100 +Subject: [PATCH 32/99] LDAP/AD: do not resolve group members during + tokenGroups request + +During initgroups requests we try to avoid to resolve the complete +member list of groups if possible, e.g. if there are no nested groups. +The tokenGroups LDAP lookup return the complete list of memberships for +a user hence it is not necessary lookup the other group member and +un-roll nested groups. With this patch only the group entry is looked up +and saved as incomplete group to the cache. + +This is achieved by adding a new boolean parameter no_members to +groups_get_send() and sdap_get_groups_send(). The difference to config +options like ldap_group_nesting_level = 0 or ignore_group_members is +that if no_members is set to true groups which are missing in the cache +are created a incomplete groups. As a result a request to lookup this +group will trigger a new LDAP request to resolve the group completely. +This way no information is ignored but the time needed to read all data +is better distributed between different requests. + +https://fedorahosted.org/sssd/ticket/2601 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit d81d8d3dc151ebc95cd0e3f3b14c1cdaa48980f1) +--- + src/providers/ipa/ipa_subdomains_ext_groups.c | 2 +- + src/providers/ldap/ldap_common.h | 3 ++- + src/providers/ldap/ldap_id.c | 14 +++++++---- + src/providers/ldap/sdap_async.h | 3 ++- + src/providers/ldap/sdap_async_enum.c | 2 +- + src/providers/ldap/sdap_async_groups.c | 36 ++++++++++++++++++++++++++- + src/providers/ldap/sdap_async_initgroups.c | 14 +++++------ + src/providers/ldap/sdap_async_initgroups_ad.c | 2 +- + src/providers/ldap/sdap_async_private.h | 6 +++++ + 9 files changed, 64 insertions(+), 18 deletions(-) + +diff --git a/src/providers/ipa/ipa_subdomains_ext_groups.c b/src/providers/ipa/ipa_subdomains_ext_groups.c +index ad278b248ec2a2a157fed0a455dbe97049e83f9d..976a71cfe3ab42425e3884c5f6d9e096fe61bb34 100644 +--- a/src/providers/ipa/ipa_subdomains_ext_groups.c ++++ b/src/providers/ipa/ipa_subdomains_ext_groups.c +@@ -872,7 +872,7 @@ static void ipa_add_ad_memberships_get_next(struct tevent_req *req) + state->sdap_id_ctx->conn, + (const char *) val->data, + BE_FILTER_NAME, BE_ATTR_CORE, +- false); ++ false, false); + if (subreq == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "groups_get_send failed.\n"); + ret = ENOMEM; +diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h +index bf69489a79e903a98878edb53d372d2242df2b0f..57ad1b8458988d7e108f019c20f67bcde32539d4 100644 +--- a/src/providers/ldap/ldap_common.h ++++ b/src/providers/ldap/ldap_common.h +@@ -212,7 +212,8 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx, + const char *name, + int filter_type, + int attrs_type, +- bool noexist_delete); ++ bool noexist_delete, ++ bool no_members); + int groups_get_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret); + + struct tevent_req *ldap_netgroup_get_send(TALLOC_CTX *memctx, +diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c +index 6de5b72a8b66cd95b16d25a2c37dc21a57695de3..55bb3c9fbd6f623e7795d7399c9e5ac4d5192e85 100644 +--- a/src/providers/ldap/ldap_id.c ++++ b/src/providers/ldap/ldap_id.c +@@ -528,6 +528,7 @@ struct groups_get_state { + int dp_error; + int sdap_ret; + bool noexist_delete; ++ bool no_members; + }; + + static int groups_get_retry(struct tevent_req *req); +@@ -544,7 +545,8 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx, + const char *name, + int filter_type, + int attrs_type, +- bool noexist_delete) ++ bool noexist_delete, ++ bool no_members) + { + struct tevent_req *req; + struct groups_get_state *state; +@@ -567,6 +569,7 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx, + state->conn = conn; + state->dp_error = DP_ERR_FATAL; + state->noexist_delete = noexist_delete; ++ state->no_members = no_members; + + state->op = sdap_id_op_create(state, state->conn->conn_cache); + if (!state->op) { +@@ -713,7 +716,8 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx, + + /* TODO: handle attrs_type */ + ret = build_attrs_from_map(state, ctx->opts->group_map, SDAP_OPTS_GROUP, +- state->domain->ignore_group_members ? ++ (state->domain->ignore_group_members ++ || state->no_members) ? + (const char **)member_filter : NULL, + &state->attrs, NULL); + +@@ -845,7 +849,7 @@ static void groups_get_search(struct tevent_req *req) + state->attrs, state->filter, + dp_opt_get_int(state->ctx->opts->basic, + SDAP_SEARCH_TIMEOUT), +- false); ++ false, state->no_members); + if (!subreq) { + tevent_req_error(req, ENOMEM); + return; +@@ -1383,7 +1387,7 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, + ar->filter_value, + ar->filter_type, + ar->attr_type, +- noexist_delete); ++ noexist_delete, false); + break; + + case BE_REQ_INITGROUPS: /* init groups for user */ +@@ -1718,7 +1722,7 @@ static struct tevent_req *get_user_and_group_send(TALLOC_CTX *memctx, + subreq = groups_get_send(req, state->ev, state->id_ctx, + state->sdom, state->conn, + state->filter_val, state->filter_type, +- state->attrs_type, state->noexist_delete); ++ state->attrs_type, state->noexist_delete, false); + if (subreq == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "users_get_send failed.\n"); + ret = ENOMEM; +diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h +index 1239f28c173373aac23c5796d694c7bd5ca24c96..ef9b3bbadba830bcf730b6fa70867c17d51380af 100644 +--- a/src/providers/ldap/sdap_async.h ++++ b/src/providers/ldap/sdap_async.h +@@ -96,7 +96,8 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx, + const char **attrs, + const char *filter, + int timeout, +- bool enumeration); ++ bool enumeration, ++ bool no_members); + int sdap_get_groups_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, char **timestamp); + +diff --git a/src/providers/ldap/sdap_async_enum.c b/src/providers/ldap/sdap_async_enum.c +index 242b3172f367b0b35738bd2e86ea927a4409d2d6..1cc09abdf1aa14e3d1690ea1abe32604ae4ff1cd 100644 +--- a/src/providers/ldap/sdap_async_enum.c ++++ b/src/providers/ldap/sdap_async_enum.c +@@ -811,7 +811,7 @@ static struct tevent_req *enum_groups_send(TALLOC_CTX *memctx, + state->attrs, state->filter, + dp_opt_get_int(state->ctx->opts->basic, + SDAP_ENUM_SEARCH_TIMEOUT), +- true); ++ true, false); + if (!subreq) { + ret = ENOMEM; + goto fail; +diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c +index c86b5c6b59a4de7e945b95cafae9149f681e2e18..818f30b95d4a4707c32d16b9866b008d89141e4d 100644 +--- a/src/providers/ldap/sdap_async_groups.c ++++ b/src/providers/ldap/sdap_async_groups.c +@@ -1750,6 +1750,7 @@ struct sdap_get_groups_state { + char *filter; + int timeout; + bool enumeration; ++ bool no_members; + + char *higher_usn; + struct sysdb_attrs **groups; +@@ -1779,7 +1780,8 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx, + const char **attrs, + const char *filter, + int timeout, +- bool enumeration) ++ bool enumeration, ++ bool no_members) + { + errno_t ret; + struct tevent_req *req; +@@ -1802,6 +1804,7 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx, + state->count = 0; + state->timeout = timeout; + state->enumeration = enumeration; ++ state->no_members = no_members; + state->base_filter = filter; + state->base_iter = 0; + state->search_bases = sdom->group_search_bases; +@@ -1926,6 +1929,7 @@ static void sdap_get_groups_process(struct tevent_req *subreq) + bool next_base = false; + size_t count; + struct sysdb_attrs **groups; ++ char **groupnamelist; + + ret = sdap_get_generic_recv(subreq, state, + &count, &groups); +@@ -1992,6 +1996,36 @@ static void sdap_get_groups_process(struct tevent_req *subreq) + return; + } + ++ if (state->no_members) { ++ ret = sysdb_attrs_primary_name_list(state->sysdb, state, ++ state->groups, state->count, ++ state->opts->group_map[SDAP_AT_GROUP_NAME].name, ++ &groupnamelist); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "sysdb_attrs_primary_name_list failed.\n"); ++ tevent_req_error(req, ret); ++ return; ++ } ++ ++ ret = sdap_add_incomplete_groups(state->sysdb, state->dom, state->opts, ++ groupnamelist, state->groups, ++ state->count); ++ if (ret == EOK) { ++ DEBUG(SSSDBG_TRACE_LIBS, ++ "Reading only group data without members successful.\n"); ++ tevent_req_done(req); ++ } else { ++ DEBUG(SSSDBG_OP_FAILURE, "sdap_add_incomplete_groups failed.\n"); ++ tevent_req_error(req, ret); ++ } ++ return; ++ ++ ret = sdap_save_groups(state, state->sysdb, state->dom, state->opts, ++ state->groups, state->count, false, ++ NULL, true, NULL); ++ } ++ + /* Check whether we need to do nested searches + * for RFC2307bis/FreeIPA/ActiveDirectory + * We don't need to do this for enumeration, +diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c +index 48c16b71637f83399d9a523f64f6d812b91681ef..2fd235f2868b877c0e5d5d9f7b1b76d269eee8ee 100644 +--- a/src/providers/ldap/sdap_async_initgroups.c ++++ b/src/providers/ldap/sdap_async_initgroups.c +@@ -29,12 +29,12 @@ + #include "providers/ldap/sdap_users.h" + + /* ==Save-fake-group-list=====================================*/ +-static errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb, +- struct sss_domain_info *domain, +- struct sdap_options *opts, +- char **groupnames, +- struct sysdb_attrs **ldap_groups, +- int ldap_groups_count) ++errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb, ++ struct sss_domain_info *domain, ++ struct sdap_options *opts, ++ char **groupnames, ++ struct sysdb_attrs **ldap_groups, ++ int ldap_groups_count) + { + TALLOC_CTX *tmp_ctx; + struct ldb_message *msg; +@@ -3152,7 +3152,7 @@ static void sdap_get_initgr_done(struct tevent_req *subreq) + + subreq = groups_get_send(req, state->ev, state->id_ctx, + state->id_ctx->opts->sdom, state->conn, +- gid, BE_FILTER_IDNUM, BE_ATTR_ALL, NULL); ++ gid, BE_FILTER_IDNUM, BE_ATTR_ALL, false, false); + if (!subreq) { + ret = ENOMEM; + goto fail; +diff --git a/src/providers/ldap/sdap_async_initgroups_ad.c b/src/providers/ldap/sdap_async_initgroups_ad.c +index 1b8c8d981ea14ac0fca0903f16296c8a6701c5dd..9915f1863f172d5d3f59afe03abbbfb87fdf3409 100644 +--- a/src/providers/ldap/sdap_async_initgroups_ad.c ++++ b/src/providers/ldap/sdap_async_initgroups_ad.c +@@ -630,7 +630,7 @@ static errno_t sdap_ad_resolve_sids_step(struct tevent_req *req) + + subreq = groups_get_send(state, state->ev, state->id_ctx, sdap_domain, + state->conn, state->current_sid, +- BE_FILTER_SECID, BE_ATTR_CORE, false); ++ BE_FILTER_SECID, BE_ATTR_CORE, false, true); + if (subreq == NULL) { + return ENOMEM; + } +diff --git a/src/providers/ldap/sdap_async_private.h b/src/providers/ldap/sdap_async_private.h +index e689394c5db8a3385c333e6b98372c6f6d34366c..3995a2ac357c52f546696284d71d2127d0302409 100644 +--- a/src/providers/ldap/sdap_async_private.h ++++ b/src/providers/ldap/sdap_async_private.h +@@ -132,4 +132,10 @@ errno_t sdap_nested_group_recv(TALLOC_CTX *mem_ctx, + unsigned long *_num_groups, + struct sysdb_attrs ***_groups); + ++errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb, ++ struct sss_domain_info *domain, ++ struct sdap_options *opts, ++ char **groupnames, ++ struct sysdb_attrs **ldap_groups, ++ int ldap_groups_count); + #endif /* _SDAP_ASYNC_PRIVATE_H_ */ +-- +2.4.0 + diff --git a/0033-IPA-idviews-check-if-view-name-is-set.patch b/0033-IPA-idviews-check-if-view-name-is-set.patch new file mode 100644 index 0000000..a3a0b23 --- /dev/null +++ b/0033-IPA-idviews-check-if-view-name-is-set.patch @@ -0,0 +1,50 @@ +From 2c7b61d223667868d284711fc0800cb9d34177e9 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Tue, 17 Mar 2015 11:08:05 +0100 +Subject: [PATCH 33/99] IPA idviews: check if view name is set + +When working with older FreeIPA releases the view name might not always +been set. This patch add checks to might sure it is only dereferenced +when set. + +Resolves https://fedorahosted.org/sssd/ticket/2604 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 8be0cf3eea892e13410c13abb030322599ca1b4f) +--- + src/providers/ipa/ipa_s2n_exop.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c +index d3502443c59b96fa854fff199833cf1239a8955e..89fe0ce2289e58e0199a394a1377758569f463f7 100644 +--- a/src/providers/ipa/ipa_s2n_exop.c ++++ b/src/providers/ipa/ipa_s2n_exop.c +@@ -1036,7 +1036,8 @@ static void ipa_s2n_get_fqlist_next(struct tevent_req *subreq) + goto fail; + } + +- if (strcmp(state->ipa_ctx->view_name, SYSDB_DEFAULT_VIEW_NAME) == 0) { ++ if (state->ipa_ctx->view_name == NULL || ++ strcmp(state->ipa_ctx->view_name, SYSDB_DEFAULT_VIEW_NAME) == 0) { + ret = ipa_s2n_get_fqlist_save_step(req); + if (ret == EOK) { + tevent_req_done(req); +@@ -1611,6 +1612,7 @@ static void ipa_s2n_get_user_done(struct tevent_req *subreq) + } + + if (ret == ENOENT ++ || state->ipa_ctx->view_name == NULL + || strcmp(state->ipa_ctx->view_name, + SYSDB_DEFAULT_VIEW_NAME) == 0) { + ret = ipa_s2n_save_objects(state->dom, state->req_input, state->attrs, +@@ -2220,6 +2222,7 @@ static void ipa_s2n_get_fqlist_done(struct tevent_req *subreq) + } + + if (state->override_attrs == NULL ++ && state->ipa_ctx->view_name != NULL + && strcmp(state->ipa_ctx->view_name, + SYSDB_DEFAULT_VIEW_NAME) != 0) { + subreq = ipa_get_ad_override_send(state, state->ev, +-- +2.4.0 + diff --git a/0017-selinux-Handle-setup-with-empty-default-and-no-confi.patch b/0034-selinux-Handle-setup-with-empty-default-and-no-confi.patch similarity index 92% rename from 0017-selinux-Handle-setup-with-empty-default-and-no-confi.patch rename to 0034-selinux-Handle-setup-with-empty-default-and-no-confi.patch index 28c1443..5e5b9a1 100644 --- a/0017-selinux-Handle-setup-with-empty-default-and-no-confi.patch +++ b/0034-selinux-Handle-setup-with-empty-default-and-no-confi.patch @@ -1,7 +1,7 @@ -From 4c047cc4720227ca7ad80f02546493ba6e0199ef Mon Sep 17 00:00:00 2001 +From 4b6ee69fb1f713aae125b0fc2d345846e7a0d642 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Thu, 12 Mar 2015 16:31:13 +0100 -Subject: [PATCH 17/17] selinux: Handle setup with empty default and no +Subject: [PATCH 34/99] selinux: Handle setup with empty default and no configured rules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -21,7 +21,7 @@ Reviewed-by: Michal Židek 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/providers/ipa/ipa_selinux.c b/src/providers/ipa/ipa_selinux.c -index 00c793a2643b51e59884730fa4f0ba3c7ed1bea6..cdb0dfa388eb3743e0b937befd63cf05ae94b71e 100644 +index 19bda3c461c712efebc61265dd8f69ab50be5f2a..631f9ab80afba7dbdb091823b0fb4a0dc1126d49 100644 --- a/src/providers/ipa/ipa_selinux.c +++ b/src/providers/ipa/ipa_selinux.c @@ -808,7 +808,7 @@ selinux_child_setup(TALLOC_CTX *mem_ctx, @@ -78,5 +78,5 @@ index 3756557a5e28624e6437e805ca8a387d2f65dd1f..81c1de877ef08a299d07837fefcd195d } else { if ((p + len ) > size) return EINVAL; -- -2.3.3 +2.4.0 diff --git a/0035-IPA-make-sure-output-variable-is-set.patch b/0035-IPA-make-sure-output-variable-is-set.patch new file mode 100644 index 0000000..96fb330 --- /dev/null +++ b/0035-IPA-make-sure-output-variable-is-set.patch @@ -0,0 +1,29 @@ +From ee3cd052a2aca57040a9b435def5442922f8af76 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Thu, 19 Mar 2015 14:26:26 +0100 +Subject: [PATCH 35/99] IPA: make sure output variable is set + +Reviewed-by: Pavel Reichl +(cherry picked from commit abb093b4ae10f2a5748bf9f194bf76794002eba0) +--- + src/providers/ipa/ipa_s2n_exop.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c +index 89fe0ce2289e58e0199a394a1377758569f463f7..c7fd1009b14bcfa7502236bbf707fcbe72f537c1 100644 +--- a/src/providers/ipa/ipa_s2n_exop.c ++++ b/src/providers/ipa/ipa_s2n_exop.c +@@ -1253,7 +1253,9 @@ static errno_t process_members(struct sss_domain_info *domain, + + if (members == NULL) { + DEBUG(SSSDBG_TRACE_INTERNAL, "No members\n"); +- *_missing_members = NULL; ++ if (_missing_members != NULL) { ++ *_missing_members = NULL; ++ } + return EOK; + } + +-- +2.4.0 + diff --git a/0036-IPA-set-EINVAL-if-dn-can-t-be-linearized.patch b/0036-IPA-set-EINVAL-if-dn-can-t-be-linearized.patch new file mode 100644 index 0000000..065767b --- /dev/null +++ b/0036-IPA-set-EINVAL-if-dn-can-t-be-linearized.patch @@ -0,0 +1,26 @@ +From e8f5e135b4d389a1ae224da174c15dfe66b30810 Mon Sep 17 00:00:00 2001 +From: Pavel Reichl +Date: Thu, 19 Mar 2015 10:21:21 -0400 +Subject: [PATCH 36/99] IPA: set EINVAL if dn can't be linearized + +Reviewed-by: Sumit Bose +(cherry picked from commit 131da4d9f40e0e407d7bcae18ff16507976bc6c7) +--- + src/providers/ipa/ipa_s2n_exop.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c +index c7fd1009b14bcfa7502236bbf707fcbe72f537c1..a844ee99d25ec28bb02ec7b7fd0afa722b6ac189 100644 +--- a/src/providers/ipa/ipa_s2n_exop.c ++++ b/src/providers/ipa/ipa_s2n_exop.c +@@ -1293,6 +1293,7 @@ static errno_t process_members(struct sss_domain_info *domain, + dn_str = ldb_dn_get_linearized(msg->dn); + if (dn_str == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_get_linearized failed.\n"); ++ ret = EINVAL; + goto done; + } + +-- +2.4.0 + diff --git a/0037-GPO-error-out-instead-of-leaving-array-element-unini.patch b/0037-GPO-error-out-instead-of-leaving-array-element-unini.patch new file mode 100644 index 0000000..5d87c05 --- /dev/null +++ b/0037-GPO-error-out-instead-of-leaving-array-element-unini.patch @@ -0,0 +1,38 @@ +From 0d628f98500a0fd642ba0c720c40393460988f73 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 20 Mar 2015 18:41:52 +0100 +Subject: [PATCH 37/99] GPO: error out instead of leaving array element + uninitialized + +In general every object created by the AD provider should have a SID +attribute. Since SIDs and GPOs are used for access control a missing SID +should be treated as error for now until it is known if there is a valid +reason why the SID is missing. + +Resolves https://fedorahosted.org/sssd/ticket/2608 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 4cfab2330323834574c179f774a0c6b1fff4936e) +--- + src/providers/ad/ad_gpo.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c +index c45b7963e221ae30e0c003762e4a8320449cd211..69ff6daaa7e060cca4cab129ecde83d3406702d1 100644 +--- a/src/providers/ad/ad_gpo.c ++++ b/src/providers/ad/ad_gpo.c +@@ -581,7 +581,10 @@ ad_gpo_get_sids(TALLOC_CTX *mem_ctx, + group_sid = ldb_msg_find_attr_as_string(res->msgs[i+1], + SYSDB_SID_STR, NULL); + if (group_sid == NULL) { +- continue; ++ DEBUG(SSSDBG_CRIT_FAILURE, "Missing SID for cache entry [%s].\n", ++ ldb_dn_get_linearized(res->msgs[i+1]->dn)); ++ ret = EINVAL; ++ goto done; + } + + group_sids[i] = talloc_steal(group_sids, group_sid); +-- +2.4.0 + diff --git a/0038-LDAP-remove-unused-code.patch b/0038-LDAP-remove-unused-code.patch new file mode 100644 index 0000000..6e0883e --- /dev/null +++ b/0038-LDAP-remove-unused-code.patch @@ -0,0 +1,39 @@ +From f5c1ef14c603dda7ca3e5d9fe8c4cf54d72e97f2 Mon Sep 17 00:00:00 2001 +From: Pavel Reichl +Date: Fri, 20 Mar 2015 05:23:49 -0400 +Subject: [PATCH 38/99] LDAP: remove unused code + +Also fix debug message. + +Reviewed-by: Jakub Hrozek +(cherry picked from commit ef9ca5848ea08aafa0827f5d2922d49130ba324d) +--- + src/providers/ldap/sdap_async_groups.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c +index 818f30b95d4a4707c32d16b9866b008d89141e4d..7779d499de87e2f0657512cb1f8e1980f9bf1f71 100644 +--- a/src/providers/ldap/sdap_async_groups.c ++++ b/src/providers/ldap/sdap_async_groups.c +@@ -2013,17 +2013,13 @@ static void sdap_get_groups_process(struct tevent_req *subreq) + state->count); + if (ret == EOK) { + DEBUG(SSSDBG_TRACE_LIBS, +- "Reading only group data without members successful.\n"); ++ "Writing only group data without members was successful.\n"); + tevent_req_done(req); + } else { + DEBUG(SSSDBG_OP_FAILURE, "sdap_add_incomplete_groups failed.\n"); + tevent_req_error(req, ret); + } + return; +- +- ret = sdap_save_groups(state, state->sysdb, state->dom, state->opts, +- state->groups, state->count, false, +- NULL, true, NULL); + } + + /* Check whether we need to do nested searches +-- +2.4.0 + diff --git a/0039-memberof-Do-not-create-request-with-0-attribute-valu.patch b/0039-memberof-Do-not-create-request-with-0-attribute-valu.patch new file mode 100644 index 0000000..6fcbfbc --- /dev/null +++ b/0039-memberof-Do-not-create-request-with-0-attribute-valu.patch @@ -0,0 +1,42 @@ +From cbab37e665d948278a491733e3993ac62beb0427 Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik +Date: Wed, 11 Mar 2015 18:11:13 +0100 +Subject: [PATCH 39/99] memberof: Do not create request with 0 attribute values + +[sysdb_set_entry_attr] (0x0080): ldb_modify failed: [Constraint violation](19) + [attribute 'ghost': attribute on 'name=Escalation,cn=groups,cn=LDAP,cn=sysdb' + specified, but with 0 values (illegal)] +[sysdb_error_to_errno] (0x0020): LDB returned unexpected error: + [Constraint violation] +[sysdb_set_entry_attr] (0x0040): Error: 14 (Bad address) +[sdap_store_group_with_gid] (0x0040): Could not store group Escalation +[sdap_save_group] (0x0080): Could not store group with GID: [Bad address] +[sdap_save_group] (0x0080): Failed to save group [Escalation]: [Bad address] +[sdap_save_groups] (0x0040): Failed to store group 1. Ignoring. + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 999c87114479f230c840a5c020e107c45b29fd56) +--- + src/ldb_modules/memberof.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/ldb_modules/memberof.c b/src/ldb_modules/memberof.c +index 995c382a8ee36bfc010f2761010db1fb48343d5d..4d7b23ea1b95bed0ec5c7cc717b95e6da3cd0717 100644 +--- a/src/ldb_modules/memberof.c ++++ b/src/ldb_modules/memberof.c +@@ -3302,6 +3302,12 @@ static int mbof_inherited_mod(struct mbof_mod_ctx *mod_ctx) + } + el->num_values = j; + ++ if (el->num_values == 0) { ++ /* nothing to do */ ++ /* We cannot modify element which has 0 values */ ++ msg->num_elements = 0; ++ } ++ + mod_ctx->igh->mod_msg = msg; + mod_ctx->igh->el = el; + +-- +2.4.0 + diff --git a/0040-tests-convert-all-unit-tests-to-cmocka-1.0-or-later.patch b/0040-tests-convert-all-unit-tests-to-cmocka-1.0-or-later.patch new file mode 100644 index 0000000..06855de --- /dev/null +++ b/0040-tests-convert-all-unit-tests-to-cmocka-1.0-or-later.patch @@ -0,0 +1,2795 @@ +From 8d1ae1f350f5618f1d8f00211d6db6b025e52dd6 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Mon, 9 Mar 2015 21:48:11 +0100 +Subject: [PATCH 40/99] tests: convert all unit tests to cmocka 1.0 or later +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +All tests now use the cmocka-1.0-compatible API. + +Signed-off-by: Lukas Slebodnik +Reviewed-by: Lukáš Slebodník +--- + src/tests/cmocka/sbus_internal_tests.c | 22 ++-- + src/tests/cmocka/sss_nss_idmap-tests.c | 8 +- + src/tests/cmocka/test_ad_access_filter.c | 86 ++++++------- + src/tests/cmocka/test_ad_common.c | 22 ++-- + src/tests/cmocka/test_ad_gpo.c | 58 ++++----- + src/tests/cmocka/test_authtok.c | 29 +++-- + src/tests/cmocka/test_be_ptask.c | 12 +- + src/tests/cmocka/test_child_common.c | 22 ++-- + src/tests/cmocka/test_copy_ccache.c | 14 ++- + src/tests/cmocka/test_copy_keytab.c | 22 ++-- + src/tests/cmocka/test_dp_opts.c | 40 ++++--- + src/tests/cmocka/test_dyndns.c | 45 ++++--- + src/tests/cmocka/test_find_uid.c | 10 +- + src/tests/cmocka/test_fo_srv.c | 22 ++-- + src/tests/cmocka/test_fqnames.c | 80 +++++++------ + src/tests/cmocka/test_ifp.c | 38 +++--- + src/tests/cmocka/test_io.c | 32 ++--- + src/tests/cmocka/test_ipa_idmap.c | 16 +-- + src/tests/cmocka/test_negcache.c | 39 +++--- + src/tests/cmocka/test_nested_groups.c | 16 +-- + src/tests/cmocka/test_nss_srv.c | 160 ++++++++++++++----------- + src/tests/cmocka/test_resolv_fake.c | 16 +-- + src/tests/cmocka/test_responder_common.c | 34 +++--- + src/tests/cmocka/test_sdap.c | 76 ++++++------ + src/tests/cmocka/test_search_bases.c | 14 +-- + src/tests/cmocka/test_sss_idmap.c | 67 ++++++----- + src/tests/cmocka/test_sss_sifp.c | 199 ++++++++++++++++--------------- + src/tests/cmocka/test_sysdb_views.c | 30 ++--- + src/tests/cmocka/test_utils.c | 104 +++++++++------- + src/tests/cwrap/test_become_user.c | 8 +- + src/tests/cwrap/test_responder_common.c | 22 ++-- + src/tests/cwrap/test_server.c | 10 +- + src/tests/cwrap/test_usertools.c | 10 +- + 33 files changed, 743 insertions(+), 640 deletions(-) + +diff --git a/src/tests/cmocka/sbus_internal_tests.c b/src/tests/cmocka/sbus_internal_tests.c +index a79f54d266375036915c8a2ff95378a379ee4448..db5738caa3c40d8d6a950a227d8c6c403530654a 100644 +--- a/src/tests/cmocka/sbus_internal_tests.c ++++ b/src/tests/cmocka/sbus_internal_tests.c +@@ -114,7 +114,7 @@ int sss_dbus_conn_send(DBusConnection *dbus_conn, + return EOK; + } + +-void sbus_get_id_test_setup(void **state) ++int sbus_get_id_test_setup(void **state) + { + struct sbus_get_id_ctx *test_ctx; + int ret; +@@ -133,6 +133,7 @@ void sbus_get_id_test_setup(void **state) + + *state = test_ctx; + global_test_ctx = test_ctx; ++ return 0; + } + + void sbus_int_test_get_uid_done(struct tevent_req *req) +@@ -218,11 +219,12 @@ void sbus_int_test_get_uid_no_sender(void **state) + assert_int_equal(ret, EOK); + } + +-void sbus_get_id_test_teardown(void **state) ++int sbus_get_id_test_teardown(void **state) + { + struct sbus_get_id_ctx *test_ctx = talloc_get_type(*state, + struct sbus_get_id_ctx); + talloc_free(test_ctx); ++ return 0; + } + + int main(int argc, const char *argv[]) +@@ -235,13 +237,13 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test_setup_teardown(sbus_int_test_get_uid, +- sbus_get_id_test_setup, +- sbus_get_id_test_teardown), +- unit_test_setup_teardown(sbus_int_test_get_uid_no_sender, +- sbus_get_id_test_setup, +- sbus_get_id_test_teardown), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_setup_teardown(sbus_int_test_get_uid, ++ sbus_get_id_test_setup, ++ sbus_get_id_test_teardown), ++ cmocka_unit_test_setup_teardown(sbus_int_test_get_uid_no_sender, ++ sbus_get_id_test_setup, ++ sbus_get_id_test_teardown), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -261,5 +263,5 @@ int main(int argc, const char *argv[]) + + DEBUG_CLI_INIT(debug_level); + tests_set_cwd(); +- return run_tests(tests); ++ return cmocka_run_group_tests(tests, NULL, NULL); + } +diff --git a/src/tests/cmocka/sss_nss_idmap-tests.c b/src/tests/cmocka/sss_nss_idmap-tests.c +index 4141a32797734ae1ee17c9c39c522f0315fdf2ab..4ba8f2f9265389d63983e44fe14f026c9a7b8d50 100644 +--- a/src/tests/cmocka/sss_nss_idmap-tests.c ++++ b/src/tests/cmocka/sss_nss_idmap-tests.c +@@ -137,10 +137,10 @@ void test_getorigbyname(void **state) + int main(int argc, const char *argv[]) + { + +- const UnitTest tests[] = { +- unit_test(test_getsidbyname), +- unit_test(test_getorigbyname), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(test_getsidbyname), ++ cmocka_unit_test(test_getorigbyname), + }; + +- return run_tests(tests); ++ return cmocka_run_group_tests(tests, NULL, NULL); + } +diff --git a/src/tests/cmocka/test_ad_access_filter.c b/src/tests/cmocka/test_ad_access_filter.c +index 7654e8498b4d5e346598964e4725f55410149585..eebc46b710481a81e44fd589e4d4a339704ec1dd 100644 +--- a/src/tests/cmocka/test_ad_access_filter.c ++++ b/src/tests/cmocka/test_ad_access_filter.c +@@ -42,7 +42,7 @@ struct ad_access_test_ctx { + + static struct ad_access_test_ctx *test_ctx; + +-void ad_access_filter_test_setup(void **state) ++int ad_access_filter_test_setup(void **state) + { + assert_true(leak_check_setup()); + test_ctx = talloc_zero(global_talloc_context, +@@ -54,12 +54,14 @@ void ad_access_filter_test_setup(void **state) + + test_ctx->dom->name = talloc_strdup(test_ctx->dom, DOM_NAME); + assert_non_null(test_ctx->dom->name); ++ return 0; + } + +-void ad_access_filter_test_teardown(void **state) ++int ad_access_filter_test_teardown(void **state) + { + talloc_free(test_ctx); + assert_true(leak_check_teardown()); ++ return 0; + } + + struct filter_parse_result { +@@ -153,14 +155,16 @@ void test_filter_no_match(void **state) + } + + +-void parse_test_setup(void **state) ++int parse_test_setup(void **state) + { + assert_true(leak_check_setup()); ++ return 0; + } + +-void parse_test_teardown(void **state) ++int parse_test_teardown(void **state) + { + assert_true(leak_check_teardown()); ++ return 0; + } + + struct parse_result { +@@ -295,42 +299,42 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test_setup_teardown(test_parse_plain, +- parse_test_setup, +- parse_test_teardown), +- +- unit_test_setup_teardown(test_parse_dom_without_kw, +- parse_test_setup, +- parse_test_teardown), +- +- unit_test_setup_teardown(test_parse_dom_kw, +- parse_test_setup, +- parse_test_teardown), +- +- unit_test_setup_teardown(test_parse_forest_kw, +- parse_test_setup, +- parse_test_teardown), +- +- unit_test_setup_teardown(test_parse_malformed, +- parse_test_setup, +- parse_test_teardown), +- +- unit_test_setup_teardown(test_no_filter, +- ad_access_filter_test_setup, +- ad_access_filter_test_teardown), +- +- unit_test_setup_teardown(test_single_filter, +- ad_access_filter_test_setup, +- ad_access_filter_test_teardown), +- +- unit_test_setup_teardown(test_filter_order, +- ad_access_filter_test_setup, +- ad_access_filter_test_teardown), +- +- unit_test_setup_teardown(test_filter_no_match, +- ad_access_filter_test_setup, +- ad_access_filter_test_teardown), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_setup_teardown(test_parse_plain, ++ parse_test_setup, ++ parse_test_teardown), ++ ++ cmocka_unit_test_setup_teardown(test_parse_dom_without_kw, ++ parse_test_setup, ++ parse_test_teardown), ++ ++ cmocka_unit_test_setup_teardown(test_parse_dom_kw, ++ parse_test_setup, ++ parse_test_teardown), ++ ++ cmocka_unit_test_setup_teardown(test_parse_forest_kw, ++ parse_test_setup, ++ parse_test_teardown), ++ ++ cmocka_unit_test_setup_teardown(test_parse_malformed, ++ parse_test_setup, ++ parse_test_teardown), ++ ++ cmocka_unit_test_setup_teardown(test_no_filter, ++ ad_access_filter_test_setup, ++ ad_access_filter_test_teardown), ++ ++ cmocka_unit_test_setup_teardown(test_single_filter, ++ ad_access_filter_test_setup, ++ ad_access_filter_test_teardown), ++ ++ cmocka_unit_test_setup_teardown(test_filter_order, ++ ad_access_filter_test_setup, ++ ad_access_filter_test_teardown), ++ ++ cmocka_unit_test_setup_teardown(test_filter_no_match, ++ ad_access_filter_test_setup, ++ ad_access_filter_test_teardown), + + }; + +@@ -353,5 +357,5 @@ int main(int argc, const char *argv[]) + + tests_set_cwd(); + +- return run_tests(tests); ++ return cmocka_run_group_tests(tests, NULL, NULL); + } +diff --git a/src/tests/cmocka/test_ad_common.c b/src/tests/cmocka/test_ad_common.c +index c4b6bd0f21827424291176abf520008d2d9488de..19a4d395ba3fc4eae6601b3ad7056c41384a5c4f 100644 +--- a/src/tests/cmocka/test_ad_common.c ++++ b/src/tests/cmocka/test_ad_common.c +@@ -47,7 +47,7 @@ struct ad_common_test_ctx { + struct sss_domain_info *subdom; + }; + +-static void ++static int + ad_common_test_setup(void **state) + { + struct ad_common_test_ctx *test_ctx; +@@ -111,9 +111,10 @@ ad_common_test_setup(void **state) + + check_leaks_push(test_ctx); + *state = test_ctx; ++ return 0; + } + +-static void ++static int + ad_common_test_teardown(void **state) + { + struct ad_common_test_ctx *test_ctx = talloc_get_type(*state, +@@ -124,6 +125,7 @@ ad_common_test_teardown(void **state) + talloc_free(test_ctx); + assert_true(check_leaks_pop(global_talloc_context) == true); + assert_true(leak_check_teardown()); ++ return 0; + } + + errno_t +@@ -210,13 +212,13 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test_setup_teardown(test_ldap_conn_list, +- ad_common_test_setup, +- ad_common_test_teardown), +- unit_test_setup_teardown(test_conn_list, +- ad_common_test_setup, +- ad_common_test_teardown), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_setup_teardown(test_ldap_conn_list, ++ ad_common_test_setup, ++ ad_common_test_teardown), ++ cmocka_unit_test_setup_teardown(test_conn_list, ++ ad_common_test_setup, ++ ad_common_test_teardown), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -238,5 +240,5 @@ int main(int argc, const char *argv[]) + + tests_set_cwd(); + +- return run_tests(tests); ++ return cmocka_run_group_tests(tests, NULL, NULL); + } +diff --git a/src/tests/cmocka/test_ad_gpo.c b/src/tests/cmocka/test_ad_gpo.c +index 4753c95d32651ab13a107a945769a5fbc8e38b7d..4dadcf1b2988e43ec2ad05ad1aedd630c2aa9c18 100644 +--- a/src/tests/cmocka/test_ad_gpo.c ++++ b/src/tests/cmocka/test_ad_gpo.c +@@ -40,7 +40,7 @@ struct ad_gpo_test_ctx { + + static struct ad_gpo_test_ctx *test_ctx; + +-void ad_gpo_test_setup(void **state) ++static int ad_gpo_test_setup(void **state) + { + assert_true(leak_check_setup()); + test_ctx = talloc_zero(global_talloc_context, +@@ -49,12 +49,14 @@ void ad_gpo_test_setup(void **state) + + test_ctx->ldb_ctx = ldb_init(test_ctx, NULL); + assert_non_null(test_ctx->ldb_ctx); ++ return 0; + } + +-void ad_gpo_test_teardown(void **state) ++static int ad_gpo_test_teardown(void **state) + { + talloc_free(test_ctx); + assert_true(leak_check_teardown()); ++ return 0; + } + + struct som_list_result { +@@ -337,31 +339,31 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test_setup_teardown(test_populate_som_list_plain, +- ad_gpo_test_setup, +- ad_gpo_test_teardown), +- unit_test_setup_teardown(test_populate_som_list_malformed, +- ad_gpo_test_setup, +- ad_gpo_test_teardown), +- unit_test_setup_teardown(test_populate_gplink_list_plain, +- ad_gpo_test_setup, +- ad_gpo_test_teardown), +- unit_test_setup_teardown(test_populate_gplink_list_with_ignored, +- ad_gpo_test_setup, +- ad_gpo_test_teardown), +- unit_test_setup_teardown(test_populate_gplink_list_with_allow_enforced, +- ad_gpo_test_setup, +- ad_gpo_test_teardown), +- unit_test_setup_teardown(test_populate_gplink_list_malformed, +- ad_gpo_test_setup, +- ad_gpo_test_teardown), +- unit_test_setup_teardown(test_ad_gpo_ace_includes_client_sid_true, +- ad_gpo_test_setup, +- ad_gpo_test_teardown), +- unit_test_setup_teardown(test_ad_gpo_ace_includes_client_sid_false, +- ad_gpo_test_setup, +- ad_gpo_test_teardown), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_setup_teardown(test_populate_som_list_plain, ++ ad_gpo_test_setup, ++ ad_gpo_test_teardown), ++ cmocka_unit_test_setup_teardown(test_populate_som_list_malformed, ++ ad_gpo_test_setup, ++ ad_gpo_test_teardown), ++ cmocka_unit_test_setup_teardown(test_populate_gplink_list_plain, ++ ad_gpo_test_setup, ++ ad_gpo_test_teardown), ++ cmocka_unit_test_setup_teardown(test_populate_gplink_list_with_ignored, ++ ad_gpo_test_setup, ++ ad_gpo_test_teardown), ++ cmocka_unit_test_setup_teardown(test_populate_gplink_list_with_allow_enforced, ++ ad_gpo_test_setup, ++ ad_gpo_test_teardown), ++ cmocka_unit_test_setup_teardown(test_populate_gplink_list_malformed, ++ ad_gpo_test_setup, ++ ad_gpo_test_teardown), ++ cmocka_unit_test_setup_teardown(test_ad_gpo_ace_includes_client_sid_true, ++ ad_gpo_test_setup, ++ ad_gpo_test_teardown), ++ cmocka_unit_test_setup_teardown(test_ad_gpo_ace_includes_client_sid_false, ++ ad_gpo_test_setup, ++ ad_gpo_test_teardown), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -383,5 +385,5 @@ int main(int argc, const char *argv[]) + + tests_set_cwd(); + +- return run_tests(tests); ++ return cmocka_run_group_tests(tests, NULL, NULL); + } +diff --git a/src/tests/cmocka/test_authtok.c b/src/tests/cmocka/test_authtok.c +index 50205cc33e9b64cdf4537c6adbe54370b1f3de3b..e37e92f68373d564f53b1267f078ea89c31ae051 100644 +--- a/src/tests/cmocka/test_authtok.c ++++ b/src/tests/cmocka/test_authtok.c +@@ -35,7 +35,7 @@ struct test_state { + struct sss_auth_token *authtoken; + }; + +-static void setup(void **state) ++static int setup(void **state) + { + struct test_state *ts = NULL; + +@@ -46,12 +46,14 @@ static void setup(void **state) + assert_non_null(ts->authtoken); + + *state = (void *)ts; ++ return 0; + } + +-static void teardown(void **state) ++static int teardown(void **state) + { + struct test_state *ts = talloc_get_type_abort(*state, struct test_state); + talloc_free(ts); ++ return 0; + } + + static void test_sss_authtok_new(void **state) +@@ -289,15 +291,20 @@ static void test_sss_authtok_copy(void **state) + + int main(void) + { +- const UnitTest tests[] = { +- unit_test_setup_teardown(test_sss_authtok_new, setup, teardown), +- unit_test_setup_teardown(test_sss_authtok_password, setup, teardown), +- unit_test_setup_teardown(test_sss_authtok_ccfile, setup, teardown), +- unit_test_setup_teardown(test_sss_authtok_empty, setup, teardown), +- unit_test_setup_teardown(test_sss_authtok_wipe_password, setup, +- teardown), +- unit_test_setup_teardown(test_sss_authtok_copy, setup, teardown) ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_setup_teardown(test_sss_authtok_new, ++ setup, teardown), ++ cmocka_unit_test_setup_teardown(test_sss_authtok_password, ++ setup, teardown), ++ cmocka_unit_test_setup_teardown(test_sss_authtok_ccfile, ++ setup, teardown), ++ cmocka_unit_test_setup_teardown(test_sss_authtok_empty, ++ setup, teardown), ++ cmocka_unit_test_setup_teardown(test_sss_authtok_wipe_password, ++ setup, teardown), ++ cmocka_unit_test_setup_teardown(test_sss_authtok_copy, ++ setup, teardown) + }; + +- return run_tests(tests); ++ return cmocka_run_group_tests(tests, NULL, NULL); + } +diff --git a/src/tests/cmocka/test_be_ptask.c b/src/tests/cmocka/test_be_ptask.c +index 205204214c758f4e95a10824db42e78dd29bc0fb..f4a120c0c6201a6a306004445445024684f713d1 100644 +--- a/src/tests/cmocka/test_be_ptask.c ++++ b/src/tests/cmocka/test_be_ptask.c +@@ -34,7 +34,7 @@ + #define PERIOD 1 + + #define new_test(test) \ +- unit_test_setup_teardown(test_ ## test, test_setup, test_teardown) ++ cmocka_unit_test_setup_teardown(test_ ## test, test_setup, test_teardown) + + struct test_ctx { + struct be_ctx *be_ctx; +@@ -265,7 +265,7 @@ errno_t test_be_ptask_sync_error(TALLOC_CTX *mem_ctx, + return ERR_INTERNAL; + } + +-void test_setup(void **state) ++static int test_setup(void **state) + { + struct test_ctx *test_ctx = NULL; + +@@ -282,12 +282,14 @@ void test_setup(void **state) + assert_non_null(test_ctx->be_ctx->ev); + + *state = test_ctx; ++ return 0; + } + +-void test_teardown(void **state) ++static int test_teardown(void **state) + { + talloc_zfree(*state); + assert_true(leak_check_teardown()); ++ return 0; + } + + void test_be_ptask_create_einval_be(void **state) +@@ -944,7 +946,7 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { ++ const struct CMUnitTest tests[] = { + new_test(be_ptask_create_einval_be), + new_test(be_ptask_create_einval_period), + new_test(be_ptask_create_einval_send), +@@ -987,5 +989,5 @@ int main(int argc, const char *argv[]) + + DEBUG_CLI_INIT(debug_level); + +- return run_tests(tests); ++ return cmocka_run_group_tests(tests, NULL, NULL); + } +diff --git a/src/tests/cmocka/test_child_common.c b/src/tests/cmocka/test_child_common.c +index 23e14ce49ff75c8c14320be687b456cfcad1982e..c8428cb764c800bd1c776bba606cfb8b3f33bef3 100644 +--- a/src/tests/cmocka/test_child_common.c ++++ b/src/tests/cmocka/test_child_common.c +@@ -38,7 +38,7 @@ struct child_test_ctx { + struct sss_test_ctx *test_ctx; + }; + +-void child_test_setup(void **state) ++static int child_test_setup(void **state) + { + struct child_test_ctx *child_tctx; + errno_t ret; +@@ -63,15 +63,17 @@ void child_test_setup(void **state) + child_tctx->pipefd_to_child[1]); + + *state = child_tctx; ++ return 0; + } + +-void child_test_teardown(void **state) ++static int child_test_teardown(void **state) + { + struct child_test_ctx *child_tctx = talloc_get_type(*state, + struct child_test_ctx); + + talloc_free(child_tctx); + check_leaks_pop(global_talloc_context); ++ return 0; + } + + /* Just make sure the exec works. The child does nothing but exits */ +@@ -165,13 +167,13 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test_setup_teardown(test_exec_child, +- child_test_setup, +- child_test_teardown), +- unit_test_setup_teardown(test_exec_child_extra_args, +- child_test_setup, +- child_test_teardown), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_setup_teardown(test_exec_child, ++ child_test_setup, ++ child_test_teardown), ++ cmocka_unit_test_setup_teardown(test_exec_child_extra_args, ++ child_test_setup, ++ child_test_teardown), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -191,6 +193,6 @@ int main(int argc, const char *argv[]) + + DEBUG_CLI_INIT(debug_level); + +- rv = run_tests(tests); ++ rv = cmocka_run_group_tests(tests, NULL, NULL); + return rv; + } +diff --git a/src/tests/cmocka/test_copy_ccache.c b/src/tests/cmocka/test_copy_ccache.c +index c7a5573b83b8faeb5c7447b48fa40ec8957e1aaf..711f8f0ab46cf37da89d6c24e4f23c398f3e0587 100644 +--- a/src/tests/cmocka/test_copy_ccache.c ++++ b/src/tests/cmocka/test_copy_ccache.c +@@ -39,7 +39,7 @@ struct ccache_test_ctx { + krb5_principal server_principal; + }; + +-void setup_ccache(void **state) ++static int setup_ccache(void **state) + { + struct ccache_test_ctx *test_ctx; + krb5_error_code kerr; +@@ -131,9 +131,10 @@ void setup_ccache(void **state) + *state = test_ctx; + + krb5_free_authdata(test_ctx->kctx, test_creds.authdata); ++ return 0; + } + +-void teardown_ccache(void **state) ++static int teardown_ccache(void **state) + { + int ret; + struct ccache_test_ctx *test_ctx = talloc_get_type(*state, +@@ -150,6 +151,7 @@ void teardown_ccache(void **state) + assert_true(check_leaks_pop(test_ctx) == true); + talloc_free(test_ctx); + assert_true(leak_check_teardown()); ++ return 0; + } + + void test_copy_ccache(void **state) +@@ -206,9 +208,9 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test_setup_teardown(test_copy_ccache, +- setup_ccache, teardown_ccache), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_setup_teardown(test_copy_ccache, ++ setup_ccache, teardown_ccache), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -232,7 +234,7 @@ int main(int argc, const char *argv[]) + * they might not after a failed run. Remove the old db to be sure */ + tests_set_cwd(); + +- rv = run_tests(tests); ++ rv = cmocka_run_group_tests(tests, NULL, NULL); + + return rv; + } +diff --git a/src/tests/cmocka/test_copy_keytab.c b/src/tests/cmocka/test_copy_keytab.c +index a9f2161a2b25e9cf67319399cc7c54487e687841..1999de3bf74772121b416f99d42d3734b5e1b72a 100644 +--- a/src/tests/cmocka/test_copy_keytab.c ++++ b/src/tests/cmocka/test_copy_keytab.c +@@ -37,7 +37,7 @@ struct keytab_test_ctx { + krb5_principal principal; + }; + +-void setup_keytab(void **state) ++static int setup_keytab(void **state) + { + struct keytab_test_ctx *test_ctx; + krb5_error_code kerr; +@@ -98,9 +98,10 @@ void setup_keytab(void **state) + + check_leaks_push(test_ctx); + *state = test_ctx; ++ return 0; + } + +-void teardown_keytab(void **state) ++static int teardown_keytab(void **state) + { + int ret; + struct keytab_test_ctx *test_ctx = talloc_get_type(*state, +@@ -116,6 +117,7 @@ void teardown_keytab(void **state) + assert_true(check_leaks_pop(test_ctx) == true); + talloc_free(test_ctx); + assert_true(leak_check_teardown()); ++ return 0; + } + + void test_copy_keytab(void **state) +@@ -292,13 +294,13 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test_setup_teardown(test_copy_keytab, +- setup_keytab, teardown_keytab), +- unit_test_setup_teardown(test_sss_krb5_kt_have_content, +- setup_keytab, teardown_keytab), +- unit_test_setup_teardown(test_copy_keytab_order, +- setup_keytab, teardown_keytab), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_setup_teardown(test_copy_keytab, ++ setup_keytab, teardown_keytab), ++ cmocka_unit_test_setup_teardown(test_sss_krb5_kt_have_content, ++ setup_keytab, teardown_keytab), ++ cmocka_unit_test_setup_teardown(test_copy_keytab_order, ++ setup_keytab, teardown_keytab), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -322,7 +324,7 @@ int main(int argc, const char *argv[]) + * they might not after a failed run. Remove the old db to be sure */ + tests_set_cwd(); + +- rv = run_tests(tests); ++ rv = cmocka_run_group_tests(tests, NULL, NULL); + + return rv; + } +diff --git a/src/tests/cmocka/test_dp_opts.c b/src/tests/cmocka/test_dp_opts.c +index 0f3052ab3c2add8286db6d5f065a8ca9391aae13..be7751a7a98116f3ef2bbf5704d8d3a3b6ef44fc 100644 +--- a/src/tests/cmocka/test_dp_opts.c ++++ b/src/tests/cmocka/test_dp_opts.c +@@ -265,7 +265,7 @@ void opt_test_get(void **state) + assert_true(bo == false); + } + +-void opt_test_getset_setup(void **state) ++static int opt_test_getset_setup(void **state) + { + int ret; + struct dp_option *opts; +@@ -276,12 +276,14 @@ void opt_test_getset_setup(void **state) + assert_defaults(opts); + + *state = opts; ++ return 0; + } + +-void opt_test_getset_teardown(void **state) ++static int opt_test_getset_teardown(void **state) + { + struct dp_option *opts = talloc_get_type(*state, struct dp_option); + talloc_free(opts); ++ return 0; + } + + void opt_test_getset_string(void **state) +@@ -367,22 +369,22 @@ int main(int argc, const char *argv[]) + _("Do not delete the test database after a test run"), NULL }, + POPT_TABLEEND + }; +- const UnitTest tests[] = { +- unit_test_setup_teardown(opt_test_getset_string, +- opt_test_getset_setup, +- opt_test_getset_teardown), +- unit_test_setup_teardown(opt_test_getset_int, +- opt_test_getset_setup, +- opt_test_getset_teardown), +- unit_test_setup_teardown(opt_test_getset_bool, +- opt_test_getset_setup, +- opt_test_getset_teardown), +- unit_test_setup_teardown(opt_test_getset_blob, +- opt_test_getset_setup, +- opt_test_getset_teardown), +- unit_test(opt_test_copy_default), +- unit_test(opt_test_copy_options), +- unit_test(opt_test_get) ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_setup_teardown(opt_test_getset_string, ++ opt_test_getset_setup, ++ opt_test_getset_teardown), ++ cmocka_unit_test_setup_teardown(opt_test_getset_int, ++ opt_test_getset_setup, ++ opt_test_getset_teardown), ++ cmocka_unit_test_setup_teardown(opt_test_getset_bool, ++ opt_test_getset_setup, ++ opt_test_getset_teardown), ++ cmocka_unit_test_setup_teardown(opt_test_getset_blob, ++ opt_test_getset_setup, ++ opt_test_getset_teardown), ++ cmocka_unit_test(opt_test_copy_default), ++ cmocka_unit_test(opt_test_copy_options), ++ cmocka_unit_test(opt_test_get) + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -408,7 +410,7 @@ int main(int argc, const char *argv[]) + test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_SYSDB_FILE); + test_dom_suite_setup(TESTS_PATH); + +- ret = run_tests(tests); ++ ret = cmocka_run_group_tests(tests, NULL, NULL); + if (ret == 0 && !no_cleanup) { + test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_SYSDB_FILE); + } +diff --git a/src/tests/cmocka/test_dyndns.c b/src/tests/cmocka/test_dyndns.c +index 345c170f1e595c0a9c116eb7e8fa84a6bc95ef40..eaf106ec6224e36c446d42d2a09e16350a8c9b13 100644 +--- a/src/tests/cmocka/test_dyndns.c ++++ b/src/tests/cmocka/test_dyndns.c +@@ -393,7 +393,7 @@ void dyndns_test_interval(void **state) + } + + /* Testsuite setup and teardown */ +-void dyndns_test_setup(void **state) ++static int dyndns_test_setup(void **state) + { + struct sss_test_conf_param params[] = { + { "dyndns_update", "true" }, +@@ -419,9 +419,10 @@ void dyndns_test_setup(void **state) + dyndns_test_ctx->be_ctx->cdb = dyndns_test_ctx->tctx->confdb; + dyndns_test_ctx->be_ctx->ev = dyndns_test_ctx->tctx->ev; + dyndns_test_ctx->be_ctx->conf_path = dyndns_test_ctx->tctx->conf_dom_path; ++ return 0; + } + +-void dyndns_test_simple_setup(void **state) ++static int dyndns_test_simple_setup(void **state) + { + assert_true(leak_check_setup()); + global_mock_context = talloc_new(global_talloc_context); +@@ -429,13 +430,15 @@ void dyndns_test_simple_setup(void **state) + + dyndns_test_ctx = talloc_zero(global_talloc_context, struct dyndns_test_ctx); + assert_non_null(dyndns_test_ctx); ++ return 0; + } + +-void dyndns_test_teardown(void **state) ++static int dyndns_test_teardown(void **state) + { + talloc_free(dyndns_test_ctx); + talloc_free(global_mock_context); + assert_true(leak_check_teardown()); ++ return 0; + } + + int main(int argc, const char *argv[]) +@@ -452,24 +455,28 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { ++ const struct CMUnitTest tests[] = { + /* Utility functions unit test */ +- unit_test_setup_teardown(dyndns_test_get_ifaddr, +- dyndns_test_simple_setup, +- dyndns_test_teardown), +- unit_test_setup_teardown(dyndns_test_get_multi_ifaddr, +- dyndns_test_simple_setup, +- dyndns_test_teardown), ++ cmocka_unit_test_setup_teardown(dyndns_test_get_ifaddr, ++ dyndns_test_simple_setup, ++ dyndns_test_teardown), ++ cmocka_unit_test_setup_teardown(dyndns_test_get_multi_ifaddr, ++ dyndns_test_simple_setup, ++ dyndns_test_teardown), + + /* Dynamic DNS update unit tests*/ +- unit_test_setup_teardown(dyndns_test_ok, +- dyndns_test_setup, dyndns_test_teardown), +- unit_test_setup_teardown(dyndns_test_error, +- dyndns_test_setup, dyndns_test_teardown), +- unit_test_setup_teardown(dyndns_test_timeout, +- dyndns_test_setup, dyndns_test_teardown), +- unit_test_setup_teardown(dyndns_test_interval, +- dyndns_test_setup, dyndns_test_teardown), ++ cmocka_unit_test_setup_teardown(dyndns_test_ok, ++ dyndns_test_setup, ++ dyndns_test_teardown), ++ cmocka_unit_test_setup_teardown(dyndns_test_error, ++ dyndns_test_setup, ++ dyndns_test_teardown), ++ cmocka_unit_test_setup_teardown(dyndns_test_timeout, ++ dyndns_test_setup, ++ dyndns_test_teardown), ++ cmocka_unit_test_setup_teardown(dyndns_test_interval, ++ dyndns_test_setup, ++ dyndns_test_teardown), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -495,7 +502,7 @@ int main(int argc, const char *argv[]) + test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_SYSDB_FILE); + test_dom_suite_setup(TESTS_PATH); + +- rv = run_tests(tests); ++ rv = cmocka_run_group_tests(tests, NULL, NULL); + if (rv == 0 && !no_cleanup) { + test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_SYSDB_FILE); + } +diff --git a/src/tests/cmocka/test_find_uid.c b/src/tests/cmocka/test_find_uid.c +index dcc367962bbd7a9a16643c79f08c856cc8635f2f..63a426a16cfde2db8d3772d3167cd58124805ac0 100644 +--- a/src/tests/cmocka/test_find_uid.c ++++ b/src/tests/cmocka/test_find_uid.c +@@ -95,11 +95,11 @@ void test_get_uid_table(void **state) + + int main(void) + { +- const UnitTest tests[] = { +- unit_test(test_check_if_uid_is_active_success), +- unit_test(test_check_if_uid_is_active_fail), +- unit_test(test_get_uid_table) ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(test_check_if_uid_is_active_success), ++ cmocka_unit_test(test_check_if_uid_is_active_fail), ++ cmocka_unit_test(test_get_uid_table) + }; + +- return run_tests(tests); ++ return cmocka_run_group_tests(tests, NULL, NULL); + } +diff --git a/src/tests/cmocka/test_fo_srv.c b/src/tests/cmocka/test_fo_srv.c +index 3ee308bd5967f44abda1980e7bff8e0a5c00dde0..7a6321006d8383ed901fe9d5df3fddc514c53550 100644 +--- a/src/tests/cmocka/test_fo_srv.c ++++ b/src/tests/cmocka/test_fo_srv.c +@@ -207,7 +207,7 @@ int test_fo_srv_data_cmp(void *ud1, void *ud2) + return strcasecmp((char*) ud1, (char*) ud2); + } + +-void test_fo_srv_setup(void **state) ++static int test_fo_srv_setup(void **state) + { + struct test_fo_srv_ctx *test_ctx; + errno_t ret; +@@ -253,9 +253,10 @@ void test_fo_srv_setup(void **state) + assert_int_equal(ret, ERR_OK); + + *state = test_ctx; ++ return 0; + } + +-void test_fo_srv_teardown(void **state) ++static int test_fo_srv_teardown(void **state) + { + struct test_fo_srv_ctx *test_ctx = + talloc_get_type(*state, struct test_fo_srv_ctx); +@@ -263,6 +264,7 @@ void test_fo_srv_teardown(void **state) + talloc_free(test_ctx); + talloc_free(global_mock_context); + assert_true(leak_check_teardown()); ++ return 0; + } + + /* reply_list and dns_domain must be a talloc context so it can be used as +@@ -564,13 +566,13 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test_setup_teardown(test_fo_srv, +- test_fo_srv_setup, +- test_fo_srv_teardown), +- unit_test_setup_teardown(test_fo_srv_ttl_change, +- test_fo_srv_setup, +- test_fo_srv_teardown), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_setup_teardown(test_fo_srv, ++ test_fo_srv_setup, ++ test_fo_srv_teardown), ++ cmocka_unit_test_setup_teardown(test_fo_srv_ttl_change, ++ test_fo_srv_setup, ++ test_fo_srv_teardown), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -594,6 +596,6 @@ int main(int argc, const char *argv[]) + * they might not after a failed run. Remove the old db to be sure */ + tests_set_cwd(); + +- rv = run_tests(tests); ++ rv = cmocka_run_group_tests(tests, NULL, NULL); + return rv; + } +diff --git a/src/tests/cmocka/test_fqnames.c b/src/tests/cmocka/test_fqnames.c +index b9b6230b9e2c86dafae159630d5202e46992f5f3..0326d5a645bad0396d8b20f635e6ee6b3e4b5587 100644 +--- a/src/tests/cmocka/test_fqnames.c ++++ b/src/tests/cmocka/test_fqnames.c +@@ -69,7 +69,7 @@ struct fqdn_test_ctx { + struct sss_names_ctx *nctx; + }; + +-void fqdn_test_setup(void **state) ++static int fqdn_test_setup(void **state) + { + struct fqdn_test_ctx *test_ctx; + +@@ -83,21 +83,23 @@ void fqdn_test_setup(void **state) + + check_leaks_push(test_ctx); + *state = test_ctx; ++ return 0; + } + +-void fqdn_test_teardown(void **state) ++static int fqdn_test_teardown(void **state) + { + struct fqdn_test_ctx *test_ctx = talloc_get_type(*state, + struct fqdn_test_ctx); + + if (test_ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Type mismatch\n"); +- return; ++ return 1; + } + + assert_true(check_leaks_pop(test_ctx) == true); + talloc_free(test_ctx); + assert_true(leak_check_teardown()); ++ return 0; + } + + void test_default(void **state) +@@ -270,7 +272,7 @@ void parse_name_check(struct parse_name_test_ctx *test_ctx, + assert_true(check_leaks_pop(test_ctx) == true); + } + +-void parse_name_test_setup(void **state) ++static int parse_name_test_setup(void **state) + { + struct parse_name_test_ctx *test_ctx; + struct sss_domain_info *dom; +@@ -312,9 +314,10 @@ void parse_name_test_setup(void **state) + + check_leaks_push(test_ctx); + *state = test_ctx; ++ return 0; + } + +-void parse_name_test_teardown(void **state) ++static int parse_name_test_teardown(void **state) + { + struct parse_name_test_ctx *test_ctx = talloc_get_type(*state, + struct parse_name_test_ctx); +@@ -322,6 +325,7 @@ void parse_name_test_teardown(void **state) + assert_true(check_leaks_pop(test_ctx) == true); + talloc_free(test_ctx); + assert_true(leak_check_teardown()); ++ return 0; + } + + void sss_parse_name_check(struct parse_name_test_ctx *test_ctx, +@@ -513,40 +517,40 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test_setup_teardown(test_default, +- fqdn_test_setup, fqdn_test_teardown), +- unit_test_setup_teardown(test_all, +- fqdn_test_setup, fqdn_test_teardown), +- unit_test_setup_teardown(test_flat, +- fqdn_test_setup, fqdn_test_teardown), +- unit_test_setup_teardown(test_flat_fallback, +- fqdn_test_setup, fqdn_test_teardown), +- unit_test_setup_teardown(test_init_nouser, +- fqdn_test_setup, fqdn_test_teardown), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_setup_teardown(test_default, ++ fqdn_test_setup, fqdn_test_teardown), ++ cmocka_unit_test_setup_teardown(test_all, ++ fqdn_test_setup, fqdn_test_teardown), ++ cmocka_unit_test_setup_teardown(test_flat, ++ fqdn_test_setup, fqdn_test_teardown), ++ cmocka_unit_test_setup_teardown(test_flat_fallback, ++ fqdn_test_setup, fqdn_test_teardown), ++ cmocka_unit_test_setup_teardown(test_init_nouser, ++ fqdn_test_setup, fqdn_test_teardown), + +- unit_test_setup_teardown(parse_name_plain, +- parse_name_test_setup, +- parse_name_test_teardown), +- unit_test_setup_teardown(parse_name_fqdn, +- parse_name_test_setup, +- parse_name_test_teardown), +- unit_test_setup_teardown(parse_name_sub, +- parse_name_test_setup, +- parse_name_test_teardown), +- unit_test_setup_teardown(parse_name_flat, +- parse_name_test_setup, +- parse_name_test_teardown), +- unit_test_setup_teardown(parse_name_default, +- parse_name_test_setup, +- parse_name_test_teardown), +- unit_test_setup_teardown(sss_parse_name_fail, +- parse_name_test_setup, +- parse_name_test_teardown), ++ cmocka_unit_test_setup_teardown(parse_name_plain, ++ parse_name_test_setup, ++ parse_name_test_teardown), ++ cmocka_unit_test_setup_teardown(parse_name_fqdn, ++ parse_name_test_setup, ++ parse_name_test_teardown), ++ cmocka_unit_test_setup_teardown(parse_name_sub, ++ parse_name_test_setup, ++ parse_name_test_teardown), ++ cmocka_unit_test_setup_teardown(parse_name_flat, ++ parse_name_test_setup, ++ parse_name_test_teardown), ++ cmocka_unit_test_setup_teardown(parse_name_default, ++ parse_name_test_setup, ++ parse_name_test_teardown), ++ cmocka_unit_test_setup_teardown(sss_parse_name_fail, ++ parse_name_test_setup, ++ parse_name_test_teardown), + +- unit_test_setup_teardown(test_sss_get_domain_name, +- parse_name_test_setup, +- parse_name_test_teardown), ++ cmocka_unit_test_setup_teardown(test_sss_get_domain_name, ++ parse_name_test_setup, ++ parse_name_test_teardown), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -570,5 +574,5 @@ int main(int argc, const char *argv[]) + * they might not after a failed run. Remove the old db to be sure */ + tests_set_cwd(); + +- return run_tests(tests); ++ return cmocka_run_group_tests(tests, NULL, NULL); + } +diff --git a/src/tests/cmocka/test_ifp.c b/src/tests/cmocka/test_ifp.c +index 5793f91911c1e15c2c241aaa51ffcd4196daea63..b9f5ba0d31f75fb61ce92ac004888fb2db1ad450 100644 +--- a/src/tests/cmocka/test_ifp.c ++++ b/src/tests/cmocka/test_ifp.c +@@ -426,7 +426,7 @@ struct ifp_test_req_ctx { + struct ifp_ctx *ifp_ctx; + }; + +-void ifp_test_req_setup(void **state) ++static int ifp_test_req_setup(void **state) + { + struct ifp_test_req_ctx *test_ctx; + errno_t ret; +@@ -447,9 +447,10 @@ void ifp_test_req_setup(void **state) + + check_leaks_push(test_ctx); + *state = test_ctx; ++ return 0; + } + +-void ifp_test_req_teardown(void **state) ++static int ifp_test_req_teardown(void **state) + { + struct ifp_test_req_ctx *test_ctx = talloc_get_type_abort(*state, + struct ifp_test_req_ctx); +@@ -460,6 +461,7 @@ void ifp_test_req_teardown(void **state) + talloc_free(test_ctx); + + assert_true(leak_check_teardown()); ++ return 0; + } + + void test_reply_path(void **state) +@@ -498,20 +500,22 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test(ifp_test_req_create), +- unit_test(ifp_test_req_wrong_uid), +- unit_test(test_path_prefix), +- unit_test_setup_teardown(test_el_to_dict, +- ifp_test_req_setup, ifp_test_req_teardown), +- unit_test(test_attr_acl), +- unit_test(test_attr_acl_ex), +- unit_test(test_attr_allowed), +- unit_test(test_path_escape_unescape), +- unit_test_setup_teardown(test_reply_path, +- ifp_test_req_setup, ifp_test_req_teardown), +- unit_test_setup_teardown(test_reply_path_escape, +- ifp_test_req_setup, ifp_test_req_teardown), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(ifp_test_req_create), ++ cmocka_unit_test(ifp_test_req_wrong_uid), ++ cmocka_unit_test_setup_teardown(test_el_to_dict, ++ ifp_test_req_setup, ++ ifp_test_req_teardown), ++ cmocka_unit_test(test_attr_acl), ++ cmocka_unit_test(test_attr_acl_ex), ++ cmocka_unit_test(test_attr_allowed), ++ cmocka_unit_test(test_path_escape_unescape), ++ cmocka_unit_test_setup_teardown(test_reply_path, ++ ifp_test_req_setup, ++ ifp_test_req_teardown), ++ cmocka_unit_test_setup_teardown(test_reply_path_escape, ++ ifp_test_req_setup, ++ ifp_test_req_teardown), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -535,5 +539,5 @@ int main(int argc, const char *argv[]) + * they might not after a failed run. Remove the old db to be sure */ + tests_set_cwd(); + +- return run_tests(tests); ++ return cmocka_run_group_tests(tests, NULL, NULL); + } +diff --git a/src/tests/cmocka/test_io.c b/src/tests/cmocka/test_io.c +index 2f95388570f4189fc2ca70e6a55be688f7921467..9bdb7107e06aa350b5de473a132137befb6de3ea 100644 +--- a/src/tests/cmocka/test_io.c ++++ b/src/tests/cmocka/test_io.c +@@ -67,7 +67,7 @@ static char *get_random_filepath(const char *template) + return path; + } + +-void test_file_setup(void **state) ++static int test_file_setup(void **state) + { + int ret; + char *file_path; +@@ -83,9 +83,10 @@ void test_file_setup(void **state) + assert_int_equal(ret, ENOENT); + + *state = file_path; ++ return 0; + } + +-void test_file_teardown(void **state) ++static int test_file_teardown(void **state) + { + int ret; + char *file_path = (char *)*state; +@@ -96,6 +97,7 @@ void test_file_teardown(void **state) + + ret = rmdir(TESTS_PATH); + assert_int_equal(ret, EOK); ++ return 0; + } + + struct dir_state { +@@ -107,7 +109,7 @@ struct dir_state { + char *filename; + }; + +-void test_dir_setup(void **state) ++static int test_dir_setup(void **state) + { + struct dir_state *data; + int ret; +@@ -139,9 +141,10 @@ void test_dir_setup(void **state) + assert_int_equal(ret, ENOENT); + + *state = data; ++ return 0; + } + +-void test_dir_teardown(void **state) ++static int test_dir_teardown(void **state) + { + int ret; + struct dir_state *data = (struct dir_state *) *state; +@@ -157,6 +160,7 @@ void test_dir_teardown(void **state) + assert_int_equal(ret, EOK); + + free(data); ++ return 0; + } + + void test_sss_open_cloexec_success(void **state) +@@ -223,17 +227,17 @@ void test_sss_openat_cloexec_fail(void **state) + + int main(void) + { +- const UnitTest tests[] = { +- unit_test_setup_teardown(test_sss_open_cloexec_success, +- test_file_setup, test_file_teardown), +- unit_test_setup_teardown(test_sss_open_cloexec_fail, +- test_file_setup, test_file_teardown), +- unit_test_setup_teardown(test_sss_openat_cloexec_success, +- test_dir_setup, test_dir_teardown), +- unit_test_setup_teardown(test_sss_openat_cloexec_fail, +- test_dir_setup, test_dir_teardown) ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_setup_teardown(test_sss_open_cloexec_success, ++ test_file_setup, test_file_teardown), ++ cmocka_unit_test_setup_teardown(test_sss_open_cloexec_fail, ++ test_file_setup, test_file_teardown), ++ cmocka_unit_test_setup_teardown(test_sss_openat_cloexec_success, ++ test_dir_setup, test_dir_teardown), ++ cmocka_unit_test_setup_teardown(test_sss_openat_cloexec_fail, ++ test_dir_setup, test_dir_teardown) + }; + + tests_set_cwd(); +- return run_tests(tests); ++ return cmocka_run_group_tests(tests, NULL, NULL); + } +diff --git a/src/tests/cmocka/test_ipa_idmap.c b/src/tests/cmocka/test_ipa_idmap.c +index 8ad56298757c6b8fd2e857e1d92d0eb767b9e8c9..fba41ae2fa33a2645ab07a90f3b608655756cafa 100644 +--- a/src/tests/cmocka/test_ipa_idmap.c ++++ b/src/tests/cmocka/test_ipa_idmap.c +@@ -142,7 +142,7 @@ static struct range_info **get_range_list(TALLOC_CTX *mem_ctx) + return range_list; + } + +-void setup_idmap_ctx(void **state) ++static int setup_idmap_ctx(void **state) + { + int ret; + struct test_ctx *test_ctx; +@@ -177,9 +177,10 @@ void setup_idmap_ctx(void **state) + + check_leaks_push(test_ctx); + *state = test_ctx; ++ return 0; + } + +-void teardown_idmap_ctx(void **state) ++static int teardown_idmap_ctx(void **state) + { + struct test_ctx *test_ctx = talloc_get_type(*state, struct test_ctx); + +@@ -189,6 +190,7 @@ void teardown_idmap_ctx(void **state) + + talloc_free(test_ctx); + assert_true(leak_check_teardown()); ++ return 0; + } + + void test_ipa_idmap_get_ranges_from_sysdb(void **state) +@@ -220,10 +222,10 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test(test_get_idmap_data_from_range), +- unit_test_setup_teardown(test_ipa_idmap_get_ranges_from_sysdb, +- setup_idmap_ctx, teardown_idmap_ctx), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(test_get_idmap_data_from_range), ++ cmocka_unit_test_setup_teardown(test_ipa_idmap_get_ranges_from_sysdb, ++ setup_idmap_ctx, teardown_idmap_ctx), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -245,5 +247,5 @@ int main(int argc, const char *argv[]) + + tests_set_cwd(); + +- return run_tests(tests); ++ return cmocka_run_group_tests(tests, NULL, NULL); + } +diff --git a/src/tests/cmocka/test_negcache.c b/src/tests/cmocka/test_negcache.c +index b6bcb6b087c5c8b4d5f7699feaca3911e2fdc5d8..5ab5bb3c359cf2ecaf2be6c7c9f91600fd03ede4 100644 +--- a/src/tests/cmocka/test_negcache.c ++++ b/src/tests/cmocka/test_negcache.c +@@ -132,7 +132,7 @@ struct test_state { + struct resp_ctx *rctx; + }; + +-static void setup(void **state) ++static int setup(void **state) + { + int ret; + struct test_state *ts; +@@ -145,12 +145,14 @@ static void setup(void **state) + assert_non_null(ts->ctx); + + *state = (void *)ts; ++ return 0; + } + +-static void teardown(void **state) ++static int teardown(void **state) + { + struct test_state *ts = talloc_get_type_abort(*state, struct test_state); + talloc_free(ts); ++ return 0; + } + + static void test_sss_ncache_init(void **state) +@@ -621,28 +623,29 @@ static void test_sss_ncache_prepopulate(void **state) + int main(void) + { + int rv; +- const UnitTest tests[] = { +- unit_test(test_sss_ncache_init), +- unit_test_setup_teardown(test_sss_ncache_uid, setup, teardown), +- unit_test_setup_teardown(test_sss_ncache_gid, setup, teardown), +- unit_test_setup_teardown(test_sss_ncache_sid, setup, teardown), +- unit_test_setup_teardown(test_sss_ncache_user, setup, teardown), +- unit_test_setup_teardown(test_sss_ncache_group, setup, teardown), +- unit_test_setup_teardown(test_sss_ncache_netgr, setup, teardown), +- unit_test_setup_teardown(test_sss_ncache_service_name, setup, +- teardown), +- unit_test_setup_teardown(test_sss_ncache_service_port, setup, +- teardown), +- unit_test_setup_teardown(test_sss_ncache_reset_permanent, setup, +- teardown), +- unit_test_setup_teardown(test_sss_ncache_prepopulate, setup, teardown) ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(test_sss_ncache_init), ++ cmocka_unit_test_setup_teardown(test_sss_ncache_uid, setup, teardown), ++ cmocka_unit_test_setup_teardown(test_sss_ncache_gid, setup, teardown), ++ cmocka_unit_test_setup_teardown(test_sss_ncache_sid, setup, teardown), ++ cmocka_unit_test_setup_teardown(test_sss_ncache_user, setup, teardown), ++ cmocka_unit_test_setup_teardown(test_sss_ncache_group, setup, teardown), ++ cmocka_unit_test_setup_teardown(test_sss_ncache_netgr, setup, teardown), ++ cmocka_unit_test_setup_teardown(test_sss_ncache_service_name, setup, ++ teardown), ++ cmocka_unit_test_setup_teardown(test_sss_ncache_service_port, ++ setup, teardown), ++ cmocka_unit_test_setup_teardown(test_sss_ncache_reset_permanent, setup, ++ teardown), ++ cmocka_unit_test_setup_teardown(test_sss_ncache_prepopulate, ++ setup, teardown) + }; + + tests_set_cwd(); + test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_SYSDB_FILE); + test_dom_suite_setup(TESTS_PATH); + +- rv = run_tests(tests); ++ rv = cmocka_run_group_tests(tests, NULL, NULL); + if (rv == 0) { + test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_SYSDB_FILE); + } +diff --git a/src/tests/cmocka/test_nested_groups.c b/src/tests/cmocka/test_nested_groups.c +index b64d67d3cc802d9bb1e585a63da04b68ecc460c4..f2861847b2011e2a8c4941bd296f1eb567860e75 100644 +--- a/src/tests/cmocka/test_nested_groups.c ++++ b/src/tests/cmocka/test_nested_groups.c +@@ -38,9 +38,9 @@ + #define TEST_ID_PROVIDER "ldap" + + #define new_test(test) \ +- unit_test_setup_teardown(nested_groups_test_ ## test, \ +- nested_groups_test_setup, \ +- nested_groups_test_teardown) ++ cmocka_unit_test_setup_teardown(nested_groups_test_ ## test, \ ++ nested_groups_test_setup, \ ++ nested_groups_test_teardown) + + /* put users and groups under the same container so we can easily run the + * same tests cases for several search base scenarios */ +@@ -393,7 +393,7 @@ static void nested_groups_test_one_group_dup_group_members(void **state) + expected, N_ELEMENTS(expected)); + } + +-void nested_groups_test_setup(void **state) ++static int nested_groups_test_setup(void **state) + { + errno_t ret; + struct nested_groups_test_ctx *test_ctx = NULL; +@@ -439,11 +439,13 @@ void nested_groups_test_setup(void **state) + ret = sdap_idmap_init(test_ctx, test_ctx->sdap_id_ctx, &test_ctx->idmap_ctx); + assert_int_equal(ret, EOK); + test_ctx->sdap_opts->idmap_ctx = test_ctx->idmap_ctx; ++ return 0; + } + +-void nested_groups_test_teardown(void **state) ++static int nested_groups_test_teardown(void **state) + { + talloc_zfree(*state); ++ return 0; + } + + int main(int argc, const char *argv[]) +@@ -460,7 +462,7 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { ++ const struct CMUnitTest tests[] = { + new_test(one_group_no_members), + new_test(one_group_unique_members), + new_test(one_group_dup_users), +@@ -491,7 +493,7 @@ int main(int argc, const char *argv[]) + test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_SYSDB_FILE); + test_dom_suite_setup(TESTS_PATH); + +- rv = run_tests(tests); ++ rv = cmocka_run_group_tests(tests, NULL, NULL); + if (rv == 0 && !no_cleanup) { + test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_SYSDB_FILE); + } +diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c +index ba84fccf718c1a3f4a8ff20a54d8e82c2aa58a1e..2406adfe20e7ac30662f338e097fbb350371384d 100644 +--- a/src/tests/cmocka/test_nss_srv.c ++++ b/src/tests/cmocka/test_nss_srv.c +@@ -2072,7 +2072,7 @@ void test_nss_getorigbyname_multi_value_attrs(void **state) + assert_int_equal(ret, EOK); + } + +-void nss_test_setup(void **state) ++static int nss_test_setup(void **state) + { + struct sss_test_conf_param params[] = { + { "enumerate", "false" }, +@@ -2080,9 +2080,10 @@ void nss_test_setup(void **state) + }; + + test_nss_setup(params, state); ++ return 0; + } + +-void nss_fqdn_test_setup(void **state) ++static int nss_fqdn_test_setup(void **state) + { + struct sss_test_conf_param params[] = { + { "enumerate", "false" }, +@@ -2091,9 +2092,10 @@ void nss_fqdn_test_setup(void **state) + }; + + test_nss_setup(params, state); ++ return 0; + } + +-void nss_test_setup_extra_attr(void **state) ++static int nss_test_setup_extra_attr(void **state) + { + struct sss_test_conf_param params[] = { + { "enumerate", "false" }, +@@ -2103,9 +2105,10 @@ void nss_test_setup_extra_attr(void **state) + test_nss_setup(params, state); + + nss_test_ctx->nctx->extra_attributes = global_extra_attrs; ++ return 0; + } + +-void nss_subdom_test_setup(void **state) ++static int nss_subdom_test_setup(void **state) + { + const char *const testdom[4] = { TEST_SUBDOM_NAME, "TEST.SUB", "test", "S-3" }; + struct sss_domain_info *subdomain; +@@ -2127,9 +2130,10 @@ void nss_subdom_test_setup(void **state) + assert_int_equal(ret, EOK); + + nss_test_ctx->subdom = subdomain; ++ return 0; + } + +-void nss_fqdn_fancy_test_setup(void **state) ++static int nss_fqdn_fancy_test_setup(void **state) + { + struct sss_test_conf_param params[] = { + { "enumerate", "false" }, +@@ -2138,11 +2142,13 @@ void nss_fqdn_fancy_test_setup(void **state) + }; + + test_nss_setup(params, state); ++ return 0; + } + +-void nss_test_teardown(void **state) ++static int nss_test_teardown(void **state) + { + talloc_free(nss_test_ctx); ++ return 0; + } + + int main(int argc, const char *argv[]) +@@ -2159,71 +2165,81 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test_setup_teardown(test_nss_getpwnam, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getpwuid, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getpwnam_neg, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getpwuid_neg, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getpwnam_search, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getpwuid_search, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getpwnam_update, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getpwuid_update, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getpwnam_fqdn, +- nss_fqdn_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getpwnam_fqdn_fancy, +- nss_fqdn_fancy_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getpwnam_space, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getpwnam_space_sub, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getpwnam_space_sub_query, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getgrnam_no_members, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getgrnam_members, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getgrnam_members_fqdn, +- nss_fqdn_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getgrnam_members_subdom, +- nss_subdom_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getgrnam_mix_dom, +- nss_subdom_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getgrnam_mix_dom_fqdn, +- nss_subdom_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getgrnam_mix_subdom, +- nss_subdom_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getgrnam_space, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getgrnam_space_sub, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_well_known_getnamebysid, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_well_known_getnamebysid_special, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_well_known_getnamebysid_non_existing, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_well_known_getidbysid_failure, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_well_known_getsidbyname, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_well_known_getsidbyname_nonexisting, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_well_known_getsidbyname_special, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getorigbyname, +- nss_test_setup, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getorigbyname_extra_attrs, +- nss_test_setup_extra_attr, nss_test_teardown), +- unit_test_setup_teardown(test_nss_getorigbyname_multi_value_attrs, +- nss_test_setup_extra_attr, nss_test_teardown), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_setup_teardown(test_nss_getpwnam, ++ nss_test_setup, nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getpwuid, ++ nss_test_setup, nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getpwnam_neg, ++ nss_test_setup, nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getpwuid_neg, ++ nss_test_setup, nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getpwnam_search, ++ nss_test_setup, nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getpwuid_search, ++ nss_test_setup, ++ nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getpwnam_update, ++ nss_test_setup, nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getpwuid_update, ++ nss_test_setup, nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getpwnam_fqdn, ++ nss_fqdn_test_setup, ++ nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getpwnam_fqdn_fancy, ++ nss_fqdn_fancy_test_setup, ++ nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getpwnam_space, ++ nss_test_setup, nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getpwnam_space_sub, ++ nss_test_setup, nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getpwnam_space_sub_query, ++ nss_test_setup, nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getgrnam_no_members, ++ nss_test_setup, nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getgrnam_members, ++ nss_test_setup, nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getgrnam_members_fqdn, ++ nss_fqdn_test_setup, nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getgrnam_members_subdom, ++ nss_subdom_test_setup, ++ nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_dom, ++ nss_subdom_test_setup, ++ nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_dom_fqdn, ++ nss_subdom_test_setup, ++ nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_subdom, ++ nss_subdom_test_setup, ++ nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getgrnam_space, ++ nss_test_setup, nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getgrnam_space_sub, ++ nss_test_setup, nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_well_known_getnamebysid, ++ nss_test_setup, nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_well_known_getnamebysid_special, ++ nss_test_setup, nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_well_known_getnamebysid_non_existing, ++ nss_test_setup, nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_well_known_getidbysid_failure, ++ nss_test_setup, nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_well_known_getsidbyname, ++ nss_test_setup, nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_well_known_getsidbyname_nonexisting, ++ nss_test_setup, nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_well_known_getsidbyname_special, ++ nss_test_setup, nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getorigbyname, ++ nss_test_setup, ++ nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getorigbyname_extra_attrs, ++ nss_test_setup_extra_attr, ++ nss_test_teardown), ++ cmocka_unit_test_setup_teardown(test_nss_getorigbyname_multi_value_attrs, ++ nss_test_setup_extra_attr, ++ nss_test_teardown), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -2249,7 +2265,7 @@ int main(int argc, const char *argv[]) + test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_SYSDB_FILE); + test_dom_suite_setup(TESTS_PATH); + +- rv = run_tests(tests); ++ rv = cmocka_run_group_tests(tests, NULL, NULL); + if (rv == 0 && !no_cleanup) { + test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_SYSDB_FILE); + } +diff --git a/src/tests/cmocka/test_resolv_fake.c b/src/tests/cmocka/test_resolv_fake.c +index 6c201e7023c4138703a8057f6eb10c9210385499..eac5697e49ce30224a89a686fe3fb5fdffe2b15b 100644 +--- a/src/tests/cmocka/test_resolv_fake.c ++++ b/src/tests/cmocka/test_resolv_fake.c +@@ -221,7 +221,7 @@ struct resolv_fake_ctx { + struct sss_test_ctx *ctx; + }; + +-void test_resolv_fake_setup(void **state) ++static int test_resolv_fake_setup(void **state) + { + struct resolv_fake_ctx *test_ctx; + int ret; +@@ -242,9 +242,10 @@ void test_resolv_fake_setup(void **state) + assert_int_equal(ret, EOK); + + *state = test_ctx; ++ return 0; + } + +-void test_resolv_fake_teardown(void **state) ++static int test_resolv_fake_teardown(void **state) + { + struct resolv_fake_ctx *test_ctx = + talloc_get_type(*state, struct resolv_fake_ctx); +@@ -252,6 +253,7 @@ void test_resolv_fake_teardown(void **state) + talloc_free(test_ctx); + talloc_free(global_mock_context); + assert_true(leak_check_teardown()); ++ return 0; + } + + void test_resolv_fake_srv_done(struct tevent_req *req) +@@ -342,10 +344,10 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test_setup_teardown(test_resolv_fake_srv, +- test_resolv_fake_setup, +- test_resolv_fake_teardown), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_setup_teardown(test_resolv_fake_srv, ++ test_resolv_fake_setup, ++ test_resolv_fake_teardown), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -369,6 +371,6 @@ int main(int argc, const char *argv[]) + * they might not after a failed run. Remove the old db to be sure */ + tests_set_cwd(); + +- rv = run_tests(tests); ++ rv = cmocka_run_group_tests(tests, NULL, NULL); + return rv; + } +diff --git a/src/tests/cmocka/test_responder_common.c b/src/tests/cmocka/test_responder_common.c +index a6f642ab23a973a423a8393b44807e37f79e5c0e..8d727b20843082667185c0ecc5d613b50b671694 100644 +--- a/src/tests/cmocka/test_responder_common.c ++++ b/src/tests/cmocka/test_responder_common.c +@@ -84,7 +84,7 @@ struct parse_inp_test_ctx { + struct resp_ctx *rctx; + }; + +-void parse_inp_test_setup(void **state) ++static int parse_inp_test_setup(void **state) + { + struct parse_inp_test_ctx *parse_inp_ctx; + int ret; +@@ -115,9 +115,10 @@ void parse_inp_test_setup(void **state) + + check_leaks_push(parse_inp_ctx); + *state = parse_inp_ctx; ++ return 0; + } + +-void parse_inp_test_teardown(void **state) ++static int parse_inp_test_teardown(void **state) + { + struct parse_inp_test_ctx *parse_inp_ctx = talloc_get_type(*state, + struct parse_inp_test_ctx); +@@ -126,6 +127,7 @@ void parse_inp_test_teardown(void **state) + + talloc_free(parse_inp_ctx); + assert_true(leak_check_teardown()); ++ return 0; + } + + int __real_sss_parse_name_for_domains(TALLOC_CTX *memctx, +@@ -279,19 +281,19 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test_setup_teardown(parse_inp_simple, +- parse_inp_test_setup, +- parse_inp_test_teardown), +- unit_test_setup_teardown(parse_inp_call_dp, +- parse_inp_test_setup, +- parse_inp_test_teardown), +- unit_test_setup_teardown(parse_inp_call_attach, +- parse_inp_test_setup, +- parse_inp_test_teardown), +- unit_test_setup_teardown(parse_inp_call_neg, +- parse_inp_test_setup, +- parse_inp_test_teardown), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_setup_teardown(parse_inp_simple, ++ parse_inp_test_setup, ++ parse_inp_test_teardown), ++ cmocka_unit_test_setup_teardown(parse_inp_call_dp, ++ parse_inp_test_setup, ++ parse_inp_test_teardown), ++ cmocka_unit_test_setup_teardown(parse_inp_call_attach, ++ parse_inp_test_setup, ++ parse_inp_test_teardown), ++ cmocka_unit_test_setup_teardown(parse_inp_call_neg, ++ parse_inp_test_setup, ++ parse_inp_test_teardown), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -317,7 +319,7 @@ int main(int argc, const char *argv[]) + test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_SYSDB_FILE); + test_dom_suite_setup(TESTS_PATH); + +- rv = run_tests(tests); ++ rv = cmocka_run_group_tests(tests, NULL, NULL); + if (rv == 0 && !no_cleanup) { + test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_SYSDB_FILE); + } +diff --git a/src/tests/cmocka/test_sdap.c b/src/tests/cmocka/test_sdap.c +index 404e100a841dbb157de7fa02864838d0412145f9..a1c9aefd86ba7b048916d681025dd1bb644b128e 100644 +--- a/src/tests/cmocka/test_sdap.c ++++ b/src/tests/cmocka/test_sdap.c +@@ -246,7 +246,7 @@ struct parse_test_ctx { + struct sdap_msg sm; + }; + +-void parse_entry_test_setup(void **state) ++static int parse_entry_test_setup(void **state) + { + struct parse_test_ctx *test_ctx; + +@@ -257,9 +257,10 @@ void parse_entry_test_setup(void **state) + + check_leaks_push(test_ctx); + *state = test_ctx; ++ return 0; + } + +-void parse_entry_test_teardown(void **state) ++static int parse_entry_test_teardown(void **state) + { + struct parse_test_ctx *test_ctx = talloc_get_type_abort(*state, + struct parse_test_ctx); +@@ -267,6 +268,7 @@ void parse_entry_test_teardown(void **state) + assert_true(check_leaks_pop(test_ctx) == true); + talloc_free(test_ctx); + assert_true(leak_check_teardown()); ++ return 0; + } + + void test_parse_with_map(void **state) +@@ -728,41 +730,41 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test_setup_teardown(test_parse_with_map, +- parse_entry_test_setup, +- parse_entry_test_teardown), +- unit_test_setup_teardown(test_parse_no_map, +- parse_entry_test_setup, +- parse_entry_test_teardown), +- unit_test_setup_teardown(test_parse_no_attrs, +- parse_entry_test_setup, +- parse_entry_test_teardown), +- unit_test_setup_teardown(test_parse_dups, +- parse_entry_test_setup, +- parse_entry_test_teardown), +- unit_test_setup_teardown(test_parse_deref, +- parse_entry_test_setup, +- parse_entry_test_teardown), +- unit_test_setup_teardown(test_parse_deref_no_attrs, +- parse_entry_test_setup, +- parse_entry_test_teardown), +- unit_test_setup_teardown(test_parse_secondary_oc, +- parse_entry_test_setup, +- parse_entry_test_teardown), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_setup_teardown(test_parse_with_map, ++ parse_entry_test_setup, ++ parse_entry_test_teardown), ++ cmocka_unit_test_setup_teardown(test_parse_no_map, ++ parse_entry_test_setup, ++ parse_entry_test_teardown), ++ cmocka_unit_test_setup_teardown(test_parse_no_attrs, ++ parse_entry_test_setup, ++ parse_entry_test_teardown), ++ cmocka_unit_test_setup_teardown(test_parse_dups, ++ parse_entry_test_setup, ++ parse_entry_test_teardown), ++ cmocka_unit_test_setup_teardown(test_parse_deref, ++ parse_entry_test_setup, ++ parse_entry_test_teardown), ++ cmocka_unit_test_setup_teardown(test_parse_deref_no_attrs, ++ parse_entry_test_setup, ++ parse_entry_test_teardown), ++ cmocka_unit_test_setup_teardown(test_parse_secondary_oc, ++ parse_entry_test_setup, ++ parse_entry_test_teardown), + /* Negative tests */ +- unit_test_setup_teardown(test_parse_no_oc, +- parse_entry_test_setup, +- parse_entry_test_teardown), +- unit_test_setup_teardown(test_parse_bad_oc, +- parse_entry_test_setup, +- parse_entry_test_teardown), +- unit_test_setup_teardown(test_parse_no_dn, +- parse_entry_test_setup, +- parse_entry_test_teardown), +- unit_test_setup_teardown(test_parse_deref_map_mismatch, +- parse_entry_test_setup, +- parse_entry_test_teardown), ++ cmocka_unit_test_setup_teardown(test_parse_no_oc, ++ parse_entry_test_setup, ++ parse_entry_test_teardown), ++ cmocka_unit_test_setup_teardown(test_parse_bad_oc, ++ parse_entry_test_setup, ++ parse_entry_test_teardown), ++ cmocka_unit_test_setup_teardown(test_parse_no_dn, ++ parse_entry_test_setup, ++ parse_entry_test_teardown), ++ cmocka_unit_test_setup_teardown(test_parse_deref_map_mismatch, ++ parse_entry_test_setup, ++ parse_entry_test_teardown), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -786,5 +788,5 @@ int main(int argc, const char *argv[]) + * they might not after a failed run. Remove the old db to be sure */ + tests_set_cwd(); + +- return run_tests(tests); ++ return cmocka_run_group_tests(tests, NULL, NULL); + } +diff --git a/src/tests/cmocka/test_search_bases.c b/src/tests/cmocka/test_search_bases.c +index e03ef3662685d92335bce4a7023e1ac7e64432c8..4538eaceb8bad2f516614c6e72c704e9265b09fb 100644 +--- a/src/tests/cmocka/test_search_bases.c ++++ b/src/tests/cmocka/test_search_bases.c +@@ -179,13 +179,13 @@ void test_get_by_dn_fail(void **state) + + int main(void) + { +- const UnitTest tests[] = { +- unit_test(test_search_bases_fail), +- unit_test(test_search_bases_success), +- unit_test(test_get_by_dn_fail), +- unit_test(test_get_by_dn), +- unit_test(test_get_by_dn2) ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(test_search_bases_fail), ++ cmocka_unit_test(test_search_bases_success), ++ cmocka_unit_test(test_get_by_dn_fail), ++ cmocka_unit_test(test_get_by_dn), ++ cmocka_unit_test(test_get_by_dn2) + }; + +- return run_tests(tests); ++ return cmocka_run_group_tests(tests, NULL, NULL); + } +diff --git a/src/tests/cmocka/test_sss_idmap.c b/src/tests/cmocka/test_sss_idmap.c +index ccdfa63ad6065b29187637b721b5e93548a09372..1e52c8507461ab3caa04eb2c0e63410c363ba723 100644 +--- a/src/tests/cmocka/test_sss_idmap.c ++++ b/src/tests/cmocka/test_sss_idmap.c +@@ -58,7 +58,7 @@ static void idmap_free(void *ptr, void *pvt) + talloc_free(ptr); + } + +-void test_sss_idmap_setup(void **state) ++static int test_sss_idmap_setup(void **state) + { + struct test_ctx *test_ctx; + enum idmap_error_code err; +@@ -78,10 +78,11 @@ void test_sss_idmap_setup(void **state) + assert_int_equal(err, IDMAP_SUCCESS); + + *state = test_ctx; ++ return 0; + } + +-void setup_ranges(struct test_ctx *test_ctx, bool external_mapping, +- bool second_domain) ++static int setup_ranges(struct test_ctx *test_ctx, bool external_mapping, ++ bool second_domain) + { + struct sss_idmap_range range; + enum idmap_error_code err; +@@ -112,9 +113,10 @@ void setup_ranges(struct test_ctx *test_ctx, bool external_mapping, + err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, name, sid, &range, NULL, + TEST_OFFSET, external_mapping); + assert_int_equal(err, IDMAP_SUCCESS); ++ return 0; + } + +-void test_sss_idmap_setup_with_domains(void **state) { ++static int test_sss_idmap_setup_with_domains(void **state) { + struct test_ctx *test_ctx; + + test_sss_idmap_setup(state); +@@ -123,9 +125,10 @@ void test_sss_idmap_setup_with_domains(void **state) { + assert_non_null(test_ctx); + + setup_ranges(test_ctx, false, false); ++ return 0; + } + +-void test_sss_idmap_setup_with_external_mappings(void **state) { ++static int test_sss_idmap_setup_with_external_mappings(void **state) { + struct test_ctx *test_ctx; + + test_sss_idmap_setup(state); +@@ -134,9 +137,10 @@ void test_sss_idmap_setup_with_external_mappings(void **state) { + assert_non_null(test_ctx); + + setup_ranges(test_ctx, true, false); ++ return 0; + } + +-void test_sss_idmap_setup_with_both(void **state) { ++static int test_sss_idmap_setup_with_both(void **state) { + struct test_ctx *test_ctx; + + test_sss_idmap_setup(state); +@@ -146,9 +150,10 @@ void test_sss_idmap_setup_with_both(void **state) { + + setup_ranges(test_ctx, false, false); + setup_ranges(test_ctx, true, true); ++ return 0; + } + +-void test_sss_idmap_teardown(void **state) ++static int test_sss_idmap_teardown(void **state) + { + struct test_ctx *test_ctx; + +@@ -161,6 +166,7 @@ void test_sss_idmap_teardown(void **state) + assert_true(check_leaks_pop(test_ctx) == true); + talloc_free(test_ctx); + assert_true(leak_check_teardown()); ++ return 0; + } + + void test_add_domain(void **state) +@@ -510,28 +516,29 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test_setup_teardown(test_add_domain, +- test_sss_idmap_setup, test_sss_idmap_teardown), +- unit_test_setup_teardown(test_map_id, +- test_sss_idmap_setup_with_domains, +- test_sss_idmap_teardown), +- unit_test_setup_teardown(test_map_id_external, +- test_sss_idmap_setup_with_external_mappings, +- test_sss_idmap_teardown), +- unit_test_setup_teardown(test_check_sid_id, +- test_sss_idmap_setup_with_domains, +- test_sss_idmap_teardown), +- unit_test_setup_teardown(test_check_sid_id, +- test_sss_idmap_setup_with_external_mappings, +- test_sss_idmap_teardown), +- unit_test_setup_teardown(test_has_algorithmic, +- test_sss_idmap_setup_with_both, +- test_sss_idmap_teardown), +- unit_test_setup_teardown(test_has_algorithmic_by_name, +- test_sss_idmap_setup_with_both, +- test_sss_idmap_teardown), +- unit_test(test_sss_idmap_check_collision_ex), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_setup_teardown(test_add_domain, ++ test_sss_idmap_setup, ++ test_sss_idmap_teardown), ++ cmocka_unit_test_setup_teardown(test_map_id, ++ test_sss_idmap_setup_with_domains, ++ test_sss_idmap_teardown), ++ cmocka_unit_test_setup_teardown(test_map_id_external, ++ test_sss_idmap_setup_with_external_mappings, ++ test_sss_idmap_teardown), ++ cmocka_unit_test_setup_teardown(test_check_sid_id, ++ test_sss_idmap_setup_with_domains, ++ test_sss_idmap_teardown), ++ cmocka_unit_test_setup_teardown(test_check_sid_id, ++ test_sss_idmap_setup_with_external_mappings, ++ test_sss_idmap_teardown), ++ cmocka_unit_test_setup_teardown(test_has_algorithmic, ++ test_sss_idmap_setup_with_both, ++ test_sss_idmap_teardown), ++ cmocka_unit_test_setup_teardown(test_has_algorithmic_by_name, ++ test_sss_idmap_setup_with_both, ++ test_sss_idmap_teardown), ++ cmocka_unit_test(test_sss_idmap_check_collision_ex), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -553,5 +560,5 @@ int main(int argc, const char *argv[]) + + tests_set_cwd(); + +- return run_tests(tests); ++ return cmocka_run_group_tests(tests, NULL, NULL); + } +diff --git a/src/tests/cmocka/test_sss_sifp.c b/src/tests/cmocka/test_sss_sifp.c +index 3c009d9780cb8c4824ed86a3a9b1bf98e2d06c25..9773d0f9554a7742f6855fb5245fae18123d6dc0 100644 +--- a/src/tests/cmocka/test_sss_sifp.c ++++ b/src/tests/cmocka/test_sss_sifp.c +@@ -116,7 +116,7 @@ static void reply_variant_array(DBusMessage *reply, + assert_true(bret); + } + +-static void test_setup(void **state) ++static int test_setup(void **state) + { + sss_sifp_error ret; + +@@ -125,23 +125,26 @@ static void test_setup(void **state) + + test_ctx.reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN); + assert_non_null(test_ctx.reply); ++ return 0; + } + +-static void test_teardown_parser(void **state) ++static int test_teardown_parser(void **state) + { + sss_sifp_free(&test_ctx.dbus_ctx); + assert_null(test_ctx.dbus_ctx); + + dbus_message_unref(test_ctx.reply); + test_ctx.reply = NULL; ++ return 0; + } + +-static void test_teardown_api(void **state) ++static int test_teardown_api(void **state) + { + sss_sifp_free(&test_ctx.dbus_ctx); + assert_null(test_ctx.dbus_ctx); + + /* sss_sifp is responsible for freeing the reply */ ++ return 0; + } + + void test_sss_sifp_strdup_valid(void **state) +@@ -2150,100 +2153,100 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test_setup_teardown(test_sss_sifp_strdup_valid, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_strdup_null, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_strcat_valid, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_strcat_left_null, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_strcat_right_null, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_strcat_both_null, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_object_path_valid, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_object_path_invalid, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_object_path_list_valid, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_object_path_list_invalid, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_bool, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_int16, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_uint16, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_int32, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_uint32, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_int64, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_uint64, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_string, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_object_path, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_string_dict, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_bool_array, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_bool_array_empty, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_int32_array, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_int32_array_empty, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_uint32_array, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_uint32_array_empty, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_int64_array, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_int64_array_empty, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_uint64_array, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_uint64_array_empty, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_string_array, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_string_array_empty, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_object_path_array, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_object_path_array_empty, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_string_dict_array, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_list, +- test_setup, test_teardown_parser), +- unit_test_setup_teardown(test_sss_sifp_parse_attr_list_empty, +- test_setup, test_teardown_parser), +- unit_test(test_sss_sifp_get_iface_for_object), +- unit_test_setup_teardown(test_sss_sifp_fetch_attr, +- test_setup, test_teardown_api), +- unit_test_setup_teardown(test_sss_sifp_fetch_all_attrs, +- test_setup, test_teardown_api), +- unit_test_setup_teardown(test_sss_sifp_fetch_object, +- test_setup, test_teardown_api), +- unit_test_setup_teardown(test_sss_sifp_invoke_list_zeroargs, +- test_setup, test_teardown_api), +- unit_test_setup_teardown(test_sss_sifp_invoke_list_withargs, +- test_setup, test_teardown_api), +- unit_test_setup_teardown(test_sss_sifp_invoke_find_zeroargs, +- test_setup, test_teardown_api), +- unit_test_setup_teardown(test_sss_sifp_invoke_find_withargs, +- test_setup, test_teardown_api), +- unit_test_setup_teardown(test_sss_sifp_list_domains, +- test_setup, test_teardown_api), +- unit_test_setup_teardown(test_sss_sifp_fetch_domain_by_name, +- test_setup, test_teardown_api), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_setup_teardown(test_sss_sifp_strdup_valid, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_strdup_null, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_strcat_valid, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_strcat_left_null, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_strcat_right_null, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_strcat_both_null, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_object_path_valid, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_object_path_invalid, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_object_path_list_valid, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_object_path_list_invalid, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_bool, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_int16, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_uint16, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_int32, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_uint32, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_int64, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_uint64, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_string, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_object_path, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_string_dict, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_bool_array, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_bool_array_empty, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_int32_array, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_int32_array_empty, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_uint32_array, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_uint32_array_empty, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_int64_array, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_int64_array_empty, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_uint64_array, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_uint64_array_empty, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_string_array, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_string_array_empty, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_object_path_array, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_object_path_array_empty, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_string_dict_array, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_list, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_list_empty, ++ test_setup, test_teardown_parser), ++ cmocka_unit_test(test_sss_sifp_get_iface_for_object), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_fetch_attr, ++ test_setup, test_teardown_api), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_fetch_all_attrs, ++ test_setup, test_teardown_api), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_fetch_object, ++ test_setup, test_teardown_api), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_invoke_list_zeroargs, ++ test_setup, test_teardown_api), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_invoke_list_withargs, ++ test_setup, test_teardown_api), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_invoke_find_zeroargs, ++ test_setup, test_teardown_api), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_invoke_find_withargs, ++ test_setup, test_teardown_api), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_list_domains, ++ test_setup, test_teardown_api), ++ cmocka_unit_test_setup_teardown(test_sss_sifp_fetch_domain_by_name, ++ test_setup, test_teardown_api), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -2263,7 +2266,7 @@ int main(int argc, const char *argv[]) + + DEBUG_CLI_INIT(debug_level); + +- rv = run_tests(tests); ++ rv = cmocka_run_group_tests(tests, NULL, NULL); + + return rv; + } +diff --git a/src/tests/cmocka/test_sysdb_views.c b/src/tests/cmocka/test_sysdb_views.c +index f5a5377ef1c924aa93102fe2170c11d036b6da4b..69118cd87a172696f8220e1446df7a856e368cb6 100644 +--- a/src/tests/cmocka/test_sysdb_views.c ++++ b/src/tests/cmocka/test_sysdb_views.c +@@ -116,7 +116,7 @@ static int _setup_sysdb_tests(struct sysdb_test_ctx **ctx, bool enumerate) + + #define setup_sysdb_tests(ctx) _setup_sysdb_tests((ctx), false) + +-static void test_sysdb_setup(void **state) ++static int test_sysdb_setup(void **state) + { + int ret; + struct sysdb_test_ctx *test_ctx; +@@ -127,15 +127,17 @@ static void test_sysdb_setup(void **state) + assert_int_equal(ret, EOK); + + *state = (void *) test_ctx; ++ return 0; + } + +-static void test_sysdb_teardown(void **state) ++static int test_sysdb_teardown(void **state) + { + struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, + struct sysdb_test_ctx); + + talloc_free(test_ctx); + assert_true(leak_check_teardown()); ++ return 0; + } + + static void test_sysdb_store_override(void **state) +@@ -440,17 +442,17 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test_setup_teardown(test_sysdb_store_override, +- test_sysdb_setup, test_sysdb_teardown), +- unit_test_setup_teardown(test_sysdb_add_overrides_to_object, +- test_sysdb_setup, test_sysdb_teardown), +- unit_test_setup_teardown(test_split_ipa_anchor, +- test_sysdb_setup, test_sysdb_teardown), +- unit_test_setup_teardown(test_sysdb_delete_view_tree, +- test_sysdb_setup, test_sysdb_teardown), +- unit_test_setup_teardown(test_sysdb_invalidate_overrides, +- test_sysdb_setup, test_sysdb_teardown), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_setup_teardown(test_sysdb_store_override, ++ test_sysdb_setup, test_sysdb_teardown), ++ cmocka_unit_test_setup_teardown(test_sysdb_add_overrides_to_object, ++ test_sysdb_setup, test_sysdb_teardown), ++ cmocka_unit_test_setup_teardown(test_split_ipa_anchor, ++ test_sysdb_setup, test_sysdb_teardown), ++ cmocka_unit_test_setup_teardown(test_sysdb_delete_view_tree, ++ test_sysdb_setup, test_sysdb_teardown), ++ cmocka_unit_test_setup_teardown(test_sysdb_invalidate_overrides, ++ test_sysdb_setup, test_sysdb_teardown), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -473,7 +475,7 @@ int main(int argc, const char *argv[]) + tests_set_cwd(); + test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_FILE, LOCAL_SYSDB_FILE); + test_dom_suite_setup(TESTS_PATH); +- rv = run_tests(tests); ++ rv = cmocka_run_group_tests(tests, NULL, NULL); + + if (rv == 0 && no_cleanup == 0) { + test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_FILE, LOCAL_SYSDB_FILE); +diff --git a/src/tests/cmocka/test_utils.c b/src/tests/cmocka/test_utils.c +index dc6e35dc02204714c5befbf4d67e7e7cbd8f4af1..2203e2c49efacab27e9cf4c6c699319cfdf5370c 100644 +--- a/src/tests/cmocka/test_utils.c ++++ b/src/tests/cmocka/test_utils.c +@@ -56,7 +56,7 @@ struct dom_list_test_ctx { + }; + + +-void setup_dom_list(void **state) ++static int setup_dom_list(void **state) + { + struct dom_list_test_ctx *test_ctx; + struct sss_domain_info *dom = NULL; +@@ -87,20 +87,22 @@ void setup_dom_list(void **state) + + check_leaks_push(test_ctx); + *state = test_ctx; ++ return 0; + } + +-void teardown_dom_list(void **state) ++static int teardown_dom_list(void **state) + { + struct dom_list_test_ctx *test_ctx = talloc_get_type(*state, + struct dom_list_test_ctx); + if (test_ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Type mismatch\n"); +- return; ++ return 1; + } + + assert_true(check_leaks_pop(test_ctx) == true); + talloc_free(test_ctx); + assert_true(leak_check_teardown()); ++ return 0; + } + + void test_find_domain_by_name_null(void **state) +@@ -465,7 +467,7 @@ struct name_init_test_ctx { + "((?P[^@]+)@(?P.+$))|" \ + "(^(?P[^@\\\\]+)$))" + +-void confdb_test_setup(void **state) ++static int confdb_test_setup(void **state) + { + struct name_init_test_ctx *test_ctx; + char *conf_db = NULL; +@@ -524,9 +526,10 @@ void confdb_test_setup(void **state) + + check_leaks_push(test_ctx); + *state = test_ctx; ++ return 0; + } + +-void confdb_test_teardown(void **state) ++static int confdb_test_teardown(void **state) + { + struct name_init_test_ctx *test_ctx; + +@@ -535,6 +538,7 @@ void confdb_test_teardown(void **state) + assert_true(check_leaks_pop(test_ctx) == true); + talloc_free(test_ctx); + assert_true(leak_check_teardown()); ++ return 0; + } + + void test_sss_names_init(void **state) +@@ -721,7 +725,7 @@ void check_expanded_value(TALLOC_CTX *tmp_ctx, + talloc_free(homedir); + } + +-void setup_homedir_ctx(void **state) ++static int setup_homedir_ctx(void **state) + { + struct sss_nss_homedir_ctx *homedir_ctx; + +@@ -740,20 +744,22 @@ void setup_homedir_ctx(void **state) + + check_leaks_push(homedir_ctx); + *state = homedir_ctx; ++ return 0; + } + +-void teardown_homedir_ctx(void **state) ++static int teardown_homedir_ctx(void **state) + { + struct sss_nss_homedir_ctx *homedir_ctx = talloc_get_type(*state, + struct sss_nss_homedir_ctx); + if (homedir_ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Type mismatch\n"); +- return; ++ return 1; + } + + assert_true(check_leaks_pop(homedir_ctx) == true); + talloc_free(homedir_ctx); + assert_true(leak_check_teardown()); ++ return 0; + } + + void test_expand_homedir_template_NULL(void **state) +@@ -877,17 +883,19 @@ void test_expand_homedir_template(void **state) + talloc_free(tmp_ctx); + } + +-void setup_add_strings_lists(void **state) ++static int setup_add_strings_lists(void **state) + { + assert_true(leak_check_setup()); + + check_leaks_push(global_talloc_context); ++ return 0; + } + +-void teardown_add_strings_lists(void **state) ++static int teardown_add_strings_lists(void **state) + { + assert_true(check_leaks_pop(global_talloc_context) == true); + assert_true(leak_check_teardown()); ++ return 0; + } + + void test_add_strings_lists(void **state) +@@ -1083,45 +1091,49 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test_setup_teardown(test_find_domain_by_sid_null, +- setup_dom_list, teardown_dom_list), +- unit_test_setup_teardown(test_find_domain_by_sid, +- setup_dom_list, teardown_dom_list), +- unit_test_setup_teardown(test_find_domain_by_sid_missing_sid, +- setup_dom_list, teardown_dom_list), +- unit_test_setup_teardown(test_find_domain_by_sid_disabled, +- setup_dom_list, teardown_dom_list), +- unit_test_setup_teardown(test_find_domain_by_name_null, +- setup_dom_list, teardown_dom_list), +- unit_test_setup_teardown(test_find_domain_by_name, +- setup_dom_list, teardown_dom_list), +- unit_test_setup_teardown(test_find_domain_by_name_missing_flat_name, +- setup_dom_list, teardown_dom_list), +- unit_test_setup_teardown(test_find_domain_by_name_disabled, +- setup_dom_list, teardown_dom_list), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_setup_teardown(test_find_domain_by_sid_null, ++ setup_dom_list, teardown_dom_list), ++ cmocka_unit_test_setup_teardown(test_find_domain_by_sid, ++ setup_dom_list, teardown_dom_list), ++ cmocka_unit_test_setup_teardown(test_find_domain_by_sid_missing_sid, ++ setup_dom_list, teardown_dom_list), ++ cmocka_unit_test_setup_teardown(test_find_domain_by_sid_disabled, ++ setup_dom_list, teardown_dom_list), ++ cmocka_unit_test_setup_teardown(test_find_domain_by_name_null, ++ setup_dom_list, teardown_dom_list), ++ cmocka_unit_test_setup_teardown(test_find_domain_by_name, ++ setup_dom_list, teardown_dom_list), ++ cmocka_unit_test_setup_teardown(test_find_domain_by_name_missing_flat_name, ++ setup_dom_list, teardown_dom_list), ++ cmocka_unit_test_setup_teardown(test_find_domain_by_name_disabled, ++ setup_dom_list, teardown_dom_list), + +- unit_test_setup_teardown(test_sss_names_init, +- confdb_test_setup, confdb_test_teardown), ++ cmocka_unit_test_setup_teardown(test_sss_names_init, ++ confdb_test_setup, ++ confdb_test_teardown), + +- unit_test(test_well_known_sid_to_name), +- unit_test(test_name_to_well_known_sid), ++ cmocka_unit_test(test_well_known_sid_to_name), ++ cmocka_unit_test(test_name_to_well_known_sid), + +- unit_test_setup_teardown(test_sss_filter_sanitize_for_dom, +- setup_dom_list, teardown_dom_list), ++ cmocka_unit_test_setup_teardown(test_sss_filter_sanitize_for_dom, ++ setup_dom_list, ++ teardown_dom_list), + +- unit_test(test_expand_homedir_template_NULL), +- unit_test_setup_teardown(test_expand_homedir_template, +- setup_homedir_ctx, teardown_homedir_ctx), +- unit_test(test_textual_public_key), +- unit_test(test_replace_whitespaces), +- unit_test(test_reverse_replace_whitespaces), +- unit_test_setup_teardown(test_add_strings_lists, +- setup_add_strings_lists, +- teardown_add_strings_lists), +- unit_test(test_sss_write_krb5_conf_snippet), +- unit_test_setup_teardown(test_fix_domain_in_name_list, +- confdb_test_setup, confdb_test_teardown), ++ cmocka_unit_test(test_expand_homedir_template_NULL), ++ cmocka_unit_test_setup_teardown(test_expand_homedir_template, ++ setup_homedir_ctx, ++ teardown_homedir_ctx), ++ cmocka_unit_test(test_textual_public_key), ++ cmocka_unit_test(test_replace_whitespaces), ++ cmocka_unit_test(test_reverse_replace_whitespaces), ++ cmocka_unit_test_setup_teardown(test_add_strings_lists, ++ setup_add_strings_lists, ++ teardown_add_strings_lists), ++ cmocka_unit_test(test_sss_write_krb5_conf_snippet), ++ cmocka_unit_test_setup_teardown(test_fix_domain_in_name_list, ++ confdb_test_setup, ++ confdb_test_teardown), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -1147,7 +1159,7 @@ int main(int argc, const char *argv[]) + test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_SYSDB_FILE); + test_dom_suite_setup(TESTS_PATH); + +- rv = run_tests(tests); ++ rv = cmocka_run_group_tests(tests, NULL, NULL); + if (rv == 0) { + test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_SYSDB_FILE); + } +diff --git a/src/tests/cwrap/test_become_user.c b/src/tests/cwrap/test_become_user.c +index 7ecea5aac34bb73ca81d94ad481f05b338e65ed0..b9e8a5c3bf216570292b2fbae25832268c6bf17b 100644 +--- a/src/tests/cwrap/test_become_user.c ++++ b/src/tests/cwrap/test_become_user.c +@@ -133,9 +133,9 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test(test_become_user), +- unit_test(test_switch_user), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(test_become_user), ++ cmocka_unit_test(test_switch_user), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -159,5 +159,5 @@ int main(int argc, const char *argv[]) + * they might not after a failed run. Remove the old db to be sure */ + tests_set_cwd(); + +- return run_tests(tests); ++ return cmocka_run_group_tests(tests, NULL, NULL); + } +diff --git a/src/tests/cwrap/test_responder_common.c b/src/tests/cwrap/test_responder_common.c +index 7e3f2e025a0dce15cc93e560a42bb566eff9fb30..2c92ff080e28151bc68e52fa02420c331d2ed4cf 100644 +--- a/src/tests/cwrap/test_responder_common.c ++++ b/src/tests/cwrap/test_responder_common.c +@@ -111,7 +111,7 @@ struct create_pipe_ctx { + const char *sock_name; + }; + +-void test_create_pipe_fd_setup(void **state) ++static int test_create_pipe_fd_setup(void **state) + { + struct create_pipe_ctx *ctx; + +@@ -120,6 +120,7 @@ void test_create_pipe_fd_setup(void **state) + ctx->fd = -1; + + *state = ctx; ++ return 0; + } + + void check_sock_properties(struct create_pipe_ctx *ctx, mode_t mode) +@@ -181,7 +182,7 @@ void test_create_pipe_fd(void **state) + check_sock_properties(ctx, 0777); + } + +-void test_create_pipe_fd_teardown(void **state) ++static int test_create_pipe_fd_teardown(void **state) + { + struct create_pipe_ctx *ctx; + +@@ -191,6 +192,7 @@ void test_create_pipe_fd_teardown(void **state) + unlink(ctx->sock_name); + close(ctx->fd); + } ++ return 0; + } + + int main(int argc, const char *argv[]) +@@ -203,13 +205,13 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test(test_uid_csv_to_uid_list), +- unit_test(test_name_csv_to_uid_list), +- unit_test(test_csv_to_uid_list_neg), +- unit_test_setup_teardown(test_create_pipe_fd, +- test_create_pipe_fd_setup, +- test_create_pipe_fd_teardown) ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(test_uid_csv_to_uid_list), ++ cmocka_unit_test(test_name_csv_to_uid_list), ++ cmocka_unit_test(test_csv_to_uid_list_neg), ++ cmocka_unit_test_setup_teardown(test_create_pipe_fd, ++ test_create_pipe_fd_setup, ++ test_create_pipe_fd_teardown) + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -231,5 +233,5 @@ int main(int argc, const char *argv[]) + + tests_set_cwd(); + +- return run_tests(tests); ++ return cmocka_run_group_tests(tests, NULL, NULL); + } +diff --git a/src/tests/cwrap/test_server.c b/src/tests/cwrap/test_server.c +index d0aeac47d0b067fdbc3399037c0a74f150337a23..f6884f14d75b5884e1a2c80b05fbb660757dced0 100644 +--- a/src/tests/cwrap/test_server.c ++++ b/src/tests/cwrap/test_server.c +@@ -169,10 +169,10 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test(test_run_as_root_fg), +- unit_test(test_run_as_sssd_fg), +- unit_test(test_run_as_root_daemon), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(test_run_as_root_fg), ++ cmocka_unit_test(test_run_as_sssd_fg), ++ cmocka_unit_test(test_run_as_root_daemon), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -198,7 +198,7 @@ int main(int argc, const char *argv[]) + test_dom_suite_cleanup(TEST_DB_PATH, CONFDB_FILE, NULL); + test_dom_suite_setup(TEST_DB_PATH); + +- rv = run_tests(tests); ++ rv = cmocka_run_group_tests(tests, NULL, NULL); + if (rv != 0) { + test_dom_suite_cleanup(TEST_DB_PATH, CONFDB_FILE, NULL); + } +diff --git a/src/tests/cwrap/test_usertools.c b/src/tests/cwrap/test_usertools.c +index 6423059456a06f0c8f8ebdd803641b7207e862fd..91eb2bc968dd741f8b1541edd2d9303626b1175f 100644 +--- a/src/tests/cwrap/test_usertools.c ++++ b/src/tests/cwrap/test_usertools.c +@@ -77,10 +77,10 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test(test_get_user_num), +- unit_test(test_get_user_str), +- unit_test(test_get_user_nullparm), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(test_get_user_num), ++ cmocka_unit_test(test_get_user_str), ++ cmocka_unit_test(test_get_user_nullparm), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -102,5 +102,5 @@ int main(int argc, const char *argv[]) + + tests_set_cwd(); + +- return run_tests(tests); ++ return cmocka_run_group_tests(tests, NULL, NULL); + } +-- +2.4.0 + diff --git a/0041-RPM-BuildRequire-libcmocka-1.0.patch b/0041-RPM-BuildRequire-libcmocka-1.0.patch new file mode 100644 index 0000000..2be8178 --- /dev/null +++ b/0041-RPM-BuildRequire-libcmocka-1.0.patch @@ -0,0 +1,30 @@ +From 2bbf29b268bd2e7f9399ad6d7f5be6ca73ef7223 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Tue, 10 Mar 2015 11:02:30 +0100 +Subject: [PATCH 41/99] RPM: BuildRequire libcmocka >= 1.0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Lukáš Slebodník +(cherry picked from commit 0aad066baeed6833cf061b71d72c6bbbb2d2b9e8) +--- + contrib/sssd.spec.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in +index bea68f1bbceac232f4ca019111b6262dca3380eb..d5f69149047bf691cc2f9663252a41c1f28f216b 100644 +--- a/contrib/sssd.spec.in ++++ b/contrib/sssd.spec.in +@@ -112,7 +112,7 @@ BuildRequires: findutils + BuildRequires: glib2-devel + BuildRequires: selinux-policy-targeted + %if 0%{?fedora} +-BuildRequires: libcmocka-devel ++BuildRequires: libcmocka-devel >= 1.0.0 + %endif + %if (0%{?fedora} >= 20) + BuildRequires: uid_wrapper +-- +2.4.0 + diff --git a/0042-build-Only-run-cmocka-tests-if-cmocka-1.0-or-newer-i.patch b/0042-build-Only-run-cmocka-tests-if-cmocka-1.0-or-newer-i.patch new file mode 100644 index 0000000..cf40178 --- /dev/null +++ b/0042-build-Only-run-cmocka-tests-if-cmocka-1.0-or-newer-i.patch @@ -0,0 +1,40 @@ +From 1acadc807209b24f681a4866812e11d04b5a129f Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Tue, 10 Mar 2015 18:10:37 +0100 +Subject: [PATCH 42/99] build: Only run cmocka tests if cmocka 1.0 or newer is + available +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Lukáš Slebodník +(cherry picked from commit cecee447d41c3ca22e94880a7d0cbd910f230fe5) +--- + src/external/libcmocka.m4 | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/external/libcmocka.m4 b/src/external/libcmocka.m4 +index 740d9ad254b50563d4d1cbcab3d10f5920ffd79f..230aa92697d8ea4ca12fce21dbaa417bbe3c9b96 100644 +--- a/src/external/libcmocka.m4 ++++ b/src/external/libcmocka.m4 +@@ -1,7 +1,7 @@ + dnl A macro to check presence of cmocka on the system + AC_DEFUN([AM_CHECK_CMOCKA], + [ +- PKG_CHECK_EXISTS(cmocka, ++ PKG_CHECK_EXISTS(cmocka >= 1.0.0, + [AC_CHECK_HEADERS([stdarg.h stddef.h setjmp.h], + [], dnl We are only intrested in action-if-not-found + [AC_MSG_WARN([Header files stdarg.h stddef.h setjmp.h are required by cmocka]) +@@ -12,7 +12,7 @@ AC_DEFUN([AM_CHECK_CMOCKA], + [PKG_CHECK_MODULES([CMOCKA], [cmocka], [have_cmocka="yes"])] + )], + dnl PKG_CHECK_EXISTS ACTION-IF-NOT-FOUND +- [AC_MSG_WARN([No libcmocka library found, cmocka tests will not be built])] ++ [AC_MSG_WARN([No libcmocka-1.0.0 or newer library found, cmocka tests will not be built])] + ) + AM_CONDITIONAL([HAVE_CMOCKA], [test x$have_cmocka = xyes]) + ]) +-- +2.4.0 + diff --git a/0043-sdap-properly-handle-binary-objectGuid-attribute.patch b/0043-sdap-properly-handle-binary-objectGuid-attribute.patch new file mode 100644 index 0000000..fc66049 --- /dev/null +++ b/0043-sdap-properly-handle-binary-objectGuid-attribute.patch @@ -0,0 +1,549 @@ +From 4619742836ec22edf8f9d274d928bc896c5b0883 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Tue, 17 Feb 2015 04:41:21 +0100 +Subject: [PATCH 43/99] sdap: properly handle binary objectGuid attribute + +Although in the initial processing SSSD treats the binary value right at +some point it mainly assumes that it is a string. Depending on the value +this might end up with the correct binary value stored in the cache but +in most cases there will be only a broken entry in the cache. + +This patch converts the binary value into a string representation which +is described in [MS-DTYP] and stores the result in the cache. + +Resolves https://fedorahosted.org/sssd/ticket/2588 + +Reviewed-by: Jakub Hrozek +--- + Makefile.am | 16 ++++ + src/db/sysdb.h | 6 ++ + src/db/sysdb_ops.c | 52 +++++++++++ + src/providers/ldap/sdap_async_groups.c | 25 ++---- + src/providers/ldap/sdap_async_initgroups.c | 7 +- + src/providers/ldap/sdap_async_users.c | 23 ++--- + src/tests/cmocka/test_string_utils.c | 59 +++++++++++++ + src/tests/cmocka/test_sysdb_utils.c | 134 +++++++++++++++++++++++++++++ + src/tests/cmocka/test_utils.c | 1 + + src/tests/cmocka/test_utils.h | 1 + + src/tests/cwrap/Makefile.am | 2 + + src/util/string_utils.c | 25 ++++++ + src/util/util.h | 7 ++ + 13 files changed, 324 insertions(+), 34 deletions(-) + create mode 100644 src/tests/cmocka/test_sysdb_utils.c + +diff --git a/Makefile.am b/Makefile.am +index 5099043549a46c15a9d7f6a581c864cbbe3137b5..df34840747bdcc3e2cc68ac1a3ca448b4aa67433 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -214,6 +214,7 @@ if HAVE_CMOCKA + test_search_bases \ + sdap-tests \ + test_sysdb_views \ ++ test_sysdb_utils \ + test_be_ptask \ + test_copy_ccache \ + test_copy_keytab \ +@@ -2113,6 +2114,21 @@ test_sysdb_views_LDADD = \ + libsss_test_common.la \ + $(NULL) + ++test_sysdb_utils_SOURCES = \ ++ src/tests/cmocka/test_sysdb_utils.c \ ++ $(NULL) ++test_sysdb_utils_CFLAGS = \ ++ $(AM_CFLAGS) \ ++ $(NULL) ++test_sysdb_utils_LDADD = \ ++ $(CMOCKA_LIBS) \ ++ $(LDB_LIBS) \ ++ $(POPT_LIBS) \ ++ $(TALLOC_LIBS) \ ++ $(SSSD_INTERNAL_LTLIBS) \ ++ libsss_test_common.la \ ++ $(NULL) ++ + test_be_ptask_SOURCES = \ + src/tests/cmocka/test_be_ptask.c \ + src/providers/dp_ptask.c \ +diff --git a/src/db/sysdb.h b/src/db/sysdb.h +index 1362f377837d25815b04b4929a2895ee3a6485a9..a1b6f207399555c85c14c8decf89edc498deb871 100644 +--- a/src/db/sysdb.h ++++ b/src/db/sysdb.h +@@ -1117,4 +1117,10 @@ errno_t sysdb_get_sids_of_members(TALLOC_CTX *mem_ctx, + const char ***_sids, + const char ***_dns, + size_t *_n); ++ ++errno_t sysdb_handle_original_uuid(const char *orig_name, ++ struct sysdb_attrs *src_attrs, ++ const char *src_name, ++ struct sysdb_attrs *dest_attrs, ++ const char *dest_name); + #endif /* __SYS_DB_H__ */ +diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c +index 06d24f220afc28b39f3856f3f0170818e11d9cf9..37529fd12c2c5c6896a2ca71293a61f93ba0eee3 100644 +--- a/src/db/sysdb_ops.c ++++ b/src/db/sysdb_ops.c +@@ -3696,3 +3696,55 @@ done: + talloc_free(tmp_ctx); + return ret; + } ++ ++errno_t sysdb_handle_original_uuid(const char *orig_name, ++ struct sysdb_attrs *src_attrs, ++ const char *src_name, ++ struct sysdb_attrs *dest_attrs, ++ const char *dest_name) ++{ ++ int ret; ++ struct ldb_message_element *el; ++ char guid_str_buf[GUID_STR_BUF_SIZE]; ++ ++ if (orig_name == NULL || src_attrs == NULL || src_name == NULL ++ || dest_attrs == NULL || dest_name == NULL) { ++ return EINVAL; ++ } ++ ++ ret = sysdb_attrs_get_el_ext(src_attrs, src_name, false, &el); ++ if (ret != EOK) { ++ if (ret != ENOENT) { ++ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_el failed.\n"); ++ } ++ return ret; ++ } ++ ++ if (el->num_values != 1) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "Found more than one UUID value, using the first.\n"); ++ } ++ ++ /* Check if we got a binary AD objectGUID */ ++ if (el->values[0].length == GUID_BIN_LENGTH ++ && strcasecmp(orig_name, "objectGUID") == 0) { ++ ret = guid_blob_to_string_buf(el->values[0].data, guid_str_buf, ++ GUID_STR_BUF_SIZE); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "guid_blob_to_string_buf failed.\n"); ++ return ret; ++ } ++ ++ ret = sysdb_attrs_add_string(dest_attrs, dest_name, guid_str_buf); ++ } else { ++ ret = sysdb_attrs_add_string(dest_attrs, dest_name, ++ (const char *)el->values[0].data); ++ } ++ ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n"); ++ return ret;; ++ } ++ ++ return EOK; ++} +diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c +index 7779d499de87e2f0657512cb1f8e1980f9bf1f71..f9613ddd72d1e1796bc6a034daf98275b07a5c79 100644 +--- a/src/providers/ldap/sdap_async_groups.c ++++ b/src/providers/ldap/sdap_async_groups.c +@@ -511,7 +511,6 @@ static int sdap_save_group(TALLOC_CTX *memctx, + bool posix_group; + bool use_id_mapping; + char *sid_str; +- const char *uuid; + struct sss_domain_info *subdomain; + int32_t ad_group_type; + +@@ -549,22 +548,14 @@ static int sdap_save_group(TALLOC_CTX *memctx, + } + + /* Always store UUID if available */ +- ret = sysdb_attrs_get_string(attrs, +- opts->group_map[SDAP_AT_GROUP_UUID].sys_name, +- &uuid); +- if (ret == EOK) { +- ret = sysdb_attrs_add_string(group_attrs, SYSDB_UUID, uuid); +- if (ret != EOK) { +- DEBUG(SSSDBG_MINOR_FAILURE, "Could not add UUID string: [%s]\n", +- sss_strerror(ret)); +- goto done; +- } +- } else if (ret == ENOENT) { +- DEBUG(SSSDBG_TRACE_ALL, "UUID not available for group [%s].\n", +- group_name); +- } else { +- DEBUG(SSSDBG_MINOR_FAILURE, "Could not identify UUID [%s]\n", +- sss_strerror(ret)); ++ ret = sysdb_handle_original_uuid( ++ opts->group_map[SDAP_AT_GROUP_UUID].def_name, ++ attrs, ++ opts->group_map[SDAP_AT_GROUP_UUID].sys_name, ++ group_attrs, SYSDB_UUID); ++ if (ret != EOK) { ++ DEBUG((ret == ENOENT) ? SSSDBG_TRACE_ALL : SSSDBG_MINOR_FAILURE, ++ "Failed to retrieve UUID [%d][%s].\n", ret, sss_strerror(ret)); + } + + /* If this object has a SID available, we will determine the correct +diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c +index 2fd235f2868b877c0e5d5d9f7b1b76d269eee8ee..96617aecc4e9c948bbbdccb1ba75e81577a19c70 100644 +--- a/src/providers/ldap/sdap_async_initgroups.c ++++ b/src/providers/ldap/sdap_async_initgroups.c +@@ -196,8 +196,13 @@ errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb, + original_dn = NULL; + } + ++ ret = sysdb_handle_original_uuid( ++ opts->group_map[SDAP_AT_GROUP_UUID].def_name, ++ ldap_groups[ai], ++ opts->group_map[SDAP_AT_GROUP_UUID].sys_name, ++ ldap_groups[ai], "uniqueIDstr"); + ret = sysdb_attrs_get_string(ldap_groups[ai], +- SYSDB_UUID, ++ "uniqueIDstr", + &uuid); + if (ret) { + DEBUG(SSSDBG_FUNC_DATA, +diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c +index 367e3d795ddd0db5c1c2f8e57d700419f371cd15..82b4df4793f5f0679046f259c251f5897af831cf 100644 +--- a/src/providers/ldap/sdap_async_users.c ++++ b/src/providers/ldap/sdap_async_users.c +@@ -140,7 +140,6 @@ int sdap_save_user(TALLOC_CTX *memctx, + TALLOC_CTX *tmpctx = NULL; + bool use_id_mapping; + char *sid_str; +- const char *uuid; + char *dom_sid_str = NULL; + struct sss_domain_info *subdomain; + +@@ -179,21 +178,13 @@ int sdap_save_user(TALLOC_CTX *memctx, + } + + /* Always store UUID if available */ +- ret = sysdb_attrs_get_string(attrs, +- opts->user_map[SDAP_AT_USER_UUID].sys_name, +- &uuid); +- if (ret == EOK) { +- ret = sysdb_attrs_add_string(user_attrs, SYSDB_UUID, uuid); +- if (ret != EOK) { +- DEBUG(SSSDBG_MINOR_FAILURE, "Could not add UUID string: [%s]\n", +- sss_strerror(ret)); +- goto done; +- } +- } else if (ret == ENOENT) { +- DEBUG(SSSDBG_TRACE_ALL, "UUID not available for user.\n"); +- } else { +- DEBUG(SSSDBG_MINOR_FAILURE, "Could not identify UUID [%s]\n", +- sss_strerror(ret)); ++ ret = sysdb_handle_original_uuid(opts->user_map[SDAP_AT_USER_UUID].def_name, ++ attrs, ++ opts->user_map[SDAP_AT_USER_UUID].sys_name, ++ user_attrs, SYSDB_UUID); ++ if (ret != EOK) { ++ DEBUG((ret == ENOENT) ? SSSDBG_TRACE_ALL : SSSDBG_MINOR_FAILURE, ++ "Failed to retrieve UUID [%d][%s].\n", ret, sss_strerror(ret)); + } + + /* If this object has a SID available, we will determine the correct +diff --git a/src/tests/cmocka/test_string_utils.c b/src/tests/cmocka/test_string_utils.c +index e446387d6c429515360b23b428555befa915b49a..5d3fcf4fe454a0be3a4c72b778003481f66910bb 100644 +--- a/src/tests/cmocka/test_string_utils.c ++++ b/src/tests/cmocka/test_string_utils.c +@@ -133,3 +133,62 @@ void test_reverse_replace_whitespaces(void **state) + assert_true(check_leaks_pop(mem_ctx) == true); + talloc_free(mem_ctx); + } ++ ++void test_guid_blob_to_string_buf(void **state) ++{ ++ int ret; ++ char str_buf[GUID_STR_BUF_SIZE]; ++ size_t c; ++ ++ /* How to get test data: ++ * The objectGUID attribute contains a 16byte long binary value ++ * representing the GUID of the object. This data can be converted ++ * manually to the string representation but it might be easier to use ++ * LDAP_SERVER_EXTENDED_DN_OID as described in [MS-ADST] section ++ * 3.1.1.3.4.1.5. This is an LDAP extended control which adds the GUID and ++ * the SID to the DN of an object. This can be activate with the -E ++ * ldapsearch option like: ++ * ++ * ldapsearch -E 1.2.840.113556.1.4.529=::MAMCAQE= .... ++ * ++ * where 'MAMCAQE=' is the base64 encoded BER sequence with the integer ++ * value 1 (see [MS-ADTS] for details about possible values). ++ * ++ * Btw, if you want to use the string representation of a GUID to search ++ * for an object in AD you have to use the GUID as the search base in the ++ * following form: ++ * ++ * ldapsearch b '' ... ++ * ++ * (please note that the '<' and '>' are really needed). ++ */ ++ struct test_data { ++ uint8_t blob[16]; ++ const char *guid_str; ++ } test_data[] = { ++ {{0x8d, 0x0d, 0xa8, 0xfe, 0xd5, 0xdb, 0x84, 0x4f, ++ 0x85, 0x74, 0x7d, 0xb0, 0x47, 0x7f, 0x96, 0x2e}, ++ "fea80d8d-dbd5-4f84-8574-7db0477f962e"}, ++ {{0x91, 0x7e, 0x2e, 0xf8, 0x4e, 0x44, 0xfa, 0x4e, ++ 0xb1, 0x13, 0x08, 0x98, 0x63, 0x49, 0x6c, 0xc6}, ++ "f82e7e91-444e-4efa-b113-089863496cc6"}, ++ {{0}, NULL} ++ }; ++ ++ ret = guid_blob_to_string_buf(NULL, str_buf, GUID_STR_BUF_SIZE); ++ assert_int_equal(ret, EINVAL); ++ ++ ret = guid_blob_to_string_buf((const uint8_t *) "1234567812345678", NULL, ++ GUID_STR_BUF_SIZE); ++ assert_int_equal(ret, EINVAL); ++ ++ ret = guid_blob_to_string_buf((const uint8_t *) "1234567812345678", str_buf, 0); ++ assert_int_equal(ret, EINVAL); ++ ++ for (c = 0; test_data[c].guid_str != NULL; c++) { ++ ret = guid_blob_to_string_buf(test_data[c].blob, str_buf, ++ sizeof(str_buf)); ++ assert_int_equal(ret, EOK); ++ assert_string_equal(test_data[c].guid_str, str_buf); ++ } ++} +diff --git a/src/tests/cmocka/test_sysdb_utils.c b/src/tests/cmocka/test_sysdb_utils.c +new file mode 100644 +index 0000000000000000000000000000000000000000..d217314ccb9234f8d0d329d87c5dc9e847acbcf0 +--- /dev/null ++++ b/src/tests/cmocka/test_sysdb_utils.c +@@ -0,0 +1,134 @@ ++/* ++ SSSD ++ ++ sysdb_utils - Tests for various sysdb calls ++ ++ Authors: ++ Sumit Bose ++ ++ Copyright (C) 2015 Red Hat ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "tests/cmocka/common_mock.h" ++ ++#define IPA_UUID "bcae7c40-97eb-11e4-88ca-525400e96a6b" ++ ++#define AD_GUID_BIN {0x8d, 0x0d, 0xa8, 0xfe, 0xd5, 0xdb, 0x84, 0x4f, \ ++ 0x85, 0x74, 0x7d, 0xb0, 0x47, 0x7f, 0x96, 0x2e}; ++#define AD_GUID "fea80d8d-dbd5-4f84-8574-7db0477f962e" ++static void test_sysdb_handle_original_uuid(void **state) ++{ ++ int ret; ++ struct sysdb_attrs *src_attrs; ++ struct sysdb_attrs *dest_attrs; ++ const char *guid; ++ uint8_t bin_guid[] = AD_GUID_BIN; ++ struct ldb_val guid_val = {bin_guid, 16}; ++ ++ ret = sysdb_handle_original_uuid(NULL, NULL, NULL, NULL, NULL); ++ assert_int_equal(ret, EINVAL); ++ ++ src_attrs = sysdb_new_attrs(NULL); ++ assert_non_null(src_attrs); ++ ++ dest_attrs = sysdb_new_attrs(NULL); ++ assert_non_null(dest_attrs); ++ ++ ret = sysdb_handle_original_uuid("xyz", src_attrs, "abc", dest_attrs, ++ "def"); ++ assert_int_equal(ret, ENOENT); ++ ++ ret = sysdb_attrs_add_val(src_attrs, "GUID", &guid_val); ++ assert_int_equal(ret, EOK); ++ ++ ret = sysdb_attrs_add_string(src_attrs, "UUID", IPA_UUID); ++ assert_int_equal(ret, EOK); ++ ++ ret = sysdb_handle_original_uuid("objectGUID", src_attrs, "GUID", ++ dest_attrs, "def"); ++ assert_int_equal(ret, EOK); ++ ret = sysdb_attrs_get_string(dest_attrs, "def", &guid); ++ assert_int_equal(ret, EOK); ++ assert_string_equal(guid, AD_GUID); ++ ++ ret = sysdb_handle_original_uuid("ipaUniqueID", src_attrs, "UUID", ++ dest_attrs, "ghi"); ++ assert_int_equal(ret, EOK); ++ ret = sysdb_attrs_get_string(dest_attrs, "ghi", &guid); ++ assert_int_equal(ret, EOK); ++ assert_string_equal(guid, IPA_UUID); ++ ++ talloc_free(src_attrs); ++ src_attrs = sysdb_new_attrs(NULL); ++ assert_non_null(src_attrs); ++ ++ /* check objectGUID with length other than 16 */ ++ ret = sysdb_attrs_add_string(src_attrs, "GUID", IPA_UUID); ++ assert_int_equal(ret, EOK); ++ ret = sysdb_handle_original_uuid("objectGUID", src_attrs, "GUID", ++ dest_attrs, "jkl"); ++ assert_int_equal(ret, EOK); ++ ret = sysdb_attrs_get_string(dest_attrs, "jkl", &guid); ++ assert_int_equal(ret, EOK); ++ assert_string_equal(guid, IPA_UUID); ++ ++ talloc_free(src_attrs); ++ talloc_free(dest_attrs); ++} ++ ++int main(int argc, const char *argv[]) ++{ ++ int rv; ++ poptContext pc; ++ int opt; ++ struct poptOption long_options[] = { ++ POPT_AUTOHELP ++ SSSD_DEBUG_OPTS ++ POPT_TABLEEND ++ }; ++ ++ const UnitTest tests[] = { ++ unit_test(test_sysdb_handle_original_uuid), ++ }; ++ ++ /* Set debug level to invalid value so we can deside if -d 0 was used. */ ++ debug_level = SSSDBG_INVALID; ++ ++ pc = poptGetContext(argv[0], argc, argv, long_options, 0); ++ while((opt = poptGetNextOpt(pc)) != -1) { ++ switch(opt) { ++ default: ++ fprintf(stderr, "\nInvalid option %s: %s\n\n", ++ poptBadOption(pc, 0), poptStrerror(opt)); ++ poptPrintUsage(pc, stderr, 0); ++ return 1; ++ } ++ } ++ poptFreeContext(pc); ++ ++ DEBUG_CLI_INIT(debug_level); ++ ++ tests_set_cwd(); ++ rv = run_tests(tests); ++ ++ return rv; ++} +diff --git a/src/tests/cmocka/test_utils.c b/src/tests/cmocka/test_utils.c +index 2203e2c49efacab27e9cf4c6c699319cfdf5370c..4cc6ec85add6bb8f9ae17ddc9af38b0316c9d49f 100644 +--- a/src/tests/cmocka/test_utils.c ++++ b/src/tests/cmocka/test_utils.c +@@ -1127,6 +1127,7 @@ int main(int argc, const char *argv[]) + cmocka_unit_test(test_textual_public_key), + cmocka_unit_test(test_replace_whitespaces), + cmocka_unit_test(test_reverse_replace_whitespaces), ++ cmocka_unit_test(test_guid_blob_to_string_buf), + cmocka_unit_test_setup_teardown(test_add_strings_lists, + setup_add_strings_lists, + teardown_add_strings_lists), +diff --git a/src/tests/cmocka/test_utils.h b/src/tests/cmocka/test_utils.h +index f85ac2f2b3c50a60099970752b06adbad38b9fd1..61ef7e43a82649d775d9b932def9e957b0761bed 100644 +--- a/src/tests/cmocka/test_utils.h ++++ b/src/tests/cmocka/test_utils.h +@@ -29,5 +29,6 @@ void test_textual_public_key(void **state); + /* from src/tests/cmocka/test_string_utils.c */ + void test_replace_whitespaces(void **state); + void test_reverse_replace_whitespaces(void **state); ++void test_guid_blob_to_string_buf(void **state); + + #endif /* __TESTS__CMOCKA__TEST_UTILS_H__ */ +diff --git a/src/tests/cwrap/Makefile.am b/src/tests/cwrap/Makefile.am +index c1991a19c3a39f957b6547854126ff6d219394e0..b805e834977f60d6ba2efdf0f700061bb5e0e264 100644 +--- a/src/tests/cwrap/Makefile.am ++++ b/src/tests/cwrap/Makefile.am +@@ -78,6 +78,7 @@ server_tests_SOURCES = \ + ../../../src/util/atomic_io.c \ + ../../../src/util/signal.c \ + ../../../src/util/util.c \ ++ ../../../src/util/string_utils.c \ + ../../../src/util/strtonum.c \ + ../../../src/util/util_errors.c \ + ../../../src/util/safe-format-string.c \ +@@ -115,6 +116,7 @@ usertools_tests_SOURCES = \ + ../../../src/util/domain_info_utils.c \ + ../../../src/util/safe-format-string.c \ + ../../../src/util/usertools.c \ ++ ../../../src/util/string_utils.c \ + ../../../src/util/strtonum.c \ + ../../../src/util/backup_file.c \ + ../../../src/util/atomic_io.c \ +diff --git a/src/util/string_utils.c b/src/util/string_utils.c +index a39b950e852de7ed43d6e8a32de3e7fb08a0dc56..71b2a092018076fd9c20ef9ac39a11964876cfc3 100644 +--- a/src/util/string_utils.c ++++ b/src/util/string_utils.c +@@ -83,3 +83,28 @@ char * sss_reverse_replace_space(TALLOC_CTX *mem_ctx, + + return replace_char(mem_ctx, orig_name, subst, ' '); + } ++ ++errno_t guid_blob_to_string_buf(const uint8_t *blob, char *str_buf, ++ size_t buf_size) ++{ ++ int ret; ++ ++ if (blob == NULL || str_buf == NULL || buf_size < GUID_STR_BUF_SIZE) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Buffer too small.\n"); ++ return EINVAL; ++ } ++ ++ ret = snprintf(str_buf, buf_size, ++ "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", ++ blob[3], blob[2], blob[1], blob[0], ++ blob[5], blob[4], ++ blob[7], blob[6], ++ blob[8], blob[9], ++ blob[10], blob[11],blob[12], blob[13],blob[14], blob[15]);; ++ if (ret != (GUID_STR_BUF_SIZE -1)) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "snprintf failed.\n"); ++ return EIO; ++ } ++ ++ return EOK; ++} +diff --git a/src/util/util.h b/src/util/util.h +index 22a67a55855282441379477236a323362c8bdb4d..91df09914abfa1a72e9280ab708e11abf9e07e18 100644 +--- a/src/util/util.h ++++ b/src/util/util.h +@@ -618,6 +618,13 @@ char * sss_reverse_replace_space(TALLOC_CTX *mem_ctx, + const char *orig_name, + const char replace_char); + ++#define GUID_BIN_LENGTH 16 ++/* 16 2-digit hex values + 4 dashes + terminating 0 */ ++#define GUID_STR_BUF_SIZE (2 * GUID_BIN_LENGTH + 4 + 1) ++ ++errno_t guid_blob_to_string_buf(const uint8_t *blob, char *str_buf, ++ size_t buf_size); ++ + /* from become_user.c */ + errno_t become_user(uid_t uid, gid_t gid); + struct sss_creds; +-- +2.4.0 + diff --git a/0044-Resolv-re-read-SRV-query-every-time-if-its-TTL-is-0.patch b/0044-Resolv-re-read-SRV-query-every-time-if-its-TTL-is-0.patch new file mode 100644 index 0000000..3ace60b --- /dev/null +++ b/0044-Resolv-re-read-SRV-query-every-time-if-its-TTL-is-0.patch @@ -0,0 +1,118 @@ +From 9dd8510d5d95d8ff7170f29ef4d9c603b3573cfe Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Mon, 23 Mar 2015 21:09:53 +0100 +Subject: [PATCH 44/99] Resolv: re-read SRV query every time if its TTL is 0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We should make sure the client re-checks the SRV query each request if +the SRV query is 0. + +Reviewed-by: Pavel Březina +(cherry picked from commit 9797aa5907191cef5db8279e20ec75fd0abbe980) +--- + src/providers/fail_over.c | 2 +- + src/tests/cmocka/test_fo_srv.c | 31 ++++++++++++++++++++++++++----- + 2 files changed, 27 insertions(+), 6 deletions(-) + +diff --git a/src/providers/fail_over.c b/src/providers/fail_over.c +index 8142081526d7902946e756ec05774c471126545e..6d835ae0efdfdf96532e8458e12238ba17910a4f 100644 +--- a/src/providers/fail_over.c ++++ b/src/providers/fail_over.c +@@ -275,7 +275,7 @@ get_srv_data_status(struct srv_data *data) + timeout = data->ttl; + } + +- if (timeout && STATUS_DIFF(data, tv) > timeout) { ++ if (STATUS_DIFF(data, tv) > timeout) { + switch(data->srv_lookup_status) { + case SRV_EXPIRED: + case SRV_NEUTRAL: +diff --git a/src/tests/cmocka/test_fo_srv.c b/src/tests/cmocka/test_fo_srv.c +index 7a6321006d8383ed901fe9d5df3fddc514c53550..e5c5e4fe3b818ca2df0ab7bcd1a83719fefba191 100644 +--- a/src/tests/cmocka/test_fo_srv.c ++++ b/src/tests/cmocka/test_fo_srv.c +@@ -200,6 +200,7 @@ struct test_fo_srv_ctx { + struct fo_resolve_srv_dns_ctx *srv_ctx; + struct fo_service *fo_svc; + struct sss_test_ctx *ctx; ++ int ttl; + }; + + int test_fo_srv_data_cmp(void *ud1, void *ud2) +@@ -431,15 +432,23 @@ static void test_fo_srv_done4(struct tevent_req *req) + /* Make sure that two queries more than TTL seconds apart resolve + * into two different lists + */ ++static void test_fo_srv_ttl_change_step(struct test_fo_srv_ctx *test_ctx); + static void test_fo_srv_before(struct tevent_req *req); + static void test_fo_srv_after(struct tevent_req *req); + + void test_fo_srv_ttl_change(void **state) + { +- errno_t ret; +- struct tevent_req *req; + struct test_fo_srv_ctx *test_ctx = + talloc_get_type(*state, struct test_fo_srv_ctx); ++ ++ test_ctx->ttl = TEST_SRV_SHORT_TTL; ++ test_fo_srv_ttl_change_step(test_ctx); ++} ++ ++static void test_fo_srv_ttl_change_step(struct test_fo_srv_ctx *test_ctx) ++{ ++ errno_t ret; ++ struct tevent_req *req; + struct ares_srv_reply *s1; + struct ares_srv_reply *s2; + char *dns_domain; +@@ -465,7 +474,7 @@ void test_fo_srv_ttl_change(void **state) + dns_domain = talloc_strdup(test_ctx, "sssd.com"); + assert_non_null(dns_domain); + +- mock_srv_results(s1, TEST_SRV_SHORT_TTL, dns_domain); ++ mock_srv_results(s1, test_ctx->ttl, dns_domain); + + ret = fo_add_srv_server(test_ctx->fo_svc, "_ldap", "sssd.com", + "sssd.local", "tcp", test_ctx); +@@ -527,8 +536,8 @@ static void test_fo_srv_before(struct tevent_req *req) + dns_domain = talloc_strdup(test_ctx, "sssd.com"); + assert_non_null(dns_domain); + +- mock_srv_results(s1, TEST_SRV_SHORT_TTL, dns_domain); +- sleep(TEST_SRV_SHORT_TTL + 1); ++ mock_srv_results(s1, test_ctx->ttl, dns_domain); ++ sleep(test_ctx->ttl + 1); + + req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev, + test_ctx->resolv, test_ctx->fo_ctx, +@@ -555,6 +564,15 @@ static void test_fo_srv_after(struct tevent_req *req) + test_ctx->ctx->done = true; + } + ++void test_fo_srv_ttl_zero(void **state) ++{ ++ struct test_fo_srv_ctx *test_ctx = ++ talloc_get_type(*state, struct test_fo_srv_ctx); ++ ++ test_ctx->ttl = 0; ++ test_fo_srv_ttl_change_step(test_ctx); ++} ++ + int main(int argc, const char *argv[]) + { + int rv; +@@ -573,6 +591,9 @@ int main(int argc, const char *argv[]) + cmocka_unit_test_setup_teardown(test_fo_srv_ttl_change, + test_fo_srv_setup, + test_fo_srv_teardown), ++ cmocka_unit_test_setup_teardown(test_fo_srv_ttl_zero, ++ test_fo_srv_setup, ++ test_fo_srv_teardown), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +-- +2.4.0 + diff --git a/0045-IPA-Use-custom-error-codes-when-validating-HBAC-rule.patch b/0045-IPA-Use-custom-error-codes-when-validating-HBAC-rule.patch new file mode 100644 index 0000000..161c5a4 --- /dev/null +++ b/0045-IPA-Use-custom-error-codes-when-validating-HBAC-rule.patch @@ -0,0 +1,315 @@ +From 319f9710185929186778814b48f2227359d4f8f4 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Mon, 16 Mar 2015 10:35:59 +0100 +Subject: [PATCH 45/99] IPA: Use custom error codes when validating HBAC rules +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +https://fedorahosted.org/sssd/ticket/2603 + +Instead of reusing EINVAL/ENOENT, use more descriptive error codes. This +will be useful in the next patch where we act on certain codes. + +Reviewed-by: Pavel Březina +(cherry picked from commit 1243e093fd31c5660adf1bb3dd477d6935a755be) +--- + src/providers/ipa/ipa_hbac_common.c | 10 +++++----- + src/providers/ipa/ipa_hbac_hosts.c | 16 ++++++++-------- + src/providers/ipa/ipa_hbac_services.c | 16 ++++++++-------- + src/providers/ipa/ipa_hbac_users.c | 16 ++++++++-------- + src/util/util_errors.c | 2 ++ + src/util/util_errors.h | 2 ++ + 6 files changed, 33 insertions(+), 29 deletions(-) + +diff --git a/src/providers/ipa/ipa_hbac_common.c b/src/providers/ipa/ipa_hbac_common.c +index 7d68aa5125682e1b43012ac978d42a0bbd2c5d55..d537db1ea591589ad687a432fb0ebba3dd4fa42a 100644 +--- a/src/providers/ipa/ipa_hbac_common.c ++++ b/src/providers/ipa/ipa_hbac_common.c +@@ -567,7 +567,7 @@ hbac_eval_user_element(TALLOC_CTX *mem_ctx, + + ret = get_ipa_groupname(users->groups, sysdb, member_dn, + &users->groups[num_groups]); +- if (ret != EOK && ret != ENOENT) { ++ if (ret != EOK && ret != ERR_UNEXPECTED_ENTRY_TYPE) { + DEBUG(SSSDBG_MINOR_FAILURE, "Parse error on [%s]\n", member_dn); + goto done; + } else if (ret == EOK) { +@@ -676,9 +676,9 @@ hbac_eval_service_element(TALLOC_CTX *mem_ctx, + ret = get_ipa_servicegroupname(tmp_ctx, sysdb, + (const char *)el->values[i].data, + &name); +- if (ret != EOK && ret != ENOENT) goto done; ++ if (ret != EOK && ret != ERR_UNEXPECTED_ENTRY_TYPE) goto done; + +- /* ENOENT means we had a memberOf entry that wasn't a ++ /* ERR_UNEXPECTED_ENTRY_TYPE means we had a memberOf entry that wasn't a + * service group. We'll just ignore those (could be + * HBAC rules) + */ +@@ -783,9 +783,9 @@ hbac_eval_host_element(TALLOC_CTX *mem_ctx, + ret = get_ipa_hostgroupname(tmp_ctx, sysdb, + (const char *)el->values[i].data, + &name); +- if (ret != EOK && ret != ENOENT) goto done; ++ if (ret != EOK && ret != ERR_UNEXPECTED_ENTRY_TYPE) goto done; + +- /* ENOENT means we had a memberOf entry that wasn't a ++ /* ERR_UNEXPECTED_ENTRY_TYPE means we had a memberOf entry that wasn't a + * host group. We'll just ignore those (could be + * HBAC rules) + */ +diff --git a/src/providers/ipa/ipa_hbac_hosts.c b/src/providers/ipa/ipa_hbac_hosts.c +index 656e0e5654a2390093fb5a7c4d7254b87be0589f..d331cdfabb489914658487734042086361c7e7b1 100644 +--- a/src/providers/ipa/ipa_hbac_hosts.c ++++ b/src/providers/ipa/ipa_hbac_hosts.c +@@ -362,14 +362,14 @@ get_ipa_hostgroupname(TALLOC_CTX *mem_ctx, + } + + if (!ldb_dn_validate(dn)) { +- ret = EINVAL; ++ ret = ERR_MALFORMED_ENTRY; + goto done; + } + + if (ldb_dn_get_comp_num(dn) < 4) { + /* RDN, hostgroups, accounts, and at least one DC= */ + /* If it's fewer, it's not a group DN */ +- ret = ENOENT; ++ ret = ERR_UNEXPECTED_ENTRY_TYPE; + goto done; + } + +@@ -379,7 +379,7 @@ get_ipa_hostgroupname(TALLOC_CTX *mem_ctx, + /* Shouldn't happen if ldb_dn_validate() + * passed, but we'll be careful. + */ +- ret = EINVAL; ++ ret = ERR_MALFORMED_ENTRY; + goto done; + } + +@@ -387,7 +387,7 @@ get_ipa_hostgroupname(TALLOC_CTX *mem_ctx, + /* RDN has the wrong attribute name. + * It's not a host. + */ +- ret = ENOENT; ++ ret = ERR_UNEXPECTED_ENTRY_TYPE; + goto done; + } + +@@ -395,7 +395,7 @@ get_ipa_hostgroupname(TALLOC_CTX *mem_ctx, + hostgroup_comp_name = ldb_dn_get_component_name(dn, 1); + if (strcasecmp("cn", hostgroup_comp_name) != 0) { + /* The second component name is not "cn" */ +- ret = ENOENT; ++ ret = ERR_UNEXPECTED_ENTRY_TYPE; + goto done; + } + +@@ -404,7 +404,7 @@ get_ipa_hostgroupname(TALLOC_CTX *mem_ctx, + (const char *) hostgroup_comp_val->data, + hostgroup_comp_val->length) != 0) { + /* The second component value is not "hostgroups" */ +- ret = ENOENT; ++ ret = ERR_UNEXPECTED_ENTRY_TYPE; + goto done; + } + +@@ -412,7 +412,7 @@ get_ipa_hostgroupname(TALLOC_CTX *mem_ctx, + account_comp_name = ldb_dn_get_component_name(dn, 2); + if (strcasecmp("cn", account_comp_name) != 0) { + /* The third component name is not "cn" */ +- ret = ENOENT; ++ ret = ERR_UNEXPECTED_ENTRY_TYPE; + goto done; + } + +@@ -421,7 +421,7 @@ get_ipa_hostgroupname(TALLOC_CTX *mem_ctx, + (const char *) account_comp_val->data, + account_comp_val->length) != 0) { + /* The third component value is not "accounts" */ +- ret = ENOENT; ++ ret = ERR_UNEXPECTED_ENTRY_TYPE; + goto done; + } + +diff --git a/src/providers/ipa/ipa_hbac_services.c b/src/providers/ipa/ipa_hbac_services.c +index 3040ce68a68520d7eee0ec478ee0adbfb80eb083..35ee003effb5ac933843cbc3bd662f81a58246ad 100644 +--- a/src/providers/ipa/ipa_hbac_services.c ++++ b/src/providers/ipa/ipa_hbac_services.c +@@ -606,14 +606,14 @@ get_ipa_servicegroupname(TALLOC_CTX *mem_ctx, + } + + if (!ldb_dn_validate(dn)) { +- ret = EINVAL; ++ ret = ERR_MALFORMED_ENTRY; + goto done; + } + + if (ldb_dn_get_comp_num(dn) < 4) { + /* RDN, services, hbac, and at least one DC= */ + /* If it's fewer, it's not a group DN */ +- ret = ENOENT; ++ ret = ERR_UNEXPECTED_ENTRY_TYPE; + goto done; + } + +@@ -623,7 +623,7 @@ get_ipa_servicegroupname(TALLOC_CTX *mem_ctx, + /* Shouldn't happen if ldb_dn_validate() + * passed, but we'll be careful. + */ +- ret = EINVAL; ++ ret = ERR_MALFORMED_ENTRY; + goto done; + } + +@@ -631,7 +631,7 @@ get_ipa_servicegroupname(TALLOC_CTX *mem_ctx, + /* RDN has the wrong attribute name. + * It's not a service. + */ +- ret = ENOENT; ++ ret = ERR_UNEXPECTED_ENTRY_TYPE; + goto done; + } + +@@ -639,7 +639,7 @@ get_ipa_servicegroupname(TALLOC_CTX *mem_ctx, + svc_comp_name = ldb_dn_get_component_name(dn, 1); + if (strcasecmp("cn", svc_comp_name) != 0) { + /* The second component name is not "cn" */ +- ret = ENOENT; ++ ret = ERR_UNEXPECTED_ENTRY_TYPE; + goto done; + } + +@@ -648,7 +648,7 @@ get_ipa_servicegroupname(TALLOC_CTX *mem_ctx, + (const char *) svc_comp_val->data, + svc_comp_val->length) != 0) { + /* The second component value is not "hbacservicegroups" */ +- ret = ENOENT; ++ ret = ERR_UNEXPECTED_ENTRY_TYPE; + goto done; + } + +@@ -656,7 +656,7 @@ get_ipa_servicegroupname(TALLOC_CTX *mem_ctx, + hbac_comp_name = ldb_dn_get_component_name(dn, 2); + if (strcasecmp("cn", hbac_comp_name) != 0) { + /* The third component name is not "cn" */ +- ret = ENOENT; ++ ret = ERR_UNEXPECTED_ENTRY_TYPE; + goto done; + } + +@@ -665,7 +665,7 @@ get_ipa_servicegroupname(TALLOC_CTX *mem_ctx, + (const char *) hbac_comp_val->data, + hbac_comp_val->length) != 0) { + /* The third component value is not "hbac" */ +- ret = ENOENT; ++ ret = ERR_UNEXPECTED_ENTRY_TYPE; + goto done; + } + +diff --git a/src/providers/ipa/ipa_hbac_users.c b/src/providers/ipa/ipa_hbac_users.c +index ebf4bf9d591135e19492a89e2fab4aac05f873d9..a8d52ffa51ba1a04cf0101cb00537c58d1a4848d 100644 +--- a/src/providers/ipa/ipa_hbac_users.c ++++ b/src/providers/ipa/ipa_hbac_users.c +@@ -60,14 +60,14 @@ get_ipa_groupname(TALLOC_CTX *mem_ctx, + } + + if (!ldb_dn_validate(dn)) { +- ret = EINVAL; ++ ret = ERR_MALFORMED_ENTRY; + goto done; + } + + if (ldb_dn_get_comp_num(dn) < 4) { + /* RDN, groups, accounts, and at least one DC= */ + /* If it's fewer, it's not a group DN */ +- ret = ENOENT; ++ ret = ERR_UNEXPECTED_ENTRY_TYPE; + goto done; + } + +@@ -77,7 +77,7 @@ get_ipa_groupname(TALLOC_CTX *mem_ctx, + /* Shouldn't happen if ldb_dn_validate() + * passed, but we'll be careful. + */ +- ret = EINVAL; ++ ret = ERR_MALFORMED_ENTRY; + goto done; + } + +@@ -85,7 +85,7 @@ get_ipa_groupname(TALLOC_CTX *mem_ctx, + /* RDN has the wrong attribute name. + * It's not a group. + */ +- ret = ENOENT; ++ ret = ERR_UNEXPECTED_ENTRY_TYPE; + goto done; + } + +@@ -93,7 +93,7 @@ get_ipa_groupname(TALLOC_CTX *mem_ctx, + group_comp_name = ldb_dn_get_component_name(dn, 1); + if (strcasecmp("cn", group_comp_name) != 0) { + /* The second component name is not "cn" */ +- ret = ENOENT; ++ ret = ERR_UNEXPECTED_ENTRY_TYPE; + goto done; + } + +@@ -102,7 +102,7 @@ get_ipa_groupname(TALLOC_CTX *mem_ctx, + (const char *) group_comp_val->data, + group_comp_val->length) != 0) { + /* The second component value is not "groups" */ +- ret = ENOENT; ++ ret = ERR_UNEXPECTED_ENTRY_TYPE; + goto done; + } + +@@ -110,7 +110,7 @@ get_ipa_groupname(TALLOC_CTX *mem_ctx, + account_comp_name = ldb_dn_get_component_name(dn, 2); + if (strcasecmp("cn", account_comp_name) != 0) { + /* The third component name is not "cn" */ +- ret = ENOENT; ++ ret = ERR_UNEXPECTED_ENTRY_TYPE; + goto done; + } + +@@ -119,7 +119,7 @@ get_ipa_groupname(TALLOC_CTX *mem_ctx, + (const char *) account_comp_val->data, + account_comp_val->length) != 0) { + /* The third component value is not "accounts" */ +- ret = ENOENT; ++ ret = ERR_UNEXPECTED_ENTRY_TYPE; + goto done; + } + +diff --git a/src/util/util_errors.c b/src/util/util_errors.c +index dad988bce2515c3614a19205f038053152916a16..b481210aa21e05eda3a4c5b0699836d085baa892 100644 +--- a/src/util/util_errors.c ++++ b/src/util/util_errors.c +@@ -69,6 +69,8 @@ struct err_string error_to_str[] = { + { "Error setting SELinux user context" }, /* ERR_SELINUX_CONTEXT */ + { "Username format not allowed by re_expression" }, /* ERR_REGEX_NOMATCH */ + { "Time specification not supported" }, /* ERR_TIMESPEC_NOT_SUPPORTED */ ++ { "Malformed cache entry" }, /* ERR_MALFORMED_ENTRY */ ++ { "Unexpected cache entry type" }, /* ERR_UNEXPECTED_ENTRY_TYPE */ + { "ERR_LAST" } /* ERR_LAST */ + }; + +diff --git a/src/util/util_errors.h b/src/util/util_errors.h +index 5d657c707dabc74cf5771af2b601500ba2664ee0..b6a667fffbbddc77de53e501e185defbd30b23e0 100644 +--- a/src/util/util_errors.h ++++ b/src/util/util_errors.h +@@ -91,6 +91,8 @@ enum sssd_errors { + ERR_SELINUX_CONTEXT, + ERR_REGEX_NOMATCH, + ERR_TIMESPEC_NOT_SUPPORTED, ++ ERR_MALFORMED_ENTRY, ++ ERR_UNEXPECTED_ENTRY_TYPE, + ERR_LAST /* ALWAYS LAST */ + }; + +-- +2.4.0 + diff --git a/0046-IPA-Drop-useless-sysdb-parameter.patch b/0046-IPA-Drop-useless-sysdb-parameter.patch new file mode 100644 index 0000000..7fb81fe --- /dev/null +++ b/0046-IPA-Drop-useless-sysdb-parameter.patch @@ -0,0 +1,154 @@ +From a7c2e661a9bedd114941c9d5f33d20b70c18e878 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Mon, 16 Mar 2015 11:00:09 +0100 +Subject: [PATCH 46/99] IPA: Drop useless sysdb parameter +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +https://fedorahosted.org/sssd/ticket/2603 + +It's better to dereference the domain structure. + +Reviewed-by: Pavel Březina +(cherry picked from commit 64d8e2df816323a004bf6e7e9d05ba373b9e033d) +--- + src/providers/ipa/ipa_hbac_common.c | 26 ++++++++++---------------- + 1 file changed, 10 insertions(+), 16 deletions(-) + +diff --git a/src/providers/ipa/ipa_hbac_common.c b/src/providers/ipa/ipa_hbac_common.c +index d537db1ea591589ad687a432fb0ebba3dd4fa42a..8436b7e2d1e9b745e3265c319669cf196f610ee1 100644 +--- a/src/providers/ipa/ipa_hbac_common.c ++++ b/src/providers/ipa/ipa_hbac_common.c +@@ -401,21 +401,18 @@ done: + + static errno_t + hbac_eval_user_element(TALLOC_CTX *mem_ctx, +- struct sysdb_ctx *sysdb, + struct sss_domain_info *domain, + const char *username, + struct hbac_request_element **user_element); + + static errno_t + hbac_eval_service_element(TALLOC_CTX *mem_ctx, +- struct sysdb_ctx *sysdb, + struct sss_domain_info *domain, + const char *servicename, + struct hbac_request_element **svc_element); + + static errno_t + hbac_eval_host_element(TALLOC_CTX *mem_ctx, +- struct sysdb_ctx *sysdb, + struct sss_domain_info *domain, + const char *hostname, + struct hbac_request_element **host_element); +@@ -455,16 +452,16 @@ hbac_ctx_to_eval_request(TALLOC_CTX *mem_ctx, + ret = ENOMEM; + goto done; + } +- ret = hbac_eval_user_element(eval_req, user_dom->sysdb, user_dom, ++ ret = hbac_eval_user_element(eval_req, user_dom, + pd->user, &eval_req->user); + } else { +- ret = hbac_eval_user_element(eval_req, domain->sysdb, domain, ++ ret = hbac_eval_user_element(eval_req, domain, + pd->user, &eval_req->user); + } + if (ret != EOK) goto done; + + /* Get the PAM service and service groups */ +- ret = hbac_eval_service_element(eval_req, domain->sysdb, domain, ++ ret = hbac_eval_service_element(eval_req, domain, + pd->service, &eval_req->service); + if (ret != EOK) goto done; + +@@ -480,7 +477,7 @@ hbac_ctx_to_eval_request(TALLOC_CTX *mem_ctx, + rhost = pd->rhost; + } + +- ret = hbac_eval_host_element(eval_req, domain->sysdb, domain, ++ ret = hbac_eval_host_element(eval_req, domain, + rhost, &eval_req->srchost); + if (ret != EOK) goto done; + +@@ -493,7 +490,7 @@ hbac_ctx_to_eval_request(TALLOC_CTX *mem_ctx, + goto done; + } + +- ret = hbac_eval_host_element(eval_req, domain->sysdb, domain, ++ ret = hbac_eval_host_element(eval_req, domain, + thost, &eval_req->targethost); + if (ret != EOK) goto done; + +@@ -508,7 +505,6 @@ done: + + static errno_t + hbac_eval_user_element(TALLOC_CTX *mem_ctx, +- struct sysdb_ctx *sysdb, + struct sss_domain_info *domain, + const char *username, + struct hbac_request_element **user_element) +@@ -565,7 +561,7 @@ hbac_eval_user_element(TALLOC_CTX *mem_ctx, + for (i = 0; i < el->num_values; i++) { + member_dn = (const char *)el->values[i].data; + +- ret = get_ipa_groupname(users->groups, sysdb, member_dn, ++ ret = get_ipa_groupname(users->groups, domain->sysdb, member_dn, + &users->groups[num_groups]); + if (ret != EOK && ret != ERR_UNEXPECTED_ENTRY_TYPE) { + DEBUG(SSSDBG_MINOR_FAILURE, "Parse error on [%s]\n", member_dn); +@@ -603,7 +599,6 @@ done: + + static errno_t + hbac_eval_service_element(TALLOC_CTX *mem_ctx, +- struct sysdb_ctx *sysdb, + struct sss_domain_info *domain, + const char *servicename, + struct hbac_request_element **svc_element) +@@ -636,7 +631,7 @@ hbac_eval_service_element(TALLOC_CTX *mem_ctx, + } + + /* Look up the service to get its originalMemberOf entries */ +- ret = sysdb_search_entry(tmp_ctx, sysdb, svc_dn, ++ ret = sysdb_search_entry(tmp_ctx, domain->sysdb, svc_dn, + LDB_SCOPE_BASE, NULL, + memberof_attrs, + &count, &msgs); +@@ -673,7 +668,7 @@ hbac_eval_service_element(TALLOC_CTX *mem_ctx, + } + + for (i = j = 0; i < el->num_values; i++) { +- ret = get_ipa_servicegroupname(tmp_ctx, sysdb, ++ ret = get_ipa_servicegroupname(tmp_ctx, domain->sysdb, + (const char *)el->values[i].data, + &name); + if (ret != EOK && ret != ERR_UNEXPECTED_ENTRY_TYPE) goto done; +@@ -702,7 +697,6 @@ done: + + static errno_t + hbac_eval_host_element(TALLOC_CTX *mem_ctx, +- struct sysdb_ctx *sysdb, + struct sss_domain_info *domain, + const char *hostname, + struct hbac_request_element **host_element) +@@ -743,7 +737,7 @@ hbac_eval_host_element(TALLOC_CTX *mem_ctx, + } + + /* Look up the host to get its originalMemberOf entries */ +- ret = sysdb_search_entry(tmp_ctx, sysdb, host_dn, ++ ret = sysdb_search_entry(tmp_ctx, domain->sysdb, host_dn, + LDB_SCOPE_BASE, NULL, + memberof_attrs, + &count, &msgs); +@@ -780,7 +774,7 @@ hbac_eval_host_element(TALLOC_CTX *mem_ctx, + } + + for (i = j = 0; i < el->num_values; i++) { +- ret = get_ipa_hostgroupname(tmp_ctx, sysdb, ++ ret = get_ipa_hostgroupname(tmp_ctx, domain->sysdb, + (const char *)el->values[i].data, + &name); + if (ret != EOK && ret != ERR_UNEXPECTED_ENTRY_TYPE) goto done; +-- +2.4.0 + diff --git a/0047-IPA-Only-treat-malformed-HBAC-rules-as-fatal-if-deny.patch b/0047-IPA-Only-treat-malformed-HBAC-rules-as-fatal-if-deny.patch new file mode 100644 index 0000000..22b34aa --- /dev/null +++ b/0047-IPA-Only-treat-malformed-HBAC-rules-as-fatal-if-deny.patch @@ -0,0 +1,183 @@ +From 4df47543690a8b185d04ca6a0270e231e4491e6d Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Mon, 16 Mar 2015 11:12:25 +0100 +Subject: [PATCH 47/99] IPA: Only treat malformed HBAC rules as fatal if deny + rules are enabled +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +https://fedorahosted.org/sssd/ticket/2603 + +If deny rules are not in effect, we can skip malformed HBAC rules +because at worst we will deny access. If deny rules are in effect, we +need to error out to be on the safe side and avoid skipping a deny rule. + +Reviewed-by: Pavel Březina +(cherry picked from commit c41ae115bfa808d04e729dcbd759d8aae8387ce7) +--- + src/providers/ipa/ipa_hbac_common.c | 68 +++++++++++++++++++++++++++++-------- + 1 file changed, 54 insertions(+), 14 deletions(-) + +diff --git a/src/providers/ipa/ipa_hbac_common.c b/src/providers/ipa/ipa_hbac_common.c +index 8436b7e2d1e9b745e3265c319669cf196f610ee1..a7e338e995de0f2e4142132c056476bc301d80cc 100644 +--- a/src/providers/ipa/ipa_hbac_common.c ++++ b/src/providers/ipa/ipa_hbac_common.c +@@ -403,18 +403,21 @@ static errno_t + hbac_eval_user_element(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *username, ++ bool deny_rules, + struct hbac_request_element **user_element); + + static errno_t + hbac_eval_service_element(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *servicename, ++ bool deny_rules, + struct hbac_request_element **svc_element); + + static errno_t + hbac_eval_host_element(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *hostname, ++ bool deny_rules, + struct hbac_request_element **host_element); + + static errno_t +@@ -452,17 +455,20 @@ hbac_ctx_to_eval_request(TALLOC_CTX *mem_ctx, + ret = ENOMEM; + goto done; + } +- ret = hbac_eval_user_element(eval_req, user_dom, +- pd->user, &eval_req->user); ++ ret = hbac_eval_user_element(eval_req, user_dom, pd->user, ++ hbac_ctx->get_deny_rules, ++ &eval_req->user); + } else { +- ret = hbac_eval_user_element(eval_req, domain, +- pd->user, &eval_req->user); ++ ret = hbac_eval_user_element(eval_req, domain, pd->user, ++ hbac_ctx->get_deny_rules, ++ &eval_req->user); + } + if (ret != EOK) goto done; + + /* Get the PAM service and service groups */ +- ret = hbac_eval_service_element(eval_req, domain, +- pd->service, &eval_req->service); ++ ret = hbac_eval_service_element(eval_req, domain, pd->service, ++ hbac_ctx->get_deny_rules, ++ &eval_req->service); + if (ret != EOK) goto done; + + /* Get the source host */ +@@ -477,8 +483,9 @@ hbac_ctx_to_eval_request(TALLOC_CTX *mem_ctx, + rhost = pd->rhost; + } + +- ret = hbac_eval_host_element(eval_req, domain, +- rhost, &eval_req->srchost); ++ ret = hbac_eval_host_element(eval_req, domain, rhost, ++ hbac_ctx->get_deny_rules, ++ &eval_req->srchost); + if (ret != EOK) goto done; + + /* The target host is always the current machine */ +@@ -490,8 +497,9 @@ hbac_ctx_to_eval_request(TALLOC_CTX *mem_ctx, + goto done; + } + +- ret = hbac_eval_host_element(eval_req, domain, +- thost, &eval_req->targethost); ++ ret = hbac_eval_host_element(eval_req, domain, thost, ++ hbac_ctx->get_deny_rules, ++ &eval_req->targethost); + if (ret != EOK) goto done; + + *request = talloc_steal(mem_ctx, eval_req); +@@ -507,6 +515,7 @@ static errno_t + hbac_eval_user_element(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *username, ++ bool deny_rules, + struct hbac_request_element **user_element) + { + errno_t ret; +@@ -564,8 +573,15 @@ hbac_eval_user_element(TALLOC_CTX *mem_ctx, + ret = get_ipa_groupname(users->groups, domain->sysdb, member_dn, + &users->groups[num_groups]); + if (ret != EOK && ret != ERR_UNEXPECTED_ENTRY_TYPE) { +- DEBUG(SSSDBG_MINOR_FAILURE, "Parse error on [%s]\n", member_dn); +- goto done; ++ if (deny_rules) { ++ DEBUG(SSSDBG_OP_FAILURE, "Parse error on [%s]: %s\n", ++ member_dn, sss_strerror(ret)); ++ goto done; ++ } else { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "Skipping malformed entry [%s]\n", member_dn); ++ continue; ++ } + } else if (ret == EOK) { + DEBUG(SSSDBG_TRACE_LIBS, "Added group [%s] for user [%s]\n", + users->groups[num_groups], users->name); +@@ -601,6 +617,7 @@ static errno_t + hbac_eval_service_element(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *servicename, ++ bool deny_rules, + struct hbac_request_element **svc_element) + { + errno_t ret; +@@ -671,7 +688,18 @@ hbac_eval_service_element(TALLOC_CTX *mem_ctx, + ret = get_ipa_servicegroupname(tmp_ctx, domain->sysdb, + (const char *)el->values[i].data, + &name); +- if (ret != EOK && ret != ERR_UNEXPECTED_ENTRY_TYPE) goto done; ++ if (ret != EOK && ret != ERR_UNEXPECTED_ENTRY_TYPE) { ++ if (deny_rules) { ++ DEBUG(SSSDBG_OP_FAILURE, "Parse error on [%s]: %s\n", ++ (const char *)el->values[i].data, ++ sss_strerror(ret)); ++ goto done; ++ } else { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Skipping malformed entry [%s]\n", ++ (const char *)el->values[i].data); ++ continue; ++ } ++ } + + /* ERR_UNEXPECTED_ENTRY_TYPE means we had a memberOf entry that wasn't a + * service group. We'll just ignore those (could be +@@ -699,6 +727,7 @@ static errno_t + hbac_eval_host_element(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *hostname, ++ bool deny_rules, + struct hbac_request_element **host_element) + { + errno_t ret; +@@ -777,7 +806,18 @@ hbac_eval_host_element(TALLOC_CTX *mem_ctx, + ret = get_ipa_hostgroupname(tmp_ctx, domain->sysdb, + (const char *)el->values[i].data, + &name); +- if (ret != EOK && ret != ERR_UNEXPECTED_ENTRY_TYPE) goto done; ++ if (ret != EOK && ret != ERR_UNEXPECTED_ENTRY_TYPE) { ++ if (deny_rules) { ++ DEBUG(SSSDBG_OP_FAILURE, "Parse error on [%s]: %s\n", ++ (const char *)el->values[i].data, ++ sss_strerror(ret)); ++ goto done; ++ } else { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Skipping malformed entry [%s]\n", ++ (const char *)el->values[i].data); ++ continue; ++ } ++ } + + /* ERR_UNEXPECTED_ENTRY_TYPE means we had a memberOf entry that wasn't a + * host group. We'll just ignore those (could be +-- +2.4.0 + diff --git a/0048-IPA-Deprecate-the-ipa_hbac_treat_deny_as-option.patch b/0048-IPA-Deprecate-the-ipa_hbac_treat_deny_as-option.patch new file mode 100644 index 0000000..2d07a22 --- /dev/null +++ b/0048-IPA-Deprecate-the-ipa_hbac_treat_deny_as-option.patch @@ -0,0 +1,37 @@ +From 010c1c605cfcd2879a6f91ba61ea8db53aa4c5ae Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Mon, 16 Mar 2015 11:28:25 +0100 +Subject: [PATCH 48/99] IPA: Deprecate the ipa_hbac_treat_deny_as option +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +https://fedorahosted.org/sssd/ticket/2603 + +Deny rules have not been supported by the IPA server since 2.1. We +should deprecate the ipa_hbac_treat_deny_as option. + +Reviewed-by: Pavel Březina +(cherry picked from commit fdfe33975cd902bf7a334e49f2667f6346c4e6ae) +--- + src/providers/ipa/ipa_access.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/providers/ipa/ipa_access.c b/src/providers/ipa/ipa_access.c +index 2ebaec337eedd205bab7c7cbb2a77568616062d0..d1ae18999d0b1c7637ab6de52b0290cde1c40e87 100644 +--- a/src/providers/ipa/ipa_access.c ++++ b/src/providers/ipa/ipa_access.c +@@ -178,6 +178,10 @@ static void ipa_hbac_check(struct tevent_req *req) + hbac_ctx->get_deny_rules = false; + } else { + hbac_ctx->get_deny_rules = true; ++ sss_log(SSS_LOG_NOTICE, ++ "WARNING: Using deny rules is deprecated, the option " ++ "ipa_hbac_treat_deny_as will be removed in the next " ++ "upstream version\n"); + } + + ret = hbac_retry(hbac_ctx); +-- +2.4.0 + diff --git a/0049-LDAP-fix-a-typo-in-debug-message.patch b/0049-LDAP-fix-a-typo-in-debug-message.patch new file mode 100644 index 0000000..0a49156 --- /dev/null +++ b/0049-LDAP-fix-a-typo-in-debug-message.patch @@ -0,0 +1,30 @@ +From 8dc685c6e8658a7844811a86cb1d7f3809026f44 Mon Sep 17 00:00:00 2001 +From: Pavel Reichl +Date: Tue, 24 Mar 2015 12:14:50 -0400 +Subject: [PATCH 49/99] LDAP: fix a typo in debug message +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Pavel Březina +(cherry picked from commit 871f340834f25ca92a481718939164e708a70e29) +--- + src/providers/ldap/sdap_access.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/providers/ldap/sdap_access.c b/src/providers/ldap/sdap_access.c +index 0b251121335841b357e55deac608f50e24311285..c10b9ddcfc6ae08ce27e6a4fbdf2e273fdee6ed9 100644 +--- a/src/providers/ldap/sdap_access.c ++++ b/src/providers/ldap/sdap_access.c +@@ -1727,7 +1727,7 @@ is_account_locked(const char *pwdAccountLockedTime, + * permanently. + */ + DEBUG(SSSDBG_TRACE_FUNC, +- "Account of: %s is beeing blocked by password policy, " ++ "Account of: %s is being blocked by password policy, " + "but value: [%s] value is ignored by SSSD.\n", + username, pwdAccountLockedTime); + locked = false; +-- +2.4.0 + diff --git a/0050-MAN-Update-ppolicy-description.patch b/0050-MAN-Update-ppolicy-description.patch new file mode 100644 index 0000000..a0a9900 --- /dev/null +++ b/0050-MAN-Update-ppolicy-description.patch @@ -0,0 +1,40 @@ +From b025247b620206d31917cd5fb40943b1f2c55201 Mon Sep 17 00:00:00 2001 +From: Pavel Reichl +Date: Thu, 26 Mar 2015 12:38:32 -0400 +Subject: [PATCH 50/99] MAN: Update ppolicy description + +Resolves: +https://fedorahosted.org/sssd/ticket/2612 + +Reviewed-by: Stephen Gallagher +(cherry picked from commit 1426ee8756a1df4ec0651417dce92e1dcc8a246d) +--- + src/man/sssd-ldap.5.xml | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml +index 00da3964af7619f19525e76c4f1292586dd60f54..7de0faef29b3112383a7f7863912b542a6c5e1ca 100644 +--- a/src/man/sssd-ldap.5.xml ++++ b/src/man/sssd-ldap.5.xml +@@ -1959,11 +1959,14 @@ ldap_access_filter = (employeeType=admin) + If set, this option denies access in case that ldap + attribute 'pwdAccountLockedTime' is present and has + value of '000001010000Z' or represents any time in the past. +- The value of 'pwdAccountLockedTime' attribute +- must end with 'Z' as only UTC time zone is +- currently suported. Please see the option +- ldap_pwdlockout_dn. + ++ The value of the 'pwdAccountLockedTime' attribute ++ must end with 'Z', which denotes the UTC time zone. ++ Other time zones are not currently supported and ++ will result in "access-denied" when users attempt ++ to log in. ++ ++ Please see the option ldap_pwdlockout_dn. + Please note that 'access_provider = ldap' must + be set for this feature to work. + +-- +2.4.0 + diff --git a/0051-CLIENT-Clear-errno-with-enabled-sss-default-nss-plug.patch b/0051-CLIENT-Clear-errno-with-enabled-sss-default-nss-plug.patch new file mode 100644 index 0000000..a7320bf --- /dev/null +++ b/0051-CLIENT-Clear-errno-with-enabled-sss-default-nss-plug.patch @@ -0,0 +1,76 @@ +From 9e030a229277cfb598fd80e861e6bb0b7cfdec9c Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik +Date: Tue, 7 Apr 2015 10:53:12 +0200 +Subject: [PATCH 51/99] CLIENT: Clear errno with enabled sss-default-nss-plugin + +Although errno was cleared in function sss_nss_make_request +some sss glic functions set errno with value of output argument errnop. + +Reproducer: +* sssd compiled with enabled option sss-default-nss-plugin +* sss is the last value in group (/etc/nsswitch.conf) +* sssd-client is installed but sssd is stopped. + +C-program: + #include + #include + #include + #include + + int main(int argc, char *argv[]) + { + struct group *p_group; + + setgrent(); + while (1) { + errno = 0; /* initialize for getgrent() */ + p_group = getgrent(); + if (p_group == NULL) { + if (errno == 0) { + break; /* end of groups */ + } else { + perror("getgrent"); + printf("getgrent error %d \n", errno); + endgrent(); + exit(-2); + } + } + printf("getgrent() OK group(%d) = %s \n", + p_group->gr_gid, p_group->gr_name); + } + + exit(0); + } + +Resolves: +https://fedorahosted.org/sssd/ticket/2619 + +Reviewed-by: Pavel Reichl +(cherry picked from commit d51bc5f43fffa516446ef62c2b860be9fa939c9d) +--- + src/sss_client/common.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/sss_client/common.c b/src/sss_client/common.c +index 1b0fb1223f3509ef0b5aaf4a53851b868e12d6f0..383572bada613e745ed198de2260a7fd27e43544 100644 +--- a/src/sss_client/common.c ++++ b/src/sss_client/common.c +@@ -725,6 +725,7 @@ enum nss_status sss_nss_make_request(enum sss_cli_command cmd, + ret = sss_cli_check_socket(errnop, SSS_NSS_SOCKET_NAME); + if (ret != SSS_STATUS_SUCCESS) { + #ifdef NONSTANDARD_SSS_NSS_BEHAVIOUR ++ *errnop = 0; + errno = 0; + return NSS_STATUS_NOTFOUND; + #else +@@ -741,6 +742,7 @@ enum nss_status sss_nss_make_request(enum sss_cli_command cmd, + case SSS_STATUS_UNAVAIL: + default: + #ifdef NONSTANDARD_SSS_NSS_BEHAVIOUR ++ *errnop = 0; + errno = 0; + return NSS_STATUS_NOTFOUND; + #else +-- +2.4.0 + diff --git a/0052-GPO-Check-return-value-of-ad_gpo_store_policy_settin.patch b/0052-GPO-Check-return-value-of-ad_gpo_store_policy_settin.patch new file mode 100644 index 0000000..6fbba6e --- /dev/null +++ b/0052-GPO-Check-return-value-of-ad_gpo_store_policy_settin.patch @@ -0,0 +1,30 @@ +From 5a4e7bf91a90e3ece5ef7ad8c2043480902677cc Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik +Date: Fri, 6 Mar 2015 20:42:35 +0100 +Subject: [PATCH 52/99] GPO: Check return value of ad_gpo_store_policy_settings + +Reviewed-by: Pavel Reichl +--- + src/providers/ad/ad_gpo.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c +index 69ff6daaa7e060cca4cab129ecde83d3406702d1..a881741a6ead9244ac123608234d1a0c35f830e3 100644 +--- a/src/providers/ad/ad_gpo.c ++++ b/src/providers/ad/ad_gpo.c +@@ -2184,6 +2184,12 @@ ad_gpo_cse_done(struct tevent_req *subreq) + */ + ret = ad_gpo_store_policy_settings(state->domain, + cse_filtered_gpo->policy_filename); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "ad_gpo_store_policy_settings failed: [%d](%s)\n", ++ ret, sss_strerror(ret)); ++ goto done; ++ } + + state->cse_gpo_index++; + ret = ad_gpo_cse_step(req); +-- +2.4.0 + diff --git a/0053-enumeration-fix-talloc-context.patch b/0053-enumeration-fix-talloc-context.patch new file mode 100644 index 0000000..7337a3d --- /dev/null +++ b/0053-enumeration-fix-talloc-context.patch @@ -0,0 +1,51 @@ +From 81bb9be1ae0b2a4ebe960f136a52576abcdfbbac Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pavel=20B=C5=99ezina?= +Date: Wed, 25 Mar 2015 12:08:04 +0100 +Subject: [PATCH 53/99] enumeration: fix talloc context + +If for some reason ptask fails (e.g. timeout), req is talloc freed +but because subreq is attached to ectx which is permanent it is +finished anyway. Then a crash occures when we are trying to access +callback data. + +The same happens in sdap_dom_enum_ex_send. + +Resolves: +https://fedorahosted.org/sssd/ticket/2611 + +Reviewed-by: Pavel Reichl +(cherry picked from commit 725bb2a9901c4f673b107ed179f5d68ec443ca63) +--- + src/providers/ldap/ldap_id_enum.c | 2 +- + src/providers/ldap/sdap_async_enum.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/providers/ldap/ldap_id_enum.c b/src/providers/ldap/ldap_id_enum.c +index 13d2a62544b3956165ef9eb480fb5b813c890fd4..1aec91a99a322911fcc5d2a3e8a89cd98bbc7a96 100644 +--- a/src/providers/ldap/ldap_id_enum.c ++++ b/src/providers/ldap/ldap_id_enum.c +@@ -133,7 +133,7 @@ ldap_enumeration_send(TALLOC_CTX *mem_ctx, + state->dom = ectx->sdom->dom; + state->id_ctx = talloc_get_type_abort(ectx->pvt, struct sdap_id_ctx); + +- subreq = sdap_dom_enum_send(ectx, ev, state->id_ctx, ectx->sdom, ++ subreq = sdap_dom_enum_send(state, ev, state->id_ctx, ectx->sdom, + state->id_ctx->conn); + if (subreq == NULL) { + /* The ptask API will reschedule the enumeration on its own on +diff --git a/src/providers/ldap/sdap_async_enum.c b/src/providers/ldap/sdap_async_enum.c +index 1cc09abdf1aa14e3d1690ea1abe32604ae4ff1cd..35afc55f809669a44aa2beda7d87dfe62d6ec10b 100644 +--- a/src/providers/ldap/sdap_async_enum.c ++++ b/src/providers/ldap/sdap_async_enum.c +@@ -91,7 +91,7 @@ sdap_dom_enum_ex_send(TALLOC_CTX *memctx, + int t; + errno_t ret; + +- req = tevent_req_create(ctx, &state, struct sdap_dom_enum_ex_state); ++ req = tevent_req_create(memctx, &state, struct sdap_dom_enum_ex_state); + if (req == NULL) return NULL; + + state->ev = ev; +-- +2.4.0 + diff --git a/0054-sudo-sanitize-filter-values.patch b/0054-sudo-sanitize-filter-values.patch new file mode 100644 index 0000000..7cf1f59 --- /dev/null +++ b/0054-sudo-sanitize-filter-values.patch @@ -0,0 +1,61 @@ +From 2fb2a267d0d15cce84b0ccea7e088a4b580e42fb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pavel=20B=C5=99ezina?= +Date: Thu, 9 Apr 2015 13:03:08 +0200 +Subject: [PATCH 54/99] sudo: sanitize filter values + +Resolves: +https://fedorahosted.org/sssd/ticket/2613 + +Reviewed-by: Pavel Reichl +(cherry picked from commit c526cd124515cc2d44a413dcbfd4a74ddb490150) +--- + src/db/sysdb_sudo.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +diff --git a/src/db/sysdb_sudo.c b/src/db/sysdb_sudo.c +index 4c50d32c779732a5fb78f23f4344ba4ba0825e84..784ac8af3ae5cb08f30eb9631c7ffa4aa92bde23 100644 +--- a/src/db/sysdb_sudo.c ++++ b/src/db/sysdb_sudo.c +@@ -221,6 +221,7 @@ sysdb_get_sudo_filter(TALLOC_CTX *mem_ctx, const char *username, + TALLOC_CTX *tmp_ctx = NULL; + char *filter = NULL; + char *specific_filter = NULL; ++ char *sanitized = NULL; + time_t now; + errno_t ret; + int i; +@@ -246,9 +247,14 @@ sysdb_get_sudo_filter(TALLOC_CTX *mem_ctx, const char *username, + } + + if ((flags & SYSDB_SUDO_FILTER_USERNAME) && (username != NULL)) { ++ ret = sss_filter_sanitize(tmp_ctx, username, &sanitized); ++ if (ret != EOK) { ++ goto done; ++ } ++ + specific_filter = talloc_asprintf_append(specific_filter, "(%s=%s)", + SYSDB_SUDO_CACHE_AT_USER, +- username); ++ sanitized); + NULL_CHECK(specific_filter, ret, done); + } + +@@ -261,9 +267,14 @@ sysdb_get_sudo_filter(TALLOC_CTX *mem_ctx, const char *username, + + if ((flags & SYSDB_SUDO_FILTER_GROUPS) && (groupnames != NULL)) { + for (i=0; groupnames[i] != NULL; i++) { ++ ret = sss_filter_sanitize(tmp_ctx, groupnames[i], &sanitized); ++ if (ret != EOK) { ++ goto done; ++ } ++ + specific_filter = talloc_asprintf_append(specific_filter, "(%s=%%%s)", + SYSDB_SUDO_CACHE_AT_USER, +- groupnames[i]); ++ sanitized); + NULL_CHECK(specific_filter, ret, done); + } + } +-- +2.4.0 + diff --git a/0055-SDAP-Do-not-set-gid-0-twice.patch b/0055-SDAP-Do-not-set-gid-0-twice.patch new file mode 100644 index 0000000..a606615 --- /dev/null +++ b/0055-SDAP-Do-not-set-gid-0-twice.patch @@ -0,0 +1,49 @@ +From cf7047634308c431f4cfbff1d88564668d2a33c7 Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik +Date: Fri, 10 Apr 2015 14:33:35 +0200 +Subject: [PATCH 55/99] SDAP: Do not set gid 0 twice + +The gid o was added to sysdb attrs directly in sdap_save_group for 1st time +and for second time in the function sdap_store_group_with_gid, +which was called every time from function sdap_save_group + +[sysdb_set_entry_attr] (0x0080): ldb_modify failed: + [Attribute or value exists](20)[attribute 'gidNumber': value #1 + on 'name=domainlocalgroup1_dom2-493341@sssdad_tree.com,cn=groups,cn=sssdad_tree.com,cn=sysdb' provided more than once] +[sysdb_set_entry_attr] (0x0040): Error: 17 (File exists) +[sysdb_store_group] (0x1000): sysdb_set_group_attr failed. +[sysdb_store_group] (0x0400): Error: 17 (File exists) +[sdap_store_group_with_gid] (0x0040): + Could not store group domainlocalgroup1_dom2-493341@sssdad_tree.com +[sdap_save_group] (0x0080): Could not store group with GID: [File exists] +[sdap_save_group] (0x0080): + Failed to save group [domainlocalgroup1_dom2-493341@sssdad_tree.com]: [File exists] +[sdap_save_groups] (0x0040): Failed to store group 0. Ignoring. + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 5d864e7a9d0e1e6fb7dd8158c5b8bfb71040b908) +--- + src/providers/ldap/sdap_async_groups.c | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c +index f9613ddd72d1e1796bc6a034daf98275b07a5c79..454d302eabf32e0837a7a4ba03063a360524b412 100644 +--- a/src/providers/ldap/sdap_async_groups.c ++++ b/src/providers/ldap/sdap_async_groups.c +@@ -599,13 +599,6 @@ static int sdap_save_group(TALLOC_CTX *memctx, + gid = 0; + DEBUG(SSSDBG_TRACE_FUNC, "Filtering AD group [%s].\n", + group_name); +- ret = sysdb_attrs_add_uint32(group_attrs, +- opts->group_map[SDAP_AT_GROUP_GID].sys_name, 0); +- if (ret != EOK) { +- DEBUG(SSSDBG_CRIT_FAILURE, +- "Failed to add a GID to non-posix group!\n"); +- return ret; +- } + ret = sysdb_attrs_add_bool(group_attrs, SYSDB_POSIX, false); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, +-- +2.4.0 + diff --git a/0056-SDAP-Extract-filtering-AD-group-to-function.patch b/0056-SDAP-Extract-filtering-AD-group-to-function.patch new file mode 100644 index 0000000..442a5a1 --- /dev/null +++ b/0056-SDAP-Extract-filtering-AD-group-to-function.patch @@ -0,0 +1,239 @@ +From bdd031d274659263db5f28408d8b75c63d3485a0 Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik +Date: Mon, 13 Apr 2015 09:44:35 +0200 +Subject: [PATCH 56/99] SDAP: Extract filtering AD group to function + +Patch remove code duplication. + +Reviewed-by: Jakub Hrozek +(cherry picked from commit bad2fc8133d941e5a6c8d8016c9689e039265c61) +--- + Makefile.am | 2 + + src/providers/ldap/sdap_ad_groups.c | 68 +++++++++++++++++++++++++++ + src/providers/ldap/sdap_async_groups.c | 40 ++++++---------- + src/providers/ldap/sdap_async_nested_groups.c | 31 ++++-------- + src/providers/ldap/sdap_async_private.h | 7 +++ + 5 files changed, 101 insertions(+), 47 deletions(-) + create mode 100644 src/providers/ldap/sdap_ad_groups.c + +diff --git a/Makefile.am b/Makefile.am +index df34840747bdcc3e2cc68ac1a3ca448b4aa67433..973f8cb35d75982c1b66f94af96a9e4cfe39d467 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -1886,6 +1886,7 @@ nestedgroups_tests_SOURCES = \ + src/providers/ldap/sdap_idmap.c \ + src/tests/cmocka/test_nested_groups.c \ + src/providers/ldap/sdap_async_nested_groups.c \ ++ src/providers/ldap/sdap_ad_groups.c \ + $(NULL) + nestedgroups_tests_CFLAGS = \ + $(AM_CFLAGS) \ +@@ -2412,6 +2413,7 @@ libsss_ldap_common_la_SOURCES = \ + src/providers/ldap/sdap_async_connection.c \ + src/providers/ldap/sdap_async_netgroups.c \ + src/providers/ldap/sdap_async_services.c \ ++ src/providers/ldap/sdap_ad_groups.c \ + src/providers/ldap/sdap_child_helpers.c \ + src/providers/ldap/sdap_fd_events.c \ + src/providers/ldap/sdap_id_op.c \ +diff --git a/src/providers/ldap/sdap_ad_groups.c b/src/providers/ldap/sdap_ad_groups.c +new file mode 100644 +index 0000000000000000000000000000000000000000..0e36328b9b52643a2ec698b2a41f2a56a8ff69b6 +--- /dev/null ++++ b/src/providers/ldap/sdap_ad_groups.c +@@ -0,0 +1,68 @@ ++/* ++ SSSD ++ ++ AD groups helper routines ++ ++ Authors: ++ Lukas Slebodnik ++ ++ Copyright (C) 2013 Red Hat ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . ++*/ ++ ++#include "db/sysdb.h" ++#include "providers/ldap/sdap.h" ++#include "providers/ldap/sdap_async_private.h" ++ ++/* ==Group-Parsing Routines=============================================== */ ++ ++errno_t sdap_check_ad_group_type(struct sss_domain_info *dom, ++ struct sdap_options *opts, ++ struct sysdb_attrs *group_attrs, ++ const char *group_name, ++ bool *_need_filter) ++{ ++ int32_t ad_group_type; ++ errno_t ret = EOK; ++ *_need_filter = false; ++ ++ if (opts->schema_type == SDAP_SCHEMA_AD) { ++ ret = sysdb_attrs_get_int32_t(group_attrs, SYSDB_GROUP_TYPE, ++ &ad_group_type); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_int32_t failed.\n"); ++ return ret; ++ } ++ ++ DEBUG(SSSDBG_TRACE_ALL, ++ "AD group [%s] has type flags %#x.\n", ++ group_name, ad_group_type); ++ ++ /* Only security groups from AD are considered for POSIX groups. ++ * Additionally only global and universal group are taken to account ++ * for trusted domains. */ ++ if (!(ad_group_type & SDAP_AD_GROUP_TYPE_SECURITY) ++ || (IS_SUBDOMAIN(dom) ++ && (!((ad_group_type & SDAP_AD_GROUP_TYPE_GLOBAL) ++ || (ad_group_type & SDAP_AD_GROUP_TYPE_UNIVERSAL))))) { ++ DEBUG(SSSDBG_TRACE_FUNC, ++ "Filtering AD group [%s].\n", group_name); ++ ++ *_need_filter = true; ++ } ++ } ++ ++ return ret; ++} +diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c +index 454d302eabf32e0837a7a4ba03063a360524b412..fb1912d2b4fae1bdaf5f94d8f72c8f8deca2b17f 100644 +--- a/src/providers/ldap/sdap_async_groups.c ++++ b/src/providers/ldap/sdap_async_groups.c +@@ -510,9 +510,9 @@ static int sdap_save_group(TALLOC_CTX *memctx, + TALLOC_CTX *tmpctx = NULL; + bool posix_group; + bool use_id_mapping; ++ bool need_filter; + char *sid_str; + struct sss_domain_info *subdomain; +- int32_t ad_group_type; + + tmpctx = talloc_new(NULL); + if (!tmpctx) { +@@ -579,32 +579,20 @@ static int sdap_save_group(TALLOC_CTX *memctx, + DEBUG(SSSDBG_TRACE_FUNC, "Processing group %s\n", group_name); + + posix_group = true; +- if (opts->schema_type == SDAP_SCHEMA_AD) { +- ret = sysdb_attrs_get_int32_t(attrs, SYSDB_GROUP_TYPE, &ad_group_type); +- if (ret != EOK) { +- DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_int32_t failed.\n"); +- goto done; +- } ++ ret = sdap_check_ad_group_type(dom, opts, attrs, group_name, ++ &need_filter); ++ if (ret != EOK) { ++ goto done; ++ } ++ if (need_filter) { ++ posix_group = false; ++ gid = 0; + +- DEBUG(SSSDBG_TRACE_ALL, "AD group [%s] has type flags %#x.\n", +- group_name, ad_group_type); +- /* Only security groups from AD are considered for POSIX groups. +- * Additionally only global and universal group are taken to account +- * for trusted domains. */ +- if (!(ad_group_type & SDAP_AD_GROUP_TYPE_SECURITY) +- || (IS_SUBDOMAIN(dom) +- && (!((ad_group_type & SDAP_AD_GROUP_TYPE_GLOBAL) +- || (ad_group_type & SDAP_AD_GROUP_TYPE_UNIVERSAL))))) { +- posix_group = false; +- gid = 0; +- DEBUG(SSSDBG_TRACE_FUNC, "Filtering AD group [%s].\n", +- group_name); +- ret = sysdb_attrs_add_bool(group_attrs, SYSDB_POSIX, false); +- if (ret != EOK) { +- DEBUG(SSSDBG_OP_FAILURE, +- "Error: Failed to mark group as non-posix!\n"); +- return ret; +- } ++ ret = sysdb_attrs_add_bool(group_attrs, SYSDB_POSIX, false); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "Error: Failed to mark group as non-posix!\n"); ++ return ret; + } + } + +diff --git a/src/providers/ldap/sdap_async_nested_groups.c b/src/providers/ldap/sdap_async_nested_groups.c +index 1eba35ae8ac90acac8a2d46e8cc5f2b57e3a9256..08e199869ad16c3b19d998a2a28eae9a0dd0a371 100644 +--- a/src/providers/ldap/sdap_async_nested_groups.c ++++ b/src/providers/ldap/sdap_async_nested_groups.c +@@ -240,32 +240,21 @@ sdap_nested_group_hash_group(struct sdap_nested_group_ctx *group_ctx, + { + struct sdap_attr_map *map = group_ctx->opts->group_map; + gid_t gid; +- errno_t ret = ENOENT; +- int32_t ad_group_type; ++ errno_t ret; + bool posix_group = true; + bool use_id_mapping; + bool can_find_gid; ++ bool need_filter; + +- if (group_ctx->opts->schema_type == SDAP_SCHEMA_AD) { +- ret = sysdb_attrs_get_int32_t(group, SYSDB_GROUP_TYPE, &ad_group_type); +- if (ret != EOK) { +- DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_int32_t failed.\n"); +- return ret; +- } ++ ret = sdap_check_ad_group_type(group_ctx->domain, group_ctx->opts, ++ group, "", &need_filter); ++ if (ret != EOK) { ++ return ret; ++ } + +- DEBUG(SSSDBG_TRACE_ALL, "AD group has type flags %#x.\n", +- ad_group_type); +- /* Only security groups from AD are considered for POSIX groups. +- * Additionally only global and universal group are taken to account +- * for trusted domains. */ +- if (!(ad_group_type & SDAP_AD_GROUP_TYPE_SECURITY) +- || (IS_SUBDOMAIN(group_ctx->domain) +- && (!((ad_group_type & SDAP_AD_GROUP_TYPE_GLOBAL) +- || (ad_group_type & SDAP_AD_GROUP_TYPE_UNIVERSAL))))) { +- posix_group = false; +- gid = 0; +- DEBUG(SSSDBG_TRACE_FUNC, "Filtering AD group.\n"); +- } ++ if (need_filter) { ++ posix_group = false; ++ gid = 0; + } + + use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping( +diff --git a/src/providers/ldap/sdap_async_private.h b/src/providers/ldap/sdap_async_private.h +index 3995a2ac357c52f546696284d71d2127d0302409..db542eaf869efcd53d0937bef3fc6e99cc78b938 100644 +--- a/src/providers/ldap/sdap_async_private.h ++++ b/src/providers/ldap/sdap_async_private.h +@@ -138,4 +138,11 @@ errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb, + char **groupnames, + struct sysdb_attrs **ldap_groups, + int ldap_groups_count); ++ ++/* from sdap_async_nested_groups.c */ ++errno_t sdap_check_ad_group_type(struct sss_domain_info *dom, ++ struct sdap_options *opts, ++ struct sysdb_attrs *group_attrs, ++ const char *group_name, ++ bool *_need_filter); + #endif /* _SDAP_ASYNC_PRIVATE_H_ */ +-- +2.4.0 + diff --git a/0057-SDAP-Filter-ad-groups-in-initgroups.patch b/0057-SDAP-Filter-ad-groups-in-initgroups.patch new file mode 100644 index 0000000..2a99c75 --- /dev/null +++ b/0057-SDAP-Filter-ad-groups-in-initgroups.patch @@ -0,0 +1,50 @@ +From 49895bb18508a4f4b83b99d9875e99e17c81285b Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik +Date: Mon, 13 Apr 2015 09:50:29 +0200 +Subject: [PATCH 57/99] SDAP: Filter ad groups in initgroups + +Function sdap_add_incomplete_groups stored domain local groups +from subdomain as POSIX group, which should not be done. + +Resolves: +https://fedorahosted.org/sssd/ticket/2614 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit b9fbeb75e7a4f50f98d979a70a710f9221892483) +--- + src/providers/ldap/sdap_async_initgroups.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c +index 96617aecc4e9c948bbbdccb1ba75e81577a19c70..ae617b9c4c6899d0b85dcc4c4b6b971d0f235b88 100644 +--- a/src/providers/ldap/sdap_async_initgroups.c ++++ b/src/providers/ldap/sdap_async_initgroups.c +@@ -51,6 +51,7 @@ errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb, + time_t now; + char *sid_str = NULL; + bool use_id_mapping; ++ bool need_filter; + char *tmp_name; + + /* There are no groups in LDAP but we should add user to groups ?? */ +@@ -210,6 +211,17 @@ errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb, + uuid = NULL; + } + ++ ret = sdap_check_ad_group_type(domain, opts, ldap_groups[ai], ++ groupname, &need_filter); ++ if (ret != EOK) { ++ goto done; ++ } ++ ++ if (need_filter) { ++ posix = false; ++ gid = 0; ++ } ++ + DEBUG(SSSDBG_TRACE_INTERNAL, + "Adding fake group %s to sysdb\n", groupname); + ret = sysdb_add_incomplete_group(domain, groupname, gid, +-- +2.4.0 + diff --git a/0018-selinux-Disconnect-before-closing-the-handle.patch b/0058-selinux-Disconnect-before-closing-the-handle.patch similarity index 89% rename from 0018-selinux-Disconnect-before-closing-the-handle.patch rename to 0058-selinux-Disconnect-before-closing-the-handle.patch index 7407760..8ef95c8 100644 --- a/0018-selinux-Disconnect-before-closing-the-handle.patch +++ b/0058-selinux-Disconnect-before-closing-the-handle.patch @@ -1,7 +1,7 @@ -From 8f4a60a1fb0c24cfb01bc683a31b52786df68ccc Mon Sep 17 00:00:00 2001 +From 816d3cc041e276b138057aacb81d1a2bfb25add6 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Fri, 10 Apr 2015 10:55:22 +0200 -Subject: [PATCH 18/20] selinux: Disconnect before closing the handle +Subject: [PATCH 58/99] selinux: Disconnect before closing the handle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -15,6 +15,7 @@ was connected. Otherwise we get a memory leak. Reviewed-by: Michal Židek +(cherry picked from commit aa00d67b2a8e07c9080e7798defdc6c774c93465) --- src/util/sss_semanage.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) @@ -65,5 +66,5 @@ index b85831c3d3f262f49b19082e96aa62ccf3afeaa8..d141de1c671e6d62a731e56b10ee1406 } -- -2.3.5 +2.4.0 diff --git a/0019-selinux-Begin-and-end-the-transaction-on-the-same-ne.patch b/0059-selinux-Begin-and-end-the-transaction-on-the-same-ne.patch similarity index 91% rename from 0019-selinux-Begin-and-end-the-transaction-on-the-same-ne.patch rename to 0059-selinux-Begin-and-end-the-transaction-on-the-same-ne.patch index 828c740..770b78a 100644 --- a/0019-selinux-Begin-and-end-the-transaction-on-the-same-ne.patch +++ b/0059-selinux-Begin-and-end-the-transaction-on-the-same-ne.patch @@ -1,7 +1,7 @@ -From 342165ced656d64ec78bdb6f8897e15666cc08d2 Mon Sep 17 00:00:00 2001 +From 9c695e3a82fe5903b36b2d514b3284efeadc908c Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Fri, 10 Apr 2015 11:06:44 +0200 -Subject: [PATCH 19/20] selinux: Begin and end the transaction on the same +Subject: [PATCH 59/99] selinux: Begin and end the transaction on the same nesting level MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -13,6 +13,7 @@ and splitting them from initialization will make init function reusable by read-only libsemanage functions. Reviewed-by: Michal Židek +(cherry picked from commit 748b38a7991d78cbf4726f2a14ace5e926629a54) --- src/util/sss_semanage.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) @@ -63,5 +64,5 @@ index d141de1c671e6d62a731e56b10ee14069f27ae87..c0342498cbd0495733a0bf701a06a02c if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux user key\n"); -- -2.3.5 +2.4.0 diff --git a/0020-selinux-Only-call-semanage-if-the-context-actually-c.patch b/0060-selinux-Only-call-semanage-if-the-context-actually-c.patch similarity index 90% rename from 0020-selinux-Only-call-semanage-if-the-context-actually-c.patch rename to 0060-selinux-Only-call-semanage-if-the-context-actually-c.patch index 7ec762b..98171dc 100644 --- a/0020-selinux-Only-call-semanage-if-the-context-actually-c.patch +++ b/0060-selinux-Only-call-semanage-if-the-context-actually-c.patch @@ -1,7 +1,7 @@ -From 92a0931dfc57ec386b4c797ff4a144d2de7ffc25 Mon Sep 17 00:00:00 2001 +From 4d31f2c294db6090047e4d5348322b32ea0aaac1 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Thu, 9 Apr 2015 22:18:35 +0200 -Subject: [PATCH 20/20] selinux: Only call semanage if the context actually +Subject: [PATCH 60/99] selinux: Only call semanage if the context actually changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -16,6 +16,7 @@ server. Adds talloc dependency to libsss_semanage. Reviewed-by: Michal Židek +(cherry picked from commit 1e0fa55fb377db788e065de917ba8e149eb56161) --- Makefile.am | 5 +++ src/providers/ipa/selinux_child.c | 35 ++++++++++++++++--- @@ -24,10 +25,10 @@ Reviewed-by: Michal Židek 4 files changed, 109 insertions(+), 4 deletions(-) diff --git a/Makefile.am b/Makefile.am -index 605fd1ff5e479078d579ac7524507546261d469c..ed89028ebdbb85752f1f7f06ef8464613ee96377 100644 +index 973f8cb35d75982c1b66f94af96a9e4cfe39d467..65b9773d8804992f7553609b77553b3b3944a54d 100644 --- a/Makefile.am +++ b/Makefile.am -@@ -784,10 +784,15 @@ endif +@@ -770,10 +770,15 @@ endif libsss_util_la_LDFLAGS = -avoid-version pkglib_LTLIBRARIES += libsss_semanage.la @@ -191,17 +192,18 @@ index c0342498cbd0495733a0bf701a06a02cfb705fc7..01a2f41d8752e127f2aa1b72faa61c23 +} #endif /* HAVE_SEMANAGE */ diff --git a/src/util/util.h b/src/util/util.h -index bf3a9a057aed77e93949370f8651af2631d91432..d217688f81d7a2e49cd3eaaf0d1be609a0f679ea 100644 +index 91df09914abfa1a72e9280ab708e11abf9e07e18..81a8709d6840a9c5cd2acb23c40fdea7f9714e98 100644 --- a/src/util/util.h +++ b/src/util/util.h -@@ -635,5 +635,7 @@ errno_t restore_creds(struct sss_creds *saved_creds); +@@ -642,6 +642,8 @@ errno_t restore_creds(struct sss_creds *saved_creds); int set_seuser(const char *login_name, const char *seuser_name, const char *mlsrange); int del_seuser(const char *login_name); +int get_seuser(TALLOC_CTX *mem_ctx, const char *login_name, + char **_seuser, char **_mls_range); - #endif /* __SSSD_UTIL_H__ */ + /* convert time from generalized form to unix time */ + errno_t sss_utc_to_time_t(const char *str, const char *format, time_t *unix_time); -- -2.3.5 +2.4.0 diff --git a/0061-Option-filter_users-had-no-effect-for-retrieving-sud.patch b/0061-Option-filter_users-had-no-effect-for-retrieving-sud.patch new file mode 100644 index 0000000..404b14d --- /dev/null +++ b/0061-Option-filter_users-had-no-effect-for-retrieving-sud.patch @@ -0,0 +1,121 @@ +From d008c239c62ab6a467559156d5df854b099e4422 Mon Sep 17 00:00:00 2001 +From: Adam Tkac +Date: Mon, 13 Apr 2015 15:00:18 +0200 +Subject: [PATCH 61/99] Option filter_users had no effect for retrieving sudo + rules +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Previously sssd_sudo always obtained sudo rules for user from LDAP even +when user was enlisted in filter_users. + +Resolves https://fedorahosted.org/sssd/ticket/2625 + +Reviewed-by: Pavel Březina +(cherry picked from commit 2a25713afc6beefb11a799903a43f695c5d7a4f9) +--- + src/responder/sudo/sudosrv.c | 24 ++++++++++++++++++++++++ + src/responder/sudo/sudosrv_cmd.c | 12 ++++++++++++ + src/responder/sudo/sudosrv_private.h | 3 +++ + 3 files changed, 39 insertions(+) + +diff --git a/src/responder/sudo/sudosrv.c b/src/responder/sudo/sudosrv.c +index e480c7a43d453cffcd6ca07e41402c1cf6eef91c..bcc0a07f04bdd7dbccc3b47932a7917312395b12 100644 +--- a/src/responder/sudo/sudosrv.c ++++ b/src/responder/sudo/sudosrv.c +@@ -27,6 +27,7 @@ + #include "responder/common/responder_sbus.h" + #include "responder/sudo/sudosrv_private.h" + #include "providers/data_provider.h" ++#include "responder/common/negcache.h" + + struct mon_cli_iface monitor_sudo_methods = { + { &mon_cli_iface_meta, 0 }, +@@ -113,9 +114,32 @@ int sudo_process_init(TALLOC_CTX *mem_ctx, + goto fail; + } + ++ ret = sss_ncache_init(rctx, &sudo_ctx->ncache); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_FATAL_FAILURE, ++ "fatal error initializing ncache\n"); ++ goto fail; ++ } ++ + sudo_ctx->rctx = rctx; + sudo_ctx->rctx->pvt_ctx = sudo_ctx; + ++ ret = confdb_get_int(cdb, CONFDB_NSS_CONF_ENTRY, ++ CONFDB_NSS_ENTRY_NEG_TIMEOUT, 15, ++ &sudo_ctx->neg_timeout); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_FATAL_FAILURE, ++ "fatal error getting ncache timeout\n"); ++ goto fail; ++ } ++ ++ sss_ncache_prepopulate(sudo_ctx->ncache, sudo_ctx->rctx->cdb, rctx); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_FATAL_FAILURE, ++ "failed to set ncache for sudo's filter_users\n"); ++ goto fail; ++ } ++ + /* Enable automatic reconnection to the Data Provider */ + ret = confdb_get_int(sudo_ctx->rctx->cdb, + CONFDB_SUDO_CONF_ENTRY, +diff --git a/src/responder/sudo/sudosrv_cmd.c b/src/responder/sudo/sudosrv_cmd.c +index fd8c46d638ecbd0275b44511dbc6d31e0e316581..dd636e949200dd49c1422a5789e9328dc4b25fb0 100644 +--- a/src/responder/sudo/sudosrv_cmd.c ++++ b/src/responder/sudo/sudosrv_cmd.c +@@ -28,6 +28,7 @@ + #include "responder/sudo/sudosrv_private.h" + #include "db/sysdb_sudo.h" + #include "sss_client/sss_cli.h" ++#include "responder/common/negcache.h" + + static errno_t sudosrv_cmd_send_reply(struct sudo_cmd_ctx *cmd_ctx, + uint8_t *response_body, +@@ -239,6 +240,7 @@ static void sudosrv_cmd_parse_query_done(struct tevent_req *req) + { + struct sudo_cmd_ctx *cmd_ctx = NULL; + struct sudo_dom_ctx *dom_ctx = NULL; ++ struct sudo_ctx *sudo_ctx = NULL; + errno_t ret; + + cmd_ctx = tevent_req_callback_data(req, struct sudo_cmd_ctx); +@@ -278,6 +280,16 @@ static void sudosrv_cmd_parse_query_done(struct tevent_req *req) + dom_ctx->domain = cmd_ctx->domain != NULL ? cmd_ctx->domain + : cmd_ctx->cli_ctx->rctx->domains; + ++ sudo_ctx = talloc_get_type(cmd_ctx->cli_ctx->rctx->pvt_ctx, struct sudo_ctx); ++ ret = sss_ncache_check_user(sudo_ctx->ncache, sudo_ctx->neg_timeout, ++ dom_ctx->domain, cmd_ctx->username); ++ if (ret == EEXIST) { ++ DEBUG(SSSDBG_TRACE_FUNC, "User [%s@%s] filtered out (ncache)\n", ++ cmd_ctx->username, dom_ctx->domain->name); ++ ret = ENOENT; ++ goto done; ++ } ++ + ret = sudosrv_get_sudorules(dom_ctx); + + done: +diff --git a/src/responder/sudo/sudosrv_private.h b/src/responder/sudo/sudosrv_private.h +index 71a272ab4b06864738ac86b31e89a0c45658665b..3c53755f9e8ec56f3dea52021d14b50f715a54e7 100644 +--- a/src/responder/sudo/sudosrv_private.h ++++ b/src/responder/sudo/sudosrv_private.h +@@ -43,6 +43,9 @@ enum sss_sudo_type { + struct sudo_ctx { + struct resp_ctx *rctx; + ++ int neg_timeout; ++ struct sss_nc_ctx *ncache; ++ + /* + * options + */ +-- +2.4.0 + diff --git a/0062-AD-Clean-up-ad_access_gpo.patch b/0062-AD-Clean-up-ad_access_gpo.patch new file mode 100644 index 0000000..5149021 --- /dev/null +++ b/0062-AD-Clean-up-ad_access_gpo.patch @@ -0,0 +1,59 @@ +From d7efa39ab732fb034f51501cb2b1b8d3b1716979 Mon Sep 17 00:00:00 2001 +From: Stephen Gallagher +Date: Tue, 14 Apr 2015 13:07:36 -0400 +Subject: [PATCH 62/99] AD: Clean up ad_access_gpo + +Align goto usage with conventions in the rest of the source. + +Reviewed-by: Jakub Hrozek +(cherry picked from commit d9079aa05eb8aacb488992fdce328c1abadd08d8) +--- + src/providers/ad/ad_gpo.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c +index a881741a6ead9244ac123608234d1a0c35f830e3..54e5545a57b7e697f730431ae35a95ccabbe21db 100644 +--- a/src/providers/ad/ad_gpo.c ++++ b/src/providers/ad/ad_gpo.c +@@ -1534,8 +1534,6 @@ ad_gpo_access_send(TALLOC_CTX *mem_ctx, + + if (gpo_map_type == GPO_MAP_PERMIT) { + ret = EOK; +- tevent_req_done(req); +- tevent_req_post(req, ev); + goto immediately; + } + +@@ -1551,8 +1549,6 @@ ad_gpo_access_send(TALLOC_CTX *mem_ctx, + "ad_gpo_access_control option were set to enforcing " \ + "mode."); + ret = EOK; +- tevent_req_done(req); +- tevent_req_post(req, ev); + goto immediately; + default: + ret = EINVAL; +@@ -1592,15 +1588,17 @@ ad_gpo_access_send(TALLOC_CTX *mem_ctx, + } + tevent_req_set_callback(subreq, ad_gpo_connect_done, req); + +- ret = EOK; ++ return req; + + immediately: + +- if (ret != EOK) { ++ if (ret == EOK) { ++ tevent_req_done(req); ++ } else { + tevent_req_error(req, ret); +- tevent_req_post(req, ev); + } + ++ tevent_req_post(req, ev); + return req; + } + +-- +2.4.0 + diff --git a/0063-AD-Always-get-domain-specific-ID-connection.patch b/0063-AD-Always-get-domain-specific-ID-connection.patch new file mode 100644 index 0000000..e66da4e --- /dev/null +++ b/0063-AD-Always-get-domain-specific-ID-connection.patch @@ -0,0 +1,69 @@ +From 89a706acf3131bbe8c0aefa9c740dd44e892754f Mon Sep 17 00:00:00 2001 +From: Stephen Gallagher +Date: Tue, 14 Apr 2015 21:50:36 -0400 +Subject: [PATCH 63/99] AD: Always get domain-specific ID connection + +ad_get_dom_ldap_conn() assumed that ad_ctx->ldap_ctx always points at +the LDAP connection for the primary domain, however it turns out that +this is not always the case. It's currently unclear why, but this +connection can sometimes be pointing at a subdomain. Since the value of +subdom_id_ctx->ldap_ctx always points to the correct domain (including +the primary domain case), there's no benefit to trying to shortcut to +the ad_ctx->ldap_ctx when performing this lookup. + +This patch also makes a minor tweak to the tests so that the primary +domain passes the sdap_domain_get() check for validity (since it needs +to have a private member assigned). + +Reviewed-by: Jakub Hrozek +(cherry picked from commit e2bd4f8a41b72aea0712ad21ad02ccebb707f536) +--- + src/providers/ad/ad_common.c | 18 +++++++----------- + src/tests/cmocka/test_ad_common.c | 1 + + 2 files changed, 8 insertions(+), 11 deletions(-) + +diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c +index 120878977d08aab04bbd9e3cf87a00a4b018b6e4..5eeb8dd74d1df89a1a0afa50560b8341b0088778 100644 +--- a/src/providers/ad/ad_common.c ++++ b/src/providers/ad/ad_common.c +@@ -1140,18 +1140,14 @@ ad_get_dom_ldap_conn(struct ad_id_ctx *ad_ctx, struct sss_domain_info *dom) + struct sdap_domain *sdom; + struct ad_id_ctx *subdom_id_ctx; + +- if (IS_SUBDOMAIN(dom)) { +- sdom = sdap_domain_get(ad_ctx->sdap_id_ctx->opts, dom); +- if (sdom == NULL || sdom->pvt == NULL) { +- DEBUG(SSSDBG_CRIT_FAILURE, "No ID ctx available for [%s].\n", +- dom->name); +- return NULL; +- } +- subdom_id_ctx = talloc_get_type(sdom->pvt, struct ad_id_ctx); +- conn = subdom_id_ctx->ldap_ctx; +- } else { +- conn = ad_ctx->ldap_ctx; ++ sdom = sdap_domain_get(ad_ctx->sdap_id_ctx->opts, dom); ++ if (sdom == NULL || sdom->pvt == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "No ID ctx available for [%s].\n", ++ dom->name); ++ return NULL; + } ++ subdom_id_ctx = talloc_get_type(sdom->pvt, struct ad_id_ctx); ++ conn = subdom_id_ctx->ldap_ctx; + + return conn; + } +diff --git a/src/tests/cmocka/test_ad_common.c b/src/tests/cmocka/test_ad_common.c +index 19a4d395ba3fc4eae6601b3ad7056c41384a5c4f..1c44bc34b9350c4c7bca1dfb3fedd3184d7f14f2 100644 +--- a/src/tests/cmocka/test_ad_common.c ++++ b/src/tests/cmocka/test_ad_common.c +@@ -94,6 +94,7 @@ ad_common_test_setup(void **state) + + ret = sdap_domain_add(ad_ctx->sdap_id_ctx->opts, test_ctx->dom, &sdom); + assert_int_equal(ret, EOK); ++ sdom->pvt = ad_ctx; + + subdom_ad_ctx = talloc_zero(test_ctx, struct ad_id_ctx); + assert_non_null(subdom_ad_ctx); +-- +2.4.0 + diff --git a/0064-AD-GPO-Always-look-up-GPOs-from-machine-domain.patch b/0064-AD-GPO-Always-look-up-GPOs-from-machine-domain.patch new file mode 100644 index 0000000..badffcc --- /dev/null +++ b/0064-AD-GPO-Always-look-up-GPOs-from-machine-domain.patch @@ -0,0 +1,217 @@ +From b025f8a22cab47ac1f705a872917e3da0799fdd9 Mon Sep 17 00:00:00 2001 +From: Stephen Gallagher +Date: Fri, 10 Apr 2015 16:34:37 -0400 +Subject: [PATCH 64/99] AD GPO: Always look up GPOs from machine domain + +When dealing with users from a child domain, SSSD was attempting to use +the subdomain for lookups. However, all GPOs applicable to this machine +are stored in the primary domain (the domain the host directly joined). + +This patch has the GPO processing use the primary domain instead of the +user domain. + +Resolves: +https://fedorahosted.org/sssd/ticket/2606 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 475d986b534c5e0dfdb8e2348ab89b13fd4874aa) +--- + src/providers/ad/ad_gpo.c | 54 +++++++++++++++++++++++++++++------------------ + 1 file changed, 33 insertions(+), 21 deletions(-) + +diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c +index 54e5545a57b7e697f730431ae35a95ccabbe21db..990acf94ae6d8fbd8f0e512354d22e1d0a71c292 100644 +--- a/src/providers/ad/ad_gpo.c ++++ b/src/providers/ad/ad_gpo.c +@@ -1401,7 +1401,8 @@ ad_gpo_perform_hbac_processing(TALLOC_CTX *mem_ctx, + enum gpo_access_control_mode gpo_mode, + enum gpo_map_type gpo_map_type, + const char *user, +- struct sss_domain_info *domain) ++ struct sss_domain_info *user_domain, ++ struct sss_domain_info *host_domain) + { + int ret; + const char *allow_key = NULL; +@@ -1416,7 +1417,7 @@ ad_gpo_perform_hbac_processing(TALLOC_CTX *mem_ctx, + deny_key = gpo_map_option_entries[gpo_map_type].deny_key; + DEBUG(SSSDBG_TRACE_ALL, "deny_key: %s\n", deny_key); + +- ret = parse_policy_setting_value(mem_ctx, domain, allow_key, ++ ret = parse_policy_setting_value(mem_ctx, host_domain, allow_key, + &allow_sids, &allow_size); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, +@@ -1426,7 +1427,7 @@ ad_gpo_perform_hbac_processing(TALLOC_CTX *mem_ctx, + goto done; + } + +- ret = parse_policy_setting_value(mem_ctx, domain, deny_key, ++ ret = parse_policy_setting_value(mem_ctx, host_domain, deny_key, + &deny_sids, &deny_size); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, +@@ -1437,8 +1438,9 @@ ad_gpo_perform_hbac_processing(TALLOC_CTX *mem_ctx, + } + + /* perform access check with the final resultant allow_sids and deny_sids */ +- ret = ad_gpo_access_check(mem_ctx, gpo_mode, gpo_map_type, user, domain, +- allow_sids, allow_size, deny_sids, deny_size); ++ ret = ad_gpo_access_check(mem_ctx, gpo_mode, gpo_map_type, user, ++ user_domain, allow_sids, allow_size, deny_sids, ++ deny_size); + + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, +@@ -1463,7 +1465,8 @@ struct ad_gpo_access_state { + char *server_hostname; + struct sdap_options *opts; + int timeout; +- struct sss_domain_info *domain; ++ struct sss_domain_info *user_domain; ++ struct sss_domain_info *host_domain; + const char *user; + int gpo_timeout_option; + const char *ad_hostname; +@@ -1556,8 +1559,13 @@ ad_gpo_access_send(TALLOC_CTX *mem_ctx, + } + } + ++ /* GPO Operations all happen against the enrolled domain, ++ * not the user's domain (which may be a trusted realm) ++ */ ++ state->user_domain = domain; ++ state->host_domain = get_domains_head(domain); ++ + state->gpo_map_type = gpo_map_type; +- state->domain = domain; + state->dacl_filtered_gpos = NULL; + state->num_dacl_filtered_gpos = 0; + state->cse_filtered_gpos = NULL; +@@ -1565,13 +1573,13 @@ ad_gpo_access_send(TALLOC_CTX *mem_ctx, + state->cse_gpo_index = 0; + state->ev = ev; + state->user = user; +- state->ldb_ctx = sysdb_ctx_get_ldb(domain->sysdb); ++ state->ldb_ctx = sysdb_ctx_get_ldb(state->host_domain->sysdb); + state->gpo_mode = ctx->gpo_access_control_mode; + state->gpo_timeout_option = ctx->gpo_cache_timeout; + state->ad_hostname = dp_opt_get_string(ctx->ad_options, AD_HOSTNAME); + state->opts = ctx->sdap_access_ctx->id_ctx->opts; + state->timeout = dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT); +- state->conn = ad_get_dom_ldap_conn(ctx->ad_id_ctx, domain); ++ state->conn = ad_get_dom_ldap_conn(ctx->ad_id_ctx, state->host_domain); + state->sdap_op = sdap_id_op_create(state, state->conn->conn_cache); + if (state->sdap_op == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed.\n"); +@@ -1606,7 +1614,8 @@ static errno_t + process_offline_gpos(TALLOC_CTX *mem_ctx, + const char *user, + enum gpo_access_control_mode gpo_mode, +- struct sss_domain_info *domain, ++ struct sss_domain_info *user_domain, ++ struct sss_domain_info *host_domain, + enum gpo_map_type gpo_map_type) + + { +@@ -1616,7 +1625,8 @@ process_offline_gpos(TALLOC_CTX *mem_ctx, + gpo_mode, + gpo_map_type, + user, +- domain); ++ user_domain, ++ host_domain); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "HBAC processing failed: [%d](%s}\n", + ret, sss_strerror(ret)); +@@ -1662,7 +1672,8 @@ ad_gpo_connect_done(struct tevent_req *subreq) + ret = process_offline_gpos(state, + state->user, + state->gpo_mode, +- state->domain, ++ state->user_domain, ++ state->host_domain, + state->gpo_map_type); + + if (ret == EOK) { +@@ -1714,11 +1725,11 @@ ad_gpo_connect_done(struct tevent_req *subreq) + DEBUG(SSSDBG_TRACE_FUNC, "sam_account_name is %s\n", sam_account_name); + + /* Convert the domain name into domain DN */ +- ret = domain_to_basedn(state, state->domain->name, &domain_dn); ++ ret = domain_to_basedn(state, state->host_domain->name, &domain_dn); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Cannot convert domain name [%s] to base DN [%d]: %s\n", +- state->domain->name, ret, sss_strerror(ret)); ++ state->host_domain->name, ret, sss_strerror(ret)); + goto done; + } + +@@ -1837,7 +1848,7 @@ ad_gpo_target_dn_retrieval_done(struct tevent_req *subreq) + state->opts, + state->timeout, + state->target_dn, +- state->domain->name); ++ state->host_domain->name); + if (subreq == NULL) { + ret = ENOMEM; + goto done; +@@ -1939,7 +1950,7 @@ ad_gpo_process_gpo_done(struct tevent_req *subreq) + goto done; + } + +- ret = ad_gpo_filter_gpos_by_dacl(state, state->user, state->domain, ++ ret = ad_gpo_filter_gpos_by_dacl(state, state->user, state->user_domain, + state->opts->idmap_ctx->map, + candidate_gpos, num_candidate_gpos, + &state->dacl_filtered_gpos, +@@ -2014,7 +2025,7 @@ ad_gpo_process_gpo_done(struct tevent_req *subreq) + * subsequent functions will add the GPO Result object (and populate it + * with resultant policy settings) for this policy application + */ +- ret = sysdb_gpo_delete_gpo_result_object(state, state->domain); ++ ret = sysdb_gpo_delete_gpo_result_object(state, state->host_domain); + if (ret != EOK) { + switch (ret) { + case ENOENT: +@@ -2085,7 +2096,7 @@ ad_gpo_cse_step(struct tevent_req *req) + DEBUG(SSSDBG_TRACE_FUNC, "retrieving GPO from cache [%s]\n", + cse_filtered_gpo->gpo_guid); + ret = sysdb_gpo_get_gpo_by_guid(state, +- state->domain, ++ state->host_domain, + cse_filtered_gpo->gpo_guid, + &res); + if (ret == EOK) { +@@ -2127,7 +2138,7 @@ ad_gpo_cse_step(struct tevent_req *req) + subreq = ad_gpo_process_cse_send(state, + state->ev, + send_to_child, +- state->domain, ++ state->host_domain, + cse_filtered_gpo->gpo_guid, + cse_filtered_gpo->smb_server, + cse_filtered_gpo->smb_share, +@@ -2180,7 +2191,7 @@ ad_gpo_cse_done(struct tevent_req *subreq) + * GPO CACHE, we store all of the supported keys present in the file + * (as part of the GPO Result object in the sysdb cache). + */ +- ret = ad_gpo_store_policy_settings(state->domain, ++ ret = ad_gpo_store_policy_settings(state->host_domain, + cse_filtered_gpo->policy_filename); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, +@@ -2198,7 +2209,8 @@ ad_gpo_cse_done(struct tevent_req *subreq) + state->gpo_mode, + state->gpo_map_type, + state->user, +- state->domain); ++ state->user_domain, ++ state->host_domain); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "HBAC processing failed: [%d](%s}\n", + ret, sss_strerror(ret)); +-- +2.4.0 + diff --git a/0065-tests-Use-cmocka-1.0-API-in-test_sysdb_utils.patch b/0065-tests-Use-cmocka-1.0-API-in-test_sysdb_utils.patch new file mode 100644 index 0000000..857f01d --- /dev/null +++ b/0065-tests-Use-cmocka-1.0-API-in-test_sysdb_utils.patch @@ -0,0 +1,38 @@ +From bdb7e7f514629696e73902b2af3a93839be3e8a4 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Tue, 24 Mar 2015 11:17:20 +0100 +Subject: [PATCH 65/99] tests: Use cmocka-1.0+ API in test_sysdb_utils + +Reviewed-by: Pavel Reichl +(cherry picked from commit e2405de14e2fb3d58af4108ecc2726818e6c7c71) +--- + src/tests/cmocka/test_sysdb_utils.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/tests/cmocka/test_sysdb_utils.c b/src/tests/cmocka/test_sysdb_utils.c +index d217314ccb9234f8d0d329d87c5dc9e847acbcf0..1e9baa88cd82e7631a1de3db7f567f1f050ca67b 100644 +--- a/src/tests/cmocka/test_sysdb_utils.c ++++ b/src/tests/cmocka/test_sysdb_utils.c +@@ -106,8 +106,8 @@ int main(int argc, const char *argv[]) + POPT_TABLEEND + }; + +- const UnitTest tests[] = { +- unit_test(test_sysdb_handle_original_uuid), ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(test_sysdb_handle_original_uuid), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +@@ -128,7 +128,7 @@ int main(int argc, const char *argv[]) + DEBUG_CLI_INIT(debug_level); + + tests_set_cwd(); +- rv = run_tests(tests); ++ rv = cmocka_run_group_tests(tests, NULL, NULL); + + return rv; + } +-- +2.4.0 + diff --git a/0066-sysdb-Add-cache_expire-to-the-default-sysdb_search_o.patch b/0066-sysdb-Add-cache_expire-to-the-default-sysdb_search_o.patch new file mode 100644 index 0000000..726da21 --- /dev/null +++ b/0066-sysdb-Add-cache_expire-to-the-default-sysdb_search_o.patch @@ -0,0 +1,32 @@ +From c61b3f050d82785525c845b839f545b5114b47f5 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Mon, 30 Mar 2015 12:18:23 +0200 +Subject: [PATCH 66/99] sysdb: Add cache_expire to the default + sysdb_search_object_by_str_attr set +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Lukáš Slebodník +(cherry picked from commit ce6f3b6b2925d2c3ec02a76c3a1b6fbe4c7b145e) +--- + src/db/sysdb_ops.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c +index 37529fd12c2c5c6896a2ca71293a61f93ba0eee3..ea786d59158eb8a82952c7e457ea83286abbf2c4 100644 +--- a/src/db/sysdb_ops.c ++++ b/src/db/sysdb_ops.c +@@ -3543,7 +3543,8 @@ static errno_t sysdb_search_object_by_str_attr(TALLOC_CTX *mem_ctx, + TALLOC_CTX *tmp_ctx; + const char *def_attrs[] = { SYSDB_NAME, SYSDB_UIDNUM, SYSDB_GIDNUM, + ORIGINALAD_PREFIX SYSDB_NAME, +- SYSDB_OBJECTCLASS, NULL }; ++ SYSDB_DEFAULT_ATTRS, ++ NULL }; + struct ldb_dn *basedn; + int ret; + struct ldb_result *res = NULL; +-- +2.4.0 + diff --git a/0067-IPA-do-not-try-to-save-override-data-for-the-default.patch b/0067-IPA-do-not-try-to-save-override-data-for-the-default.patch new file mode 100644 index 0000000..3f22c2d --- /dev/null +++ b/0067-IPA-do-not-try-to-save-override-data-for-the-default.patch @@ -0,0 +1,47 @@ +From 3453e4734d2f7738034af61edb7d33c0c7095d8a Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Wed, 22 Apr 2015 15:10:07 +0200 +Subject: [PATCH 67/99] IPA: do not try to save override data for the default + view + +For the default view all override data is available in the cached user +or group object. Even if separate override data is available it should +not be written into the cache. + +Resolves https://fedorahosted.org/sssd/ticket/2630 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 2ab9a4538eb2e1a255e645f7efdcfd6bb722d265) +--- + src/providers/ipa/ipa_s2n_exop.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c +index a844ee99d25ec28bb02ec7b7fd0afa722b6ac189..b9de88984ea36d5010d5544258d7d0cc68bfa669 100644 +--- a/src/providers/ipa/ipa_s2n_exop.c ++++ b/src/providers/ipa/ipa_s2n_exop.c +@@ -2164,11 +2164,16 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom, + goto done; + } + +- ret = sysdb_store_override(dom, view_name, type, override_attrs, +- res->msgs[0]->dn); +- if (ret != EOK) { +- DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_override failed.\n"); +- goto done; ++ if (strcmp(view_name, SYSDB_DEFAULT_VIEW_NAME) != 0) { ++ /* For the default view the data return by the extdom plugin already ++ * contains all needed data and it is not expected to have a separate ++ * override object. */ ++ ret = sysdb_store_override(dom, view_name, type, override_attrs, ++ res->msgs[0]->dn); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_override failed.\n"); ++ goto done; ++ } + } + + done: +-- +2.4.0 + diff --git a/0068-IPA-use-sysdb_attrs_add_string_safe-to-add-group-mem.patch b/0068-IPA-use-sysdb_attrs_add_string_safe-to-add-group-mem.patch new file mode 100644 index 0000000..2c5cec6 --- /dev/null +++ b/0068-IPA-use-sysdb_attrs_add_string_safe-to-add-group-mem.patch @@ -0,0 +1,37 @@ +From 7752046aea558e4fbf057d4efc9aea1a61b1e009 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 3 Apr 2015 12:12:34 +0200 +Subject: [PATCH 68/99] IPA: use sysdb_attrs_add_string_safe to add group + member + +The member list returned by the extdom plugin might contain some entries +more than once. Although this is an issue on the server side to avoid +ldb errors duplicates should be filtered out on the client as well. + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 625cff0b0938538e51fdd3b2d985e6082b492ea5) +--- + src/providers/ipa/ipa_s2n_exop.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c +index b9de88984ea36d5010d5544258d7d0cc68bfa669..688fdefe8eefe29a0cd13010bb3998527f3111f4 100644 +--- a/src/providers/ipa/ipa_s2n_exop.c ++++ b/src/providers/ipa/ipa_s2n_exop.c +@@ -1300,10 +1300,11 @@ static errno_t process_members(struct sss_domain_info *domain, + DEBUG(SSSDBG_TRACE_ALL, "Adding member [%s][%s]\n", + members[c], dn_str); + +- ret = sysdb_attrs_add_string(group_attrs, SYSDB_MEMBER, dn_str); ++ ret = sysdb_attrs_add_string_safe(group_attrs, SYSDB_MEMBER, ++ dn_str); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, +- "sysdb_attrs_add_string failed.\n"); ++ "sysdb_attrs_add_string_safe failed.\n"); + goto done; + } + } +-- +2.4.0 + diff --git a/0069-IPA-check-ghosts-in-groups-found-by-uuid-as-well.patch b/0069-IPA-check-ghosts-in-groups-found-by-uuid-as-well.patch new file mode 100644 index 0000000..66932db --- /dev/null +++ b/0069-IPA-check-ghosts-in-groups-found-by-uuid-as-well.patch @@ -0,0 +1,64 @@ +From 1b2119aab14a4ea3ca6de0d29a661b2825bfec8d Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 24 Apr 2015 17:07:22 +0200 +Subject: [PATCH 69/99] IPA: check ghosts in groups found by uuid as well + +With views and overrides groups are not allowed to have ghost members +anymore because the name of a member might be overridden. To achieve +this ghost members are looked up and resolved later during group +lookups. Currently this is only done for group lookups by name but +should happen as well if the group is looked up by uuid. + +Resolves https://fedorahosted.org/sssd/ticket/2631 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 605dc7fcc848dffb7c9d270c864c70e6dff1242e) +--- + src/providers/ipa/ipa_id.c | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +diff --git a/src/providers/ipa/ipa_id.c b/src/providers/ipa/ipa_id.c +index 384e39a31022b1ec47c3d1abf19e8630762a5da6..38ac4904dcd97c3e241b28143e1f7b8fade37d70 100644 +--- a/src/providers/ipa/ipa_id.c ++++ b/src/providers/ipa/ipa_id.c +@@ -789,10 +789,21 @@ static void ipa_id_get_account_info_orig_done(struct tevent_req *subreq) + goto fail; + } + ++ class = ldb_msg_find_attr_as_string(state->obj_msg, SYSDB_OBJECTCLASS, ++ NULL); ++ if (class == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find an objectclass.\n"); ++ ret = EINVAL; ++ goto fail; ++ } ++ ++ + if (state->ipa_ctx->view_name != NULL && + strcmp(state->ipa_ctx->view_name, SYSDB_DEFAULT_VIEW_NAME) != 0) { + +- if ((state->ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_GROUP) { ++ if ((state->ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_GROUP ++ || ((state->ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_BY_UUID ++ && strcmp(class, SYSDB_GROUP_CLASS) == 0)) { + /* check for ghost members because ghost members are not allowed + * if a view other than the default view is applied.*/ + state->ghosts = ldb_msg_find_element(state->obj_msg, SYSDB_GHOST); +@@ -840,14 +851,6 @@ static void ipa_id_get_account_info_orig_done(struct tevent_req *subreq) + tevent_req_set_callback(subreq, ipa_id_get_account_info_done, req); + return; + } else { +- class = ldb_msg_find_attr_as_string(state->obj_msg, SYSDB_OBJECTCLASS, +- NULL); +- if (class == NULL) { +- DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find an objectclass.\n"); +- ret = EINVAL; +- goto fail; +- } +- + if (strcmp(class, SYSDB_USER_CLASS) == 0) { + type = SYSDB_MEMBER_USER; + } else { +-- +2.4.0 + diff --git a/0070-simple-access-provider-make-user-grp-res-more-robust.patch b/0070-simple-access-provider-make-user-grp-res-more-robust.patch new file mode 100644 index 0000000..66d10d7 --- /dev/null +++ b/0070-simple-access-provider-make-user-grp-res-more-robust.patch @@ -0,0 +1,117 @@ +From 45a089a7bcf54e27fb46dc1a2c08c21ac07db96a Mon Sep 17 00:00:00 2001 +From: Pavel Reichl +Date: Mon, 20 Apr 2015 11:33:29 -0400 +Subject: [PATCH 70/99] simple-access-provider: make user grp res more robust + +Not all user groups need to be resolved if group deny list is empty. + +Resolves: +https://fedorahosted.org/sssd/ticket/2519 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 82a958e6592c4a4078e45b7197bbe4751b70f511) +--- + src/providers/simple/simple_access_check.c | 26 ++++++++++++++++++++++---- + src/util/util_errors.c | 1 + + src/util/util_errors.h | 1 + + 3 files changed, 24 insertions(+), 4 deletions(-) + +diff --git a/src/providers/simple/simple_access_check.c b/src/providers/simple/simple_access_check.c +index c8217f6d4ef2560931d3151276085eb2a6028be5..14d833be2bccda9ded3b04b881b09fd0be6684bf 100644 +--- a/src/providers/simple/simple_access_check.c ++++ b/src/providers/simple/simple_access_check.c +@@ -395,6 +395,8 @@ struct simple_check_groups_state { + + const char **group_names; + size_t num_names; ++ ++ bool failed_to_resolve_groups; + }; + + static void simple_check_get_groups_next(struct tevent_req *subreq); +@@ -430,6 +432,7 @@ simple_check_get_groups_send(TALLOC_CTX *mem_ctx, + + state->ev = ev; + state->ctx = ctx; ++ state->failed_to_resolve_groups = false; + + DEBUG(SSSDBG_TRACE_LIBS, "Looking up groups for user %s\n", username); + +@@ -548,11 +551,10 @@ static void simple_check_get_groups_next(struct tevent_req *subreq) + DEBUG(SSSDBG_OP_FAILURE, + "Could not resolve name of group with GID %"SPRIgid"\n", + state->lookup_groups[state->giter].gid); +- tevent_req_error(req, ret); +- return; ++ state->failed_to_resolve_groups = true; ++ } else { ++ state->num_names++; + } +- +- state->num_names++; + state->giter++; + + if (state->giter < state->num_groups) { +@@ -686,6 +688,9 @@ simple_check_get_groups_recv(struct tevent_req *req, + TEVENT_REQ_RETURN_ON_ERROR(req); + + *_group_names = talloc_steal(mem_ctx, state->group_names); ++ if (state->failed_to_resolve_groups) { ++ return ERR_SIMPLE_GROUPS_MISSING; ++ } + return EOK; + } + +@@ -775,12 +780,25 @@ static void simple_access_check_done(struct tevent_req *subreq) + + /* We know the names now. Run the check. */ + ret = simple_check_get_groups_recv(subreq, state, &state->group_names); ++ + talloc_zfree(subreq); + if (ret == ENOENT) { + /* If the user wasn't found, just shortcut */ + state->access_granted = false; + tevent_req_done(req); + return; ++ } else if (ret == ERR_SIMPLE_GROUPS_MISSING) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "Could not collect groups of user %s\n", state->username); ++ if (state->ctx->deny_groups == NULL) { ++ DEBUG(SSSDBG_TRACE_FUNC, ++ "But no deny groups were defined so we can continue.\n"); ++ } else { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "Some deny groups were defined, we can't continue\n"); ++ tevent_req_error(req, ret); ++ return; ++ } + } else if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Could not collect groups of user %s\n", state->username); +diff --git a/src/util/util_errors.c b/src/util/util_errors.c +index b481210aa21e05eda3a4c5b0699836d085baa892..4f9a2e7001695e0babe8342c497480b325f3322a 100644 +--- a/src/util/util_errors.c ++++ b/src/util/util_errors.c +@@ -71,6 +71,7 @@ struct err_string error_to_str[] = { + { "Time specification not supported" }, /* ERR_TIMESPEC_NOT_SUPPORTED */ + { "Malformed cache entry" }, /* ERR_MALFORMED_ENTRY */ + { "Unexpected cache entry type" }, /* ERR_UNEXPECTED_ENTRY_TYPE */ ++ { "Failed to resolve one of user groups." }, /* ERR_SIMPLE_GROUPS_MISSING */ + { "ERR_LAST" } /* ERR_LAST */ + }; + +diff --git a/src/util/util_errors.h b/src/util/util_errors.h +index b6a667fffbbddc77de53e501e185defbd30b23e0..5842a71550a7d14342f976c69f117f41bee1f531 100644 +--- a/src/util/util_errors.h ++++ b/src/util/util_errors.h +@@ -93,6 +93,7 @@ enum sssd_errors { + ERR_TIMESPEC_NOT_SUPPORTED, + ERR_MALFORMED_ENTRY, + ERR_UNEXPECTED_ENTRY_TYPE, ++ ERR_SIMPLE_GROUPS_MISSING, + ERR_LAST /* ALWAYS LAST */ + }; + +-- +2.4.0 + diff --git a/0071-IPA-allow-initgroups-by-SID-for-AD-users.patch b/0071-IPA-allow-initgroups-by-SID-for-AD-users.patch new file mode 100644 index 0000000..2277f18 --- /dev/null +++ b/0071-IPA-allow-initgroups-by-SID-for-AD-users.patch @@ -0,0 +1,205 @@ +From 85287a6b897d818d279171a83aa3c8a0de66f13b Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Wed, 22 Apr 2015 16:57:37 +0200 +Subject: [PATCH 71/99] IPA: allow initgroups by SID for AD users + +If a user from a trusted AD domain is search with the help of an +override name the SID from the override anchor is used to search the +user in AD. Currently the initgroups request only allows searches by +name. With this patch a SID can be used as well. + +Resolves https://fedorahosted.org/sssd/ticket/2632 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit f70a1adbfc30b9acc302027439fb8157e0c6ea2a) +--- + src/db/sysdb_search.c | 24 ++++++++++++++++-------- + src/providers/data_provider.h | 1 + + src/providers/ipa/ipa_subdomains_id.c | 13 +++++++++++++ + src/providers/ldap/ldap_id.c | 15 +++++++++++++-- + src/providers/ldap/sdap_async_initgroups.c | 2 ++ + src/tests/sysdb-tests.c | 12 +++++++++++- + 6 files changed, 56 insertions(+), 11 deletions(-) + +diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c +index 677257405fae51774d4cd0c17516238e74fb7592..da0c6d90c6b3a88cfa928aaffa2c8eb843cb1a74 100644 +--- a/src/db/sysdb_search.c ++++ b/src/db/sysdb_search.c +@@ -1589,7 +1589,7 @@ done: + + errno_t sysdb_get_real_name(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, +- const char *name_or_upn, ++ const char *name_or_upn_or_sid, + const char **_cname) + { + errno_t ret; +@@ -1603,20 +1603,28 @@ errno_t sysdb_get_real_name(TALLOC_CTX *mem_ctx, + return ENOMEM; + } + +- ret = sysdb_getpwnam(tmp_ctx, domain, name_or_upn, &res); ++ ret = sysdb_getpwnam(tmp_ctx, domain, name_or_upn_or_sid, &res); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Cannot canonicalize username\n"); + goto done; + } + + if (res->count == 0) { +- ret = sysdb_search_user_by_upn(tmp_ctx, domain, name_or_upn, NULL, +- &msg); ++ ret = sysdb_search_user_by_upn(tmp_ctx, domain, name_or_upn_or_sid, ++ NULL, &msg); + if (ret != EOK) { +- /* User cannot be found in cache */ +- DEBUG(SSSDBG_OP_FAILURE, "Cannot find user [%s] in cache\n", +- name_or_upn); +- goto done; ++ if (ret == ENOENT) { ++ ret = sysdb_search_user_by_sid_str(tmp_ctx, domain, ++ name_or_upn_or_sid, NULL, ++ &msg); ++ } ++ ++ if (ret != EOK) { ++ /* User cannot be found in cache */ ++ DEBUG(SSSDBG_OP_FAILURE, "Cannot find user [%s] in cache\n", ++ name_or_upn_or_sid); ++ goto done; ++ } + } + } else if (res->count == 1) { + msg = res->msgs[0]; +diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h +index 5df493e9d1ae21ada6f5fd6198a6d9c36680d044..89fb06a0d6f791a8ae50f9d8b4b69d6176912c6c 100644 +--- a/src/providers/data_provider.h ++++ b/src/providers/data_provider.h +@@ -150,6 +150,7 @@ + #define DP_SEC_ID_LEN (sizeof(DP_SEC_ID) - 1) + + #define EXTRA_NAME_IS_UPN "U" ++#define EXTRA_NAME_IS_SID "S" + #define EXTRA_INPUT_MAYBE_WITH_VIEW "V" + + /* AUTH related common data and functions */ +diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c +index 0508e14b690c144f4bace9ed14a326ac724eb910..15776d2e13af158058a874f761671a5801cf3d6a 100644 +--- a/src/providers/ipa/ipa_subdomains_id.c ++++ b/src/providers/ipa/ipa_subdomains_id.c +@@ -201,6 +201,7 @@ static void ipa_subdomain_account_got_override(struct tevent_req *subreq) + } + + if (state->override_attrs != NULL) { ++ DEBUG(SSSDBG_TRACE_ALL, "Processing override.\n"); + ret = sysdb_attrs_get_string(state->override_attrs, + SYSDB_OVERRIDE_ANCHOR_UUID, + &anchor); +@@ -219,6 +220,16 @@ static void ipa_subdomain_account_got_override(struct tevent_req *subreq) + DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_sid failed.\n"); + goto fail; + } ++ ++ if (state->ipa_server_mode ++ && (state->ar->entry_type & BE_REQ_TYPE_MASK) ++ == BE_REQ_INITGROUPS) { ++ DEBUG(SSSDBG_TRACE_ALL, ++ "Switching back to BE_REQ_INITGROUPS.\n"); ++ ar->entry_type = BE_REQ_INITGROUPS; ++ ar->filter_type = BE_FILTER_SECID; ++ ar->attr_type = BE_ATTR_CORE; ++ } + } else { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unsupported override anchor type [%s].\n", anchor); +@@ -1125,6 +1136,8 @@ static errno_t ipa_get_ad_apply_override_step(struct tevent_req *req) + + /* Replace ID with name in search filter */ + if ((entry_type == BE_REQ_USER && state->ar->filter_type == BE_FILTER_IDNUM) ++ || (entry_type == BE_REQ_INITGROUPS ++ && state->ar->filter_type == BE_FILTER_SECID) + || entry_type == BE_REQ_BY_SECID) { + if (state->obj_msg == NULL) { + ret = get_object_from_cache(state, state->obj_dom, state->ar, +diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c +index 55bb3c9fbd6f623e7795d7399c9e5ac4d5192e85..c2686d249ddf5448c3589c4d8afe32caf09c90a4 100644 +--- a/src/providers/ldap/ldap_id.c ++++ b/src/providers/ldap/ldap_id.c +@@ -1391,7 +1391,8 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, + break; + + case BE_REQ_INITGROUPS: /* init groups for user */ +- if (ar->filter_type != BE_FILTER_NAME) { ++ if (ar->filter_type != BE_FILTER_NAME ++ && ar->filter_type != BE_FILTER_SECID) { + ret = EINVAL; + state->err = "Invalid filter type"; + goto done; +@@ -1401,11 +1402,21 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, + state->err = "Invalid attr type"; + goto done; + } ++ if (ar->filter_type == BE_FILTER_SECID && ar->extra_value != NULL ++ && strcmp(ar->extra_value, EXTRA_NAME_IS_SID) != 0) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "Unexpected extra value [%s] for BE_FILTER_SECID.\n", ++ ar->extra_value); ++ ret = EINVAL; ++ state->err = "Invalid extra value"; ++ goto done; ++ } + + subreq = groups_by_user_send(state, be_ctx->ev, id_ctx, + sdom, conn, + ar->filter_value, +- ar->extra_value, ++ (ar->filter_type == BE_FILTER_SECID) ++ ? EXTRA_NAME_IS_SID : ar->extra_value, + noexist_delete); + break; + +diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c +index ae617b9c4c6899d0b85dcc4c4b6b971d0f235b88..5c5be5eabd7006b457291062519cdad9626f13fa 100644 +--- a/src/providers/ldap/sdap_async_initgroups.c ++++ b/src/providers/ldap/sdap_async_initgroups.c +@@ -2716,6 +2716,8 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, + + if (extra_value && strcmp(extra_value, EXTRA_NAME_IS_UPN) == 0) { + search_attr = state->opts->user_map[SDAP_AT_USER_PRINC].name; ++ } else if (extra_value && strcmp(extra_value, EXTRA_NAME_IS_SID) == 0) { ++ search_attr = state->opts->user_map[SDAP_AT_USER_OBJECTSID].name; + } else { + search_attr = state->opts->user_map[SDAP_AT_USER_NAME].name; + } +diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c +index 7c2c6d208127b0b6f9025435619b027246c6dd35..0185beeaf03d0fc72c9ead22bc73887c701d964f 100644 +--- a/src/tests/sysdb-tests.c ++++ b/src/tests/sysdb-tests.c +@@ -3577,6 +3577,10 @@ START_TEST(test_sysdb_get_real_name) + ret = sysdb_attrs_add_string(user_attrs, SYSDB_UPN, "foo@bar"); + fail_unless(ret == EOK, "sysdb_attrs_add_string failed."); + ++ ret = sysdb_attrs_add_string(user_attrs, SYSDB_SID_STR, ++ "S-1-5-21-123-456-789-111"); ++ fail_unless(ret == EOK, "sysdb_attrs_add_string failed."); ++ + ret = sysdb_store_user(test_ctx->domain, "RealName", + NULL, 22345, 0, "gecos", + "/home/realname", "/bin/bash", +@@ -3592,7 +3596,13 @@ START_TEST(test_sysdb_get_real_name) + ret = sysdb_get_real_name(test_ctx, test_ctx->domain, "foo@bar", &str); + fail_unless(ret == EOK, "sysdb_get_real_name failed."); + fail_unless(strcmp(str, "RealName") == 0, "Expected [%s], got [%s].", +- "foo@bar", str); ++ "RealName", str); ++ ++ ret = sysdb_get_real_name(test_ctx, test_ctx->domain, ++ "S-1-5-21-123-456-789-111", &str); ++ fail_unless(ret == EOK, "sysdb_get_real_name failed."); ++ fail_unless(strcmp(str, "RealName") == 0, "Expected [%s], got [%s].", ++ "RealName", str); + + } + END_TEST +-- +2.4.0 + diff --git a/0072-IPA-fix-segfault-in-ipa_s2n_exop.patch b/0072-IPA-fix-segfault-in-ipa_s2n_exop.patch new file mode 100644 index 0000000..d1e1101 --- /dev/null +++ b/0072-IPA-fix-segfault-in-ipa_s2n_exop.patch @@ -0,0 +1,31 @@ +From e31d5babfd036cf64c9179dc60bbd79f541ef89b Mon Sep 17 00:00:00 2001 +From: Aron Parsons +Date: Wed, 29 Apr 2015 03:19:32 +0000 +Subject: [PATCH 72/99] IPA: fix segfault in ipa_s2n_exop + +can be triggered on demand by assigning a POSIX group +with external members sudo privileges, then dropping +the cache and doing a sudo -U -l. + +Reviewed-by: Sumit Bose +(cherry picked from commit c520f40d1a2d77cf1d413451b5682297733521ed) +--- + src/providers/ipa/ipa_s2n_exop.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c +index 688fdefe8eefe29a0cd13010bb3998527f3111f4..d07923cffb49bbfeb7d500f281b1a2aff547ed1c 100644 +--- a/src/providers/ipa/ipa_s2n_exop.c ++++ b/src/providers/ipa/ipa_s2n_exop.c +@@ -2165,7 +2165,7 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom, + goto done; + } + +- if (strcmp(view_name, SYSDB_DEFAULT_VIEW_NAME) != 0) { ++ if (view_name != NULL && strcmp(view_name, SYSDB_DEFAULT_VIEW_NAME) != 0) { + /* For the default view the data return by the extdom plugin already + * contains all needed data and it is not expected to have a separate + * override object. */ +-- +2.4.0 + diff --git a/0073-autofs-fix-Cannot-allocate-memory-with-FQDNs.patch b/0073-autofs-fix-Cannot-allocate-memory-with-FQDNs.patch new file mode 100644 index 0000000..50ecf33 --- /dev/null +++ b/0073-autofs-fix-Cannot-allocate-memory-with-FQDNs.patch @@ -0,0 +1,36 @@ +From 8f57c6765b10de36582ef1dbee32d75452451a94 Mon Sep 17 00:00:00 2001 +From: Aron Parsons +Date: Wed, 29 Apr 2015 02:44:18 +0000 +Subject: [PATCH 73/99] autofs: fix 'Cannot allocate memory' with FQDNs + +https://fedorahosted.org/sssd/ticket/2643 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 4df706219e64527209f12ad0c7814ee1be979c07) +--- + src/responder/autofs/autofssrv_cmd.c | 9 --------- + 1 file changed, 9 deletions(-) + +diff --git a/src/responder/autofs/autofssrv_cmd.c b/src/responder/autofs/autofssrv_cmd.c +index 797e638d53a8adbac658541496bd0ab85d271533..27b6617c2dd2403aa50cf2c9d96886b3bfee7ea7 100644 +--- a/src/responder/autofs/autofssrv_cmd.c ++++ b/src/responder/autofs/autofssrv_cmd.c +@@ -628,15 +628,6 @@ lookup_automntmap_step(struct setautomntent_lookup_ctx *lookup_ctx) + + /* Check each domain for this map name */ + while (dom) { +- /* if it is a domainless search, skip domains that require fully +- * qualified names instead */ +- while (dom && dctx->cmd_ctx->check_next && dom->fqnames) { +- dom = get_next_domain(dom, false); +- } +- +- /* No domains left to search */ +- if (!dom) break; +- + if (dom != dctx->domain) { + /* make sure we reset the check_provider flag when we check + * a new domain */ +-- +2.4.0 + diff --git a/0074-GPO-Do-not-ignore-missing-attrs-for-GPOs.patch b/0074-GPO-Do-not-ignore-missing-attrs-for-GPOs.patch new file mode 100644 index 0000000..690a454 --- /dev/null +++ b/0074-GPO-Do-not-ignore-missing-attrs-for-GPOs.patch @@ -0,0 +1,57 @@ +From 7c8c34c1ad152892f93d8e01336258bfd0bc35b9 Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik +Date: Wed, 29 Apr 2015 09:17:18 +0200 +Subject: [PATCH 74/99] GPO: Do not ignore missing attrs for GPOs + +We don't want to skip over a GPO that might properly be denying +users. + +[sssd[be[a.foo.com]]] [sdap_sd_search_send] (0x0400): + Searching entry [cn={2BA15B73-9524-419F-B4B7-185E1F0D3DCF},cn=policies,cn=system,DC=foo,DC=com] using SD +[sssd[be[a.foo.com]]] [sdap_get_generic_ext_step] (0x0400): + calling ldap_search_ext with [(objectclass=*)][cn={2BA15B73-9524-419F-B4B7-185E1F0D3DCF},cn=policies,cn=system,DC=lzb,DC=hq]. +[sssd[be[a.foo.com]]] [sdap_process_message] (0x4000): + Message type: [LDAP_RES_SEARCH_RESULT] +[sssd[be[a.foo.com]]] [sdap_get_generic_op_finished] (0x0400): + Search result: Referral(10), 0000202B: RefErr: DSID-0310063C, data 0, 1 access points + ref 1: 'lzb.hq' +[sssd[be[a.foo.com]]] [sdap_get_generic_op_finished] (0x1000): + Ref: ldap://foo.com/cn=%7B2BA15B73-9524-419F-B4B7-185E1F0D3DCF%7D,cn=policies,cn=system,DC=foo,DC=com +[sssd[be[a.foo.com]]] [ad_gpo_get_gpo_attrs_done] (0x0040): + no attrs found for GPO; try next GPO. + +Resolves: +https://fedorahosted.org/sssd/ticket/2629 + +Reviewed-by: Stephen Gallagher +(cherry picked from commit 03e5f1528184a558fd990e66f083157b404dce08) +--- + src/providers/ad/ad_gpo.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c +index 990acf94ae6d8fbd8f0e512354d22e1d0a71c292..af864dfbe021438feceffd610cc0ad2b69ca670a 100644 +--- a/src/providers/ad/ad_gpo.c ++++ b/src/providers/ad/ad_gpo.c +@@ -3497,9 +3497,15 @@ ad_gpo_get_gpo_attrs_done(struct tevent_req *subreq) + } + + if ((num_results < 1) || (results == NULL)) { +- DEBUG(SSSDBG_OP_FAILURE, "no attrs found for GPO; try next GPO.\n"); +- state->gpo_index++; +- ret = ad_gpo_get_gpo_attrs_step(req); ++ const char *gpo_dn = state->candidate_gpos[state->gpo_index]->gpo_dn; ++ ++ DEBUG(SSSDBG_OP_FAILURE, ++ "BUG: No attrs found for GPO [%s]. This was likely caused by " ++ "the GPO entry being a referred to another domain controller." ++ " SSSD does not yet support this configuration. See upstream " ++ "ticket #2645 for more information.\n", ++ gpo_dn); ++ ret = ERR_INTERNAL; + goto done; + } + else if (num_results > 1) { +-- +2.4.0 + diff --git a/0075-sss_nss_idmap-tests-Use-different-prepared-buffers-f.patch b/0075-sss_nss_idmap-tests-Use-different-prepared-buffers-f.patch new file mode 100644 index 0000000..e6102c3 --- /dev/null +++ b/0075-sss_nss_idmap-tests-Use-different-prepared-buffers-f.patch @@ -0,0 +1,65 @@ +From 21d34cf3c25de9e39f3947059f65b56c8e7dbe25 Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik +Date: Mon, 4 May 2015 07:34:19 +0200 +Subject: [PATCH 75/99] sss_nss_idmap-tests: Use different prepared buffers for + big endian + +We get error EBADMSG instead of EOK due to endianess issue + +[==========] Running 2 test(s). +[ RUN ] test_getsidbyname +0x4a != 0 +src/tests/cmocka/sss_nss_idmap-tests.c:108: error: Failure! + +[ FAILED ] test_getsidbyname +[ RUN ] test_getorigbyname +0x4a != 0 +src/tests/cmocka/sss_nss_idmap-tests.c:127: error: Failure! + +[ FAILED ] test_getorigbyname + +Reviewed-by: Sumit Bose +(cherry picked from commit 582f6b1d15d216a39a66b70f0b3ecdf5b0f47673) +--- + src/tests/cmocka/sss_nss_idmap-tests.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/src/tests/cmocka/sss_nss_idmap-tests.c b/src/tests/cmocka/sss_nss_idmap-tests.c +index 4ba8f2f9265389d63983e44fe14f026c9a7b8d50..8807eca619d7b07d919168e5629042cf38f654ac 100644 +--- a/src/tests/cmocka/sss_nss_idmap-tests.c ++++ b/src/tests/cmocka/sss_nss_idmap-tests.c +@@ -28,6 +28,7 @@ + + + #include "util/util.h" ++#include "util/sss_endian.h" + + #include "sss_client/idmap/sss_nss_idmap.h" + #include "tests/cmocka/common_mock.h" +@@ -42,12 +43,23 @@ struct sss_nss_make_request_test_data { + enum nss_status nss_status; + }; + ++#if (__BYTE_ORDER == __LITTLE_ENDIAN) + uint8_t buf1[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 't', 'e', 's', 't', 0x00}; + uint8_t buf2[] = {0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 't', 'e', 's', 't', 0x00}; + uint8_t buf3[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 't', 'e', 's', 't', 0x00}; + uint8_t buf4[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 't', 'e', 's', 't', 'x'}; + + uint8_t buf_orig1[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 'k', 'e', 'y', 0x00, 'v', 'a', 'l', 'u', 'e', 0x00}; ++#elif (__BYTE_ORDER == __BIG_ENDIAN) ++uint8_t buf1[] = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 't', 'e', 's', 't', 0x00}; ++uint8_t buf2[] = {0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 't', 'e', 's', 't', 0x00}; ++uint8_t buf3[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 't', 'e', 's', 't', 0x00}; ++uint8_t buf4[] = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 't', 'e', 's', 't', 'x'}; ++ ++uint8_t buf_orig1[] = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 'k', 'e', 'y', 0x00, 'v', 'a', 'l', 'u', 'e', 0x00}; ++#else ++ #error "unknow endianess" ++#endif + + enum nss_status sss_nss_make_request(enum sss_cli_command cmd, + struct sss_cli_req_data *rd, +-- +2.4.0 + diff --git a/0076-SDAP-Fix-id-mapping-with-disabled-subdomains.patch b/0076-SDAP-Fix-id-mapping-with-disabled-subdomains.patch new file mode 100644 index 0000000..dc85648 --- /dev/null +++ b/0076-SDAP-Fix-id-mapping-with-disabled-subdomains.patch @@ -0,0 +1,65 @@ +From 2bf32678c96304d04e69813fd6d317d981ad2c41 Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik +Date: Tue, 28 Apr 2015 20:26:47 +0200 +Subject: [PATCH 76/99] SDAP: Fix id mapping with disabled subdomains +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If subdomains are disabled "subdomain_provider = none" +then auto-discovery discovery of domain SID is disabled. +It is possible to configure options ldap_idmap_default_domain{,_sid} +and id mapping should work. + +However value of option ldap_idmap_default_domain_sid was not assigned to +sss_domain_info for main domain. It was only used for initialisation of +sdap_idmap_ctx. As a result of this bug posix attributes were used in +ldap filter and id mapping worked just for users with posix attributes. + +[be_get_account_info] (0x0100): Got request for [0x1001][1][name=user] +[be_req_set_domain] (0x0400): + Changing request domain from [EXAMPLE.TEST] to [EXAMPLE.TEST] +[sdap_idmap_domain_has_algorithmic_mapping] (0x0080): + Could not parse domain SID from [(null)] +[sdap_idmap_domain_has_algorithmic_mapping] (0x0080): + Could not parse domain SID from [(null)] +[sdap_search_user_next_base] (0x0400): + Searching for users with base [DC=EXAMPLE,DC=TEST] +[sdap_get_generic_ext_step] (0x0400): + calling ldap_search_ext with + [(&(sAMAccountName=hdpadmin)(objectclass=user) + (sAMAccountName=*)(&(uidNumber=*)(!(uidNumber=0))))] + [DC=EXAMPLE,DC=TEST]. +[sdap_search_user_process] (0x0400): Search for users, returned 0 results. +[sdap_get_users_done] (0x0040): Failed to retrieve users + +Resolves: +https://fedorahosted.org/sssd/ticket/2635 + +Reviewed-by: Pavel Březina +(cherry picked from commit 21687d1d553579e81aa43bfa20f2e70fb39e8461) +--- + src/providers/ldap/sdap_idmap.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/providers/ldap/sdap_idmap.c b/src/providers/ldap/sdap_idmap.c +index 0a82e61f788b663e564d68c5d48bb705a33584eb..dd959b2c133b342f105f76c26c889d678ce40391 100644 +--- a/src/providers/ldap/sdap_idmap.c ++++ b/src/providers/ldap/sdap_idmap.c +@@ -288,6 +288,13 @@ sdap_idmap_init(TALLOC_CTX *mem_ctx, + + sid_str = dp_opt_get_string(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_DEFAULT_DOMAIN_SID); + if (sid_str) { ++ struct sss_domain_info *domain = idmap_ctx->id_ctx->be->domain; ++ domain->domain_id = talloc_strdup(domain, sid_str); ++ if (domain->domain_id == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } ++ + /* Set the default domain as slice 0 */ + ret = sdap_idmap_add_domain(idmap_ctx, dom_name, + sid_str, 0); +-- +2.4.0 + diff --git a/0077-IPA-do-initgroups-if-extdom-exop-supports-it.patch b/0077-IPA-do-initgroups-if-extdom-exop-supports-it.patch new file mode 100644 index 0000000..cbe8972 --- /dev/null +++ b/0077-IPA-do-initgroups-if-extdom-exop-supports-it.patch @@ -0,0 +1,99 @@ +From 24905d4ecbf210687e385449448f5a5ec97d2833 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Tue, 28 Apr 2015 17:18:48 +0200 +Subject: [PATCH 77/99] IPA: do initgroups if extdom exop supports it + +Newer versions of the extdom plugin return the full list of +group-memberships during a user lookup request. With these version there +is no need to reject a initgroups request for sub/trusted-domain users +anymore. This is e.g. useful for callers which call getgrouplist() +directly without calling getpwnam() before. Additionally it helps if for +some reasons the lifetime of the user entry and the lifetime of the +initgroups data is different. + +Related to https://fedorahosted.org/sssd/ticket/2633 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit e87badc0f6fb20a443cf12bde9582ecbc2aef727) +--- + src/providers/ipa/ipa_s2n_exop.c | 3 --- + src/providers/ipa/ipa_subdomains.h | 4 ++++ + src/providers/ipa/ipa_subdomains_id.c | 24 +++++++++++++++++------- + 3 files changed, 21 insertions(+), 10 deletions(-) + +diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c +index d07923cffb49bbfeb7d500f281b1a2aff547ed1c..3830a2b4b0a82f056b0992c260bef6fe718c10da 100644 +--- a/src/providers/ipa/ipa_s2n_exop.c ++++ b/src/providers/ipa/ipa_s2n_exop.c +@@ -50,9 +50,6 @@ enum response_types { + }; + + /* ==Sid2Name Extended Operation============================================= */ +-#define EXOP_SID2NAME_OID "2.16.840.1.113730.3.8.10.4" +-#define EXOP_SID2NAME_V1_OID "2.16.840.1.113730.3.8.10.4.1" +- + struct ipa_s2n_exop_state { + struct sdap_handle *sh; + +diff --git a/src/providers/ipa/ipa_subdomains.h b/src/providers/ipa/ipa_subdomains.h +index ceb862226b504bca6c9c596554fb88e6df1d51c3..9b179792dcab7ea935fa7159ca879d12b561a55f 100644 +--- a/src/providers/ipa/ipa_subdomains.h ++++ b/src/providers/ipa/ipa_subdomains.h +@@ -28,6 +28,10 @@ + #include "providers/dp_backend.h" + #include "providers/ipa/ipa_common.h" + ++/* ==Sid2Name Extended Operation============================================= */ ++#define EXOP_SID2NAME_OID "2.16.840.1.113730.3.8.10.4" ++#define EXOP_SID2NAME_V1_OID "2.16.840.1.113730.3.8.10.4.1" ++ + struct be_ctx *ipa_get_subdomains_be_ctx(struct be_ctx *be_ctx); + + const char *get_flat_name_from_subdomain_name(struct be_ctx *be_ctx, +diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c +index 15776d2e13af158058a874f761671a5801cf3d6a..1253510dcb8523c19d879d4351ffa07995f161f7 100644 +--- a/src/providers/ipa/ipa_subdomains_id.c ++++ b/src/providers/ipa/ipa_subdomains_id.c +@@ -386,15 +386,9 @@ struct tevent_req *ipa_get_subdom_acct_send(TALLOC_CTX *memctx, + case BE_REQ_GROUP: + case BE_REQ_BY_SECID: + case BE_REQ_USER_AND_GROUP: ++ case BE_REQ_INITGROUPS: + ret = EOK; + break; +- case BE_REQ_INITGROUPS: +- ret = ENOTSUP; +- DEBUG(SSSDBG_TRACE_FUNC, "Initgroups requests are not handled " \ +- "by the IPA provider but are resolved " \ +- "by the responder directly from the " \ +- "cache.\n"); +- break; + default: + ret = EINVAL; + DEBUG(SSSDBG_OP_FAILURE, "Invalid sub-domain request type.\n"); +@@ -434,6 +428,22 @@ static void ipa_get_subdom_acct_connected(struct tevent_req *subreq) + return; + } + ++ if (state->entry_type == BE_REQ_INITGROUPS) { ++ /* With V1 of the extdom plugin a user lookup will resolve the full ++ * group membership of the user. */ ++ if (sdap_is_extension_supported(sdap_id_op_handle(state->op), ++ EXOP_SID2NAME_V1_OID)) { ++ state->entry_type = BE_REQ_USER; ++ } else { ++ DEBUG(SSSDBG_TRACE_FUNC, "Initgroups requests are not handled " \ ++ "by the IPA provider but are resolved " \ ++ "by the responder directly from the " \ ++ "cache.\n"); ++ tevent_req_error(req, ENOTSUP); ++ return; ++ } ++ } ++ + req_input = talloc(state, struct req_input); + if (req_input == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc failed.\n"); +-- +2.4.0 + diff --git a/0078-IPA-update-initgr-expire-timestamp-conditionally.patch b/0078-IPA-update-initgr-expire-timestamp-conditionally.patch new file mode 100644 index 0000000..3cacccc --- /dev/null +++ b/0078-IPA-update-initgr-expire-timestamp-conditionally.patch @@ -0,0 +1,104 @@ +From f643fadbd072a9d3725f5f750340d5b13628ce6a Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Tue, 28 Apr 2015 17:20:05 +0200 +Subject: [PATCH 78/99] IPA: update initgr expire timestamp conditionally + +Newer versions of the extdom plugin return the full list of +group-memberships during user lookups. As a result the lifetime of the +group-membership data is updates in those cases. But if the user is not +looked up directly but is resolved as a group member during a group +lookup SSSD does not resolve all group-membership of the user to avoid +deep recursion and eventually a complete enumeration of the user and +group base. In this case the lifetime of the group-memberships should +not be updated because it might be incomplete. + +Related to https://fedorahosted.org/sssd/ticket/2633 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit cffe3135f29c737f2598f3c1384bfba1694fb843) +--- + src/providers/ipa/ipa_s2n_exop.c | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c +index 3830a2b4b0a82f056b0992c260bef6fe718c10da..daebd68853c2d8671b752edb8f2639f795093014 100644 +--- a/src/providers/ipa/ipa_s2n_exop.c ++++ b/src/providers/ipa/ipa_s2n_exop.c +@@ -685,7 +685,8 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom, + struct resp_attrs *attrs, + struct resp_attrs *simple_attrs, + const char *view_name, +- struct sysdb_attrs *override_attrs); ++ struct sysdb_attrs *override_attrs, ++ bool update_initgr_timeout); + + static errno_t s2n_response_to_attrs(TALLOC_CTX *mem_ctx, + char *retoid, +@@ -1118,7 +1119,7 @@ static errno_t ipa_s2n_get_fqlist_save_step(struct tevent_req *req) + + ret = ipa_s2n_save_objects(state->dom, &state->req_input, state->attrs, + NULL, state->ipa_ctx->view_name, +- state->override_attrs); ++ state->override_attrs, false); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_save_objects failed.\n"); + return ret; +@@ -1617,7 +1618,7 @@ static void ipa_s2n_get_user_done(struct tevent_req *subreq) + || strcmp(state->ipa_ctx->view_name, + SYSDB_DEFAULT_VIEW_NAME) == 0) { + ret = ipa_s2n_save_objects(state->dom, state->req_input, state->attrs, +- state->simple_attrs, NULL, NULL); ++ state->simple_attrs, NULL, NULL, true); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_save_objects failed.\n"); + goto done; +@@ -1739,7 +1740,8 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom, + struct resp_attrs *attrs, + struct resp_attrs *simple_attrs, + const char *view_name, +- struct sysdb_attrs *override_attrs) ++ struct sysdb_attrs *override_attrs, ++ bool update_initgr_timeout) + { + int ret; + time_t now; +@@ -1938,7 +1940,8 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom, + } + } + +- if (attrs->response_type == RESP_USER_GROUPLIST) { ++ if (attrs->response_type == RESP_USER_GROUPLIST ++ && update_initgr_timeout) { + /* Since RESP_USER_GROUPLIST contains all group memberships it + * is effectively an initgroups request hence + * SYSDB_INITGR_EXPIRE will be set.*/ +@@ -2209,7 +2212,7 @@ static void ipa_s2n_get_fqlist_done(struct tevent_req *subreq) + &sid_str); + if (ret == ENOENT) { + ret = ipa_s2n_save_objects(state->dom, state->req_input, state->attrs, +- state->simple_attrs, NULL, NULL); ++ state->simple_attrs, NULL, NULL, true); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_save_objects failed.\n"); + goto fail; +@@ -2249,7 +2252,7 @@ static void ipa_s2n_get_fqlist_done(struct tevent_req *subreq) + ret = ipa_s2n_save_objects(state->dom, state->req_input, state->attrs, + state->simple_attrs, + state->ipa_ctx->view_name, +- state->override_attrs); ++ state->override_attrs, true); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_save_objects failed.\n"); + tevent_req_error(req, ret); +@@ -2285,7 +2288,7 @@ static void ipa_s2n_get_user_get_override_done(struct tevent_req *subreq) + + ret = ipa_s2n_save_objects(state->dom, state->req_input, state->attrs, + state->simple_attrs, state->ipa_ctx->view_name, +- override_attrs); ++ override_attrs, true); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_save_objects failed.\n"); + tevent_req_error(req, ret); +-- +2.4.0 + diff --git a/0079-IPA-enhance-ipa_initgr_get_overrides_send.patch b/0079-IPA-enhance-ipa_initgr_get_overrides_send.patch new file mode 100644 index 0000000..3b3b221 --- /dev/null +++ b/0079-IPA-enhance-ipa_initgr_get_overrides_send.patch @@ -0,0 +1,198 @@ +From 58a19d50888b1a7da0ee78b49e7d3dcbebc8614d Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Tue, 28 Apr 2015 20:58:15 +0200 +Subject: [PATCH 79/99] IPA: enhance ipa_initgr_get_overrides_send() + +This patch makes ipa_initgr_get_overrides_send() public and add support +to search overrides by UUID or by SID. + +Related to https://fedorahosted.org/sssd/ticket/2633 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 145578006684481434ced78461ab8d1c3570f478) +--- + src/db/sysdb_views.c | 5 ++++ + src/providers/ipa/ipa_id.c | 63 +++++++++++++++++++++++++++++++++------------- + src/providers/ipa/ipa_id.h | 10 ++++++++ + 3 files changed, 61 insertions(+), 17 deletions(-) + +diff --git a/src/db/sysdb_views.c b/src/db/sysdb_views.c +index 945f16ac1753e3b4dfa0c799b00ad177b24d438c..aadd6018f4d1e2ca33e2e00dd8b13b55a8c03f3e 100644 +--- a/src/db/sysdb_views.c ++++ b/src/db/sysdb_views.c +@@ -739,6 +739,11 @@ errno_t sysdb_apply_default_override(struct sss_domain_info *domain, + NULL }; + bool override_attrs_found = false; + ++ if (override_attrs == NULL) { ++ /* nothing to do */ ++ return EOK; ++ } ++ + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); +diff --git a/src/providers/ipa/ipa_id.c b/src/providers/ipa/ipa_id.c +index 38ac4904dcd97c3e241b28143e1f7b8fade37d70..ebf5f03b822e00aa04e45eeca79b8dade67631d2 100644 +--- a/src/providers/ipa/ipa_id.c ++++ b/src/providers/ipa/ipa_id.c +@@ -294,6 +294,7 @@ struct ipa_initgr_get_overrides_state { + + struct ldb_message **groups; + size_t group_count; ++ const char *groups_id_attr; + size_t group_idx; + struct be_acct_req *ar; + +@@ -302,13 +303,14 @@ struct ipa_initgr_get_overrides_state { + + static int ipa_initgr_get_overrides_step(struct tevent_req *req); + +-static struct tevent_req * ++struct tevent_req * + ipa_initgr_get_overrides_send(TALLOC_CTX *memctx, + struct tevent_context *ev, + struct ipa_id_ctx *ipa_ctx, + struct sss_domain_info *user_dom, + size_t groups_count, +- struct ldb_message **groups) ++ struct ldb_message **groups, ++ const char *groups_id_attr) + { + int ret; + struct tevent_req *req; +@@ -334,6 +336,12 @@ ipa_initgr_get_overrides_send(TALLOC_CTX *memctx, + ret = EINVAL; + goto done; + } ++ state->groups_id_attr = talloc_strdup(state, groups_id_attr); ++ if (state->groups_id_attr == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ++ ret = ENOMEM; ++ goto done; ++ } + + ret = ipa_initgr_get_overrides_step(req); + done: +@@ -366,7 +374,7 @@ static int ipa_initgr_get_overrides_step(struct tevent_req *req) + } + + ipa_uuid = ldb_msg_find_attr_as_string(state->groups[state->group_idx], +- SYSDB_UUID, NULL); ++ state->groups_id_attr, NULL); + if (ipa_uuid == NULL) { + /* This should never happen, the search filter used to get the list + * of groups includes "uuid=*" +@@ -377,11 +385,24 @@ static int ipa_initgr_get_overrides_step(struct tevent_req *req) + + talloc_free(state->ar); /* Avoid spiking memory with many groups */ + +- ret = get_be_acct_req_for_uuid(state, ipa_uuid, +- state->user_dom->name, &state->ar); +- if (ret != EOK) { +- DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_sid failed.\n"); +- return ret; ++ if (strcmp(state->groups_id_attr, SYSDB_UUID) == 0) { ++ ret = get_be_acct_req_for_uuid(state, ipa_uuid, ++ state->user_dom->name, &state->ar); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_sid failed.\n"); ++ return ret; ++ } ++ } else if (strcmp(state->groups_id_attr, SYSDB_SID_STR) == 0) { ++ ret = get_be_acct_req_for_sid(state, ipa_uuid, ++ state->user_dom->name, &state->ar); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_sid failed.\n"); ++ return ret; ++ } ++ } else { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported groups ID type [%s].\n", ++ state->groups_id_attr); ++ return EINVAL; + } + + DEBUG(SSSDBG_TRACE_LIBS, "Fetching group %s\n", ipa_uuid); +@@ -408,7 +429,7 @@ static void ipa_initgr_get_overrides_override_done(struct tevent_req *subreq) + struct ipa_initgr_get_overrides_state *state = tevent_req_data(req, + struct ipa_initgr_get_overrides_state); + int ret; +- struct sysdb_attrs *override_attrs; ++ struct sysdb_attrs *override_attrs = NULL; + + ret = ipa_get_ad_override_recv(subreq, &state->dp_error, state, + &override_attrs); +@@ -419,10 +440,16 @@ static void ipa_initgr_get_overrides_override_done(struct tevent_req *subreq) + return; + } + +- ret = sysdb_store_override(state->user_dom, state->ipa_ctx->view_name, +- SYSDB_MEMBER_GROUP, +- override_attrs, +- state->groups[state->group_idx]->dn); ++ if (strcmp(state->ipa_ctx->view_name, SYSDB_DEFAULT_VIEW_NAME) == 0) { ++ ret = sysdb_apply_default_override(state->user_dom, override_attrs, ++ state->groups[state->group_idx]->dn); ++ } else { ++ ret = sysdb_store_override(state->user_dom, ++ state->ipa_ctx->view_name, ++ SYSDB_MEMBER_GROUP, ++ override_attrs, ++ state->groups[state->group_idx]->dn); ++ } + talloc_free(override_attrs); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_override failed.\n"); +@@ -443,7 +470,7 @@ static void ipa_initgr_get_overrides_override_done(struct tevent_req *subreq) + tevent_req_done(req); + } + +-static int ipa_initgr_get_overrides_recv(struct tevent_req *req, int *dp_error) ++int ipa_initgr_get_overrides_recv(struct tevent_req *req, int *dp_error) + { + struct ipa_initgr_get_overrides_state *state = tevent_req_data(req, + struct ipa_initgr_get_overrides_state); +@@ -884,7 +911,8 @@ static void ipa_id_get_account_info_orig_done(struct tevent_req *subreq) + if (state->user_groups != NULL) { + subreq = ipa_initgr_get_overrides_send(state, state->ev, state->ipa_ctx, + state->domain, state->group_cnt, +- state->user_groups); ++ state->user_groups, ++ SYSDB_UUID); + if (subreq == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "ipa_resolve_user_list_send failed.\n"); + ret = ENOMEM; +@@ -962,8 +990,9 @@ static void ipa_id_get_account_info_done(struct tevent_req *subreq) + + if (state->user_groups != NULL) { + subreq = ipa_initgr_get_overrides_send(state, state->ev, state->ipa_ctx, +- state->domain, state->group_cnt, +- state->user_groups); ++ state->domain, state->group_cnt, ++ state->user_groups, ++ SYSDB_UUID); + if (subreq == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "ipa_resolve_user_list_send failed.\n"); + ret = ENOMEM; +diff --git a/src/providers/ipa/ipa_id.h b/src/providers/ipa/ipa_id.h +index 2bb5e0d38f42d4bbb04854dfb04804fecf6257e8..c03ca037a2850478a8f4933bac4fcf8bd70ada04 100644 +--- a/src/providers/ipa/ipa_id.h ++++ b/src/providers/ipa/ipa_id.h +@@ -119,4 +119,14 @@ errno_t get_object_from_cache(TALLOC_CTX *mem_ctx, + struct sss_domain_info *dom, + struct be_acct_req *ar, + struct ldb_message **_msg); ++ ++struct tevent_req * ++ipa_initgr_get_overrides_send(TALLOC_CTX *memctx, ++ struct tevent_context *ev, ++ struct ipa_id_ctx *ipa_ctx, ++ struct sss_domain_info *user_dom, ++ size_t groups_count, ++ struct ldb_message **groups, ++ const char *groups_id_attr); ++int ipa_initgr_get_overrides_recv(struct tevent_req *req, int *dp_error); + #endif +-- +2.4.0 + diff --git a/0080-IPA-search-for-overrides-during-initgroups-in-sever-.patch b/0080-IPA-search-for-overrides-during-initgroups-in-sever-.patch new file mode 100644 index 0000000..e4a41c5 --- /dev/null +++ b/0080-IPA-search-for-overrides-during-initgroups-in-sever-.patch @@ -0,0 +1,115 @@ +From eaf656843831d579f30f94154d88aba2201c1712 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Tue, 28 Apr 2015 20:59:43 +0200 +Subject: [PATCH 80/99] IPA: search for overrides during initgroups in sever + mode + +After the group memberships of a user from a trusted domain are read it +must be checked if there are overrides for the discovered groups to be +able to return the right gid or name to the caller. + +Related to https://fedorahosted.org/sssd/ticket/2633 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 2263c6dd1242c92253240f4998c86a04b6a0ca3a) +--- + src/providers/ipa/ipa_subdomains_id.c | 69 +++++++++++++++++++++++++++++++++++ + 1 file changed, 69 insertions(+) + +diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c +index 1253510dcb8523c19d879d4351ffa07995f161f7..617c091d3abc4808da4a279213ffc3e1119001bf 100644 +--- a/src/providers/ipa/ipa_subdomains_id.c ++++ b/src/providers/ipa/ipa_subdomains_id.c +@@ -569,6 +569,8 @@ struct ipa_get_ad_acct_state { + static void ipa_get_ad_acct_ad_part_done(struct tevent_req *subreq); + static void ipa_get_ad_override_done(struct tevent_req *subreq); + static errno_t ipa_get_ad_apply_override_step(struct tevent_req *req); ++static errno_t ipa_get_ad_ipa_membership_step(struct tevent_req *req); ++static void ipa_id_get_groups_overrides_done(struct tevent_req *subreq); + static void ipa_get_ad_acct_done(struct tevent_req *subreq); + static struct ad_id_ctx *ipa_get_ad_id_ctx(struct ipa_id_ctx *ipa_ctx, + struct sss_domain_info *dom); +@@ -1123,6 +1125,9 @@ static errno_t ipa_get_ad_apply_override_step(struct tevent_req *req) + struct tevent_req *subreq; + const char *obj_name; + int entry_type; ++ size_t groups_count = 0; ++ struct ldb_message **groups = NULL; ++ const char *attrs[] = SYSDB_INITGR_ATTRS; + + if (state->override_attrs != NULL) { + /* We are in ipa-server-mode, so the view is the default view by +@@ -1179,6 +1184,70 @@ static errno_t ipa_get_ad_apply_override_step(struct tevent_req *req) + state->ar->entry_type = BE_REQ_USER; + } + ++ /* Lookup all groups the user is a member of which do not have ORIGINALAD ++ * attributes set, i.e. where overrides might not have been applied. */ ++ ret = sysdb_asq_search(state, state->obj_dom, state->obj_msg->dn, ++ "(&("SYSDB_GC")("SYSDB_GIDNUM"=*)" \ ++ "(!("ORIGINALAD_PREFIX SYSDB_GIDNUM"=*))" \ ++ "(!("ORIGINALAD_PREFIX SYSDB_NAME"=*)))", ++ SYSDB_INITGR_ATTR, ++ attrs, &groups_count, &groups); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_groups_without_orig failed.\n"); ++ return ret; ++ } ++ ++ if (groups != NULL) { ++ subreq = ipa_initgr_get_overrides_send(state, state->ev, state->ipa_ctx, ++ state->obj_dom, groups_count, ++ groups, SYSDB_SID_STR); ++ if (subreq == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "ipa_initgr_get_overrides_send failed.\n"); ++ return ENOMEM; ++ } ++ tevent_req_set_callback(subreq, ipa_id_get_groups_overrides_done, req); ++ return EOK; ++ } ++ ++ ret = ipa_get_ad_ipa_membership_step(req); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_ipa_membership_step failed.\n"); ++ return ret; ++ } ++ ++ return EOK; ++} ++ ++static void ipa_id_get_groups_overrides_done(struct tevent_req *subreq) ++{ ++ struct tevent_req *req = tevent_req_callback_data(subreq, ++ struct tevent_req); ++ errno_t ret; ++ ++ ret = ipa_initgr_get_overrides_recv(subreq, NULL); ++ talloc_zfree(subreq); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "IPA resolve user groups overrides failed [%d].\n", ret); ++ tevent_req_error(req, ret); ++ return; ++ } ++ ++ ret = ipa_get_ad_ipa_membership_step(req); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_ipa_membership_step failed.\n"); ++ tevent_req_error(req, ret); ++ return; ++ } ++ ++ return; ++} ++ ++static errno_t ipa_get_ad_ipa_membership_step(struct tevent_req *req) ++{ ++ struct ipa_get_ad_acct_state *state = tevent_req_data(req, ++ struct ipa_get_ad_acct_state); ++ struct tevent_req *subreq; + + /* For initgroups request we have to check IPA group memberships of AD + * users. This has to be done for other user-request as well to make sure +-- +2.4.0 + diff --git a/0081-IPA-do-not-add-domain-name-unconditionally.patch b/0081-IPA-do-not-add-domain-name-unconditionally.patch new file mode 100644 index 0000000..149da28 --- /dev/null +++ b/0081-IPA-do-not-add-domain-name-unconditionally.patch @@ -0,0 +1,61 @@ +From 226224c91971247f60a86d9c46dd1402f5c29e8a Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 17 Apr 2015 18:22:10 +0200 +Subject: [PATCH 81/99] IPA: do not add domain name unconditionally + +Depending on the server-side configuration the extdom plugin can return +short or fully qualified names for IPA objects. The client must handle +the names according to its own configuration and not add the domain part +of the fully-qualified name unconditionally. + +Resolves https://fedorahosted.org/sssd/ticket/2647 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 3fe2e555edd3963d72483600e5d9616873afd00a) +--- + src/providers/ipa/ipa_s2n_exop.c | 2 ++ + src/tests/cmocka/test_utils.c | 1 + + src/util/domain_info_utils.c | 2 +- + 3 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c +index daebd68853c2d8671b752edb8f2639f795093014..fa00691af579659905e43e71503bd36bf0415bad 100644 +--- a/src/providers/ipa/ipa_s2n_exop.c ++++ b/src/providers/ipa/ipa_s2n_exop.c +@@ -1724,6 +1724,8 @@ static errno_t get_groups_dns(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, + ret = ENOMEM; + goto done; + } ++ ++ DEBUG(SSSDBG_TRACE_ALL, "Added [%s][%s].\n", name_list[c], dn_list[c]); + } + + *_dn_list = talloc_steal(mem_ctx, dn_list); +diff --git a/src/tests/cmocka/test_utils.c b/src/tests/cmocka/test_utils.c +index 4cc6ec85add6bb8f9ae17ddc9af38b0316c9d49f..933e7cd462c11c8ff0f048ec434c8a45f5827e0c 100644 +--- a/src/tests/cmocka/test_utils.c ++++ b/src/tests/cmocka/test_utils.c +@@ -1063,6 +1063,7 @@ void test_fix_domain_in_name_list(void **state) + sd->name = talloc_strdup(sd, "TesT.CasE.DoM"); + assert_non_null(sd->name); + sd->names = dom->names; ++ sd->fqnames = true; + DLIST_ADD(dom->subdomains, sd); + sd->parent = dom; + +diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c +index e76c1cefb49334bf70ef9709b3986134f7ef565c..9fb2110eb34c7e7f5d9933f1aabed43970be1149 100644 +--- a/src/util/domain_info_utils.c ++++ b/src/util/domain_info_utils.c +@@ -831,7 +831,7 @@ errno_t fix_domain_in_name_list(TALLOC_CTX *mem_ctx, + goto done; + } + +- out[c] = sss_tc_fqname(out, head->names, out_domain, in_name); ++ out[c] = sss_get_domain_name(out, in_name, out_domain); + } + + if (out[c] == NULL) { +-- +2.4.0 + diff --git a/0082-NSS-check-for-overrides-before-calling-backend.patch b/0082-NSS-check-for-overrides-before-calling-backend.patch new file mode 100644 index 0000000..4f1ae24 --- /dev/null +++ b/0082-NSS-check-for-overrides-before-calling-backend.patch @@ -0,0 +1,101 @@ +From a4a447b7bf394ded65c8ae872832e7cd135425d1 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Wed, 29 Apr 2015 15:21:17 +0200 +Subject: [PATCH 82/99] NSS: check for overrides before calling backend + +Currently the flag that the input data in a user or group lookup request +might be an override value is only set if no cached entry was found. If +the cached entry of an object with overrides is expired and a request +with the override value as input is processed the flag is not set and +the backend might not be able to find the right entry on the server. +Typically this should not happen because of mid-point refreshes. To +reproduce this create a FreeIPA user and override the login name for a +specific view. On a client which has this view applied call + +getent passwd overridename +sss_cache -E +getent passwd overridename + +The second getent command will still show the right output but in the +logs a + +[sss_dp_get_reply] (0x1000): Got reply from Data Provider - DP error + code: 3 errno: 0 error message: Account info lookup failed + +message can be found for the second request. + +Related to https://fedorahosted.org/sssd/ticket/2642 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 35b178d02dfd293778aefbc0b465a5a3a4b6cd8f) +--- + src/responder/nss/nsssrv_cmd.c | 25 ++++++++++++++++++++----- + 1 file changed, 20 insertions(+), 5 deletions(-) + +diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c +index 4c0e9414d2cdebe61fd91de06f4900f00904ef22..70da3924f2b087f463a25748d0ea1a4d88b0e818 100644 +--- a/src/responder/nss/nsssrv_cmd.c ++++ b/src/responder/nss/nsssrv_cmd.c +@@ -948,7 +948,10 @@ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx) + + if (cmdctx->name_is_upn) { + extra_flag = EXTRA_NAME_IS_UPN; +- } else if (DOM_HAS_VIEWS(dom) && dctx->res->count == 0) { ++ } else if (DOM_HAS_VIEWS(dom) && (dctx->res->count == 0 ++ || ldb_msg_find_attr_as_string(dctx->res->msgs[0], ++ OVERRIDE_PREFIX SYSDB_NAME, ++ NULL) != NULL)) { + extra_flag = EXTRA_INPUT_MAYBE_WITH_VIEW; + } else { + extra_flag = NULL; +@@ -1608,7 +1611,10 @@ static int nss_cmd_getpwuid_search(struct nss_dom_ctx *dctx) + * yet) then verify that the cache is uptodate */ + if (dctx->check_provider) { + +- if (DOM_HAS_VIEWS(dom) && dctx->res->count == 0) { ++ if (DOM_HAS_VIEWS(dom) && (dctx->res->count == 0 ++ || ldb_msg_find_attr_as_uint64(dctx->res->msgs[0], ++ OVERRIDE_PREFIX SYSDB_UIDNUM, ++ 0) != 0)) { + extra_flag = EXTRA_INPUT_MAYBE_WITH_VIEW; + } else { + extra_flag = NULL; +@@ -3049,7 +3055,10 @@ static int nss_cmd_getgrnam_search(struct nss_dom_ctx *dctx) + * yet) then verify that the cache is uptodate */ + if (dctx->check_provider) { + +- if (DOM_HAS_VIEWS(dom) && dctx->res->count == 0) { ++ if (DOM_HAS_VIEWS(dom) && (dctx->res->count == 0 ++ || ldb_msg_find_attr_as_string(dctx->res->msgs[0], ++ OVERRIDE_PREFIX SYSDB_NAME, ++ NULL) != NULL)) { + extra_flag = EXTRA_INPUT_MAYBE_WITH_VIEW; + } else { + extra_flag = NULL; +@@ -3173,7 +3182,10 @@ static int nss_cmd_getgrgid_search(struct nss_dom_ctx *dctx) + * yet) then verify that the cache is uptodate */ + if (dctx->check_provider) { + +- if (DOM_HAS_VIEWS(dom) && dctx->res->count == 0) { ++ if (DOM_HAS_VIEWS(dom) && (dctx->res->count == 0 ++ || ldb_msg_find_attr_as_uint64(dctx->res->msgs[0], ++ OVERRIDE_PREFIX SYSDB_GIDNUM, ++ 0) != 0)) { + extra_flag = EXTRA_INPUT_MAYBE_WITH_VIEW; + } else { + extra_flag = NULL; +@@ -4131,7 +4143,10 @@ static int nss_cmd_initgroups_search(struct nss_dom_ctx *dctx) + + if (cmdctx->name_is_upn) { + extra_flag = EXTRA_NAME_IS_UPN; +- } else if (DOM_HAS_VIEWS(dom) && dctx->res->count == 0) { ++ } else if (DOM_HAS_VIEWS(dom) && (dctx->res->count == 0 ++ || ldb_msg_find_attr_as_string(dctx->res->msgs[0], ++ OVERRIDE_PREFIX SYSDB_NAME, ++ NULL) != NULL)) { + extra_flag = EXTRA_INPUT_MAYBE_WITH_VIEW; + } else { + extra_flag = NULL; +-- +2.4.0 + diff --git a/0083-IPA-allow-initgroups-by-UUID-for-FreeIPA-users.patch b/0083-IPA-allow-initgroups-by-UUID-for-FreeIPA-users.patch new file mode 100644 index 0000000..b8d1353 --- /dev/null +++ b/0083-IPA-allow-initgroups-by-UUID-for-FreeIPA-users.patch @@ -0,0 +1,266 @@ +From 3b00bcd8b6d53d33207005c4e7a631b6a241d300 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Wed, 29 Apr 2015 16:46:14 +0200 +Subject: [PATCH 83/99] IPA: allow initgroups by UUID for FreeIPA users + +If a FreeIPA user is searched with the help of an override name the UUID +from the override anchor is used to search the user. Currently the +initgroups request only allows searches by SID or name. With this patch +a UUID can be used as well. + +Related to https://fedorahosted.org/sssd/ticket/2642 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 0f9c28eb52d2b45c8a97f709308dc11377831b8c) +--- + src/db/sysdb_search.c | 32 ++++++++++++++++++++---------- + src/providers/data_provider.h | 1 - + src/providers/ipa/ipa_id.c | 15 +++++++++++++- + src/providers/ldap/ldap_id.c | 20 ++++++++----------- + src/providers/ldap/sdap_async.h | 1 + + src/providers/ldap/sdap_async_initgroups.c | 14 ++++++++++--- + src/tests/sysdb-tests.c | 9 +++++++++ + 7 files changed, 64 insertions(+), 28 deletions(-) + +diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c +index da0c6d90c6b3a88cfa928aaffa2c8eb843cb1a74..ccd8fa0808cded46a6306912d161cbac60fcc24b 100644 +--- a/src/db/sysdb_search.c ++++ b/src/db/sysdb_search.c +@@ -1612,20 +1612,30 @@ errno_t sysdb_get_real_name(TALLOC_CTX *mem_ctx, + if (res->count == 0) { + ret = sysdb_search_user_by_upn(tmp_ctx, domain, name_or_upn_or_sid, + NULL, &msg); +- if (ret != EOK) { ++ if (ret == ENOENT) { ++ ret = sysdb_search_user_by_sid_str(tmp_ctx, domain, ++ name_or_upn_or_sid, NULL, &msg); + if (ret == ENOENT) { +- ret = sysdb_search_user_by_sid_str(tmp_ctx, domain, +- name_or_upn_or_sid, NULL, +- &msg); +- } +- +- if (ret != EOK) { +- /* User cannot be found in cache */ +- DEBUG(SSSDBG_OP_FAILURE, "Cannot find user [%s] in cache\n", +- name_or_upn_or_sid); +- goto done; ++ ret = sysdb_search_object_by_uuid(tmp_ctx, domain, ++ name_or_upn_or_sid, NULL, ++ &res); ++ if (ret == EOK && res->count == 1) { ++ msg = res->msgs[0]; ++ } else { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "sysdb_search_object_by_uuid did not return a " \ ++ "single result.\n"); ++ ret = ENOENT; ++ goto done; ++ } + } + } ++ if (ret != EOK) { ++ /* User cannot be found in cache */ ++ DEBUG(SSSDBG_OP_FAILURE, "Cannot find user [%s] in cache\n", ++ name_or_upn_or_sid); ++ goto done; ++ } + } else if (res->count == 1) { + msg = res->msgs[0]; + } else { +diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h +index 89fb06a0d6f791a8ae50f9d8b4b69d6176912c6c..5df493e9d1ae21ada6f5fd6198a6d9c36680d044 100644 +--- a/src/providers/data_provider.h ++++ b/src/providers/data_provider.h +@@ -150,7 +150,6 @@ + #define DP_SEC_ID_LEN (sizeof(DP_SEC_ID) - 1) + + #define EXTRA_NAME_IS_UPN "U" +-#define EXTRA_NAME_IS_SID "S" + #define EXTRA_INPUT_MAYBE_WITH_VIEW "V" + + /* AUTH related common data and functions */ +diff --git a/src/providers/ipa/ipa_id.c b/src/providers/ipa/ipa_id.c +index ebf5f03b822e00aa04e45eeca79b8dade67631d2..e3a7fffc35021ad0490246cd435fb618956b91a4 100644 +--- a/src/providers/ipa/ipa_id.c ++++ b/src/providers/ipa/ipa_id.c +@@ -555,6 +555,7 @@ struct ipa_id_get_account_info_state { + struct sss_domain_info *domain; + struct be_req *be_req; + struct be_acct_req *ar; ++ struct be_acct_req *orig_ar; + const char *realm; + + struct sysdb_attrs *override_attrs; +@@ -733,13 +734,25 @@ static void ipa_id_get_account_info_got_override(struct tevent_req *subreq) + + if (strcmp(state->ar->domain, anchor_domain) == 0) { + ++ state->orig_ar = state->ar; ++ + ret = get_be_acct_req_for_uuid(state, ipa_uuid, + state->ar->domain, + &state->ar); + if (ret != EOK) { +- DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_sid failed.\n"); ++ DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_uuid failed.\n"); + goto fail; + } ++ ++ if ((state->orig_ar->entry_type & BE_REQ_TYPE_MASK) ++ == BE_REQ_INITGROUPS) { ++ DEBUG(SSSDBG_TRACE_ALL, ++ "Switching back to BE_REQ_INITGROUPS.\n"); ++ state->ar->entry_type = BE_REQ_INITGROUPS; ++ state->ar->filter_type = BE_FILTER_UUID; ++ state->ar->attr_type = BE_ATTR_CORE; ++ } ++ + } else { + DEBUG(SSSDBG_MINOR_FAILURE, + "Anchor from a different domain [%s], expected [%s]. " \ +diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c +index c2686d249ddf5448c3589c4d8afe32caf09c90a4..63098a82e96b0f6a020b94bdaf238eee4559c09b 100644 +--- a/src/providers/ldap/ldap_id.c ++++ b/src/providers/ldap/ldap_id.c +@@ -964,6 +964,7 @@ struct groups_by_user_state { + struct sss_domain_info *domain; + + const char *name; ++ int name_type; + const char *extra_value; + const char **attrs; + +@@ -982,6 +983,7 @@ static struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx, + struct sdap_domain *sdom, + struct sdap_id_conn_ctx *conn, + const char *name, ++ int name_type, + const char *extra_value, + bool noexist_delete) + { +@@ -1007,6 +1009,7 @@ static struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx, + } + + state->name = name; ++ state->name_type = name_type; + state->extra_value = extra_value; + state->domain = sdom->dom; + state->sysdb = sdom->dom->sysdb; +@@ -1069,6 +1072,7 @@ static void groups_by_user_connect_done(struct tevent_req *subreq) + state->ctx, + state->conn, + state->name, ++ state->name_type, + state->extra_value, + state->attrs); + if (!subreq) { +@@ -1392,7 +1396,8 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, + + case BE_REQ_INITGROUPS: /* init groups for user */ + if (ar->filter_type != BE_FILTER_NAME +- && ar->filter_type != BE_FILTER_SECID) { ++ && ar->filter_type != BE_FILTER_SECID ++ && ar->filter_type != BE_FILTER_UUID) { + ret = EINVAL; + state->err = "Invalid filter type"; + goto done; +@@ -1402,21 +1407,12 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, + state->err = "Invalid attr type"; + goto done; + } +- if (ar->filter_type == BE_FILTER_SECID && ar->extra_value != NULL +- && strcmp(ar->extra_value, EXTRA_NAME_IS_SID) != 0) { +- DEBUG(SSSDBG_OP_FAILURE, +- "Unexpected extra value [%s] for BE_FILTER_SECID.\n", +- ar->extra_value); +- ret = EINVAL; +- state->err = "Invalid extra value"; +- goto done; +- } + + subreq = groups_by_user_send(state, be_ctx->ev, id_ctx, + sdom, conn, + ar->filter_value, +- (ar->filter_type == BE_FILTER_SECID) +- ? EXTRA_NAME_IS_SID : ar->extra_value, ++ ar->filter_type, ++ ar->extra_value, + noexist_delete); + break; + +diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h +index ef9b3bbadba830bcf730b6fa70867c17d51380af..e9bfc5759dff5bca06c95a920752c66343fd2924 100644 +--- a/src/providers/ldap/sdap_async.h ++++ b/src/providers/ldap/sdap_async.h +@@ -135,6 +135,7 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, + struct sdap_id_ctx *id_ctx, + struct sdap_id_conn_ctx *conn, + const char *name, ++ int name_type, + const char *extra_value, + const char **grp_attrs); + int sdap_get_initgr_recv(struct tevent_req *req); +diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c +index 5c5be5eabd7006b457291062519cdad9626f13fa..4f775d76b77a311c3394beec4546c4f6c7dc5f6f 100644 +--- a/src/providers/ldap/sdap_async_initgroups.c ++++ b/src/providers/ldap/sdap_async_initgroups.c +@@ -2667,6 +2667,7 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, + struct sdap_id_ctx *id_ctx, + struct sdap_id_conn_ctx *conn, + const char *name, ++ int name_type, + const char *extra_value, + const char **grp_attrs) + { +@@ -2716,10 +2717,17 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, + + if (extra_value && strcmp(extra_value, EXTRA_NAME_IS_UPN) == 0) { + search_attr = state->opts->user_map[SDAP_AT_USER_PRINC].name; +- } else if (extra_value && strcmp(extra_value, EXTRA_NAME_IS_SID) == 0) { +- search_attr = state->opts->user_map[SDAP_AT_USER_OBJECTSID].name; + } else { +- search_attr = state->opts->user_map[SDAP_AT_USER_NAME].name; ++ switch (name_type) { ++ case BE_FILTER_SECID: ++ search_attr = state->opts->user_map[SDAP_AT_USER_OBJECTSID].name; ++ break; ++ case BE_FILTER_UUID: ++ search_attr = state->opts->user_map[SDAP_AT_USER_UUID].name; ++ break; ++ default: ++ search_attr = state->opts->user_map[SDAP_AT_USER_NAME].name; ++ } + } + + state->user_base_filter = +diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c +index 0185beeaf03d0fc72c9ead22bc73887c701d964f..450a9d1d693135c296f3433d905d1aba115548b8 100644 +--- a/src/tests/sysdb-tests.c ++++ b/src/tests/sysdb-tests.c +@@ -3581,6 +3581,10 @@ START_TEST(test_sysdb_get_real_name) + "S-1-5-21-123-456-789-111"); + fail_unless(ret == EOK, "sysdb_attrs_add_string failed."); + ++ ret = sysdb_attrs_add_string(user_attrs, SYSDB_UUID, ++ "12345678-9012-3456-7890-123456789012"); ++ fail_unless(ret == EOK, "sysdb_attrs_add_string failed."); ++ + ret = sysdb_store_user(test_ctx->domain, "RealName", + NULL, 22345, 0, "gecos", + "/home/realname", "/bin/bash", +@@ -3604,6 +3608,11 @@ START_TEST(test_sysdb_get_real_name) + fail_unless(strcmp(str, "RealName") == 0, "Expected [%s], got [%s].", + "RealName", str); + ++ ret = sysdb_get_real_name(test_ctx, test_ctx->domain, ++ "12345678-9012-3456-7890-123456789012", &str); ++ fail_unless(ret == EOK, "sysdb_get_real_name failed."); ++ fail_unless(strcmp(str, "RealName") == 0, "Expected [%s], got [%s].", ++ "RealName", str); + } + END_TEST + +-- +2.4.0 + diff --git a/0084-SPEC-Fix-cyclic-dependencies-between-sssd-krb5-commo.patch b/0084-SPEC-Fix-cyclic-dependencies-between-sssd-krb5-commo.patch new file mode 100644 index 0000000..0d79427 --- /dev/null +++ b/0084-SPEC-Fix-cyclic-dependencies-between-sssd-krb5-commo.patch @@ -0,0 +1,61 @@ +From 79d0c56ea407a1747f7aa30f916613da314f2ac5 Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik +Date: Sat, 18 Apr 2015 17:36:35 +0200 +Subject: [PATCH 84/99] SPEC: Fix cyclic dependencies between + sssd-{krb5,}-common +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +libsss_ldap_common(sssd-common) requires libsss_krb5_common.so(sssd-krb5-common) +and sssd-krb5-common requires sssd-common. + +sh$ nm --dynamic --defined-only /usr/lib64/sssd/libsss_krb5_common.so +000000000000c4d0 T krb5_service_init +000000000000b8c0 T krb5_try_kdcip +000000000000c710 T remove_krb5_info_files +0000000000014960 T select_principal_from_keytab +00000000000141d0 T sss_krb5_get_error_message + +sh$ nm --dynamic --undefined-only /usr/lib64/sssd/libsss_ldap_common.so + U krb5_service_init + U krb5_try_kdcip + U remove_krb5_info_files + U select_principal_from_keytab + U sss_krb5_get_error_message + +This patch fix cyclic dependency with rpm packaging becuase +it's not simple task to remove krb5 dependency from ldap provider. + +Resolves: +https://fedorahosted.org/sssd/ticket/2507 + +Reviewed-by: Pavel Březina +(cherry picked from commit 56552c518a07b45b25d4a2ef58d37fac0918ce60) +--- + contrib/sssd.spec.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in +index d5f69149047bf691cc2f9663252a41c1f28f216b..35de4449318a763358265c25518e00b34c07da10 100644 +--- a/contrib/sssd.spec.in ++++ b/contrib/sssd.spec.in +@@ -588,6 +588,7 @@ rm -rf $RPM_BUILD_ROOT + %{_libdir}/%{name}/libsss_child.so + %{_libdir}/%{name}/libsss_crypt.so + %{_libdir}/%{name}/libsss_debug.so ++%{_libdir}/%{name}/libsss_krb5_common.so + %{_libdir}/%{name}/libsss_ldap_common.so + %{_libdir}/%{name}/libsss_util.so + %{_libdir}/%{name}/libsss_semanage.so +@@ -645,7 +646,6 @@ rm -rf $RPM_BUILD_ROOT + %files krb5-common + %defattr(-,root,root,-) + %doc COPYING +-%{_libdir}/%{name}/libsss_krb5_common.so + %attr(4750,root,sssd) %{_libexecdir}/%{servicename}/ldap_child + %attr(4750,root,sssd) %{_libexecdir}/%{servicename}/krb5_child + +-- +2.4.0 + diff --git a/0001-BUILD-Remove-unused-libraries-for-pysss.so.patch b/0085-BUILD-Remove-unused-libraries-for-pysss.so.patch similarity index 69% rename from 0001-BUILD-Remove-unused-libraries-for-pysss.so.patch rename to 0085-BUILD-Remove-unused-libraries-for-pysss.so.patch index a193e13..3aef344 100644 --- a/0001-BUILD-Remove-unused-libraries-for-pysss.so.patch +++ b/0085-BUILD-Remove-unused-libraries-for-pysss.so.patch @@ -1,7 +1,7 @@ -From 12098bc18511c9becb375302f29ab87b94352f43 Mon Sep 17 00:00:00 2001 +From e8f00c8792ac1fcffffc3cf8bdf7e23898c9511f Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Mon, 9 Feb 2015 17:40:07 +0100 -Subject: [PATCH 01/15] BUILD: Remove unused libraries for pysss.so +Subject: [PATCH 85/99] BUILD: Remove unused libraries for pysss.so Reviewed-by: Stephen Gallagher --- @@ -9,10 +9,10 @@ Reviewed-by: Stephen Gallagher 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Makefile.am b/Makefile.am -index 29d148c4a0cbda6882b4a619d6c71d2efcc8fb43..176c193d97389f14da6f202fef46579b2e2a2e59 100644 +index 65b9773d8804992f7553609b77553b3b3944a54d..697ec14bf6340961fa93612472a54d3f83edfd6c 100644 --- a/Makefile.am +++ b/Makefile.am -@@ -443,15 +443,9 @@ SSSD_LIBS = \ +@@ -445,15 +445,9 @@ SSSD_LIBS = \ PYTHON_BINDINGS_LIBS = \ $(TALLOC_LIBS) \ @@ -30,5 +30,5 @@ index 29d148c4a0cbda6882b4a619d6c71d2efcc8fb43..176c193d97389f14da6f202fef46579b TOOLS_LIBS = \ $(LTLIBINTL) \ -- -2.1.0 +2.4.0 diff --git a/0002-BUILD-Remove-unused-variables.patch b/0086-BUILD-Remove-unused-variables.patch similarity index 87% rename from 0002-BUILD-Remove-unused-variables.patch rename to 0086-BUILD-Remove-unused-variables.patch index ff4475d..a9d7596 100644 --- a/0002-BUILD-Remove-unused-variables.patch +++ b/0086-BUILD-Remove-unused-variables.patch @@ -1,7 +1,7 @@ -From f8b0f5158332b5c8ae5828512e3fd5f1d64851a8 Mon Sep 17 00:00:00 2001 +From 56fb38fb620cce336a10b4487cdc2d687ebad5e1 Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Mon, 9 Feb 2015 18:46:16 +0100 -Subject: [PATCH 02/15] BUILD: Remove unused variables +Subject: [PATCH 86/99] BUILD: Remove unused variables Reviewed-by: Stephen Gallagher --- @@ -22,5 +22,5 @@ index a1bd87a0ee3a56ddd25c4aba7687ffc7540b4ec2..241de9fd0e401c40f8136861e7c7070c AC_SUBST(PYTHON_INCLUDES) -- -2.1.0 +2.4.0 diff --git a/0003-BUILD-Remove-detection-of-type-Py_ssize_t.patch b/0087-BUILD-Remove-detection-of-type-Py_ssize_t.patch similarity index 93% rename from 0003-BUILD-Remove-detection-of-type-Py_ssize_t.patch rename to 0087-BUILD-Remove-detection-of-type-Py_ssize_t.patch index 306116c..1b033a4 100644 --- a/0003-BUILD-Remove-detection-of-type-Py_ssize_t.patch +++ b/0087-BUILD-Remove-detection-of-type-Py_ssize_t.patch @@ -1,7 +1,7 @@ -From d262610c969e0a3d8c3ad5a7deecc4d0519c6845 Mon Sep 17 00:00:00 2001 +From f5fa6265e747c582e783f1b867cc96e9afc84d79 Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Mon, 9 Feb 2015 19:16:30 +0100 -Subject: [PATCH 03/15] BUILD: Remove detection of type Py_ssize_t +Subject: [PATCH 87/99] BUILD: Remove detection of type Py_ssize_t The type Py_ssize_t is defined in python >= 2.6 @@ -53,5 +53,5 @@ index 828bd22ec44fe9493bfaa246b072777b70c7b585..cf8c848482d82e0060cbfe748c05bd09 PyObject *sss_python_set_new(void); int sss_python_set_add(PyObject *set, PyObject *key); -- -2.1.0 +2.4.0 diff --git a/0004-UTIL-Remove-python-wrapper-sss_python_set_new.patch b/0088-UTIL-Remove-python-wrapper-sss_python_set_new.patch similarity index 95% rename from 0004-UTIL-Remove-python-wrapper-sss_python_set_new.patch rename to 0088-UTIL-Remove-python-wrapper-sss_python_set_new.patch index d55a643..29d90e4 100644 --- a/0004-UTIL-Remove-python-wrapper-sss_python_set_new.patch +++ b/0088-UTIL-Remove-python-wrapper-sss_python_set_new.patch @@ -1,7 +1,7 @@ -From 51308d75c1d128ca6ff90bb5a50aab7720781948 Mon Sep 17 00:00:00 2001 +From ecbcf8d863aa8888bc3ee7b642ba9a82d8015a08 Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Mon, 9 Feb 2015 19:19:55 +0100 -Subject: [PATCH 04/15] UTIL: Remove python wrapper sss_python_set_new +Subject: [PATCH 88/99] UTIL: Remove python wrapper sss_python_set_new The function PySet_New is available in python >= 2.6 @@ -82,5 +82,5 @@ index cf8c848482d82e0060cbfe748c05bd09c7492c4f..6851a64e816ccf3bb84321bbeb9946ad bool sss_python_set_check(PyObject *set); -- -2.1.0 +2.4.0 diff --git a/0005-UTIL-Remove-python-wrapper-sss_python_set_add.patch b/0089-UTIL-Remove-python-wrapper-sss_python_set_add.patch similarity index 95% rename from 0005-UTIL-Remove-python-wrapper-sss_python_set_add.patch rename to 0089-UTIL-Remove-python-wrapper-sss_python_set_add.patch index ad8c001..0565e7d 100644 --- a/0005-UTIL-Remove-python-wrapper-sss_python_set_add.patch +++ b/0089-UTIL-Remove-python-wrapper-sss_python_set_add.patch @@ -1,7 +1,7 @@ -From a54cfca2362b2fb7a7b6ecc90881c3de6bb3556f Mon Sep 17 00:00:00 2001 +From 3ef450d7bce2c6af6f3ea06de5bae5bc7fe7e81a Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Mon, 9 Feb 2015 19:23:44 +0100 -Subject: [PATCH 05/15] UTIL: Remove python wrapper sss_python_set_add +Subject: [PATCH 89/99] UTIL: Remove python wrapper sss_python_set_add The function PySet_Add is available in python >= 2.6 @@ -89,5 +89,5 @@ index 6851a64e816ccf3bb84321bbeb9946ad2fbfbc41..1ff13c4ef4380ff791cf3cfbe12845fb /* Unicode compatibility */ -- -2.1.0 +2.4.0 diff --git a/0006-UTIL-Remove-python-wrapper-sss_python_set_check.patch b/0090-UTIL-Remove-python-wrapper-sss_python_set_check.patch similarity index 95% rename from 0006-UTIL-Remove-python-wrapper-sss_python_set_check.patch rename to 0090-UTIL-Remove-python-wrapper-sss_python_set_check.patch index 0c7ef19..e556324 100644 --- a/0006-UTIL-Remove-python-wrapper-sss_python_set_check.patch +++ b/0090-UTIL-Remove-python-wrapper-sss_python_set_check.patch @@ -1,7 +1,7 @@ -From 6176976f2a895cca5eba9f714c6a6607f61aa8aa Mon Sep 17 00:00:00 2001 +From 2d282d0aab99219337d27ee520825539405c65a6 Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Mon, 9 Feb 2015 19:30:39 +0100 -Subject: [PATCH 06/15] UTIL: Remove python wrapper sss_python_set_check +Subject: [PATCH 90/99] UTIL: Remove python wrapper sss_python_set_check The macro PySet_Check is defined in python >= 2.6 @@ -75,5 +75,5 @@ index 1ff13c4ef4380ff791cf3cfbe12845fb26b3b873..56c25ebb74bffc061688c3c32515d6e0 PyObject *sss_python_unicode_from_string(const char *u); -- -2.1.0 +2.4.0 diff --git a/0007-UTIL-Remove-compatibility-macro-PyModule_AddIntMacro.patch b/0091-UTIL-Remove-compatibility-macro-PyModule_AddIntMacro.patch similarity index 92% rename from 0007-UTIL-Remove-compatibility-macro-PyModule_AddIntMacro.patch rename to 0091-UTIL-Remove-compatibility-macro-PyModule_AddIntMacro.patch index 0dc2c88..cecdc76 100644 --- a/0007-UTIL-Remove-compatibility-macro-PyModule_AddIntMacro.patch +++ b/0091-UTIL-Remove-compatibility-macro-PyModule_AddIntMacro.patch @@ -1,7 +1,7 @@ -From fb70347a6f68cb7cde82c0d31b66b192b7404a03 Mon Sep 17 00:00:00 2001 +From b08e99dc192b21695406753ebbbca1e3adb4d4f2 Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Mon, 9 Feb 2015 19:33:44 +0100 -Subject: [PATCH 07/15] UTIL: Remove compatibility macro PyModule_AddIntMacro +Subject: [PATCH 91/99] UTIL: Remove compatibility macro PyModule_AddIntMacro The macro PyModule_AddIntMacro is defined in python >= 2.6 @@ -41,5 +41,5 @@ index 56c25ebb74bffc061688c3c32515d6e0288ac94d..5521aa5cfd84acffc65edbe76a264b1f #define TYPE_READY(module, type, name) do { \ if (PyType_Ready(&type) < 0) \ -- -2.1.0 +2.4.0 diff --git a/0008-UTIL-Remove-python-wrapper-sss_python_unicode_from_s.patch b/0092-UTIL-Remove-python-wrapper-sss_python_unicode_from_s.patch similarity index 97% rename from 0008-UTIL-Remove-python-wrapper-sss_python_unicode_from_s.patch rename to 0092-UTIL-Remove-python-wrapper-sss_python_unicode_from_s.patch index 20cb64d..2f518b3 100644 --- a/0008-UTIL-Remove-python-wrapper-sss_python_unicode_from_s.patch +++ b/0092-UTIL-Remove-python-wrapper-sss_python_unicode_from_s.patch @@ -1,7 +1,7 @@ -From 65b439f58285de44c7dcd4a03e0f32a2fb247d82 Mon Sep 17 00:00:00 2001 +From 6bbd0c9a30247f22c3581702b310beff51d39b08 Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Mon, 9 Feb 2015 19:38:42 +0100 -Subject: [PATCH 08/15] UTIL: Remove python wrapper +Subject: [PATCH 92/99] UTIL: Remove python wrapper sss_python_unicode_from_string The function PyUnicode_FromString is available in python >= 2.6 @@ -156,5 +156,5 @@ index 5521aa5cfd84acffc65edbe76a264b1f2a52e9fd..7e2bac33656dcbac91bb4f4d32ec9fbc PyObject * sss_exception_with_doc(char *name, char *doc, PyObject *base, PyObject *dict); -- -2.1.0 +2.4.0 diff --git a/0009-BUILD-Use-python-config-for-detection-FLAGS.patch b/0093-BUILD-Use-python-config-for-detection-FLAGS.patch similarity index 97% rename from 0009-BUILD-Use-python-config-for-detection-FLAGS.patch rename to 0093-BUILD-Use-python-config-for-detection-FLAGS.patch index 8320e21..513d620 100644 --- a/0009-BUILD-Use-python-config-for-detection-FLAGS.patch +++ b/0093-BUILD-Use-python-config-for-detection-FLAGS.patch @@ -1,7 +1,7 @@ -From daeaf3b5d3bd3877f1a5b8cc60f0cf401d09e31f Mon Sep 17 00:00:00 2001 +From 79e1d351cf71cc15a13223b093174377b83ae6a8 Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Tue, 10 Feb 2015 16:14:59 +0100 -Subject: [PATCH 09/15] BUILD: Use python-config for detection *FLAGS +Subject: [PATCH 93/99] BUILD: Use python-config for detection *FLAGS The script python-config was not available in older versions of python. This patch simplify detection of python CFLAGS and LDFLAGS and increase @@ -129,5 +129,5 @@ index d59233aa01ac591cfc86be974d8ae26ebbe4635d..c91e8df17b0371538f02bfeb9cade1ce + unset ac_cv_path_PYTHON_CONFIG +]) -- -2.1.0 +2.4.0 diff --git a/0010-SPEC-Use-new-convention-for-python-packages.patch b/0094-SPEC-Use-new-convention-for-python-packages.patch similarity index 90% rename from 0010-SPEC-Use-new-convention-for-python-packages.patch rename to 0094-SPEC-Use-new-convention-for-python-packages.patch index 750fb18..9520609 100644 --- a/0010-SPEC-Use-new-convention-for-python-packages.patch +++ b/0094-SPEC-Use-new-convention-for-python-packages.patch @@ -1,7 +1,7 @@ -From 0bb5eeeedf08dcd6b49e24d3480f2bc5b09c38b0 Mon Sep 17 00:00:00 2001 +From 0a238d24c721fcc8b009367283b1ffaa77a9abe2 Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Tue, 10 Feb 2015 16:33:04 +0100 -Subject: [PATCH 10/15] SPEC: Use new convention for python packages +Subject: [PATCH 94/99] SPEC: Use new convention for python packages Reviewed-by: Stephen Gallagher --- @@ -9,7 +9,7 @@ Reviewed-by: Stephen Gallagher 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in -index bea68f1bbceac232f4ca019111b6262dca3380eb..fc87ff2c9a2012683bb0c989c992b8706851148a 100644 +index 35de4449318a763358265c25518e00b34c07da10..ce9291d65411e1ab8db6e4d33afb8f862de0020d 100644 --- a/contrib/sssd.spec.in +++ b/contrib/sssd.spec.in @@ -339,14 +339,16 @@ Requires: libipa_hbac = %{version}-%{release} @@ -67,5 +67,5 @@ index bea68f1bbceac232f4ca019111b6262dca3380eb..fc87ff2c9a2012683bb0c989c992b870 %{python_sitearch}/pyhbac.so -- -2.1.0 +2.4.0 diff --git a/0011-SPEC-Move-python-bindings-to-separate-packages.patch b/0095-SPEC-Move-python-bindings-to-separate-packages.patch similarity index 90% rename from 0011-SPEC-Move-python-bindings-to-separate-packages.patch rename to 0095-SPEC-Move-python-bindings-to-separate-packages.patch index 283cc91..4b8781a 100644 --- a/0011-SPEC-Move-python-bindings-to-separate-packages.patch +++ b/0095-SPEC-Move-python-bindings-to-separate-packages.patch @@ -1,7 +1,7 @@ -From 79ff61df76fdf77a5942bc555e9dc584192eebe0 Mon Sep 17 00:00:00 2001 +From 16f4dea2c58236942e7c062b2b410b0cb14cee6d Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Tue, 10 Feb 2015 16:50:12 +0100 -Subject: [PATCH 11/15] SPEC: Move python bindings to separate packages +Subject: [PATCH 95/99] SPEC: Move python bindings to separate packages Some pyhton bindings pysss and pysss_murmur was in package sssd-common. Therefore package sssd-common had python as a dependency. @@ -12,7 +12,7 @@ Reviewed-by: Stephen Gallagher 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in -index fc87ff2c9a2012683bb0c989c992b8706851148a..6d6f0b9294e2150549f36c64a11ace64be8a83cc 100644 +index ce9291d65411e1ab8db6e4d33afb8f862de0020d..66c209a4619b942ca262e4a4f2bd43731beae788 100644 --- a/contrib/sssd.spec.in +++ b/contrib/sssd.spec.in @@ -196,6 +196,9 @@ Summary: Userspace tools for use with the SSSD @@ -54,7 +54,7 @@ index fc87ff2c9a2012683bb0c989c992b8706851148a..6d6f0b9294e2150549f36c64a11ace64 %package ldap Summary: The LDAP back end of the SSSD Group: Applications/System -@@ -637,8 +662,6 @@ rm -rf $RPM_BUILD_ROOT +@@ -638,8 +663,6 @@ rm -rf $RPM_BUILD_ROOT %{_mandir}/man8/sss_cache.8* %{_mandir}/man1/sss_ssh_authorizedkeys.1* %{_mandir}/man1/sss_ssh_knownhostsproxy.1* @@ -79,5 +79,5 @@ index fc87ff2c9a2012683bb0c989c992b8706851148a..6d6f0b9294e2150549f36c64a11ace64 %defattr(-,root,root,-) %doc src/sss_client/COPYING src/sss_client/COPYING.LESSER -- -2.1.0 +2.4.0 diff --git a/0012-BUILD-Add-possibility-to-build-python-2-3-bindings.patch b/0096-BUILD-Add-possibility-to-build-python-2-3-bindings.patch similarity index 96% rename from 0012-BUILD-Add-possibility-to-build-python-2-3-bindings.patch rename to 0096-BUILD-Add-possibility-to-build-python-2-3-bindings.patch index 31d96f2..b680ca5 100644 --- a/0012-BUILD-Add-possibility-to-build-python-2-3-bindings.patch +++ b/0096-BUILD-Add-possibility-to-build-python-2-3-bindings.patch @@ -1,7 +1,7 @@ -From a80ec6ff2bdb9367ac7d5c50c3ab7d83877bd7bb Mon Sep 17 00:00:00 2001 +From 263ae7b08d8ecacd7de671a7f2e6041966b4aff4 Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Tue, 10 Feb 2015 17:22:03 +0100 -Subject: [PATCH 12/15] BUILD: Add possibility to build python{2,3} bindings +Subject: [PATCH 96/99] BUILD: Add possibility to build python{2,3} bindings Resolves: https://fedorahosted.org/sssd/ticket/2574 @@ -17,10 +17,10 @@ Reviewed-by: Stephen Gallagher 6 files changed, 267 insertions(+), 65 deletions(-) diff --git a/Makefile.am b/Makefile.am -index 176c193d97389f14da6f202fef46579b2e2a2e59..14ee3dd528f0d89b3e0d2afdb99313e6c570234f 100644 +index 697ec14bf6340961fa93612472a54d3f83edfd6c..027d627586aad212ce7f62d6e6b01b7da2ea2126 100644 --- a/Makefile.am +++ b/Makefile.am -@@ -299,12 +299,22 @@ noinst_LTLIBRARIES = +@@ -301,12 +301,22 @@ noinst_LTLIBRARIES = pkglib_LTLIBRARIES = @@ -49,7 +49,7 @@ index 176c193d97389f14da6f202fef46579b2e2a2e59..14ee3dd528f0d89b3e0d2afdb99313e6 endif dist_noinst_SCRIPTS = \ -@@ -2782,58 +2792,109 @@ sssd_pac_plugin_la_LDFLAGS = \ +@@ -2833,58 +2843,109 @@ sssd_pac_plugin_la_LDFLAGS = \ -avoid-version \ -module @@ -185,7 +185,7 @@ index 176c193d97389f14da6f202fef46579b2e2a2e59..14ee3dd528f0d89b3e0d2afdb99313e6 if BUILD_CIFS_IDMAP_PLUGIN cifs_idmap_sss_la_SOURCES = \ -@@ -2995,17 +3056,51 @@ SSSSCONFIG_MODULES = +@@ -3046,17 +3107,51 @@ SSSSCONFIG_MODULES = endif all-local: ldb_mod_test_dir $(SSSDCONFIG_MODULES) @@ -242,7 +242,7 @@ index 176c193d97389f14da6f202fef46579b2e2a2e59..14ee3dd528f0d89b3e0d2afdb99313e6 endif for doc in $(SSSD_DOCS); do \ $(MKDIR_P) $$doc $(DESTDIR)/$(docdir); \ -@@ -3039,16 +3134,20 @@ install-data-hook: +@@ -3090,16 +3185,20 @@ install-data-hook: fi uninstall-hook: @@ -267,7 +267,7 @@ index 176c193d97389f14da6f202fef46579b2e2a2e59..14ee3dd528f0d89b3e0d2afdb99313e6 if [ ! $(srcdir)/src/config/SSSDConfig/ipachangeconf.py -ef $(builddir)/src/config/SSSDConfig/ipachangeconf.py ]; then \ rm -f $(builddir)/src/config/SSSDConfig/ipachangeconf.py ; \ fi -@@ -3059,7 +3158,20 @@ if BUILD_PYTHON_BINDINGS +@@ -3110,7 +3209,20 @@ if BUILD_PYTHON_BINDINGS rm -f $(builddir)/src/config/SSSDConfig/*.pyc @@ -362,7 +362,7 @@ index f72e448528edcffb855504a38a179c400f98ac42..e30405f3a17ffd2c9899b6eb17af85ec AM_CHECK_SELINUX AM_CHECK_SELINUX_LOGIN_DIR diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in -index 6d6f0b9294e2150549f36c64a11ace64be8a83cc..ecbb29dd9222578fdd2c8505770f0345684012f3 100644 +index 66c209a4619b942ca262e4a4f2bd43731beae788..847b6cf2a36f5323cdfad77dd5ef5772b261c2b9 100644 --- a/contrib/sssd.spec.in +++ b/contrib/sssd.spec.in @@ -781,10 +781,12 @@ rm -rf $RPM_BUILD_ROOT @@ -528,5 +528,5 @@ index 0b28f45e67cb4b033516a585867085dba7b412e6..faa8bb2d33b9d94d380b8f7045ba45aa except ImportError as e: print("Could not load the pysss_murmur module. Please check if it is compiled", file=sys.stderr) -- -2.1.0 +2.4.0 diff --git a/0013-TESTS-Run-python-tests-with-all-supported-python-ver.patch b/0097-TESTS-Run-python-tests-with-all-supported-python-ver.patch similarity index 92% rename from 0013-TESTS-Run-python-tests-with-all-supported-python-ver.patch rename to 0097-TESTS-Run-python-tests-with-all-supported-python-ver.patch index 3679a9d..bf6a726 100644 --- a/0013-TESTS-Run-python-tests-with-all-supported-python-ver.patch +++ b/0097-TESTS-Run-python-tests-with-all-supported-python-ver.patch @@ -1,7 +1,7 @@ -From 63f84d9c9b662bc66ac7125307c1918dc6a671a7 Mon Sep 17 00:00:00 2001 +From 9240213bf2bf604bdd2cf9a91fb410326865805f Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Mon, 23 Feb 2015 22:56:55 +0100 -Subject: [PATCH 13/15] TESTS: Run python tests with all supported python +Subject: [PATCH 97/99] TESTS: Run python tests with all supported python versions This patch add simple bash wrappers for python tests. @@ -25,10 +25,10 @@ Reviewed-by: Stephen Gallagher create mode 100755 src/tests/pysss_murmur-test.py3.sh diff --git a/Makefile.am b/Makefile.am -index 14ee3dd528f0d89b3e0d2afdb99313e6c570234f..605fd1ff5e479078d579ac7524507546261d469c 100644 +index 027d627586aad212ce7f62d6e6b01b7da2ea2126..99729ff6041a29dc79de7f90511d60420af8fd19 100644 --- a/Makefile.am +++ b/Makefile.am -@@ -248,13 +248,20 @@ endif # HAVE_CMOCKA +@@ -250,13 +250,20 @@ endif # HAVE_CMOCKA PYTHON_TESTS = @@ -54,7 +54,7 @@ index 14ee3dd528f0d89b3e0d2afdb99313e6c570234f..605fd1ff5e479078d579ac7524507546 TESTS = \ $(PYTHON_TESTS) \ $(non_interactive_cmocka_based_tests) \ -@@ -323,6 +330,8 @@ dist_noinst_SCRIPTS = \ +@@ -325,6 +332,8 @@ dist_noinst_SCRIPTS = \ src/config/SSSDConfig/ipachangeconf.py \ src/config/SSSDConfig/__init__.py \ src/config/SSSDConfigTest.py \ @@ -63,7 +63,7 @@ index 14ee3dd528f0d89b3e0d2afdb99313e6c570234f..605fd1ff5e479078d579ac7524507546 src/config/SSSDConfig/sssd_upgrade_config.py \ contrib/rhel/update_debug_levels.py \ contrib/fedora/bashrc_sssd \ -@@ -333,7 +342,11 @@ dist_noinst_SCRIPTS = \ +@@ -335,7 +344,11 @@ dist_noinst_SCRIPTS = \ contrib/ci/run \ contrib/ci/valgrind-condense \ src/tests/pyhbac-test.py \ @@ -142,5 +142,5 @@ index 0000000000000000000000000000000000000000..00b352ad3e15ba7d53885b86129bf76e +SCRIPT_PATH=$(dirname "$SCRIPT") +exec python3 $SCRIPT_PATH/pysss_murmur-test.py -- -2.1.0 +2.4.0 diff --git a/0014-SPEC-Replace-python_-macros-with-python2_.patch b/0098-SPEC-Replace-python_-macros-with-python2_.patch similarity index 92% rename from 0014-SPEC-Replace-python_-macros-with-python2_.patch rename to 0098-SPEC-Replace-python_-macros-with-python2_.patch index 97b434b..2dadee6 100644 --- a/0014-SPEC-Replace-python_-macros-with-python2_.patch +++ b/0098-SPEC-Replace-python_-macros-with-python2_.patch @@ -1,7 +1,7 @@ -From dfd30a859fb397afa3346e282f70c07b88010744 Mon Sep 17 00:00:00 2001 +From eca9ad01d4e5e6e90ee7b6eeec36f6425308c21a Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Tue, 10 Feb 2015 18:07:05 +0100 -Subject: [PATCH 14/15] SPEC: Replace python_ macros with python2_ +Subject: [PATCH 98/99] SPEC: Replace python_ macros with python2_ Reviewed-by: Stephen Gallagher --- @@ -9,7 +9,7 @@ Reviewed-by: Stephen Gallagher 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in -index ecbb29dd9222578fdd2c8505770f0345684012f3..0a12fff74101ae4beaa41685bc6a5d13c1795447 100644 +index 847b6cf2a36f5323cdfad77dd5ef5772b261c2b9..2640c806b5c34479bea5d7d3bc19dba18f9afbad 100644 --- a/contrib/sssd.spec.in +++ b/contrib/sssd.spec.in @@ -1,8 +1,14 @@ @@ -87,5 +87,5 @@ index ecbb29dd9222578fdd2c8505770f0345684012f3..0a12fff74101ae4beaa41685bc6a5d13 %files libwbclient %defattr(-,root,root,-) -- -2.1.0 +2.4.0 diff --git a/0015-SPEC-Build-python3-bindings-on-available-platforms.patch b/0099-SPEC-Build-python3-bindings-on-available-platforms.patch similarity index 98% rename from 0015-SPEC-Build-python3-bindings-on-available-platforms.patch rename to 0099-SPEC-Build-python3-bindings-on-available-platforms.patch index ae9fef8..9428718 100644 --- a/0015-SPEC-Build-python3-bindings-on-available-platforms.patch +++ b/0099-SPEC-Build-python3-bindings-on-available-platforms.patch @@ -1,7 +1,7 @@ -From ee4ce01ae70a318eee764176d924dbc92b789c53 Mon Sep 17 00:00:00 2001 +From 9b9be004de2a9bc00b78756f6a63cc27ac513ea9 Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Tue, 10 Feb 2015 19:39:45 +0100 -Subject: [PATCH 15/15] SPEC: Build python3 bindings on available platforms +Subject: [PATCH 99/99] SPEC: Build python3 bindings on available platforms Resolves: https://fedorahosted.org/sssd/ticket/2574 @@ -48,7 +48,7 @@ index 0cdb9962987edddf4dd2fff659e3262bbd50b045..4e0ce1e0328927f42b3849d9c39180b4 systemd xml-core diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in -index 0a12fff74101ae4beaa41685bc6a5d13c1795447..7d0fbdc36747671a69eecdff26f49b4fbaedb586 100644 +index 2640c806b5c34479bea5d7d3bc19dba18f9afbad..948bf26ef13f4c1b8a2dda7f01c1aed0f1cd07d4 100644 --- a/contrib/sssd.spec.in +++ b/contrib/sssd.spec.in @@ -9,6 +9,7 @@ @@ -374,5 +374,5 @@ index 5cc6cae693f09adae12df0d2267e0868ae2f74c0..e808f23e7560241e3fc158d71da2dbdb #ifdef HAVE_CONFIG_LIB { "libsss_config.so", { LIBPFX"libsss_config.so", NULL } }, -- -2.1.0 +2.4.0 diff --git a/sssd.spec b/sssd.spec index 325985d..eca4875 100644 --- a/sssd.spec +++ b/sssd.spec @@ -27,7 +27,7 @@ Name: sssd Version: 1.12.4 -Release: 6%{?dist} +Release: 7%{?dist} Group: Applications/System Summary: System Security Services Daemon License: GPLv3+ @@ -36,26 +36,105 @@ Source0: https://fedorahosted.org/released/sssd/%{name}-%{version}.tar.gz BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) ### Patches ### -Patch0001: 0001-BUILD-Remove-unused-libraries-for-pysss.so.patch -Patch0002: 0002-BUILD-Remove-unused-variables.patch -Patch0003: 0003-BUILD-Remove-detection-of-type-Py_ssize_t.patch -Patch0004: 0004-UTIL-Remove-python-wrapper-sss_python_set_new.patch -Patch0005: 0005-UTIL-Remove-python-wrapper-sss_python_set_add.patch -Patch0006: 0006-UTIL-Remove-python-wrapper-sss_python_set_check.patch -Patch0007: 0007-UTIL-Remove-compatibility-macro-PyModule_AddIntMacro.patch -Patch0008: 0008-UTIL-Remove-python-wrapper-sss_python_unicode_from_s.patch -Patch0009: 0009-BUILD-Use-python-config-for-detection-FLAGS.patch -Patch0010: 0010-SPEC-Use-new-convention-for-python-packages.patch -Patch0011: 0011-SPEC-Move-python-bindings-to-separate-packages.patch -Patch0012: 0012-BUILD-Add-possibility-to-build-python-2-3-bindings.patch -Patch0013: 0013-TESTS-Run-python-tests-with-all-supported-python-ver.patch -Patch0014: 0014-SPEC-Replace-python_-macros-with-python2_.patch -Patch0015: 0015-SPEC-Build-python3-bindings-on-available-platforms.patch -Patch0016: 0016-selinux-Delete-existing-user-mapping-on-empty-defaul.patch -Patch0017: 0017-selinux-Handle-setup-with-empty-default-and-no-confi.patch -Patch0018: 0018-selinux-Disconnect-before-closing-the-handle.patch -Patch0019: 0019-selinux-Begin-and-end-the-transaction-on-the-same-ne.patch -Patch0020: 0020-selinux-Only-call-semanage-if-the-context-actually-c.patch +Patch0001: 0001-PAM-do-not-reject-abruptly.patch +Patch0002: 0002-PAM-new-option-pam_account_expired_message.patch +Patch0003: 0003-PAM-warn-all-services-about-account-expiration.patch +Patch0004: 0004-PAM-check-return-value-of-confdb_get_string.patch +Patch0005: 0005-resolv-Use-the-same-default-timeout-for-SRV-queries-.patch +Patch0006: 0006-FO-Use-SRV-TTL-in-fail-over-code.patch +Patch0007: 0007-SDAP-refactor-pwexpire-policy.patch +Patch0008: 0008-SDAP-enable-change-phase-of-pw-expire-policy-check.patch +Patch0009: 0009-LDAP-unlink-ccname_file_dummy-if-there-is-an-error.patch +Patch0010: 0010-selinux-Delete-existing-user-mapping-on-empty-defaul.patch +Patch0011: 0011-ldap_child-initialized-ccname_file_dummy.patch +Patch0012: 0012-UTIL-convert-GeneralizedTime-to-unix-time.patch +Patch0013: 0013-SDAP-Lock-out-ssh-keys-when-account-naturally-expire.patch +Patch0014: 0014-SDAP-fix-minor-neglect-in-is_account_locked.patch +Patch0015: 0015-be_refresh-refresh-all-domains-in-backend.patch +Patch0016: 0016-sdap_handle_acct_req_send-remove-be_req.patch +Patch0017: 0017-be_refresh-refactor-netgroups-refresh.patch +Patch0018: 0018-be_refresh-add-sdap_refresh_init.patch +Patch0019: 0019-be_refresh-support-users.patch +Patch0020: 0020-be_refresh-support-groups.patch +Patch0021: 0021-Log-reason-in-debug-message-why-ldb_modify-failed.patch +Patch0022: 0022-ldap_child-fix-coverity-warning.patch +Patch0023: 0023-NSS-Handle-ENOENT-when-doing-initgroups-by-UPN.patch +Patch0024: 0024-MAN-libkrb5-and-SSSD-use-different-expansions.patch +Patch0025: 0025-DEBUG-Add-missing-strings-for-error-messages.patch +Patch0026: 0026-test-Check-ERR_LAST.patch +Patch0027: 0027-PAM-use-the-logon_name-as-the-key-for-the-PAM-initgr.patch +Patch0028: 0028-pam_initgr_check_timeout-add-debug-output.patch +Patch0029: 0029-ipa-do-not-treat-missing-sub-domain-users-as-error.patch +Patch0030: 0030-ipa-make-sure-extdom-expo-data-is-available.patch +Patch0031: 0031-ipa_selinux-Fix-warning-may-be-used-uninitialized.patch +Patch0032: 0032-LDAP-AD-do-not-resolve-group-members-during-tokenGro.patch +Patch0033: 0033-IPA-idviews-check-if-view-name-is-set.patch +Patch0034: 0034-selinux-Handle-setup-with-empty-default-and-no-confi.patch +Patch0035: 0035-IPA-make-sure-output-variable-is-set.patch +Patch0036: 0036-IPA-set-EINVAL-if-dn-can-t-be-linearized.patch +Patch0037: 0037-GPO-error-out-instead-of-leaving-array-element-unini.patch +Patch0038: 0038-LDAP-remove-unused-code.patch +Patch0039: 0039-memberof-Do-not-create-request-with-0-attribute-valu.patch +Patch0040: 0040-tests-convert-all-unit-tests-to-cmocka-1.0-or-later.patch +Patch0041: 0041-RPM-BuildRequire-libcmocka-1.0.patch +Patch0042: 0042-build-Only-run-cmocka-tests-if-cmocka-1.0-or-newer-i.patch +Patch0043: 0043-sdap-properly-handle-binary-objectGuid-attribute.patch +Patch0044: 0044-Resolv-re-read-SRV-query-every-time-if-its-TTL-is-0.patch +Patch0045: 0045-IPA-Use-custom-error-codes-when-validating-HBAC-rule.patch +Patch0046: 0046-IPA-Drop-useless-sysdb-parameter.patch +Patch0047: 0047-IPA-Only-treat-malformed-HBAC-rules-as-fatal-if-deny.patch +Patch0048: 0048-IPA-Deprecate-the-ipa_hbac_treat_deny_as-option.patch +Patch0049: 0049-LDAP-fix-a-typo-in-debug-message.patch +Patch0050: 0050-MAN-Update-ppolicy-description.patch +Patch0051: 0051-CLIENT-Clear-errno-with-enabled-sss-default-nss-plug.patch +Patch0052: 0052-GPO-Check-return-value-of-ad_gpo_store_policy_settin.patch +Patch0053: 0053-enumeration-fix-talloc-context.patch +Patch0054: 0054-sudo-sanitize-filter-values.patch +Patch0055: 0055-SDAP-Do-not-set-gid-0-twice.patch +Patch0056: 0056-SDAP-Extract-filtering-AD-group-to-function.patch +Patch0057: 0057-SDAP-Filter-ad-groups-in-initgroups.patch +Patch0058: 0058-selinux-Disconnect-before-closing-the-handle.patch +Patch0059: 0059-selinux-Begin-and-end-the-transaction-on-the-same-ne.patch +Patch0060: 0060-selinux-Only-call-semanage-if-the-context-actually-c.patch +Patch0061: 0061-Option-filter_users-had-no-effect-for-retrieving-sud.patch +Patch0062: 0062-AD-Clean-up-ad_access_gpo.patch +Patch0063: 0063-AD-Always-get-domain-specific-ID-connection.patch +Patch0064: 0064-AD-GPO-Always-look-up-GPOs-from-machine-domain.patch +Patch0065: 0065-tests-Use-cmocka-1.0-API-in-test_sysdb_utils.patch +Patch0066: 0066-sysdb-Add-cache_expire-to-the-default-sysdb_search_o.patch +Patch0067: 0067-IPA-do-not-try-to-save-override-data-for-the-default.patch +Patch0068: 0068-IPA-use-sysdb_attrs_add_string_safe-to-add-group-mem.patch +Patch0069: 0069-IPA-check-ghosts-in-groups-found-by-uuid-as-well.patch +Patch0070: 0070-simple-access-provider-make-user-grp-res-more-robust.patch +Patch0071: 0071-IPA-allow-initgroups-by-SID-for-AD-users.patch +Patch0072: 0072-IPA-fix-segfault-in-ipa_s2n_exop.patch +Patch0073: 0073-autofs-fix-Cannot-allocate-memory-with-FQDNs.patch +Patch0074: 0074-GPO-Do-not-ignore-missing-attrs-for-GPOs.patch +Patch0075: 0075-sss_nss_idmap-tests-Use-different-prepared-buffers-f.patch +Patch0076: 0076-SDAP-Fix-id-mapping-with-disabled-subdomains.patch +Patch0077: 0077-IPA-do-initgroups-if-extdom-exop-supports-it.patch +Patch0078: 0078-IPA-update-initgr-expire-timestamp-conditionally.patch +Patch0079: 0079-IPA-enhance-ipa_initgr_get_overrides_send.patch +Patch0080: 0080-IPA-search-for-overrides-during-initgroups-in-sever-.patch +Patch0081: 0081-IPA-do-not-add-domain-name-unconditionally.patch +Patch0082: 0082-NSS-check-for-overrides-before-calling-backend.patch +Patch0083: 0083-IPA-allow-initgroups-by-UUID-for-FreeIPA-users.patch +Patch0084: 0084-SPEC-Fix-cyclic-dependencies-between-sssd-krb5-commo.patch +Patch0085: 0085-BUILD-Remove-unused-libraries-for-pysss.so.patch +Patch0086: 0086-BUILD-Remove-unused-variables.patch +Patch0087: 0087-BUILD-Remove-detection-of-type-Py_ssize_t.patch +Patch0088: 0088-UTIL-Remove-python-wrapper-sss_python_set_new.patch +Patch0089: 0089-UTIL-Remove-python-wrapper-sss_python_set_add.patch +Patch0090: 0090-UTIL-Remove-python-wrapper-sss_python_set_check.patch +Patch0091: 0091-UTIL-Remove-compatibility-macro-PyModule_AddIntMacro.patch +Patch0092: 0092-UTIL-Remove-python-wrapper-sss_python_unicode_from_s.patch +Patch0093: 0093-BUILD-Use-python-config-for-detection-FLAGS.patch +Patch0094: 0094-SPEC-Use-new-convention-for-python-packages.patch +Patch0095: 0095-SPEC-Move-python-bindings-to-separate-packages.patch +Patch0096: 0096-BUILD-Add-possibility-to-build-python-2-3-bindings.patch +Patch0097: 0097-TESTS-Run-python-tests-with-all-supported-python-ver.patch +Patch0098: 0098-SPEC-Replace-python_-macros-with-python2_.patch +Patch0099: 0099-SPEC-Build-python3-bindings-on-available-platforms.patch ### Dependencies ### Requires: sssd-common = %{version}-%{release} @@ -1015,6 +1094,9 @@ if [ $1 -eq 0 ]; then fi %changelog +* Fri May 08 2015 Lukas Slebodnik - 1.12.4-7 +- Backport patches from upstream 1.12.5 prerelease - contains many fixes + * Wed Apr 15 2015 Lukas Slebodnik - 1.12.4-6 - Fix slow login with ipa and SELinux - Resolves: upstream #2624 - Only set the selinux context if the context