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)  

exec-config.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 #include <exec-config.h>
26 
27 #include <alloc.h>
28 #include <string_lib.h>
29 #include <writer.h>
30 
31 #include <rlist.h>
32 #include <eval_context.h>
33 #include <conversion.h>
34 #include <generic_agent.h> // TODO: fix
35 #include <regex.h> // pcre_free()
36 #include <item_lib.h>
37 
38 
39 static char *GetIpAddresses(const EvalContext *ctx)
40 {
41  Writer *ipbuf = StringWriter();
42 
43  for (Item *iptr = EvalContextGetIpAddresses(ctx); iptr != NULL; iptr = iptr->next)
44  {
45  WriterWrite(ipbuf, iptr->name);
46  if (iptr->next != NULL)
47  {
48  WriterWriteChar(ipbuf, ' ');
49  }
50  }
51 
52  return StringWriterClose(ipbuf);
53 }
54 
55 static void RegexFree(void *ptr)
56 {
57  pcre_free(ptr);
58 }
59 
60 static void MailFilterFill(const char *str,
61  Seq **output, Seq **output_regex,
62  const char *filter_type)
63 {
64  const char *errorstr;
65  int erroffset;
66  pcre *rx = pcre_compile(str,
67  PCRE_MULTILINE | PCRE_DOTALL | PCRE_ANCHORED,
68  &errorstr, &erroffset, NULL);
69  if (!rx)
70  {
72  "Invalid regular expression in mailfilter_%s: "
73  "pcre_compile() '%s' in expression '%s' (offset: %d). "
74  "Ignoring expression.", filter_type,
75  errorstr, str, erroffset);
76  }
77  else
78  {
79  SeqAppend(*output, xstrdup(str));
80  SeqAppend(*output_regex, rx);
81  }
82 }
83 
84 static void RlistMailFilterFill(const Rlist *input,
85  Seq **output, Seq **output_regex,
86  const char *filter_type)
87 {
88  int len = RlistLen(input);
89 
90  *output = SeqNew(len, &free);
91  *output_regex = SeqNew(len, &RegexFree);
92 
93  const Rlist *ptr = input;
94  for (int i = 0; i < len; i++)
95  {
96  const char *str = ptr->val.item;
97  MailFilterFill(str, output, output_regex, filter_type);
98 
99  ptr = ptr->next;
100  }
101 }
102 
103 static void SeqMailFilterFill(const Seq *input,
104  Seq **output, Seq **output_regex,
105  const char *filter_type)
106 {
107  int len = SeqLength(input);
108 
109  *output = SeqNew(len, &free);
110  *output_regex = SeqNew(len, &RegexFree);
111 
112  for (int i = 0; i < len; i++)
113  {
114  MailFilterFill(SeqAt(input, i), output, output_regex, filter_type);
115  }
116 }
117 
118 ExecConfig *ExecConfigNew(bool scheduled_run, const EvalContext *ctx, const Policy *policy)
119 {
120  ExecConfig *exec_config = xcalloc(1, sizeof(ExecConfig));
121 
122  exec_config->scheduled_run = scheduled_run;
123  exec_config->exec_command = xstrdup("");
124  exec_config->agent_expireafter = 2 * 60; /* two hours */
125 
126  exec_config->mail_server = xstrdup("");
127  exec_config->mail_from_address = xstrdup("");
128  exec_config->mail_to_address = xstrdup("");
129  exec_config->mail_subject = xstrdup("");
130  exec_config->mail_max_lines = 30;
131  exec_config->mailfilter_include = SeqNew(0, &free);
132  exec_config->mailfilter_include_regex = SeqNew(0, &RegexFree);
133  exec_config->mailfilter_exclude = SeqNew(0, &free);
134  exec_config->mailfilter_exclude_regex = SeqNew(0, &RegexFree);
135 
136  exec_config->fq_name = xstrdup(VFQNAME);
137  exec_config->ip_address = xstrdup(VIPADDRESS);
138  exec_config->ip_addresses = GetIpAddresses(ctx);
139 
140  Seq *constraints = ControlBodyConstraints(policy, AGENT_TYPE_EXECUTOR);
141  if (constraints)
142  {
143  for (size_t i = 0; i < SeqLength(constraints); i++)
144  {
145  Constraint *cp = SeqAt(constraints, i);
146 
147  if (!IsDefinedClass(ctx, cp->classes))
148  {
149  continue;
150  }
151 
152  VarRef *ref = VarRefParseFromScope(cp->lval, "control_executor");
153  DataType t;
154  const void *value = EvalContextVariableGet(ctx, ref, &t);
155  VarRefDestroy(ref);
156 
157  if (t == CF_DATA_TYPE_NONE)
158  {
159  ProgrammingError("Unknown attribute '%s' in control body,"
160  " should have already been stopped by the parser",
161  cp->lval);
162  }
163 
164  if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_MAILFROM].lval) == 0)
165  {
166  free(exec_config->mail_from_address);
167  exec_config->mail_from_address = xstrdup(value);
168  Log(LOG_LEVEL_DEBUG, "mailfrom '%s'", exec_config->mail_from_address);
169  }
170  else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_MAILTO].lval) == 0)
171  {
172  free(exec_config->mail_to_address);
173  exec_config->mail_to_address = xstrdup(value);
174  Log(LOG_LEVEL_DEBUG, "mailto '%s'", exec_config->mail_to_address);
175  }
176  else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_MAILSUBJECT].lval) == 0)
177  {
178  free(exec_config->mail_subject);
179  exec_config->mail_subject = xstrdup(value);
180  Log(LOG_LEVEL_DEBUG, "mailsubject '%s'", exec_config->mail_subject);
181  }
182  else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_SMTPSERVER].lval) == 0)
183  {
184  free(exec_config->mail_server);
185  exec_config->mail_server = xstrdup(value);
186  Log(LOG_LEVEL_DEBUG, "smtpserver '%s'", exec_config->mail_server);
187  }
188  else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_EXECCOMMAND].lval) == 0)
189  {
190  free(exec_config->exec_command);
191  exec_config->exec_command = xstrdup(value);
192  Log(LOG_LEVEL_DEBUG, "exec_command '%s'", exec_config->exec_command);
193  }
194  else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_AGENT_EXPIREAFTER].lval) == 0)
195  {
196  exec_config->agent_expireafter = IntFromString(value);
197  Log(LOG_LEVEL_DEBUG, "agent_expireafter %d", exec_config->agent_expireafter);
198  }
199  else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_MAILMAXLINES].lval) == 0)
200  {
201  exec_config->mail_max_lines = IntFromString(value);
202  Log(LOG_LEVEL_DEBUG, "maxlines %d", exec_config->mail_max_lines);
203  }
204  else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_MAILFILTER_INCLUDE].lval) == 0)
205  {
206  SeqDestroy(exec_config->mailfilter_include);
207  SeqDestroy(exec_config->mailfilter_include_regex);
208  RlistMailFilterFill(value, &exec_config->mailfilter_include,
209  &exec_config->mailfilter_include_regex, "include");
210  }
211  else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_MAILFILTER_EXCLUDE].lval) == 0)
212  {
213  SeqDestroy(exec_config->mailfilter_exclude);
214  SeqDestroy(exec_config->mailfilter_exclude_regex);
215  RlistMailFilterFill(value, &exec_config->mailfilter_exclude,
216  &exec_config->mailfilter_exclude_regex, "exclude");
217  }
218  }
219  }
220 
221  return exec_config;
222 }
223 
225 {
226  ExecConfig *copy = xcalloc(1, sizeof(ExecConfig));
227 
228  copy->scheduled_run = config->scheduled_run;
229  copy->exec_command = xstrdup(config->exec_command);
230  copy->agent_expireafter = config->agent_expireafter;
231  copy->mail_server = xstrdup(config->mail_server);
233  copy->mail_to_address = xstrdup(config->mail_to_address);
234  copy->mail_subject = xstrdup(config->mail_subject);
235  copy->mail_max_lines = config->mail_max_lines;
237  &copy->mailfilter_include_regex, "include");
239  &copy->mailfilter_exclude_regex, "exclude");
240  copy->fq_name = xstrdup(config->fq_name);
241  copy->ip_address = xstrdup(config->ip_address);
242  copy->ip_addresses = xstrdup(config->ip_addresses);
243 
244  return copy;
245 }
246 
247 void ExecConfigDestroy(ExecConfig *exec_config)
248 {
249  if (exec_config)
250  {
251  free(exec_config->exec_command);
252  free(exec_config->mail_server);
253  free(exec_config->mail_from_address);
254  free(exec_config->mail_to_address);
255  free(exec_config->mail_subject);
256  SeqDestroy(exec_config->mailfilter_include);
257  SeqDestroy(exec_config->mailfilter_exclude);
258  SeqDestroy(exec_config->mailfilter_include_regex);
259  SeqDestroy(exec_config->mailfilter_exclude_regex);
260  free(exec_config->fq_name);
261  free(exec_config->ip_address);
262  free(exec_config->ip_addresses);
263 
264  free(exec_config);
265  }
266 }
void * xcalloc(size_t nmemb, size_t size)
Definition: alloc-mini.c:51
char * xstrdup(const char *str)
Definition: alloc-mini.c:56
const ConstraintSyntax CFEX_CONTROLBODY[]
Definition: mod_common.c:376
@ EXEC_CONTROL_AGENT_EXPIREAFTER
Definition: cf3.defs.h:508
@ EXEC_CONTROL_MAILMAXLINES
Definition: cf3.defs.h:502
@ EXEC_CONTROL_SMTPSERVER
Definition: cf3.defs.h:501
@ EXEC_CONTROL_MAILFILTER_EXCLUDE
Definition: cf3.defs.h:504
@ EXEC_CONTROL_EXECCOMMAND
Definition: cf3.defs.h:507
@ EXEC_CONTROL_MAILFILTER_INCLUDE
Definition: cf3.defs.h:503
@ EXEC_CONTROL_MAILTO
Definition: cf3.defs.h:499
@ EXEC_CONTROL_MAILSUBJECT
Definition: cf3.defs.h:500
@ EXEC_CONTROL_MAILFROM
Definition: cf3.defs.h:498
@ AGENT_TYPE_EXECUTOR
Definition: cf3.defs.h:405
DataType
Definition: cf3.defs.h:368
@ CF_DATA_TYPE_NONE
Definition: cf3.defs.h:385
static int input(void)
Definition: cf3lex.c:2154
void free(void *)
char VFQNAME[]
Definition: cf3globals.c:58
char VIPADDRESS[64]
Definition: cf3globals.c:81
long IntFromString(const char *s)
Definition: conversion.c:390
const void * EvalContextVariableGet(const EvalContext *ctx, const VarRef *ref, DataType *type_out)
Item * EvalContextGetIpAddresses(const EvalContext *ctx)
static bool IsDefinedClass(const EvalContext *ctx, const char *context)
Definition: eval_context.h:213
static char * GetIpAddresses(const EvalContext *ctx)
Definition: exec-config.c:39
ExecConfig * ExecConfigNew(bool scheduled_run, const EvalContext *ctx, const Policy *policy)
Definition: exec-config.c:118
ExecConfig * ExecConfigCopy(const ExecConfig *config)
Definition: exec-config.c:224
static void RegexFree(void *ptr)
Definition: exec-config.c:55
static void SeqMailFilterFill(const Seq *input, Seq **output, Seq **output_regex, const char *filter_type)
Definition: exec-config.c:103
void ExecConfigDestroy(ExecConfig *exec_config)
Definition: exec-config.c:247
static void RlistMailFilterFill(const Rlist *input, Seq **output, Seq **output_regex, const char *filter_type)
Definition: exec-config.c:84
static void MailFilterFill(const char *str, Seq **output, Seq **output_regex, const char *filter_type)
Definition: exec-config.c:60
Seq * ControlBodyConstraints(const Policy *policy, AgentType agent)
#define NULL
Definition: getopt1.c:56
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
#define ProgrammingError(...)
Definition: misc_lib.h:33
int RlistLen(const Rlist *start)
Definition: rlist.c:672
size_t SeqLength(const Seq *seq)
Length of the sequence.
Definition: sequence.c:354
Seq * SeqNew(size_t initialCapacity, void(ItemDestroy)(void *item))
Definition: sequence.c:31
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
const char * lval
Definition: cf3.defs.h:656
char * classes
Definition: policy.h:135
char * lval
Definition: policy.h:132
int mail_max_lines
Definition: exec-config.h:42
int agent_expireafter
Definition: exec-config.h:36
Seq * mailfilter_exclude_regex
Definition: exec-config.h:48
Seq * mailfilter_include_regex
Definition: exec-config.h:47
char * fq_name
Definition: exec-config.h:54
char * ip_addresses
Definition: exec-config.h:56
char * exec_command
Definition: exec-config.h:35
char * mail_server
Definition: exec-config.h:38
Seq * mailfilter_exclude
Definition: exec-config.h:45
char * ip_address
Definition: exec-config.h:55
Seq * mailfilter_include
Definition: exec-config.h:44
char * mail_from_address
Definition: exec-config.h:39
bool scheduled_run
Definition: exec-config.h:34
char * mail_to_address
Definition: exec-config.h:40
char * mail_subject
Definition: exec-config.h:41
Definition: item_lib.h:33
Definition: policy.h:53
Definition: rlist.h:35
Rval val
Definition: rlist.h:36
Rlist * next
Definition: rlist.h:37
void * item
Definition: cf3.defs.h:615
Sequence data-structure.
Definition: sequence.h:50
Definition: writer.c:45
VarRef * VarRefParseFromScope(const char *var_ref_string, const char *scope)
void VarRefDestroy(VarRef *ref)
size_t WriterWrite(Writer *writer, const char *str)
Definition: writer.c:193
char * StringWriterClose(Writer *writer)
Definition: writer.c:262
size_t WriterWriteChar(Writer *writer, char c)
Definition: writer.c:200
Writer * StringWriter(void)
Definition: writer.c:67