00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "cf.defs.h"
00033 #include "cf.extern.h"
00034
00035 void GetRandom ARGLIST((char* args,char *value));
00036 void HandleFunctionExec ARGLIST((char* args,char *value));
00037 void HandleStatInfo ARGLIST((enum builtin fn,char* args,char *value));
00038 void HandleCompareStat ARGLIST((enum builtin fn,char* args,char *value));
00039 void HandleReturnsZero ARGLIST((char* args,char *value));
00040 void HandleIPRange ARGLIST((char* args,char *value));
00041 void HandleIsDefined ARGLIST((char* args,char *value));
00042 void HandleStrCmp ARGLIST((char* args,char *value));
00043 void HandleShowState ARGLIST((char* args,char *value));
00044
00045
00046
00047 int IsBuiltinFunction(item)
00048
00049 char *item;
00050
00051 { char name[maxvarsize],args[bufsize];
00052 char c1 = '?',c2 = '?' ;
00053
00054 sscanf(item,"%255[a-zA-Z0-9_]%c%255[^)]%c",name,&c1,args,&c2);
00055
00056 if (c1 != '(' || c2 != ')')
00057 {
00058 return false;
00059 }
00060
00061 Debug("IsBuiltinFunction: %s(%s)\n",name,args);
00062 return true;
00063 }
00064
00065
00066
00067 char *EvaluateFunction(f,value)
00068
00069 char *f,*value;
00070
00071 { enum builtin fn;
00072 char name[maxvarsize],vargs[bufsize],args[bufsize];
00073
00074 sscanf(f,"%255[^(](%255[^)])",name,vargs);
00075 ExpandVarstring(vargs,args,NULL);
00076 Debug("HandleFunction: %s(%s)\n",name,args);
00077
00078 switch (fn = FunctionStringToCode(name))
00079 {
00080 case fn_randomint:
00081 GetRandom(args,value);
00082 break;
00083 case fn_newerthan:
00084 case fn_accessedbefore:
00085 case fn_changedbefore:
00086 HandleCompareStat(fn,args,value);
00087 break;
00088 case fn_fileexists:
00089 case fn_isdir:
00090 case fn_islink:
00091 case fn_isplain:
00092 HandleStatInfo(fn,args,value);
00093 break;
00094 case fn_execresult:
00095 HandleFunctionExec(args,value);
00096 break;
00097 case fn_returnszero:
00098 HandleReturnsZero(args,value);
00099 break;
00100 case fn_iprange:
00101 HandleIPRange(args,value);
00102 break;
00103 case fn_isdefined:
00104 HandleIsDefined(args,value);
00105 break;
00106 case fn_strcmp:
00107 HandleStrCmp(args,value);
00108 break;
00109 case fn_showstate:
00110 HandleShowState(args,value);
00111 break;
00112 }
00113
00114 return value;
00115 }
00116
00117
00118
00119
00120
00121 enum builtin FunctionStringToCode(str)
00122
00123 char *str;
00124
00125 { char *sp;
00126 int i;
00127 enum builtin fn;
00128
00129 fn = nofn;
00130
00131 for (sp = str; *sp != '\0'; sp++)
00132 {
00133 *sp = ToLower(*sp);
00134 if (*sp == ':')
00135 {
00136 *sp = '\0';
00137 }
00138 }
00139
00140 for (i = 1; BUILTINS[i] != '\0'; i++)
00141 {
00142 if (strcmp(BUILTINS[i],str) == 0)
00143 {
00144 fn = (enum builtin) i;
00145 break;
00146 }
00147 }
00148
00149 if (fn == nofn)
00150 {
00151 snprintf(OUTPUT,bufsize,"Internal function %s not recognized",str);
00152 yyerror(OUTPUT);
00153 FatalError("Could not parse function");
00154 }
00155
00156 return (enum builtin) i;
00157 }
00158
00159
00160
00161 void GetRandom(args,value)
00162
00163 char *args,*value;
00164
00165 { int result,count=0,from=-1,to=-1;
00166 char *sp;
00167
00168 if (ACTION != control)
00169 {
00170 yyerror("Use of RandInt(a,b) outside of variable assignment");
00171 }
00172
00173 for (sp = args; *sp != '\0'; sp++)
00174 {
00175 if (*sp == ',')
00176 {
00177 count++;
00178 }
00179 }
00180
00181 if (count != 1)
00182 {
00183 yyerror("RandomInt(a,b): argument error");
00184 return;
00185 }
00186
00187 sscanf(args,"%d,%d",&from,&to);
00188
00189 if ((from < 0) || (to < 0) || (from == to))
00190 {
00191 yyerror("RandomInt(a,b) must have different non-negative arguments < INT_MAX");
00192 return;
00193 }
00194
00195 if (from > to)
00196 {
00197 yyerror("RandomInt(a,b) - b was less than a");
00198 return;
00199 }
00200
00201 result = from + (int)(drand48()*(double)(to-from));
00202 Debug("RandomInt(%u)\n",result);
00203 snprintf(value,bufsize,"%u",result);
00204 }
00205
00206
00207
00208 void HandleStatInfo(fn,args,value)
00209
00210 enum builtin fn;
00211 char *args,*value;
00212
00213 { struct stat statbuf;
00214
00215 if (strchr(args,','))
00216 {
00217 yyerror("Illegal argument to unary class-function");
00218 return;
00219 }
00220
00221 if (lstat(args,&statbuf) == -1)
00222 {
00223 strcpy(value,CF_NOCLASS);
00224 return;
00225 }
00226 else
00227 {
00228 if (fn == fn_fileexists)
00229 {
00230 strcpy(value,CF_ANYCLASS);
00231 return;
00232 }
00233 }
00234
00235 strcpy(value,CF_NOCLASS);
00236
00237 switch(fn)
00238 {
00239 case fn_isdir:
00240 if (S_ISDIR(statbuf.st_mode))
00241 {
00242 strcpy(value,CF_ANYCLASS);
00243 return;
00244 }
00245 break;
00246 case fn_islink:
00247 if (S_ISLNK(statbuf.st_mode))
00248 {
00249 strcpy(value,CF_ANYCLASS);
00250 return;
00251 }
00252 break;
00253 case fn_isplain:
00254 if (S_ISREG(statbuf.st_mode))
00255 {
00256 strcpy(value,CF_ANYCLASS);
00257 return;
00258 }
00259 break;
00260 }
00261
00262 strcpy(value,CF_NOCLASS);
00263 }
00264
00265
00266
00267 void HandleIPRange(args,value)
00268
00269 char *args,*value;
00270
00271 { struct stat statbuf;
00272
00273 if (strchr(args,','))
00274 {
00275 yyerror("Illegal argument to unary class-function");
00276 return;
00277 }
00278
00279 strcpy(value,CF_NOCLASS);
00280
00281 if (!FuzzyMatchParse(args))
00282 {
00283 return;
00284 }
00285
00286 if (FuzzySetMatch(args,VIPADDRESS) == 0)
00287 {
00288 strcpy(value,CF_ANYCLASS);
00289 }
00290 }
00291
00292
00293
00294 void HandleCompareStat(fn,args,value)
00295
00296 enum builtin fn;
00297 char *args,*value;
00298
00299 { struct stat frombuf,tobuf;
00300 char *sp,from[bufsize],to[bufsize];
00301 int count = 0;
00302
00303 from[0] = '\0';
00304 to[0] = '\0';
00305
00306 for (sp = args; *sp != '\0'; sp++)
00307 {
00308 if (*sp == ',')
00309 {
00310 count++;
00311 }
00312 }
00313
00314 if (count != 1)
00315 {
00316 yyerror("RandomInt(a,b): argument error");
00317 return;
00318 }
00319
00320 sscanf(args,"%[^,],%[^)]",from,to);
00321 Debug("Comparing [%s] < [%s]\n",from,to);
00322
00323 if (from[0]=='\0' || to[0] == '\0')
00324 {
00325 yyerror("Argument error in class-function");
00326 return;
00327 }
00328
00329 strcpy(value,CF_NOCLASS);
00330
00331 if (stat(from,&frombuf) == -1)
00332 {
00333 return;
00334 }
00335
00336 if (stat(to,&tobuf) == -1)
00337 {
00338 return;
00339 }
00340
00341 switch(fn)
00342 {
00343 case fn_newerthan:
00344 if (frombuf.st_mtime > tobuf.st_mtime)
00345 {
00346 strcpy(value,CF_ANYCLASS);
00347 return;
00348 }
00349 break;
00350
00351 case fn_accessedbefore:
00352 if (frombuf.st_atime < tobuf.st_atime)
00353 {
00354 strcpy(value,CF_ANYCLASS);
00355 return;
00356 }
00357 break;
00358
00359 case fn_changedbefore:
00360 if (frombuf.st_ctime < tobuf.st_ctime)
00361 {
00362 strcpy(value,CF_ANYCLASS);
00363 return;
00364 }
00365 break;
00366 }
00367
00368 strcpy(value,CF_NOCLASS);
00369 }
00370
00371
00372
00373
00374 void HandleFunctionExec(args,value)
00375
00376 char *args,*value;
00377
00378 { char command[maxvarsize];
00379
00380 if (ACTION != control)
00381 {
00382 yyerror("Use of ExecResult(s) outside of variable assignment");
00383 }
00384
00385 if (*args == '/')
00386 {
00387 strncpy(command,args,maxvarsize);
00388 GetExecOutput(command,value);
00389 Chop(value);
00390 value[maxvarsize-1] = '\0';
00391 }
00392 else
00393 {
00394 yyerror("ExecResult(/command) must specify an absolute path");
00395 }
00396 }
00397
00398
00399
00400 void HandleReturnsZero(args,value)
00401
00402 char *args,*value;
00403
00404 { char command[bufsize];
00405
00406 if (ACTION != groups)
00407 {
00408 yyerror("Use of ReturnsZero(s) outside of class assignment");
00409 }
00410
00411 Debug("HandleReturnsZero(%s)\n",args);
00412
00413 if (*args == '/')
00414 {
00415 strncpy(command,args,bufsize);
00416
00417 if (ShellCommandReturnsZero(command))
00418 {
00419 strcpy(value,CF_ANYCLASS);
00420 return;
00421 }
00422 }
00423 else
00424 {
00425 yyerror("ExecResult(/command) must specify an absolute path");
00426 }
00427
00428 strcpy(value,CF_NOCLASS);
00429 }
00430
00431
00432
00433
00434 void HandleIsDefined(args,value)
00435
00436 char *args,*value;
00437
00438 {
00439 if (ACTION != groups)
00440 {
00441 yyerror("Use of IsDefined(s) outside of class assignment");
00442 }
00443
00444 Debug("HandleIsDefined(%s)\n",args);
00445
00446 if (GetMacroValue(CONTEXTID,args))
00447 {
00448 strcpy(value,CF_ANYCLASS);
00449 return;
00450 }
00451
00452 strcpy(value,CF_NOCLASS);
00453 }
00454
00455
00456
00457
00458 void HandleStrCmp(args,value)
00459
00460 char *args,*value;
00461
00462 { char *sp,from[bufsize],to[bufsize],*nfrom,*nto;
00463 int count = 0;
00464
00465 from[0] = '\0';
00466 to[0] = '\0';
00467
00468 for (sp = args; *sp != '\0'; sp++)
00469 {
00470 if (*sp == ',')
00471 {
00472 count++;
00473 }
00474 }
00475
00476 if (count != 1)
00477 {
00478 yyerror("StrCmp(a,b): argument error");
00479 return;
00480 }
00481
00482 sscanf(args,"%[^,],%[^)]",from,to);
00483 Debug("Comparing [%s] < [%s]\n",from,to);
00484
00485 if (from[0]=='\0' || to[0] == '\0')
00486 {
00487 yyerror("Argument error in class-function");
00488 return;
00489 }
00490
00491 nfrom = UnQuote(from);
00492 nto = UnQuote(to);
00493
00494 if (strcmp(nfrom,nto) == 0)
00495 {
00496 strcpy(value,CF_ANYCLASS);
00497 }
00498 else
00499 {
00500 strcpy(value,CF_NOCLASS);
00501 }
00502 }
00503
00504
00505
00506
00507
00508 void HandleShowState(args,value)
00509
00510 char *args,*value;
00511
00512 { struct stat statbuf;
00513 char buffer[bufsize];
00514 FILE *fp;
00515 int i = 0;
00516
00517 if (PARSING)
00518 {
00519 return;
00520 }
00521
00522 if (ACTION != alerts)
00523 {
00524 yyerror("Use of ShowState(type) outside of alert declaration");
00525 }
00526
00527 Debug("ShowState(%s)\n",args);
00528
00529 snprintf(buffer,bufsize,"%s/state/cf_%s",WORKDIR,args);
00530
00531 if (stat(buffer,&statbuf) == 0)
00532 {
00533 if ((fp = fopen(buffer,"r")) == NULL)
00534 {
00535 Verbose("Could not open state %s\n",buffer);
00536 return;
00537 }
00538
00539 while(!feof(fp))
00540 {
00541 buffer[0] = '\0';
00542
00543 fgets(buffer,bufsize,fp);
00544 i++;
00545
00546 if (strlen(buffer) > 0)
00547 {
00548 printf("%s: (%2d) %s",VPREFIX,i,buffer);
00549 }
00550 }
00551
00552 fclose(fp);
00553 snprintf(buffer,bufsize,"State of %s recorded at %s\n",args,ctime(&statbuf.st_mtime));
00554 strcpy(value,buffer);
00555 }
00556 else
00557 {
00558 snprintf(buffer,bufsize,"State parameter %s is not known or recorded\n",args);
00559 strcpy(value,buffer);
00560 }
00561 }
00562