146 lines
5.4 KiB
Diff
146 lines
5.4 KiB
Diff
|
From 7703a7efe1ed4800a7676cfaac9bd00fec7de1c4 Mon Sep 17 00:00:00 2001
|
||
|
From: Jakub Hrozek <jhrozek@redhat.com>
|
||
|
Date: Wed, 4 Apr 2018 14:13:56 +0200
|
||
|
Subject: [PATCH] FILES: Skip files that are not created yet
|
||
|
MIME-Version: 1.0
|
||
|
Content-Type: text/plain; charset=UTF-8
|
||
|
Content-Transfer-Encoding: 8bit
|
||
|
|
||
|
In order to avoid complex ordering logic, even if one file is updated,
|
||
|
we flush all the entries. In theory, we could only flush the individual
|
||
|
file and all the files preceding it, but it's safer to just create a
|
||
|
complete mirror every time.
|
||
|
|
||
|
And this can be problematic if one of the files we try to update is not
|
||
|
created yet during the update. This can happen e.g. when a file is not
|
||
|
created during early boot.
|
||
|
|
||
|
To solve this, try to be very defensive and always flush the whole
|
||
|
database, ignore ENOENT errors, but abort on all other errors.
|
||
|
|
||
|
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||
|
(cherry picked from commit c1bce7da6c33b352dc708a5dd9712a4d96c63057)
|
||
|
---
|
||
|
src/providers/files/files_ops.c | 22 ++++++++++---
|
||
|
src/tests/intg/test_files_provider.py | 60 +++++++++++++++++++++++++++++++++++
|
||
|
2 files changed, 78 insertions(+), 4 deletions(-)
|
||
|
|
||
|
diff --git a/src/providers/files/files_ops.c b/src/providers/files/files_ops.c
|
||
|
index b91078417..f5a40297a 100644
|
||
|
--- a/src/providers/files/files_ops.c
|
||
|
+++ b/src/providers/files/files_ops.c
|
||
|
@@ -734,8 +734,15 @@ static errno_t sf_enum_files(struct files_id_ctx *id_ctx,
|
||
|
/* All users were deleted, therefore we need to enumerate each file again */
|
||
|
for (size_t i = 0; id_ctx->passwd_files[i] != NULL; i++) {
|
||
|
ret = sf_enum_users(id_ctx, id_ctx->passwd_files[i]);
|
||
|
- if (ret != EOK) {
|
||
|
- DEBUG(SSSDBG_OP_FAILURE, "Cannot enumerate users\n");
|
||
|
+ if (ret == ENOENT) {
|
||
|
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
||
|
+ "The file %s does not exist (yet), skipping\n",
|
||
|
+ id_ctx->passwd_files[i]);
|
||
|
+ continue;
|
||
|
+ } else if (ret != EOK) {
|
||
|
+ DEBUG(SSSDBG_OP_FAILURE,
|
||
|
+ "Cannot enumerate users from %s, aborting\n",
|
||
|
+ id_ctx->passwd_files[i]);
|
||
|
goto done;
|
||
|
}
|
||
|
}
|
||
|
@@ -750,8 +757,15 @@ static errno_t sf_enum_files(struct files_id_ctx *id_ctx,
|
||
|
/* All groups were deleted, therefore we need to enumerate each file again */
|
||
|
for (size_t i = 0; id_ctx->group_files[i] != NULL; i++) {
|
||
|
ret = sf_enum_groups(id_ctx, id_ctx->group_files[i]);
|
||
|
- if (ret != EOK) {
|
||
|
- DEBUG(SSSDBG_OP_FAILURE, "Cannot enumerate groups\n");
|
||
|
+ if (ret == ENOENT) {
|
||
|
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
||
|
+ "The file %s does not exist (yet), skipping\n",
|
||
|
+ id_ctx->group_files[i]);
|
||
|
+ continue;
|
||
|
+ } else if (ret != EOK) {
|
||
|
+ DEBUG(SSSDBG_OP_FAILURE,
|
||
|
+ "Cannot enumerate groups from %s, aborting\n",
|
||
|
+ id_ctx->group_files[i]);
|
||
|
goto done;
|
||
|
}
|
||
|
}
|
||
|
diff --git a/src/tests/intg/test_files_provider.py b/src/tests/intg/test_files_provider.py
|
||
|
index ce5c7b774..cc9c1f1c7 100644
|
||
|
--- a/src/tests/intg/test_files_provider.py
|
||
|
+++ b/src/tests/intg/test_files_provider.py
|
||
|
@@ -187,6 +187,40 @@ def files_multiple_sources(request):
|
||
|
return alt_pwops, alt_grops
|
||
|
|
||
|
|
||
|
+@pytest.fixture
|
||
|
+def files_multiple_sources_nocreate(request):
|
||
|
+ """
|
||
|
+ Sets up SSSD with multiple sources, but does not actually create
|
||
|
+ the files.
|
||
|
+ """
|
||
|
+ alt_passwd_path = tempfile.mktemp(prefix='altpasswd')
|
||
|
+ request.addfinalizer(lambda: os.unlink(alt_passwd_path))
|
||
|
+
|
||
|
+ alt_group_path = tempfile.mktemp(prefix='altgroup')
|
||
|
+ request.addfinalizer(lambda: os.unlink(alt_group_path))
|
||
|
+
|
||
|
+ passwd_list = ",".join([os.environ["NSS_WRAPPER_PASSWD"], alt_passwd_path])
|
||
|
+ group_list = ",".join([os.environ["NSS_WRAPPER_GROUP"], alt_group_path])
|
||
|
+
|
||
|
+ conf = unindent("""\
|
||
|
+ [sssd]
|
||
|
+ domains = files
|
||
|
+ services = nss
|
||
|
+
|
||
|
+ [nss]
|
||
|
+ debug_level = 10
|
||
|
+
|
||
|
+ [domain/files]
|
||
|
+ id_provider = files
|
||
|
+ passwd_files = {passwd_list}
|
||
|
+ group_files = {group_list}
|
||
|
+ debug_level = 10
|
||
|
+ """).format(**locals())
|
||
|
+ create_conf_fixture(request, conf)
|
||
|
+ create_sssd_fixture(request)
|
||
|
+ return alt_passwd_path, alt_group_path
|
||
|
+
|
||
|
+
|
||
|
@pytest.fixture
|
||
|
def proxy_to_files_domain_only(request):
|
||
|
conf = unindent("""\
|
||
|
@@ -1113,3 +1147,29 @@ def test_multiple_passwd_group_files(add_user_with_canary,
|
||
|
|
||
|
check_group(GROUP1)
|
||
|
check_group(ALT_GROUP1)
|
||
|
+
|
||
|
+
|
||
|
+def test_multiple_files_created_after_startup(add_user_with_canary,
|
||
|
+ add_group_with_canary,
|
||
|
+ files_multiple_sources_nocreate):
|
||
|
+ """
|
||
|
+ Test that users and groups can be mirrored from multiple files,
|
||
|
+ but those files are not created when SSSD starts, only afterwards.
|
||
|
+ """
|
||
|
+ alt_passwd_path, alt_group_path = files_multiple_sources_nocreate
|
||
|
+
|
||
|
+ check_user(USER1)
|
||
|
+ check_group(GROUP1)
|
||
|
+
|
||
|
+ # touch the files
|
||
|
+ for fpath in (alt_passwd_path, alt_group_path):
|
||
|
+ with open(fpath, "w") as f:
|
||
|
+ pass
|
||
|
+
|
||
|
+ alt_pwops = PasswdOps(alt_passwd_path)
|
||
|
+ alt_grops = GroupOps(alt_group_path)
|
||
|
+ alt_pwops.useradd(**ALT_USER1)
|
||
|
+ alt_grops.groupadd(**ALT_GROUP1)
|
||
|
+
|
||
|
+ check_user(ALT_USER1)
|
||
|
+ check_group(ALT_GROUP1)
|
||
|
--
|
||
|
2.14.3
|
||
|
|