cfengine  3.15.4
About: CFEngine is a configuration management system for configuring and maintaining Unix-like computers (using an own high level policy language). Community version.
  Fossies Dox: cfengine-3.15.4.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

loading.c
Go to the documentation of this file.
1 /*
2  Copyright 2019 Northern.tech AS
3 
4  This file is part of CFEngine 3 - written and maintained by Northern.tech AS.
5 
6  This program is free software; you can redistribute it and/or modify it
7  under the terms of the GNU General Public License as published by the
8  Free Software Foundation; version 3.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
18 
19  To the extent this program is licensed as part of the Enterprise
20  versions of CFEngine, the applicable Commercial Open Source License
21  (COSL) may apply to this file if you as a licensee so wish it. See
22  included file COSL.txt.
23 */
24 #include <loading.h>
25 
26 #include <eval_context.h>
27 #include <hash.h>
28 #include <file_lib.h>
29 #include <files_names.h>
30 #include <string_lib.h>
31 #include <writer.h>
32 #include <parser.h>
33 #include <expand.h>
34 #include <rlist.h>
35 #include <misc_lib.h>
36 #include <class.h>
37 #include <fncall.h>
38 #include <known_dirs.h>
39 #include <ornaments.h>
40 #include <policy.h>
41 #include <cleanup.h>
42 
43 // TODO: remove
44 #include <vars.h> /* IsCf3VarString */
45 #include <audit.h> /* FatalError */
46 
47 
48 static Policy *LoadPolicyFile(EvalContext *ctx, GenericAgentConfig *config, const char *policy_file,
49  StringMap *policy_files_hashes, StringSet *parsed_files_checksums,
50  StringSet *failed_files);
51 
52 
53 
54 
55 /*
56  * The difference between filename and input_input file is that the latter is the file specified by -f or
57  * equivalently the file containing body common control. This will hopefully be squashed in later refactoring.
58  */
59 Policy *Cf3ParseFile(const GenericAgentConfig *config, const char *input_path)
60 {
61  struct stat statbuf;
62 
63  if (stat(input_path, &statbuf) == -1)
64  {
65  if (config->ignore_missing_inputs)
66  {
67  return PolicyNew();
68  }
69 
70  Log(LOG_LEVEL_ERR, "Can't stat file '%s' for parsing. (stat: %s)", input_path, GetErrorStr());
71  DoCleanupAndExit(EXIT_FAILURE);
72  }
73  else if (S_ISDIR(statbuf.st_mode))
74  {
75  if (config->ignore_missing_inputs)
76  {
77  return PolicyNew();
78  }
79 
80  Log(LOG_LEVEL_ERR, "Can't parse directory '%s'.", input_path);
81  DoCleanupAndExit(EXIT_FAILURE);
82  }
83 
84 #ifndef _WIN32
85  if (config->check_not_writable_by_others && (statbuf.st_mode & (S_IWGRP | S_IWOTH)))
86  {
87  Log(LOG_LEVEL_ERR, "File %s (owner %ju) is writable by others (security exception)", input_path, (uintmax_t)statbuf.st_uid);
88  DoCleanupAndExit(EXIT_FAILURE);
89  }
90 #endif
91 
92  Log(LOG_LEVEL_VERBOSE, "BEGIN parsing file: %s", input_path);
93 
94  if (!FileCanOpen(input_path, "r"))
95  {
96  Log(LOG_LEVEL_ERR, "Can't open file '%s' for parsing", input_path);
97  DoCleanupAndExit(EXIT_FAILURE);
98  }
99 
100  Policy *policy = NULL;
101  if (StringEndsWith(input_path, ".json"))
102  {
103  Writer *contents = FileRead(input_path, SIZE_MAX, NULL);
104  if (!contents)
105  {
106  Log(LOG_LEVEL_ERR, "Error reading JSON input file '%s'", input_path);
107  return NULL;
108  }
109  JsonElement *json_policy = NULL;
110  const char *data = StringWriterData(contents);
111  if (JsonParse(&data, &json_policy) != JSON_PARSE_OK)
112  {
113  Log(LOG_LEVEL_ERR, "Error parsing JSON input file '%s'", input_path);
114  WriterClose(contents);
115  return NULL;
116  }
117 
118  policy = PolicyFromJson(json_policy);
119  if (policy == NULL)
120  {
122  "Failed to deserialize a policy from the JSON input file '%s'",
123  input_path);
124  JsonDestroy(json_policy);
125  WriterClose(contents);
126  return NULL;
127  }
128 
129  JsonDestroy(json_policy);
130  WriterClose(contents);
131  }
132  else
133  {
134  if (config->agent_type == AGENT_TYPE_COMMON)
135  {
137  }
138  else
139  {
140  policy = ParserParseFile(config->agent_type, input_path, 0, 0);
141  }
142  }
143 
144  Log(LOG_LEVEL_VERBOSE, "END parsing file: %s", input_path);
145  return policy;
146 }
147 
148 static Policy *LoadPolicyInputFiles(EvalContext *ctx, GenericAgentConfig *config, const Rlist *inputs,
149  StringMap *policy_files_hashes, StringSet *parsed_files_checksums,
150  StringSet *failed_files)
151 {
152  Policy *policy = PolicyNew();
153 
154  for (const Rlist *rp = inputs; rp; rp = rp->next)
155  {
156  if (rp->val.type != RVAL_TYPE_SCALAR)
157  {
158  Log(LOG_LEVEL_ERR, "Non-file object in inputs list");
159  continue;
160  }
161 
162  const char *unresolved_input = RlistScalarValue(rp);
163  if (IsExpandable(unresolved_input))
164  {
165  PolicyResolve(ctx, policy, config);
166  }
167 
168  Rval resolved_input = EvaluateFinalRval(ctx, policy, NULL, "sys", rp->val, true, NULL);
169 
170  Policy *aux_policy = NULL;
171  switch (resolved_input.type)
172  {
173  case RVAL_TYPE_SCALAR:
174  if (IsCf3VarString(RvalScalarValue(resolved_input)))
175  {
176  Log(LOG_LEVEL_ERR, "Unresolved variable '%s' in input list, cannot parse", RvalScalarValue(resolved_input));
177  break;
178  }
179 
180  aux_policy = LoadPolicyFile(ctx, config,
181  GenericAgentResolveInputPath(config, RvalScalarValue(resolved_input)),
182  policy_files_hashes, parsed_files_checksums, failed_files);
183  break;
184 
185  case RVAL_TYPE_LIST:
186  aux_policy = LoadPolicyInputFiles(ctx, config,
187  RvalRlistValue(resolved_input),
188  policy_files_hashes, parsed_files_checksums, failed_files);
189  break;
190 
191  default:
192  ProgrammingError("Unknown type in input list for parsing: %d", resolved_input.type);
193  break;
194  }
195 
196  if (aux_policy)
197  {
198  policy = PolicyMerge(policy, aux_policy);
199  }
200 
201  RvalDestroy(resolved_input);
202  }
203 
204  return policy;
205 }
206 
207 // TODO: should be replaced by something not complected with loading
208 static void ShowContext(EvalContext *ctx)
209 {
210  Seq *hard_contexts = SeqNew(1000, NULL);
211  Seq *soft_contexts = SeqNew(1000, NULL);
212 
213  {
215  Class *cls = NULL;
216  while ((cls = ClassTableIteratorNext(iter)))
217  {
218  if (cls->is_soft)
219  {
220  SeqAppend(soft_contexts, cls->name);
221  }
222  else
223  {
224  SeqAppend(hard_contexts, cls->name);
225  }
226  }
227 
229  }
230 
231  SeqSort(soft_contexts, (SeqItemComparator)strcmp, NULL);
232  SeqSort(hard_contexts, (SeqItemComparator)strcmp, NULL);
233 
234  Log(LOG_LEVEL_VERBOSE, "----------------------------------------------------------------");
235 
236  {
237  Log(LOG_LEVEL_VERBOSE, "BEGIN Discovered hard classes:");
238 
239  for (size_t i = 0; i < SeqLength(hard_contexts); i++)
240  {
241  const char *context = SeqAt(hard_contexts, i);
242  Log(LOG_LEVEL_VERBOSE, "C: discovered hard class %s", context);
243  }
244 
245  Log(LOG_LEVEL_VERBOSE, "END Discovered hard classes");
246  }
247 
248  Log(LOG_LEVEL_VERBOSE, "----------------------------------------------------------------");
249 
250  if (SeqLength(soft_contexts))
251  {
252  Log(LOG_LEVEL_VERBOSE, "BEGIN initial soft classes:");
253 
254  for (size_t i = 0; i < SeqLength(soft_contexts); i++)
255  {
256  const char *context = SeqAt(soft_contexts, i);
257  Log(LOG_LEVEL_VERBOSE, "C: added soft class %s", context);
258  }
259 
260  Log(LOG_LEVEL_VERBOSE, "END initial soft classes");
261  }
262 
263  SeqDestroy(hard_contexts);
264  SeqDestroy(soft_contexts);
265 }
266 
267 static void RenameMainBundle(EvalContext *ctx, Policy *policy)
268 {
269  assert(policy != NULL);
270  assert(ctx != NULL);
271  assert(policy->bundles != NULL);
272  char *const entry_point = GetRealPath(EvalContextGetEntryPoint(ctx));
273  if (NULL_OR_EMPTY(entry_point))
274  {
275  free(entry_point);
276  return;
277  }
278  Seq *bundles = policy->bundles;
279  int length = SeqLength(bundles);
280  bool removed = false;
281  for (int i = 0; i < length; ++i)
282  {
283  Bundle *const bundle = SeqAt(bundles, i);
284  if (StringEqual(bundle->name, "__main__"))
285  {
286  char *abspath = GetRealPath(bundle->source_path);
287  if (StringEqual(abspath, entry_point))
288  {
290  "Redefining __main__ bundle from file %s to be main",
291  abspath);
292  strncpy(bundle->name, "main", 4+1);
293  // "__main__" is always big enough for "main"
294  }
295  else
296  {
298  "Dropping __main__ bundle from file %s (entry point: %s)",
299  abspath,
300  entry_point);
301  removed = true;
302  SeqSet(bundles, i, NULL); // SeqSet calls destroy function
303  }
304  free(abspath);
305  }
306  }
307  if (removed)
308  {
309  SeqRemoveNulls(bundles);
310  }
311  free(entry_point);
312 }
313 
314 static Policy *LoadPolicyFile(EvalContext *ctx, GenericAgentConfig *config, const char *policy_file,
315  StringMap *policy_files_hashes, StringSet *parsed_files_checksums,
316  StringSet *failed_files)
317 {
318  unsigned char digest[EVP_MAX_MD_SIZE + 1] = { 0 };
319  char hashbuffer[CF_HOSTKEY_STRING_SIZE] = { 0 };
320 
321  HashFile(policy_file, digest, CF_DEFAULT_DIGEST, false);
322  HashPrintSafe(hashbuffer, sizeof(hashbuffer), digest,
323  CF_DEFAULT_DIGEST, true);
324 
325  Log(LOG_LEVEL_DEBUG, "Hashed policy file %s to %s", policy_file, hashbuffer);
326 
327  if (StringMapHasKey(policy_files_hashes, policy_file))
328  {
329  Log(LOG_LEVEL_VERBOSE, "Skipping loading of duplicate policy file %s", policy_file);
330  return NULL;
331  }
332  else if (StringSetContains(parsed_files_checksums, hashbuffer))
333  {
334  Log(LOG_LEVEL_VERBOSE, "Skipping loading of duplicate (detected by hash) policy file %s",
335  policy_file);
336  return NULL;
337  }
338  else
339  {
340  Log(LOG_LEVEL_DEBUG, "Loading policy file %s", policy_file);
341  }
342 
343  Policy *policy = Cf3ParseFile(config, policy_file);
344 
345  StringMapInsert(policy_files_hashes, xstrdup(policy_file), xstrdup(hashbuffer));
346  StringSetAdd(parsed_files_checksums, xstrdup(hashbuffer));
347 
348  if (policy)
349  {
350  RenameMainBundle(ctx, policy);
351  Seq *errors = SeqNew(10, free);
352  if (!PolicyCheckPartial(policy, errors))
353  {
354  Writer *writer = FileWriter(stderr);
355  for (size_t i = 0; i < errors->length; i++)
356  {
357  PolicyErrorWrite(writer, errors->data[i]);
358  }
359  WriterClose(writer);
360  SeqDestroy(errors);
361 
362  StringSetAdd(failed_files, xstrdup(policy_file));
363  PolicyDestroy(policy);
364  return NULL;
365  }
366 
367  SeqDestroy(errors);
368  }
369  else
370  {
371  StringSetAdd(failed_files, xstrdup(policy_file));
372  return NULL;
373  }
374 
375  PolicyResolve(ctx, policy, config);
376 
377  Body *body_common_control = PolicyGetBody(policy, NULL, "common", "control");
378  Body *body_file_control = PolicyGetBody(policy, NULL, "file", "control");
379 
380  if (body_common_control)
381  {
382  Seq *potential_inputs = BodyGetConstraint(body_common_control, "inputs");
383  Constraint *cp = EffectiveConstraint(ctx, potential_inputs);
384  SeqDestroy(potential_inputs);
385 
386  if (cp)
387  {
388  Policy *aux_policy = LoadPolicyInputFiles(ctx, config, RvalRlistValue(cp->rval),
389  policy_files_hashes, parsed_files_checksums,
390  failed_files);
391  if (aux_policy)
392  {
393  policy = PolicyMerge(policy, aux_policy);
394  }
395  }
396  }
397 
398  if (body_file_control)
399  {
400  Seq *potential_inputs = BodyGetConstraint(body_file_control, "inputs");
401  Constraint *cp = EffectiveConstraint(ctx, potential_inputs);
402  SeqDestroy(potential_inputs);
403 
404  if (cp)
405  {
406  Policy *aux_policy = LoadPolicyInputFiles(ctx, config, RvalRlistValue(cp->rval),
407  policy_files_hashes, parsed_files_checksums,
408  failed_files);
409  if (aux_policy)
410  {
411  policy = PolicyMerge(policy, aux_policy);
412  }
413  }
414  }
415 
416  return policy;
417 }
418 
419 static bool VerifyBundleSequence(EvalContext *ctx, const Policy *policy, const GenericAgentConfig *config)
420 {
421  Rlist *fallback = NULL;
423  if (!bundlesequence)
424  {
425  RlistAppendScalar(&fallback, "main");
426  bundlesequence = fallback;
427  }
428 
429  const char *name;
430  bool ok = true;
431  for (const Rlist *rp = bundlesequence; rp != NULL; rp = rp->next)
432  {
433  switch (rp->val.type)
434  {
435  case RVAL_TYPE_SCALAR:
436  name = RlistScalarValue(rp);
437  break;
438 
439  case RVAL_TYPE_FNCALL:
440  name = RlistFnCallValue(rp)->name;
441  break;
442 
443  default:
444  name = NULL;
445  ok = false;
446  {
447  Writer *w = StringWriter();
448  WriterWrite(w, "Illegal item found in bundlesequence '");
449  RvalWrite(w, rp->val);
450  WriterWrite(w, "'");
452  WriterClose(w);
453  }
454  continue;
455  }
456 
457  if (!config->ignore_missing_bundles && !PolicyGetBundle(policy, NULL, NULL, name))
458  {
459  Log(LOG_LEVEL_ERR, "Bundle '%s' listed in the bundlesequence is not a defined bundle", name);
460  ok = false;
461  }
462  }
463 
464  RlistDestroy(fallback);
465  return ok;
466 }
467 
468 /**
469  * @brief Reads the release_id file from inputs and return a JsonElement.
470  */
472 {
473  char filename[CF_MAXVARSIZE];
474 
475  GetReleaseIdFile(GetInputDir(), filename, sizeof(filename));
476 
477  struct stat sb;
478  if (stat(filename, &sb) == -1)
479  {
480  return NULL;
481  }
482 
483  JsonElement *validated_doc = NULL;
484  JsonParseError err = JsonParseFile(filename, 4096, &validated_doc);
485  if (err != JSON_PARSE_OK)
486  {
488  "Could not read release ID: '%s' did not contain valid JSON data. "
489  "(JsonParseFile: '%s')", filename, JsonParseErrorToString(err));
490  }
491 
492  return validated_doc;
493 }
494 
496 {
497  StringMap *policy_files_hashes = StringMapNew();
498  StringSet *parsed_files_checksums = StringSetNew();
499  StringSet *failed_files = StringSetNew();
500 
501  Banner("Loading policy");
502 
503  Policy *policy = LoadPolicyFile(ctx, config, config->input_file,
504  policy_files_hashes, parsed_files_checksums,
505  failed_files);
506 
507  if (StringSetSize(failed_files) > 0)
508  {
509  Log(LOG_LEVEL_ERR, "There are syntax errors in policy files");
510  DoCleanupAndExit(EXIT_FAILURE);
511  }
512 
513  StringSetDestroy(parsed_files_checksums);
514  StringSetDestroy(failed_files);
515  if (policy != NULL)
516  {
517  policy->policy_files_hashes = policy_files_hashes;
518  }
519  else
520  {
521  StringMapDestroy(policy_files_hashes);
522  }
523 
524  {
525  Seq *errors = SeqNew(100, PolicyErrorDestroy);
526 
527  if (PolicyCheckPartial(policy, errors))
528  {
529  if (!config->bundlesequence &&
530  (PolicyIsRunnable(policy) || config->check_runnable))
531  {
533  "Running full policy integrity checks");
534  PolicyCheckRunnable(ctx, policy, errors,
535  config->ignore_missing_bundles);
536  }
537  }
538 
539  if (SeqLength(errors) > 0)
540  {
541  Writer *writer = FileWriter(stderr);
542  for (size_t i = 0; i < errors->length; i++)
543  {
544  PolicyErrorWrite(writer, errors->data[i]);
545  }
546  WriterClose(writer);
547  DoCleanupAndExit(EXIT_FAILURE); // TODO: do not exit
548  }
549 
550  SeqDestroy(errors);
551  }
552 
554  {
555  Legend();
556  ShowContext(ctx);
557  }
558 
559  if (config->agent_type == AGENT_TYPE_AGENT)
560  {
561  Banner("Preliminary variable/class-context convergence");
562  }
563 
564  if (policy)
565  {
566  /* store names of all bundles in the EvalContext */
567  for (size_t i = 0; i < SeqLength(policy->bundles); i++)
568  {
569  Bundle *bp = SeqAt(policy->bundles, i);
571  }
572 
573  for (size_t i = 0; i < SeqLength(policy->bundles); i++)
574  {
575  Bundle *bp = SeqAt(policy->bundles, i);
576  EvalContextStackPushBundleFrame(ctx, bp, NULL, false);
577 
578  for (size_t j = 0; j < SeqLength(bp->promise_types); j++)
579  {
580  PromiseType *sp = SeqAt(bp->promise_types, j);
582 
583  for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++)
584  {
585  Promise *pp = SeqAt(sp->promises, ppi);
586 
587  /* Skip constraint syntax verification through all
588  * slist/container iterations for cf-promises! cf-agent
589  * still checks though. */
590  if (config->agent_type != AGENT_TYPE_COMMON)
591  {
593  }
594  }
595 
597  }
598 
600  }
601 
602  PolicyResolve(ctx, policy, config);
603 
604  // TODO: need to move this inside PolicyCheckRunnable eventually.
605  if (!config->bundlesequence && config->check_runnable)
606  {
607  // only verify policy-defined bundlesequence for cf-agent, cf-promises
608  if ((config->agent_type == AGENT_TYPE_AGENT) ||
609  (config->agent_type == AGENT_TYPE_COMMON))
610  {
611  if (!VerifyBundleSequence(ctx, policy, config))
612  {
613  FatalError(ctx, "Errors in promise bundles: could not verify bundlesequence");
614  }
615  }
616  }
617  }
618 
619  if (config->agent_type == AGENT_TYPE_AGENT &&
621  {
622  /* Doing bootstrap, set the release_id to "bootstrap" and also write it
623  * into a file so that sub-agent executed as part of bootstrap can just
624  * pick it up and then rewrite it with the actual value from
625  * masterfiles. */
626  policy->release_id = xstrdup("bootstrap");
627 
628  char filename[PATH_MAX];
629  GetReleaseIdFile(GetInputDir(), filename, sizeof(filename));
630  FILE *release_id_stream = safe_fopen_create_perms(filename, "w",
632  if (release_id_stream == NULL)
633  {
634  Log(LOG_LEVEL_ERR, "Failed to open the release_id file for writing during bootstrap");
635  }
636  else
637  {
638  Writer *release_id_writer = FileWriter(release_id_stream);
639  WriterWrite(release_id_writer, "{ releaseId: \"bootstrap\" }\n");
640  WriterClose(release_id_writer);
641  }
642  }
643  else
644  {
645  JsonElement *validated_doc = ReadReleaseIdFileFromInputs();
646  if (validated_doc)
647  {
648  const char *release_id = JsonObjectGetAsString(validated_doc, "releaseId");
649  if (release_id)
650  {
651  policy->release_id = xstrdup(release_id);
652  }
653  JsonDestroy(validated_doc);
654  }
655  }
656 
657  return policy;
658 }
char * xstrdup(const char *str)
Definition: alloc-mini.c:56
void FatalError(const EvalContext *ctx, char *s,...)
Definition: audit.c:94
@ COMMON_CONTROL_BUNDLESEQUENCE
Definition: cf3.defs.h:416
@ RVAL_TYPE_LIST
Definition: cf3.defs.h:607
@ RVAL_TYPE_SCALAR
Definition: cf3.defs.h:606
@ RVAL_TYPE_FNCALL
Definition: cf3.defs.h:608
@ AGENT_TYPE_COMMON
Definition: cf3.defs.h:401
@ AGENT_TYPE_AGENT
Definition: cf3.defs.h:402
HashMethod CF_DEFAULT_DIGEST
Definition: cf3globals.c:88
void free(void *)
void ClassTableIteratorDestroy(ClassTableIterator *iter)
Definition: class.c:286
Class * ClassTableIteratorNext(ClassTableIterator *iter)
Definition: class.c:248
void DoCleanupAndExit(int ret)
Definition: cleanup.c:57
#define CF_PERMS_DEFAULT
Definition: definitions.h:58
#define CF_MAXVARSIZE
Definition: definitions.h:36
const char * EvalContextGetEntryPoint(EvalContext *const ctx)
void EvalContextStackPushPromiseTypeFrame(EvalContext *ctx, const PromiseType *owner)
const void * EvalContextVariableControlCommonGet(const EvalContext *ctx, CommonControl lval)
ClassTableIterator * EvalContextClassTableIteratorNewGlobal(const EvalContext *ctx, const char *ns, bool is_hard, bool is_soft)
void EvalContextStackPushBundleFrame(EvalContext *ctx, const Bundle *owner, const Rlist *args, bool inherits_previous)
void EvalContextStackPopFrame(EvalContext *ctx)
void EvalContextPushBundleName(const EvalContext *ctx, const char *bundle_name)
void PolicyResolve(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config)
Definition: expand.c:1065
Rval EvaluateFinalRval(EvalContext *ctx, const Policy *policy, const char *ns, const char *scope, Rval rval, bool forcelist, const Promise *pp)
Definition: expand.c:610
PromiseResult CommonEvalPromise(EvalContext *ctx, const Promise *pp, void *param)
Definition: expand.c:1291
PromiseResult ExpandPromise(EvalContext *ctx, const Promise *pp, PromiseActuator *act_on_promise, void *param)
Definition: expand.c:257
bool IsExpandable(const char *str)
Definition: expand.c:1117
FILE * safe_fopen_create_perms(const char *const path, const char *const mode, const mode_t create_perms)
Definition: file_lib.c:832
bool FileCanOpen(const char *path, const char *modes)
Definition: file_lib.c:46
Writer * FileRead(const char *filename, size_t max_size, bool *truncated)
Definition: file_lib.c:63
char * GetRealPath(const char *const path)
Definition: files_names.c:670
void GetReleaseIdFile(const char *base_path, char *filename, size_t max_size)
Gets the release_id file name in the given base_path.
const char * GenericAgentResolveInputPath(const GenericAgentConfig *config, const char *input_file)
#define NULL
Definition: getopt1.c:56
char * HashPrintSafe(char *dst, size_t dst_size, const unsigned char *digest, HashMethod type, bool use_prefix)
Definition: hash.c:612
void HashFile(const char *const filename, unsigned char digest[EVP_MAX_MD_SIZE+1], HashMethod type, bool text_mode)
Definition: hash.c:443
#define CF_HOSTKEY_STRING_SIZE
Definition: hash.h:151
void JsonDestroy(JsonElement *const element)
Destroy a JSON element.
Definition: json.c:386
JsonParseError JsonParseFile(const char *const path, const size_t size_max, JsonElement **const json_out)
Convenience function to parse JSON from a file.
Definition: json.c:2727
const char * JsonObjectGetAsString(const JsonElement *const object, const char *const key)
Get the value of a field in an object, as a string.
Definition: json.c:1204
JsonParseError JsonParse(const char **const data, JsonElement **const json_out)
Parse a string to create a JsonElement.
Definition: json.c:2648
const char * JsonParseErrorToString(const JsonParseError error)
Definition: json.c:1905
JsonParseError
Definition: json.h:83
@ JSON_PARSE_OK
Definition: json.h:84
const char * GetInputDir(void)
Definition: known_dirs.c:182
static Policy * LoadPolicyFile(EvalContext *ctx, GenericAgentConfig *config, const char *policy_file, StringMap *policy_files_hashes, StringSet *parsed_files_checksums, StringSet *failed_files)
Definition: loading.c:314
static void ShowContext(EvalContext *ctx)
Definition: loading.c:208
static JsonElement * ReadReleaseIdFileFromInputs()
Reads the release_id file from inputs and return a JsonElement.
Definition: loading.c:471
static Policy * LoadPolicyInputFiles(EvalContext *ctx, GenericAgentConfig *config, const Rlist *inputs, StringMap *policy_files_hashes, StringSet *parsed_files_checksums, StringSet *failed_files)
Definition: loading.c:148
Policy * LoadPolicy(EvalContext *ctx, GenericAgentConfig *config)
Definition: loading.c:495
static void RenameMainBundle(EvalContext *ctx, Policy *policy)
Definition: loading.c:267
Policy * Cf3ParseFile(const GenericAgentConfig *config, const char *input_path)
Definition: loading.c:59
static bool VerifyBundleSequence(EvalContext *ctx, const Policy *policy, const GenericAgentConfig *config)
Definition: loading.c:419
LogLevel LogGetGlobalLevel(void)
Definition: logging.c:581
const char * GetErrorStr(void)
Definition: logging.c:275
void Log(LogLevel level, const char *fmt,...)
Definition: logging.c:409
@ LOG_LEVEL_ERR
Definition: logging.h:42
@ LOG_LEVEL_DEBUG
Definition: logging.h:47
@ LOG_LEVEL_WARNING
Definition: logging.h:43
@ LOG_LEVEL_VERBOSE
Definition: logging.h:46
void StringMapDestroy(StringMap *map)
Definition: map.c:359
bool StringMapHasKey(const StringMap *map, const char *key)
Definition: map.c:359
bool StringMapInsert(const StringMap *map, char *key, char *value)
Definition: map.c:359
StringMap * StringMapNew(void)
Definition: map.c:359
#define ProgrammingError(...)
Definition: misc_lib.h:33
void Banner(const char *s)
Definition: ornaments.c:219
void Legend()
Definition: ornaments.c:206
Policy * ParserParseFile(AgentType agent_type, const char *path, unsigned int warnings, unsigned int warnings_error)
Parse a CFEngine file to create a Policy DOM.
Definition: parser.c:111
#define S_IWOTH
Definition: platform.h:951
#define S_ISDIR(m)
Definition: platform.h:916
#define S_IWGRP
Definition: platform.h:944
#define PATH_MAX
Definition: platform.h:176
bool PolicyCheckPartial(const Policy *policy, Seq *errors)
Check a partial policy DOM for errors.
Definition: policy.c:1072
Policy * PolicyFromJson(JsonElement *json_policy)
Deserialize a policy from JSON.
Definition: policy.c:2351
void PolicyDestroy(Policy *policy)
Definition: policy.c:121
Seq * BodyGetConstraint(Body *body, const char *lval)
A sequence of constraints matching the l-value.
Definition: policy.c:2389
Bundle * PolicyGetBundle(const Policy *policy, const char *ns, const char *type, const char *name)
Query a policy for a bundle.
Definition: policy.c:339
void PolicyErrorWrite(Writer *writer, const PolicyError *error)
Definition: policy.c:1276
void PolicyErrorDestroy(PolicyError *error)
Definition: policy.c:1161
bool PolicyIsRunnable(const Policy *policy)
Check to see if a policy is runnable (contains body common control)
Definition: policy.c:372
Body * PolicyGetBody(const Policy *policy, const char *ns, const char *type, const char *name)
Query a policy for a body.
Definition: policy.c:306
Policy * PolicyMerge(Policy *a, Policy *b)
Merge two partial policy objects. The memory for the child objects of the original policies are trans...
Definition: policy.c:385
bool PolicyCheckRunnable(const EvalContext *ctx, const Policy *policy, Seq *errors, bool ignore_missing_bundles)
Check a runnable policy DOM for errors.
Definition: policy.c:1049
Policy * PolicyNew(void)
Definition: policy.c:100
Constraint * EffectiveConstraint(const EvalContext *ctx, Seq *constraints)
Returns the first effective constraint from a list of candidates, depending on evaluation state.
Definition: policy.c:2445
FnCall * RlistFnCallValue(const Rlist *rlist)
Definition: rlist.c:105
char * RlistScalarValue(const Rlist *rlist)
Definition: rlist.c:83
Rlist * RvalRlistValue(Rval rval)
Definition: rlist.c:153
void RvalWrite(Writer *writer, Rval rval)
Definition: rlist.c:1386
char * RvalScalarValue(Rval rval)
Definition: rlist.c:129
void RlistDestroy(Rlist *rl)
Definition: rlist.c:501
void RvalDestroy(Rval rval)
Definition: rlist.c:940
Rlist * RlistAppendScalar(Rlist **start, const char *scalar)
Definition: rlist.c:545
size_t SeqLength(const Seq *seq)
Length of the sequence.
Definition: sequence.c:354
void SeqRemoveNulls(Seq *seq)
Definition: sequence.c:409
Seq * SeqNew(size_t initialCapacity, void(ItemDestroy)(void *item))
Definition: sequence.c:31
void SeqSet(Seq *seq, size_t index, void *item)
Definition: sequence.c:93
void SeqSort(Seq *seq, SeqItemComparator Compare, void *user_data)
Sort a Sequence according to the given item comparator function.
Definition: sequence.c:279
void SeqDestroy(Seq *seq)
Destroy an existing Sequence.
Definition: sequence.c:60
void SeqAppend(Seq *seq, void *item)
Append a new item to the Sequence.
Definition: sequence.c:104
static void * SeqAt(const Seq *seq, int i)
Definition: sequence.h:57
int(* SeqItemComparator)(const void *, const void *, void *user_data)
Function to compare two items in a Sequence.
Definition: sequence.h:100
bool StringSetContains(const StringSet *set, const char *element)
Definition: set.c:34
size_t StringSetSize(const StringSet *set)
Definition: set.c:34
StringSet * StringSetNew(void)
Definition: set.c:34
void StringSetDestroy(StringSet *set)
Definition: set.c:34
void StringSetAdd(const StringSet *set, char *element)
Definition: set.c:34
bool StringEndsWith(const char *str, const char *suffix)
Check if a string ends with the given suffix.
Definition: string_lib.c:1330
bool StringEqual(const char *const a, const char *const b)
Definition: string_lib.c:256
#define NULL_OR_EMPTY(str)
Definition: string_lib.h:43
Definition: policy.h:85
Definition: policy.h:70
char * name
Definition: policy.h:74
Seq * promise_types
Definition: policy.h:78
char * source_path
Definition: policy.h:80
Definition: class.h:31
char * name
Definition: class.h:33
bool is_soft
Definition: class.h:36
Rval rval
Definition: policy.h:133
char * name
Definition: fncall.h:32
unsigned int parser_warnings
Definition: generic_agent.h:77
bool check_not_writable_by_others
Definition: generic_agent.h:56
AgentType agent_type
Definition: generic_agent.h:47
struct GenericAgentConfig::@14::@15 common
struct GenericAgentConfig::@14 agent_specific
struct GenericAgentConfig::@14::@16 agent
unsigned int parser_warnings_error
Definition: generic_agent.h:78
Definition: policy.h:53
Seq * bundles
Definition: policy.h:56
char * release_id
Definition: policy.h:54
StringMap * policy_files_hashes
Definition: policy.h:58
Seq * promises
Definition: policy.h:104
Definition: rlist.h:35
Rlist * next
Definition: rlist.h:37
Definition: cf3.defs.h:614
RvalType type
Definition: cf3.defs.h:616
Sequence data-structure.
Definition: sequence.h:50
size_t length
Definition: sequence.h:52
void ** data
Definition: sequence.h:51
Definition: map.h:212
Definition: set.h:138
Definition: writer.c:45
bool IsCf3VarString(const char *str)
Definition: vars.c:123
size_t WriterWrite(Writer *writer, const char *str)
Definition: writer.c:193
Writer * FileWriter(FILE *file)
Definition: writer.c:56
const char * StringWriterData(const Writer *writer)
Definition: writer.c:229
void WriterClose(Writer *writer)
Definition: writer.c:242
Writer * StringWriter(void)
Definition: writer.c:67