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)  

cf-agent.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 
25 
26 #include <platform.h>
27 #include <generic_agent.h>
28 
29 #include <actuator.h>
30 #include <audit.h>
31 #include <cleanup.h>
32 #include <eval_context.h>
33 #include <verify_classes.h>
34 #include <verify_databases.h>
35 #include <verify_environments.h>
36 #include <verify_exec.h>
37 #include <verify_methods.h>
38 #include <verify_processes.h>
39 #include <verify_packages.h>
40 #include <verify_users.h>
41 #include <verify_services.h>
42 #include <verify_storage.h>
43 #include <verify_files.h>
44 #include <verify_files_utils.h>
45 #include <verify_vars.h>
46 #include <addr_lib.h>
47 #include <files_names.h>
48 #include <files_interfaces.h>
49 #include <files_repository.h>
50 #include <files_edit.h>
51 #include <files_properties.h>
52 #include <item_lib.h>
53 #include <vars.h>
54 #include <conversion.h>
55 #include <expand.h>
56 #include <locks.h>
57 #include <scope.h>
58 #include <matching.h>
59 #include <match_scope.h>
60 #include <instrumentation.h>
61 #include <promises.h>
62 #include <unix.h>
63 #include <attributes.h>
64 #include <communication.h>
65 #include <signals.h>
66 #include <nfs.h>
67 #include <processes_select.h>
68 #include <list.h>
69 #include <fncall.h>
70 #include <rlist.h>
71 #include <agent-diagnostics.h>
72 #include <known_dirs.h>
74 #include <syslog_client.h>
75 #include <man.h>
76 #include <bootstrap.h>
77 #include <policy_server.h>
78 #include <misc_lib.h>
79 #include <buffer.h>
80 #include <loading.h>
81 #include <conn_cache.h> /* ConnCache_Init,ConnCache_Destroy */
82 #include <net.h>
83 #include <package_module.h>
84 #include <string_lib.h>
85 #include <cfnet.h>
86 #include <repair.h>
87 #include <dbm_api.h> /* CheckDBRepairFlagFile() */
88 #include <sys/types.h> /* checking umask on writing setxid log */
89 #include <sys/stat.h> /* checking umask on writing setxid log */
90 
91 #include <mod_common.h>
92 
93 #ifdef HAVE_AVAHI_CLIENT_CLIENT_H
94 #ifdef HAVE_AVAHI_COMMON_ADDRESS_H
95 #include <findhub.h>
96 #endif
97 #endif
98 
99 #include <ornaments.h>
100 
101 
102 extern int PR_KEPT;
103 extern int PR_REPAIRED;
104 extern int PR_NOTKEPT;
105 
106 static bool ALLCLASSESREPORT = false; /* GLOBAL_P */
107 static bool ALWAYS_VALIDATE = false; /* GLOBAL_P */
108 static bool CFPARANOID = false; /* GLOBAL_P */
109 static bool PERFORM_DB_CHECK = false;
110 
111 static const Rlist *ACCESSLIST = NULL; /* GLOBAL_P */
112 
113 static int CFA_BACKGROUND = 0; /* GLOBAL_X */
114 static int CFA_BACKGROUND_LIMIT = 1; /* GLOBAL_P */
115 
116 static Item *PROCESSREFRESH = NULL; /* GLOBAL_P */
117 
118 static const char *const AGENT_TYPESEQUENCE[] =
119 {
120  "meta",
121  "vars",
122  "defaults",
123  "classes", /* Maelstrom order 2 */
124  "users",
125  "files",
126  "packages",
127  "guest_environments",
128  "methods",
129  "processes",
130  "services",
131  "commands",
132  "storage",
133  "databases",
134  "reports",
135  NULL
136 };
137 
138 /*******************************************************************/
139 /* Agent specific variables */
140 /*******************************************************************/
141 
142 static void ThisAgentInit(void);
143 static GenericAgentConfig *CheckOpts(int argc, char **argv);
144 static char **TranslateOldBootstrapOptionsSeparate(int *argc_new, char **argv);
145 static char **TranslateOldBootstrapOptionsConcatenated(int argc, char **argv);
146 static void FreeFixedStringArray(int size, char **array);
147 static void CheckAgentAccess(const Rlist *list, const Policy *policy);
148 static void KeepControlPromises(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config);
149 static PromiseResult KeepAgentPromise(EvalContext *ctx, const Promise *pp, void *param);
150 static void NewTypeContext(TypeSequence type);
151 static void DeleteTypeContext(EvalContext *ctx, TypeSequence type);
153 static bool VerifyBootstrap(void);
154 static void KeepPromiseBundles(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config);
155 static void KeepPromises(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config);
156 static int NoteBundleCompliance(const Bundle *bundle, int save_pr_kept, int save_pr_repaired, int save_pr_notkept, struct timespec start);
157 static void AllClassesReport(const EvalContext *ctx);
158 static bool HasAvahiSupport(void);
159 static int AutomaticBootstrap(GenericAgentConfig *config);
160 static void BannerStatus(PromiseResult status, char *type, char *name);
161 static PromiseResult DefaultVarPromise(EvalContext *ctx, const Promise *pp);
162 static void WaitForBackgroundProcesses();
163 
164 /*******************************************************************/
165 /* Command line options */
166 /*******************************************************************/
167 
168 static const char *const CF_AGENT_SHORT_DESCRIPTION =
169  "evaluate CFEngine policy code and actuate change to the system.";
170 
171 static const char *const CF_AGENT_MANPAGE_LONG_DESCRIPTION =
172  "cf-agent evaluates policy code and makes changes to the system. Policy bundles are evaluated in the order of the "
173  "provided bundlesequence (this is normally specified in the common control body). "
174  "For each bundle, cf-agent groups promise statements according to their type. Promise types are then evaluated in a preset "
175  "order to ensure fast system convergence to policy.\n";
176 
177 static const struct option OPTIONS[] =
178 {
179  {"bootstrap", required_argument, 0, 'B'},
180  {"bundlesequence", required_argument, 0, 'b'},
181  {"workdir", required_argument, 0, 'w'},
182  {"debug", no_argument, 0, 'd'},
183  {"define", required_argument, 0, 'D'},
184  {"self-diagnostics", optional_argument, 0, 'x'},
185  {"dry-run", no_argument, 0, 'n'},
186  {"file", required_argument, 0, 'f'},
187  {"help", no_argument, 0, 'h'},
188  {"inform", no_argument, 0, 'I'},
189  {"log-level", required_argument, 0, 'g'},
190  {"negate", required_argument, 0, 'N'},
191  {"no-lock", no_argument, 0, 'K'},
192  {"verbose", no_argument, 0, 'v'},
193  {"version", no_argument, 0, 'V'},
194  {"timing-output", no_argument, 0, 't'},
195  {"trust-server", optional_argument, 0, 'T'},
196  {"color", optional_argument, 0, 'C'},
197  {"no-extensions", no_argument, 0, 'E'},
198  {"timestamp", no_argument, 0, 'l'},
199  /* Only long option for the rest */
200  {"log-modules", required_argument, 0, 0},
201  {"show-evaluated-classes", optional_argument, 0, 0 },
202  {"show-evaluated-vars", optional_argument, 0, 0 },
203  {"skip-bootstrap-policy-run", no_argument, 0, 0 },
204  {"skip-db-check", optional_argument, 0, 0 },
205  {NULL, 0, 0, '\0'}
206 };
207 
208 static const char *const HINTS[] =
209 {
210  "Bootstrap CFEngine to the given policy server IP, hostname or :avahi (automatic detection)",
211  "Set or override bundlesequence from command line",
212  "Override the default /var/cfengine work directory for testing (same as setting CFENGINE_TEST_OVERRIDE_WORKDIR)",
213  "Enable debugging output",
214  "Define a list of comma separated classes to be defined at the start of execution",
215  "Run checks to diagnose a CFEngine agent installation",
216  "All talk and no action mode - make no changes, only inform of promises not kept",
217  "Specify an alternative input file than the default. This option is overridden by FILE if supplied as argument.",
218  "Print the help message",
219  "Print basic information about changes made to the system, i.e. promises repaired",
220  "Specify how detailed logs should be. Possible values: 'error', 'warning', 'notice', 'info', 'verbose', 'debug'",
221  "Define a list of comma separated classes to be undefined at the start of execution",
222  "Ignore locking constraints during execution (ifelapsed/expireafter) if \"too soon\" to run",
223  "Output verbose information about the behaviour of the agent",
224  "Output the version of the software",
225  "Output timing information on console when in verbose mode",
226  "Possible values: 'yes' (default, trust the server when bootstrapping), 'no' (server key must already be trusted)",
227  "Enable colorized output. Possible values: 'always', 'auto', 'never'. If option is used, the default value is 'auto'",
228  "Disable extension loading (used while upgrading)",
229  "Log timestamps on each line of log output",
230  "Enable even more detailed debug logging for specific areas of the implementation. Use together with '-d'. Use --log-modules=help for a list of available modules",
231  "Show *final* evaluated classes, including those defined in common bundles in policy. Optionally can take a regular expression.",
232  "Show *final* evaluated variables, including those defined without dependency to user-defined classes in policy. Optionally can take a regular expression.",
233  "Do not run policy as the last step of the bootstrap process",
234  "Do not run database integrity checks and repairs at startup",
235  NULL
236 };
237 
238 /*******************************************************************/
239 
240 int main(int argc, char *argv[])
241 {
243 #ifdef HAVE_LIBXML2
244  xmlInitParser();
245 #endif
246  struct timespec start = BeginMeasure();
247 
248  GenericAgentConfig *config = CheckOpts(argc, argv);
249  bool force_repair = CheckDBRepairFlagFile();
250  if (force_repair || PERFORM_DB_CHECK)
251  {
252  repair_lmdb_default(force_repair);
253  }
254  EvalContext *ctx = EvalContextNew();
255 
256  // Enable only for cf-agent eval context.
258 
259  GenericAgentConfigApply(ctx, config);
260 
261  const char *program_invocation_name = argv[0];
262  const char *last_dir_sep = strrchr(program_invocation_name, FILE_SEPARATOR);
263  const char *program_name = (last_dir_sep != NULL ? last_dir_sep + 1 : program_invocation_name);
264  GenericAgentDiscoverContext(ctx, config, program_name);
265 
266  /* FIXME: (CFE-2709) ALWAYS_VALIDATE will always be false here, since it can
267  * only change in KeepPromises(), five lines later on. */
268  Policy *policy = SelectAndLoadPolicy(config, ctx, ALWAYS_VALIDATE, true);
269 
270  if (!policy)
271  {
272  Log(LOG_LEVEL_ERR, "Error reading CFEngine policy. Exiting...");
273  DoCleanupAndExit(EXIT_FAILURE);
274  }
275 
276  int ret = 0;
277 
279  ThisAgentInit();
280  ConnCache_Init();
281 
282  BeginAudit();
283  KeepPromises(ctx, policy, config);
284 
285  if (EvalAborted(ctx))
286  {
287  ret = EC_EVAL_ABORTED;
288  }
289 
291 
292  if (ALLCLASSESREPORT)
293  {
294  AllClassesReport(ctx);
295  }
296 
298 
299  /* Update packages cache. */
300  UpdatePackagesCache(ctx, false);
301 
302  /* Wait for background processes before generating reports because
303  * GenerateReports() does nothing if it detects multiple cf-agent processes
304  * running. */
306 
307  GenerateReports(config, ctx);
308 
309  PurgeLocks();
311 
313  {
316  }
317 
319  {
322  }
323 
324  PolicyDestroy(policy); /* Can we safely do this earlier ? */
326  {
328  WriteAmPolicyHubFile(false);
329  ret = 1;
330  }
331 
332  EndAudit(ctx, CFA_BACKGROUND);
333 
335 
336  GenericAgentFinalize(ctx, config);
338 
339 #ifdef HAVE_LIBXML2
340  xmlCleanupParser();
341 #endif
342 
343  return ret;
344 }
345 
346 /*******************************************************************/
347 /* Level 1 */
348 /*******************************************************************/
349 
350 static void ConfigureBootstrap(GenericAgentConfig *config, const char *argument)
351 {
352  assert(config != NULL);
353  if (!BootstrapAllowed())
354  {
355  Log(LOG_LEVEL_ERR, "Not enough privileges to bootstrap CFEngine");
356  DoCleanupAndExit(EXIT_FAILURE);
357  }
358 
359  if(strcmp(optarg, ":avahi") == 0)
360  {
361  if(!HasAvahiSupport())
362  {
363  Log(LOG_LEVEL_ERR, "Avahi support is not built in, please see options to the configure script and rebuild CFEngine");
364  DoCleanupAndExit(EXIT_FAILURE);
365  }
366 
367  int err = AutomaticBootstrap(config);
368  if (err < 0)
369  {
370  Log(LOG_LEVEL_ERR, "Automatic bootstrap failed, error code '%d'", err);
371  DoCleanupAndExit(EXIT_FAILURE);
372  }
373  return;
374  }
375 
376  if(IsLoopbackAddress(argument))
377  {
378  Log(LOG_LEVEL_WARNING, "Bootstrapping to loopback interface (localhost), other hosts will not be able to bootstrap to this server");
379  }
380 
381  // temporary assure that network functions are working
382  OpenNetwork();
383 
384  config->agent_specific.agent.bootstrap_argument = xstrdup(argument);
385 
386  char *host, *port;
387  ParseHostPort(optarg, &host, &port);
388 
389  char ipaddr[CF_MAX_IP_LEN] = "";
390  if (Hostname2IPString(ipaddr, host,sizeof(ipaddr)) == -1)
391  {
393  "Could not resolve hostname '%s', unable to bootstrap",
394  host);
395  DoCleanupAndExit(EXIT_FAILURE);
396  }
397 
398  CloseNetwork();
399 
400  MINUSF = true;
401  config->ignore_locks = true;
402  GenericAgentConfigSetInputFile(config, GetInputDir(), "promises.cf");
403 
404  config->agent_specific.agent.bootstrap_ip = xstrdup(ipaddr);
405  config->agent_specific.agent.bootstrap_host = xstrdup(host);
406 
407  if (port == NULL)
408  {
410  }
411  else
412  {
413  config->agent_specific.agent.bootstrap_port = xstrdup(port);
414  }
415 }
416 
417 static GenericAgentConfig *CheckOpts(int argc, char **argv)
418 {
419  extern char *optarg;
420  int c;
421 
423  bool option_trust_server = false;
424 ;
425 /* DEPRECATED:
426  --policy-server (-s) is deprecated in community version 3.5.0.
427  Support rewrite from some common old bootstrap options (until community version 3.6.0?).
428  */
429 
430  int argc_new = argc;
431  char **argv_tmp = TranslateOldBootstrapOptionsSeparate(&argc_new, argv);
432  char **argv_new = TranslateOldBootstrapOptionsConcatenated(argc_new, argv_tmp);
433  FreeFixedStringArray(argc_new, argv_tmp);
434 
435  int longopt_idx;
436  while ((c = getopt_long(argc_new, argv_new, "tdvnKIf:g:w:D:N:VxMB:b:hC::ElT::",
437  OPTIONS, &longopt_idx))
438  != -1)
439  {
440  switch (c)
441  {
442  case 't':
443  TIMING = true;
444  break;
445 
446  case 'w':
447  Log(LOG_LEVEL_INFO, "Setting workdir to '%s'", optarg);
448  setenv_wrapper("CFENGINE_TEST_OVERRIDE_WORKDIR", optarg, 1);
449  break;
450 
451  case 'f':
453  MINUSF = true;
454  break;
455 
456  case 'b':
457  if (optarg)
458  {
459  Rlist *bundlesequence = RlistFromSplitString(optarg, ',');
460  GenericAgentConfigSetBundleSequence(config, bundlesequence);
461  RlistDestroy(bundlesequence);
462  }
463  break;
464 
465  case 'd':
467  break;
468 
469  case 'B':
470  {
471  ConfigureBootstrap(config, optarg);
472  }
473  break;
474 
475  case 'K':
476  config->ignore_locks = true;
477  break;
478 
479  case 'D':
480  {
481  StringSet *defined_classes = StringSetFromString(optarg, ',');
482  if (! config->heap_soft)
483  {
484  config->heap_soft = defined_classes;
485  }
486  else
487  {
488  StringSetJoin(config->heap_soft, defined_classes, xstrdup);
489  StringSetDestroy(defined_classes);
490  }
491  }
492  break;
493 
494  case 'N':
495  {
496  StringSet *negated_classes = StringSetFromString(optarg, ',');
497  if (! config->heap_negated)
498  {
499  config->heap_negated = negated_classes;
500  }
501  else
502  {
503  StringSetJoin(config->heap_negated, negated_classes, xstrdup);
504  StringSetDestroy(negated_classes);
505  }
506  }
507  break;
508 
509  case 'I':
511  break;
512 
513  case 'v':
515  break;
516 
517  case 'g':
519  break;
520 
521  case 'n':
522  DONTDO = true;
523  config->ignore_locks = true;
524  break;
525 
526  case 'V':
527  {
528  Writer *w = FileWriter(stdout);
530  FileWriterDetach(w);
531  }
532  DoCleanupAndExit(EXIT_SUCCESS);
533 
534  case 'h':
535  {
536  Writer *w = FileWriter(stdout);
537  WriterWriteHelp(w, "cf-agent", OPTIONS, HINTS, NULL, false, true);
538  FileWriterDetach(w);
539  }
540  DoCleanupAndExit(EXIT_SUCCESS);
541 
542  case 'M':
543  {
544  Writer *out = FileWriter(stdout);
545  ManPageWrite(out, "cf-agent", time(NULL),
548  OPTIONS, HINTS,
549  NULL, false,
550  true);
551  FileWriterDetach(out);
552  DoCleanupAndExit(EXIT_SUCCESS);
553  }
554 
555  case 'x':
556  {
557  const char *workdir = GetWorkDir();
558  const char *inputdir = GetInputDir();
559  const char *logdir = GetLogDir();
560  const char *statedir = GetStateDir();
561  Writer *out = FileWriter(stdout);
562  WriterWriteF(out, "self-diagnostics for agent using workdir '%s'\n", workdir);
563  WriterWriteF(out, "self-diagnostics for agent using inputdir '%s'\n", inputdir);
564  WriterWriteF(out, "self-diagnostics for agent using logdir '%s'\n", logdir);
565  WriterWriteF(out, "self-diagnostics for agent using statedir '%s'\n", statedir);
566 
569  FileWriterDetach(out);
570  }
571  DoCleanupAndExit(EXIT_SUCCESS);
572 
573  case 'C':
574  if (!GenericAgentConfigParseColor(config, optarg))
575  {
576  DoCleanupAndExit(EXIT_FAILURE);
577  }
578  break;
579 
580  case 'E':
582  break;
583 
584  case 'l':
586  break;
587 
588  case 'T':
589  option_trust_server = true;
590 
591  /* If the argument is missing, we trust by default. */
592  if (optarg == NULL || strcmp(optarg, "yes") == 0)
593  {
595  }
596  else
597  {
599  }
600 
601  break;
602 
603  /* long options only */
604  case 0:
605  {
606  const char *const option_name = OPTIONS[longopt_idx].name;
607  if (StringEqual(option_name, "log-modules"))
608  {
610  if (!ret)
611  {
612  DoCleanupAndExit(EXIT_FAILURE);
613  }
614  }
615  else if (StringEqual(option_name, "show-evaluated-classes"))
616  {
617  if (optarg == NULL)
618  {
619  optarg = ".*";
620  }
622  }
623  else if (StringEqual(option_name, "show-evaluated-vars"))
624  {
625  if (optarg == NULL)
626  {
627  optarg = ".*";
628  }
630  }
631  else if (StringEqual(option_name, "skip-bootstrap-policy-run"))
632  {
634  }
635  else if (StringEqual(option_name, "skip-db-check"))
636  {
637  if (optarg == NULL)
638  {
639  PERFORM_DB_CHECK = false; // Skip (no arg), check = false
640  }
641  else if (StringEqual_IgnoreCase(optarg, "yes"))
642  {
643  PERFORM_DB_CHECK = false; // Skip = yes, check = false
644  }
645  else if (StringEqual_IgnoreCase(optarg, "no"))
646  {
647  PERFORM_DB_CHECK = true; // Skip = no, check = true
648  }
649  else
650  {
652  "Invalid argument for --skip-db-check(yes/no): '%s'",
653  optarg);
654  DoCleanupAndExit(EXIT_FAILURE);
655  }
656  }
657  break;
658  }
659  default:
660  {
661  Writer *w = FileWriter(stdout);
662  WriterWriteHelp(w, "cf-agent", OPTIONS, HINTS, NULL, false, true);
663  FileWriterDetach(w);
664  }
665  DoCleanupAndExit(EXIT_FAILURE);
666  }
667  }
668 
669  if (!GenericAgentConfigParseArguments(config, argc_new - optind,
670  argv_new + optind))
671  {
672  Log(LOG_LEVEL_ERR, "Too many arguments");
673  DoCleanupAndExit(EXIT_FAILURE);
674  }
675 
676  if (option_trust_server &&
678  {
680  "Option --trust-server can only be used when bootstrapping");
681  DoCleanupAndExit(EXIT_FAILURE);
682  }
683 
684  FreeFixedStringArray(argc_new, argv_new);
685 
686  return config;
687 }
688 
689 
690 static char **TranslateOldBootstrapOptionsSeparate(int *argc_new, char **argv)
691 {
692  int i;
693  int policy_server_argnum = 0;
694  int server_address_argnum = 0;
695  int bootstrap_argnum = 0;
696  int argc = *argc_new;
697 
698  for(i = 0; i < argc; i++)
699  {
700  if(strcmp(argv[i], "--policy-server") == 0 || strcmp(argv[i], "-s") == 0)
701  {
702  policy_server_argnum = i;
703  }
704 
705  if(strcmp(argv[i], "--bootstrap") == 0 || strcmp(argv[i], "-B") == 0)
706  {
707  bootstrap_argnum = i;
708  }
709  }
710 
711  if(policy_server_argnum > 0)
712  {
713  if(policy_server_argnum + 1 < argc)
714  {
715  server_address_argnum = policy_server_argnum + 1;
716  }
717  }
718 
719  char **argv_new;
720 
721  if(bootstrap_argnum > 0 && server_address_argnum > 0)
722  {
723  Log(LOG_LEVEL_WARNING, "Deprecated bootstrap options detected. The --policy-server (-s) option is deprecated from CFEngine community version 3.5.0."
724  "Please provide the address argument to --bootstrap (-B) instead. Rewriting your arguments now, but you need to adjust them as this support will be removed soon.");
725 
726  *argc_new = argc - 1; // --policy-server deprecated
727  argv_new = xcalloc(1, sizeof(char *) * (*argc_new + 1));
728 
729  int new_i = 0;
730 
731  for(i = 0; i < argc; i++)
732  {
733  if(i == bootstrap_argnum)
734  {
735  argv_new[new_i++] = xstrdup(argv[bootstrap_argnum]);
736  argv_new[new_i++] = xstrdup(argv[server_address_argnum]);
737  }
738  else if(i == server_address_argnum)
739  {
740  // skip: handled above
741  }
742  else if(i == policy_server_argnum)
743  {
744  // skip: deprecated
745  }
746  else
747  {
748  argv_new[new_i++] = xstrdup(argv[i]);
749  }
750  }
751  }
752  else
753  {
754  argv_new = xcalloc(1, sizeof(char *) * (*argc_new + 1));
755 
756  for(i = 0; i < argc; i++)
757  {
758  argv_new[i] = xstrdup(argv[i]);
759  }
760  }
761 
762  return argv_new;
763 }
764 
765 
766 static char **TranslateOldBootstrapOptionsConcatenated(int argc, char **argv)
767 {
768  char **argv_new = xcalloc(1, sizeof(char *) * (argc + 1));
769 
770  for(int i = 0; i < argc; i++)
771  {
772  if(strcmp(argv[i], "-Bs") == 0)
773  {
774  Log(LOG_LEVEL_WARNING, "Deprecated bootstrap options detected. The --policy-server (-s) option is deprecated from CFEngine community version 3.5.0."
775  "Please provide the address argument to --bootstrap (-B) instead. Rewriting your arguments now, but you need to adjust them as this support will be removed soon.");
776  argv_new[i] = xstrdup("-B");
777  }
778  else
779  {
780  argv_new[i] = xstrdup(argv[i]);
781  }
782  }
783 
784  return argv_new;
785 }
786 
787 
788 static void FreeFixedStringArray(int size, char **array)
789 {
790  for(int i = 0; i < size; i++)
791  {
792  free(array[i]);
793  }
794 
795  free(array);
796 }
797 
798 /*******************************************************************/
799 
800 static void ThisAgentInit(void)
801 {
802  char filename[CF_BUFSIZE];
803 
804 #ifdef HAVE_SETSID
805  setsid();
806 #endif
807 
808  CFA_MAXTHREADS = 30;
809  EDITFILESIZE = 100000;
810 
811 /*
812  do not set signal(SIGCHLD,SIG_IGN) in agent near
813  popen() - or else pclose will fail to return
814  status which we need for setting returns
815 */
816 
817  snprintf(filename, CF_BUFSIZE, "%s/cfagent.%s.log", GetLogDir(), VSYSNAME.nodename);
818  ToLowerStrInplace(filename);
819  MapName(filename);
820 
821  const mode_t current_umask = umask(0777); // Gets and changes umask
822  umask(current_umask); // Restores umask
823  Log(LOG_LEVEL_DEBUG, "Current umask is %o", current_umask);
824  FILE *fp = safe_fopen(filename, "a");
825  if (fp != NULL)
826  {
827  fclose(fp);
828  }
829 }
830 
831 /*******************************************************************/
832 
833 static void KeepPromises(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config)
834 {
835  KeepControlPromises(ctx, policy, config);
836  /* Check if 'abortclasses' aborted evaluation or not. */
837  if (EvalAborted(ctx))
838  {
839  return;
840  }
841  KeepPromiseBundles(ctx, policy, config);
842 }
843 
844 /*******************************************************************/
845 /* Level 2 */
846 /*******************************************************************/
847 
848 static void KeepControlPromises(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config)
849 {
850  Seq *constraints = ControlBodyConstraints(policy, AGENT_TYPE_AGENT);
851  if (constraints)
852  {
853  for (size_t i = 0; i < SeqLength(constraints); i++)
854  {
855  Constraint *cp = SeqAt(constraints, i);
856 
857  if (!IsDefinedClass(ctx, cp->classes))
858  {
859  continue;
860  }
861 
863  {
864  /* Already handled in generic_agent */
865  continue;
866  }
867 
868  VarRef *ref = VarRefParseFromScope(cp->lval, "control_agent");
869  DataType value_type;
870  const void *value = EvalContextVariableGet(ctx, ref, &value_type);
871  VarRefDestroy(ref);
872 
873  /* If var not found */
874  if (value_type == CF_DATA_TYPE_NONE)
875  {
876  Log(LOG_LEVEL_ERR, "Unknown lval '%s' in agent control body", cp->lval);
877  continue;
878  }
879 
880  /* 'files_single_copy => { }' is a perfectly valid case. */
882  {
883  assert(value_type == CF_DATA_TYPE_STRING_LIST);
884  SINGLE_COPY_LIST = value;
887  {
888  char *rlist_str = RlistToString(SINGLE_COPY_LIST);
889  Log(LOG_LEVEL_VERBOSE, "Setting file single copy list to: %s", rlist_str);
890  free(rlist_str);
891  }
892  continue;
893  }
894 
895  /* Empty list is not supported for the other constraints/attributes. */
896  if (value == NULL)
897  {
899  "Empty list is not a valid value for '%s' attribute in agent control body",
900  cp->lval);
901  continue;
902  }
903 
904  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_MAXCONNECTIONS].lval) == 0)
905  {
906  CFA_MAXTHREADS = (int) IntFromString(value);
907  Log(LOG_LEVEL_VERBOSE, "Setting maxconnections to %d", CFA_MAXTHREADS);
908  continue;
909  }
910 
912  {
913  CF_PERSISTENCE = (int) IntFromString(value);
914  Log(LOG_LEVEL_VERBOSE, "Setting checksum_alert_time to %d", CF_PERSISTENCE);
915  continue;
916  }
917 
918  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_AGENTFACILITY].lval) == 0)
919  {
920  SetFacility(value);
921  continue;
922  }
923 
924  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_AGENTACCESS].lval) == 0)
925  {
926  ACCESSLIST = value;
927  CheckAgentAccess(ACCESSLIST, policy);
928  continue;
929  }
930 
932  {
933  Log(LOG_LEVEL_VERBOSE, "Setting refresh_processes when starting to...");
934  for (const Rlist *rp = value; rp != NULL; rp = rp->next)
935  {
937  // TODO: why is this only done in verbose mode?
938  // original commit says 'optimization'.
940  {
942  }
943  }
944  continue;
945  }
946 
947  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_ABORTCLASSES].lval) == 0)
948  {
949  Log(LOG_LEVEL_VERBOSE, "Setting abort classes from ...");
950 
951  for (const Rlist *rp = value; rp != NULL; rp = rp->next)
952  {
953  char name[CF_MAXVARSIZE] = "";
954 
956 
957  EvalContextHeapAddAbort(ctx, name, cp->classes);
958  }
959 
960  continue;
961  }
962 
964  {
965  Log(LOG_LEVEL_VERBOSE, "Setting abort bundle classes from ...");
966 
967  for (const Rlist *rp = value; rp != NULL; rp = rp->next)
968  {
969  char name[CF_MAXVARSIZE] = "";
971 
973  }
974 
975  continue;
976  }
977 
978  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_ADDCLASSES].lval) == 0)
979  {
980  Log(LOG_LEVEL_VERBOSE, "Add classes ...");
981 
982  for (const Rlist *rp = value; rp != NULL; rp = rp->next)
983  {
984  Log(LOG_LEVEL_VERBOSE, "... %s", RlistScalarValue(rp));
985  EvalContextClassPutSoft(ctx, RlistScalarValue(rp), CONTEXT_SCOPE_NAMESPACE, "source=environment");
986  }
987 
988  continue;
989  }
990 
991  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_ALWAYSVALIDATE].lval) == 0)
992  {
994  Log(LOG_LEVEL_VERBOSE, "Setting alwaysvalidate to '%s'", ALWAYS_VALIDATE ? "true" : "false");
995  continue;
996  }
997 
999  {
1001  Log(LOG_LEVEL_VERBOSE, "Setting allclassesreport to '%s'", ALLCLASSESREPORT ? "true" : "false");
1002  }
1003 
1004  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_SECUREINPUT].lval) == 0)
1005  {
1006  CFPARANOID = BooleanFromString(value);
1007  Log(LOG_LEVEL_VERBOSE, "Setting secure input to '%s'", CFPARANOID ? "true" : "false");
1008  continue;
1009  }
1010 
1011  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_BINDTOINTERFACE].lval) == 0)
1012  {
1013  SetBindInterface(value);
1014  continue;
1015  }
1016 
1017  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_HASHUPDATES].lval) == 0)
1018  {
1019  bool enabled = BooleanFromString(value);
1020 
1021  SetChecksumUpdatesDefault(ctx, enabled);
1022  Log(LOG_LEVEL_VERBOSE, "Setting checksum updates to '%s'", enabled ? "true" : "false");
1023  continue;
1024  }
1025 
1026  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_CHILDLIBPATH].lval) == 0)
1027  {
1028  Log(LOG_LEVEL_VERBOSE, "Setting 'LD_LIBRARY_PATH=%s'", (const char *)value);
1029  setenv_wrapper("LD_LIBRARY_PATH", value, 1);
1030  continue;
1031  }
1032 
1033  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_DEFAULTCOPYTYPE].lval) == 0)
1034  {
1035  DEFAULT_COPYTYPE = value;
1036  Log(LOG_LEVEL_VERBOSE, "Setting defaultcopytype to '%s'", DEFAULT_COPYTYPE);
1037  continue;
1038  }
1039 
1040  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_FAUTODEFINE].lval) == 0)
1041  {
1042  SetFileAutoDefineList(value);
1043  Log(LOG_LEVEL_VERBOSE, "Setting file auto define list");
1044  continue;
1045  }
1046 
1047  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_DRYRUN].lval) == 0)
1048  {
1049  DONTDO = BooleanFromString(value);
1050  Log(LOG_LEVEL_VERBOSE, "Setting dryrun to %c", DONTDO);
1051  continue;
1052  }
1053 
1054  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_INFORM].lval) == 0)
1055  {
1056  bool inform = BooleanFromString(value);
1057  if (inform)
1058  {
1060  }
1061  else
1062  {
1064  {
1066  }
1067  }
1068  Log(LOG_LEVEL_VERBOSE, "body agent control, inform => '%s', sets new log level to '%s'",
1069  inform ? "true" : "false", LogLevelToString(LogGetGlobalLevel()));
1070  continue;
1071  }
1072 
1073  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_VERBOSE].lval) == 0)
1074  {
1075  bool verbose = BooleanFromString(value);
1076  if (verbose)
1077  {
1079  }
1080  else
1081  {
1083  {
1085  }
1086  }
1087  Log(LOG_LEVEL_VERBOSE, "body agent control, verbose => '%s', sets new log level to '%s'",
1088  verbose ? "true" : "false", LogLevelToString(LogGetGlobalLevel()));
1089  continue;
1090  }
1091 
1092  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_REPOSITORY].lval) == 0)
1093  {
1094  SetRepositoryLocation(value);
1095  Log(LOG_LEVEL_VERBOSE, "Setting repository to '%s'", (const char *)value);
1096  continue;
1097  }
1098 
1099  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_SKIPIDENTIFY].lval) == 0)
1100  {
1101  bool enabled = BooleanFromString(value);
1102 
1103  SetSkipIdentify(enabled);
1104  Log(LOG_LEVEL_VERBOSE, "Setting skipidentify to '%s'", enabled ? "true" : "false");
1105  continue;
1106  }
1107 
1108  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_SUSPICIOUSNAMES].lval) == 0)
1109  {
1110  for (const Rlist *rp = value; rp != NULL; rp = rp->next)
1111  {
1113  Log(LOG_LEVEL_VERBOSE, "Considering '%s' as suspicious file", RlistScalarValue(rp));
1114  }
1115 
1116  continue;
1117  }
1118 
1119  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_REPCHAR].lval) == 0)
1120  {
1121  char c = *(char *)value;
1122 
1123  SetRepositoryChar(c);
1124  Log(LOG_LEVEL_VERBOSE, "Setting repchar to '%c'", c);
1125  continue;
1126  }
1127 
1129  {
1130  CF_MOUNTALL = BooleanFromString(value);
1131  Log(LOG_LEVEL_VERBOSE, "Setting mountfilesystems to '%s'", CF_MOUNTALL ? "true" : "false");
1132  continue;
1133  }
1134 
1135  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_EDITFILESIZE].lval) == 0)
1136  {
1137  EDITFILESIZE = IntFromString(value);
1138  Log(LOG_LEVEL_VERBOSE, "Setting edit file size to %d", EDITFILESIZE);
1139  continue;
1140  }
1141 
1142  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_IFELAPSED].lval) == 0)
1143  {
1144  VIFELAPSED = IntFromString(value);
1145  Log(LOG_LEVEL_VERBOSE, "Setting ifelapsed to %d", VIFELAPSED);
1146  continue;
1147  }
1148 
1149  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_EXPIREAFTER].lval) == 0)
1150  {
1151  VEXPIREAFTER = IntFromString(value);
1152  Log(LOG_LEVEL_VERBOSE, "Setting expireafter to %d", VEXPIREAFTER);
1153  continue;
1154  }
1155 
1156  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_TIMEOUT].lval) == 0)
1157  {
1158  CONNTIMEOUT = IntFromString(value);
1159  Log(LOG_LEVEL_VERBOSE, "Setting timeout to %jd", (intmax_t) CONNTIMEOUT);
1160  continue;
1161  }
1162 
1163  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_MAX_CHILDREN].lval) == 0)
1164  {
1166  Log(LOG_LEVEL_VERBOSE, "Setting max_children to %d", CFA_BACKGROUND_LIMIT);
1167  if (CFA_BACKGROUND_LIMIT > 10)
1168  {
1169  Log(LOG_LEVEL_ERR, "Silly value for max_children in agent control promise (%d > 10)",
1172  }
1173  continue;
1174  }
1175 
1176  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_ENVIRONMENT].lval) == 0)
1177  {
1178  Log(LOG_LEVEL_VERBOSE, "Setting environment variables from ...");
1179 
1180  for (const Rlist *rp = value; rp != NULL; rp = rp->next)
1181  {
1182  assert(strchr(RlistScalarValue(rp), '=')); /* Valid for putenv() */
1183  if (putenv_wrapper(RlistScalarValue(rp)) != 0)
1184  {
1185  Log(LOG_LEVEL_ERR, "Failed to set environment variable '%s'. (putenv: %s)",
1186  RlistScalarValue(rp), GetErrorStr());
1187  }
1188  }
1189 
1190  continue;
1191  }
1192 
1194  {
1195  Log(LOG_LEVEL_VERBOSE, "SET select_end_match_eof %s", (char *) value);
1197  }
1198 
1199  if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_REPORTCLASSLOG].lval) == 0)
1200  {
1202 
1203  Log(LOG_LEVEL_VERBOSE, "Setting report_class_log to %s",
1204  config->agent_specific.agent.report_class_log? "true" : "false");
1205  continue;
1206  }
1207  }
1208  }
1209 
1210  const void *value = NULL;
1212  {
1213  LASTSEENEXPIREAFTER = IntFromString(value) * 60;
1214  }
1215 
1217  {
1218  FIPS_MODE = BooleanFromString(value);
1219  Log(LOG_LEVEL_VERBOSE, "Setting FIPS mode to '%s'", FIPS_MODE ? "true" : "false");
1220  }
1221 
1223  {
1224  SetSyslogPort(IntFromString(value));
1225  Log(LOG_LEVEL_VERBOSE, "Setting syslog_port to '%s'", (const char *)value);
1226  }
1227 
1229  {
1230  /* Don't resolve syslog_host now, better do it per log request. */
1231  if (!SetSyslogHost(value))
1232  {
1234  "Failed to set syslog_host to '%s', too long", (const char *)value);
1235  }
1236  else
1237  {
1238  Log(LOG_LEVEL_VERBOSE, "Setting syslog_host to '%s'", (const char *)value);
1239  }
1240  }
1241 
1243  {
1244  double bval;
1245  if (DoubleFromString(value, &bval))
1246  {
1247  bwlimit_kbytes = (uint32_t) ( bval / 1000.0);
1248  Log(LOG_LEVEL_VERBOSE, "Setting rate limit to %d kBytes/sec", bwlimit_kbytes);
1249  }
1250  }
1251  Nova_Initialize(ctx);
1252 
1253  // If not have been enabled above then should be disabled.
1254  // By default it's enabled to catch all set classes on startup stage
1255  // before this part of the policy is processed.
1256  if (!config->agent_specific.agent.report_class_log)
1257  {
1259  }
1260 }
1261 
1262 /*********************************************************************/
1263 
1264 static void KeepPromiseBundles(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config)
1265 {
1266  Rlist *bundlesequence = NULL;
1267 
1268  Banner("Begin policy/promise evaluation");
1269 
1270  if (config->bundlesequence != NULL)
1271  {
1272  Log(LOG_LEVEL_INFO, "Using command line specified bundlesequence");
1273  bundlesequence = RlistCopy(config->bundlesequence);
1274  }
1275  else
1276  {
1279 
1280  if (bundlesequence == NULL)
1281  {
1282  RlistAppendScalar(&bundlesequence, "main");
1283  }
1284  }
1285 
1286  bool ok = true;
1287  for (const Rlist *rp = bundlesequence; rp; rp = rp->next)
1288  {
1289  const char *name = NULL;
1290 
1291  switch (rp->val.type)
1292  {
1293  case RVAL_TYPE_SCALAR:
1294  name = RlistScalarValue(rp);
1295  break;
1296  case RVAL_TYPE_FNCALL:
1297  name = RlistFnCallValue(rp)->name;
1298  break;
1299 
1300  default:
1301  name = NULL;
1302  {
1303  Writer *w = StringWriter();
1304  WriterWrite(w, "Illegal item found in bundlesequence: ");
1305  RvalWrite(w, rp->val);
1306  Log(LOG_LEVEL_ERR, "%s", StringWriterData(w));
1307  WriterClose(w);
1308  }
1309  ok = false;
1310  break;
1311  }
1312 
1313  if (!config->ignore_missing_bundles)
1314  {
1315  const Bundle *bp = EvalContextResolveBundleExpression(ctx, policy, name, "agent");
1316  if (!bp)
1317  {
1318  bp = EvalContextResolveBundleExpression(ctx, policy, name, "common");
1319  }
1320 
1321  if (!bp)
1322  {
1323  Log(LOG_LEVEL_ERR, "Bundle '%s' listed in the bundlesequence was not found", name);
1324  ok = false;
1325  }
1326  }
1327  }
1328 
1329  if (!ok)
1330  {
1331  FatalError(ctx, "Errors in agent bundles");
1332  }
1333 
1334  Writer *w = StringWriter();
1335  WriterWrite(w, "Using bundlesequence => ");
1336  RlistWrite(w, bundlesequence);
1338  WriterClose(w);
1339 
1340 /* If all is okay, go ahead and evaluate */
1341 
1342  for (const Rlist *rp = bundlesequence; rp; rp = rp->next)
1343  {
1344  const char *name = NULL;
1345  const Rlist *args = NULL;
1346 
1347  switch (rp->val.type)
1348  {
1349  case RVAL_TYPE_FNCALL:
1350  name = RlistFnCallValue(rp)->name;
1351  args = RlistFnCallValue(rp)->args;
1352  break;
1353  default:
1354  name = RlistScalarValue(rp);
1355  args = NULL;
1356  break;
1357  }
1358 
1359  EvalContextSetBundleArgs(ctx, args);
1360 
1361  const Bundle *bp = EvalContextResolveBundleExpression(ctx, policy, name, "agent");
1362  if (!bp)
1363  {
1364  bp = EvalContextResolveBundleExpression(ctx, policy, name, "common");
1365  }
1366 
1367  if (bp)
1368  {
1369  BundleBanner(bp,args);
1370  EvalContextStackPushBundleFrame(ctx, bp, args, false);
1371  ScheduleAgentOperations(ctx, bp);
1373  EndBundleBanner(bp);
1374  if (EvalAborted(ctx))
1375  {
1376  break;
1377  }
1378  }
1379  else
1380  {
1381  if (config->ignore_missing_bundles)
1382  {
1383  Log(LOG_LEVEL_VERBOSE, "Ignoring missing bundle '%s'", name);
1384  }
1385  else
1386  {
1387  FatalError(ctx, "Bundlesequence contained unknown bundle reference '%s'", name);
1388  }
1389  }
1390  }
1391 
1392  RlistDestroy(bundlesequence);
1393 }
1394 
1395 static void AllClassesReport(const EvalContext *ctx)
1396 {
1397  char context_report_file[CF_BUFSIZE];
1398  snprintf(context_report_file, CF_BUFSIZE, "%s%callclasses.txt", GetStateDir(), FILE_SEPARATOR);
1399 
1400  FILE *fp = safe_fopen(context_report_file, "w");
1401  if (fp == NULL)
1402  {
1403  Log(LOG_LEVEL_INFO, "Could not open allclasses cache file '%s' (fopen: %s)", context_report_file, GetErrorStr());
1404  }
1405  else
1406  {
1407  Writer *writer = FileWriter(fp);
1409  Class *cls = NULL;
1410  while ((cls = ClassTableIteratorNext(iter)))
1411  {
1412  char *expr = ClassRefToString(cls->ns, cls->name);
1413  WriterWriteF(writer, "%s\n", expr);
1414  free(expr);
1415  }
1417  WriterClose(writer);
1418  }
1419 }
1420 
1422 // NB - this function can be called recursively through "methods"
1423 {
1424  int save_pr_kept = PR_KEPT;
1425  int save_pr_repaired = PR_REPAIRED;
1426  int save_pr_notkept = PR_NOTKEPT;
1427  struct timespec start = BeginMeasure();
1428 
1430  {
1432  }
1433 
1435 
1436  for (int pass = 1; pass < CF_DONEPASSES; pass++)
1437  {
1438  for (TypeSequence type = 0; AGENT_TYPESEQUENCE[type] != NULL; type++)
1439  {
1440  const PromiseType *sp = BundleGetPromiseType((Bundle *)bp, AGENT_TYPESEQUENCE[type]);
1441 
1442  if (!sp || SeqLength(sp->promises) == 0)
1443  {
1444  continue;
1445  }
1446 
1447  NewTypeContext(type);
1448 
1449  SpecialTypeBanner(type, pass);
1451 
1452  for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++)
1453  {
1454  Promise *pp = SeqAt(sp->promises, ppi);
1455 
1456  EvalContextSetPass(ctx, pass);
1457 
1458  PromiseResult promise_result = ExpandPromise(ctx, pp, KeepAgentPromise, NULL);
1459  result = PromiseResultUpdate(result, promise_result);
1460 
1461  if (EvalAborted(ctx) || BundleAbort(ctx))
1462  {
1463  DeleteTypeContext(ctx, type);
1465  NoteBundleCompliance(bp, save_pr_kept, save_pr_repaired, save_pr_notkept, start);
1466  return result;
1467  }
1468  }
1469 
1470  DeleteTypeContext(ctx, type);
1472 
1473  if (type == TYPE_SEQUENCE_CONTEXTS)
1474  {
1475  BundleResolve(ctx, bp);
1477  }
1478  }
1479  }
1480 
1481  NoteBundleCompliance(bp, save_pr_kept, save_pr_repaired, save_pr_notkept, start);
1482  return result;
1483 }
1484 
1485 /*********************************************************************/
1486 
1487 #ifdef __MINGW32__
1488 
1489 static void CheckAgentAccess(const Rlist *list, const Policy *policy)
1490 {
1491 }
1492 
1493 #else
1494 
1495 static void CheckAgentAccess(const Rlist *list, const Policy *policy)
1496 {
1497  uid_t uid = getuid();
1498 
1499  for (const Rlist *rp = list; rp != NULL; rp = rp->next)
1500  {
1501  if (Str2Uid(RlistScalarValue(rp), NULL, NULL) == uid)
1502  {
1503  return;
1504  }
1505  }
1506 
1507  {
1508  StringSet *input_files = PolicySourceFiles(policy);
1509  StringSetIterator iter = StringSetIteratorInit(input_files);
1510  const char *input_file = NULL;
1511  while ((input_file = StringSetIteratorNext(&iter)))
1512  {
1513  struct stat sb;
1514  stat(input_file, &sb);
1515 
1516  if (ACCESSLIST)
1517  {
1518  bool access = false;
1519  for (const Rlist *rp2 = ACCESSLIST; rp2 != NULL; rp2 = rp2->next)
1520  {
1521  if (Str2Uid(RlistScalarValue(rp2), NULL, NULL) == sb.st_uid)
1522  {
1523  access = true;
1524  break;
1525  }
1526  }
1527 
1528  if (!access)
1529  {
1530  Log(LOG_LEVEL_ERR, "File '%s' is not owned by an authorized user (security exception)", input_file);
1531  DoCleanupAndExit(EXIT_FAILURE);
1532  }
1533  }
1534  else if (CFPARANOID && IsPrivileged())
1535  {
1536  if (sb.st_uid != getuid())
1537  {
1538  Log(LOG_LEVEL_ERR, "File '%s' is not owned by uid %ju (security exception)", input_file,
1539  (uintmax_t)getuid());
1540  DoCleanupAndExit(EXIT_FAILURE);
1541  }
1542  }
1543  }
1544 
1545  StringSetDestroy(input_files);
1546  }
1547 
1548  Log(LOG_LEVEL_ERR, "You are denied access to run this policy");
1549  DoCleanupAndExit(EXIT_FAILURE);
1550 }
1551 #endif /* !__MINGW32__ */
1552 
1553 /*********************************************************************/
1554 
1556 {
1557  char *regex = PromiseGetConstraintAsRval(pp, "if_match_regex", RVAL_TYPE_SCALAR);
1558  bool okay = true;
1559 
1560 
1561  DataType value_type = CF_DATA_TYPE_NONE;
1562  const void *value = NULL;
1563  {
1564  VarRef *ref = VarRefParseFromScope(pp->promiser, "this");
1565  value = EvalContextVariableGet(ctx, ref, &value_type);
1566  VarRefDestroy(ref);
1567  }
1568 
1569  switch (value_type)
1570  {
1571  case CF_DATA_TYPE_STRING:
1572  case CF_DATA_TYPE_INT:
1573  case CF_DATA_TYPE_REAL:
1574  if (regex && !FullTextMatch(ctx, regex, value))
1575  {
1576  return PROMISE_RESULT_NOOP;
1577  }
1578 
1579  if (regex == NULL)
1580  {
1581  return PROMISE_RESULT_NOOP;
1582  }
1583  break;
1584 
1586  case CF_DATA_TYPE_INT_LIST:
1588  if (regex)
1589  {
1590  for (const Rlist *rp = value; rp != NULL; rp = rp->next)
1591  {
1592  if (FullTextMatch(ctx, regex, RlistScalarValue(rp)))
1593  {
1594  okay = false;
1595  break;
1596  }
1597  }
1598 
1599  if (okay)
1600  {
1601  return PROMISE_RESULT_NOOP;
1602  }
1603  }
1604  break;
1605 
1606  default:
1607  break;
1608  }
1609 
1610  {
1612  EvalContextVariableRemove(ctx, ref);
1613  VarRefDestroy(ref);
1614  }
1615 
1616  return VerifyVarPromise(ctx, pp, NULL);
1617 }
1618 
1619 static void LogVariableValue(const EvalContext *ctx, const Promise *pp)
1620 {
1622  char *out = NULL;
1623 
1624  DataType type;
1625  const void *var = EvalContextVariableGet(ctx, ref, &type);
1626  switch (type)
1627  {
1628  case CF_DATA_TYPE_INT:
1629  case CF_DATA_TYPE_REAL:
1630  case CF_DATA_TYPE_STRING:
1631  out = xstrdup((char *) var);
1632  break;
1633  case CF_DATA_TYPE_INT_LIST:
1636  {
1637  size_t siz = CF_BUFSIZE;
1638  size_t len = 0;
1639  out = xcalloc(1, CF_BUFSIZE);
1640 
1641  for (Rlist *rp = (Rlist *) var; rp != NULL; rp = rp->next)
1642  {
1643  const char *s = (char *) rp->val.item;
1644 
1645  if (strlen(s) + len + 3 >= siz) // ", " + NULL
1646  {
1647  out = xrealloc(out, siz + CF_BUFSIZE);
1648  siz += CF_BUFSIZE;
1649  }
1650 
1651  if (len > 0)
1652  {
1653  len += strlcat(out, ", ", siz);
1654  }
1655 
1656  len += strlcat(out, s, siz);
1657  }
1658  break;
1659  }
1661  {
1662  Writer *w = StringWriter();
1663  JsonWriteCompact(w, (JsonElement *) var);
1664  out = StringWriterClose(w);
1665  break;
1666  }
1667  default:
1668  /* TODO is CF_DATA_TYPE_NONE acceptable? Today all meta variables
1669  * are of this type. */
1670  /* UnexpectedError("Variable '%s' is of unknown type %d", */
1671  /* pp->promiser, type); */
1672  out = xstrdup("NONE");
1673  break;
1674  }
1675 
1676  Log(LOG_LEVEL_DEBUG, "V: '%s' => '%s'", pp->promiser, out);
1677  free(out);
1678  VarRefDestroy(ref);
1679 }
1680 
1681 static PromiseResult KeepAgentPromise(EvalContext *ctx, const Promise *pp, ARG_UNUSED void *param)
1682 {
1683  assert(param == NULL);
1684  struct timespec start = BeginMeasure();
1686 
1687  if (strcmp("meta", pp->parent_promise_type->name) == 0 ||
1688  strcmp("vars", pp->parent_promise_type->name) == 0)
1689  {
1690  Log(LOG_LEVEL_VERBOSE, "V: Computing value of '%s'", pp->promiser);
1691 
1692  result = VerifyVarPromise(ctx, pp, NULL);
1693  if (result != PROMISE_RESULT_FAIL)
1694  {
1696  {
1697  LogVariableValue(ctx, pp);
1698  }
1699  }
1700  }
1701  else if (strcmp("defaults", pp->parent_promise_type->name) == 0)
1702  {
1703  result = DefaultVarPromise(ctx, pp);
1704  }
1705  else if (strcmp("classes", pp->parent_promise_type->name) == 0)
1706  {
1707  result = VerifyClassPromise(ctx, pp, NULL);
1708  }
1709  else if (strcmp("processes", pp->parent_promise_type->name) == 0)
1710  {
1711  if (!LoadProcessTable())
1712  {
1713  Log(LOG_LEVEL_ERR, "Unable to read the process table - cannot keep processes: type promises");
1714  return PROMISE_RESULT_FAIL;
1715  }
1716  result = VerifyProcessesPromise(ctx, pp);
1717  if (result != PROMISE_RESULT_SKIPPED)
1718  {
1719  EndMeasurePromise(start, pp);
1720  }
1721  }
1722  else if (strcmp("storage", pp->parent_promise_type->name) == 0)
1723  {
1724  result = FindAndVerifyStoragePromises(ctx, pp);
1725  if (result != PROMISE_RESULT_SKIPPED)
1726  {
1727  EndMeasurePromise(start, pp);
1728  }
1729  }
1730  else if (strcmp("packages", pp->parent_promise_type->name) == 0)
1731  {
1732  result = VerifyPackagesPromise(ctx, pp);
1733  if (result != PROMISE_RESULT_SKIPPED)
1734  {
1735  EndMeasurePromise(start, pp);
1736  }
1737  }
1738  else if (strcmp("users", pp->parent_promise_type->name) == 0)
1739  {
1740  result = VerifyUsersPromise(ctx, pp);
1741  if (result != PROMISE_RESULT_SKIPPED)
1742  {
1743  EndMeasurePromise(start, pp);
1744  }
1745  }
1746 
1747  else if (strcmp("files", pp->parent_promise_type->name) == 0)
1748  {
1749  result = ParallelFindAndVerifyFilesPromises(ctx, pp);
1750  if (result != PROMISE_RESULT_SKIPPED)
1751  {
1752  EndMeasurePromise(start, pp);
1753  }
1754  }
1755  else if (strcmp("commands", pp->parent_promise_type->name) == 0)
1756  {
1757  result = VerifyExecPromise(ctx, pp);
1758  if (result != PROMISE_RESULT_SKIPPED)
1759  {
1760  EndMeasurePromise(start, pp);
1761  }
1762  }
1763  else if (strcmp("databases", pp->parent_promise_type->name) == 0)
1764  {
1765  result = VerifyDatabasePromises(ctx, pp);
1766  if (result != PROMISE_RESULT_SKIPPED)
1767  {
1768  EndMeasurePromise(start, pp);
1769  }
1770  }
1771  else if (strcmp("methods", pp->parent_promise_type->name) == 0)
1772  {
1773  result = VerifyMethodsPromise(ctx, pp);
1774  if (result != PROMISE_RESULT_SKIPPED)
1775  {
1776  EndMeasurePromise(start, pp);
1777  }
1778  }
1779  else if (strcmp("services", pp->parent_promise_type->name) == 0)
1780  {
1781  result = VerifyServicesPromise(ctx, pp);
1782  if (result != PROMISE_RESULT_SKIPPED)
1783  {
1784  EndMeasurePromise(start, pp);
1785  }
1786  }
1787  else if (strcmp("guest_environments", pp->parent_promise_type->name) == 0)
1788  {
1789  result = VerifyEnvironmentsPromise(ctx, pp);
1790  if (result != PROMISE_RESULT_SKIPPED)
1791  {
1792  EndMeasurePromise(start, pp);
1793  }
1794  }
1795  else if (strcmp("reports", pp->parent_promise_type->name) == 0)
1796  {
1797  result = VerifyReportPromise(ctx, pp);
1798  }
1799  else
1800  {
1801  result = PROMISE_RESULT_NOOP;
1802  }
1803 
1804  BannerStatus(result, pp->parent_promise_type->name, pp->promiser);
1805  EvalContextLogPromiseIterationOutcome(ctx, pp, result);
1806  return result;
1807 }
1808 
1809 
1810 static void BannerStatus(PromiseResult status, char *type, char *name)
1811 {
1812  if ((strcmp(type, "vars") == 0) || (strcmp(type, "classes") == 0))
1813  {
1814  return;
1815  }
1816 
1817  switch (status)
1818  {
1819  case PROMISE_RESULT_CHANGE:
1820  Log(LOG_LEVEL_VERBOSE, "A: Promise REPAIRED");
1821  break;
1822 
1824  Log(LOG_LEVEL_VERBOSE, "A: Promise TIMED-OUT");
1825  break;
1826 
1827  case PROMISE_RESULT_WARN:
1828  case PROMISE_RESULT_FAIL:
1830  Log(LOG_LEVEL_VERBOSE, "A: Promise NOT KEPT!");
1831  break;
1832 
1833  case PROMISE_RESULT_DENIED:
1834  Log(LOG_LEVEL_VERBOSE, "A: Promise NOT KEPT - denied");
1835  break;
1836 
1837  case PROMISE_RESULT_NOOP:
1838  Log(LOG_LEVEL_VERBOSE, "A: Promise was KEPT");
1839  break;
1840  default:
1841  return;
1842  break;
1843  }
1844 
1845  Log(LOG_LEVEL_VERBOSE, "P: END %s promise (%.30s%s)",
1846  type, name,
1847  (strlen(name) > 30) ? "..." : "");
1848 }
1849 
1850 /*********************************************************************/
1851 /* Type context */
1852 /*********************************************************************/
1853 
1854 static void NewTypeContext(TypeSequence type)
1855 {
1856 // get maxconnections
1857 
1858  switch (type)
1859  {
1862  break;
1863 
1864  case TYPE_SEQUENCE_FILES:
1865  break;
1866 
1868  break;
1869 
1870  case TYPE_SEQUENCE_STORAGE:
1871 #ifndef __MINGW32__ // TODO: Run if implemented on Windows
1873  {
1876  }
1877 #endif /* !__MINGW32__ */
1878  break;
1879 
1880  default:
1881  break;
1882  }
1883 
1884  return;
1885 }
1886 
1887 /*********************************************************************/
1888 
1890 {
1891  switch (type)
1892  {
1895  break;
1896 
1897  case TYPE_SEQUENCE_FILES:
1898  break;
1899 
1901  break;
1902 
1903  case TYPE_SEQUENCE_STORAGE:
1905  break;
1906 
1910  break;
1911 
1912  default:
1913  break;
1914  }
1915 }
1916 
1917 /**************************************************************/
1918 /* Thread context */
1919 /**************************************************************/
1920 
1921 #ifdef __MINGW32__
1922 
1924 {
1925  int background = PromiseGetConstraintAsBoolean(ctx, "background", pp);
1926 
1927  if (background)
1928  {
1929  Log(LOG_LEVEL_VERBOSE, "Background processing of files promises is not supported on Windows");
1930  }
1931 
1932  return FindAndVerifyFilesPromises(ctx, pp);
1933 }
1934 
1935 #else /* !__MINGW32__ */
1936 
1938 {
1939  int background = PromiseGetConstraintAsBoolean(ctx, "background", pp);
1940  pid_t child = 1;
1942 
1943  if (background)
1944  {
1946  {
1947  CFA_BACKGROUND++;
1948  Log(LOG_LEVEL_VERBOSE, "Spawning new process...");
1949  child = fork();
1950 
1951  if (child == 0)
1952  {
1953  ALARM_PID = -1;
1954 
1955  result = PromiseResultUpdate(result, FindAndVerifyFilesPromises(ctx, pp));
1956 
1957  Log(LOG_LEVEL_VERBOSE, "Exiting backgrounded promise");
1959  _exit(EXIT_SUCCESS);
1960  // TODO: need to solve this
1961  }
1962  }
1963  else
1964  {
1965  Log(LOG_LEVEL_VERBOSE, "Promised parallel execution promised but exceeded the max number of promised background tasks, so serializing");
1966  background = 0;
1967  }
1968  }
1969  else
1970  {
1971  result = PromiseResultUpdate(result, FindAndVerifyFilesPromises(ctx, pp));
1972  }
1973 
1974  return result;
1975 }
1976 
1977 #endif /* !__MINGW32__ */
1978 
1979 /**************************************************************/
1980 
1981 static bool VerifyBootstrap(void)
1982 {
1983  const char *policy_server = PolicyServerGet();
1984  if (NULL_OR_EMPTY(policy_server))
1985  {
1986  Log(LOG_LEVEL_ERR, "Bootstrapping failed, no policy server is specified");
1987  return false;
1988  }
1989 
1990  // we should at least have gotten promises.cf from the policy hub
1991  {
1992  char filename[CF_MAXVARSIZE];
1993  snprintf(filename, sizeof(filename), "%s/promises.cf", GetInputDir());
1994  MapName(filename);
1995 
1996  struct stat sb;
1997  if (stat(filename, &sb) == -1)
1998  {
1999  Log(LOG_LEVEL_ERR, "Bootstrapping failed, no input file at '%s' after bootstrap", filename);
2000  return false;
2001  }
2002  }
2003 
2004  // embedded failsafe.cf (bootstrap.c) contains a promise to start cf-execd (executed while running this cf-agent)
2006  LoadProcessTable();
2007 
2008  if (!IsProcessNameRunning(".*cf-execd.*"))
2009  {
2010  Log(LOG_LEVEL_ERR, "Bootstrapping failed, cf-execd is not running");
2011  return false;
2012  }
2013 
2014 
2015  Log(LOG_LEVEL_NOTICE, "Bootstrap to '%s' completed successfully!", policy_server);
2016  return true;
2017 }
2018 
2019 /**************************************************************/
2020 /* Compliance comp */
2021 /**************************************************************/
2022 
2023 static int NoteBundleCompliance(const Bundle *bundle, int save_pr_kept, int save_pr_repaired, int save_pr_notkept, struct timespec start)
2024 {
2025  double delta_pr_kept, delta_pr_repaired, delta_pr_notkept;
2026  double bundle_compliance = 0.0;
2027 
2028  delta_pr_kept = (double) (PR_KEPT - save_pr_kept);
2029  delta_pr_notkept = (double) (PR_NOTKEPT - save_pr_notkept);
2030  delta_pr_repaired = (double) (PR_REPAIRED - save_pr_repaired);
2031 
2032  Log(LOG_LEVEL_VERBOSE, "A: ...................................................");
2033  Log(LOG_LEVEL_VERBOSE, "A: Bundle Accounting Summary for '%s' in namespace %s", bundle->name, bundle->ns);
2034 
2035  if (delta_pr_kept + delta_pr_notkept + delta_pr_repaired <= 0)
2036  {
2037  Log(LOG_LEVEL_VERBOSE, "A: Zero promises executed for bundle '%s'", bundle->name);
2038  Log(LOG_LEVEL_VERBOSE, "A: ...................................................");
2039  return PROMISE_RESULT_NOOP;
2040  }
2041  else
2042  {
2043  Log(LOG_LEVEL_VERBOSE, "A: Promises kept in '%s' = %.0lf", bundle->name, delta_pr_kept);
2044  Log(LOG_LEVEL_VERBOSE, "A: Promises not kept in '%s' = %.0lf", bundle->name, delta_pr_notkept);
2045  Log(LOG_LEVEL_VERBOSE, "A: Promises repaired in '%s' = %.0lf", bundle->name, delta_pr_repaired);
2046 
2047  bundle_compliance = (delta_pr_kept + delta_pr_repaired) / (delta_pr_kept + delta_pr_notkept + delta_pr_repaired);
2048 
2049  Log(LOG_LEVEL_VERBOSE, "A: Aggregate compliance (promises kept/repaired) for bundle '%s' = %.1lf%%",
2050  bundle->name, bundle_compliance * 100.0);
2051 
2053  {
2054  char name[CF_MAXVARSIZE];
2055  snprintf(name, CF_MAXVARSIZE, "%s:%s", bundle->ns, bundle->name);
2056  EndMeasure(name, start);
2057  }
2058  else
2059  {
2060  EndMeasure(NULL, start);
2061  }
2062  Log(LOG_LEVEL_VERBOSE, "A: ...................................................");
2063  }
2064 
2065  // return the worst case for the bundle status
2066 
2067  if (delta_pr_notkept > 0)
2068  {
2069  return PROMISE_RESULT_FAIL;
2070  }
2071 
2072  if (delta_pr_repaired > 0)
2073  {
2074  return PROMISE_RESULT_CHANGE;
2075  }
2076 
2077  return PROMISE_RESULT_NOOP;
2078 }
2079 
2080 #if defined(HAVE_AVAHI_CLIENT_CLIENT_H) && defined(HAVE_AVAHI_COMMON_ADDRESS_H)
2081 
2082 static bool HasAvahiSupport(void)
2083 {
2084  return true;
2085 }
2086 
2087 
2088 static int AutomaticBootstrap(GenericAgentConfig *config)
2089 {
2090  List *foundhubs = NULL;
2091  int hubcount = ListHubs(&foundhubs);
2092  int ret;
2093 
2094  switch(hubcount)
2095  {
2096  case -1:
2097  Log(LOG_LEVEL_ERR, "Error while trying to find a Policy Server");
2098  ret = -1;
2099  break;
2100  case 0:
2101  Log(LOG_LEVEL_ERR, "No hubs were found. Exiting.");
2102  ret = -1;
2103  break;
2104  case 1:
2105  {
2106  char *hostname = ((HostProperties*)foundhubs)->Hostname;
2107  char *ipaddr = ((HostProperties*)foundhubs)->IPAddress;
2108  Log(LOG_LEVEL_NOTICE, "Autodiscovered hub installed on hostname '%s', IP address '%s'",
2109  hostname, ipaddr);
2110 
2111  // TODO: This is a very bad way to check for valid IP(?)
2112  if (strlen(ipaddr) < CF_MAX_IP_LEN)
2113  {
2114  config->agent_specific.agent.bootstrap_argument = xstrdup(ipaddr);
2115  config->agent_specific.agent.bootstrap_ip = xstrdup(ipaddr);
2116  config->agent_specific.agent.bootstrap_host = xstrdup(ipaddr);
2117  ret = 0;
2118  }
2119  else
2120  {
2121  Log(LOG_LEVEL_ERR, "Invalid autodiscovered hub IP address '%s'", ipaddr);
2122  ret = -1;
2123  }
2124  break;
2125  }
2126  default:
2127  Log(LOG_LEVEL_ERR, "Found more than one hub registered in the network. Please bootstrap manually using IP from the list below.");
2128  PrintList(foundhubs);
2129  ret = -1;
2130  };
2131 
2132  if (avahi_handle)
2133  {
2134  /*
2135  * This case happens when dlopen does not manage to open the library.
2136  */
2137  dlclose(avahi_handle);
2138  }
2139  ListDestroy(&foundhubs);
2140 
2141  return ret;
2142 }
2143 #else
2144 
2145 static bool HasAvahiSupport(void)
2146 {
2147  return false;
2148 }
2149 
2151 {
2152  ProgrammingError("Attempted automated bootstrap on a non-avahi build of CFEngine");
2153 }
2154 
2155 #endif // Avahi
2156 
2158 {
2159 #ifdef __MINGW32__
2160  /* no fork() on Windows */
2161  return;
2162 #else
2163  Log(LOG_LEVEL_VERBOSE, "Waiting for background processes");
2164  bool have_children = true;
2165  while (have_children)
2166  {
2167  pid_t child = wait(NULL);
2168  if (child >= 0)
2169  {
2170  Log(LOG_LEVEL_VERBOSE, "Background process %ju terminated", (uintmax_t) child);
2171  }
2172  have_children = !((child == -1) && (errno == ECHILD));
2173  }
2174  Log(LOG_LEVEL_VERBOSE, "No more background processes to wait for");
2175  return;
2176 #endif /* __MINGW32__ */
2177 }
PromiseResult PromiseResultUpdate(PromiseResult prior, PromiseResult evidence)
Definition: actuator.c:28
PromiseResult PromiseActuator(EvalContext *ctx, const Promise *pp, void *param)
Definition: actuator.h:30
bool IsLoopbackAddress(const char *address)
Definition: addr_lib.c:548
AddressType ParseHostPort(char *s, char **hostname, char **port)
Definition: addr_lib.c:588
AgentDiagnosticsResult AgentDiagnosticsResultNew(bool success, char *message)
const AgentDiagnosticCheck * AgentDiagnosticsAllChecks(void)
void AgentDiagnosticsRun(const char *workdir, const AgentDiagnosticCheck checks[], Writer *output)
void AgentDiagnosticsRunAllChecksNova(const char *workdir, Writer *output, AgentDiagnosticsRunFunction AgentDiagnosticsRunPtr, AgentDiagnosticsResultNewFunction AgentDiagnosticsResultNewPtr)
void * xcalloc(size_t nmemb, size_t size)
Definition: alloc-mini.c:51
char * xstrdup(const char *str)
Definition: alloc-mini.c:56
void * xrealloc(void *ptr, size_t size)
Definition: alloc.c:51
void FatalError(const EvalContext *ctx, char *s,...)
Definition: audit.c:94
void EndAudit(const EvalContext *ctx, int background_tasks)
Definition: audit.c:68
void BeginAudit()
Definition: audit.c:38
bool BootstrapAllowed(void)
Definition: bootstrap.c:72
bool WriteAmPolicyHubFile(bool am_policy_hub)
Definition: bootstrap.c:211
void Nova_NoteAgentExecutionPerformance(const char *input_file, struct timespec start)
void GenerateReports(const GenericAgentConfig *config, const EvalContext *ctx)
void Nova_TrackExecution(const char *input_file)
static void FreeFixedStringArray(int size, char **array)
Definition: cf-agent.c:788
int main(int argc, char *argv[])
Definition: cf-agent.c:240
static PromiseResult ParallelFindAndVerifyFilesPromises(EvalContext *ctx, const Promise *pp)
Definition: cf-agent.c:1937
static PromiseResult DefaultVarPromise(EvalContext *ctx, const Promise *pp)
Definition: cf-agent.c:1555
static bool CFPARANOID
Definition: cf-agent.c:108
static int NoteBundleCompliance(const Bundle *bundle, int save_pr_kept, int save_pr_repaired, int save_pr_notkept, struct timespec start)
Definition: cf-agent.c:2023
static bool ALWAYS_VALIDATE
Definition: cf-agent.c:107
static void KeepPromiseBundles(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config)
Definition: cf-agent.c:1264
static void WaitForBackgroundProcesses()
Definition: cf-agent.c:2157
static int CFA_BACKGROUND_LIMIT
Definition: cf-agent.c:114
PromiseResult ScheduleAgentOperations(EvalContext *ctx, const Bundle *bp)
Definition: cf-agent.c:1421
static bool PERFORM_DB_CHECK
Definition: cf-agent.c:109
static void BannerStatus(PromiseResult status, char *type, char *name)
Definition: cf-agent.c:1810
static const char *const AGENT_TYPESEQUENCE[]
Definition: cf-agent.c:118
static GenericAgentConfig * CheckOpts(int argc, char **argv)
Definition: cf-agent.c:417
static void NewTypeContext(TypeSequence type)
Definition: cf-agent.c:1854
static char ** TranslateOldBootstrapOptionsSeparate(int *argc_new, char **argv)
Definition: cf-agent.c:690
static int CFA_BACKGROUND
Definition: cf-agent.c:113
static const char *const HINTS[]
Definition: cf-agent.c:208
static void AllClassesReport(const EvalContext *ctx)
Definition: cf-agent.c:1395
static bool HasAvahiSupport(void)
Definition: cf-agent.c:2145
static const Rlist * ACCESSLIST
Definition: cf-agent.c:111
static void ConfigureBootstrap(GenericAgentConfig *config, const char *argument)
Definition: cf-agent.c:350
static void CheckAgentAccess(const Rlist *list, const Policy *policy)
Definition: cf-agent.c:1495
static PromiseResult KeepAgentPromise(EvalContext *ctx, const Promise *pp, void *param)
Definition: cf-agent.c:1681
static int AutomaticBootstrap(GenericAgentConfig *config)
Definition: cf-agent.c:2150
int PR_NOTKEPT
Definition: audit.c:34
int PR_REPAIRED
Definition: audit.c:33
static bool ALLCLASSESREPORT
Definition: cf-agent.c:106
static void KeepPromises(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config)
Definition: cf-agent.c:833
static void LogVariableValue(const EvalContext *ctx, const Promise *pp)
Definition: cf-agent.c:1619
static void DeleteTypeContext(EvalContext *ctx, TypeSequence type)
Definition: cf-agent.c:1889
int PR_KEPT
Definition: audit.c:32
static char ** TranslateOldBootstrapOptionsConcatenated(int argc, char **argv)
Definition: cf-agent.c:766
static bool VerifyBootstrap(void)
Definition: cf-agent.c:1981
static const char *const CF_AGENT_MANPAGE_LONG_DESCRIPTION
Definition: cf-agent.c:171
static Item * PROCESSREFRESH
Definition: cf-agent.c:116
static const struct option OPTIONS[]
Definition: cf-agent.c:177
static const char *const CF_AGENT_SHORT_DESCRIPTION
Definition: cf-agent.c:168
static void KeepControlPromises(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config)
Definition: cf-agent.c:848
static void ThisAgentInit(void)
Definition: cf-agent.c:800
#define ARG_UNUSED
Definition: cf-net.c:47
TypeSequence
Definition: cf3.defs.h:521
@ TYPE_SEQUENCE_FILES
Definition: cf3.defs.h:527
@ TYPE_SEQUENCE_PACKAGES
Definition: cf3.defs.h:528
@ TYPE_SEQUENCE_PROCESSES
Definition: cf3.defs.h:531
@ TYPE_SEQUENCE_STORAGE
Definition: cf3.defs.h:534
@ TYPE_SEQUENCE_ENVIRONMENTS
Definition: cf3.defs.h:529
@ TYPE_SEQUENCE_CONTEXTS
Definition: cf3.defs.h:525
@ COMMON_CONTROL_FIPS_MODE
Definition: cf3.defs.h:430
@ COMMON_CONTROL_SYSLOG_HOST
Definition: cf3.defs.h:428
@ COMMON_CONTROL_BWLIMIT
Definition: cf3.defs.h:431
@ COMMON_CONTROL_LASTSEEN_EXPIRE_AFTER
Definition: cf3.defs.h:422
@ COMMON_CONTROL_MAX
Definition: cf3.defs.h:438
@ COMMON_CONTROL_BUNDLESEQUENCE
Definition: cf3.defs.h:416
@ COMMON_CONTROL_SYSLOG_PORT
Definition: cf3.defs.h:429
@ RVAL_TYPE_SCALAR
Definition: cf3.defs.h:606
@ RVAL_TYPE_FNCALL
Definition: cf3.defs.h:608
#define EC_EVAL_ABORTED
Definition: cf3.defs.h:149
const ConstraintSyntax CFA_CONTROLBODY[]
Definition: mod_common.c:272
PromiseResult
Definition: cf3.defs.h:122
@ PROMISE_RESULT_CHANGE
Definition: cf3.defs.h:125
@ PROMISE_RESULT_INTERRUPTED
Definition: cf3.defs.h:130
@ PROMISE_RESULT_NOOP
Definition: cf3.defs.h:124
@ PROMISE_RESULT_WARN
Definition: cf3.defs.h:126
@ PROMISE_RESULT_SKIPPED
Definition: cf3.defs.h:123
@ PROMISE_RESULT_DENIED
Definition: cf3.defs.h:128
@ PROMISE_RESULT_FAIL
Definition: cf3.defs.h:127
@ PROMISE_RESULT_TIMEOUT
Definition: cf3.defs.h:129
@ AGENT_TYPE_AGENT
Definition: cf3.defs.h:402
DataType
Definition: cf3.defs.h:368
@ CF_DATA_TYPE_NONE
Definition: cf3.defs.h:385
@ CF_DATA_TYPE_REAL
Definition: cf3.defs.h:371
@ CF_DATA_TYPE_STRING_LIST
Definition: cf3.defs.h:372
@ CF_DATA_TYPE_INT_LIST
Definition: cf3.defs.h:373
@ CF_DATA_TYPE_STRING
Definition: cf3.defs.h:369
@ CF_DATA_TYPE_INT
Definition: cf3.defs.h:370
@ CF_DATA_TYPE_CONTAINER
Definition: cf3.defs.h:384
@ CF_DATA_TYPE_REAL_LIST
Definition: cf3.defs.h:374
@ CONTEXT_SCOPE_NAMESPACE
Definition: cf3.defs.h:946
@ AGENT_CONTROL_SUSPICIOUSNAMES
Definition: cf3.defs.h:482
@ AGENT_CONTROL_AGENTACCESS
Definition: cf3.defs.h:448
@ AGENT_CONTROL_CHECKSUM_ALERT_TIME
Definition: cf3.defs.h:457
@ AGENT_CONTROL_SELECT_END_MATCH_EOF
Definition: cf3.defs.h:489
@ AGENT_CONTROL_REPOSITORY
Definition: cf3.defs.h:477
@ AGENT_CONTROL_AGENTFACILITY
Definition: cf3.defs.h:449
@ AGENT_CONTROL_ENVIRONMENT
Definition: cf3.defs.h:462
@ AGENT_CONTROL_EXPIREAFTER
Definition: cf3.defs.h:464
@ AGENT_CONTROL_ABORTBUNDLECLASSES
Definition: cf3.defs.h:446
@ AGENT_CONTROL_FSINGLECOPY
Definition: cf3.defs.h:465
@ AGENT_CONTROL_DRYRUN
Definition: cf3.defs.h:459
@ AGENT_CONTROL_ALLCLASSESREPORT
Definition: cf3.defs.h:450
@ AGENT_CONTROL_ABORTCLASSES
Definition: cf3.defs.h:445
@ AGENT_CONTROL_EDITFILESIZE
Definition: cf3.defs.h:461
@ AGENT_CONTROL_CHILDLIBPATH
Definition: cf3.defs.h:456
@ AGENT_CONTROL_TIMEOUT
Definition: cf3.defs.h:486
@ AGENT_CONTROL_ALWAYSVALIDATE
Definition: cf3.defs.h:451
@ AGENT_CONTROL_ADDCLASSES
Definition: cf3.defs.h:447
@ AGENT_CONTROL_HASHUPDATES
Definition: cf3.defs.h:455
@ AGENT_CONTROL_REPORTCLASSLOG
Definition: cf3.defs.h:488
@ AGENT_CONTROL_IFELAPSED
Definition: cf3.defs.h:468
@ AGENT_CONTROL_DEFAULTCOPYTYPE
Definition: cf3.defs.h:458
@ AGENT_CONTROL_REPCHAR
Definition: cf3.defs.h:475
@ AGENT_CONTROL_MOUNTFILESYSTEMS
Definition: cf3.defs.h:473
@ AGENT_CONTROL_SECUREINPUT
Definition: cf3.defs.h:478
@ AGENT_CONTROL_MAXCONNECTIONS
Definition: cf3.defs.h:472
@ AGENT_CONTROL_REFRESH_PROCESSES
Definition: cf3.defs.h:476
@ AGENT_CONTROL_FAUTODEFINE
Definition: cf3.defs.h:466
@ AGENT_CONTROL_VERBOSE
Definition: cf3.defs.h:487
@ AGENT_CONTROL_INFORM
Definition: cf3.defs.h:469
@ AGENT_CONTROL_MAX_CHILDREN
Definition: cf3.defs.h:471
@ AGENT_CONTROL_SKIPIDENTIFY
Definition: cf3.defs.h:481
@ AGENT_CONTROL_BINDTOINTERFACE
Definition: cf3.defs.h:454
#define CF_DONEPASSES
Definition: cf3.defs.h:344
bool DONTDO
Definition: cf3globals.c:55
int EDITFILESIZE
Definition: cf3globals.c:119
time_t CONNTIMEOUT
Definition: cf3globals.c:106
int VIFELAPSED
Definition: cf3globals.c:126
int CF_PERSISTENCE
Definition: cf3globals.c:41
long LASTSEENEXPIREAFTER
Definition: cf3globals.c:49
pid_t ALARM_PID
Definition: cf3globals.c:112
bool FIPS_MODE
Definition: cf3globals.c:36
bool MINUSF
Definition: cf3globals.c:150
struct utsname VSYSNAME
Definition: cf3globals.c:38
const char * DEFAULT_COPYTYPE
Definition: cf3globals.c:65
int VEXPIREAFTER
Definition: cf3globals.c:133
int CFA_MAXTHREADS
Definition: cf3globals.c:40
void free(void *)
void SetSkipIdentify(bool enabled)
void SetBindInterface(const char *ip)
Definition: net.c:40
#define CF_MAX_IP_LEN
Definition: cfnet.h:39
char * ClassRefToString(const char *ns, const char *name)
Definition: class.c:319
void ClassTableIteratorDestroy(ClassTableIterator *iter)
Definition: class.c:286
Class * ClassTableIteratorNext(ClassTableIterator *iter)
Definition: class.c:248
void DoCleanupAndExit(int ret)
Definition: cleanup.c:57
int Hostname2IPString(char *dst, const char *hostname, size_t dst_size)
DNS lookup of hostname, store the address as string into dst of size dst_size.
void ConnCache_Init()
Definition: conn_cache.c:60
void ConnCache_Destroy()
Definition: conn_cache.c:70
uid_t Str2Uid(const char *uidbuff, char *usercopy, const Promise *pp)
Definition: conversion.c:1087
bool DoubleFromString(const char *s, double *value_out)
Definition: conversion.c:521
long IntFromString(const char *s)
Definition: conversion.c:390
bool BooleanFromString(const char *s)
Definition: conversion.c:354
bool CheckDBRepairFlagFile()
Definition: dbm_api.c:717
#define CF_BUFSIZE
Definition: definitions.h:50
#define CF_MAXVARSIZE
Definition: definitions.h:36
void Nova_Initialize(EvalContext *ctx)
void EvalContextLogPromiseIterationOutcome(EvalContext *ctx, const Promise *pp, PromiseResult result)
bool BundleAbort(EvalContext *ctx)
Definition: eval_context.c:803
void EvalContextAllClassesLoggingEnable(EvalContext *ctx, bool enable)
void EvalContextSetSelectEndMatchEof(EvalContext *ctx, bool value)
Definition: eval_context.c:194
void EvalContextHeapAddAbort(EvalContext *ctx, const char *context, const char *activated_on_context)
Definition: eval_context.c:839
EvalContext * EvalContextNew(void)
void EvalContextStackPushPromiseTypeFrame(EvalContext *ctx, const PromiseType *owner)
bool EvalAborted(const EvalContext *ctx)
Definition: eval_context.c:833
void EvalContextHeapAddAbortCurrentBundle(EvalContext *ctx, const char *context, const char *activated_on_context)
Definition: eval_context.c:856
const void * EvalContextVariableControlCommonGet(const EvalContext *ctx, CommonControl lval)
const Bundle * EvalContextResolveBundleExpression(const EvalContext *ctx, const Policy *policy, const char *callee_reference, const char *callee_type)
Find a bundle for a bundle call, given a callee reference (in the form of ns:bundle),...
void EvalContextSetBundleArgs(EvalContext *ctx, const Rlist *args)
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 EvalContextSetPass(EvalContext *ctx, int pass)
const void * EvalContextVariableGet(const EvalContext *ctx, const VarRef *ref, DataType *type_out)
bool EvalContextVariableRemove(const EvalContext *ctx, const VarRef *ref)
void EvalContextStackPopFrame(EvalContext *ctx)
void SetChecksumUpdatesDefault(EvalContext *ctx, bool enabled)
bool EvalContextClassPutSoft(EvalContext *ctx, const char *name, ContextScope scope, const char *tags)
static bool IsDefinedClass(const EvalContext *ctx, const char *context)
Definition: eval_context.h:213
void BundleResolve(EvalContext *ctx, const Bundle *bundle)
Definition: expand.c:800
PromiseResult ExpandPromise(EvalContext *ctx, const Promise *pp, PromiseActuator *act_on_promise, void *param)
Definition: expand.c:257
void BundleResolvePromiseType(EvalContext *ctx, const Bundle *bundle, const char *type, PromiseActuator *actuator)
Definition: expand.c:715
void extension_libraries_disable()
Definition: extensions.c:63
FILE * safe_fopen(const char *const path, const char *const mode)
Definition: file_lib.c:812
char * MapName(char *s)
Definition: file_lib.c:441
#define FILE_SEPARATOR
Definition: file_lib.h:102
void AddFilenameToListOfSuspicious(const char *pattern)
void SetRepositoryChar(char c)
void SetRepositoryLocation(const char *path)
void PrintList(List *list)
Definition: findhub.c:128
int ListHubs(List **list)
Definition: findhub.c:150
void GenericAgentConfigSetInputFile(GenericAgentConfig *config, const char *inputdir, const char *input_file)
void SetFacility(const char *retval)
GenericAgentConfig * GenericAgentConfigNewDefault(AgentType agent_type, bool tty_interactive)
bool GenericAgentPostLoadInit(const EvalContext *ctx)
Policy * SelectAndLoadPolicy(GenericAgentConfig *config, EvalContext *ctx, bool validate_policy, bool write_validated_file)
void GenericAgentConfigSetBundleSequence(GenericAgentConfig *config, const Rlist *bundlesequence)
void SetupSignalsForAgent(void)
void GenericAgentShowContextsFormatted(EvalContext *ctx, const char *regexp)
Seq * ControlBodyConstraints(const Policy *policy, AgentType agent)
void GenericAgentFinalize(EvalContext *ctx, GenericAgentConfig *config)
void GenericAgentDiscoverContext(EvalContext *ctx, GenericAgentConfig *config, const char *program_name)
void GenericAgentShowVariablesFormatted(EvalContext *ctx, const char *regexp)
bool GenericAgentConfigParseArguments(GenericAgentConfig *config, int argc, char **argv)
bool GetTTYInteractive(void)
bool GenericAgentConfigParseColor(GenericAgentConfig *config, const char *mode)
void GenericAgentConfigApply(EvalContext *ctx, const GenericAgentConfig *config)
void GenericAgentWriteVersion(Writer *w)
int errno
#define NULL
Definition: getopt1.c:56
int optind
Definition: getopt.c:102
char * optarg
Definition: getopt.c:87
#define no_argument
Definition: getopt.h:98
#define required_argument
Definition: getopt.h:99
int getopt_long()
#define optional_argument
Definition: getopt.h:100
void EndMeasure(char *eventname, struct timespec start)
void EndMeasurePromise(struct timespec start, const Promise *pp)
bool TIMING
struct timespec BeginMeasure()
Item * PrependItem(Item **liststart, const char *itemstring, const char *classes)
Definition: item_lib.c:372
void JsonWriteCompact(Writer *const w, const JsonElement *const element)
Definition: json.c:1832
const char * GetInputDir(void)
Definition: known_dirs.c:182
const char * GetLogDir(void)
Definition: known_dirs.c:146
const char * GetStateDir(void)
Definition: known_dirs.c:186
const char * GetWorkDir(void)
Definition: known_dirs.c:114
int ListDestroy(List **list)
Destroy a linked list.
Definition: list.c:162
void * avahi_handle
Definition: load_avahi.h:61
void BackupLockDatabase(void)
Definition: locks.c:1144
void PurgeLocks(void)
Definition: locks.c:1161
bool LogEnableModulesFromString(char *s)
Definition: logging.c:476
void LogSetGlobalLevelArgOrExit(const char *const arg)
Definition: logging.c:567
void LoggingEnableTimestamps(bool enable)
Definition: logging.c:88
void LogSetGlobalLevel(LogLevel level)
Definition: logging.c:561
LogLevel LogGetGlobalLevel(void)
Definition: logging.c:581
bool WouldLog(LogLevel level)
Definition: logging.c:308
const char * GetErrorStr(void)
Definition: logging.c:275
void Log(LogLevel level, const char *fmt,...)
Definition: logging.c:409
const char * LogLevelToString(LogLevel level)
Definition: logging.c:112
@ LOG_LEVEL_ERR
Definition: logging.h:42
@ LOG_LEVEL_NOTICE
Definition: logging.h:44
@ LOG_LEVEL_DEBUG
Definition: logging.h:47
@ LOG_LEVEL_WARNING
Definition: logging.h:43
@ LOG_LEVEL_VERBOSE
Definition: logging.h:46
@ LOG_LEVEL_INFO
Definition: logging.h:45
void ManPageWrite(Writer *out, const char *program, time_t last_modified, const char *short_description, const char *long_description, const struct option options[], const char *const option_hints[], const Description *commands, bool command_first, bool accepts_file_argument)
Definition: man.c:226
bool FullTextMatch(EvalContext *ctx, const char *regexp, const char *teststring)
Definition: match_scope.c:87
bool IsRegexItemIn(const EvalContext *ctx, const Item *list, const char *regex)
Definition: matching.c:235
int putenv_wrapper(const char *str)
Definition: misc_lib.c:169
int setenv_wrapper(const char *name, const char *value, int overwrite)
Definition: misc_lib.c:140
#define ProgrammingError(...)
Definition: misc_lib.h:33
CommonControl CommonControlFromString(const char *lval)
Definition: mod_common.c:546
uint32_t bwlimit_kbytes
Definition: net.c:302
void DeleteMountInfo(Seq *list)
Definition: nfs.c:405
void BundleBanner(const Bundle *bp, const Rlist *params)
Definition: ornaments.c:227
void Banner(const char *s)
Definition: ornaments.c:219
void SpecialTypeBanner(TypeSequence type, int pass)
Definition: ornaments.c:113
void EndBundleBanner(const Bundle *bp)
Definition: ornaments.c:246
void UpdatePackagesCache(EvalContext *ctx, bool force_update)
bool IsPrivileged()
Definition: patches.c:105
uid_t getuid(void)
void PolicyDestroy(Policy *policy)
Definition: policy.c:121
int PromiseGetConstraintAsBoolean(const EvalContext *ctx, const char *lval, const Promise *pp)
Get the trinary boolean value of the first effective constraint found matching, from a promise.
Definition: policy.c:2481
const Bundle * PromiseGetBundle(const Promise *pp)
Definition: policy.c:2671
void * PromiseGetConstraintAsRval(const Promise *pp, const char *lval, RvalType rtype)
Get the Rval value of the first effective constraint that matches the given type.
Definition: policy.c:3054
const PromiseType * BundleGetPromiseType(const Bundle *bp, const char *name)
Definition: policy.c:1600
StringSet * PolicySourceFiles(const Policy *policy)
Definition: policy.c:240
bool PolicyServerRemoveFile(const char *workdir)
Remove the policy_server.dat file.
const char * PolicyServerGet()
Used to access the internal POLICY_SERVER variable.
Access to Policy Server IP Address, hostname and port number.
bool IsProcessNameRunning(char *procNameRegex)
bool LoadProcessTable()
void ClearProcessTable(void)
void PromiseRef(LogLevel level, const Promise *pp)
Definition: promises.c:769
PromiseResult VerifyReportPromise(EvalContext *ctx, const Promise *pp)
#define CloseNetwork()
Definition: prototypes3.h:102
#define OpenNetwork()
Definition: prototypes3.h:101
int repair_lmdb_default(bool force)
Definition: repair.c:14
FnCall * RlistFnCallValue(const Rlist *rlist)
Definition: rlist.c:105
char * RlistScalarValue(const Rlist *rlist)
Definition: rlist.c:83
void RvalWrite(Writer *writer, Rval rval)
Definition: rlist.c:1386
void RlistWrite(Writer *writer, const Rlist *list)
Definition: rlist.c:1318
Rlist * RlistFromSplitString(const char *string, char sep)
Definition: rlist.c:1067
void RlistDestroy(Rlist *rl)
Definition: rlist.c:501
Rlist * RlistAppendScalar(Rlist **start, const char *scalar)
Definition: rlist.c:545
char * RlistToString(const Rlist *rlist)
Definition: rlist.c:1403
Rlist * RlistCopy(const Rlist *rp)
Definition: rlist.c:494
size_t SeqLength(const Seq *seq)
Length of the sequence.
Definition: sequence.c:354
void SeqClear(Seq *seq)
Remove all elements in sequence.
Definition: sequence.c:314
static void * SeqAt(const Seq *seq, int i)
Definition: sequence.h:57
StringSetIterator StringSetIteratorInit(StringSet *set)
Definition: set.c:34
StringSet * StringSetFromString(const char *str, char delimiter)
Definition: set.c:179
void StringSetJoin(const StringSet *set, const StringSet *otherset, StringCopyFn copy_function)
Definition: set.c:34
StringSet * StringSetNew(void)
Definition: set.c:34
void StringSetDestroy(StringSet *set)
Definition: set.c:34
char * StringSetIteratorNext(StringSetIterator *iter)
Definition: set.c:34
#define MAX(x, y)
Definition: snprintf.c:500
bool StringEqual(const char *const a, const char *const b)
Definition: string_lib.c:256
bool StringEqual_IgnoreCase(const char *const a, const char *const b)
Definition: string_lib.c:296
void ToLowerStrInplace(char *str)
Definition: string_lib.c:162
#define NULL_OR_EMPTY(str)
Definition: string_lib.h:43
size_t strlcat(char *dst, const char *src, size_t siz)
Definition: strlcat.c:36
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:34
Definition: policy.h:70
char * name
Definition: policy.h:74
char * ns
Definition: policy.h:75
Definition: class.h:31
char * ns
Definition: class.h:32
char * name
Definition: class.h:33
const char * lval
Definition: cf3.defs.h:656
char * classes
Definition: policy.h:135
char * lval
Definition: policy.h:132
char * name
Definition: fncall.h:32
Rlist * args
Definition: fncall.h:33
StringSet * heap_soft
Definition: generic_agent.h:59
char * show_evaluated_variables
Definition: generic_agent.h:92
struct GenericAgentConfig::@14 agent_specific
struct GenericAgentConfig::@14::@16 agent
StringSet * heap_negated
Definition: generic_agent.h:60
char * show_evaluated_classes
Definition: generic_agent.h:91
Definition: item_lib.h:33
Definition: list.c:40
Definition: policy.h:53
Seq * promises
Definition: policy.h:104
char * name
Definition: policy.h:103
PromiseType * parent_promise_type
Definition: policy.h:111
char * promiser
Definition: policy.h:115
Definition: rlist.h:35
Rlist * next
Definition: rlist.h:37
Sequence data-structure.
Definition: sequence.h:50
Definition: set.h:138
Definition: writer.c:45
Definition: getopt.h:83
char * name
Definition: getopt.h:87
char nodename[257]
Definition: platform.h:109
void SetSyslogPort(uint16_t port)
Definition: syslog_client.c:62
bool SetSyslogHost(const char *host)
Definition: syslog_client.c:49
VarRef * VarRefParseFromScope(const char *var_ref_string, const char *scope)
void VarRefDestroy(VarRef *ref)
VarRef * VarRefParseFromBundle(const char *var_ref_string, const Bundle *bundle)
Parse the variable reference in the context of a bundle. This means that the VarRef will inherit scop...
PromiseResult VerifyClassPromise(EvalContext *ctx, const Promise *pp, void *param)
PromiseResult VerifyDatabasePromises(EvalContext *ctx, const Promise *pp)
void NewEnvironmentsContext(void)
PromiseResult VerifyEnvironmentsPromise(EvalContext *ctx, const Promise *pp)
void DeleteEnvironmentsContext(void)
PromiseResult VerifyExecPromise(EvalContext *ctx, const Promise *pp)
Definition: verify_exec.c:96
PromiseResult FindAndVerifyFilesPromises(EvalContext *ctx, const Promise *pp)
Definition: verify_files.c:875
void SetFileAutoDefineList(const Rlist *auto_define_list)
StringSet * SINGLE_COPY_CACHE
const Rlist * SINGLE_COPY_LIST
PromiseResult VerifyMethodsPromise(EvalContext *ctx, const Promise *pp)
void CleanScheduledPackages(void)
Clean the package schedule and installed lists.
PromiseResult VerifyPackagesPromise(EvalContext *ctx, const Promise *pp)
void ExecuteScheduledPackages(EvalContext *ctx)
Execute the full package schedule.
PromiseResult VerifyProcessesPromise(EvalContext *ctx, const Promise *pp)
PromiseResult VerifyServicesPromise(EvalContext *ctx, const Promise *pp)
Seq * GetGlobalMountedFSList(void)
PromiseResult FindAndVerifyStoragePromises(EvalContext *ctx, const Promise *pp)
void DeleteStorageContext(void)
bool CF_MOUNTALL
PromiseResult VerifyUsersPromise(EvalContext *ctx, const Promise *pp)
Definition: verify_users.c:36
PromiseResult VerifyVarPromise(EvalContext *ctx, const Promise *pp, void *param)
Definition: verify_vars.c:109
void WriterWriteHelp(Writer *w, const char *component, const struct option options[], const char *const hints[], const Description *commands, bool command_first, bool accepts_file_argument)
Definition: writer.c:331
size_t WriterWrite(Writer *writer, const char *str)
Definition: writer.c:193
Writer * FileWriter(FILE *file)
Definition: writer.c:56
char * StringWriterClose(Writer *writer)
Definition: writer.c:262
const char * StringWriterData(const Writer *writer)
Definition: writer.c:229
void WriterClose(Writer *writer)
Definition: writer.c:242
size_t WriterWriteF(Writer *writer, const char *fmt,...)
Definition: writer.c:144
Writer * StringWriter(void)
Definition: writer.c:67
FILE * FileWriterDetach(Writer *writer)
Definition: writer.c:277