Exemplo n.º 1
0
static void ThisAgentInit(EvalContext *ctx)
{
    umask(077);
    sprintf(VPREFIX, "cf-monitord");

    SetReferenceTime(ctx, false);
    SetStartTime();

    signal(SIGINT, HandleSignalsForDaemon);
    signal(SIGTERM, HandleSignalsForDaemon);
    signal(SIGHUP, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);
    signal(SIGUSR1, HandleSignalsForDaemon);
    signal(SIGUSR2, HandleSignalsForDaemon);

    FORGETRATE = 0.6;

    MonitorInitialize();
}
Exemplo n.º 2
0
static void ThisAgentInit(EvalContext *ctx)
{
    umask(077);
    strcpy(VPREFIX, "cf-monitord");

    time_t t = SetReferenceTime();
    UpdateTimeClasses(ctx, t);

    signal(SIGINT, HandleSignalsForDaemon);
    signal(SIGTERM, HandleSignalsForDaemon);
    signal(SIGHUP, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);
    signal(SIGUSR1, HandleSignalsForDaemon);
    signal(SIGUSR2, HandleSignalsForDaemon);

    FORGETRATE = 0.6;

    MonitorInitialize();
}
Exemplo n.º 3
0
void GenericAgentDiscoverContext(EvalContext *ctx, GenericAgentConfig *config)
{
    GenericAgentSetDefaultDigest(&CF_DEFAULT_DIGEST, &CF_DEFAULT_DIGEST_LEN);

    GenericAgentInitialize(ctx, config);

    time_t t = SetReferenceTime();
    UpdateTimeClasses(ctx, t);
    SanitizeEnvironment();

    THIS_AGENT_TYPE = config->agent_type;
    EvalContextClassPutHard(ctx, CF_AGENTTYPES[config->agent_type], "cfe_internal,source=agent");

    DetectEnvironment(ctx);

    EvalContextHeapPersistentLoadAll(ctx);
    LoadSystemConstants(ctx);

    if (config->agent_type == AGENT_TYPE_AGENT && config->agent_specific.agent.bootstrap_policy_server)
    {
        if (!RemoveAllExistingPolicyInInputs(GetInputDir()))
        {
            Log(LOG_LEVEL_ERR, "Error removing existing input files prior to bootstrap");
            exit(EXIT_FAILURE);
        }

        if (!WriteBuiltinFailsafePolicy(GetInputDir()))
        {
            Log(LOG_LEVEL_ERR, "Error writing builtin failsafe to inputs prior to bootstrap");
            exit(EXIT_FAILURE);
        }

        bool am_policy_server = false;
        {
            const char *canonified_bootstrap_policy_server = CanonifyName(config->agent_specific.agent.bootstrap_policy_server);
            am_policy_server = NULL != EvalContextClassGet(ctx, NULL, canonified_bootstrap_policy_server);
            {
                char policy_server_ipv4_class[CF_BUFSIZE];
                snprintf(policy_server_ipv4_class, CF_MAXVARSIZE, "ipv4_%s", canonified_bootstrap_policy_server);
                am_policy_server |= NULL != EvalContextClassGet(ctx, NULL, policy_server_ipv4_class);
            }

            if (am_policy_server)
            {
                Log(LOG_LEVEL_INFO, "Assuming role as policy server, with policy distribution point at %s", GetMasterDir());
                EvalContextClassPutHard(ctx, "am_policy_hub", "source=bootstrap");

                if (!MasterfileExists(GetMasterDir()))
                {
                    Log(LOG_LEVEL_ERR, "In order to bootstrap as a policy server, the file '%s/promises.cf' must exist.", GetMasterDir());
                    exit(EXIT_FAILURE);
                }
            }
            else
            {
                Log(LOG_LEVEL_INFO, "Not assuming role as policy server");
            }

            WriteAmPolicyHubFile(CFWORKDIR, am_policy_server);
        }

        WritePolicyServerFile(GetWorkDir(), config->agent_specific.agent.bootstrap_policy_server);
        SetPolicyServer(ctx, config->agent_specific.agent.bootstrap_policy_server);
        /* FIXME: Why it is called here? Can't we move both invocations to before if? */
        UpdateLastPolicyUpdateTime(ctx);
        Log(LOG_LEVEL_INFO, "Bootstrapping to '%s'", POLICY_SERVER);
    }
    else
    {
        char *existing_policy_server = ReadPolicyServerFile(GetWorkDir());
        if (existing_policy_server)
        {
            Log(LOG_LEVEL_VERBOSE, "This agent is bootstrapped to '%s'", existing_policy_server);
            SetPolicyServer(ctx, existing_policy_server);
            free(existing_policy_server);
            UpdateLastPolicyUpdateTime(ctx);
        }
        else
        {
            Log(LOG_LEVEL_VERBOSE, "This agent is not bootstrapped");
            return;
        }

        if (GetAmPolicyHub(GetWorkDir()))
        {
            EvalContextClassPutHard(ctx, "am_policy_hub", "source=bootstrap,deprecated,alias=policy_server");
            Log(LOG_LEVEL_VERBOSE, "Additional class defined: am_policy_hub");
            EvalContextClassPutHard(ctx, "policy_server", "inventory,attribute_name=CFEngine roles,source=bootstrap");
            Log(LOG_LEVEL_VERBOSE, "Additional class defined: policy_server");
        }
    }
}
Exemplo n.º 4
0
static void CheckFileChanges(EvalContext *ctx, Policy **policy, GenericAgentConfig *config)
{
    Log(LOG_LEVEL_DEBUG, "Checking file updates for input file '%s'",
        config->input_file);

    time_t validated_at = ReadTimestampFromPolicyValidatedFile(config, NULL);

    bool reload_config = false;

    if (config->agent_specific.daemon.last_validated_at < validated_at)
    {
        Log(LOG_LEVEL_VERBOSE, "New promises detected...");
        reload_config = true;
    }
    if (ReloadConfigRequested())
    {
        Log(LOG_LEVEL_VERBOSE, "Force reload of inputs files...");
        reload_config = true;
    }

    if (reload_config)
    {
        ClearRequestReloadConfig();

        /* Rereading policies now, so update timestamp. */
        config->agent_specific.daemon.last_validated_at = validated_at;

        if (GenericAgentArePromisesValid(config))
        {
            Log(LOG_LEVEL_NOTICE, "Rereading policy file '%s'",
                config->input_file);

            /* STEP 1: Free everything */

            EvalContextClear(ctx);

            strcpy(VDOMAIN, "undefined.domain");

            ClearAuthAndACLs();
            PolicyDestroy(*policy);               *policy = NULL;

            /* STEP 2: Set Environment, Parse and Evaluate policy */

            /*
             * TODO why is this done separately here? What's the difference to
             * calling the same steps as in cf-serverd.c:main()? Those are:
             *   GenericAgentConfigApply();     // not here!
             *   GenericAgentDiscoverContext(); // not here!
             *   EvalContextClassPutHard("server");             // only here!
             *   if (GenericAgentCheckPolicy()) // not here!
             *     policy = LoadPolicy();
             *   ThisAgentInit();               // not here, only calls umask()
             *   ReloadHAConfig();                              // only here!
             *   KeepPromises();
             *   Summarize();
             * Plus the following from within StartServer() which is only
             * called during startup:
             *   InitSignals();                  // not here
             *   ServerTLSInitialize();          // not here
             *   SetServerListenState();         // not here
             *   InitServer()                    // not here
             *   PolicyNew()+AcquireServerLock() // not here
             *   PrepareServer(sd);              // not here
             *   CollectCallStart();  // both
             */

            EvalContextSetPolicyServerFromFile(ctx, GetWorkDir());

            UpdateLastPolicyUpdateTime(ctx);

            DetectEnvironment(ctx);
            KeepHardClasses(ctx);
            LoadAugments(ctx, config);

            /* During startup this is done in GenericAgentDiscoverContext(). */
            EvalContextClassPutHard(ctx, CF_AGENTTYPES[AGENT_TYPE_SERVER], "cfe_internal,source=agent");

            time_t t = SetReferenceTime();
            UpdateTimeClasses(ctx, t);

            /* TODO BUG: this modifies config, but previous config has not
             * been reset/free'd. Ideally we would want LoadPolicy to not
             * modify config at all, but only modify ctx. */
            *policy = LoadPolicy(ctx, config);

            /* Reload HA related configuration */
            ReloadHAConfig();

            KeepPromises(ctx, *policy, config);
            Summarize();
        }
        else
        {
            Log(LOG_LEVEL_INFO, "File changes contain errors -- ignoring");
        }
    }
    else
    {
        Log(LOG_LEVEL_DEBUG, "No new promises found");
    }
}
Exemplo n.º 5
0
void GenericAgentDiscoverContext(EvalContext *ctx, GenericAgentConfig *config)
{
    GenericAgentInitialize(ctx, config);

    SetReferenceTime(ctx, true);
    SetStartTime();
    SanitizeEnvironment();

    THIS_AGENT_TYPE = config->agent_type;
    EvalContextHeapAddHard(ctx, CF_AGENTTYPES[config->agent_type]);

    GenericAgentSetDefaultDigest(&CF_DEFAULT_DIGEST, &CF_DEFAULT_DIGEST_LEN);

    GetNameInfo3(ctx, config->agent_type);
    GetInterfacesInfo(ctx);

    Get3Environment(ctx, config->agent_type);
    BuiltinClasses(ctx);
    OSClasses(ctx);

    EvalContextHeapPersistentLoadAll(ctx);
    LoadSystemConstants(ctx);

    if (config->agent_type == AGENT_TYPE_AGENT && config->agent_specific.agent.bootstrap_policy_server)
    {
        if (!RemoveAllExistingPolicyInInputs(GetWorkDir()))
        {
            Log(LOG_LEVEL_ERR, "Error removing existing input files prior to bootstrap");
            exit(EXIT_FAILURE);
        }

        if (!WriteBuiltinFailsafePolicy(GetWorkDir()))
        {
            Log(LOG_LEVEL_ERR, "Error writing builtin failsafe to inputs prior to bootstrap");
            exit(EXIT_FAILURE);
        }

        bool am_policy_server = false;
        {
            const char *canonified_bootstrap_policy_server = CanonifyName(config->agent_specific.agent.bootstrap_policy_server);
            am_policy_server = IsDefinedClass(ctx, canonified_bootstrap_policy_server, NULL);
            {
                char policy_server_ipv4_class[CF_BUFSIZE];
                snprintf(policy_server_ipv4_class, CF_MAXVARSIZE, "ipv4_%s", canonified_bootstrap_policy_server);
                am_policy_server |= IsDefinedClass(ctx, policy_server_ipv4_class, NULL);
            }

            if (am_policy_server)
            {
                Log(LOG_LEVEL_INFO, "Assuming role as policy server, with policy distribution point at %s/masterfiles", GetWorkDir());
                EvalContextHeapAddHard(ctx, "am_policy_hub");

                if (!MasterfileExists(GetWorkDir()))
                {
                    Log(LOG_LEVEL_ERR, "In order to bootstrap as a policy server, the file '%s/masterfiles/promises.cf' must exist.", GetWorkDir());
                    exit(EXIT_FAILURE);
                }
            }
            else
            {
                Log(LOG_LEVEL_INFO, "Not assuming role as policy server");
            }

            WriteAmPolicyHubFile(CFWORKDIR, am_policy_server);
        }

        WritePolicyServerFile(GetWorkDir(), config->agent_specific.agent.bootstrap_policy_server);
        SetPolicyServer(ctx, config->agent_specific.agent.bootstrap_policy_server);
        Log(LOG_LEVEL_INFO, "Bootstrapping to '%s'", POLICY_SERVER);
    }
    else
    {
        char *existing_policy_server = ReadPolicyServerFile(GetWorkDir());
        if (existing_policy_server)
        {
            Log(LOG_LEVEL_VERBOSE, "This agent is bootstrapped to '%s'", existing_policy_server);
        }
        else
        {
            Log(LOG_LEVEL_VERBOSE, "This agent is not bootstrapped");
        }
        SetPolicyServer(ctx, existing_policy_server);

        if (GetAmPolicyHub(GetWorkDir()))
        {
            EvalContextHeapAddHard(ctx, "am_policy_hub");  // DEPRECATED: use policy_server instead
            Log(LOG_LEVEL_VERBOSE, "Additional class defined: am_policy_hub");
            EvalContextHeapAddHard(ctx, "policy_server");
            Log(LOG_LEVEL_VERBOSE, "Additional class defined: policy_server");
        }
    }
}
Exemplo n.º 6
0
static bool ScheduleRun(EvalContext *ctx, Policy **policy, GenericAgentConfig *config,
                        ExecdConfig **execd_config, ExecConfig **exec_config)
{
    Log(LOG_LEVEL_VERBOSE, "Sleeping for pulse time %d seconds...", CFPULSETIME);
    sleep(CFPULSETIME);         /* 1 Minute resolution is enough */

    /*
     * FIXME: this logic duplicates the one from cf-serverd.c. Unify ASAP.
     */

    if (CheckNewPromises(config) == RELOAD_FULL)
    {
        /* Full reload */

        Log(LOG_LEVEL_INFO, "Re-reading promise file '%s'", config->input_file);

        EvalContextClear(ctx);

        strcpy(VDOMAIN, "undefined.domain");

        PolicyDestroy(*policy);
        *policy = NULL;

        {
            char *existing_policy_server = ReadPolicyServerFile(GetWorkDir());
            SetPolicyServer(ctx, existing_policy_server);
            free(existing_policy_server);
        }
        UpdateLastPolicyUpdateTime(ctx);

        DetectEnvironment(ctx);

        EvalContextClassPutHard(ctx, CF_AGENTTYPES[AGENT_TYPE_EXECUTOR], "cfe_internal,source=agent");

        time_t t = SetReferenceTime();
        UpdateTimeClasses(ctx, t);

        GenericAgentConfigSetBundleSequence(config, NULL);

        *policy = LoadPolicy(ctx, config);
        ExecConfigDestroy(*exec_config);
        ExecdConfigDestroy(*execd_config);

        *exec_config = ExecConfigNew(!ONCE, ctx, *policy);
        *execd_config = ExecdConfigNew(ctx, *policy);

        SetFacility((*execd_config)->log_facility);
    }
    else
    {
        /* Environment reload */

        EvalContextClear(ctx);

        DetectEnvironment(ctx);

        time_t t = SetReferenceTime();
        UpdateTimeClasses(ctx, t);
    }

    {
        StringSetIterator it = StringSetIteratorInit((*execd_config)->schedule);
        const char *time_context = NULL;
        while ((time_context = StringSetIteratorNext(&it)))
        {
            if (IsDefinedClass(ctx, time_context))
            {
                Log(LOG_LEVEL_VERBOSE, "Waking up the agent at %s ~ %s", ctime(&CFSTARTTIME), time_context);
                return true;
            }
        }
    }

    Log(LOG_LEVEL_VERBOSE, "Nothing to do at %s", ctime(&CFSTARTTIME));
    return false;
}
Exemplo n.º 7
0
void GenericAgentDiscoverContext(EvalContext *ctx, GenericAgentConfig *config)
{
    strcpy(VPREFIX, "");

    Log(LOG_LEVEL_VERBOSE, " %s", NameVersion());
    Banner("Initialization preamble");

    GenericAgentSetDefaultDigest(&CF_DEFAULT_DIGEST, &CF_DEFAULT_DIGEST_LEN);
    GenericAgentInitialize(ctx, config);

    time_t t = SetReferenceTime();
    UpdateTimeClasses(ctx, t);
    SanitizeEnvironment();

    THIS_AGENT_TYPE = config->agent_type;
    LoggingSetAgentType(CF_AGENTTYPES[config->agent_type]);
    EvalContextClassPutHard(ctx, CF_AGENTTYPES[config->agent_type],
                            "cfe_internal,source=agent");

    DetectEnvironment(ctx);

    EvalContextHeapPersistentLoadAll(ctx);
    LoadSystemConstants(ctx);

    const char *bootstrap_arg =
        config->agent_specific.agent.bootstrap_policy_server;

    /* Are we bootstrapping the agent? */
    if (config->agent_type == AGENT_TYPE_AGENT && bootstrap_arg != NULL)
    {
        EvalContextClassPutHard(ctx, "bootstrap_mode", "source=environment");

        if (!RemoveAllExistingPolicyInInputs(GetInputDir()))
        {
            Log(LOG_LEVEL_ERR,
                "Error removing existing input files prior to bootstrap");
            exit(EXIT_FAILURE);
        }

        if (!WriteBuiltinFailsafePolicy(GetInputDir()))
        {
            Log(LOG_LEVEL_ERR,
                "Error writing builtin failsafe to inputs prior to bootstrap");
            exit(EXIT_FAILURE);
        }

        char canonified_ipaddr[strlen(bootstrap_arg) + 1];
        StringCanonify(canonified_ipaddr, bootstrap_arg);

        bool am_policy_server =
            EvalContextClassGet(ctx, NULL, canonified_ipaddr) != NULL;

        if (am_policy_server)
        {
            Log(LOG_LEVEL_INFO, "Assuming role as policy server,"
                " with policy distribution point at: %s", GetMasterDir());
            MarkAsPolicyServer(ctx);

            if (!MasterfileExists(GetMasterDir()))
            {
                Log(LOG_LEVEL_ERR, "In order to bootstrap as a policy server,"
                    " the file '%s/promises.cf' must exist.", GetMasterDir());
                exit(EXIT_FAILURE);
            }

            CheckAndSetHAState(GetWorkDir(), ctx);
        }
        else
        {
            Log(LOG_LEVEL_INFO, "Assuming role as regular client,"
                " bootstrapping to policy server: %s", bootstrap_arg);

            if (config->agent_specific.agent.bootstrap_trust_server)
            {
                EvalContextClassPutHard(ctx, "trust_server", "source=agent");
                Log(LOG_LEVEL_NOTICE,
                    "Bootstrap mode: implicitly trusting server, "
                    "use --trust-server=no if server trust is already established");
            }
        }

        WriteAmPolicyHubFile(am_policy_server);

        WritePolicyServerFile(GetWorkDir(), bootstrap_arg);
        SetPolicyServer(ctx, bootstrap_arg);

        /* FIXME: Why it is called here? Can't we move both invocations to before if? */
        UpdateLastPolicyUpdateTime(ctx);
    }
    else
    {
        char *existing_policy_server = ReadPolicyServerFile(GetWorkDir());
        if (existing_policy_server)
        {
            Log(LOG_LEVEL_VERBOSE, "This agent is bootstrapped to: %s",
                existing_policy_server);
            SetPolicyServer(ctx, existing_policy_server);
            free(existing_policy_server);
            UpdateLastPolicyUpdateTime(ctx);
        }
        else
        {
            Log(LOG_LEVEL_VERBOSE, "This agent is not bootstrapped -"
                " can't find policy_server.dat in: %s", GetWorkDir());
            return;
        }

        if (GetAmPolicyHub())
        {
            MarkAsPolicyServer(ctx);

            /* Should this go in MarkAsPolicyServer() ? */
            CheckAndSetHAState(GetWorkDir(), ctx);
        }
    }
}
Exemplo n.º 8
0
void CheckFileChanges(Policy **policy, GenericAgentConfig *config, const ReportContext *report_context)
{
    if (EnterpriseExpiry())
    {
        CfOut(cf_error, "", "!! This enterprise license is invalid.");
    }

    CfDebug("Checking file updates on %s\n", config->input_file);

    if (NewPromiseProposals(config->input_file, InputFiles(*policy)))
    {
        CfOut(cf_verbose, "", " -> New promises detected...\n");

        if (CheckPromises(config->input_file, report_context))
        {
            CfOut(cf_inform, "", "Rereading config files %s..\n", config->input_file);

            /* Free & reload -- lock this to avoid access errors during reload */

            DeleteItemList(VNEGHEAP);
            
            DeleteAlphaList(&VHEAP);
            InitAlphaList(&VHEAP);
            DeleteAlphaList(&VHARDHEAP);
            InitAlphaList(&VHARDHEAP);
            
            DeleteAlphaList(&VADDCLASSES);
            InitAlphaList(&VADDCLASSES);

            DeleteItemList(IPADDRESSES);
            IPADDRESSES = NULL;

            DeleteItemList(SV.trustkeylist);
            DeleteItemList(SV.skipverify);
            DeleteItemList(SV.attackerlist);
            DeleteItemList(SV.nonattackerlist);
            DeleteItemList(SV.multiconnlist);

            DeleteAuthList(VADMIT);
            DeleteAuthList(VDENY);

            DeleteAuthList(VARADMIT);
            DeleteAuthList(VARDENY);

            DeleteAuthList(ROLES);

            //DeleteRlist(VINPUTLIST); This is just a pointer, cannot free it

            DeleteAllScope();

            strcpy(VDOMAIN, "undefined.domain");
            POLICY_SERVER[0] = '\0';

            VADMIT = VADMITTOP = NULL;
            VDENY = VDENYTOP = NULL;

            VARADMIT = VARADMITTOP = NULL;
            VARDENY = VARDENYTOP = NULL;

            ROLES = ROLESTOP = NULL;

            VNEGHEAP = NULL;
            SV.trustkeylist = NULL;
            SV.skipverify = NULL;
            SV.attackerlist = NULL;
            SV.nonattackerlist = NULL;
            SV.multiconnlist = NULL;

            PolicyDestroy(*policy);
            *policy = NULL;

            ERRORCOUNT = 0;

            NewScope("sys");

            SetPolicyServer(POLICY_SERVER);
            NewScalar("sys", "policy_hub", POLICY_SERVER, DATA_TYPE_STRING);

            if (EnterpriseExpiry())
            {
                CfOut(cf_error, "",
                      "Cfengine - autonomous configuration engine. This enterprise license is invalid.\n");
            }

            NewScope("const");
            NewScope("this");
            NewScope("control_server");
            NewScope("control_common");
            NewScope("mon");
            NewScope("remote_access");
            GetNameInfo3();
            GetInterfacesInfo(AGENT_TYPE_SERVER);
            Get3Environment();
            BuiltinClasses();
            OSClasses();
            KeepHardClasses();

            HardClass(CF_AGENTTYPES[THIS_AGENT_TYPE]);

            SetReferenceTime(true);
            *policy = ReadPromises(AGENT_TYPE_SERVER, config, report_context);
            KeepPromises(*policy, config, report_context);
            Summarize();

        }
        else
        {
            CfOut(cf_inform, "", " !! File changes contain errors -- ignoring");
            PROMISETIME = time(NULL);
        }
    }
    else
    {
        CfDebug(" -> No new promises found\n");
    }
}
Exemplo n.º 9
0
static Item *MonReSample(EvalContext *ctx, int slot, Attributes a, const Promise *pp, PromiseResult *result)
{
 CfLock thislock;
 char eventname[CF_BUFSIZE];
 char comm[20];
 struct timespec start;
 FILE *fin = NULL;
 mode_t maskval = 0;
 
 if (a.measure.stream_type && strcmp(a.measure.stream_type, "pipe") == 0)
    {
    if (!IsExecutable(CommandArg0(pp->promiser)))
       {
       cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "%s promises to be executable but isn't\n", pp->promiser);
       *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL);
       return NULL;
       }
    else
       {
       Log(LOG_LEVEL_VERBOSE, "Promiser string contains a valid executable (%s) - ok", CommandArg0(pp->promiser));
       }
    }
 
 TransactionContext tc =
     {
     .expireafter = a.transaction.expireafter,
     .ifelapsed = MONITOR_RESTARTED ? 0 : a.transaction.ifelapsed, // Force a measurement if restarted
     };
 
 CFSTARTTIME = time(NULL);
 
 thislock = AcquireLock(ctx, pp->promiser, VUQNAME, CFSTARTTIME, tc, pp, false);
 
 if (thislock.lock == NULL)
    {
    if (a.measure.history_type && (strcmp(a.measure.history_type, "log") == 0))
       {
       DeleteItemList(ENTERPRISE_DATA[slot].output);
       ENTERPRISE_DATA[slot].output = NULL;
       }
    else
       {
       /* If static or time-series, and too soon or busy then use a cached value
          to avoid artificial gaps in the history */
       }
    
    MONITOR_RESTARTED = false;
    return ENTERPRISE_DATA[slot].output;
    }
 else
    {
    DeleteItemList(ENTERPRISE_DATA[slot].output);
    ENTERPRISE_DATA[slot].output = NULL;
    
    Log(LOG_LEVEL_INFO, "Sampling \'%s\' ...(timeout=%d,owner=%ju,group=%ju)", pp->promiser, a.contain.timeout,
        (uintmax_t)a.contain.owner, (uintmax_t)a.contain.group);
    
    start = BeginMeasure();
    
    CommandPrefix(pp->promiser, comm);
    
    if (a.contain.timeout != 0)
       {
       SetTimeOut(a.contain.timeout);
       }
    
    /* Stream types */
    
    if (a.measure.stream_type && strcmp(a.measure.stream_type, "file") == 0)
       {
       long filepos = 0;
       struct stat sb;
       
       Log(LOG_LEVEL_VERBOSE, "Stream \"%s\" is a plain file", pp->promiser);
       
       if (stat(pp->promiser, &sb) == -1)
          {
          Log(LOG_LEVEL_INFO, "Unable to find stream '%s'. (stat: %s)", pp->promiser, GetErrorStr());
          YieldCurrentLock(thislock);
          MONITOR_RESTARTED = false;
          return NULL;
          }

       fin = safe_fopen(pp->promiser, "r");
       
       if (a.measure.growing)
          {
          filepos = Mon_RestoreFilePosition(pp->promiser);
          
          if (sb.st_size >= filepos)
             {
             fseek(fin, filepos, SEEK_SET);
             }
          }
       }
    else if (a.measure.stream_type && strcmp(a.measure.stream_type, "pipe") == 0)
       {
       Log(LOG_LEVEL_VERBOSE, "(Setting pipe umask to %jo)", (uintmax_t)a.contain.umask);
       maskval = umask(a.contain.umask);
       
       if (a.contain.umask == 0)
          {
          Log(LOG_LEVEL_VERBOSE, "Programming %s running with umask 0! Use umask= to set", pp->promiser);
          }
       
       
       // Mark: This is strange that we used these wrappers. Currently no way of setting these
       a.contain.owner = -1;
       a.contain.group = -1;
       a.contain.chdir = NULL;
       a.contain.chroot = NULL;
       // Mark: they were unset, and would fail for non-root(!)
       
       if (a.contain.shelltype == SHELL_TYPE_POWERSHELL)
          {
#ifdef __MINGW32__
          fin =
              cf_popen_powershell_setuid(pp->promiser, "r", a.contain.owner, a.contain.group, a.contain.chdir,
                                         a.contain.chroot, false);
#else // !__MINGW32__
          Log(LOG_LEVEL_ERR, "Powershell is only supported on Windows");
          YieldCurrentLock(thislock);
          MONITOR_RESTARTED = false;
          return NULL;
#endif // !__MINGW32__
          }
       else if (a.contain.shelltype == SHELL_TYPE_USE)
          {
          fin = cf_popen_shsetuid(pp->promiser, "r", a.contain.owner, a.contain.group, a.contain.chdir, a.contain.chroot, false);
          }
       else
          {
          fin =
              cf_popensetuid(pp->promiser, "r", a.contain.owner, a.contain.group, a.contain.chdir,
                             a.contain.chroot, false);
          }
       }
    
    /* generic file stream */
    
    if (fin == NULL)
       {
       cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a,
            "Couldn't open pipe to command '%s'. (cf_popen: %s)", pp->promiser, GetErrorStr());
       *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL);
       YieldCurrentLock(thislock);
       MONITOR_RESTARTED = false;
       return ENTERPRISE_DATA[slot].output;
       }
    
    size_t line_size = CF_BUFSIZE;
    char *line = xmalloc(line_size);
    
    for (;;)
       {
       ssize_t res = CfReadLine(&line, &line_size, fin);
       if (res == -1)
          {
          if (!feof(fin))
             {
             cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_TIMEOUT, pp, a, "Sample stream '%s'. (fread: %s)",
                  pp->promiser, GetErrorStr());
             *result = PromiseResultUpdate(*result, PROMISE_RESULT_TIMEOUT);
             YieldCurrentLock(thislock);
             free(line);
             return ENTERPRISE_DATA[slot].output;
             }
          else
             {
             break;
             }
          }
       
       AppendItem(&(ENTERPRISE_DATA[slot].output), line, NULL);
       }
    
    free(line);
    
    if (a.measure.stream_type && strcmp(a.measure.stream_type, "file") == 0)
       {
       long fileptr = ftell(fin);
       
       fclose(fin);
       Mon_SaveFilePosition(pp->promiser, fileptr);
       }
    else if (a.measure.stream_type && strcmp(a.measure.stream_type, "pipe") == 0)
       {
       cf_pclose(fin);
       }
    }
 
 if (a.contain.timeout != 0)
    {
    alarm(0);
    signal(SIGALRM, SIG_DFL);
    }
 
 Log(LOG_LEVEL_INFO, "Collected sample of %s", pp->promiser);
 umask(maskval);
 YieldCurrentLock(thislock);
 MONITOR_RESTARTED = false;
 
 snprintf(eventname, CF_BUFSIZE - 1, "Sample(%s)", pp->promiser);
 EndMeasure(eventname, start);
 return ENTERPRISE_DATA[slot].output;
}

/************************************************************************************/

void HistoryUpdate(EvalContext *ctx, Averages newvals)
{
 CfLock thislock;
 time_t now = time(NULL);
 
/* We do this only once per hour - this should not be changed */
 
 Log(LOG_LEVEL_VERBOSE, "(Updating long-term history database)");
 
 Policy *history_db_policy = PolicyNew();
 Promise *pp = NULL;
 Bundle *bp = PolicyAppendBundle(history_db_policy, NamespaceDefault(), "history_db_bundle", "agent", NULL, NULL);
 PromiseType *tp = BundleAppendPromiseType(bp, "history_db");
 
 pp = PromiseTypeAppendPromise(tp, "the long term memory", (Rval) { NULL, RVAL_TYPE_NOPROMISEE }, NULL);
 assert(pp);
 
 TransactionContext tc =
     {
         .expireafter = 0,
         .ifelapsed = 59
     };
 
 thislock = AcquireLock(ctx, pp->promiser, VUQNAME, now, tc, pp, false);
 
 if (thislock.lock == NULL)
    {
    PolicyDestroy(history_db_policy);
    return;
    }
 
/* Refresh the class context of the agent */
 
 EvalContextClear(ctx);
 
 DetectEnvironment(ctx);
 time_t t = SetReferenceTime();
 UpdateTimeClasses(ctx, t);
 
 EvalContextHeapPersistentLoadAll(ctx);
 LoadSystemConstants(ctx);
 
 YieldCurrentLock(thislock);
 PolicyDestroy(history_db_policy);
 
 Mon_HistoryUpdate(CFSTARTTIME, &newvals); 
 Mon_DumpSlowlyVaryingObservations();

}

/************************************************************************************/

static Item *MonGetMeasurementStream(EvalContext *ctx, Attributes a, const Promise *pp, PromiseResult *result)
{
 int i;
 
 for (i = 0; i < CF_DUNBAR_WORK; i++)
    {
    if (ENTERPRISE_DATA[i].path == NULL)
       {
       break;
       }
    
    if (strcmp(ENTERPRISE_DATA[i].path, pp->promiser) == 0)
       {
       ENTERPRISE_DATA[i].output = MonReSample(ctx, i, a, pp, result);
       return ENTERPRISE_DATA[i].output;
       }
    }
 
 ENTERPRISE_DATA[i].path = xstrdup(pp->promiser);
 ENTERPRISE_DATA[i].output = MonReSample(ctx, i, a, pp, result);
 return ENTERPRISE_DATA[i].output;
}
Exemplo n.º 10
0
int OpenReceiverChannel(void)
{
    struct addrinfo *response, *ap;
    struct addrinfo query = {
        .ai_flags = AI_PASSIVE,
        .ai_family = AF_UNSPEC,
        .ai_socktype = SOCK_STREAM
    };

    /* Listen to INADDR(6)_ANY if BINDINTERFACE unset. */
    char *ptr = NULL;
    if (BINDINTERFACE[0] != '\0')
    {
        ptr = BINDINTERFACE;
    }

    /* Resolve listening interface. */
    if (getaddrinfo(ptr, STR_CFENGINEPORT, &query, &response) != 0)
    {
        Log(LOG_LEVEL_ERR, "DNS/service lookup failure. (getaddrinfo: %s)", GetErrorStr());
        return -1;
    }

    int sd = -1;
    for (ap = response; ap != NULL; ap = ap->ai_next)
    {
        if ((sd = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol)) == -1)
        {
            continue;
        }

        int yes = 1;
        if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR,
                       &yes, sizeof(yes)) == -1)
        {
            Log(LOG_LEVEL_ERR, "Socket option SO_REUSEADDR was not accepted. (setsockopt: %s)", GetErrorStr());
            exit(1);
        }

        struct linger cflinger = {
            .l_onoff = 1,
            .l_linger = 60
        };
        if (setsockopt(sd, SOL_SOCKET, SO_LINGER,
                       &cflinger, sizeof(cflinger)) == -1)
        {
            Log(LOG_LEVEL_ERR, "Socket option SO_LINGER was not accepted. (setsockopt: %s)", GetErrorStr());
            exit(1);
        }

        if (bind(sd, ap->ai_addr, ap->ai_addrlen) != -1)
        {
            if (LogGetGlobalLevel() >= LOG_LEVEL_DEBUG)
            {
                /* Convert IP address to string, no DNS lookup performed. */
                char txtaddr[CF_MAX_IP_LEN] = "";
                getnameinfo(ap->ai_addr, ap->ai_addrlen,
                            txtaddr, sizeof(txtaddr),
                            NULL, 0, NI_NUMERICHOST);
                Log(LOG_LEVEL_DEBUG, "Bound to address '%s' on '%s' = %d", txtaddr,
                    CLASSTEXT[VSYSTEMHARDCLASS], VSYSTEMHARDCLASS);
            }
            break;
        }
        else
        {
            Log(LOG_LEVEL_ERR, "Could not bind server address. (bind: %s)", GetErrorStr());
            cf_closesocket(sd);
        }
    }

    if (sd < 0)
    {
        Log(LOG_LEVEL_ERR, "Couldn't open/bind a socket");
        exit(1);
    }

    freeaddrinfo(response);
    return sd;
}

/*********************************************************************/
/* Level 3                                                           */
/*********************************************************************/

void CheckFileChanges(EvalContext *ctx, Policy **policy, GenericAgentConfig *config)
{
    Log(LOG_LEVEL_DEBUG, "Checking file updates for input file '%s'", config->input_file);

    if (NewPromiseProposals(ctx, config, InputFiles(ctx, *policy)))
    {
        Log(LOG_LEVEL_VERBOSE, "New promises detected...");

        if (CheckPromises(config))
        {
            Log(LOG_LEVEL_INFO, "Rereading policy file '%s'", config->input_file);

            /* Free & reload -- lock this to avoid access errors during reload */
            
            EvalContextHeapClear(ctx);

            DeleteItemList(IPADDRESSES);
            IPADDRESSES = NULL;

            DeleteItemList(SV.trustkeylist);
            DeleteItemList(SV.skipverify);
            DeleteItemList(SV.attackerlist);
            DeleteItemList(SV.nonattackerlist);
            DeleteItemList(SV.multiconnlist);

            DeleteAuthList(SV.admit);
            DeleteAuthList(SV.deny);

            DeleteAuthList(SV.varadmit);
            DeleteAuthList(SV.vardeny);

            DeleteAuthList(SV.roles);

            //DeleteRlist(VINPUTLIST); This is just a pointer, cannot free it

            ScopeDeleteAll();

            strcpy(VDOMAIN, "undefined.domain");
            POLICY_SERVER[0] = '\0';

            SV.admit = NULL;
            SV.admittop = NULL;

            SV.varadmit = NULL;
            SV.varadmittop = NULL;

            SV.deny = NULL;
            SV.denytop = NULL;

            SV.vardeny = NULL;
            SV.vardenytop = NULL;

            SV.roles = NULL;
            SV.rolestop = NULL;

            SV.trustkeylist = NULL;
            SV.skipverify = NULL;
            SV.attackerlist = NULL;
            SV.nonattackerlist = NULL;
            SV.multiconnlist = NULL;

            PolicyDestroy(*policy);
            *policy = NULL;

            {
                char *existing_policy_server = ReadPolicyServerFile(GetWorkDir());
                SetPolicyServer(ctx, existing_policy_server);
                free(existing_policy_server);
            }

            GetNameInfo3(ctx, AGENT_TYPE_SERVER);
            GetInterfacesInfo(ctx, AGENT_TYPE_SERVER);
            Get3Environment(ctx, AGENT_TYPE_SERVER);
            BuiltinClasses(ctx);
            OSClasses(ctx);
            KeepHardClasses(ctx);

            EvalContextHeapAddHard(ctx, CF_AGENTTYPES[config->agent_type]);

            SetReferenceTime(ctx, true);
            *policy = GenericAgentLoadPolicy(ctx, config);
            KeepPromises(ctx, *policy, config);
            Summarize();

        }
        else
        {
            Log(LOG_LEVEL_INFO, "File changes contain errors -- ignoring");
            PROMISETIME = time(NULL);
        }
    }
    else
    {
        Log(LOG_LEVEL_DEBUG, "No new promises found");
    }
}
Exemplo n.º 11
0
void GenericInitialize(int argc,char **argv,char *agents)

{ enum cfagenttype ag = Agent2Type(agents);
  char vbuff[CF_BUFSIZE];
  int ok = false;

#ifdef HAVE_NOVA
CF_DEFAULT_DIGEST = cf_sha256;
CF_DEFAULT_DIGEST_LEN = CF_SHA256_LEN;
#else
CF_DEFAULT_DIGEST = cf_md5;
CF_DEFAULT_DIGEST_LEN = CF_MD5_LEN;
#endif
 
InitializeGA(argc,argv);

SetReferenceTime(true);
SetStartTime(false);
SetSignals();
SanitizeEnvironment();

strcpy(THIS_AGENT,CF_AGENTTYPES[ag]);
NewClass(THIS_AGENT);
THIS_AGENT_TYPE = ag;

// need scope sys to set vars in expiry function
SetNewScope("sys");

if (EnterpriseExpiry())
   {
   CfOut(cf_error,"","Cfengine - autonomous configuration engine. This enterprise license is invalid.\n");
   exit(1);
   }

if (AM_NOVA)
   {
   CfOut(cf_verbose,""," -> This is CFE Nova\n");
   }

if (AM_CONSTELLATION)
   {
   CfOut(cf_verbose,""," -> This is CFE Constellation\n");
   }

NewScope("const");
NewScope("match");
NewScope("mon");
GetNameInfo3();
CfGetInterfaceInfo(ag);

if (ag != cf_know)
   {
   Get3Environment();
   BuiltinClasses();
   OSClasses();
   }

LoadPersistentContext();
LoadSystemConstants();

snprintf(vbuff,CF_BUFSIZE,"control_%s",THIS_AGENT);
SetNewScope(vbuff);
NewScope("this");
NewScope("match");

if (BOOTSTRAP)
   {
   CheckAutoBootstrap();
   }
else
   {
   if (strlen(POLICY_SERVER) > 0)
      {
      CfOut(cf_verbose,""," -> Found a policy server (hub) on %s",POLICY_SERVER);
      }
   else
      {
      CfOut(cf_verbose,""," -> No policy server (hub) watch yet registered");
      }
   }

SetPolicyServer(POLICY_SERVER);

if (ag != cf_keygen)
   {
   if (!MissingInputFile())
      {
      bool check_promises = false;

      if (SHOWREPORTS)
         {
         check_promises = true;
         CfOut(cf_verbose, "", " -> Reports mode is enabled, force-validating policy");
         }
      if (IsFileOutsideDefaultRepository(VINPUTFILE))
         {
         check_promises = true;
         CfOut(cf_verbose, "", " -> Input file is outside default repository, validating it");
         }
      if (NewPromiseProposals())
         {
         check_promises = true;
         CfOut(cf_verbose, "", " -> Input file is changed since last validation, validating it");
         }

      if (check_promises)
         {
         ok = CheckPromises(ag);
         if (BOOTSTRAP && !ok)
            {
            CfOut(cf_verbose, "", " -> Policy is not valid, but proceeding with bootstrap");
            ok = true;
            }
         }
      else
         {
         CfOut(cf_verbose, "", " -> Policy is already validated");
         ok = true;
         }
      }

   if (ok)
      {
      ReadPromises(ag,agents);
      }
   else
      {
      CfOut(cf_error,"","cf-agent was not able to get confirmation of promises from cf-promises, so going to failsafe\n");
      snprintf(VINPUTFILE,CF_BUFSIZE-1,"failsafe.cf");
      ReadPromises(ag,agents);
      }
   
   if (SHOWREPORTS)
      {
      CompilationReport(VINPUTFILE);
      }

   CheckLicenses();
   }

XML = 0;
}
Exemplo n.º 12
0
void CheckOpts(int argc,char **argv)

{ extern char *optarg;
 int optindex = 0;
 int c;

umask(077);
sprintf(VPREFIX,"cfenvd"); 
openlog(VPREFIX,LOG_PID|LOG_NOWAIT|LOG_ODELAY,LOG_DAEMON);

strcpy(CFLOCK,"cfenvd");

SetContext("cfenvd");


IGNORELOCK = false; 
OUTPUT[0] = '\0';

while ((c=getopt_long(argc,argv,"d:vhHFVT",CFDENVOPTIONS,&optindex)) != EOF)
  {
  switch ((char) c)
      {
      case 'd': 

                switch ((optarg==NULL)?3:*optarg)
                   {
                   case '1': D1 = true;
                             break;
                   case '2': D2 = true;
                             break;
                   default:  DEBUG = true;
                             break;
                   }
  
                NO_FORK = true;
                printf("cfenvd: Debug mode: running in foreground\n");
                break;

      case 'v': VERBOSE = true;
         break;

      case 'V': printf("GNU %s-%s daemon\n%s\n",PACKAGE,VERSION,COPYRIGHT);
         printf("This program is covered by the GNU Public License and may be\n");
         printf("copied free of charge. No warrenty is implied.\n\n");
         exit(0);
         break;

      case 'F': NO_FORK = true;
         break;

      case 'H': HISTO = true;
         break;

      case 'T': TCPDUMP = true;
                break;
  
      default:  Syntax();
                exit(1);

      }
   }

LOGGING = true;                    /* Do output to syslog */

SetReferenceTime(false);
SetStartTime(false);
SetSignals();
signal (SIGTERM,HandleSignal);                   /* Signal Handler */
signal (SIGHUP,HandleSignal);
signal (SIGINT,HandleSignal);
signal (SIGPIPE,HandleSignal);
signal (SIGSEGV,HandleSignal);
signal (SIGUSR1,HandleSignal);
signal (SIGUSR2,HandleSignal);
}
Exemplo n.º 13
0
static bool ScheduleRun(Policy **policy, ExecConfig *exec_config, const ReportContext *report_context)
{
    Item *ip;

    CfOut(cf_verbose, "", "Sleeping...\n");
    sleep(CFPULSETIME);         /* 1 Minute resolution is enough */

// recheck license (in case of license updates or expiry)

    if (EnterpriseExpiry())
    {
        CfOut(cf_error, "", "Cfengine - autonomous configuration engine. This enterprise license is invalid.\n");
        exit(1);
    }

    /*
     * FIXME: this logic duplicates the one from cf-serverd.c. Unify ASAP.
     */

    if (CheckNewPromises(report_context) == RELOAD_FULL)
    {
        /* Full reload */

        CfOut(cf_inform, "", "Re-reading promise file %s..\n", VINPUTFILE);

        DeleteAlphaList(&VHEAP);
        InitAlphaList(&VHEAP);
        DeleteAlphaList(&VHARDHEAP);
        InitAlphaList(&VHARDHEAP);
        DeleteAlphaList(&VADDCLASSES);
        InitAlphaList(&VADDCLASSES);

        DeleteItemList(IPADDRESSES);
        IPADDRESSES = NULL;

        DeleteItemList(VNEGHEAP);

        DeleteAllScope();

        strcpy(VDOMAIN, "undefinded.domain");
        POLICY_SERVER[0] = '\0';

        VNEGHEAP = NULL;
        VINPUTLIST = NULL;

        PolicyDestroy(*policy);
        *policy = NULL;

        ERRORCOUNT = 0;

        NewScope("sys");

        SetPolicyServer(POLICY_SERVER);
        NewScalar("sys", "policy_hub", POLICY_SERVER, cf_str);

        NewScope("const");
        NewScope("this");
        NewScope("mon");
        NewScope("control_server");
        NewScope("control_common");
        NewScope("remote_access");

        GetNameInfo3();
        GetInterfacesInfo(AGENT_TYPE_EXECUTOR);
        Get3Environment();
        BuiltinClasses();
        OSClasses();

        HardClass(CF_AGENTTYPES[THIS_AGENT_TYPE]);

        SetReferenceTime(true);

        GenericAgentConfig config = {
            .bundlesequence = NULL
        };

        *policy = ReadPromises(AGENT_TYPE_EXECUTOR, CF_EXECC, config, report_context);
        KeepPromises(*policy, exec_config);
    }
Exemplo n.º 14
0
static bool ScheduleRun(Policy **policy, GenericAgentConfig *config, ExecConfig *exec_config, const ReportContext *report_context)
{
    Item *ip;

    CfOut(OUTPUT_LEVEL_VERBOSE, "", "Sleeping...\n");
    sleep(CFPULSETIME);         /* 1 Minute resolution is enough */

// recheck license (in case of license updates or expiry)

    if (EnterpriseExpiry())
    {
        CfOut(OUTPUT_LEVEL_ERROR, "", "Cfengine - autonomous configuration engine. This enterprise license is invalid.\n");
        exit(1);
    }

    /*
     * FIXME: this logic duplicates the one from cf-serverd.c. Unify ASAP.
     */

    if (CheckNewPromises(config->input_file, InputFiles(*policy), report_context) == RELOAD_FULL)
    {
        /* Full reload */

        CfOut(OUTPUT_LEVEL_INFORM, "", "Re-reading promise file %s..\n", config->input_file);

        DeleteAlphaList(&VHEAP);
        InitAlphaList(&VHEAP);
        DeleteAlphaList(&VHARDHEAP);
        InitAlphaList(&VHARDHEAP);
        DeleteAlphaList(&VADDCLASSES);
        InitAlphaList(&VADDCLASSES);

        DeleteItemList(IPADDRESSES);
        IPADDRESSES = NULL;

        DeleteItemList(VNEGHEAP);

        DeleteAllScope();

        strcpy(VDOMAIN, "undefinded.domain");
        POLICY_SERVER[0] = '\0';

        VNEGHEAP = NULL;

        PolicyDestroy(*policy);
        *policy = NULL;

        ERRORCOUNT = 0;

        NewScope("sys");

        SetPolicyServer(POLICY_SERVER);
        NewScalar("sys", "policy_hub", POLICY_SERVER, DATA_TYPE_STRING);

        NewScope("const");
        NewScope("this");
        NewScope("mon");
        NewScope("control_server");
        NewScope("control_common");
        NewScope("remote_access");

        GetNameInfo3();
        GetInterfacesInfo(AGENT_TYPE_EXECUTOR);
        Get3Environment();
        BuiltinClasses();
        OSClasses();

        HardClass(CF_AGENTTYPES[THIS_AGENT_TYPE]);

        SetReferenceTime(true);

        GenericAgentConfigSetBundleSequence(config, NULL);

        *policy = GenericAgentLoadPolicy(AGENT_TYPE_EXECUTOR, config, report_context);
        KeepPromises(*policy, exec_config);
    }
    else
    {
        /* Environment reload */

        DeleteAlphaList(&VHEAP);
        InitAlphaList(&VHEAP);
        DeleteAlphaList(&VADDCLASSES);
        InitAlphaList(&VADDCLASSES);
        DeleteAlphaList(&VHARDHEAP);
        InitAlphaList(&VHARDHEAP);

        DeleteItemList(IPADDRESSES);
        IPADDRESSES = NULL;


        DeleteScope("this");
        DeleteScope("mon");
        DeleteScope("sys");
        NewScope("this");
        NewScope("mon");
        NewScope("sys");

        GetInterfacesInfo(AGENT_TYPE_EXECUTOR);
        Get3Environment();
        BuiltinClasses();
        OSClasses();
        SetReferenceTime(true);
    }

    for (ip = SCHEDULE; ip != NULL; ip = ip->next)
    {
        CfOut(OUTPUT_LEVEL_VERBOSE, "", "Checking schedule %s...\n", ip->name);

        if (IsDefinedClass(ip->name, NULL))
        {
            CfOut(OUTPUT_LEVEL_VERBOSE, "", "Waking up the agent at %s ~ %s \n", cf_ctime(&CFSTARTTIME), ip->name);
            return true;
        }
    }

    CfOut(OUTPUT_LEVEL_VERBOSE, "", "Nothing to do at %s\n", cf_ctime(&CFSTARTTIME));
    return false;
}
Exemplo n.º 15
0
void CheckFileChanges(EvalContext *ctx, Policy **policy, GenericAgentConfig *config, time_t *last_policy_reload)
{
    time_t validated_at;

    Log(LOG_LEVEL_DEBUG, "Checking file updates for input file '%s'", config->input_file);

    validated_at = ReadTimestampFromPolicyValidatedMasterfiles(config);

    if (*last_policy_reload < validated_at)
    {
        *last_policy_reload = validated_at;

        Log(LOG_LEVEL_VERBOSE, "New promises detected...");

        if (GenericAgentArePromisesValid(config))
        {
            Log(LOG_LEVEL_INFO, "Rereading policy file '%s'", config->input_file);

            /* Free & reload -- lock this to avoid access errors during reload */

            EvalContextClear(ctx);

            free(SV.allowciphers);
            SV.allowciphers = NULL;

            DeleteItemList(SV.trustkeylist);
            DeleteItemList(SV.attackerlist);
            DeleteItemList(SV.nonattackerlist);
            DeleteItemList(SV.multiconnlist);

            DeleteAuthList(&SV.admit, &SV.admittail);
            DeleteAuthList(&SV.deny, &SV.denytail);

            DeleteAuthList(&SV.varadmit, &SV.varadmittail);
            DeleteAuthList(&SV.vardeny, &SV.vardenytail);

            DeleteAuthList(&SV.roles, &SV.rolestail);

            strcpy(VDOMAIN, "undefined.domain");

            SV.trustkeylist = NULL;
            SV.attackerlist = NULL;
            SV.nonattackerlist = NULL;
            SV.multiconnlist = NULL;

            acl_Free(paths_acl);    paths_acl = NULL;
            acl_Free(classes_acl);  classes_acl = NULL;
            acl_Free(vars_acl);     vars_acl = NULL;
            acl_Free(literals_acl); literals_acl = NULL;
            acl_Free(query_acl);    query_acl = NULL;

            StringMapDestroy(SV.path_shortcuts);
            SV.path_shortcuts = NULL;

            PolicyDestroy(*policy);
            *policy = NULL;

            {
                char *existing_policy_server = ReadPolicyServerFile(GetWorkDir());
                SetPolicyServer(ctx, existing_policy_server);
                free(existing_policy_server);
            }
            UpdateLastPolicyUpdateTime(ctx);

            DetectEnvironment(ctx);
            KeepHardClasses(ctx);

            EvalContextClassPutHard(ctx, CF_AGENTTYPES[AGENT_TYPE_SERVER], "cfe_internal,source=agent");

            time_t t = SetReferenceTime();
            UpdateTimeClasses(ctx, t);
            *policy = GenericAgentLoadPolicy(ctx, config);
            KeepPromises(ctx, *policy, config);
            Summarize();
        }
        else
        {
            Log(LOG_LEVEL_INFO, "File changes contain errors -- ignoring");
        }
    }
    else
    {
        Log(LOG_LEVEL_DEBUG, "No new promises found");
    }
}
Exemplo n.º 16
0
static bool ScheduleRun(EvalContext *ctx, Policy **policy, GenericAgentConfig *config, ExecConfig *exec_config)
{
    CfOut(OUTPUT_LEVEL_VERBOSE, "", "Sleeping for pulse time %d seconds...\n", CFPULSETIME);
    sleep(CFPULSETIME);         /* 1 Minute resolution is enough */

    /*
     * FIXME: this logic duplicates the one from cf-serverd.c. Unify ASAP.
     */

    if (CheckNewPromises(ctx, config, InputFiles(ctx, *policy)) == RELOAD_FULL)
    {
        /* Full reload */

        CfOut(OUTPUT_LEVEL_INFORM, "", "Re-reading promise file %s..\n", config->input_file);

        EvalContextHeapClear(ctx);

        DeleteItemList(IPADDRESSES);
        IPADDRESSES = NULL;

        ScopeDeleteAll();

        strcpy(VDOMAIN, "undefined.domain");
        POLICY_SERVER[0] = '\0';

        PolicyDestroy(*policy);
        *policy = NULL;

        SetPolicyServer(ctx, POLICY_SERVER);
        ScopeNewSpecialScalar(ctx, "sys", "policy_hub", POLICY_SERVER, DATA_TYPE_STRING);

        GetNameInfo3(ctx, AGENT_TYPE_EXECUTOR);
        GetInterfacesInfo(ctx, AGENT_TYPE_EXECUTOR);
        Get3Environment(ctx, AGENT_TYPE_EXECUTOR);
        BuiltinClasses(ctx);
        OSClasses(ctx);

        EvalContextHeapAddHard(ctx, CF_AGENTTYPES[AGENT_TYPE_EXECUTOR]);

        SetReferenceTime(ctx, true);

        GenericAgentConfigSetBundleSequence(config, NULL);

        *policy = GenericAgentLoadPolicy(ctx, config);
        ExecConfigUpdate(ctx, *policy, exec_config);

        SetFacility(exec_config->log_facility);
    }
    else
    {
        /* Environment reload */

        EvalContextHeapClear(ctx);

        DeleteItemList(IPADDRESSES);
        IPADDRESSES = NULL;

        ScopeClear("this");
        ScopeClear("mon");
        ScopeClear("sys");

        GetInterfacesInfo(ctx, AGENT_TYPE_EXECUTOR);
        Get3Environment(ctx, AGENT_TYPE_EXECUTOR);
        BuiltinClasses(ctx);
        OSClasses(ctx);
        SetReferenceTime(ctx, true);
    }

    {
        StringSetIterator it = StringSetIteratorInit(exec_config->schedule);
        const char *time_context = NULL;
        while ((time_context = StringSetIteratorNext(&it)))
        {
            if (IsDefinedClass(ctx, time_context, NULL))
            {
                CfOut(OUTPUT_LEVEL_VERBOSE, "", "Waking up the agent at %s ~ %s \n", cf_ctime(&CFSTARTTIME), time_context);
                return true;
            }
        }
    }

    CfOut(OUTPUT_LEVEL_VERBOSE, "", "Nothing to do at %s\n", cf_ctime(&CFSTARTTIME));
    return false;
}
Exemplo n.º 17
0
int OpenReceiverChannel(void)
{
    struct addrinfo *response, *ap;
    struct addrinfo query = {
        .ai_flags = AI_PASSIVE,
        .ai_family = AF_UNSPEC,
        .ai_socktype = SOCK_STREAM
    };

    /* Listen to INADDR(6)_ANY if BINDINTERFACE unset. */
    char *ptr = NULL;
    if (BINDINTERFACE[0] != '\0')
    {
        ptr = BINDINTERFACE;
    }

    char servname[10];
    snprintf(servname, 10, "%d", CFENGINE_PORT);

    /* Resolve listening interface. */
    if (getaddrinfo(ptr, servname, &query, &response) != 0)
    {
        Log(LOG_LEVEL_ERR, "DNS/service lookup failure. (getaddrinfo: %s)", GetErrorStr());
        return -1;
    }

    int sd = -1;
    for (ap = response; ap != NULL; ap = ap->ai_next)
    {
        if ((sd = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol)) == -1)
        {
            continue;
        }

        int yes = 1;
        if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR,
                       &yes, sizeof(yes)) == -1)
        {
            Log(LOG_LEVEL_ERR, "Socket option SO_REUSEADDR was not accepted. (setsockopt: %s)", GetErrorStr());
            exit(1);
        }

        struct linger cflinger = {
            .l_onoff = 1,
            .l_linger = 60
        };
        if (setsockopt(sd, SOL_SOCKET, SO_LINGER,
                       &cflinger, sizeof(cflinger)) == -1)
        {
            Log(LOG_LEVEL_ERR, "Socket option SO_LINGER was not accepted. (setsockopt: %s)", GetErrorStr());
            exit(1);
        }

        if (bind(sd, ap->ai_addr, ap->ai_addrlen) != -1)
        {
            if (LogGetGlobalLevel() >= LOG_LEVEL_DEBUG)
            {
                /* Convert IP address to string, no DNS lookup performed. */
                char txtaddr[CF_MAX_IP_LEN] = "";
                getnameinfo(ap->ai_addr, ap->ai_addrlen,
                            txtaddr, sizeof(txtaddr),
                            NULL, 0, NI_NUMERICHOST);
                Log(LOG_LEVEL_DEBUG, "Bound to address '%s' on '%s' = %d", txtaddr,
                    CLASSTEXT[VSYSTEMHARDCLASS], VSYSTEMHARDCLASS);
            }
            break;
        }
        else
        {
            Log(LOG_LEVEL_ERR, "Could not bind server address. (bind: %s)", GetErrorStr());
            cf_closesocket(sd);
        }
    }

    if (sd < 0)
    {
        Log(LOG_LEVEL_ERR, "Couldn't open/bind a socket");
        exit(1);
    }

    freeaddrinfo(response);
    return sd;
}

/*********************************************************************/
/* Level 3                                                           */
/*********************************************************************/

void CheckFileChanges(EvalContext *ctx, Policy **policy, GenericAgentConfig *config, time_t *last_policy_reload)
{
    time_t validated_at;

    Log(LOG_LEVEL_DEBUG, "Checking file updates for input file '%s'", config->input_file);

    validated_at = ReadTimestampFromPolicyValidatedMasterfiles(config);

    if (*last_policy_reload < validated_at)
    {
        *last_policy_reload = validated_at;

        Log(LOG_LEVEL_VERBOSE, "New promises detected...");

        if (GenericAgentArePromisesValid(config))
        {
            Log(LOG_LEVEL_INFO, "Rereading policy file '%s'", config->input_file);

            /* Free & reload -- lock this to avoid access errors during reload */
            
            EvalContextClear(ctx);

            free(SV.allowciphers);
            SV.allowciphers = NULL;

            DeleteItemList(SV.trustkeylist);
            DeleteItemList(SV.attackerlist);
            DeleteItemList(SV.nonattackerlist);
            DeleteItemList(SV.multiconnlist);

            DeleteAuthList(SV.admit);
            DeleteAuthList(SV.deny);

            DeleteAuthList(SV.varadmit);
            DeleteAuthList(SV.vardeny);

            DeleteAuthList(SV.roles);

            strcpy(VDOMAIN, "undefined.domain");

            SV.admit = NULL;
            SV.admittop = NULL;

            SV.varadmit = NULL;
            SV.varadmittop = NULL;

            SV.deny = NULL;
            SV.denytop = NULL;

            SV.vardeny = NULL;
            SV.vardenytop = NULL;

            SV.roles = NULL;
            SV.rolestop = NULL;

            SV.trustkeylist = NULL;
            SV.attackerlist = NULL;
            SV.nonattackerlist = NULL;
            SV.multiconnlist = NULL;

            PolicyDestroy(*policy);
            *policy = NULL;

            {
                char *existing_policy_server = ReadPolicyServerFile(GetWorkDir());
                SetPolicyServer(ctx, existing_policy_server);
                free(existing_policy_server);
            }
            UpdateLastPolicyUpdateTime(ctx);

            DetectEnvironment(ctx);
            KeepHardClasses(ctx);

            EvalContextClassPutHard(ctx, CF_AGENTTYPES[config->agent_type], "cfe_internal,source=agent");

            time_t t = SetReferenceTime();
            UpdateTimeClasses(ctx, t);
            *policy = GenericAgentLoadPolicy(ctx, config);
            KeepPromises(ctx, *policy, config);
            Summarize();
        }
        else
        {
            Log(LOG_LEVEL_INFO, "File changes contain errors -- ignoring");
        }
    }
    else
    {
        Log(LOG_LEVEL_DEBUG, "No new promises found");
    }
}