From 9ef5b31e79cf69cd05e7ef6f4ff2aa15bd5c91e9 Mon Sep 17 00:00:00 2001 From: fuanan <2385803914@qq.com> Date: Tue, 31 Aug 2021 18:38:27 +0800 Subject: [PATCH] Fix CVE-2021-3621 --- ...-ERROR-and-PRINT-macros-to-the-tools.patch | 874 ++++++++++++++++++ backport-CVE-2021-3621.patch | 284 ++++++ ...move-redundant-header-file-inclusion.patch | 122 +++ ...s-remove-when-log-directory-is-emtry.patch | 38 + sssd.spec | 12 +- 5 files changed, 1329 insertions(+), 1 deletion(-) create mode 100644 backport-Added-ERROR-and-PRINT-macros-to-the-tools.patch create mode 100644 backport-CVE-2021-3621.patch create mode 100644 backport-Remove-redundant-header-file-inclusion.patch create mode 100644 backport-SSSCTL-fix-logs-remove-when-log-directory-is-emtry.patch diff --git a/backport-Added-ERROR-and-PRINT-macros-to-the-tools.patch b/backport-Added-ERROR-and-PRINT-macros-to-the-tools.patch new file mode 100644 index 0000000..e50d2b0 --- /dev/null +++ b/backport-Added-ERROR-and-PRINT-macros-to-the-tools.patch @@ -0,0 +1,874 @@ +From f24e5ab53f820ed230ac785c85ef6ac4c96b7350 Mon Sep 17 00:00:00 2001 +From: Alex Rodin +Date: Wed, 16 Oct 2019 17:03:03 -0400 +Subject: [PATCH] Added ERROR and PRINT macros to the tools +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Tools: Added ERROR and PRINT macros to the tools + +Replaced functions printf and fprintf with corresponding PRINT and ERROR macro in the tools. + +Resolves: https://pagure.io/SSSD/sssd/issue/3078 + +Reviewed-by: Michal Židek +--- + src/tools/common/sss_tools.c | 20 +++---- + src/tools/sss_groupshow.c | 14 ++--- + src/tools/sss_override.c | 44 ++++++++-------- + src/tools/sss_seed.c | 8 +-- + src/tools/sssctl/sssctl.c | 10 ++-- + src/tools/sssctl/sssctl_access_report.c | 4 +- + src/tools/sssctl/sssctl_cache.c | 10 ++-- + src/tools/sssctl/sssctl_cert.c | 2 +- + src/tools/sssctl/sssctl_config.c | 12 ++--- + src/tools/sssctl/sssctl_data.c | 24 ++++----- + src/tools/sssctl/sssctl_domains.c | 18 +++---- + src/tools/sssctl/sssctl_logs.c | 14 ++--- + src/tools/sssctl/sssctl_systemd.c | 2 +- + src/tools/sssctl/sssctl_user_checks.c | 70 ++++++++++++------------- + 14 files changed, 122 insertions(+), 130 deletions(-) + +diff --git a/src/tools/common/sss_tools.c b/src/tools/common/sss_tools.c +index 0d918f164e..bcbbafe4c2 100644 +--- a/src/tools/common/sss_tools.c ++++ b/src/tools/common/sss_tools.c +@@ -32,7 +32,7 @@ + + static void sss_tool_print_common_opts(int min_len) + { +- fprintf(stderr, _("Help options:\n")); ++ ERROR("Help options:\n"); + fprintf(stderr, " %-*s\t %s\n", min_len, "-?, --help", + _("Show this for a command")); + fprintf(stderr, " %-*s\t %s\n", min_len, "--usage", +@@ -241,8 +241,8 @@ void sss_tool_usage(const char *tool_name, struct sss_route_cmd *commands) + int min_len; + int i; + +- fprintf(stderr, _("Usage:\n%s COMMAND COMMAND-ARGS\n\n"), tool_name); +- fprintf(stderr, _("Available commands:\n")); ++ ERROR("Usage:\n%s COMMAND COMMAND-ARGS\n\n", tool_name); ++ ERROR("Available commands:\n"); + + min_len = sss_tool_max_length(commands); + +@@ -260,7 +260,7 @@ void sss_tool_usage(const char *tool_name, struct sss_route_cmd *commands) + } + } + +- fprintf(stderr, _("\n")); ++ ERROR("\n"); + sss_tool_print_common_opts(min_len); + } + +@@ -433,8 +433,8 @@ errno_t sss_tool_popt_ex(struct sss_cmdline *cmdline, + goto done; + } + } else { +- fprintf(stderr, _("Invalid option %s: %s\n\n"), +- poptBadOption(pc, 0), poptStrerror(ret)); ++ ERROR("Invalid option %s: %s\n\n", ++ poptBadOption(pc, 0), poptStrerror(ret)); + poptPrintHelp(pc, stderr, 0); + ret = EINVAL; + goto done; +@@ -445,7 +445,7 @@ errno_t sss_tool_popt_ex(struct sss_cmdline *cmdline, + fopt = poptGetArg(pc); + if (_fopt != NULL) { + if (fopt == NULL) { +- fprintf(stderr, _("Missing option: %s\n\n"), fopt_help); ++ ERROR("Missing option: %s\n\n", fopt_help); + poptPrintHelp(pc, stderr, 0); + ret = EINVAL; + goto done; +@@ -453,7 +453,7 @@ errno_t sss_tool_popt_ex(struct sss_cmdline *cmdline, + + /* No more arguments expected. If something follows it is an error. */ + if (poptGetArg(pc)) { +- fprintf(stderr, _("Only one free argument is expected!\n\n")); ++ ERROR("Only one free argument is expected!\n\n"); + poptPrintHelp(pc, stderr, 0); + ret = EINVAL; + goto done; +@@ -462,7 +462,7 @@ errno_t sss_tool_popt_ex(struct sss_cmdline *cmdline, + *_fopt = fopt; + } else if (_fopt == NULL && fopt != NULL) { + /* Unexpected free argument. */ +- fprintf(stderr, _("Unexpected parameter: %s\n\n"), fopt); ++ ERROR("Unexpected parameter: %s\n\n", fopt); + poptPrintHelp(pc, stderr, 0); + ret = EINVAL; + goto done; +@@ -474,7 +474,7 @@ errno_t sss_tool_popt_ex(struct sss_cmdline *cmdline, + + /* If at least one option is required and not provided, print error. */ + if (require_option == SSS_TOOL_OPT_REQUIRED) { +- fprintf(stderr, _("At least one option is required!\n\n")); ++ ERROR("At least one option is required!\n\n"); + poptPrintHelp(pc, stderr, 0); + ret = EINVAL; + goto done; +diff --git a/src/tools/sss_groupshow.c b/src/tools/sss_groupshow.c +index ac4c3dc912..7b0fbe1177 100644 +--- a/src/tools/sss_groupshow.c ++++ b/src/tools/sss_groupshow.c +@@ -612,26 +612,26 @@ static void print_group_info(struct group_info *g, unsigned level) + snprintf(fmt, 8, "%%%ds", level*PADDING_SPACES); + snprintf(padding, 512, fmt, ""); + +- printf(_("%1$s%2$sGroup: %3$s\n"), padding, +- g->mpg ? _("Magic Private ") : "", +- g->name); +- printf(_("%1$sGID number: %2$d\n"), padding, g->gid); ++ PRINT("%1$s%2$sGroup: %3$s\n", padding, ++ g->mpg ? _("Magic Private ") : "", ++ g->name); ++ PRINT("%1$sGID number: %2$d\n", padding, g->gid); + +- printf(_("%1$sMember users: "), padding); ++ PRINT("%1$sMember users: ", padding); + if (g->user_members) { + for (i=0; g->user_members[i]; ++i) { + printf("%s%s", i>0 ? "," : "", + g->user_members[i]); + } + } +- printf(_("\n%1$sIs a member of: "), padding); ++ PRINT("\n%1$sIs a member of: ", padding); + if (g->memberofs) { + for (i=0; g->memberofs[i]; ++i) { + printf("%s%s", i>0 ? "," : "", + g->memberofs[i]); + } + } +- printf(_("\n%1$sMember groups: "), padding); ++ PRINT("\n%1$sMember groups: ", padding); + } + + static void print_recursive(struct group_info **group_members, unsigned level) +diff --git a/src/tools/sss_override.c b/src/tools/sss_override.c +index a12aa2785b..031e6a93f1 100644 +--- a/src/tools/sss_override.c ++++ b/src/tools/sss_override.c +@@ -80,7 +80,7 @@ static errno_t parse_cmdline(struct sss_cmdline *cmdline, + ret = sss_tool_parse_name(tool_ctx, tool_ctx, input_name, + &orig_name, &domain); + if (ret != EOK) { +- fprintf(stderr, _("Unable to parse name %s.\n"), input_name); ++ ERROR("Unable to parse name %s.\n", input_name); + return ret; + } + +@@ -184,7 +184,7 @@ static errno_t parse_cmdline_find(struct sss_cmdline *cmdline, + dom = find_domain_by_name(tool_ctx->domains, domname, true); + if (dom == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to find domain %s\n", domname); +- fprintf(stderr, _("Unable to find domain %s\n"), domname); ++ ERROR("Unable to find domain %s\n", domname); + return EINVAL; + } + +@@ -267,11 +267,11 @@ errno_t prepare_view_msg(struct sss_domain_info *domain) + + ret = prepare_view(domain); + if (ret == EEXIST) { +- fprintf(stderr, _("Other than " LOCALVIEW " view already exists " +- "in domain %s.\n"), domain->name); ++ ERROR("Other than " LOCALVIEW " view already exists " ++ "in domain %s.\n", domain->name); + } else if (ret != EOK) { +- fprintf(stderr, _("Unable to prepare " LOCALVIEW +- " view in domain %s.\n"), domain->name); ++ ERROR("Unable to prepare " LOCALVIEW ++ " view in domain %s.\n", domain->name); + } + + return ret; +@@ -580,8 +580,7 @@ static errno_t get_user_domain_msg(struct sss_tool_ctx *tool_ctx, + user->domain, tool_ctx->domains); + if (newdom == NULL) { + domname = user->domain == NULL ? "[unknown]" : user->domain->name; +- fprintf(stderr, _("Unable to find user %s@%s.\n"), +- user->orig_name, domname); ++ ERROR("Unable to find user %s@%s.\n", user->orig_name, domname); + return ENOENT; + } + +@@ -605,8 +604,7 @@ static errno_t get_group_domain_msg(struct sss_tool_ctx *tool_ctx, + group->domain, tool_ctx->domains); + if (newdom == NULL) { + domname = group->domain == NULL ? "[unknown]" : group->domain->name; +- fprintf(stderr, _("Unable to find group %s@%s.\n"), +- group->orig_name, domname); ++ ERROR("Unable to find group %s@%s.\n", group->orig_name, domname); + return ENOENT; + } + +@@ -756,12 +754,12 @@ static errno_t override_fqn(TALLOC_CTX *mem_ctx, + if (ret == EAGAIN) { + DEBUG(SSSDBG_OP_FAILURE, "Unable to find domain from " + "fqn %s\n", input); +- fprintf(stderr, _("Changing domain is not allowed!\n")); ++ ERROR("Changing domain is not allowed!\n"); + ret = EINVAL; + } else if (ret == EOK && dom != NULL && dom != domain) { + DEBUG(SSSDBG_OP_FAILURE, "Trying to change domain from " + "%s to %s, not allowed!\n", domain->name, dom->name); +- fprintf(stderr, _("Changing domain is not allowed!\n")); ++ ERROR("Changing domain is not allowed!\n"); + ret = EINVAL; + } else if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse name %s [%d]: %s\n", +@@ -1293,8 +1291,8 @@ static errno_t user_export(const char *filename, + + db = sss_colondb_open(tmp_ctx, SSS_COLONDB_WRITE, filename); + if (db == NULL) { +- fprintf(stderr, _("Unable to open %s.\n"), +- filename == NULL ? "stdout" : filename); ++ ERROR("Unable to open %s.\n", ++ filename == NULL ? "stdout" : filename); + ret = EIO; + goto done; + } +@@ -1363,7 +1361,7 @@ static errno_t group_export(const char *filename, + + db = sss_colondb_open(tmp_ctx, SSS_COLONDB_WRITE, filename); + if (db == NULL) { +- fprintf(stderr, _("Unable to open %s.\n"), ++ ERROR("Unable to open %s.\n", + filename == NULL ? "stdout" : filename); + ret = EIO; + goto done; +@@ -1600,7 +1598,7 @@ static int override_user_import(struct sss_cmdline *cmdline, + + db = sss_colondb_open(tool_ctx, SSS_COLONDB_READ, filename); + if (db == NULL) { +- fprintf(stderr, _("Unable to open %s.\n"), filename); ++ ERROR("Unable to open %s.\n", filename); + ret = EIO; + goto done; + } +@@ -1611,7 +1609,7 @@ static int override_user_import(struct sss_cmdline *cmdline, + ret = sss_tool_parse_name(tool_ctx, tool_ctx, obj.input_name, + &obj.orig_name, &obj.domain); + if (ret != EOK) { +- fprintf(stderr, _("Unable to parse name %s.\n"), obj.input_name); ++ ERROR("Unable to parse name %s.\n", obj.input_name); + goto done; + } + +@@ -1629,8 +1627,8 @@ static int override_user_import(struct sss_cmdline *cmdline, + } + + if (ret != EOF) { +- fprintf(stderr, _("Invalid format on line %d. " +- "Use --debug option for more information.\n"), linenum); ++ ERROR("Invalid format on line %d. " ++ "Use --debug option for more information.\n", linenum); + goto done; + } + +@@ -1851,7 +1849,7 @@ static int override_group_import(struct sss_cmdline *cmdline, + + db = sss_colondb_open(tool_ctx, SSS_COLONDB_READ, filename); + if (db == NULL) { +- fprintf(stderr, _("Unable to open %s.\n"), filename); ++ ERROR("Unable to open %s.\n", filename); + ret = EIO; + goto done; + } +@@ -1862,7 +1860,7 @@ static int override_group_import(struct sss_cmdline *cmdline, + ret = sss_tool_parse_name(tool_ctx, tool_ctx, obj.input_name, + &obj.orig_name, &obj.domain); + if (ret != EOK) { +- fprintf(stderr, _("Unable to parse name %s.\n"), obj.input_name); ++ ERROR("Unable to parse name %s.\n", obj.input_name); + goto done; + } + +@@ -1880,8 +1878,8 @@ static int override_group_import(struct sss_cmdline *cmdline, + } + + if (ret != EOF) { +- fprintf(stderr, _("Invalid format on line %d. " +- "Use --debug option for more information.\n"), linenum); ++ ERROR("Invalid format on line %d. " ++ "Use --debug option for more information.\n", linenum); + goto done; + } + +diff --git a/src/tools/sss_seed.c b/src/tools/sss_seed.c +index 564f5b3b9e..91bfb4cf84 100644 +--- a/src/tools/sss_seed.c ++++ b/src/tools/sss_seed.c +@@ -823,7 +823,7 @@ int main(int argc, const char **argv) + /* interactive mode to fill in user information */ + if (sctx->interact == true) { + if (sctx->user_cached == true) { +- ERROR(_("User entry already exists in the cache.\n")); ++ ERROR("User entry already exists in the cache.\n"); + ret = EEXIST; + goto done; + } else { +@@ -871,10 +871,10 @@ int main(int argc, const char **argv) + goto done; + } else { + if (sctx->user_cached == false) { +- printf(_("User cache entry created for %1$s\n"), sctx->uctx->name); ++ PRINT("User cache entry created for %1$s\n", sctx->uctx->name); + } +- printf(_("Temporary password added to cache entry for %1$s\n"), +- sctx->uctx->name); ++ PRINT("Temporary password added to cache entry for %1$s\n", ++ sctx->uctx->name); + } + + done: +diff --git a/src/tools/sssctl/sssctl.c b/src/tools/sssctl/sssctl.c +index 4a50a1d86b..2997dbf968 100644 +--- a/src/tools/sssctl/sssctl.c ++++ b/src/tools/sssctl/sssctl.c +@@ -75,7 +75,7 @@ sssctl_prompt(const char *message, + while ((c = getchar()) != '\n' && c != EOF); + + if (ret != 1) { +- fprintf(stderr, _("Unable to read user input\n")); ++ ERROR("Unable to read user input\n"); + return SSSCTL_PROMPT_ERROR; + } + +@@ -88,8 +88,8 @@ sssctl_prompt(const char *message, + return SSSCTL_PROMPT_NO; + } + +- fprintf(stderr, _("Invalid input, please provide either " +- "'%s' or '%s'.\n"), yes, no); ++ ERROR("Invalid input, please provide either " ++ "'%s' or '%s'.\n", yes, no); + + attempts++; + } while (attempts < 3); +@@ -106,12 +106,12 @@ errno_t sssctl_run_command(const char *command) + ret = system(command); + if (ret == -1) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to execute %s\n", command); +- fprintf(stderr, _("Error while executing external command\n")); ++ ERROR("Error while executing external command\n"); + return EFAULT; + } else if (WEXITSTATUS(ret) != 0) { + DEBUG(SSSDBG_CRIT_FAILURE, "Command %s failed with [%d]\n", + command, WEXITSTATUS(ret)); +- fprintf(stderr, _("Error while executing external command\n")); ++ ERROR("Error while executing external command\n"); + return EIO; + } + +diff --git a/src/tools/sssctl/sssctl_access_report.c b/src/tools/sssctl/sssctl_access_report.c +index 80087b248e..5d715eff27 100644 +--- a/src/tools/sssctl/sssctl_access_report.c ++++ b/src/tools/sssctl/sssctl_access_report.c +@@ -282,14 +282,14 @@ static errno_t refresh_hbac_rules(struct sss_tool_ctx *tool_ctx, + + path = sbus_opath_compose(tmp_ctx, IFP_PATH_DOMAINS, domain->name); + if (path == NULL) { +- printf(_("Out of memory!\n")); ++ PRINT("Out of memory!\n"); + ret = ENOMEM; + goto done; + } + + conn = sbus_sync_connect_system(tmp_ctx, NULL); + if (conn == NULL) { +- fprintf(stderr, _("Unable to connect to system bus!\n")); ++ ERROR("Unable to connect to system bus!\n"); + ret = EIO; + goto done; + } +diff --git a/src/tools/sssctl/sssctl_cache.c b/src/tools/sssctl/sssctl_cache.c +index e0d067cfbe..421e817b17 100644 +--- a/src/tools/sssctl/sssctl_cache.c ++++ b/src/tools/sssctl/sssctl_cache.c +@@ -519,8 +519,8 @@ static errno_t sssctl_print_object(struct sssctl_object_info *info, + ret = EOK; + goto done; + } else if (ret != EOK) { +- fprintf(stderr, _("Error: Unable to get object [%d]: %s\n"), +- ret, sss_strerror(ret)); ++ ERROR("Error: Unable to get object [%d]: %s\n", ++ ret, sss_strerror(ret)); + goto done; + } + +@@ -535,8 +535,8 @@ static errno_t sssctl_print_object(struct sssctl_object_info *info, + if (ret == ENOENT) { + continue; + } else if (ret != EOK) { +- fprintf(stderr, _("%s: Unable to read value [%d]: %s\n"), +- info[i].msg, ret, sss_strerror(ret)); ++ ERROR("%s: Unable to read value [%d]: %s\n", ++ info[i].msg, ret, sss_strerror(ret)); + continue; + } + +@@ -573,7 +573,7 @@ static errno_t parse_cmdline(struct sss_cmdline *cmdline, + ret = sss_tool_parse_name(tool_ctx, tool_ctx, input_name, + &orig_name, &domain); + if (ret != EOK) { +- fprintf(stderr, _("Unable to parse name %s.\n"), input_name); ++ ERROR("Unable to parse name %s.\n", input_name); + return ret; + } + +diff --git a/src/tools/sssctl/sssctl_cert.c b/src/tools/sssctl/sssctl_cert.c +index 863ff8d978..7eb3efbb86 100644 +--- a/src/tools/sssctl/sssctl_cert.c ++++ b/src/tools/sssctl/sssctl_cert.c +@@ -142,7 +142,7 @@ errno_t sssctl_cert_map(struct sss_cmdline *cmdline, + + conn = sbus_sync_connect_system(tmp_ctx, NULL); + if (conn == NULL) { +- fprintf(stderr, _("Unable to connect to system bus!\n")); ++ ERROR("Unable to connect to system bus!\n"); + ret = EIO; + goto done; + } +diff --git a/src/tools/sssctl/sssctl_config.c b/src/tools/sssctl/sssctl_config.c +index ff382192a2..4852e22165 100644 +--- a/src/tools/sssctl/sssctl_config.c ++++ b/src/tools/sssctl/sssctl_config.c +@@ -78,8 +78,8 @@ errno_t sssctl_config_check(struct sss_cmdline *cmdline, + /* Check the file permissions */ + ret = sss_ini_config_access_check(init_data); + if (ret != EOK) { +- printf(_("File ownership and permissions check failed. " +- "Expected root:root and 0600.\n")); ++ PRINT("File ownership and permissions check failed. " ++ "Expected root:root and 0600.\n"); + ret = EPERM; + goto done; + } +@@ -101,7 +101,7 @@ errno_t sssctl_config_check(struct sss_cmdline *cmdline, + } + + /* Output from validators */ +- printf(_("Issues identified by validators: %zu\n"), num_errors); ++ PRINT("Issues identified by validators: %zu\n", num_errors); + for (i = 0; i < num_errors; i++) { + printf("%s\n", strs[i]); + } +@@ -111,8 +111,7 @@ errno_t sssctl_config_check(struct sss_cmdline *cmdline, + num_ra_error = ref_array_len(ra); + + printf("\n"); +- printf(_("Messages generated during configuration merging: %zu\n"), +- num_ra_error); ++ PRINT("Messages generated during configuration merging: %zu\n",num_ra_error); + + i = 0; + while (ref_array_get(ra, i, &msg) != NULL) { +@@ -124,8 +123,7 @@ errno_t sssctl_config_check(struct sss_cmdline *cmdline, + ra = sss_ini_get_ra_success_list(init_data); + + printf("\n"); +- printf(_("Used configuration snippet files: %u\n"), +- ref_array_len(ra)); ++ PRINT("Used configuration snippet files: %u\n", ref_array_len(ra)); + + i = 0; + while (ref_array_get(ra, i, &msg) != NULL) { +diff --git a/src/tools/sssctl/sssctl_data.c b/src/tools/sssctl/sssctl_data.c +index cc46cafbfa..8d79b977fd 100644 +--- a/src/tools/sssctl/sssctl_data.c ++++ b/src/tools/sssctl/sssctl_data.c +@@ -86,8 +86,8 @@ static errno_t sssctl_backup(bool force) + + ret = sssctl_create_backup_dir(SSS_BACKUP_DIR); + if (ret != EOK) { +- fprintf(stderr, _("Unable to create backup directory [%d]: %s"), +- ret, sss_strerror(ret)); ++ ERROR("Unable to create backup directory [%d]: %s", ++ ret, sss_strerror(ret)); + return ret; + } + +@@ -108,14 +108,14 @@ static errno_t sssctl_backup(bool force) + ret = sssctl_run_command("sss_override user-export " + SSS_BACKUP_USER_OVERRIDES); + if (ret != EOK) { +- fprintf(stderr, _("Unable to export user overrides\n")); ++ ERROR("Unable to export user overrides\n"); + return ret; + } + + ret = sssctl_run_command("sss_override group-export " + SSS_BACKUP_GROUP_OVERRIDES); + if (ret != EOK) { +- fprintf(stderr, _("Unable to export group overrides\n")); ++ ERROR("Unable to export group overrides\n"); + return ret; + } + +@@ -161,7 +161,7 @@ static errno_t sssctl_restore(bool force_start, bool force_restart) + ret = sssctl_run_command("sss_override user-import " + SSS_BACKUP_USER_OVERRIDES); + if (ret != EOK) { +- fprintf(stderr, _("Unable to import user overrides\n")); ++ ERROR("Unable to import user overrides\n"); + return ret; + } + } +@@ -170,7 +170,7 @@ static errno_t sssctl_restore(bool force_start, bool force_restart) + ret = sssctl_run_command("sss_override group-import " + SSS_BACKUP_GROUP_OVERRIDES); + if (ret != EOK) { +- fprintf(stderr, _("Unable to import group overrides\n")); ++ ERROR("Unable to import group overrides\n"); + return ret; + } + } +@@ -232,23 +232,23 @@ errno_t sssctl_cache_remove(struct sss_cmdline *cmdline, + return ERR_SSSD_RUNNING; + } + +- printf(_("Creating backup of local data...\n")); ++ PRINT("Creating backup of local data...\n"); + ret = sssctl_backup(opts.override); + if (ret != EOK) { +- fprintf(stderr, _("Unable to create backup of local data," +- " can not remove the cache.\n")); ++ ERROR("Unable to create backup of local data," ++ " can not remove the cache.\n"); + return ret; + } + +- printf(_("Removing cache files...\n")); ++ PRINT("Removing cache files...\n"); + ret = sss_remove_subtree(DB_PATH); + if (ret != EOK) { +- fprintf(stderr, _("Unable to remove cache files\n")); ++ ERROR("Unable to remove cache files\n"); + return ret; + } + + if (opts.restore) { +- printf(_("Restoring local data...\n")); ++ PRINT("Restoring local data...\n"); + sssctl_restore(opts.start, opts.start); + } else { + sssctl_start_sssd(opts.start); +diff --git a/src/tools/sssctl/sssctl_domains.c b/src/tools/sssctl/sssctl_domains.c +index 39e810c9d4..3fef44b730 100644 +--- a/src/tools/sssctl/sssctl_domains.c ++++ b/src/tools/sssctl/sssctl_domains.c +@@ -102,7 +102,7 @@ errno_t sssctl_domain_list(struct sss_cmdline *cmdline, + + conn = sbus_sync_connect_system(tmp_ctx, NULL); + if (conn == NULL) { +- fprintf(stderr, _("Unable to connect to system bus!\n")); ++ ERROR("Unable to connect to system bus!\n"); + ret = EIO; + goto done; + } +@@ -164,7 +164,7 @@ sssctl_domain_status_online(struct sbus_sync_connection *conn, + return ret; + } + +- printf(_("Online status: %s\n"), is_online ? _("Online") : _("Offline")); ++ PRINT("Online status: %s\n", is_online ? _("Online") : _("Offline")); + + return EOK; + } +@@ -209,7 +209,7 @@ sssctl_domain_status_active_server(struct sbus_sync_connection *conn, + goto done; + } + +- printf(_("Active servers:\n")); ++ PRINT("Active servers:\n"); + for (i = 0; services[i] != NULL; i++) { + ret = sbus_call_ifp_domain_ActiveServer(tmp_ctx, conn, IFP_BUS, + domain_path, services[i], &server); +@@ -257,7 +257,7 @@ sssctl_domain_status_server_list(struct sbus_sync_connection *conn, + } + + for (i = 0; services[i] != NULL; i++) { +- printf(_("Discovered %s servers:\n"), proper_service_name(services[i])); ++ PRINT("Discovered %s servers:\n", proper_service_name(services[i])); + + ret = sbus_call_ifp_domain_ListServers(tmp_ctx, conn, IFP_BUS, + domain_path, services[i], &servers); +@@ -339,7 +339,7 @@ errno_t sssctl_domain_status(struct sss_cmdline *cmdline, + + path = sbus_opath_compose(tmp_ctx, IFP_PATH_DOMAINS, opts.domain); + if (path == NULL) { +- printf(_("Out of memory!\n")); ++ PRINT("Out of memory!\n"); + ret = ENOMEM; + goto done; + } +@@ -351,7 +351,7 @@ errno_t sssctl_domain_status(struct sss_cmdline *cmdline, + + conn = sbus_sync_connect_system(tmp_ctx, NULL); + if (conn == NULL) { +- fprintf(stderr, _("Unable to connect to system bus!\n")); ++ ERROR("Unable to connect to system bus!\n"); + ret = EIO; + goto done; + } +@@ -359,7 +359,7 @@ errno_t sssctl_domain_status(struct sss_cmdline *cmdline, + if (opts.online) { + ret = sssctl_domain_status_online(conn, path); + if (ret != EOK) { +- fprintf(stderr, _("Unable to get online status\n")); ++ ERROR("Unable to get online status\n"); + goto done; + } + +@@ -369,7 +369,7 @@ errno_t sssctl_domain_status(struct sss_cmdline *cmdline, + if (opts.active) { + ret = sssctl_domain_status_active_server(conn, path); + if (ret != EOK) { +- fprintf(stderr, _("Unable to get online status\n")); ++ ERROR("Unable to get online status\n"); + goto done; + } + +@@ -379,7 +379,7 @@ errno_t sssctl_domain_status(struct sss_cmdline *cmdline, + if (opts.servers) { + ret = sssctl_domain_status_server_list(conn, path); + if (ret != EOK) { +- fprintf(stderr, _("Unable to get server list\n")); ++ ERROR("Unable to get server list\n"); + goto done; + } + } +diff --git a/src/tools/sssctl/sssctl_logs.c b/src/tools/sssctl/sssctl_logs.c +index aca988c053..fc03f396c0 100644 +--- a/src/tools/sssctl/sssctl_logs.c ++++ b/src/tools/sssctl/sssctl_logs.c +@@ -245,19 +245,19 @@ errno_t sssctl_logs_remove(struct sss_cmdline *cmdline, + } + + if (opts.delete) { +- printf(_("Deleting log files...\n")); ++ PRINT("Deleting log files...\n"); + ret = sss_remove_subtree(LOG_PATH); + if (ret != EOK) { +- fprintf(stderr, _("Unable to remove log files\n")); ++ ERROR("Unable to remove log files\n"); + return ret; + } + + sss_signal(SIGHUP); + } else { +- printf(_("Truncating log files...\n")); ++ PRINT("Truncating log files...\n"); + ret = sssctl_run_command("truncate --size 0 " LOG_FILES); + if (ret != EOK) { +- fprintf(stderr, _("Unable to truncate log files\n")); ++ ERROR("Unable to truncate log files\n"); + return ret; + } + } +@@ -283,13 +283,13 @@ errno_t sssctl_logs_fetch(struct sss_cmdline *cmdline, + + cmd = talloc_asprintf(tool_ctx, "tar -czf %s %s", file, LOG_FILES); + if (cmd == NULL) { +- fprintf(stderr, _("Out of memory!")); ++ ERROR("Out of memory!"); + } + +- printf(_("Archiving log files into %s...\n"), file); ++ PRINT("Archiving log files into %s...\n", file); + ret = sssctl_run_command(cmd); + if (ret != EOK) { +- fprintf(stderr, _("Unable to archive log files\n")); ++ ERROR("Unable to archive log files\n"); + return ret; + } + +diff --git a/src/tools/sssctl/sssctl_systemd.c b/src/tools/sssctl/sssctl_systemd.c +index 28eb71ab1d..1d30558589 100644 +--- a/src/tools/sssctl/sssctl_systemd.c ++++ b/src/tools/sssctl/sssctl_systemd.c +@@ -51,7 +51,7 @@ static errno_t sssctl_systemd_call(systemd_method method) + + conn = sbus_sync_connect_system(tmp_ctx, NULL); + if (conn == NULL) { +- fprintf(stderr, _("Unable to connect to system bus!\n")); ++ ERROR("Unable to connect to system bus!\n"); + ret = EIO; + goto done; + } +diff --git a/src/tools/sssctl/sssctl_user_checks.c b/src/tools/sssctl/sssctl_user_checks.c +index 5fb207e2db..218789d93e 100644 +--- a/src/tools/sssctl/sssctl_user_checks.c ++++ b/src/tools/sssctl/sssctl_user_checks.c +@@ -92,7 +92,7 @@ static errno_t get_ifp_user(const char *username) + + conn = sbus_sync_connect_system(tmp_ctx, NULL); + if (conn == NULL) { +- fprintf(stderr, _("Unable to connect to system bus!\n")); ++ ERROR("Unable to connect to system bus!\n"); + ret = EIO; + goto done; + } +@@ -114,7 +114,7 @@ static errno_t get_ifp_user(const char *username) + goto done; + } + +- fprintf(stdout, _("SSSD InfoPipe user lookup result:\n")); ++ PRINT("SSSD InfoPipe user lookup result:\n"); + PRINT_IFP_PROPERTY(user, name, "s"); + PRINT_IFP_PROPERTY(user, uidNumber, PRIu32); + PRINT_IFP_PROPERTY(user, gidNumber, PRIu32); +@@ -164,14 +164,14 @@ static int sss_getpwnam_check(const char *user) + + dl_handle = dlopen("libnss_sss.so.2", RTLD_NOW); + if (dl_handle == NULL) { +- fprintf(stderr, _("dlopen failed with [%s].\n"), dlerror()); ++ ERROR("dlopen failed with [%s].\n", dlerror()); + ret = EIO; + goto done; + } + + sss_getpwnam_r = dlsym(dl_handle, "_nss_sss_getpwnam_r"); + if (sss_getpwnam_r == NULL) { +- fprintf(stderr, _("dlsym failed with [%s].\n"), dlerror()); ++ ERROR("dlsym failed with [%s].\n", dlerror()); + ret = EIO; + goto done; + } +@@ -179,25 +179,25 @@ static int sss_getpwnam_check(const char *user) + buflen = DEFAULT_BUFSIZE; + buffer = malloc(buflen); + if (buffer == NULL) { +- fprintf(stderr, _("malloc failed.\n")); ++ ERROR("malloc failed.\n"); + ret = ENOMEM; + goto done; + } + + status = sss_getpwnam_r(user, &pwd, buffer, buflen, &nss_errno); + if (status != NSS_STATUS_SUCCESS) { +- fprintf(stderr, _("sss_getpwnam_r failed with [%d].\n"), status); ++ ERROR("sss_getpwnam_r failed with [%d].\n", status); + ret = EIO; + goto done; + } + +- fprintf(stdout, _("SSSD nss user lookup result:\n")); +- fprintf(stdout, _(" - user name: %s\n"), pwd.pw_name); +- fprintf(stdout, _(" - user id: %d\n"), pwd.pw_uid); +- fprintf(stdout, _(" - group id: %d\n"), pwd.pw_gid); +- fprintf(stdout, _(" - gecos: %s\n"), pwd.pw_gecos); +- fprintf(stdout, _(" - home directory: %s\n"), pwd.pw_dir); +- fprintf(stdout, _(" - shell: %s\n\n"), pwd.pw_shell); ++ PRINT("SSSD nss user lookup result:\n"); ++ PRINT(" - user name: %s\n", pwd.pw_name); ++ PRINT(" - user id: %d\n", pwd.pw_uid); ++ PRINT(" - group id: %d\n", pwd.pw_gid); ++ PRINT(" - gecos: %s\n", pwd.pw_gecos); ++ PRINT(" - home directory: %s\n", pwd.pw_dir); ++ PRINT(" - shell: %s\n\n", pwd.pw_shell); + + ret = 0; + +@@ -244,65 +244,61 @@ errno_t sssctl_user_checks(struct sss_cmdline *cmdline, + return ret; + } + +- fprintf(stdout, _("user: %s\naction: %s\nservice: %s\n\n"), +- user, action, service); ++ PRINT("user: %s\naction: %s\nservice: %s\n\n", user, action, service); + + if (*user != '\0') { + ret = sss_getpwnam_check(user); + if (ret != 0) { +- fprintf(stderr, _("User name lookup with [%s] failed.\n"), user); ++ ERROR("User name lookup with [%s] failed.\n", user); + } + + ret = get_ifp_user(user); + if (ret != 0) { +- fprintf(stderr, _("InfoPipe User lookup with [%s] failed.\n"), +- user); ++ ERROR("InfoPipe User lookup with [%s] failed.\n", user); + } + } + + ret = pam_start(service, user, &conv, &pamh); + if (ret != PAM_SUCCESS) { +- fprintf(stderr, _("pam_start failed: %s\n"), pam_strerror(pamh, ret)); ++ ERROR("pam_start failed: %s\n", pam_strerror(pamh, ret)); + return 1; + } + + if ( strncmp(action, "auth", 4)== 0 ) { +- fprintf(stdout, _("testing pam_authenticate\n\n")); ++ PRINT("testing pam_authenticate\n\n"); + ret = pam_authenticate(pamh, 0); + pret = pam_get_item(pamh, PAM_USER, (const void **) &pam_user); + if (pret != PAM_SUCCESS) { +- fprintf(stderr, _("pam_get_item failed: %s\n"), pam_strerror(pamh, +- pret)); ++ ERROR("pam_get_item failed: %s\n", pam_strerror(pamh, pret)); + pam_user = "- not available -"; + } +- fprintf(stderr, _("pam_authenticate for user [%s]: %s\n\n"), pam_user, ++ ERROR("pam_authenticate for user [%s]: %s\n\n", pam_user, + pam_strerror(pamh, ret)); + } else if ( strncmp(action, "chau", 4)== 0 ) { +- fprintf(stdout, _("testing pam_chauthtok\n\n")); ++ PRINT("testing pam_chauthtok\n\n"); + ret = pam_chauthtok(pamh, 0); +- fprintf(stderr, _("pam_chauthtok: %s\n\n"), pam_strerror(pamh, ret)); ++ ERROR("pam_chauthtok: %s\n\n", pam_strerror(pamh, ret)); + } else if ( strncmp(action, "acct", 4)== 0 ) { +- fprintf(stdout, _("testing pam_acct_mgmt\n\n")); ++ PRINT("testing pam_acct_mgmt\n\n"); + ret = pam_acct_mgmt(pamh, 0); +- fprintf(stderr, _("pam_acct_mgmt: %s\n\n"), pam_strerror(pamh, ret)); ++ ERROR("pam_acct_mgmt: %s\n\n", pam_strerror(pamh, ret)); + } else if ( strncmp(action, "setc", 4)== 0 ) { +- fprintf(stdout, _("testing pam_setcred\n\n")); ++ PRINT("testing pam_setcred\n\n"); + ret = pam_setcred(pamh, 0); +- fprintf(stderr, _("pam_setcred: [%s]\n\n"), pam_strerror(pamh, ret)); ++ ERROR("pam_setcred: [%s]\n\n", pam_strerror(pamh, ret)); + } else if ( strncmp(action, "open", 4)== 0 ) { +- fprintf(stdout, _("testing pam_open_session\n\n")); ++ PRINT("testing pam_open_session\n\n"); + ret = pam_open_session(pamh, 0); +- fprintf(stderr, _("pam_open_session: %s\n\n"), pam_strerror(pamh, ret)); ++ ERROR("pam_open_session: %s\n\n", pam_strerror(pamh, ret)); + } else if ( strncmp(action, "clos", 4)== 0 ) { +- fprintf(stdout, _("testing pam_close_session\n\n")); ++ PRINT("testing pam_close_session\n\n"); + ret = pam_close_session(pamh, 0); +- fprintf(stderr, _("pam_close_session: %s\n\n"), +- pam_strerror(pamh, ret)); ++ ERROR("pam_close_session: %s\n\n", pam_strerror(pamh, ret)); + } else { +- fprintf(stderr, _("unknown action\n")); ++ ERROR("unknown action\n"); + } + +- fprintf(stderr, _("PAM Environment:\n")); ++ ERROR("PAM Environment:\n"); + pam_env = pam_getenvlist(pamh); + if (pam_env != NULL && pam_env[0] != NULL) { + for (c = 0; pam_env[c] != NULL; c++) { +@@ -310,7 +306,7 @@ errno_t sssctl_user_checks(struct sss_cmdline *cmdline, + free(pam_env[c]); + } + } else { +- fprintf(stderr, _(" - no env -\n")); ++ ERROR(" - no env -\n"); + } + free(pam_env); + +-- +2.23.0 + diff --git a/backport-CVE-2021-3621.patch b/backport-CVE-2021-3621.patch new file mode 100644 index 0000000..109e23b --- /dev/null +++ b/backport-CVE-2021-3621.patch @@ -0,0 +1,284 @@ +From 7ab83f97e1cbefb78ece17232185bdd2985f0bbe Mon Sep 17 00:00:00 2001 +From: Alexey Tikhonov +Date: Fri, 18 Jun 2021 13:17:19 +0200 +Subject: [PATCH] TOOLS: replace system() with execvp() to avoid execution of + user supplied command +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +:relnote: A flaw was found in SSSD, where the sssctl command was +vulnerable to shell command injection via the logs-fetch and +cache-expire subcommands. This flaw allows an attacker to trick +the root user into running a specially crafted sssctl command, +such as via sudo, to gain root access. The highest threat from this +vulnerability is to confidentiality, integrity, as well as system +availability. +This patch fixes a flaw by replacing system() with execvp(). + +:fixes: CVE-2021-3621 + +Reviewed-by: Pavel Březina +--- + src/tools/sssctl/sssctl.c | 39 ++++++++++++++++------- + src/tools/sssctl/sssctl.h | 2 +- + src/tools/sssctl/sssctl_data.c | 57 +++++++++++----------------------- + src/tools/sssctl/sssctl_logs.c | 32 +++++++++++++++---- + 4 files changed, 73 insertions(+), 57 deletions(-) + +diff --git a/src/tools/sssctl/sssctl.c b/src/tools/sssctl/sssctl.c +index 2997dbf968..8adaf30910 100644 +--- a/src/tools/sssctl/sssctl.c ++++ b/src/tools/sssctl/sssctl.c +@@ -97,22 +97,36 @@ sssctl_prompt(const char *message, + return SSSCTL_PROMPT_ERROR; + } + +-errno_t sssctl_run_command(const char *command) ++errno_t sssctl_run_command(const char *const argv[]) + { + int ret; ++ int wstatus; + +- DEBUG(SSSDBG_TRACE_FUNC, "Running %s\n", command); ++ DEBUG(SSSDBG_TRACE_FUNC, "Running '%s'\n", argv[0]); + +- ret = system(command); ++ ret = fork(); + if (ret == -1) { +- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to execute %s\n", command); + ERROR("Error while executing external command\n"); + return EFAULT; +- } else if (WEXITSTATUS(ret) != 0) { +- DEBUG(SSSDBG_CRIT_FAILURE, "Command %s failed with [%d]\n", +- command, WEXITSTATUS(ret)); ++ } ++ ++ if (ret == 0) { ++ /* cast is safe - see ++ https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html ++ "The statement about argv[] and envp[] being constants ... " ++ */ ++ execvp(argv[0], discard_const_p(char * const, argv)); + ERROR("Error while executing external command\n"); +- return EIO; ++ _exit(1); ++ } else { ++ if (waitpid(ret, &wstatus, 0) == -1) { ++ ERROR("Error while executing external command '%s'\n", argv[0]); ++ return EFAULT; ++ } else if (WEXITSTATUS(wstatus) != 0) { ++ ERROR("Command '%s' failed with [%d]\n", ++ argv[0], WEXITSTATUS(wstatus)); ++ return EIO; ++ } + } + + return EOK; +@@ -132,11 +146,14 @@ static errno_t sssctl_manage_service(enum sssctl_svc_action action) + #elif defined(HAVE_SERVICE) + switch (action) { + case SSSCTL_SVC_START: +- return sssctl_run_command(SERVICE_PATH" sssd start"); ++ return sssctl_run_command( ++ (const char *[]){SERVICE_PATH, "sssd", "start", NULL}); + case SSSCTL_SVC_STOP: +- return sssctl_run_command(SERVICE_PATH" sssd stop"); ++ return sssctl_run_command( ++ (const char *[]){SERVICE_PATH, "sssd", "stop", NULL}); + case SSSCTL_SVC_RESTART: +- return sssctl_run_command(SERVICE_PATH" sssd restart"); ++ return sssctl_run_command( ++ (const char *[]){SERVICE_PATH, "sssd", "restart", NULL}); + } + #endif + +diff --git a/src/tools/sssctl/sssctl.h b/src/tools/sssctl/sssctl.h +index 0115b2457c..599ef65196 100644 +--- a/src/tools/sssctl/sssctl.h ++++ b/src/tools/sssctl/sssctl.h +@@ -47,7 +47,7 @@ enum sssctl_prompt_result + sssctl_prompt(const char *message, + enum sssctl_prompt_result defval); + +-errno_t sssctl_run_command(const char *command); ++errno_t sssctl_run_command(const char *const argv[]); /* argv[0] - command */ + bool sssctl_start_sssd(bool force); + bool sssctl_stop_sssd(bool force); + bool sssctl_restart_sssd(bool force); +diff --git a/src/tools/sssctl/sssctl_data.c b/src/tools/sssctl/sssctl_data.c +index 8d79b977fd..bf22913416 100644 +--- a/src/tools/sssctl/sssctl_data.c ++++ b/src/tools/sssctl/sssctl_data.c +@@ -105,15 +105,15 @@ static errno_t sssctl_backup(bool force) + } + } + +- ret = sssctl_run_command("sss_override user-export " +- SSS_BACKUP_USER_OVERRIDES); ++ ret = sssctl_run_command((const char *[]){"sss_override", "user-export", ++ SSS_BACKUP_USER_OVERRIDES, NULL}); + if (ret != EOK) { + ERROR("Unable to export user overrides\n"); + return ret; + } + +- ret = sssctl_run_command("sss_override group-export " +- SSS_BACKUP_GROUP_OVERRIDES); ++ ret = sssctl_run_command((const char *[]){"sss_override", "group-export", ++ SSS_BACKUP_GROUP_OVERRIDES, NULL}); + if (ret != EOK) { + ERROR("Unable to export group overrides\n"); + return ret; +@@ -158,8 +158,8 @@ static errno_t sssctl_restore(bool force_start, bool force_restart) + } + + if (sssctl_backup_file_exists(SSS_BACKUP_USER_OVERRIDES)) { +- ret = sssctl_run_command("sss_override user-import " +- SSS_BACKUP_USER_OVERRIDES); ++ ret = sssctl_run_command((const char *[]){"sss_override", "user-import", ++ SSS_BACKUP_USER_OVERRIDES, NULL}); + if (ret != EOK) { + ERROR("Unable to import user overrides\n"); + return ret; +@@ -167,8 +167,8 @@ static errno_t sssctl_restore(bool force_start, bool force_restart) + } + + if (sssctl_backup_file_exists(SSS_BACKUP_USER_OVERRIDES)) { +- ret = sssctl_run_command("sss_override group-import " +- SSS_BACKUP_GROUP_OVERRIDES); ++ ret = sssctl_run_command((const char *[]){"sss_override", "group-import", ++ SSS_BACKUP_GROUP_OVERRIDES, NULL}); + if (ret != EOK) { + ERROR("Unable to import group overrides\n"); + return ret; +@@ -296,40 +296,19 @@ errno_t sssctl_cache_expire(struct sss_cmdline *cmdline, + void *pvt) + { + errno_t ret; +- char *cmd_args = NULL; +- const char *cachecmd = SSS_CACHE; +- char *cmd = NULL; +- int i; +- +- if (cmdline->argc == 0) { +- ret = sssctl_run_command(cachecmd); +- goto done; +- } + +- cmd_args = talloc_strdup(tool_ctx, ""); +- if (cmd_args == NULL) { +- ret = ENOMEM; +- goto done; ++ const char **args = talloc_array_size(tool_ctx, ++ sizeof(char *), ++ cmdline->argc + 2); ++ if (!args) { ++ return ENOMEM; + } ++ memcpy(&args[1], cmdline->argv, sizeof(char *) * cmdline->argc); ++ args[0] = SSS_CACHE; ++ args[cmdline->argc + 1] = NULL; + +- for (i = 0; i < cmdline->argc; i++) { +- cmd_args = talloc_strdup_append(cmd_args, cmdline->argv[i]); +- if (i != cmdline->argc - 1) { +- cmd_args = talloc_strdup_append(cmd_args, " "); +- } +- } +- +- cmd = talloc_asprintf(tool_ctx, "%s %s", cachecmd, cmd_args); +- if (cmd == NULL) { +- ret = ENOMEM; +- goto done; +- } +- +- ret = sssctl_run_command(cmd); +- +-done: +- talloc_free(cmd_args); +- talloc_free(cmd); ++ ret = sssctl_run_command(args); + ++ talloc_free(args); + return ret; + } +diff --git a/src/tools/sssctl/sssctl_logs.c b/src/tools/sssctl/sssctl_logs.c +index 9ff2be05b6..ebb2c4571c 100644 +--- a/src/tools/sssctl/sssctl_logs.c ++++ b/src/tools/sssctl/sssctl_logs.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + + #include "util/util.h" + #include "tools/common/sss_process.h" +@@ -230,6 +231,7 @@ errno_t sssctl_logs_remove(struct sss_cmdline *cmdline, + { + struct sssctl_logs_opts opts = {0}; + errno_t ret; ++ glob_t globbuf; + + /* Parse command line. */ + struct poptOption options[] = { +@@ -253,8 +255,20 @@ errno_t sssctl_logs_remove(struct sss_cmdline *cmdline, + + sss_signal(SIGHUP); + } else { ++ globbuf.gl_offs = 4; ++ ret = glob(LOG_PATH"/*.log", GLOB_ERR|GLOB_DOOFFS, NULL, &globbuf); ++ if (ret != 0) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to expand log files list\n"); ++ return ret; ++ } ++ globbuf.gl_pathv[0] = discard_const_p(char, "truncate"); ++ globbuf.gl_pathv[1] = discard_const_p(char, "--no-create"); ++ globbuf.gl_pathv[2] = discard_const_p(char, "--size"); ++ globbuf.gl_pathv[3] = discard_const_p(char, "0"); ++ + PRINT("Truncating log files...\n"); +- ret = sssctl_run_command("truncate --no-create --size 0 " LOG_FILES); ++ ret = sssctl_run_command((const char * const*)globbuf.gl_pathv); ++ globfree(&globbuf); + if (ret != EOK) { + ERROR("Unable to truncate log files\n"); + return ret; +@@ -269,8 +283,8 @@ errno_t sssctl_logs_fetch(struct sss_cmdline *cmdline, + void *pvt) + { + const char *file; +- const char *cmd; + errno_t ret; ++ glob_t globbuf; + + /* Parse command line. */ + ret = sss_tool_popt_ex(cmdline, NULL, SSS_TOOL_OPT_OPTIONAL, NULL, NULL, +@@ -280,13 +294,19 @@ errno_t sssctl_logs_fetch(struct sss_cmdline *cmdline, + return ret; + } + +- cmd = talloc_asprintf(tool_ctx, "tar -czf %s %s", file, LOG_FILES); +- if (cmd == NULL) { +- ERROR("Out of memory!"); ++ globbuf.gl_offs = 3; ++ ret = glob(LOG_PATH"/*.log", GLOB_ERR|GLOB_DOOFFS, NULL, &globbuf); ++ if (ret != 0) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to expand log files list\n"); ++ return ret; + } ++ globbuf.gl_pathv[0] = discard_const_p(char, "tar"); ++ globbuf.gl_pathv[1] = discard_const_p(char, "-czf"); ++ globbuf.gl_pathv[2] = discard_const_p(char, file); + + PRINT("Archiving log files into %s...\n", file); +- ret = sssctl_run_command(cmd); ++ ret = sssctl_run_command((const char * const*)globbuf.gl_pathv); ++ globfree(&globbuf); + if (ret != EOK) { + ERROR("Unable to archive log files\n"); + return ret; +-- +2.23.0 + diff --git a/backport-Remove-redundant-header-file-inclusion.patch b/backport-Remove-redundant-header-file-inclusion.patch new file mode 100644 index 0000000..4958831 --- /dev/null +++ b/backport-Remove-redundant-header-file-inclusion.patch @@ -0,0 +1,122 @@ +From 50cc1963f66dbfd388874775b99e604b1f7b35c5 Mon Sep 17 00:00:00 2001 +From: MIZUTA Takeshi +Date: Mon, 3 Feb 2020 18:46:20 +0900 +Subject: [PATCH] Remove redundant header file inclusion +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There are some source code including the same header file redundantly. +We remove these redundant header file inclusion. + +Reviewed-by: Pavel Březina +--- + src/monitor/monitor.c | 1 - + src/providers/ipa/ipa_netgroups.c | 1 - + src/responder/common/cache_req/cache_req.c | 1 - + src/responder/pam/pamsrv_cmd.c | 1 - + src/sss_client/sss_pac_responder_client.c | 1 - + src/tests/cmocka/test_negcache.c | 1 - + src/tools/sssctl/sssctl_logs.c | 1 - + src/util/usertools.c | 1 - + 8 files changed, 8 deletions(-) + +diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c +index a97a528ae7..a1d366e5fb 100644 +--- a/src/monitor/monitor.c ++++ b/src/monitor/monitor.c +@@ -31,7 +31,6 @@ + #ifdef HAVE_SYS_INOTIFY_H + #include + #endif +-#include + #include + #include + #include +diff --git a/src/providers/ipa/ipa_netgroups.c b/src/providers/ipa/ipa_netgroups.c +index 944bb36c27..360c803ed5 100644 +--- a/src/providers/ipa/ipa_netgroups.c ++++ b/src/providers/ipa/ipa_netgroups.c +@@ -26,7 +26,6 @@ + #include "db/sysdb.h" + #include "providers/ldap/sdap_async_private.h" + #include "providers/ipa/ipa_id.h" +-#include "db/sysdb.h" + #include + + #define ENTITY_NG 1 +diff --git a/src/responder/common/cache_req/cache_req.c b/src/responder/common/cache_req/cache_req.c +index 303cee35b7..d2be34f9ad 100644 +--- a/src/responder/common/cache_req/cache_req.c ++++ b/src/responder/common/cache_req/cache_req.c +@@ -26,7 +26,6 @@ + #include "util/util.h" + #include "responder/common/responder.h" + #include "responder/common/cache_req/cache_req_private.h" +-#include "responder/common/cache_req/cache_req_private.h" + #include "responder/common/cache_req/cache_req_plugin.h" + + static const struct cache_req_plugin * +diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c +index 72412204b4..935d01e03b 100644 +--- a/src/responder/pam/pamsrv_cmd.c ++++ b/src/responder/pam/pamsrv_cmd.c +@@ -32,7 +32,6 @@ + #include "responder/pam/pamsrv.h" + #include "responder/pam/pam_helpers.h" + #include "responder/common/cache_req/cache_req.h" +-#include "db/sysdb.h" + + enum pam_verbosity { + PAM_VERBOSITY_NO_MESSAGES = 0, +diff --git a/src/sss_client/sss_pac_responder_client.c b/src/sss_client/sss_pac_responder_client.c +index 07d92315db..450e0884e3 100644 +--- a/src/sss_client/sss_pac_responder_client.c ++++ b/src/sss_client/sss_pac_responder_client.c +@@ -24,7 +24,6 @@ + #include + #include + +-#include + #include + + #include "sss_client/sss_cli.h" +diff --git a/src/tests/cmocka/test_negcache.c b/src/tests/cmocka/test_negcache.c +index f8e4fc35ea..3ed1cb14af 100644 +--- a/src/tests/cmocka/test_negcache.c ++++ b/src/tests/cmocka/test_negcache.c +@@ -38,7 +38,6 @@ + #include "util/util_sss_idmap.h" + #include "lib/idmap/sss_idmap.h" + #include "util/util.h" +-#include "util/util_sss_idmap.h" + #include "db/sysdb_private.h" + #include "responder/common/responder.h" + #include "responder/common/negcache.h" +diff --git a/src/tools/sssctl/sssctl_logs.c b/src/tools/sssctl/sssctl_logs.c +index fc03f396c0..04a32bad85 100644 +--- a/src/tools/sssctl/sssctl_logs.c ++++ b/src/tools/sssctl/sssctl_logs.c +@@ -31,7 +31,6 @@ + #include + #include + #include +-#include + + #include "util/util.h" + #include "tools/common/sss_process.h" +diff --git a/src/util/usertools.c b/src/util/usertools.c +index 4753a89d49..eba83a4654 100644 +--- a/src/util/usertools.c ++++ b/src/util/usertools.c +@@ -22,7 +22,6 @@ + #include + #include + #include +-#include + #include + + #include "db/sysdb.h" +-- +2.23.0 + diff --git a/backport-SSSCTL-fix-logs-remove-when-log-directory-is-emtry.patch b/backport-SSSCTL-fix-logs-remove-when-log-directory-is-emtry.patch new file mode 100644 index 0000000..8b9d8d5 --- /dev/null +++ b/backport-SSSCTL-fix-logs-remove-when-log-directory-is-emtry.patch @@ -0,0 +1,38 @@ +From cf15e9eac653ee4a2d3eeed28e5fd25a299f85fb Mon Sep 17 00:00:00 2001 +From: Luiz Angelo Daros de Luca +Date: Tue, 15 Sep 2020 14:22:14 -0300 +Subject: [PATCH] SSSCTL: fix logs-remove when log directory is empty +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +"sssctl logs-remove" calls "truncate --size 0 *.log" and "*.log" +will expand to literal '*.log' when directory is empty. The result +is a new empty '*.log' file. + +Add '--no-create' to truncate call. + +Signed-off-by: Luiz Angelo Daros de Luca + +Reviewed-by: Pavel Březina +Reviewed-by: Sumit Bose +--- + src/tools/sssctl/sssctl_logs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/tools/sssctl/sssctl_logs.c b/src/tools/sssctl/sssctl_logs.c +index 04a32bad85..9ff2be05b6 100644 +--- a/src/tools/sssctl/sssctl_logs.c ++++ b/src/tools/sssctl/sssctl_logs.c +@@ -254,7 +254,7 @@ errno_t sssctl_logs_remove(struct sss_cmdline *cmdline, + sss_signal(SIGHUP); + } else { + PRINT("Truncating log files...\n"); +- ret = sssctl_run_command("truncate --size 0 " LOG_FILES); ++ ret = sssctl_run_command("truncate --no-create --size 0 " LOG_FILES); + if (ret != EOK) { + ERROR("Unable to truncate log files\n"); + return ret; +-- +2.23.0 + diff --git a/sssd.spec b/sssd.spec index a88ca09..4f59d73 100644 --- a/sssd.spec +++ b/sssd.spec @@ -1,6 +1,6 @@ Name: sssd Version: 2.2.2 -Release: 9 +Release: 10 Summary: System Security Services Daemon License: GPLv3+ and LGPLv3+ URL: https://pagure.io/SSSD/sssd/ @@ -8,6 +8,10 @@ Source0: https://releases.pagure.org/SSSD/sssd/%{name}-%{version}.tar.gz Patch0:sssd-BUILD-Accept-krb5-1.18-for-building-the-PAC-plu.patch Patch1:backport-nss-Collision-with-external-nss-symbol.patch +Patch2:backport-Added-ERROR-and-PRINT-macros-to-the-tools.patch +Patch3:backport-Remove-redundant-header-file-inclusion.patch +Patch4:backport-SSSCTL-fix-logs-remove-when-log-directory-is-emtry.patch +Patch5:backport-CVE-2021-3621.patch Requires: python3-sssd = %{version}-%{release} Requires: libldb @@ -581,6 +585,12 @@ fi %{_libdir}/%{name}/modules/libwbclient.so %changelog +* Tue Aug 31 2021 fuanan - 2.2.2-10 +- Type:CVE +- ID:CVE-2021-3621 +- SUG:NA +- DESC:fix CVE-2021-3621 + * Tue Jun 8 2021 panxiaohe - 2.2.2-9 - fix error in postun scriptlet -- Gitee