void CheckConstraint(char *type, char *name, char *lval, Rval rval, SubTypeSyntax ss) { int lmatch = false; int i, l, allowed = false; const BodySyntax *bs; char output[CF_BUFSIZE]; CfDebug("CheckConstraint(%s,%s,", type, lval); if (DEBUG) { ShowRval(stdout, rval); } CfDebug(")\n"); if (ss.subtype != NULL) /* In a bundle */ { if (strcmp(ss.subtype, type) == 0) { CfDebug("Found type %s's body syntax\n", type); bs = ss.bs; for (l = 0; bs[l].lval != NULL; l++) { CfDebug("CMP-bundle # (%s,%s)\n", lval, bs[l].lval); if (strcmp(lval, bs[l].lval) == 0) { /* If we get here we have found the lval and it is valid for this subtype */ lmatch = true; CfDebug("Matched syntatically correct bundle (lval,rval) item = (%s) to its rval\n", lval); if (bs[l].dtype == cf_body) { CfDebug("Constraint syntax ok, but definition of body is elsewhere %s=%c\n", lval, rval.rtype); PrependRlist(&BODYPARTS, rval.item, rval.rtype); return; } else if (bs[l].dtype == cf_bundle) { CfDebug("Constraint syntax ok, but definition of relevant bundle is elsewhere %s=%c\n", lval, rval.rtype); PrependRlist(&SUBBUNDLES, rval.item, rval.rtype); return; } else { CheckConstraintTypeMatch(lval, rval, bs[l].dtype, (char *) (bs[l].range), 0); return; } } } } } /* Now check the functional modules - extra level of indirection Note that we only check body attributes relative to promise type. We can enter any promise types in any bundle, but only recognized types will be dealt with. */ for (i = 0; CF_COMMON_BODIES[i].lval != NULL; i++) { CfDebug("CMP-common # %s,%s\n", lval, CF_COMMON_BODIES[i].lval); if (strcmp(lval, CF_COMMON_BODIES[i].lval) == 0) { CfDebug("Found a match for lval %s in the common constraint attributes\n", lval); return; } } for (i = 0; CF_COMMON_EDITBODIES[i].lval != NULL; i++) { CfDebug("CMP-common # %s,%s\n", lval, CF_COMMON_EDITBODIES[i].lval); if (strcmp(lval, CF_COMMON_EDITBODIES[i].lval) == 0) { CfDebug("Found a match for lval %s in the common edit constraint attributes\n", lval); return; } } // Now check if it is in the common list... if (!lmatch || !allowed) { snprintf(output, CF_BUFSIZE, "Constraint lvalue \'%s\' is not allowed in bundle category \'%s\'", lval, type); ReportError(output); } }
void LastSaw(char *username,char *ipaddress,unsigned char digest[EVP_MAX_MD_SIZE+1],enum roles role) { char databuf[CF_BUFSIZE]; time_t now = time(NULL); int known = false; struct Rlist *rp; struct CfKeyBinding *kp; if (strlen(ipaddress) == 0) { CfOut(cf_inform,"","LastSeen registry for empty IP with role %d",role); return; } ThreadLock(cft_output); switch (role) { case cf_accept: snprintf(databuf,CF_BUFSIZE-1,"-%s",HashPrint(CF_DEFAULT_DIGEST,digest)); break; case cf_connect: snprintf(databuf,CF_BUFSIZE-1,"+%s",HashPrint(CF_DEFAULT_DIGEST,digest)); break; } ThreadUnlock(cft_output); ThreadLock(cft_server_keyseen); for (rp = SERVER_KEYSEEN; rp != NULL; rp=rp->next) { kp = (struct CfKeyBinding *) rp->item; if (strcmp(kp->name,databuf) == 0) { known = true; kp->timestamp = now; CfOut(cf_verbose,""," -> Last saw %s (%s) now",ipaddress,databuf); // Refresh address ThreadLock(cft_system); if (kp->address) { free(kp->address); } kp->address = strdup(ipaddress); ThreadUnlock(cft_system); ThreadUnlock(cft_server_keyseen); return; } } CfOut(cf_verbose,""," -> Last saw %s (%s) first time now",ipaddress,databuf); ThreadLock(cft_system); kp = (struct CfKeyBinding *)malloc((sizeof(struct CfKeyBinding))); ThreadUnlock(cft_system); if (kp == NULL) { ThreadUnlock(cft_server_keyseen); return; } rp = PrependRlist(&SERVER_KEYSEEN,"nothing",CF_SCALAR); ThreadLock(cft_system); free(rp->item); rp->item = kp; kp->address = strdup(ipaddress); if ((kp->name = strdup(databuf)) == NULL) { free(kp); ThreadUnlock(cft_system); ThreadUnlock(cft_server_keyseen); return; } ThreadUnlock(cft_system); kp->key = HavePublicKey(username,ipaddress,databuf+1); kp->timestamp = now; ThreadUnlock(cft_server_keyseen); }
static void Apoptosis() { Promise pp = { 0 }; Rlist *signals = NULL, *owners = NULL; char mypid[32]; static char promiser_buf[CF_SMALLBUF]; #if defined(__CYGWIN__) || defined(__MINGW32__) return; #endif CfOut(cf_verbose, "", " !! Programmed pruning of the scheduler cluster"); #ifdef MINGW snprintf(promiser_buf, sizeof(promiser_buf), "cf-execd"); // using '\' causes regexp problems #else snprintf(promiser_buf, sizeof(promiser_buf), "%s/bin/cf-execd", CFWORKDIR); #endif pp.promiser = promiser_buf; pp.promisee = (Rval) {"cfengine", CF_SCALAR}; pp.classes = "any"; pp.offset.line = 0; pp.audit = NULL; pp.conlist = NULL; pp.bundletype = "agent"; pp.bundle = "exec_apoptosis"; pp.ref = "Programmed death"; pp.agentsubtype = "processes"; pp.done = false; pp.next = NULL; pp.cache = NULL; pp.inode_cache = NULL; pp.this_server = NULL; pp.donep = &(pp.done); pp.conn = NULL; GetCurrentUserName(mypid, 31); PrependRlist(&signals, "term", CF_SCALAR); PrependRlist(&owners, mypid, CF_SCALAR); ConstraintAppendToPromise(&pp, "signals", (Rval) {signals, CF_LIST}, "any", false); ConstraintAppendToPromise(&pp, "process_select", (Rval) {xstrdup("true"), CF_SCALAR}, "any", false); ConstraintAppendToPromise(&pp, "process_owner", (Rval) {owners, CF_LIST}, "any", false); ConstraintAppendToPromise(&pp, "ifelapsed", (Rval) {xstrdup("0"), CF_SCALAR}, "any", false); ConstraintAppendToPromise(&pp, "process_count", (Rval) {xstrdup("true"), CF_SCALAR}, "any", false); ConstraintAppendToPromise(&pp, "match_range", (Rval) {xstrdup("0,2"), CF_SCALAR}, "any", false); ConstraintAppendToPromise(&pp, "process_result", (Rval) {xstrdup("process_owner.process_count"), CF_SCALAR}, "any", false); CfOut(cf_verbose, "", " -> Looking for cf-execd processes owned by %s", mypid); if (LoadProcessTable(&PROCESSTABLE)) { VerifyProcessesPromise(&pp); } DeleteItemList(PROCESSTABLE); if (pp.conlist) { DeleteConstraintList(pp.conlist); } CfOut(cf_verbose, "", " !! Pruning complete"); }