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)  

agent-diagnostics.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 <agent-diagnostics.h>
26 
27 #include <alloc.h>
28 #include <crypto.h>
29 #include <files_interfaces.h>
30 #include <string_lib.h>
31 #include <bootstrap.h>
32 #include <policy_server.h>
33 #include <dbm_api.h>
34 #include <dbm_priv.h>
35 #include <tokyo_check.h>
36 #include <lastseen.h>
37 #include <file_lib.h>
38 #include <known_dirs.h>
39 
40 
42 {
43  return (AgentDiagnosticsResult) { success, message };
44 }
45 
47 {
48  free(result.message);
49 }
50 
51 void AgentDiagnosticsRun(const char *workdir, const AgentDiagnosticCheck checks[], Writer *output)
52 {
53  {
54  char diagnostics_path[CF_BUFSIZE] = { 0 };
55  snprintf(diagnostics_path, CF_BUFSIZE, "%s/diagnostics", workdir);
56  MapName(diagnostics_path);
57 
58  struct stat sb;
59  if (stat(diagnostics_path, &sb) != 0)
60  {
61  if (mkdir(diagnostics_path, DEFAULTMODE) != 0)
62  {
63  WriterWriteF(output, "Cannot create diagnostics output directory '%s'", diagnostics_path);
64  return;
65  }
66  }
67  }
68 
69 
70  for (int i = 0; checks[i].description; i++)
71  {
72  AgentDiagnosticsResult result = checks[i].check(workdir);
73  WriterWriteF(output, "[ %s ] %s: %s\n",
74  result.success ? "YES" : "NO ",
75  checks[i].description,
76  result.message);
78  }
79 }
80 
82 {
83  char *policy_server = PolicyServerReadFile(workdir);
84  return AgentDiagnosticsResultNew(policy_server != NULL,
85  policy_server != NULL ? policy_server : xstrdup("Not bootstrapped"));
86 }
87 
89 {
90  bool am_policy_server = GetAmPolicyHub();
91  return AgentDiagnosticsResultNew(am_policy_server,
92  am_policy_server ? xstrdup("Acting as a policy server") : xstrdup("Not acting as a policy server"));
93 }
94 
96 {
97  char *path = PrivateKeyFile(workdir);
98  struct stat sb;
100 
101  if (stat(path, &sb) != 0)
102  {
103  res = AgentDiagnosticsResultNew(false, StringFormat("No private key found at '%s'", path));
104  }
105  else if (sb.st_mode != (S_IFREG | S_IWUSR | S_IRUSR))
106  {
107  res = AgentDiagnosticsResultNew(false, StringFormat("Private key found at '%s', but had incorrect permissions '%o'", path, sb.st_mode));
108  }
109  else
110  {
111  res = AgentDiagnosticsResultNew(true, StringFormat("OK at '%s'", path));
112  }
113 
114  free(path);
115  return res;
116 }
117 
119 {
120  char *path = PublicKeyFile(workdir);
121  struct stat sb;
123 
124  if (stat(path, &sb) != 0)
125  {
126  res = AgentDiagnosticsResultNew(false, StringFormat("No public key found at '%s'", path));
127  }
128  else if (sb.st_mode != (S_IFREG | S_IWUSR | S_IRUSR))
129  {
130  res = AgentDiagnosticsResultNew(false, StringFormat("Public key found at '%s', but had incorrect permissions '%o'", path, sb.st_mode));
131  }
132  else if (sb.st_size != 426)
133  {
134  res = AgentDiagnosticsResultNew(false, StringFormat("Public key at '%s' had size %lld bytes, expected 426 bytes", path, (long long)sb.st_size));
135  }
136  else
137  {
138  res = AgentDiagnosticsResultNew(true, StringFormat("OK at '%s'", path));
139  }
140 
141  free(path);
142  return res;
143 }
144 
146 {
147  char *dbpath = DBIdToPath(id);
148  char *error = DBPrivDiagnose(dbpath);
149 
150  if (error)
151  {
152  free(dbpath);
153  return AgentDiagnosticsResultNew(false, error);
154  }
155  else
156  {
157  int ret = CheckTokyoDBCoherence(dbpath);
158  free(dbpath);
159  if (ret)
160  {
161  return AgentDiagnosticsResultNew(false, xstrdup("Internal DB coherence problem"));
162  }
163  else
164  {
165  if (id == dbid_lastseen)
166  {
167  if (IsLastSeenCoherent() == false)
168  {
169  return AgentDiagnosticsResultNew(false, xstrdup("Lastseen DB data coherence problem"));
170  }
171  }
172  return AgentDiagnosticsResultNew(true, xstrdup("OK"));
173 
174  }
175  }
176 }
177 
179 {
180  return AgentDiagnosticsCheckDB(workdir, dbid_state);
181 }
182 
184 {
185  return AgentDiagnosticsCheckDB(workdir, dbid_checksums);
186 }
187 
189 {
190  return AgentDiagnosticsCheckDB(workdir, dbid_lastseen);
191 }
192 
194 {
196 }
197 
199 {
200  return AgentDiagnosticsCheckDB(workdir, dbid_filestats);
201 }
202 
204 {
205  return AgentDiagnosticsCheckDB(workdir, dbid_locks);
206 }
207 
209 {
210  return AgentDiagnosticsCheckDB(workdir, dbid_performance);
211 }
212 
214 {
215  static const AgentDiagnosticCheck checks[] =
216  {
217  { "Check that agent is bootstrapped", &AgentDiagnosticsCheckIsBootstrapped },
218  { "Check if agent is acting as a policy server", &AgentDiagnosticsCheckAmPolicyServer },
219  { "Check private key", &AgentDiagnosticsCheckPrivateKey },
220  { "Check public key", &AgentDiagnosticsCheckPublicKey },
221 
222  { "Check persistent classes DB", &AgentDiagnosticsCheckDBPersistentClasses },
223  { "Check checksums DB", &AgentDiagnosticsCheckDBChecksums },
224  { "Check observations DB", &AgentDiagnosticsCheckDBObservations },
225  { "Check file stats DB", &AgentDiagnosticsCheckDBFileStats },
226  { "Check locks DB", &AgentDiagnosticsCheckDBLocks },
227  { "Check performance DB", &AgentDiagnosticsCheckDBPerformance },
228  { "Check lastseen DB", &AgentDiagnosticsCheckDBLastSeen },
229  { NULL, NULL }
230  };
231 
232  return checks;
233 }
234 
236  ARG_UNUSED const char *, workdir, ARG_UNUSED Writer *, output,
237  ARG_UNUSED AgentDiagnosticsRunFunction, AgentDiagnosticsRunPtr,
238  ARG_UNUSED AgentDiagnosticsResultNewFunction, AgentDiagnosticsResultNewPtr)
239 {
240 }
AgentDiagnosticsResult AgentDiagnosticsCheckDBFileStats(const char *workdir)
AgentDiagnosticsResult AgentDiagnosticsCheckDBChecksums(const char *workdir)
static void AgentDiagnosticsResultDestroy(AgentDiagnosticsResult result)
AgentDiagnosticsResult AgentDiagnosticsCheckDBPersistentClasses(const char *workdir)
AgentDiagnosticsResult AgentDiagnosticsCheckDBLocks(const char *workdir)
AgentDiagnosticsResult AgentDiagnosticsResultNew(bool success, char *message)
AgentDiagnosticsResult AgentDiagnosticsCheckDBPerformance(const char *workdir)
AgentDiagnosticsResult AgentDiagnosticsCheckDBLastSeen(const char *workdir)
const AgentDiagnosticCheck * AgentDiagnosticsAllChecks(void)
void AgentDiagnosticsRun(const char *workdir, const AgentDiagnosticCheck checks[], Writer *output)
AgentDiagnosticsResult AgentDiagnosticsCheckIsBootstrapped(const char *workdir)
AgentDiagnosticsResult AgentDiagnosticsCheckAmPolicyServer(const char *workdir)
void AgentDiagnosticsRunAllChecksNova(const char *workdir, Writer *output, AgentDiagnosticsRunFunction AgentDiagnosticsRunPtr, AgentDiagnosticsResultNewFunction AgentDiagnosticsResultNewPtr)
static AgentDiagnosticsResult AgentDiagnosticsCheckDB(const char *workdir, dbid id)
AgentDiagnosticsResult AgentDiagnosticsCheckPrivateKey(const char *workdir)
AgentDiagnosticsResult AgentDiagnosticsCheckDBObservations(const char *workdir)
AgentDiagnosticsResult AgentDiagnosticsCheckPublicKey(const char *workdir)
AgentDiagnosticsResult(* AgentDiagnosticsResultNewFunction)(bool success, char *message)
void(* AgentDiagnosticsRunFunction)(const char *workdir, const AgentDiagnosticCheck checks[], Writer *output)
char * xstrdup(const char *str)
Definition: alloc-mini.c:56
bool GetAmPolicyHub(void)
Definition: bootstrap.c:191
#define ARG_UNUSED
Definition: cf-net.c:47
#define DEFAULTMODE
Definition: cf3.defs.h:342
void free(void *)
char * PublicKeyFile(const char *workdir)
Definition: crypto.c:749
char * PrivateKeyFile(const char *workdir)
Definition: crypto.c:757
char * DBIdToPath(dbid id)
Definition: dbm_api.c:171
dbid
Definition: dbm_api.h:36
@ dbid_filestats
Definition: dbm_api.h:41
@ dbid_checksums
Definition: dbm_api.h:40
@ dbid_lastseen
Definition: dbm_api.h:45
@ dbid_state
Definition: dbm_api.h:44
@ dbid_performance
Definition: dbm_api.h:39
@ dbid_locks
Definition: dbm_api.h:47
@ dbid_observations
Definition: dbm_api.h:43
char * DBPrivDiagnose(const char *dbpath)
Check a database file for consistency.
#define CF_BUFSIZE
Definition: definitions.h:50
#define ENTERPRISE_VOID_FUNC_4ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4)
char * MapName(char *s)
Definition: file_lib.c:441
#define NULL
Definition: getopt1.c:56
bool IsLastSeenCoherent(void)
check whether the lastseen DB is coherent or not.
Definition: lastseen.c:304
#define S_IFREG
Definition: platform.h:900
#define S_IRUSR
Definition: platform.h:936
#define S_IWUSR
Definition: platform.h:937
char * PolicyServerReadFile(const char *workdir)
Reads the policy_server.dat file.
Access to Policy Server IP Address, hostname and port number.
char * StringFormat(const char *fmt,...)
Format string like sprintf and return formatted string allocated on heap as a return value.
Definition: string_lib.c:51
AgentDiagnosticCheckFn * check
Definition: writer.c:45
int CheckTokyoDBCoherence(const char *path)
Definition: tokyo_check.c:484
size_t WriterWriteF(Writer *writer, const char *fmt,...)
Definition: writer.c:144