Skip to content

Commit 0ab5c4d

Browse files
authored
Merge pull request #3831 from nrwahl2/nrwahl2-refactors
Drop uses of FILENAME_MAX
2 parents ecdc327 + 52af7e6 commit 0ab5c4d

File tree

5 files changed

+201
-221
lines changed

5 files changed

+201
-221
lines changed

configure.ac

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,9 +1216,6 @@ dnl Structures
12161216
dnl ========================================================================
12171217

12181218
AC_CHECK_MEMBERS([struct tm.tm_gmtoff],,,[[#include <time.h>]])
1219-
AC_CHECK_MEMBER([struct dirent.d_type],
1220-
AC_DEFINE(HAVE_STRUCT_DIRENT_D_TYPE,1,[Define this if struct dirent has d_type]),,
1221-
[#include <dirent.h>])
12221219

12231220
dnl ========================================================================
12241221
dnl Functions

daemons/based/based_io.c

Lines changed: 5 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2004-2024 the Pacemaker project contributors
2+
* Copyright 2004-2025 the Pacemaker project contributors
33
*
44
* The version control history for this file may have further details.
55
*
@@ -86,25 +86,10 @@ retrieveCib(const char *filename, const char *sigfile)
8686
return root;
8787
}
8888

89-
/*
90-
* for OSs without support for direntry->d_type, like Solaris
91-
*/
92-
#ifndef DT_UNKNOWN
93-
# define DT_UNKNOWN 0
94-
# define DT_FIFO 1
95-
# define DT_CHR 2
96-
# define DT_DIR 4
97-
# define DT_BLK 6
98-
# define DT_REG 8
99-
# define DT_LNK 10
100-
# define DT_SOCK 12
101-
# define DT_WHT 14
102-
#endif /*DT_UNKNOWN*/
103-
10489
static int cib_archive_filter(const struct dirent * a)
10590
{
10691
int rc = 0;
107-
/* Looking for regular files (d_type = 8) starting with 'cib-' and not ending in .sig */
92+
// Looking for regular files starting with "cib-" and not ending in .sig
10893
struct stat s;
10994
char *a_path = crm_strdup_printf("%s/%s", cib_root, a->d_name);
11095

@@ -113,23 +98,9 @@ static int cib_archive_filter(const struct dirent * a)
11398
crm_trace("%s - stat failed: %s (%d)", a->d_name, pcmk_rc_str(rc), rc);
11499
rc = 0;
115100

116-
} else if ((s.st_mode & S_IFREG) != S_IFREG) {
117-
unsigned char dtype;
118-
#ifdef HAVE_STRUCT_DIRENT_D_TYPE
119-
dtype = a->d_type;
120-
#else
121-
switch (s.st_mode & S_IFMT) {
122-
case S_IFREG: dtype = DT_REG; break;
123-
case S_IFDIR: dtype = DT_DIR; break;
124-
case S_IFCHR: dtype = DT_CHR; break;
125-
case S_IFBLK: dtype = DT_BLK; break;
126-
case S_IFLNK: dtype = DT_LNK; break;
127-
case S_IFIFO: dtype = DT_FIFO; break;
128-
case S_IFSOCK: dtype = DT_SOCK; break;
129-
default: dtype = DT_UNKNOWN; break;
130-
}
131-
#endif
132-
crm_trace("%s - wrong type (%d)", a->d_name, dtype);
101+
} else if (!S_ISREG(s.st_mode)) {
102+
crm_trace("%s - wrong type (%#o)",
103+
a->d_name, (unsigned int) (s.st_mode & S_IFMT));
133104

134105
} else if(strstr(a->d_name, "cib-") != a->d_name) {
135106
crm_trace("%s - wrong prefix", a->d_name);

lib/common/cib_secrets.c

Lines changed: 118 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2011-2020 the Pacemaker project contributors
2+
* Copyright 2011-2025 the Pacemaker project contributors
33
*
44
* The version control history for this file may have further details.
55
*
@@ -23,60 +23,93 @@
2323

2424
#include <crm/common/util.h>
2525

26-
static int is_magic_value(char *p);
27-
static bool check_md5_hash(char *hash, char *value);
28-
static void add_secret_params(gpointer key, gpointer value, gpointer user_data);
29-
static char *read_local_file(char *local_file);
30-
31-
#define MAX_VALUE_LEN 255
32-
#define MAGIC "lrm://"
33-
34-
static int
35-
is_magic_value(char *p)
26+
/*!
27+
* \internal
28+
* \brief Read file contents into a string, with trailing whitespace removed
29+
*
30+
* \param[in] filename Name of file to read
31+
*
32+
* \return File contents as a string, or \c NULL on failure or empty file
33+
*
34+
* \note It would be simpler to call \c pcmk__file_contents() directly without
35+
* trimming trailing whitespace. However, this would change hashes for
36+
* existing value files that have trailing whitespace. Similarly, if we
37+
* trim trailing whitespace, it would make sense to trim leading
38+
* whitespace, but this changes existing hashes.
39+
*/
40+
static char *
41+
read_file_trimmed(const char *filename)
3642
{
37-
return !strcmp(p, MAGIC);
38-
}
43+
char *p = NULL;
44+
char *buf = NULL;
45+
int rc = pcmk__file_contents(filename, &buf);
3946

40-
static bool
41-
check_md5_hash(char *hash, char *value)
42-
{
43-
bool rc = false;
44-
char *hash2 = NULL;
47+
if (rc != pcmk_rc_ok) {
48+
crm_err("Failed to read %s: %s", filename, pcmk_rc_str(rc));
49+
free(buf);
50+
return NULL;
51+
}
4552

46-
hash2 = crm_md5sum(value);
47-
crm_debug("hash: %s, calculated hash: %s", hash, hash2);
48-
if (pcmk__str_eq(hash, hash2, pcmk__str_casei)) {
49-
rc = true;
53+
if (buf == NULL) {
54+
crm_err("File %s is empty", filename);
55+
return NULL;
5056
}
51-
free(hash2);
52-
return rc;
57+
58+
// Strip trailing white space
59+
for (p = buf + strlen(buf) - 1; (p >= buf) && isspace(*p); p--);
60+
*(p + 1) = '\0';
61+
62+
return buf;
5363
}
5464

55-
static char *
56-
read_local_file(char *local_file)
65+
/*!
66+
* \internal
67+
* \brief Read checksum from a file and compare against calculated checksum
68+
*
69+
* \param[in] filename File containing stored checksum
70+
* \param[in] secret_value String to calculate checksum from
71+
* \param[in] rsc_id Resource ID (for logging only)
72+
* \param[in] param Parameter name (for logging only)
73+
*
74+
* \return Standard Pacemaker return code
75+
*/
76+
static int
77+
validate_hash(const char *filename, const char *secret_value,
78+
const char *rsc_id, const char *param)
5779
{
58-
FILE *fp = fopen(local_file, "r");
59-
char buf[MAX_VALUE_LEN+1];
60-
char *p;
80+
char *stored = NULL;
81+
char *calculated = NULL;
82+
int rc = pcmk_rc_ok;
6183

62-
if (!fp) {
63-
if (errno != ENOENT) {
64-
crm_perror(LOG_ERR, "cannot open %s" , local_file);
65-
}
66-
return NULL;
84+
stored = read_file_trimmed(filename);
85+
if (stored == NULL) {
86+
crm_err("Could not read md5 sum for resource %s parameter '%s' from "
87+
"file '%s'",
88+
rsc_id, param, filename);
89+
rc = ENOENT;
90+
goto done;
6791
}
6892

69-
if (!fgets(buf, MAX_VALUE_LEN, fp)) {
70-
crm_perror(LOG_ERR, "cannot read %s", local_file);
71-
fclose(fp);
72-
return NULL;
93+
calculated = crm_md5sum(secret_value);
94+
if (calculated == NULL) {
95+
// Should be impossible
96+
rc = EINVAL;
97+
goto done;
7398
}
74-
fclose(fp);
7599

76-
// Strip trailing white space
77-
for (p = buf + strlen(buf) - 1; (p >= buf) && isspace(*p); p--);
78-
*(p+1) = '\0';
79-
return strdup(buf);
100+
crm_trace("Stored hash: %s, calculated hash: %s", stored, calculated);
101+
102+
if (!pcmk__str_eq(stored, calculated, pcmk__str_casei)) {
103+
crm_err("Calculated md5 sum for resource %s parameter '%s' does not "
104+
"match stored md5 sum",
105+
rsc_id, param);
106+
rc = pcmk_rc_cib_corrupt;
107+
}
108+
109+
done:
110+
free(stored);
111+
free(calculated);
112+
return rc;
80113
}
81114

82115
/*!
@@ -95,98 +128,68 @@ read_local_file(char *local_file)
95128
int
96129
pcmk__substitute_secrets(const char *rsc_id, GHashTable *params)
97130
{
98-
char local_file[FILENAME_MAX+1], *start_pname;
99-
char hash_file[FILENAME_MAX+1], *hash;
100-
GList *secret_params = NULL, *l;
101-
char *key, *pvalue, *secret_value;
131+
GHashTableIter iter;
132+
char *param = NULL;
133+
char *value = NULL;
134+
GString *filename = NULL;
135+
gsize dir_len = 0;
102136
int rc = pcmk_rc_ok;
103137

104138
if (params == NULL) {
105139
return pcmk_rc_ok;
106140
}
107141

108-
/* secret_params could be cached with the resource;
109-
* there are also parameters sent with operations
110-
* which cannot be cached
111-
*/
112-
g_hash_table_foreach(params, add_secret_params, &secret_params);
113-
if (secret_params == NULL) { // No secret parameters found
114-
return pcmk_rc_ok;
115-
}
116-
117-
crm_debug("Replace secret parameters for resource %s", rsc_id);
142+
// Some params are sent with operations, so we cannot cache secret params
143+
g_hash_table_iter_init(&iter, params);
144+
while (g_hash_table_iter_next(&iter, (gpointer *) &param,
145+
(gpointer *) &value)) {
146+
char *secret_value = NULL;
147+
int hash_rc = pcmk_rc_ok;
118148

119-
if (snprintf(local_file, FILENAME_MAX, PCMK__CIB_SECRETS_DIR "/%s/", rsc_id)
120-
> FILENAME_MAX) {
121-
crm_err("Can't replace secret parameters for %s: file name size exceeded",
122-
rsc_id);
123-
return ENAMETOOLONG;
124-
}
125-
start_pname = local_file + strlen(local_file);
126-
127-
for (l = g_list_first(secret_params); l; l = g_list_next(l)) {
128-
key = (char *)(l->data);
129-
pvalue = g_hash_table_lookup(params, key);
130-
if (!pvalue) { /* this cannot really happen */
131-
crm_err("odd, no parameter %s for rsc %s found now", key, rsc_id);
149+
if (!pcmk__str_eq(value, "lrm://", pcmk__str_none)) {
150+
// Not a secret parameter
132151
continue;
133152
}
134153

135-
if ((strlen(key) + strlen(local_file)) >= FILENAME_MAX-2) {
136-
crm_err("%s: parameter name %s too big", rsc_id, key);
137-
rc = ENAMETOOLONG;
138-
continue;
154+
if (filename == NULL) {
155+
// First secret parameter. Fill in directory path for use with all.
156+
crm_debug("Replacing secret parameters for resource %s", rsc_id);
157+
158+
filename = g_string_sized_new(128);
159+
pcmk__g_strcat(filename, PCMK__CIB_SECRETS_DIR "/", rsc_id, "/",
160+
NULL);
161+
dir_len = filename->len;
162+
163+
} else {
164+
// Reset filename to the resource's secrets directory path
165+
g_string_truncate(filename, dir_len);
139166
}
140167

141-
strcpy(start_pname, key);
142-
secret_value = read_local_file(local_file);
143-
if (!secret_value) {
144-
crm_err("secret for rsc %s parameter %s not found in %s",
145-
rsc_id, key, PCMK__CIB_SECRETS_DIR);
168+
// Path to file containing secret value for this parameter
169+
g_string_append(filename, param);
170+
secret_value = read_file_trimmed(filename->str);
171+
if (secret_value == NULL) {
172+
crm_err("Secret value for resource %s parameter '%s' not found in "
173+
PCMK__CIB_SECRETS_DIR,
174+
rsc_id, param);
146175
rc = ENOENT;
147176
continue;
148177
}
149178

150-
strcpy(hash_file, local_file);
151-
if (strlen(hash_file) + 5 > FILENAME_MAX) {
152-
crm_err("cannot build such a long name "
153-
"for the sign file: %s.sign", hash_file);
179+
// Path to file containing md5 sum for this parameter
180+
g_string_append(filename, ".sign");
181+
hash_rc = validate_hash(filename->str, secret_value, rsc_id, param);
182+
if (hash_rc != pcmk_rc_ok) {
183+
rc = hash_rc;
154184
free(secret_value);
155-
rc = ENAMETOOLONG;
156185
continue;
157-
158-
} else {
159-
strcat(hash_file, ".sign");
160-
hash = read_local_file(hash_file);
161-
if (hash == NULL) {
162-
crm_err("md5 sum for rsc %s parameter %s "
163-
"cannot be read from %s", rsc_id, key, hash_file);
164-
free(secret_value);
165-
rc = ENOENT;
166-
continue;
167-
168-
} else if (!check_md5_hash(hash, secret_value)) {
169-
crm_err("md5 sum for rsc %s parameter %s "
170-
"does not match", rsc_id, key);
171-
free(secret_value);
172-
free(hash);
173-
rc = pcmk_rc_cib_corrupt;
174-
continue;
175-
}
176-
free(hash);
177186
}
178-
g_hash_table_replace(params, strdup(key), secret_value);
179-
}
180-
g_list_free(secret_params);
181-
return rc;
182-
}
183187

184-
static void
185-
add_secret_params(gpointer key, gpointer value, gpointer user_data)
186-
{
187-
GList **lp = (GList **)user_data;
188+
g_hash_table_iter_replace(&iter, (gpointer) secret_value);
189+
}
188190

189-
if (is_magic_value((char *)value)) {
190-
*lp = g_list_append(*lp, (char *)key);
191+
if (filename != NULL) {
192+
g_string_free(filename, TRUE);
191193
}
194+
return rc;
192195
}

0 commit comments

Comments
 (0)