Exemple #1
0
void LoadSystemConstants(EvalContext *ctx)
{
    ScopeNewSpecialScalar(ctx, "const", "dollar", "$", DATA_TYPE_STRING);
    ScopeNewSpecialScalar(ctx, "const", "n", "\n", DATA_TYPE_STRING);
    ScopeNewSpecialScalar(ctx, "const", "r", "\r", DATA_TYPE_STRING);
    ScopeNewSpecialScalar(ctx, "const", "t", "\t", DATA_TYPE_STRING);
    ScopeNewSpecialScalar(ctx, "const", "endl", "\n", DATA_TYPE_STRING);
/* NewScalar("const","0","\0",cf_str);  - this cannot work */

}
Exemple #2
0
void VerifyEnvironmentsPromise(EvalContext *ctx, Promise *pp)
{
    Attributes a = { {0} };
    CfLock thislock;
    Promise *pexp;

    a = GetEnvironmentsAttributes(ctx, pp);

    if (EnvironmentsSanityChecks(a, pp))
    {
        thislock = AcquireLock(ctx, "virtual", VUQNAME, CFSTARTTIME, a.transaction, pp, false);

        if (thislock.lock == NULL)
        {
            return;
        }

        PromiseBanner(pp);
        ScopeNewSpecialScalar(ctx, "this", "promiser", pp->promiser, DATA_TYPE_STRING);

        pexp = ExpandDeRefPromise(ctx, "this", pp);
        VerifyEnvironments(ctx, a, pp);
        PromiseDestroy(pexp);
    }

    YieldCurrentLock(thislock);
}
Exemple #3
0
static void VerifyProcesses(EvalContext *ctx, Attributes a, Promise *pp)
{
    CfLock thislock;
    char lockname[CF_BUFSIZE];

    if (a.restart_class)
    {
        snprintf(lockname, CF_BUFSIZE - 1, "proc-%s-%s", pp->promiser, a.restart_class);
    }
    else
    {
        snprintf(lockname, CF_BUFSIZE - 1, "proc-%s-norestart", pp->promiser);
    }

    thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, a.transaction, pp, false);

    if (thislock.lock == NULL)
    {
        return;
    }

    ScopeDeleteSpecialScalar("this", "promiser");
    ScopeNewSpecialScalar(ctx, "this", "promiser", pp->promiser, DATA_TYPE_STRING);
    PromiseBanner(pp);
    VerifyProcessOp(ctx, PROCESSTABLE, a, pp);
    ScopeDeleteSpecialScalar("this", "promiser");

    YieldCurrentLock(thislock);
}
Exemple #4
0
void ScopeNewList(EvalContext *ctx, VarRef lval, void *rval, DataType dt)
{
    assert(!ScopeIsReserved(lval.scope));
    if (ScopeIsReserved(lval.scope))
    {
        ScopeNewSpecialScalar(ctx, lval.scope, lval.lval, rval, dt);
    }
    Rval rvald;

    if (EvalContextVariableGet(ctx, lval, &rvald, NULL))
    {
        ScopeDeleteVariable(lval.scope, lval.lval);
    }

    EvalContextVariablePut(ctx, lval, (Rval) {rval, RVAL_TYPE_LIST }, dt);
}
Exemple #5
0
void ScopeNewScalar(EvalContext *ctx, VarRef lval, const char *rval, DataType dt)
{
    CfDebug("NewScalar(%s,%s,%s)\n", lval.scope, lval.lval, rval);
    assert(!ScopeIsReserved(lval.scope));
    if (ScopeIsReserved(lval.scope))
    {
        ScopeNewSpecialScalar(ctx, lval.scope, lval.lval, rval, dt);
    }

    Rval rvald;
    if (EvalContextVariableGet(ctx, lval, &rvald, NULL))
    {
        ScopeDeleteScalar(lval);
    }

/*
 * We know AddVariableHash does not change passed Rval structure or its
 * contents, but we have no easy way to express it in C type system, hence cast.
 */
    EvalContextVariablePut(ctx, lval, (Rval) {(char *) rval, RVAL_TYPE_SCALAR }, dt);
}
Exemple #6
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;
}
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)
    {
        CfOut(OUTPUT_LEVEL_ERROR, "getaddrinfo", "DNS/service lookup failure");
        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)
        {
            CfOut(OUTPUT_LEVEL_ERROR, "setsockopt",
                  "Socket option SO_REUSEADDR was not accepted");
            exit(1);
        }

        struct linger cflinger = {
            .l_onoff = 1,
            .l_linger = 60
        };
        if (setsockopt(sd, SOL_SOCKET, SO_LINGER,
                       &cflinger, sizeof(cflinger)) == -1)
        {
            CfOut(OUTPUT_LEVEL_ERROR, "setsockopt",
                  "Socket option SO_LINGER was not accepted");
            exit(1);
        }

        if (bind(sd, ap->ai_addr, ap->ai_addrlen) != -1)
        {
            if (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);
                printf("Bound to address %s on %s=%d\n", txtaddr,
                       CLASSTEXT[VSYSTEMHARDCLASS], VSYSTEMHARDCLASS);
            }
            break;
        }
        else
        {
            CfOut(OUTPUT_LEVEL_ERROR, "bind", "Could not bind server address");
            cf_closesocket(sd);
        }
    }

    if (sd < 0)
    {
        CfOut(OUTPUT_LEVEL_ERROR, "", "Couldn't open/bind a socket\n");
        exit(1);
    }

    freeaddrinfo(response);
    return sd;
}

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

void CheckFileChanges(EvalContext *ctx, Policy **policy, GenericAgentConfig *config)
{
    CfDebug("Checking file updates on %s\n", config->input_file);

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

        if (CheckPromises(config))
        {
            CfOut(OUTPUT_LEVEL_INFORM, "", "Rereading config files %s..\n", 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;

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

            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
        {
            CfOut(OUTPUT_LEVEL_INFORM, "", " !! File changes contain errors -- ignoring");
            PROMISETIME = time(NULL);
        }
    }
    else
    {
        CfDebug(" -> No new promises found\n");
    }
}
Exemple #8
0
void SetPolicyServer(EvalContext *ctx, char *name)
/* 
 * If name contains a string, it's written to file,
 * if not, name is filled with the contents of file.
 */
{
    char file[CF_BUFSIZE];
    FILE *fout, *fin;
    char fileContents[CF_MAXVARSIZE] = { 0 };

    snprintf(file, CF_BUFSIZE - 1, "%s/policy_server.dat", CFWORKDIR);
    MapName(file);

    if ((fin = fopen(file, "r")) != NULL)
    {
        if (fscanf(fin, "%1023s", fileContents) != 1)
        {
            CfDebug("Couldn't read string from policy_server.dat");
        }
        fclose(fin);
    }

    // update file if different and we know what to put there

    if ((NULL_OR_EMPTY(name)) && (!NULL_OR_EMPTY(fileContents)))
    {
        snprintf(name, CF_MAXVARSIZE, "%s", fileContents);
    }
    else if ((!NULL_OR_EMPTY(name)) && (strcmp(name, fileContents) != 0))
    {
        if ((fout = fopen(file, "w")) == NULL)
        {
            CfOut(OUTPUT_LEVEL_ERROR, "fopen", "Unable to write policy server file! (%s)", file);
            return;
        }

        fprintf(fout, "%s", name);
        fclose(fout);
    }

    if (NULL_OR_EMPTY(name))
    {
        // avoids "Scalar item in servers => {  } in rvalue is out of bounds ..."
        // when NovaBase is checked with unprivileged (not bootstrapped) cf-promises 
        ScopeNewSpecialScalar(ctx, "sys", "policy_hub", "undefined", DATA_TYPE_STRING);
    }
    else
    {
        ScopeNewSpecialScalar(ctx, "sys", "policy_hub", name, DATA_TYPE_STRING);
    }

// Get the timestamp on policy update

    snprintf(file, CF_MAXVARSIZE, "%s/masterfiles/cf_promises_validated", CFWORKDIR);
    MapName(file);

    struct stat sb;
    
    if ((cfstat(file, &sb)) != 0)
    {
        return;
    }
    
    char timebuf[26];
    cf_strtimestamp_local(sb.st_mtime, timebuf);
    
    ScopeNewSpecialScalar(ctx, "sys", "last_policy_update", timebuf, DATA_TYPE_STRING);
}