Esempio n. 1
0
static void KeepServerPromise(Promise *pp)
{
    char *sp = NULL;

    if (!IsDefinedClass(pp->classes))
    {
        CfOut(cf_verbose, "", "Skipping whole promise, as context is %s\n", pp->classes);
        return;
    }

    if (VarClassExcluded(pp, &sp))
    {
        CfOut(cf_verbose, "", "\n");
        CfOut(cf_verbose, "", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . \n");
        CfOut(cf_verbose, "", "Skipping whole next promise (%s), as var-context %s is not relevant\n", pp->promiser,
              sp);
        CfOut(cf_verbose, "", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . \n");
        return;
    }

    if (strcmp(pp->agentsubtype, "classes") == 0)
    {
        KeepClassContextPromise(pp);
        return;
    }

    sp = (char *) GetConstraintValue("resource_type", pp, CF_SCALAR);

    if (strcmp(pp->agentsubtype, "access") == 0 && sp && strcmp(sp, "literal") == 0)
    {
        KeepLiteralAccessPromise(pp, "literal");
        return;
    }

    if (strcmp(pp->agentsubtype, "access") == 0 && sp && strcmp(sp, "query") == 0)
    {
        KeepQueryAccessPromise(pp, "query");
        return;
    }

    if (strcmp(pp->agentsubtype, "access") == 0 && sp && strcmp(sp, "context") == 0)
    {
        KeepLiteralAccessPromise(pp, "context");
        return;
    }

/* Default behaviour is file access */

    if (strcmp(pp->agentsubtype, "access") == 0)
    {
        KeepFileAccessPromise(pp);
        return;
    }

    if (strcmp(pp->agentsubtype, "roles") == 0)
    {
        KeepServerRolePromise(pp);
        return;
    }
}
Esempio n. 2
0
void DefaultVarPromise(Promise *pp)

{
    char *regex = GetConstraintValue("if_match_regex", pp, CF_SCALAR);
    Rval rval;
    enum cfdatatype dt;
    Rlist *rp;
    bool okay = true;

    dt = GetVariable("this", pp->promiser, &rval);

    switch (dt)
    {
    case cf_str:
    case cf_int:
    case cf_real:

        if (regex && !FullTextMatch(regex,rval.item))
        {
            return;
        }

        if (regex == NULL)
        {
            return;
        }

        break;

    case cf_slist:
    case cf_ilist:
    case cf_rlist:

        if (regex)
        {
            for (rp = (Rlist *) rval.item; rp != NULL; rp = rp->next)
            {
                if (FullTextMatch(regex,rp->item))
                {
                    okay = false;
                    break;
                }
            }

            if (okay)
            {
                return;
            }
        }

        break;

    default:
        break;
    }

    DeleteScalar(pp->bundle, pp->promiser);
    ConvergeVarHashPromise(pp->bundle, pp, true);
}
Esempio n. 3
0
void EndMeasurePromise(struct timespec start, Promise *pp)
{
    char id[CF_BUFSIZE], *mid = NULL;

    mid = GetConstraintValue("measurement_class", pp, CF_SCALAR);

    if (mid)
    {
        snprintf(id, CF_BUFSIZE, "%s:%s:%.100s", (char *) mid, pp->agentsubtype, pp->promiser);
        Chop(id);
        EndMeasure(id, start);
    }
}
Esempio n. 4
0
void PromiseBanner(Promise *pp)
{
    char handle[CF_MAXVARSIZE];
    const char *sp;

    if ((sp = GetConstraintValue("handle", pp, RVAL_TYPE_SCALAR)) || (sp = PromiseID(pp)))
    {
        strncpy(handle, sp, CF_MAXVARSIZE - 1);
    }
    else
    {
        strcpy(handle, "(enterprise only)");
    }

    CfOut(cf_verbose, "", "\n");
    CfOut(cf_verbose, "", "    .........................................................\n");

    if (VERBOSE || DEBUG)
    {
        printf("%s>     Promise's handle: %s\n", VPREFIX, handle);
        printf("%s>     Promise made by: \"%s\"", VPREFIX, pp->promiser);
    }

    if (pp->promisee.item)
    {
        if (VERBOSE)
        {
            printf("\n%s>     Promise made to (stakeholders): ", VPREFIX);
            ShowRval(stdout, pp->promisee);
        }
    }

    if (VERBOSE)
    {
        printf("\n");
    }

    if (pp->ref)
    {
        CfOut(cf_verbose, "", "\n");
        CfOut(cf_verbose, "", "    Comment:  %s\n", pp->ref);
    }

    CfOut(cf_verbose, "", "    .........................................................\n");
    CfOut(cf_verbose, "", "\n");
}
Esempio n. 5
0
void KeepLiteralAccessPromise(Promise *pp, char *type)
{
    Constraint *cp;
    Rlist *rp;
    Auth *ap, *dp;
    char *handle = GetConstraintValue("handle", pp, CF_SCALAR);

    if (handle == NULL)
    {
        CfOut(cf_error, "", "Access to literal server data requires you to define a promise handle for reference");
        return;
    }

    if (!GetAuthPath(handle, VARADMIT))
    {
        InstallServerAuthPath(handle, &VARADMIT, &VARADMITTOP);
    }

    RegisterLiteralServerData(handle, pp);

    if (!GetAuthPath(handle, VARDENY))
    {
        InstallServerAuthPath(handle, &VARDENY, &VARDENYTOP);
    }

    ap = GetAuthPath(handle, VARADMIT);
    dp = GetAuthPath(handle, VARDENY);

    if (strcmp(type, "literal") == 0)
    {
        ap->literal = true;
    }

    if (strcmp(type, "context") == 0)
    {
        ap->classpattern = true;
    }

    for (cp = pp->conlist; cp != NULL; cp = cp->next)
    {
        if (!IsDefinedClass(cp->classes))
        {
            continue;
        }

        switch (cp->rval.rtype)
        {
        case CF_SCALAR:

            if (strcmp(cp->lval, CF_REMACCESS_BODIES[cfs_encrypted].lval) == 0)
            {
                ap->encrypt = true;
            }

            break;

        case CF_LIST:

            for (rp = (Rlist *) cp->rval.item; rp != NULL; rp = rp->next)
            {
                if (strcmp(cp->lval, CF_REMACCESS_BODIES[cfs_admit].lval) == 0)
                {
                    PrependItem(&(ap->accesslist), rp->item, NULL);
                    continue;
                }

                if (strcmp(cp->lval, CF_REMACCESS_BODIES[cfs_deny].lval) == 0)
                {
                    PrependItem(&(dp->accesslist), rp->item, NULL);
                    continue;
                }

                if (strcmp(cp->lval, CF_REMACCESS_BODIES[cfs_maproot].lval) == 0)
                {
                    PrependItem(&(ap->maproot), rp->item, NULL);
                    continue;
                }
            }
            break;

        case CF_FNCALL:
            /* Shouldn't happen */
            break;
        }
    }
}
Esempio n. 6
0
int VerifyMethod(char *attrname, Attributes a, Promise *pp)
{
    Bundle *bp;
    void *vp;
    FnCall *fp;
    char method_name[CF_EXPANDSIZE];
    Rlist *params = NULL;
    int retval = false;
    CfLock thislock;
    char lockname[CF_BUFSIZE];

    if (a.havebundle)
    {
        if ((vp = GetConstraintValue(attrname, pp, CF_FNCALL)))
        {
            fp = (FnCall *) vp;
            ExpandScalar(fp->name, method_name);
            params = fp->args;
        }
        else if ((vp = GetConstraintValue(attrname, pp, CF_SCALAR)))
        {
            ExpandScalar((char *) vp, method_name);
            params = NULL;
        }
        else
        {
            return false;
        }
    }

    GetLockName(lockname, "method", pp->promiser, params);

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

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

    PromiseBanner(pp);

    if ((bp = GetBundle(method_name, "agent")))
    {
        char *bp_stack = THIS_BUNDLE;

        BannerSubBundle(bp, params);

        DeleteScope(bp->name);
        NewScope(bp->name);
        HashVariables(bp->name);

        AugmentScope(bp->name, bp->args, params);

        THIS_BUNDLE = bp->name;
        PushPrivateClassContext();

        retval = ScheduleAgentOperations(bp);

        PopPrivateClassContext();
        THIS_BUNDLE = bp_stack;

        if (retval)
        {
            cfPS(cf_verbose, CF_NOP, "", pp, a, " -> Method invoked successfully\n");
        }
        else
        {
            cfPS(cf_inform, CF_FAIL, "", pp, a, " !! Method could not be invoked successfully\n");
        }

        DeleteFromScope(bp->name, bp->args);
    }
    else
    {
        if (IsCf3VarString(method_name))
        {
            CfOut(cf_error, "",
                  " !! A variable seems to have been used for the name of the method. In this case, the promiser also needs to contain the uique name of the method");
        }
        if (bp && bp->name)
        {
            cfPS(cf_error, CF_FAIL, "", pp, a, " !! Method \"%s\" was used but was not defined!\n", bp->name);
        }
        else
        {
            cfPS(cf_error, CF_FAIL, "", pp, a,
                 " !! A method attempted to use a bundle \"%s\" that was apparently not defined!\n", method_name);
        }
    }

    YieldCurrentLock(thislock);
    return retval;
}
Esempio n. 7
0
static void DoVerifyServices(Attributes a, Promise *pp, const ReportContext *report_context)
{
    FnCall *default_bundle = NULL;
    Rlist *args = NULL;

// Need to set up the default service pack to eliminate syntax

    if (GetConstraintValue("service_bundle", pp, CF_SCALAR) == NULL)
    {
        switch (a.service.service_policy)
        {
        case cfsrv_start:
            AppendRlist(&args, pp->promiser, CF_SCALAR);
            AppendRlist(&args, "start", CF_SCALAR);
            break;

        case cfsrv_restart:
            AppendRlist(&args, pp->promiser, CF_SCALAR);
            AppendRlist(&args, "restart", CF_SCALAR);
            break;

        case cfsrv_reload:
            AppendRlist(&args, pp->promiser, CF_SCALAR);
            AppendRlist(&args, "restart", CF_SCALAR);
            break;
            
        case cfsrv_stop:
        case cfsrv_disable:
        default:
            AppendRlist(&args, pp->promiser, CF_SCALAR);
            AppendRlist(&args, "stop", CF_SCALAR);
            break;

        }

        default_bundle = NewFnCall("default:standard_services", args);

        ConstraintAppendToPromise(pp, "service_bundle", (Rval) {default_bundle, CF_FNCALL}, "any", false);
        a.havebundle = true;
    }

// Set $(this.service_policy) for flexible bundle adaptation

    switch (a.service.service_policy)
    {
    case cfsrv_start:
        NewScalar("this", "service_policy", "start", cf_str);
        break;

    case cfsrv_restart:
        NewScalar("this", "service_policy", "restart", cf_str);
        break;

    case cfsrv_reload:
        NewScalar("this", "service_policy", "reload", cf_str);
        break;
        
    case cfsrv_stop:
    case cfsrv_disable:
    default:
        NewScalar("this", "service_policy", "stop", cf_str);
        break;
    }

    if (default_bundle && GetBundle(PolicyFromPromise(pp), default_bundle->name, "agent") == NULL)
    {
        cfPS(cf_inform, CF_FAIL, "", pp, a, " !! Service %s could not be invoked successfully\n", pp->promiser);
    }

    if (!DONTDO)
    {
        VerifyMethod("service_bundle", a, pp, report_context);  // Send list of classes to set privately?
    }
}
Esempio n. 8
0
static void VerifyTopicPromise(Promise *pp)
{
    char id[CF_BUFSIZE];
    Attributes a = { {0} };
    Topic *tp = NULL, *otp;
    Rlist *rp, *rps, *contexts;
    char *handle = (char *) GetConstraintValue("handle", pp, CF_SCALAR);

    a = GetTopicsAttributes(pp);

    CfOut(cf_verbose, "", " -> Attempting to install topic %s::%s \n", pp->classes, pp->promiser);

// Add a standard reserved word

    contexts = SplitContextExpression(pp->classes, pp);

    for (rp = contexts; rp != NULL; rp = rp->next)
    {
        if ((tp = InsertTopic(pp->promiser, rp->item)) == NULL)
        {
            return;
        }

        CfOut(cf_verbose, "", " -> New topic promise for \"%s\" about context \"%s\"", pp->promiser, ScalarValue(rp));

        if (a.fwd_name && a.bwd_name)
        {
            AddTopicAssociation(tp, &(tp->associations), a.fwd_name, a.bwd_name, a.associates, true, rp->item,
                                pp->promiser);
        }

        // Handle all synonyms as associations

        if (a.synonyms)
        {
            for (rps = a.synonyms; rps != NULL; rps = rps->next)
            {
                otp = IdempInsertTopic(rps->item);
                CfOut(cf_verbose, "", " ---> %s is a synonym for %s", ScalarValue(rps), tp->topic_name);
            }

            AddTopicAssociation(tp, &(tp->associations), KM_SYNONYM, KM_SYNONYM, a.synonyms, true, rp->item,
                                pp->promiser);
        }

        // Handle all generalizations as associations

        if (a.general)
        {
            for (rps = a.general; rps != NULL; rps = rps->next)
            {
                otp = IdempInsertTopic(rps->item);
                CfOut(cf_verbose, "", " ---> %s is a generalization for %s", ScalarValue(rps), tp->topic_name);
            }

            AddTopicAssociation(tp, &(tp->associations), KM_GENERALIZES_B, KM_GENERALIZES_F, a.general, true, rp->item,
                                pp->promiser);
        }

        if (handle)
        {
            char synonym[CF_BUFSIZE];

            snprintf(synonym, CF_BUFSIZE - 1, "handles::%s", handle);
            otp = IdempInsertTopic(synonym);
            PrependRScalar(&(a.synonyms), otp->topic_name, CF_SCALAR);
        }

        // Treat comments as occurrences of information.

        if (pp->ref)
        {
            Rlist *list = NULL;

            snprintf(id, CF_MAXVARSIZE, "%s.%s", pp->classes, CanonifyName(pp->promiser));
            PrependRScalar(&list, "description", CF_SCALAR);
            AddOccurrence(&OCCURRENCES, pp->ref, list, cfk_literal, id);
            DeleteRlist(list);
        }

        if (handle)
        {
            Rlist *list = NULL;

            PrependRScalar(&list, handle, CF_SCALAR);
            AddTopicAssociation(tp, &(tp->associations), "is the promise of", "stands for", list, true, rp->item,
                                pp->promiser);
            DeleteRlist(list);
            list = NULL;
            snprintf(id, CF_MAXVARSIZE, "%s.%s", pp->classes, handle);
            PrependRScalar(&list, "description", CF_SCALAR);
            AddOccurrence(&OCCURRENCES, pp->ref, list, cfk_literal, id);
            DeleteRlist(list);
        }
    }

    DeleteRlist(contexts);
}
Esempio n. 9
0
void cfPS(enum cfreport level, char status, char *errstr, const Promise *pp, Attributes attr, char *fmt, ...)
{
    va_list ap;
    char buffer[CF_BUFSIZE], output[CF_BUFSIZE], *v, handle[CF_MAXVARSIZE];
    const char *sp;
    Item *ip, *mess = NULL;
    int verbose;
    Rval retval;

    if ((fmt == NULL) || (strlen(fmt) == 0))
    {
        return;
    }

    va_start(ap, fmt);
    vsnprintf(buffer, CF_BUFSIZE - 1, fmt, ap);
    va_end(ap);
    Chop(buffer);
    AppendItem(&mess, buffer, NULL);

    if ((errstr == NULL) || (strlen(errstr) > 0))
    {
        snprintf(output, CF_BUFSIZE - 1, " !!! System reports error for %s: \"%s\"", errstr, GetErrorStr());
        AppendItem(&mess, output, NULL);
    }

    if (level == cf_error)
    {
        if (GetVariable("control_common", "version", &retval) != cf_notype)
        {
            v = (char *) retval.item;
        }
        else
        {
            v = "not specified";
        }

        if ((sp = GetConstraintValue("handle", pp, CF_SCALAR)) || (sp = PromiseID(pp)))
        {
            strncpy(handle, sp, CF_MAXVARSIZE - 1);
        }
        else
        {
            strcpy(handle, "(unknown)");
        }

        if (INFORM || VERBOSE || DEBUG)
        {
            snprintf(output, CF_BUFSIZE - 1, "I: Report relates to a promise with handle \"%s\"", handle);
            AppendItem(&mess, output, NULL);
        }

        if (pp && pp->audit)
        {
            snprintf(output, CF_BUFSIZE - 1, "I: Made in version \'%s\' of \'%s\' near line %zu",
                     v, pp->audit->filename, pp->offset.line);
        }
        else
        {
            snprintf(output, CF_BUFSIZE - 1, "I: Promise is made internally by cfengine");
        }

        AppendItem(&mess, output, NULL);

        if (pp != NULL)
        {
            switch (pp->promisee.rtype)
            {
            case CF_SCALAR:
                snprintf(output, CF_BUFSIZE - 1, "I: The promise was made to: \'%s\'", (char *) pp->promisee.item);
                AppendItem(&mess, output, NULL);
                break;

            case CF_LIST:

                snprintf(output, CF_BUFSIZE - 1, "I: The promise was made to (stakeholders): ");
                PrintRlist(output+strlen(output), CF_BUFSIZE, (Rlist *)pp->promisee.item);
                AppendItem(&mess, output, NULL);
                break;
            }



            if (pp->ref)
            {
                snprintf(output, CF_BUFSIZE - 1, "I: Comment: %s\n", pp->ref);
                AppendItem(&mess, output, NULL);
            }
        }
    }

    verbose = (attr.transaction.report_level == cf_verbose) || VERBOSE;

    switch (level)
    {
    case cf_inform:

        if (INFORM || verbose || DEBUG || attr.transaction.report_level == cf_inform)
        {
            LogList(stdout, mess, verbose);
        }

        if (attr.transaction.log_level == cf_inform)
        {
            MakeLog(mess, level);
        }
        break;

    case cf_reporting:
    case cf_cmdout:

        if (attr.report.to_file)
        {
            FileReport(mess, verbose, attr.report.to_file);
        }
        else
        {
            LogList(stdout, mess, verbose);
        }

        if (attr.transaction.log_level == cf_inform)
        {
            MakeLog(mess, level);
        }
        break;

    case cf_verbose:

        if (verbose || DEBUG)
        {
            LogList(stdout, mess, verbose);
        }

        if (attr.transaction.log_level == cf_verbose)
        {
            MakeLog(mess, level);
        }

        break;

    case cf_error:

        if (attr.report.to_file)
        {
            FileReport(mess, verbose, attr.report.to_file);
        }
        else
        {
            LogList(stdout, mess, verbose);
        }

        if (attr.transaction.log_level == cf_error)
        {
            MakeLog(mess, level);
        }
        break;

    case cf_log:

        MakeLog(mess, level);
        break;

    default:
        break;
    }

    if (pp != NULL)
    {
        LogPromiseResult(pp->promiser, pp->promisee.rtype, pp->promisee.item, status, attr.transaction.log_level, mess);
    }

    /* Now complete the exits status classes and auditing */

    if (pp != NULL)
    {
        for (ip = mess; ip != NULL; ip = ip->next)
        {
            ClassAuditLog(pp, attr, ip->name, status, buffer);
        }
    }

    DeleteItemList(mess);
}