1 /*
2   Copyright 2021 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 #ifndef CFENGINE_POLICY_H
26 #define CFENGINE_POLICY_H
27 
28 #include <cf3.defs.h>
29 
30 #include <writer.h>
31 #include <sequence.h>
32 #include <json.h>
33 #include <set.h>
34 
35 typedef enum
36 {
37     POLICY_ELEMENT_TYPE_POLICY,
38     POLICY_ELEMENT_TYPE_BUNDLE,
39     POLICY_ELEMENT_TYPE_BODY,
40     POLICY_ELEMENT_TYPE_BUNDLE_SECTION,
41     POLICY_ELEMENT_TYPE_PROMISE,
42     POLICY_ELEMENT_TYPE_CONSTRAINT
43 } PolicyElementType;
44 
45 typedef struct
46 {
47     PolicyElementType type;
48     const void *subject;
49     char *message;
50 } PolicyError;
51 
52 struct Policy_
53 {
54     char *release_id;
55 
56     Seq *bundles;
57     Seq *bodies;
58     Seq *custom_promise_types;
59     StringMap *policy_files_hashes;
60 };
61 
62 typedef struct
63 {
64     size_t start;
65     size_t end;
66     size_t line;
67     size_t context;
68 } SourceOffset;
69 
70 struct Bundle_
71 {
72     Policy *parent_policy;
73 
74     char *type;
75     char *name;
76     char *ns;
77     Rlist *args;
78 
79     Seq *sections;
80     Seq *custom_sections;
81 
82     char *source_path;
83     SourceOffset offset;
84 };
85 
86 struct Body_
87 {
88     Policy *parent_policy;
89 
90     char *type;
91     char *name;
92     char *ns;
93     Rlist *args;
94 
95     Seq *conlist;
96 
97     char *source_path;
98     SourceOffset offset;
99 };
100 
101 struct BundleSection_
102 {
103     Bundle *parent_bundle;
104 
105     char *promise_type;
106     Seq *promises;
107 
108     SourceOffset offset;
109 };
110 
111 struct Promise_
112 {
113     BundleSection *parent_section;
114 
115     char *classes;
116     char *comment;
117     char *promiser;
118     Rval promisee;
119     Seq *conlist;
120 
121     const Promise *org_pp;            /* A ptr to the unexpanded raw promise */
122 
123     SourceOffset offset;
124 };
125 
126 struct Constraint_
127 {
128     PolicyElementType type;
129     union {
130         Promise *promise;
131         Body *body;
132     } parent;
133 
134     char *lval;
135     Rval rval;
136 
137     char *classes;
138     bool references_body;
139 
140     SourceOffset offset;
141 };
142 
143 const char *NamespaceDefault(void);
144 
145 Policy *PolicyNew(void);
146 int PolicyCompare(const void *a, const void *b);
147 void PolicyDestroy(Policy *policy);
148 unsigned PolicyHash(const Policy *policy);
149 
150 StringSet *PolicySourceFiles(const Policy *policy);
151 const char *PolicyGetPolicyFileHash(const Policy *policy, const char *policy_file_path);
152 
153 Policy *PolicyMerge(Policy *a, Policy *b);
154 Body *PolicyGetBody(const Policy *policy, const char *ns, const char *type, const char *name);
155 Bundle *PolicyGetBundle(const Policy *policy, const char *ns, const char *type, const char *name);
156 bool PolicyIsRunnable(const Policy *policy);
157 const Policy *PolicyFromPromise(const Promise *promise);
158 char *BundleQualifiedName(const Bundle *bundle);
159 
160 PolicyError *PolicyErrorNew(PolicyElementType type, const void *subject, const char *error_msg, ...);
161 void PolicyErrorDestroy(PolicyError *error);
162 void PolicyErrorWrite(Writer *writer, const PolicyError *error);
163 
164 bool PolicyCheckPartial(const Policy *policy, Seq *errors);
165 bool PolicyCheckRunnable(const EvalContext *ctx, const Policy *policy, Seq *errors, bool ignore_missing_bundles);
166 
167 Bundle *PolicyAppendBundle(Policy *policy, const char *ns, const char *name, const char *type, const Rlist *args, const char *source_path);
168 Body *PolicyAppendBody(Policy *policy, const char *ns, const char *name, const char *type, Rlist *args, const char *source_path);
169 Body *PolicyAppendPromiseBlock(Policy *policy, const char *ns, const char *name, const char *type, Rlist *args, const char *source_path);
170 
171 JsonElement *PolicyToJson(const Policy *policy);
172 JsonElement *BundleToJson(const Bundle *bundle);
173 JsonElement *BodyToJson(const Body *body);
174 Policy *PolicyFromJson(JsonElement *json_policy);
175 void PolicyToString(const Policy *policy, Writer *writer);
176 
177 BundleSection *BundleAppendSection(Bundle *bundle, const char *promise_type);
178 const BundleSection *BundleGetSection(const Bundle *bp, const char *promise_type);
179 
180 Constraint *BodyAppendConstraint(Body *body, const char *lval, Rval rval, const char *classes, bool references_body);
181 Seq *BodyGetConstraint(Body *body, const char *lval);
182 bool BodyHasConstraint(const Body *body, const char *lval);
183 
184 const char *ConstraintGetNamespace(const Constraint *cp);
185 
186 Promise *BundleSectionAppendPromise(BundleSection *section, const char *promiser, Rval promisee, const char *classes, const char *varclasses);
187 void BundleSectionDestroy(BundleSection *section);
188 
189 void PromiseDestroy(Promise *pp);
190 
191 Constraint *PromiseAppendConstraint(Promise *promise, const char *lval, Rval rval, bool references_body);
192 
193 const char *PromiseGetNamespace(const Promise *pp);
194 const Bundle *PromiseGetBundle(const Promise *pp);
195 const Policy *PromiseGetPolicy(const Promise *pp);
196 
PromiseGetPromiseType(const Promise * pp)197 static inline const char *PromiseGetPromiseType(const Promise *pp)
198 {
199     assert(pp != NULL);
200     return pp->parent_section->promise_type;
201 }
202 
203 void PromisePath(Writer *w, const Promise *pp);
204 const char *PromiseGetHandle(const Promise *pp);
205 int PromiseGetConstraintAsInt(const EvalContext *ctx, const char *lval, const Promise *pp);
206 bool PromiseGetConstraintAsReal(const EvalContext *ctx, const char *lval, const Promise *list, double *value_out);
207 mode_t PromiseGetConstraintAsOctal(const EvalContext *ctx, const char *lval, const Promise *list);
208 uid_t PromiseGetConstraintAsUid(const EvalContext *ctx, const char *lval, const Promise *pp);
209 gid_t PromiseGetConstraintAsGid(const EvalContext *ctx, char *lval, const Promise *pp);
210 Rlist *PromiseGetConstraintAsList(const EvalContext *ctx, const char *lval, const Promise *pp);
211 int PromiseGetConstraintAsBoolean(const EvalContext *ctx, const char *lval, const Promise *list);
212 Constraint *PromiseGetConstraintWithType(const Promise *promise, const char *lval, RvalType type);
213 Constraint *PromiseGetImmediateConstraint(const Promise *promise, const char *lval);
214 void *PromiseGetConstraintAsRval(const Promise *promise, const char *lval, RvalType type);
215 Constraint *PromiseGetConstraint(const Promise *promise, const char *lval);
216 
217 bool PromiseBundleOrBodyConstraintExists(const EvalContext *ctx, const char *lval, const Promise *pp);
218 
219 void PromiseRecheckAllConstraints(const EvalContext *ctx, const Promise *pp);
220 
221 void ConstraintDestroy(Constraint *cp);
222 int ConstraintsGetAsBoolean(const EvalContext *ctx, const char *lval, const Seq *constraints);
223 const char *ConstraintContext(const Constraint *cp);
224 Constraint *EffectiveConstraint(const EvalContext *ctx, Seq *constraints);
225 
226 void *PromiseGetImmediateRvalValue(const char *lval, const Promise *pp, RvalType rtype);
227 
228 char *QualifiedNameNamespaceComponent(const char *qualified_name);
229 char *QualifiedNameScopeComponent(const char *qualified_name);
230 bool BundleTypeCheck(const char *name);
231 Rval DefaultBundleConstraint(const Promise *pp, char *promisetype);
232 
233 bool PolicyHasCustomPromiseType(const Policy *policy, const char *name);
234 
235 #endif
236