URL: https://github.com/SSSD/sssd/pull/5825
Author: sumit-bose
 Title: #5825: krb5: use hidden file when creating config snippets
Action: opened

PR body:
"""
When creating config snippets fir libkrb5 SSSD first creates a temporary
file with a random suffix and renames this file after all content is
written. If this temporary file is not properly removed or renamed dur
to an error it might confuse libkrb5.

To avoid this confusion with this patch the temporary files are created
as hidden files, the name will start with a '.', which are ignored by
libkrb5.

Resolves: https://github.com/SSSD/sssd/issues/5824
"""

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/5825/head:pr5825
git checkout pr5825
From ecb4a007571baf73f03ad08c23ab76b56659d4f1 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sb...@redhat.com>
Date: Wed, 13 Oct 2021 09:54:53 +0200
Subject: [PATCH] krb5: use hidden file when creating config snippets

When creating config snippets fir libkrb5 SSSD first creates a temporary
file with a random suffix and renames this file after all content is
written. If this temporary file is not properly removed or renamed dur
to an error it might confuse libkrb5.

To avoid this confusion with this patch the temporary files are created
as hidden files, the name will start with a '.', which are ignored by
libkrb5.

Resolves: https://github.com/SSSD/sssd/issues/5824
---
 src/tests/cmocka/test_utils.c | 21 +++++++++++++++++++++
 src/util/domain_info_utils.c  | 26 ++++++++++++++++++++++++--
 src/util/util.h               |  2 ++
 3 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/src/tests/cmocka/test_utils.c b/src/tests/cmocka/test_utils.c
index 536cee59f4..6661740087 100644
--- a/src/tests/cmocka/test_utils.c
+++ b/src/tests/cmocka/test_utils.c
@@ -1513,6 +1513,26 @@ void test_sss_write_krb5_conf_snippet(void **state)
     free(path);
 }
 
+void test_get_hidden_path(void **state)
+{
+    char *s;
+
+    assert_null(get_hidden_tmp_path(NULL, NULL));
+    assert_null(get_hidden_tmp_path(NULL, "/"));
+    assert_null(get_hidden_tmp_path(NULL, "/abc/"));
+
+    s = get_hidden_tmp_path(NULL, "abc");
+    assert_string_equal(s, ".abcXXXXXX");
+    talloc_free(s);
+
+    s = get_hidden_tmp_path(NULL, "/abc");
+    assert_string_equal(s, "/.abcXXXXXX");
+    talloc_free(s);
+
+    s = get_hidden_tmp_path(NULL, "/xyz/xyz/xyz//abc");
+    assert_string_equal(s, "/xyz/xyz/xyz//.abcXXXXXX");
+    talloc_free(s);
+}
 
 struct unique_file_test_ctx {
     char *filename;
@@ -2127,6 +2147,7 @@ int main(int argc, const char *argv[])
                                         setup_leak_tests,
                                         teardown_leak_tests),
         cmocka_unit_test(test_sss_write_krb5_conf_snippet),
+        cmocka_unit_test(test_get_hidden_path),
         cmocka_unit_test_setup_teardown(test_sss_unique_file,
                                         unique_file_test_setup,
                                         unique_file_test_teardown),
diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c
index c2e510ecf1..0673930ee3 100644
--- a/src/util/domain_info_utils.c
+++ b/src/util/domain_info_utils.c
@@ -471,7 +471,7 @@ sss_write_domain_mappings(struct sss_domain_info *domain)
     DEBUG(SSSDBG_FUNC_DATA, "Mapping file for domain [%s] is [%s]\n",
                              domain->name, mapping_file);
 
-    tmp_file = talloc_asprintf(tmp_ctx, "%sXXXXXX", mapping_file);
+    tmp_file = get_hidden_tmp_path(tmp_ctx, mapping_file);
     if (tmp_file == NULL) {
         ret = ENOMEM;
         goto done;
@@ -631,6 +631,28 @@ errno_t get_dom_names(TALLOC_CTX *mem_ctx,
     return ret;
 }
 
+char *get_hidden_tmp_path(TALLOC_CTX *mem_ctx, const char *path)
+{
+    char *s;
+
+    if (path == NULL) {
+        return NULL;
+    }
+
+    s = strrchr(path, '/');
+    if (s == NULL) {
+        /* No path, just file name */
+        return talloc_asprintf(mem_ctx, ".%sXXXXXX", path);
+    } else if ( *(s + 1) == '\0') {
+        /* '/' is the last character, there is no filename */
+        DEBUG(SSSDBG_OP_FAILURE, "Missing file name in [%s].\n", path);
+        return NULL;
+    }
+
+    return talloc_asprintf(mem_ctx, "%.*s.%sXXXXXX", (int)(s - path + 1),
+                                                     path, s+1);
+}
+
 static errno_t sss_write_krb5_snippet_common(const char *file_name,
                                              const char *content)
 {
@@ -649,7 +671,7 @@ static errno_t sss_write_krb5_snippet_common(const char *file_name,
         return ENOMEM;
     }
 
-    tmp_file = talloc_asprintf(tmp_ctx, "%sXXXXXX", file_name);
+    tmp_file = get_hidden_tmp_path(tmp_ctx, file_name);
     if (tmp_file == NULL) {
         DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
         ret = ENOMEM;
diff --git a/src/util/util.h b/src/util/util.h
index bcbb9ac72f..e85cd12022 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -637,6 +637,8 @@ errno_t sss_get_domain_mappings_content(TALLOC_CTX *mem_ctx,
 
 errno_t sss_write_domain_mappings(struct sss_domain_info *domain);
 
+char *get_hidden_tmp_path(TALLOC_CTX *mem_ctx, const char *path);
+
 errno_t sss_write_krb5_conf_snippet(const char *path, bool canonicalize,
                                     bool udp_limit);
 
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedorahosted.org/archives/list/sssd-devel@lists.fedorahosted.org
Do not reply to spam on the list, report it: 
https://pagure.io/fedora-infrastructure

Reply via email to