~tieto/+junk/cfengine3

« back to all changes in this revision

Viewing changes to .pc/remove-man-errors/src/generic_agent.c

  • Committer: Bazaar Package Importer
  • Author(s): Antonio Radici
  • Date: 2010-04-30 08:11:20 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100430081120-qjlb3etnasi7mr0a
Tags: 3.0.4+dfsg-1
 * debian/watch: modified to catch the newest versions
 * debian/control:
    + removed DMUA
    + bumped Standards-Version to 3.8.4 (no changed needed)
 * debian/patches:
    + all patches refreshed
    + rename-doesnt-fail: removed, it is incorporated upstream
    + added some more typos to patches/fix-error-typos
* Switch to dpkg-source 3.0 (quilt) format
    + debian/control: removed quilt from B-D
    + debian/rules: removed patch/unpatch and quilt include
    + debian/README.source removed
* debian/cfengin3.lintian-overrides:
    + overridden a spelling error (it is not)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Copyright (C) Cfengine AS
 
3
 
 
4
   This file is part of Cfengine 3 - written and maintained by Cfengine 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 Commerical 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
/*****************************************************************************/
 
27
/*                                                                           */
 
28
/* File: generic_agent.c                                                     */
 
29
/*                                                                           */
 
30
/*****************************************************************************/
 
31
 
 
32
#include "cf3.defs.h"
 
33
#include "cf3.extern.h"
 
34
 
 
35
extern FILE *yyin;
 
36
extern char *CFH[][2];
 
37
extern void CheckOpts(int argc,char **argv);
 
38
 
 
39
/*****************************************************************************/
 
40
 
 
41
void GenericInitialize(int argc,char **argv,char *agents)
 
42
 
 
43
{ enum cfagenttype ag = Agent2Type(agents);
 
44
  char vbuff[CF_BUFSIZE];
 
45
  int ok;
 
46
 
 
47
InitializeGA(argc,argv);
 
48
 
 
49
SetReferenceTime(true);
 
50
SetStartTime(false);
 
51
SetSignals();
 
52
 
 
53
// See cf3.defs.h for these settings
 
54
 
 
55
if (EnterpriseExpiry(LIC_DAY,LIC_MONTH,LIC_YEAR)) 
 
56
   {
 
57
   CfOut(cf_error,"","Cfengine - autonomous configuration engine. This enterprise license is invalid.\n");
 
58
   exit(1);
 
59
   }
 
60
 
 
61
if (!NOHARDCLASSES)
 
62
   {
 
63
   NewScope("const");
 
64
   NewScope("match");
 
65
   NewScope("mon");
 
66
   SetNewScope("sys");
 
67
   GetNameInfo3();
 
68
   CfGetInterfaceInfo(ag);
 
69
      
 
70
   if (ag != cf_know)
 
71
      {
 
72
      Get3Environment();
 
73
      OSClasses();
 
74
      }
 
75
   }
 
76
 
 
77
LoadPersistentContext();
 
78
LoadSystemConstants();
 
79
 
 
80
strcpy(THIS_AGENT,CF_AGENTTYPES[ag]);
 
81
NewClass(CanonifyName(THIS_AGENT));
 
82
THIS_AGENT_TYPE = ag;
 
83
 
 
84
snprintf(vbuff,CF_BUFSIZE,"control_%s",THIS_AGENT);
 
85
 
 
86
SetNewScope(vbuff);
 
87
NewScope("this");
 
88
NewScope("match");
 
89
 
 
90
if (BOOTSTRAP)
 
91
   {
 
92
   SetPolicyServer(POLICY_SERVER);
 
93
   CheckAutoBootstrap();
 
94
   }
 
95
 
 
96
ok = BOOTSTRAP || CheckPromises(ag);
 
97
 
 
98
if (ok)
 
99
   {
 
100
   ReadPromises(ag,agents);
 
101
   }
 
102
else
 
103
   {
 
104
   CfOut(cf_error,"","cf-agent was not able to get confirmation of promises from cf-promises, so going to failsafe\n");
 
105
   snprintf(VINPUTFILE,CF_BUFSIZE-1,"failsafe.cf");
 
106
   ReadPromises(ag,agents);
 
107
   }
 
108
 
 
109
if (SHOWREPORTS || ERRORCOUNT)
 
110
   {
 
111
   CompilationReport(VINPUTFILE);
 
112
   }
 
113
 
 
114
CheckLicenses();
 
115
 
 
116
XML = 0;
 
117
}
 
118
 
 
119
/*****************************************************************************/
 
120
 
 
121
void GenericDeInitialize()
 
122
 
 
123
{
 
124
Debug("GenericDeInitialize()\n");
 
125
 
 
126
CloseWmi();
 
127
CloseNetwork();
 
128
Cf3CloseLog();
 
129
CloseAllDB();
 
130
}
 
131
 
 
132
/*****************************************************************************/
 
133
/* Level                                                                     */
 
134
/*****************************************************************************/
 
135
 
 
136
int CheckPromises(enum cfagenttype ag)
 
137
 
 
138
{ char cmd[CF_BUFSIZE],path[CF_BUFSIZE];
 
139
  struct stat sb;
 
140
 
 
141
if ((ag != cf_agent) && (ag != cf_executor) && (ag != cf_server))
 
142
   {
 
143
   return true;
 
144
   }
 
145
 
 
146
CfOut(cf_verbose,""," > Verifying the syntax of the inputs...\n");
 
147
 
 
148
snprintf(cmd,CF_BUFSIZE-1,"%s%cbin%ccf-promises%s",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR,EXEC_SUFFIX);
 
149
 
 
150
if (cfstat(cmd,&sb) == -1)
 
151
   {
 
152
   CfOut(cf_error,"","cf-promises%s needs to be installed in %s%cbin for pre-validation of full configuration",EXEC_SUFFIX,CFWORKDIR,FILE_SEPARATOR);
 
153
   return false;
 
154
   }
 
155
 
 
156
/* If we are cf-agent, check syntax before attempting to run */
 
157
 
 
158
if ((*VINPUTFILE == '.') || IsAbsoluteFileName(VINPUTFILE))
 
159
   {
 
160
   snprintf(cmd,CF_BUFSIZE-1,"\"%s%cbin%ccf-promises%s\" -f \"%s\"",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR,EXEC_SUFFIX,VINPUTFILE);
 
161
   }
 
162
else
 
163
   {
 
164
   snprintf(cmd,CF_BUFSIZE-1,"\"%s%cbin%ccf-promises%s\" -f \"%s%cinputs%c%s\"",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR,EXEC_SUFFIX,CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR,VINPUTFILE);
 
165
   }
 
166
 
 
167
/* Check if reloading policy will succeed */
 
168
 
 
169
if (ShellCommandReturnsZero(cmd,true))
 
170
   {
 
171
   return true;
 
172
   }
 
173
else
 
174
   {
 
175
   return false;
 
176
   }
 
177
}
 
178
 
 
179
/*****************************************************************************/
 
180
 
 
181
void ReadPromises(enum cfagenttype ag,char *agents)
 
182
 
 
183
{ char *v,rettype;
 
184
  void *retval;
 
185
  char vbuff[CF_BUFSIZE];
 
186
  struct Constraint *cp;
 
187
 
 
188
if (ag == cf_keygen)
 
189
   {
 
190
   return;
 
191
   }
 
192
 
 
193
/* Parse the files*/
 
194
 
 
195
Cf3ParseFiles();
 
196
 
 
197
/* Now import some web variables that are set in cf-know/control for the report options */
 
198
 
 
199
strncpy(STYLESHEET,"/cf_enterprise.css",CF_BUFSIZE-1);
 
200
strncpy(WEBDRIVER,"",CF_MAXVARSIZE-1);
 
201
 
 
202
/* Make the compilation reports*/
 
203
 
 
204
OpenReports(agents);
 
205
 
 
206
SetAuditVersion();
 
207
 
 
208
if (GetVariable("control_common","version",&retval,&rettype) != cf_notype)
 
209
   {
 
210
   v = (char *)retval;
 
211
   }
 
212
else
 
213
   {
 
214
   v = "not specified";
 
215
   }
 
216
 
 
217
if (strchr(retval,':'))
 
218
   {
 
219
   CfOut(cf_error,""," !! The version string may not contain the \":\" character");
 
220
   }
 
221
 
 
222
snprintf(vbuff,CF_BUFSIZE-1,"<h1>Expanded promises for %s</h1>",agents);
 
223
CfHtmlHeader(FREPORT_HTML,vbuff,STYLESHEET,WEBDRIVER,BANNER);
 
224
 
 
225
fprintf(FREPORT_TXT,"Expanded promise list for %s component\n\n",agents);
 
226
 
 
227
ShowContext();
 
228
fprintf(FREPORT_HTML,"%s",CFH[cfx_promise][cfb]);
 
229
 
 
230
VerifyPromises(cf_common);
 
231
 
 
232
fprintf(FREPORT_HTML,"%s",CFH[cfx_promise][cfe]);
 
233
 
 
234
if (ag != cf_common)
 
235
   {
 
236
   ShowScopedVariables();
 
237
   }
 
238
 
 
239
CfHtmlFooter(FREPORT_HTML,FOOTER);
 
240
 
 
241
CloseReports(agents);
 
242
}
 
243
 
 
244
/*****************************************************************************/
 
245
 
 
246
void Cf3OpenLog()
 
247
 
 
248
{
 
249
#ifdef MINGW
 
250
NovaWin_OpenLog();
 
251
#else
 
252
openlog(VPREFIX,LOG_PID|LOG_NOWAIT|LOG_ODELAY,FACILITY);
 
253
#endif
 
254
}
 
255
 
 
256
/*****************************************************************************/
 
257
 
 
258
void Cf3CloseLog()
 
259
 
 
260
{
 
261
#ifdef MINGW
 
262
NovaWin_CloseLog();
 
263
#else
 
264
closelog();
 
265
#endif
 
266
}
 
267
 
 
268
/*****************************************************************************/
 
269
 
 
270
void PromiseManagement(char *agent)
 
271
 
 
272
{ enum cfagenttype ag = Agent2Type(agent);
 
273
 
 
274
switch (ag)
 
275
   {
 
276
   case cf_common:
 
277
       break;
 
278
 
 
279
   case cf_agent:
 
280
       break;
 
281
 
 
282
   case cf_server:
 
283
       break;
 
284
 
 
285
   case cf_monitor:
 
286
       break;
 
287
   }
 
288
}
 
289
 
 
290
/*******************************************************************/
 
291
/* Level 1                                                         */
 
292
/*******************************************************************/
 
293
 
 
294
void InitializeGA(int argc,char *argv[])
 
295
 
 
296
{ char *sp;
 
297
  int i,j,seed,force = false;
 
298
  struct stat statbuf,sb;
 
299
  unsigned char s[16],vbuff[CF_BUFSIZE];
 
300
  char ebuff[CF_EXPANDSIZE];
 
301
 
 
302
#ifdef NT
 
303
if (cfstat("/cygdrive",&statbuf) == 0)
 
304
   {
 
305
   FILE_SEPARATOR = '/';
 
306
   strcpy(FILE_SEPARATOR_STR,"/");
 
307
   }
 
308
else
 
309
   {
 
310
   FILE_SEPARATOR = '\\';
 
311
   strcpy(FILE_SEPARATOR_STR,"\\");
 
312
   }
 
313
#else
 
314
FILE_SEPARATOR = '/';
 
315
strcpy(FILE_SEPARATOR_STR,"/");
 
316
#endif
 
317
 
 
318
NewClass("any");
 
319
 
 
320
#ifdef HAVE_LIBCFNOVA
 
321
NewClass("nova_edition");
 
322
#else
 
323
NewClass("community_edition");
 
324
#endif
 
325
 
 
326
strcpy(VPREFIX,GetConsolePrefix());
 
327
 
 
328
if (VERBOSE)
 
329
   {
 
330
   NewClass("verbose_mode");
 
331
   }
 
332
 
 
333
if (INFORM)
 
334
   {
 
335
   NewClass("inform_mode");
 
336
   }
 
337
 
 
338
if (DEBUG)
 
339
   {
 
340
   NewClass("debug_mode");
 
341
   }
 
342
 
 
343
CfOut(cf_verbose,"","Cfengine - autonomous configuration engine - commence self-diagnostic prelude\n");
 
344
CfOut(cf_verbose,"","------------------------------------------------------------------------\n");
 
345
 
 
346
/* Define trusted directories */
 
347
 
 
348
#ifdef MINGW
 
349
if(NovaWin_GetProgDir(CFWORKDIR, CF_BUFSIZE - sizeof("Cfengine")))
 
350
  {
 
351
  strcat(CFWORKDIR, "\\Cfengine");
 
352
  }
 
353
else
 
354
  {
 
355
  CfOut(cf_error, "", "!! Could not get CFWORKDIR from Windows environment variable, falling back to compile time dir (%s)", WORKDIR);
 
356
  strcpy(CFWORKDIR,WORKDIR);
 
357
  }
 
358
Debug("Setting CFWORKDIR=%s\n", CFWORKDIR);
 
359
#elif defined(CFCYG)
 
360
strcpy(CFWORKDIR,WORKDIR);
 
361
MapName(CFWORKDIR);
 
362
#else
 
363
if (getuid() > 0)
 
364
   {
 
365
   strncpy(CFWORKDIR,GetHome(getuid()),CF_BUFSIZE-10);
 
366
   strcat(CFWORKDIR,"/.cfagent");
 
367
 
 
368
   if (strlen(CFWORKDIR) > CF_BUFSIZE/2)
 
369
      {
 
370
      FatalError("Suspicious looking home directory. The path is too long and will lead to problems.");
 
371
      }
 
372
   }
 
373
else
 
374
   {
 
375
   strcpy(CFWORKDIR,WORKDIR);
 
376
   }
 
377
#endif
 
378
 
 
379
/* On windows, use 'binary mode' as default for files */
 
380
 
 
381
#ifdef MINGW
 
382
_fmode = _O_BINARY;
 
383
#endif
 
384
 
 
385
strcpy(SYSLOGHOST,"localhost");
 
386
SYSLOGPORT = htons(514);
 
387
 
 
388
Cf3OpenLog();
 
389
 
 
390
if (!LOOKUP) /* cf-know should not do this in lookup mode */
 
391
   {
 
392
   CfOut(cf_verbose,"","Work directory is %s\n",CFWORKDIR);
 
393
 
 
394
   snprintf(HASHDB,CF_BUFSIZE-1,"%s%c%s",CFWORKDIR,FILE_SEPARATOR,CF_CHKDB);
 
395
 
 
396
   snprintf(vbuff,CF_BUFSIZE,"%s%cinputs%cupdate.conf",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR);
 
397
   MakeParentDirectory(vbuff,force);
 
398
   snprintf(vbuff,CF_BUFSIZE,"%s%cbin%ccf-agent -D from_cfexecd",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR);
 
399
   MakeParentDirectory(vbuff,force);
 
400
   snprintf(vbuff,CF_BUFSIZE,"%s%coutputs%cspooled_reports",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR);
 
401
   MakeParentDirectory(vbuff,force);
 
402
   snprintf(vbuff,CF_BUFSIZE,"%s%clastseen%cintermittencies",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR);
 
403
   MakeParentDirectory(vbuff,force);
 
404
   snprintf(vbuff,CF_BUFSIZE,"%s%creports%cvarious",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR);
 
405
   MakeParentDirectory(vbuff,force);
 
406
 
 
407
   snprintf(vbuff,CF_BUFSIZE,"%s%cinputs",CFWORKDIR,FILE_SEPARATOR);
 
408
 
 
409
   if (cfstat(vbuff,&sb) == -1)
 
410
      {
 
411
      FatalError(" !!! No access to workspace");
 
412
      }
 
413
   else
 
414
      {
 
415
      cf_chmod(vbuff,sb.st_mode | 0700);
 
416
      }
 
417
 
 
418
   snprintf(vbuff,CF_BUFSIZE,"%s%coutputs",CFWORKDIR,FILE_SEPARATOR);
 
419
 
 
420
   if (cfstat(vbuff,&sb) == -1)
 
421
      {
 
422
      FatalError(" !!! No access to workspace");
 
423
      }
 
424
   else
 
425
      {
 
426
      cf_chmod(vbuff,sb.st_mode | 0700);
 
427
      }
 
428
 
 
429
   sprintf(ebuff,"%s%cstate%ccf_procs",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR);
 
430
   MakeParentDirectory(ebuff,force);
 
431
 
 
432
   if (cfstat(ebuff,&statbuf) == -1)
 
433
      {
 
434
      CreateEmptyFile(ebuff);
 
435
      }
 
436
 
 
437
   sprintf(ebuff,"%s%cstate%ccf_rootprocs",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR);
 
438
 
 
439
   if (cfstat(ebuff,&statbuf) == -1)
 
440
      {
 
441
      CreateEmptyFile(ebuff);
 
442
      }
 
443
 
 
444
   sprintf(ebuff,"%s%cstate%ccf_otherprocs",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR);
 
445
 
 
446
   if (cfstat(ebuff,&statbuf) == -1)
 
447
      {
 
448
      CreateEmptyFile(ebuff);
 
449
      }
 
450
   }
 
451
 
 
452
OpenNetwork();
 
453
 
 
454
// cleanup db file from v. 3.0.2 (can be removed later)
 
455
char oldLockDb[CF_BUFSIZE];
 
456
snprintf(oldLockDb, sizeof(oldLockDb), "%s/cfengine_lock_db", CFWORKDIR);
 
457
unlink(oldLockDb);
 
458
 
 
459
/* Init crypto stuff */
 
460
 
 
461
OpenSSL_add_all_algorithms();
 
462
OpenSSL_add_all_digests();
 
463
ERR_load_crypto_strings();
 
464
CheckWorkingDirectories();
 
465
RandomSeed();
 
466
 
 
467
RAND_bytes(s,16);
 
468
s[15] = '\0';
 
469
seed = ElfHash(s);
 
470
srand48((long)seed);
 
471
 
 
472
LoadSecretKeys();
 
473
 
 
474
/* CheckOpts(argc,argv); - MacOS can't handle this back reference */
 
475
 
 
476
if (!MINUSF)
 
477
   {
 
478
   snprintf(VINPUTFILE,CF_BUFSIZE-1,"promises.cf");
 
479
   }
 
480
 
 
481
AUDITDBP = NULL;
 
482
 
 
483
DetermineCfenginePort();
 
484
 
 
485
VIFELAPSED = 1;
 
486
VEXPIREAFTER = 1;
 
487
 
 
488
setlinebuf(stdout);
 
489
 
 
490
if (BOOTSTRAP)
 
491
   {
 
492
   snprintf(vbuff,CF_BUFSIZE,"%s%cinputs%cfailsafe.cf",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR);
 
493
 
 
494
   if (!IsEnterprise() && cfstat(vbuff,&statbuf) == -1)
 
495
      {
 
496
      CfOut(cf_inform,"","Didn't find established file %s, so looking for one in current directory\n",vbuff);
 
497
          snprintf(VINPUTFILE,CF_BUFSIZE-1,".%cfailsafe.cf",FILE_SEPARATOR);
 
498
      }
 
499
   else
 
500
      {
 
501
      CfOut(cf_inform,"","Found an established failsafe file %s, so using it.\n",vbuff);
 
502
      strncpy(VINPUTFILE,vbuff,CF_BUFSIZE-1);
 
503
      }
 
504
   }
 
505
 
 
506
}
 
507
 
 
508
/*******************************************************************/
 
509
 
 
510
void Cf3ParseFiles()
 
511
 
 
512
{ struct Rlist *rp,*sl;
 
513
 
 
514
PARSING = true;
 
515
 
 
516
if ((PROMISETIME = time((time_t *)NULL)) == -1)
 
517
   {
 
518
   printf("Couldn't read system clock\n");
 
519
   }
 
520
 
 
521
Cf3ParseFile(VINPUTFILE);
 
522
 
 
523
// Expand any lists in this list now
 
524
 
 
525
HashVariables();
 
526
HashControls();
 
527
 
 
528
if (VINPUTLIST != NULL)
 
529
   {
 
530
   for (rp = VINPUTLIST; rp != NULL; rp=rp->next)
 
531
      {
 
532
      if (rp->type != CF_SCALAR)
 
533
         {
 
534
         CfOut(cf_error,"","Non-file object in inputs list\n");
 
535
         }
 
536
      else
 
537
         {
 
538
         struct Rval returnval = EvaluateFinalRval("sys",rp->item,rp->type,true,NULL);
 
539
 
 
540
         switch (returnval.rtype)
 
541
            {
 
542
            case CF_SCALAR:
 
543
                Cf3ParseFile((char *)returnval.item);
 
544
                break;
 
545
 
 
546
            case CF_LIST:
 
547
                for (sl = (struct Rlist *)returnval.item; sl != NULL; sl=sl->next)
 
548
                   {
 
549
                   Cf3ParseFile((char *)sl->item);
 
550
                   }
 
551
                break;
 
552
            }
 
553
         }
 
554
      }
 
555
   }
 
556
 
 
557
HashVariables();
 
558
PARSING = false;
 
559
}
 
560
 
 
561
/*******************************************************************/
 
562
 
 
563
int NewPromiseProposals()
 
564
 
 
565
{ struct Rlist *rp,*sl;
 
566
  struct stat sb;
 
567
  int result = false;
 
568
 
 
569
if (cfstat(InputLocation(VINPUTFILE),&sb) == -1)
 
570
   {
 
571
   CfOut(cf_error,"stat","There is no readable input file at %s",VINPUTFILE);
 
572
   return false;
 
573
   }
 
574
 
 
575
if (sb.st_mtime > PROMISETIME)
 
576
   {
 
577
   return true;
 
578
   }
 
579
 
 
580
if (VINPUTLIST != NULL)
 
581
   {
 
582
   for (rp = VINPUTLIST; rp != NULL; rp=rp->next)
 
583
      {
 
584
      if (rp->type != CF_SCALAR)
 
585
         {
 
586
         CfOut(cf_error,"","Non file object %s in list\n",(char *)rp->item);
 
587
         }
 
588
      else
 
589
         {
 
590
         struct Rval returnval = EvaluateFinalRval("sys",rp->item,rp->type,true,NULL);
 
591
 
 
592
         switch (returnval.rtype)
 
593
            {
 
594
            case CF_SCALAR:
 
595
 
 
596
                if (cfstat(InputLocation((char *)returnval.item),&sb) == -1)
 
597
                   {
 
598
                   CfOut(cf_error,"stat","There are no readable promise proposals at %s",(char *)returnval.item);
 
599
                   break;
 
600
                   }
 
601
 
 
602
                if (sb.st_mtime > PROMISETIME)
 
603
                   {
 
604
                   result = true;
 
605
                   }
 
606
 
 
607
                break;
 
608
 
 
609
            case CF_LIST:
 
610
 
 
611
                for (sl = (struct Rlist *)returnval.item; sl != NULL; sl=sl->next)
 
612
                   {
 
613
                   if (cfstat(InputLocation((char *)sl->item),&sb) == -1)
 
614
                      {
 
615
                      CfOut(cf_error,"stat","There are no readable promise proposals at %s",(char *)sl->item);
 
616
                      break;
 
617
                      }
 
618
 
 
619
                   if (sb.st_mtime > PROMISETIME)
 
620
                      {
 
621
                      result = true;
 
622
                      break;
 
623
                      }
 
624
                   }
 
625
 
 
626
                break;
 
627
            }
 
628
 
 
629
         DeleteRvalItem(returnval.item,returnval.rtype);
 
630
 
 
631
         if (result)
 
632
            {
 
633
            break;
 
634
            }
 
635
         }
 
636
      }
 
637
   }
 
638
 
 
639
return result;
 
640
}
 
641
 
 
642
/*******************************************************************/
 
643
 
 
644
void OpenReports(char *agents)
 
645
 
 
646
{ char name[CF_BUFSIZE];
 
647
 
 
648
if (SHOWREPORTS)
 
649
   {
 
650
   snprintf(name,CF_BUFSIZE,"%s%creports%cpromise_output_%s.txt",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR,agents);
 
651
 
 
652
   if ((FREPORT_TXT = fopen(name,"w")) == NULL)
 
653
      {
 
654
      CfOut(cf_error,"fopen","Cannot open output file %s",name);
 
655
      FREPORT_TXT = fopen(NULLFILE,"w");
 
656
      }
 
657
 
 
658
   snprintf(name,CF_BUFSIZE,"%s%creports%cpromise_output_%s.html",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR,agents);
 
659
 
 
660
   if ((FREPORT_HTML = fopen(name,"w")) == NULL)
 
661
      {
 
662
      CfOut(cf_error,"fopen","Cannot open output file %s",name);
 
663
      FREPORT_HTML = fopen(NULLFILE,"w");
 
664
      }
 
665
 
 
666
   snprintf(name,CF_BUFSIZE,"%s%cpromise_knowledge.cf",CFWORKDIR,FILE_SEPARATOR);
 
667
 
 
668
   if ((FKNOW = fopen(name,"w")) == NULL)
 
669
      {
 
670
      CfOut(cf_error,"fopen","Cannot open output file %s",name);
 
671
      FKNOW = fopen(NULLFILE,"w");
 
672
      }
 
673
   }
 
674
else
 
675
   {
 
676
   snprintf(name,CF_BUFSIZE,NULLFILE);
 
677
   if ((FREPORT_TXT = fopen(name,"w")) == NULL)
 
678
      {
 
679
      char vbuff[CF_BUFSIZE];
 
680
      snprintf(vbuff,CF_BUFSIZE,"Cannot open output file %s",name);
 
681
      FatalError(vbuff);
 
682
      }
 
683
 
 
684
   if ((FREPORT_HTML = fopen(name,"w")) == NULL)
 
685
      {
 
686
      char vbuff[CF_BUFSIZE];
 
687
      snprintf(vbuff,CF_BUFSIZE,"Cannot open output file %s",name);
 
688
      FatalError(vbuff);
 
689
      }
 
690
 
 
691
   if ((FKNOW = fopen(name,"w")) == NULL)
 
692
      {
 
693
      char vbuff[CF_BUFSIZE];
 
694
      snprintf(vbuff,CF_BUFSIZE,"Cannot open output file %s",name);
 
695
      FatalError(vbuff);
 
696
      }
 
697
   }
 
698
 
 
699
if (!(FKNOW && FREPORT_HTML && FREPORT_TXT))
 
700
   {
 
701
   FatalError("Unable to continue as the null-file is unwritable");
 
702
   }
 
703
 
 
704
fprintf(FKNOW,"bundle knowledge CfengineEnterpriseFundamentals\n{\n");
 
705
ShowTopicRepresentation(FKNOW);
 
706
fprintf(FKNOW,"}\n\nbundle knowledge CfengineSiteConfiguration\n{\n");
 
707
}
 
708
 
 
709
/*******************************************************************/
 
710
 
 
711
void CloseReports(char *agents)
 
712
 
 
713
{ char name[CF_BUFSIZE];
 
714
 
 
715
if (SHOWREPORTS)
 
716
   {
 
717
   CfOut(cf_cmdout,"","Wrote compilation report %s%creports%cpromise_output_%s.txt",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR,agents);
 
718
   CfOut(cf_cmdout,"","Wrote compilation report %s%creports%cpromise_output_%s.html",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR,agents);
 
719
   CfOut(cf_cmdout,"","Wrote knowledge map %s%cpromise_knowledge.cf",CFWORKDIR,FILE_SEPARATOR,agents);
 
720
   }
 
721
 
 
722
fprintf(FKNOW,"}\n");
 
723
fclose(FKNOW);
 
724
fclose(FREPORT_HTML);
 
725
fclose(FREPORT_TXT);
 
726
}
 
727
 
 
728
/*******************************************************************/
 
729
/* Level                                                           */
 
730
/*******************************************************************/
 
731
 
 
732
void Cf3ParseFile(char *filename)
 
733
 
 
734
{ FILE *save_yyin = yyin;
 
735
  struct stat statbuf;
 
736
  struct Rlist *rp;
 
737
  int access = false;
 
738
  char wfilename[CF_BUFSIZE];
 
739
 
 
740
 
 
741
strncpy(wfilename,InputLocation(filename),CF_BUFSIZE);
 
742
 
 
743
if (cfstat(wfilename,&statbuf) == -1)
 
744
   {
 
745
   if (IGNORE_MISSING_INPUTS)
 
746
      {
 
747
      return;
 
748
      }
 
749
 
 
750
   CfOut(cf_error,"stat","Can't stat file \"%s\" for parsing\n",wfilename);
 
751
   exit(1);
 
752
   }
 
753
 
 
754
#ifndef NT
 
755
if (statbuf.st_mode & (S_IWGRP | S_IWOTH))
 
756
   {
 
757
   CfOut(cf_error,"","File %s (owner %d) is writable by others (security exception)",wfilename,statbuf.st_uid);
 
758
   exit(1);
 
759
   }
 
760
#endif
 
761
 
 
762
Debug("+++++++++++++++++++++++++++++++++++++++++++++++\n");
 
763
CfOut(cf_verbose,"","  > Parsing file %s\n",wfilename);
 
764
Debug("+++++++++++++++++++++++++++++++++++++++++++++++\n");
 
765
 
 
766
PrependAuditFile(wfilename);
 
767
 
 
768
if ((yyin = fopen(wfilename,"r")) == NULL)      /* Open root file */
 
769
   {
 
770
   printf("Can't open file %s for parsing\n",wfilename);
 
771
   exit (1);
 
772
   }
 
773
 
 
774
P.line_no = 1;
 
775
P.line_pos = 1;
 
776
P.list_nesting = 0;
 
777
P.arg_nesting = 0;
 
778
P.filename = strdup(wfilename);
 
779
 
 
780
P.currentid = NULL;
 
781
P.currentstring = NULL;
 
782
P.currenttype = NULL;
 
783
P.currentclasses = NULL;
 
784
P.currentRlist = NULL;
 
785
P.currentpromise = NULL;
 
786
P.promiser = NULL;
 
787
 
 
788
while (!feof(yyin))
 
789
   {
 
790
   yyparse();
 
791
 
 
792
   if (ferror(yyin))  /* abortable */
 
793
      {
 
794
      perror("cfengine");
 
795
      exit(1);
 
796
      }
 
797
   }
 
798
 
 
799
fclose (yyin);
 
800
}
 
801
 
 
802
/*******************************************************************/
 
803
 
 
804
struct Constraint *ControlBodyConstraints(enum cfagenttype agent)
 
805
 
 
806
{ struct Body *body;
 
807
  char scope[CF_BUFSIZE];
 
808
 
 
809
for (body = BODIES; body != NULL; body = body->next)
 
810
   {
 
811
   if (strcmp(body->type,CF_AGENTTYPES[agent]) == 0)
 
812
      {
 
813
      if (strcmp(body->name,"control") == 0)
 
814
         {
 
815
         Debug("%s body for type %s\n",body->name,body->type);
 
816
         return body->conlist;
 
817
         }
 
818
      }
 
819
   }
 
820
 
 
821
return NULL;
 
822
}
 
823
 
 
824
/*******************************************************************/
 
825
 
 
826
void SetFacility(char *retval)
 
827
 
 
828
{
 
829
if (strcmp(retval,"LOG_USER") == 0)
 
830
   {
 
831
   FACILITY = LOG_USER;
 
832
   }
 
833
else if (strcmp(retval,"LOG_DAEMON") == 0)
 
834
   {
 
835
   FACILITY = LOG_DAEMON;
 
836
   }
 
837
else if (strcmp(retval,"LOG_LOCAL0") == 0)
 
838
   {
 
839
   FACILITY = LOG_LOCAL0;
 
840
   }
 
841
else if (strcmp(retval,"LOG_LOCAL1") == 0)
 
842
   {
 
843
   FACILITY = LOG_LOCAL1;
 
844
   }
 
845
else if (strcmp(retval,"LOG_LOCAL2") == 0)
 
846
   {
 
847
   FACILITY = LOG_LOCAL2;
 
848
   }
 
849
else if (strcmp(retval,"LOG_LOCAL3") == 0)
 
850
   {
 
851
   FACILITY = LOG_LOCAL3;
 
852
   }
 
853
else if (strcmp(retval,"LOG_LOCAL4") == 0)
 
854
   {
 
855
   FACILITY = LOG_LOCAL4;
 
856
   }
 
857
else if (strcmp(retval,"LOG_LOCAL5") == 0)
 
858
   {
 
859
   FACILITY = LOG_LOCAL5;
 
860
   }
 
861
else if (strcmp(retval,"LOG_LOCAL6") == 0)
 
862
   {
 
863
   FACILITY = LOG_LOCAL6;
 
864
   }
 
865
else if (strcmp(retval,"LOG_LOCAL7") == 0)
 
866
   {
 
867
   FACILITY = LOG_LOCAL7;
 
868
   }
 
869
 
 
870
Cf3CloseLog();
 
871
Cf3OpenLog();
 
872
}
 
873
 
 
874
/**************************************************************/
 
875
 
 
876
struct Bundle *GetBundle(char *name,char *agent)
 
877
 
 
878
{ struct Bundle *bp;
 
879
 
 
880
for (bp = BUNDLES; bp != NULL; bp = bp->next) /* get schedule */
 
881
   {
 
882
   if (strcmp(bp->name,name) == 0)
 
883
      {
 
884
      if (agent)
 
885
         {
 
886
         if ((strcmp(bp->type,agent) == 0) || (strcmp(bp->type,"common") == 0))
 
887
            {
 
888
            return bp;
 
889
            }
 
890
         else
 
891
            {
 
892
            CfOut(cf_verbose,"","The bundle called %s is not of type %s\n",name,agent);
 
893
            }
 
894
         }
 
895
      else
 
896
         {
 
897
         return bp;
 
898
         }
 
899
      }
 
900
   }
 
901
 
 
902
return NULL;
 
903
}
 
904
 
 
905
/**************************************************************/
 
906
 
 
907
struct SubType *GetSubTypeForBundle(char *type,struct Bundle *bp)
 
908
 
 
909
{ struct SubType *sp;
 
910
 
 
911
if (bp == NULL)
 
912
   {
 
913
   return NULL;
 
914
   }
 
915
 
 
916
for (sp = bp->subtypes; sp != NULL; sp=sp->next)
 
917
   {
 
918
   if (strcmp(type,sp->name)== 0)
 
919
      {
 
920
      return sp;
 
921
      }
 
922
   }
 
923
 
 
924
return NULL;
 
925
}
 
926
 
 
927
/**************************************************************/
 
928
 
 
929
void BannerBundle(struct Bundle *bp,struct Rlist *params)
 
930
 
 
931
{
 
932
CfOut(cf_verbose,"","\n");
 
933
CfOut(cf_verbose,"","*****************************************************************\n");
 
934
 
 
935
if (VERBOSE || DEBUG)
 
936
   {
 
937
   printf("%s BUNDLE %s",VPREFIX,bp->name);
 
938
   }
 
939
 
 
940
if (params && (VERBOSE||DEBUG))
 
941
   {
 
942
   printf("(");
 
943
   ShowRlist(stdout,params);
 
944
   printf(" )\n");
 
945
   }
 
946
else
 
947
   {
 
948
   if (VERBOSE||DEBUG) printf("\n");
 
949
   }
 
950
 
 
951
CfOut(cf_verbose,"","*****************************************************************\n");
 
952
CfOut(cf_verbose,"","\n");
 
953
}
 
954
 
 
955
/**************************************************************/
 
956
 
 
957
void BannerSubBundle(struct Bundle *bp,struct Rlist *params)
 
958
 
 
959
{
 
960
CfOut(cf_verbose,"","\n");
 
961
CfOut(cf_verbose,"","      * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n");
 
962
 
 
963
if (VERBOSE || DEBUG)
 
964
   {
 
965
   printf("%s       BUNDLE %s",VPREFIX,bp->name);
 
966
   }
 
967
 
 
968
if (params && (VERBOSE||DEBUG))
 
969
   {
 
970
   printf("(");
 
971
   ShowRlist(stdout,params);
 
972
   printf(" )\n");
 
973
   }
 
974
else
 
975
   {
 
976
   if (VERBOSE||DEBUG) printf("\n");
 
977
   }
 
978
CfOut(cf_verbose,"","      * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n");
 
979
CfOut(cf_verbose,"","\n");
 
980
}
 
981
 
 
982
/**************************************************************/
 
983
 
 
984
void PromiseBanner(struct Promise *pp)
 
985
 
 
986
{ char *sp,handle[CF_MAXVARSIZE];
 
987
 
 
988
if ((sp = GetConstraint("handle",pp,CF_SCALAR)) || (sp = PromiseID(pp)))
 
989
   {
 
990
   strncpy(handle,sp,CF_MAXVARSIZE-1);
 
991
   }
 
992
else
 
993
   {
 
994
   strcpy(handle,"(enterprise only)");
 
995
   }
 
996
 
 
997
CfOut(cf_verbose,"","\n");
 
998
CfOut(cf_verbose,"","    .........................................................\n");
 
999
 
 
1000
if (VERBOSE||DEBUG)
 
1001
   {
 
1002
   printf ("%s     Promise handle: %s\n",VPREFIX,handle);
 
1003
   printf ("%s     Promise made by: %s",VPREFIX,pp->promiser);
 
1004
   }
 
1005
 
 
1006
if (pp->promisee)
 
1007
   {
 
1008
   if (VERBOSE)
 
1009
      {
 
1010
      printf(" -> ");
 
1011
      ShowRval(stdout,pp->promisee,pp->petype);
 
1012
      }
 
1013
   }
 
1014
 
 
1015
if (VERBOSE)
 
1016
   {
 
1017
   printf("\n");
 
1018
   }
 
1019
 
 
1020
if (pp->ref)
 
1021
   {
 
1022
   CfOut(cf_verbose,"","\n");
 
1023
   CfOut(cf_verbose,"","    Comment:  %s\n",pp->ref);
 
1024
   }
 
1025
 
 
1026
CfOut(cf_verbose,"","    .........................................................\n");
 
1027
CfOut(cf_verbose,"","\n");
 
1028
}
 
1029
 
 
1030
 
 
1031
/*********************************************************************/
 
1032
 
 
1033
void CheckWorkingDirectories()
 
1034
    
 
1035
/* NOTE: We do not care about permissions (ACLs) in windows */
 
1036
 
 
1037
{ struct stat statbuf;
 
1038
  int result;
 
1039
  char *sp,vbuff[CF_BUFSIZE];
 
1040
  char output[CF_BUFSIZE];
 
1041
 
 
1042
Debug("CheckWorkingDirectories()\n");
 
1043
 
 
1044
if (uname(&VSYSNAME) == -1)
 
1045
   {
 
1046
   perror("uname ");
 
1047
   FatalError("Uname couldn't get kernel name info!!\n");
 
1048
   }
 
1049
 
 
1050
snprintf(LOGFILE,CF_BUFSIZE,"%s%ccfagent.%s.log",CFWORKDIR,FILE_SEPARATOR,VSYSNAME.nodename);
 
1051
VSETUIDLOG = strdup(LOGFILE);
 
1052
 
 
1053
snprintf(vbuff,CF_BUFSIZE,"%s%c.",CFWORKDIR,FILE_SEPARATOR);
 
1054
MakeParentDirectory(vbuff,false);
 
1055
 
 
1056
CfOut(cf_verbose,"","Making sure that locks are private...\n");
 
1057
 
 
1058
if (chown(CFWORKDIR,getuid(),getgid()) == -1)
 
1059
   {
 
1060
   CfOut(cf_error,"chown","Unable to set owner on %s to %d.%d",CFWORKDIR,getuid(),getgid());
 
1061
   }
 
1062
 
 
1063
if (cfstat(CFWORKDIR,&statbuf) != -1)
 
1064
   {
 
1065
   /* change permissions go-w */
 
1066
   cf_chmod(CFWORKDIR,(mode_t)(statbuf.st_mode & ~022));
 
1067
   }
 
1068
 
 
1069
snprintf(vbuff,CF_BUFSIZE,"%s%cstate%c.",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR);
 
1070
MakeParentDirectory(vbuff,false);
 
1071
 
 
1072
snprintf(CFPRIVKEYFILE,CF_BUFSIZE,"%s%cppkeys%clocalhost.priv",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR);
 
1073
snprintf(CFPUBKEYFILE,CF_BUFSIZE,"%s%cppkeys%clocalhost.pub",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR);
 
1074
 
 
1075
CfOut(cf_verbose,"","Checking integrity of the state database\n");
 
1076
snprintf(vbuff,CF_BUFSIZE,"%s%cstate",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR);
 
1077
 
 
1078
if (cfstat(vbuff,&statbuf) == -1)
 
1079
   {
 
1080
   snprintf(vbuff,CF_BUFSIZE,"%s%cstate%c.",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR);
 
1081
   MakeParentDirectory(vbuff,false);
 
1082
 
 
1083
   if (chown(vbuff,getuid(),getgid()) == -1)
 
1084
      {
 
1085
      CfOut(cf_error,"chown","Unable to set owner on %s to %d.%d",vbuff,getuid(),getgid());
 
1086
      }
 
1087
 
 
1088
   cf_chmod(vbuff,(mode_t)0755);
 
1089
   }
 
1090
else
 
1091
   {
 
1092
#ifndef MINGW
 
1093
   if (statbuf.st_mode & 022)
 
1094
      {
 
1095
      CfOut(cf_error,"","UNTRUSTED: State directory %s (mode %o) was not private!\n",CFWORKDIR,statbuf.st_mode & 0777);
 
1096
      }
 
1097
#endif  /* NOT MINGW */
 
1098
   }
 
1099
 
 
1100
CfOut(cf_verbose,"","Checking integrity of the module directory\n");
 
1101
 
 
1102
snprintf(vbuff,CF_BUFSIZE,"%s%cmodules",CFWORKDIR,FILE_SEPARATOR);
 
1103
 
 
1104
if (cfstat(vbuff,&statbuf) == -1)
 
1105
   {
 
1106
   snprintf(vbuff,CF_BUFSIZE,"%s%cmodules%c.",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR);
 
1107
   MakeParentDirectory(vbuff,false);
 
1108
 
 
1109
   if (chown(vbuff,getuid(),getgid()) == -1)
 
1110
      {
 
1111
      CfOut(cf_error,"chown","Unable to set owner on %s to %d.%d",vbuff,getuid(),getgid());
 
1112
      }
 
1113
 
 
1114
   cf_chmod(vbuff,(mode_t)0700);
 
1115
   }
 
1116
else
 
1117
   {
 
1118
#ifndef MINGW
 
1119
   if (statbuf.st_mode & 022)
 
1120
      {
 
1121
      CfOut(cf_error,"","UNTRUSTED: Module directory %s (mode %o) was not private!\n",vbuff,statbuf.st_mode & 0777);
 
1122
      }
 
1123
#endif  /* NOT MINGW */
 
1124
   }
 
1125
 
 
1126
CfOut(cf_verbose,"","Checking integrity of the PKI directory\n");
 
1127
 
 
1128
snprintf(vbuff,CF_BUFSIZE,"%s%cppkeys",CFWORKDIR,FILE_SEPARATOR);
 
1129
 
 
1130
if (cfstat(vbuff,&statbuf) == -1)
 
1131
   {
 
1132
   snprintf(vbuff,CF_BUFSIZE,"%s%cppkeys%c.",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR);
 
1133
   MakeParentDirectory(vbuff,false);
 
1134
 
 
1135
   cf_chmod(vbuff,(mode_t)0700); /* Keys must be immutable to others */
 
1136
   }
 
1137
else
 
1138
   {
 
1139
#ifndef MINGW
 
1140
   if (statbuf.st_mode & 077)
 
1141
      {
 
1142
      snprintf(output,CF_BUFSIZE-1,"UNTRUSTED: Private key directory %s%cppkeys (mode %o) was not private!\n",CFWORKDIR,FILE_SEPARATOR,statbuf.st_mode & 0777);
 
1143
      FatalError(output);
 
1144
      }
 
1145
#endif  /* NOT MINGW */
 
1146
   }
 
1147
}
 
1148
 
 
1149
/*******************************************************************/
 
1150
/* Level 2                                                         */
 
1151
/*******************************************************************/
 
1152
 
 
1153
char *InputLocation(char *filename)
 
1154
 
 
1155
{ static char wfilename[CF_BUFSIZE], path[CF_BUFSIZE];
 
1156
 
 
1157
if (MINUSF && (filename != VINPUTFILE) && (*VINPUTFILE == '.' || IsAbsoluteFileName(VINPUTFILE)) && !IsAbsoluteFileName(filename))
 
1158
   {
 
1159
   /* If -f assume included relative files are in same directory */
 
1160
   strncpy(path,VINPUTFILE,CF_BUFSIZE-1);
 
1161
   ChopLastNode(path);
 
1162
   snprintf(wfilename,CF_BUFSIZE-1,"%s%c%s",path,FILE_SEPARATOR,filename);
 
1163
   }
 
1164
else if ((*filename == '.') || IsAbsoluteFileName(filename))
 
1165
   {
 
1166
   strncpy(wfilename,filename,CF_BUFSIZE-1);
 
1167
   }
 
1168
else
 
1169
   {
 
1170
   snprintf(wfilename,CF_BUFSIZE-1,"%s%cinputs%c%s",CFWORKDIR,FILE_SEPARATOR,FILE_SEPARATOR,filename);
 
1171
   }
 
1172
 
 
1173
return MapName(wfilename);
 
1174
}
 
1175
 
 
1176
/*******************************************************************/
 
1177
 
 
1178
void CompilationReport(char *fname)
 
1179
 
 
1180
{ char filename[CF_BUFSIZE],output[CF_BUFSIZE];
 
1181
 
 
1182
snprintf(filename,CF_BUFSIZE-1,"%s.txt",fname);
 
1183
printf("Summarizing promises as text to %s\n",filename);
 
1184
 
 
1185
if ((FREPORT_TXT = fopen(filename,"w")) == NULL)
 
1186
   {
 
1187
   snprintf(output,CF_BUFSIZE,"Could not write output log to %s",filename);
 
1188
   FatalError(output);
 
1189
   }
 
1190
 
 
1191
snprintf(filename,CF_BUFSIZE-1,"%s.html",fname);
 
1192
printf("Summarizing promises as html to %s\n",filename);
 
1193
 
 
1194
if ((FREPORT_HTML = fopen(filename,"w")) == NULL)
 
1195
   {
 
1196
   snprintf(output,CF_BUFSIZE,"Could not write output log to %s",filename);
 
1197
   FatalError(output);
 
1198
   }
 
1199
 
 
1200
if ((FKNOW = fopen(NULLFILE,"w")) == NULL)
 
1201
   {
 
1202
   FatalError("Null-file failed");
 
1203
   }
 
1204
 
 
1205
ShowPromises(BUNDLES,BODIES);
 
1206
 
 
1207
fclose(FREPORT_HTML);
 
1208
fclose(FREPORT_TXT);
 
1209
fclose(FKNOW);
 
1210
}
 
1211
 
 
1212
/*******************************************************************/
 
1213
 
 
1214
void VerifyPromises(enum cfagenttype agent)
 
1215
 
 
1216
{ struct Bundle *bp,*bundles;
 
1217
  struct SubType *sp;
 
1218
  struct Promise *pp;
 
1219
  struct Body *bdp;
 
1220
  struct Scope *ptr;
 
1221
  struct Rlist *rp,*params;
 
1222
  struct FnCall *fp;
 
1223
  char buf[CF_BUFSIZE], *scope;
 
1224
  char rettype,*name;
 
1225
 
 
1226
Debug("\n\nVerifyPromises()\n");
 
1227
 
 
1228
if (REQUIRE_COMMENTS == CF_UNDEFINED)
 
1229
   {
 
1230
   for (bdp = BODIES; bdp != NULL; bdp = bdp->next) /* get schedule */
 
1231
      {
 
1232
      if ((strcmp(bdp->name,"control") == 0) && (strcmp(bdp->type,"common") == 0))
 
1233
         {
 
1234
         REQUIRE_COMMENTS = GetRawBooleanConstraint("require_comments",bdp->conlist);
 
1235
         break;
 
1236
         }
 
1237
      }
 
1238
   }
 
1239
 
 
1240
for (rp = BODYPARTS; rp != NULL; rp=rp->next)
 
1241
   {
 
1242
   switch (rp->type)
 
1243
      {
 
1244
      case CF_SCALAR:
 
1245
          if (!IsBody(BODIES,(char *)rp->item))
 
1246
             {
 
1247
             CfOut(cf_error,"","Undeclared promise body \"%s()\" was referenced in a promise\n",(char *)rp->item);
 
1248
             ERRORCOUNT++;
 
1249
             }
 
1250
          break;
 
1251
 
 
1252
      case CF_FNCALL:
 
1253
          fp = (struct FnCall *)rp->item;
 
1254
 
 
1255
          if (!IsBody(BODIES,fp->name))
 
1256
             {
 
1257
             CfOut(cf_error,"","Undeclared promise body \"%s()\" was referenced in a promise\n",fp->name);
 
1258
             ERRORCOUNT++;
 
1259
             }
 
1260
          break;
 
1261
      }
 
1262
   }
 
1263
 
 
1264
/* Check for undefined subbundles */
 
1265
 
 
1266
for (rp = SUBBUNDLES; rp != NULL; rp=rp->next)
 
1267
   {
 
1268
   switch (rp->type)
 
1269
      {
 
1270
      case CF_SCALAR:
 
1271
          if (!IsBundle(BUNDLES,(char *)rp->item))
 
1272
             {
 
1273
             CfOut(cf_error,"","Undeclared promise bundle \"%s()\" was referenced in a promise\n",(char *)rp->item);
 
1274
             ERRORCOUNT++;
 
1275
             }
 
1276
          break;
 
1277
 
 
1278
      case CF_FNCALL:
 
1279
          fp = (struct FnCall *)rp->item;
 
1280
 
 
1281
          if (!IsBundle(BUNDLES,fp->name))
 
1282
             {
 
1283
             CfOut(cf_error,"","Undeclared promise bundle \"%s()\" was referenced in a promise\n",fp->name);
 
1284
             ERRORCOUNT++;
 
1285
             }
 
1286
          break;
 
1287
      }
 
1288
   }
 
1289
 
 
1290
/* Now look once through ALL the bundles themselves */
 
1291
 
 
1292
for (bp = BUNDLES; bp != NULL; bp = bp->next) /* get schedule */
 
1293
   {
 
1294
   scope = bp->name;
 
1295
   THIS_BUNDLE = bp->name;
 
1296
 
 
1297
   for (sp = bp->subtypes; sp != NULL; sp = sp->next) /* get schedule */
 
1298
      {
 
1299
      if (strcmp(sp->name,"classes") == 0)
 
1300
         {
 
1301
         /* these should not be evaluated here */
 
1302
         continue;
 
1303
         }
 
1304
 
 
1305
      for (pp = sp->promiselist; pp != NULL; pp=pp->next)
 
1306
         {
 
1307
         ExpandPromise(agent,scope,pp,NULL);
 
1308
         }
 
1309
      }
 
1310
   }
 
1311
 
 
1312
 
 
1313
HashVariables();
 
1314
HashControls();
 
1315
 
 
1316
/* Now look once through the sequences bundles themselves */
 
1317
 
 
1318
if (BadBundleSequence(agent))
 
1319
   {
 
1320
   FatalError("Errors in promise bundles");
 
1321
   }
 
1322
}
 
1323
 
 
1324
/********************************************************************/
 
1325
 
 
1326
void PrependAuditFile(char *file)
 
1327
 
 
1328
{ struct stat statbuf;;
 
1329
 
 
1330
if ((AUDITPTR = (struct Audit *)malloc(sizeof(struct Audit))) == NULL)
 
1331
   {
 
1332
   FatalError("Memory allocation failure in PrependAuditFile");
 
1333
   }
 
1334
 
 
1335
if (cfstat(file,&statbuf) == -1)
 
1336
   {
 
1337
   /* shouldn't happen */
 
1338
   return;
 
1339
   }
 
1340
 
 
1341
HashFile(file,AUDITPTR->digest,cf_md5);
 
1342
 
 
1343
AUDITPTR->next = VAUDIT;
 
1344
AUDITPTR->filename = strdup(file);
 
1345
AUDITPTR->date = strdup(cf_ctime(&statbuf.st_mtime));
 
1346
Chop(AUDITPTR->date);
 
1347
AUDITPTR->version = NULL;
 
1348
VAUDIT = AUDITPTR;
 
1349
}
 
1350
 
 
1351
 
 
1352
/*******************************************************************/
 
1353
/* Level 3                                                         */
 
1354
/*******************************************************************/
 
1355
 
 
1356
void CheckVariablePromises(char *scope,struct Promise *varlist)
 
1357
 
 
1358
{ struct Promise *pp;
 
1359
  int allow_redefine = false;
 
1360
 
 
1361
Debug("CheckVariablePromises()\n");
 
1362
 
 
1363
for (pp = varlist; pp != NULL; pp=pp->next)
 
1364
   {
 
1365
   ConvergeVarHashPromise(scope,pp,allow_redefine);
 
1366
   }
 
1367
}
 
1368
 
 
1369
/*******************************************************************/
 
1370
 
 
1371
void CheckCommonClassPromises(struct Promise *classlist)
 
1372
 
 
1373
{ struct Promise *pp;
 
1374
 
 
1375
CfOut(cf_verbose,""," -> Checking common class promises...\n");
 
1376
 
 
1377
for (pp = classlist; pp != NULL; pp=pp->next)
 
1378
   {
 
1379
   KeepClassContextPromise(pp);
 
1380
   }
 
1381
}
 
1382
 
 
1383
/*******************************************************************/
 
1384
 
 
1385
void CheckBundleParameters(char *scope,struct Rlist *args)
 
1386
 
 
1387
{ struct Rlist *rp;
 
1388
  struct Rval retval;
 
1389
  char *lval,rettype;;
 
1390
 
 
1391
for (rp = args; rp != NULL; rp = rp->next)
 
1392
   {
 
1393
   lval = (char *)rp->item;
 
1394
 
 
1395
   if (GetVariable(scope,lval,(void *)&retval,&rettype) != cf_notype)
 
1396
      {
 
1397
      CfOut(cf_error,"","Variable and bundle parameter %s collide",lval);
 
1398
      FatalError("Aborting");
 
1399
      }
 
1400
   }
 
1401
}
 
1402
 
 
1403
/*******************************************************************/
 
1404
 
 
1405
void CheckControlPromises(char *scope,char *agent,struct Constraint *controllist)
 
1406
 
 
1407
{ struct Constraint *cp;
 
1408
  struct SubTypeSyntax *sp;
 
1409
  struct BodySyntax *bp = NULL;
 
1410
  char *lval;
 
1411
  void *rval = NULL,*retval;
 
1412
  int i = 0,override = true;
 
1413
  struct Rval returnval;
 
1414
  char rettype,rtype;
 
1415
 
 
1416
Debug("CheckControlPromises(%s)\n",agent);
 
1417
 
 
1418
for (i = 0; CF_ALL_BODIES[i].bs != NULL; i++)
 
1419
   {
 
1420
   bp = CF_ALL_BODIES[i].bs;
 
1421
 
 
1422
   if (strcmp(agent,CF_ALL_BODIES[i].btype) == 0)
 
1423
      {
 
1424
      break;
 
1425
      }
 
1426
   }
 
1427
 
 
1428
if (bp == NULL)
 
1429
   {
 
1430
   FatalError("Unknown agent");
 
1431
   }
 
1432
 
 
1433
for (cp = controllist; cp != NULL; cp=cp->next)
 
1434
   {
 
1435
   if (IsExcluded(cp->classes))
 
1436
      {
 
1437
      continue;
 
1438
      }
 
1439
 
 
1440
   if (strcmp(cp->lval,CFG_CONTROLBODY[cfg_bundlesequence].lval) == 0)
 
1441
      {
 
1442
      returnval = ExpandPrivateRval(CONTEXTID,cp->rval,cp->type);
 
1443
      }
 
1444
   else
 
1445
      {
 
1446
      returnval = EvaluateFinalRval(CONTEXTID,cp->rval,cp->type,true,NULL);
 
1447
      }
 
1448
 
 
1449
   DeleteVariable(scope,cp->lval);
 
1450
   
 
1451
   if (!AddVariableHash(scope,cp->lval,returnval.item,returnval.rtype,GetControlDatatype(cp->lval,bp),cp->audit->filename,cp->lineno))
 
1452
      {
 
1453
      CfOut(cf_error,"","Rule from %s at/before line %d\n",cp->audit->filename,cp->lineno);
 
1454
      }
 
1455
 
 
1456
   if (strcmp(cp->lval,CFG_CONTROLBODY[cfg_output_prefix].lval) == 0)
 
1457
      {
 
1458
      strncpy(VPREFIX,returnval.item,CF_MAXVARSIZE);
 
1459
      }
 
1460
 
 
1461
   if (strcmp(cp->lval,CFG_CONTROLBODY[cfg_domain].lval) == 0)
 
1462
      {
 
1463
      strcpy(VDOMAIN,cp->rval);
 
1464
      CfOut(cf_verbose,"","SET domain = %s\n",VDOMAIN);
 
1465
      DeleteScalar("sys","domain");
 
1466
      DeleteScalar("sys","fqhost");
 
1467
      snprintf(VFQNAME,CF_MAXVARSIZE,"%s.%s",VUQNAME,VDOMAIN);
 
1468
      NewScalar("sys","fqhost",VFQNAME,cf_str);
 
1469
      NewScalar("sys","domain",VDOMAIN,cf_str);
 
1470
      DeleteClass("undefined_domain");
 
1471
      NewClass(CanonifyName(VDOMAIN));
 
1472
      }
 
1473
 
 
1474
   if (strcmp(cp->lval,CFG_CONTROLBODY[cfg_ignore_missing_inputs].lval) == 0)
 
1475
      {
 
1476
      CfOut(cf_verbose,"","SET ignore_missing_inputs %s\n",cp->rval);
 
1477
      IGNORE_MISSING_INPUTS = GetBoolean(cp->rval);
 
1478
      }
 
1479
 
 
1480
   if (strcmp(cp->lval,CFG_CONTROLBODY[cfg_ignore_missing_bundles].lval) == 0)
 
1481
      {
 
1482
      CfOut(cf_verbose,"","SET ignore_missing_bundles %s\n",cp->rval);
 
1483
      IGNORE_MISSING_BUNDLES = GetBoolean(cp->rval);
 
1484
      }
 
1485
 
 
1486
   DeleteRvalItem(returnval.item,returnval.rtype);
 
1487
   }
 
1488
}
 
1489
 
 
1490
/*******************************************************************/
 
1491
 
 
1492
void SetAuditVersion()
 
1493
 
 
1494
{ void *rval;
 
1495
  char rtype = 'x';
 
1496
 
 
1497
  /* In addition, each bundle can have its own version */
 
1498
 
 
1499
switch (GetVariable("control_common","cfinputs_version",&rval,&rtype))
 
1500
   {
 
1501
   case cf_str:
 
1502
       if (rtype != CF_SCALAR)
 
1503
          {
 
1504
          yyerror("non-scalar version string");
 
1505
          }
 
1506
       AUDITPTR->version = strdup((char *)rval);
 
1507
       break;
 
1508
 
 
1509
   default:
 
1510
       AUDITPTR->version = strdup("no specified version");
 
1511
       break;
 
1512
   }
 
1513
}
 
1514
 
 
1515
/*******************************************************************/
 
1516
 
 
1517
void Syntax(char *component,struct option options[],char *hints[],char *id)
 
1518
 
 
1519
{ int i;
 
1520
 
 
1521
printf("\n\n%s\n\n",component);
 
1522
 
 
1523
printf("SYNOPSIS:\n\n   program [options]\n\nDESCRIPTION:\n\n%s\n",id);
 
1524
printf("Command line options:\n\n");
 
1525
 
 
1526
for (i=0; options[i].name != NULL; i++)
 
1527
   {
 
1528
   if (options[i].has_arg)
 
1529
      {
 
1530
      printf("--%-12s, -%c value - %s\n",options[i].name,(char)options[i].val,hints[i]);
 
1531
      }
 
1532
   else
 
1533
      {
 
1534
      printf("--%-12s, -%-7c - %s\n",options[i].name,(char)options[i].val,hints[i]);
 
1535
      }
 
1536
   }
 
1537
 
 
1538
 
 
1539
printf("\nBug reports: bug-cfengine@cfengine.org, ");
 
1540
printf("Community help: help-cfengine@cfengine.org\n");
 
1541
printf("Community info: http://www.cfengine.org, ");
 
1542
printf("Support services: http://www.cfengine.com\n\n");
 
1543
printf("This software is (C) 2008 Cfengine AS.\n");
 
1544
}
 
1545
 
 
1546
/*******************************************************************/
 
1547
 
 
1548
void ManPage(char *component,struct option options[],char *hints[],char *id)
 
1549
 
 
1550
{ int i;
 
1551
 
 
1552
printf(".TH %s 8 \"Maintenance Commands\"\n",GetArg0(component));
 
1553
printf(".SH NAME\n%s\n\n",component);
 
1554
 
 
1555
printf(".SH SYNOPSIS:\n\n %s [options]\n\n.SH DESCRIPTION:\n\n%s\n",GetArg0(component),id);
 
1556
 
 
1557
printf(".B cfengine\n"
 
1558
       "is a self-healing configuration and change management based system. You can think of"
 
1559
       ".B cfengine\n"
 
1560
       "as a very high level language, much higher level than Perl or shell. A"
 
1561
       "single statement is called a promise, and compliance can result in many hundreds of files"
 
1562
       "being created, or the permissions of many hundreds of"
 
1563
       "files being set. The idea of "
 
1564
       ".B cfengine\n"
 
1565
       "is to create a one or more sets of configuration files which will"
 
1566
       "classify and describe the setup of every host in a network.\n");
 
1567
 
 
1568
printf(".SH COMMAND LINE OPTIONS:\n");
 
1569
 
 
1570
for (i=0; options[i].name != NULL; i++)
 
1571
   {
 
1572
   if (options[i].has_arg)
 
1573
      {
 
1574
      printf(".IP \"--%s, -%c\" value\n%s\n",options[i].name,(char)options[i].val,hints[i]);
 
1575
      }
 
1576
   else
 
1577
      {
 
1578
      printf(".IP \"--%s, -%c\"\n%s\n",options[i].name,(char)options[i].val,hints[i]);
 
1579
      }
 
1580
   }
 
1581
 
 
1582
printf(".SH AUTHOR\n"
 
1583
       "Mark Burgess and Cfengine AS\n"
 
1584
       ".SH INFORMATION\n");
 
1585
 
 
1586
printf("\nBug reports: bug-cfengine@cfengine.org\n");
 
1587
printf(".pp\nCommunity help: help-cfengine@cfengine.org\n");
 
1588
printf(".pp\nCommunity info: http://www.cfengine.org\n");
 
1589
printf(".pp\nSupport services: http://www.cfengine.com\n");
 
1590
printf(".pp\nThis software is (C) 2008- Cfengine AS.\n");
 
1591
}
 
1592
 
 
1593
/*******************************************************************/
 
1594
 
 
1595
void Version(char *component)
 
1596
 
 
1597
{
 
1598
printf("This comprises %s core community version %s - %s%s\n",component,VERSION,CF3COPYRIGHT,VYEAR);
 
1599
EnterpriseVersion();
 
1600
}
 
1601
 
 
1602
/********************************************************************/
 
1603
 
 
1604
void WritePID(char *filename)
 
1605
 
 
1606
{ FILE *fp;
 
1607
 
 
1608
snprintf(PIDFILE,CF_BUFSIZE-1,"%s%c%s",CFWORKDIR,FILE_SEPARATOR,filename);
 
1609
 
 
1610
if ((fp = fopen(PIDFILE,"w")) == NULL)
 
1611
   {
 
1612
   CfOut(cf_inform,"fopen","Could not write to PID file %s\n",filename);
 
1613
   return;
 
1614
   }
 
1615
 
 
1616
fprintf(fp,"%d\n",getpid());
 
1617
 
 
1618
fclose(fp);
 
1619
}
 
1620
 
 
1621
/*******************************************************************/
 
1622
 
 
1623
void HashVariables()
 
1624
 
 
1625
{ struct Bundle *bp,*bundles;
 
1626
  struct SubType *sp;
 
1627
  struct Scope *ptr;
 
1628
 
 
1629
CfOut(cf_verbose,"","Initiate variable convergence...\n");
 
1630
 
 
1631
for (bp = BUNDLES; bp != NULL; bp = bp->next) /* get schedule */
 
1632
   {
 
1633
   SetNewScope(bp->name);
 
1634
   THIS_BUNDLE = bp->name;
 
1635
 
 
1636
   for (sp = bp->subtypes; sp != NULL; sp = sp->next) /* get schedule */
 
1637
      {
 
1638
      if (strcmp(sp->name,"vars") == 0)
 
1639
         {
 
1640
         CheckVariablePromises(bp->name,sp->promiselist);
 
1641
         }
 
1642
 
 
1643
      // We must also set global classes here?
 
1644
 
 
1645
      if (strcmp(bp->type,"common") == 0&&  strcmp(sp->name,"classes") == 0)
 
1646
         {
 
1647
         CheckCommonClassPromises(sp->promiselist);
 
1648
         }
 
1649
      }
 
1650
 
 
1651
   CheckBundleParameters(bp->name,bp->args);
 
1652
   }
 
1653
}
 
1654
 
 
1655
/*******************************************************************/
 
1656
 
 
1657
void HashControls()
 
1658
 
 
1659
{ struct Body *bdp;
 
1660
  char buf[CF_BUFSIZE];
 
1661
 
 
1662
/* Only control bodies need to be hashed like variables */
 
1663
 
 
1664
CfOut(cf_verbose,"","Initiate control variable convergence...\n");
 
1665
 
 
1666
for (bdp = BODIES; bdp != NULL; bdp = bdp->next) /* get schedule */
 
1667
   {
 
1668
   if (strcmp(bdp->name,"control") == 0)
 
1669
      {
 
1670
      snprintf(buf,CF_BUFSIZE,"%s_%s",bdp->name,bdp->type);
 
1671
      SetNewScope(buf);
 
1672
      CheckControlPromises(buf,bdp->type,bdp->conlist);
 
1673
      }
 
1674
   }
 
1675
}
 
1676
 
 
1677
/*******************************************************************/
 
1678
 
 
1679
void UnHashVariables()
 
1680
 
 
1681
{ struct Bundle *bp,*bundles;
 
1682
 
 
1683
for (bp = BUNDLES; bp != NULL; bp = bp->next) /* get schedule */
 
1684
   {
 
1685
   DeleteScope(bp->name);
 
1686
   }
 
1687
}
 
1688
 
 
1689
/********************************************************************/
 
1690
 
 
1691
int BadBundleSequence(enum cfagenttype agent)
 
1692
 
 
1693
{ struct Rlist *rp,*params;
 
1694
  char rettype,*name;
 
1695
  void *retval = NULL;
 
1696
  int ok = true;
 
1697
  struct FnCall *fp;
 
1698
 
 
1699
if (THIS_AGENT_TYPE != cf_agent && THIS_AGENT_TYPE != cf_know && THIS_AGENT_TYPE != cf_common)
 
1700
   {
 
1701
   return false;
 
1702
   }
 
1703
 
 
1704
if (CBUNDLESEQUENCE)
 
1705
   {
 
1706
   return false;
 
1707
   }
 
1708
 
 
1709
if (GetVariable("control_common","bundlesequence",&retval,&rettype) == cf_notype)
 
1710
   {
 
1711
   CfOut(cf_error,""," !!! No bundlesequence in the common control body");
 
1712
 
 
1713
   if (agent == cf_common)
 
1714
      {
 
1715
      return false;
 
1716
      }
 
1717
   else
 
1718
      {
 
1719
      return true;
 
1720
      }
 
1721
   }
 
1722
 
 
1723
if (rettype != CF_LIST)
 
1724
   {
 
1725
   FatalError("Promised bundlesequence was not a list");
 
1726
   }
 
1727
 
 
1728
if (agent == cf_agent || agent == cf_common)
 
1729
   {
 
1730
   for (rp = (struct Rlist *)retval; rp != NULL; rp=rp->next)
 
1731
      {
 
1732
      switch (rp->type)
 
1733
         {
 
1734
         case CF_SCALAR:
 
1735
             name = (char *)rp->item;
 
1736
             params = NULL;
 
1737
             break;
 
1738
 
 
1739
         case CF_FNCALL:
 
1740
             fp = (struct FnCall *)rp->item;
 
1741
             name = (char *)fp->name;
 
1742
             params = (struct Rlist *)fp->args;
 
1743
             break;
 
1744
 
 
1745
         default:
 
1746
             name = NULL;
 
1747
             params = NULL;
 
1748
             CfOut(cf_error,"","Illegal item found in bundlesequence: ");
 
1749
             ShowRval(stdout,rp->item,rp->type);
 
1750
             printf(" = %c\n",rp->type);
 
1751
             ok = false;
 
1752
             break;
 
1753
         }
 
1754
 
 
1755
      if (!IGNORE_MISSING_BUNDLES && !GetBundle(name,NULL))
 
1756
         {
 
1757
         CfOut(cf_error,"","Bundle \"%s\" listed in the bundlesequence is not a defined bundle\n",name);
 
1758
         ok = false;
 
1759
         }
 
1760
      }
 
1761
 
 
1762
   if (!ok)
 
1763
      {
 
1764
      return true;
 
1765
      }
 
1766
   else
 
1767
      {
 
1768
      return false;
 
1769
      }
 
1770
   }
 
1771
 
 
1772
return false;
 
1773
}