From b959b5f92a8f098fae6f285ba46726c14640b707 Mon Sep 17 00:00:00 2001 From: Lars Erik Wik Date: Tue, 4 Nov 2025 12:30:11 +0100 Subject: [PATCH 1/5] Added test for overriding default directory create mode Ticket: CFE-4590, ENT-13239 Signed-off-by: Lars Erik Wik --- ...t_control_default_directory_create_mode.cf | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 tests/acceptance/10_files/agent_control_default_directory_create_mode.cf diff --git a/tests/acceptance/10_files/agent_control_default_directory_create_mode.cf b/tests/acceptance/10_files/agent_control_default_directory_create_mode.cf new file mode 100644 index 0000000000..d6702b31bb --- /dev/null +++ b/tests/acceptance/10_files/agent_control_default_directory_create_mode.cf @@ -0,0 +1,71 @@ +############################################################################## +# +# Test overriding default directory create mode (CFE-4590, ENT-13239). +# +############################################################################## + + +body common control +{ + inputs => { "../default.cf.sub" }; + bundlesequence => { default("$(this.promise_filename)") }; + version => "1.0"; +} + +body agent control { + # Override the default directory create mode to 0755 (it defaults to 0700 if + # not specified) + default_directory_create_mode => "a+rx"; # Can also use octets 0755 +} + +############################################################################## + +bundle agent init +{ + methods: + "clean"; +} + +############################################################################## + +bundle agent test +{ + meta: + "description" -> { "CFE-4590", "ENT-13239" } + string => "Test overriding default directory create mode"; + + files: + "$(G.testdir)/foo/config.txt" + create => "true", + perms => m(0655); +} + +############################################################################## + +bundle agent check +{ + vars: + "expected" + string => "[0-9]*755", + comment => "We only care about the last three octets (i.e., 755)"; + "actual" + string => filestat("$(G.testdir)/foo/", "modeoct"); + + methods: + "Pass/FAIL" + usebundle => dcs_check_regcmp("$(expected)", "$(actual)", + "$(this.promise_filename)", "false"); + + reports: + "Expected $(expected), actual $(actual)"; +} + +############################################################################## + +bundle agent clean +{ + files: + "$(G.testdir)/foo/." + delete => tidy, + if => fileexist("$(this.promiser)"); +} From 59827e8b311a4ca88f53a99ca1502b9781aacd76 Mon Sep 17 00:00:00 2001 From: Lars Erik Wik Date: Tue, 4 Nov 2025 14:58:04 +0100 Subject: [PATCH 2/5] Skip remaining string comparisons after successful match Signed-off-by: Lars Erik Wik --- cf-agent/cf-agent.c | 1 + 1 file changed, 1 insertion(+) diff --git a/cf-agent/cf-agent.c b/cf-agent/cf-agent.c index 7a7ad905fc..a42006c30d 100644 --- a/cf-agent/cf-agent.c +++ b/cf-agent/cf-agent.c @@ -1337,6 +1337,7 @@ static void KeepControlPromises(EvalContext *ctx, const Policy *policy, GenericA { Log(LOG_LEVEL_VERBOSE, "SET select_end_match_eof %s", (char *) value); EvalContextSetSelectEndMatchEof(ctx, BooleanFromString(value)); + continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_REPORTCLASSLOG].lval) == 0) From 928eb806f95609f2ac56b41125c4a7f8eefb186d Mon Sep 17 00:00:00 2001 From: Lars Erik Wik Date: Tue, 4 Nov 2025 15:08:12 +0100 Subject: [PATCH 3/5] Added default_directory_create_mode to body agent control Allow overriding the default 0700 permissions when `cf-agent` creates parent directories during file promise repairs. The new attribute `default_directory_create_mode` in body agent control enables users to specify custom permissions (e.g., 0755) for automatically created directories, avoiding the need for explicit perms promises on each parent directory when deeper paths are required. This addresses cases where files need broader access permissions but their auto-created parent directories would otherwise default to 0700, making the files inaccessible despite having correct permissions. Example usage: ``` body agent control { default_directory_create_mode => "0755"; } ``` Ticket: CFE-4590, ENT-13239 Changelog: Title Signed-off-by: Lars Erik Wik --- cf-agent/cf-agent.c | 21 +++++++++++++++++++++ libpromises/cf3.defs.h | 3 +-- libpromises/cf3.extern.h | 2 ++ libpromises/cf3globals.c | 7 +++++++ libpromises/mod_common.c | 1 + 5 files changed, 32 insertions(+), 2 deletions(-) diff --git a/cf-agent/cf-agent.c b/cf-agent/cf-agent.c index a42006c30d..c30c049724 100644 --- a/cf-agent/cf-agent.c +++ b/cf-agent/cf-agent.c @@ -1363,6 +1363,27 @@ static void KeepControlPromises(EvalContext *ctx, const Policy *policy, GenericA { EvalContextSetAgentEvalOrder(ctx, EVAL_ORDER_CLASSIC); } + continue; + } + + if (StringEqual(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_DEFAULT_DIRECTORY_CREATE_MODE].lval)) + { + assert(value_type == CF_DATA_TYPE_STRING); + const char *mode_str = value; + mode_t plus, minus; + if (ParseModeString(mode_str, &plus, &minus)) + { + DEFAULTMODE |= plus; + DEFAULTMODE &= ~minus; + Log(LOG_LEVEL_VERBOSE, "Changed default directory create mode to %ju " + "(default_directory_create_mode => \"%s\")", (uintmax_t) DEFAULTMODE, mode_str); + } + else + { + Log(LOG_LEVEL_ERR, "Failed to parse mode string for overriding default directory create mode " + "(default_directory_create_mode => \"%s\")", mode_str); + } + continue; } } } diff --git a/libpromises/cf3.defs.h b/libpromises/cf3.defs.h index cea29e672b..c3e6e87aee 100644 --- a/libpromises/cf3.defs.h +++ b/libpromises/cf3.defs.h @@ -344,8 +344,6 @@ struct GidList_ #define CF_NOINT -678L #define CF_UNDEFINED_ITEM (void *)0x1234 -#define DEFAULTMODE ((mode_t)0700) - #define CF_DONEPASSES 4 #define CFPULSETIME 60 @@ -496,6 +494,7 @@ typedef enum AGENT_CONTROL_SELECT_END_MATCH_EOF, AGENT_CONTROL_COPYFROM_RESTRICT_KEYS, AGENT_CONTROL_EVALUATION_ORDER, + AGENT_CONTROL_DEFAULT_DIRECTORY_CREATE_MODE, AGENT_CONTROL_NONE } AgentControl; diff --git a/libpromises/cf3.extern.h b/libpromises/cf3.extern.h index d8d93f5341..6303b170b9 100644 --- a/libpromises/cf3.extern.h +++ b/libpromises/cf3.extern.h @@ -48,6 +48,8 @@ extern char VFQNAME[CF_MAXVARSIZE]; extern char VDOMAIN[CF_MAXVARSIZE / 2]; extern char VUQNAME[CF_MAXVARSIZE / 2]; +extern mode_t DEFAULTMODE; + typedef enum EvalMode { EVAL_MODE_NORMAL = 0, /* needs to be 'false' to work for DONTDO below */ EVAL_MODE_DRY_RUN = 1, diff --git a/libpromises/cf3globals.c b/libpromises/cf3globals.c index 745cfc50a1..f14f4d39c6 100644 --- a/libpromises/cf3globals.c +++ b/libpromises/cf3globals.c @@ -154,3 +154,10 @@ char BINDINTERFACE[CF_MAXVARSIZE]; /* GLOBAL_P */ - GenericAgentLoadPolicy (ReadPolicyValidatedFile) */ bool MINUSF = false; /* GLOBAL_A */ + +/* + Can be mutated in cf-agent.c (from control body) + + Used as default directory create mode. +*/ +mode_t DEFAULTMODE = (mode_t) 0700; diff --git a/libpromises/mod_common.c b/libpromises/mod_common.c index d017b8cca3..24e9788bce 100644 --- a/libpromises/mod_common.c +++ b/libpromises/mod_common.c @@ -321,6 +321,7 @@ const ConstraintSyntax CFA_CONTROLBODY[] = ConstraintSyntaxNewBool("select_end_match_eof", "Set the default behavior of select_end_match_eof in edit_line promises. Default: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("copyfrom_restrict_keys", ".*", "A list of key hashes to restrict copy_from to", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("evaluation_order", "(classic|top_down)", "Order of evaluation of promises of agent", SYNTAX_STATUS_NORMAL), + ConstraintSyntaxNewString("default_directory_create_mode", ".*", "Default directory create mode (defaults to 0700 if not specified)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; From 01e1a5a8ade485de9684bd38a76923a5723e648a Mon Sep 17 00:00:00 2001 From: Lars Erik Wik Date: Tue, 4 Nov 2025 15:18:00 +0100 Subject: [PATCH 4/5] Replaced hardcoded directory create mode with DEFAULTMODE Signed-off-by: Lars Erik Wik --- cf-agent/verify_files_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cf-agent/verify_files_utils.c b/cf-agent/verify_files_utils.c index a743df1fb4..6a195e3e18 100644 --- a/cf-agent/verify_files_utils.c +++ b/cf-agent/verify_files_utils.c @@ -1019,7 +1019,7 @@ static PromiseResult SourceSearchAndCopy(EvalContext *ctx, const char *from, cha if ((!attr->copy.collapse) && (stat(newto, &dsb) == -1)) { - if (mkdir(changes_newto, 0700) == -1) + if (mkdir(changes_newto, DEFAULTMODE) == -1) { RecordInterruption(ctx, pp, attr, "Can't make directory '%s'. (mkdir: %s)", newto, GetErrorStr()); From 3b554e80f0d6984774e22b153bb93063c0a7fae2 Mon Sep 17 00:00:00 2001 From: Lars Erik Wik Date: Sun, 9 Nov 2025 16:17:10 +0100 Subject: [PATCH 5/5] Make sure the last configuration wins When default create mode is configured multiple times, then make sure the last configuration always wins. Ticket: CFE-4590, ENT-13239 Signed-off-by: Lars Erik Wik --- .../10_files/agent_control_default_directory_create_mode.cf | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/acceptance/10_files/agent_control_default_directory_create_mode.cf b/tests/acceptance/10_files/agent_control_default_directory_create_mode.cf index d6702b31bb..9e79ab2100 100644 --- a/tests/acceptance/10_files/agent_control_default_directory_create_mode.cf +++ b/tests/acceptance/10_files/agent_control_default_directory_create_mode.cf @@ -15,6 +15,7 @@ body common control body agent control { # Override the default directory create mode to 0755 (it defaults to 0700 if # not specified) + default_directory_create_mode => "0777"; # Make sure the last one wins default_directory_create_mode => "a+rx"; # Can also use octets 0755 }