Exemple #1
0
static void TexinfoShowRange(FILE *fout, char *s, DataType type)
{
    Rlist *list = NULL, *rp;

    if (strlen(s) == 0)
    {
        fprintf(fout, "@noindent @b{Allowed input range}: (arbitrary string)\n\n");
        return;
    }

    if ((type == DATA_TYPE_OPTION) || (type == DATA_TYPE_OPTION_LIST))
    {
        list = RlistFromSplitString(s, ',');
        fprintf(fout, "@noindent @b{Allowed input range}: @*\n@example");

        for (rp = list; rp != NULL; rp = rp->next)
        {
            fprintf(fout, "\n          @code{%s}", (char *) rp->item);
        }

        fprintf(fout, "\n@end example\n");
        RlistDestroy(list);
    }
    else
    {
        fprintf(fout, "@noindent @b{Allowed input range}: @code{%s}\n\n", TexInfoEscape(s));
    }
}
Exemple #2
0
/**
 * Splits the given string into lines. On Windows, both \n and \r\n newlines are
 * detected. Escaped newlines are respected/ignored too.
 *
 * @param detect_crlf whether to try to detect and respect "\r\n" line endings
 * @return: an #Rlist where items are the individual lines **without** the
 *          trailing newline character(s)
 * @note: Free the result with RlistDestroy()
 * @warning: This function doesn't work properly if @string uses "\r\n" newlines
 *           and contains '\r' characters that are not part of any "\r\n"
 *           sequence because it first splits @string on '\r'.
 */
Rlist *RlistFromStringSplitLines(const char *string, bool detect_crlf)
{
    if (string == NULL || string[0] == '\0')
    {
        return NULL;
    }

    if (!detect_crlf || (strstr(string, "\r\n") == NULL))
    {
        return RlistFromSplitString(string, '\n');
    }

    /* else we split on '\r' just like RlistFromSplitString() above, but
     * strip leading '\n' in every chunk, thus effectively split on \r\n. See
     * the warning in the function's documentation.*/
    Rlist *liststart = NULL;

    for (const char *sp = string; *sp != '\0';)
    {
        sp += SubStrnCopyChr(&liststart, sp, '\r', '\n');
        assert(sp - string <= strlen(string));
        if (*sp)
        {
            assert(*sp == '\r' && (sp == string || sp[-1] != '\\'));
            sp++;
        }
    }

    RlistReverse(&liststart);
    return liststart;
}
Exemple #3
0
static void test_split_escaped(void)
{
    Rlist *list = RlistFromSplitString("a\\,b\\c\\,d,w\\,x\\,y\\,z", ',');
    assert_int_equal(2, RlistLen(list));
    assert_string_equal("a,b\\c,d", RlistScalarValue(list));
    assert_string_equal("w,x,y,z", RlistScalarValue(list->next));

    RlistDestroy(list);
}
Exemple #4
0
static void test_reverse(void)
{
    Rlist *list = RlistFromSplitString("a,b,c", ',');

    RlistReverse(&list);
    assert_string_equal("c", RlistScalarValue(list));
    assert_string_equal("b", RlistScalarValue(list->next));
    assert_string_equal("a", RlistScalarValue(list->next->next));

    RlistDestroy(list);
}
Exemple #5
0
static void test_split_long(void)
{
    char buf[CF_MAXVARSIZE * 2], *tail = buf + CF_MAXVARSIZE;
    memset(buf, '$', sizeof(buf) - 1);
    buf[sizeof(buf) - 1] = '\0';
    buf[CF_MAXVARSIZE - 1] = ',';

    Rlist *list = RlistFromSplitString(buf, ',');
    assert_int_equal(2, RlistLen(list));

    assert_string_equal(tail, RlistScalarValue(list));
    assert_string_equal(tail, RlistScalarValue(list->next));

    RlistDestroy(list);
}
Exemple #6
0
static void test_split_long_escaped(void)
{
    char buf[CF_MAXVARSIZE * 2 + 2], *tail = buf + CF_MAXVARSIZE + 1;
    memset(buf, '$', sizeof(buf) - 1);
    buf[sizeof(buf) - 1] = '\0';
    buf[CF_MAXVARSIZE] = ',';
    memcpy(buf + CF_MAXVARSIZE / 2, "\\,", 2);
    memcpy(tail + CF_MAXVARSIZE / 2, "\\,", 2);

    Rlist *list = RlistFromSplitString(buf, ',');
    assert_int_equal(2, RlistLen(list));

    tail[CF_MAXVARSIZE / 2] = '$'; /* blot out the back-slash */
    assert_string_equal(tail + 1, RlistScalarValue(list));
    assert_string_equal(tail + 1, RlistScalarValue(list->next));

    RlistDestroy(list);
}
Exemple #7
0
Rlist *RlistParseShown(const char *string)
{
    Rlist *newlist = NULL, *splitlist, *rp;

/* Parse a string representation generated by ShowList and turn back into Rlist */

    splitlist = RlistFromSplitString(string, ',');

    for (rp = splitlist; rp != NULL; rp = rp->next)
    {
        char value[CF_MAXVARSIZE] = { 0 };
        sscanf(RlistScalarValue(rp), "%*[{ '\"]%255[^'\"}]", value);
        RlistAppendScalar(&newlist, value);
    }

    RlistDestroy(splitlist);
    return newlist;
}
Exemple #8
0
static void RemoveTimeClass(EvalContext *ctx, const char* tags)
{
    Rlist *tags_rlist = RlistFromSplitString(tags, ',');
    ClassTableIterator *iter = EvalContextClassTableIteratorNewGlobal(ctx, NULL, true, true);
    StringSet *global_matches = ClassesMatching(ctx, iter, ".*", tags_rlist, false);
    ClassTableIteratorDestroy(iter);

    StringSetIterator it = StringSetIteratorInit(global_matches);
    const char *element = NULL;
    while ((element = StringSetIteratorNext(&it)))
    {
        EvalContextClassRemove(ctx, NULL, element);
    }

    StringSetDestroy(global_matches);

    RlistDestroy(tags_rlist);
}
Exemple #9
0
static GenericAgentConfig *CheckOpts(int argc, char **argv)
{
    extern char *optarg;
    char *sp;
    int optindex = 0;
    int c, alpha = false, v6 = false;
    GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_AGENT);

    /* Because of the MacOS linker we have to call this from each agent
       individually before Generic Initialize */

    POLICY_SERVER[0] = '\0';

    while ((c = getopt_long(argc, argv, "rdvnKIf:D:N:Vs:x:MBb:h", OPTIONS, &optindex)) != EOF)
    {
        switch ((char) c)
        {
        case 'f':
            if (optarg && strlen(optarg) < 5)
            {
                FatalError(" -f used but argument \"%s\" incorrect", optarg);
            }

            GenericAgentConfigSetInputFile(config, optarg);
            MINUSF = true;
            break;

        case 'b':
            if (optarg)
            {
                config->bundlesequence = RlistFromSplitString(optarg, ',');
                CBUNDLESEQUENCE_STR = optarg;
            }
            break;

        case 'd':
            HardClass("opt_debug");
            DEBUG = true;
            break;

        case 'B':
            BOOTSTRAP = true;
            MINUSF = true;
            GenericAgentConfigSetInputFile(config, "promises.cf");
            IGNORELOCK = true;
            HardClass("bootstrap_mode");
            break;

        case 's':

            if(IsLoopbackAddress(optarg))
            {
                FatalError("Use a non-loopback address when bootstrapping");
            }

            // temporary assure that network functions are working
            OpenNetwork();

            strncpy(POLICY_SERVER, Hostname2IPString(optarg), CF_BUFSIZE - 1);

            CloseNetwork();

            for (sp = POLICY_SERVER; *sp != '\0'; sp++)
            {
                if (isalpha((int)*sp))
                {
                    alpha = true;
                }

                if (ispunct((int)*sp) && *sp != ':' && *sp != '.')
                {
                    alpha = true;
                }

                if (*sp == ':')
                {
                    v6 = true;
                }
            }

            if (alpha && !v6)
            {
                FatalError
                ("Error specifying policy server. The policy server's IP address could not be looked up. Please use the IP address instead if there is no error.");
            }

            break;

        case 'K':
            IGNORELOCK = true;
            break;

        case 'D':
            NewClassesFromString(optarg);
            break;

        case 'N':
            NegateClassesFromString(optarg);
            break;

        case 'I':
            INFORM = true;
            break;

        case 'v':
            VERBOSE = true;
            break;

        case 'n':
            DONTDO = true;
            IGNORELOCK = true;
            HardClass("opt_dry_run");
            break;

        case 'V':
            PrintVersionBanner("cf-agent");
            exit(0);

        case 'h':
            Syntax("cf-agent - cfengine's change agent", OPTIONS, HINTS, ID);
            exit(0);

        case 'M':
            ManPage("cf-agent - cfengine's change agent", OPTIONS, HINTS, ID);
            exit(0);

        case 'x':
            CfOut(OUTPUT_LEVEL_ERROR, "", "Self-diagnostic functionality is retired");
            exit(0);

        case 'r':
            SHOWREPORTS = true;
            break;

        default:
            Syntax("cf-agent - cfengine's change agent", OPTIONS, HINTS, ID);
            exit(1);
        }
    }

    if (argv[optind] != NULL)
    {
        CfOut(OUTPUT_LEVEL_ERROR, "", "Unexpected argument with no preceding option: %s\n", argv[optind]);
        FatalError("Aborted");
    }

    CfDebug("Set debugging\n");

    return config;
}
Exemple #10
0
static GenericAgentConfig *CheckOpts(EvalContext *ctx, int argc, char **argv)
{
    extern char *optarg;
    int optindex = 0;
    int c;
    GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_RUNAGENT);

    DEFINECLASSES[0] = '\0';
    SENDCLASSES[0] = '\0';

    while ((c = getopt_long(argc, argv, "t:q:db:vnKhIif:D:VSxo:s:MH:lC::", OPTIONS, &optindex)) != EOF)
    {
        switch ((char) c)
        {
        case 'l':
            LEGACY_OUTPUT = true;
            break;

        case 'f':
            GenericAgentConfigSetInputFile(config, GetWorkDir(), optarg);
            MINUSF = true;
            break;

        case 'b':
            BACKGROUND = true;
            if (optarg)
            {
                MAXCHILD = atoi(optarg);
            }
            break;

        case 'd':
            LogSetGlobalLevel(LOG_LEVEL_DEBUG);
            break;

        case 'K':
            IGNORELOCK = true;
            break;

        case 's':
            strncpy(SENDCLASSES, optarg, CF_MAXVARSIZE);

            if (strlen(optarg) > CF_MAXVARSIZE)
            {
                Log(LOG_LEVEL_ERR, "Argument too long (-s)");
                exit(EXIT_FAILURE);
            }
            break;

        case 'D':
            strncpy(DEFINECLASSES, optarg, CF_MAXVARSIZE);

            if (strlen(optarg) > CF_MAXVARSIZE)
            {
                Log(LOG_LEVEL_ERR, "Argument too long (-D)");
                exit(EXIT_FAILURE);
            }
            break;

        case 'H':
            HOSTLIST = RlistFromSplitString(optarg, ',');
            break;

        case 'o':
            strncpy(REMOTE_AGENT_OPTIONS, optarg, CF_MAXVARSIZE);
            break;

        case 'I':
            LogSetGlobalLevel(LOG_LEVEL_INFO);
            break;

        case 'i':
            INTERACTIVE = true;
            break;

        case 'v':
            LogSetGlobalLevel(LOG_LEVEL_VERBOSE);
            break;

        case 'n':
            DONTDO = true;
            IGNORELOCK = true;
            EvalContextClassPutHard(ctx, "opt_dry_run");
            break;

        case 't':
            CONNTIMEOUT = atoi(optarg);
            break;

        case 'V':
            {
                Writer *w = FileWriter(stdout);
                GenericAgentWriteVersion(w);
                FileWriterDetach(w);
            }
            exit(0);

        case 'h':
            {
                Writer *w = FileWriter(stdout);
                GenericAgentWriteHelp(w, "cf-runagent", OPTIONS, HINTS, true);
                FileWriterDetach(w);
            }
            exit(0);

        case 'M':
            {
                Writer *out = FileWriter(stdout);
                ManPageWrite(out, "cf-runagent", time(NULL),
                             CF_RUNAGENT_SHORT_DESCRIPTION,
                             CF_RUNAGENT_MANPAGE_LONG_DESCRIPTION,
                             OPTIONS, HINTS,
                             true);
                FileWriterDetach(out);
                exit(EXIT_SUCCESS);
            }

        case 'x':
            Log(LOG_LEVEL_ERR, "Self-diagnostic functionality is retired.");
            exit(0);

        case 'C':
            if (!GenericAgentConfigParseColor(config, optarg))
            {
                exit(EXIT_FAILURE);
            }
            break;

        default:
            {
                Writer *w = FileWriter(stdout);
                GenericAgentWriteHelp(w, "cf-runagent", OPTIONS, HINTS, true);
                FileWriterDetach(w);
            }
            exit(1);

        }
    }

    if (!GenericAgentConfigParseArguments(config, argc - optind, argv + optind))
    {
        Log(LOG_LEVEL_ERR, "Too many arguments");
        exit(EXIT_FAILURE);
    }

    return config;
}
Exemple #11
0
GenericAgentConfig *CheckOpts(int argc, char **argv)
{
    extern char *optarg;
    int optindex = 0;
    int c;
    GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_COMMON);

    while ((c = getopt_long(argc, argv, "dvnIf:D:N:VSrxMb:i:p:s:cg:hW:lC::", OPTIONS, &optindex)) != EOF)
    {
        switch ((char) c)
        {
        case 0:
            switch (optindex)
            {
            case PROMISES_OPTION_EVAL_FUNCTIONS:
                if (!optarg)
                {
                    optarg = "yes";
                }
                config->agent_specific.common.eval_functions = strcmp("yes", optarg) == 0;
                break;

            case PROMISES_OPTION_SHOW_CLASSES:
                if (!optarg)
                {
                    optarg = "yes";
                }
                config->agent_specific.common.show_classes = strcmp("yes", optarg) == 0;
                break;

            case PROMISES_OPTION_SHOW_VARIABLES:
                if (!optarg)
                {
                    optarg = "yes";
                }
                config->agent_specific.common.show_variables = strcmp("yes", optarg) == 0;
                break;

            default:
                break;
            }

        case 'l':
            LEGACY_OUTPUT = true;
            break;

        case 'c':
            config->check_runnable = true;
            break;

        case 'f':

            if (optarg && (strlen(optarg) < 5))
            {
                Log(LOG_LEVEL_ERR, " -f used but argument '%s' incorrect", optarg);
                exit(EXIT_FAILURE);
            }

            GenericAgentConfigSetInputFile(config, GetInputDir(), optarg);
            MINUSF = true;
            break;

        case 'd':
            LogSetGlobalLevel(LOG_LEVEL_DEBUG);
            break;

        case 'b':
            if (optarg)
            {
                Rlist *bundlesequence = RlistFromSplitString(optarg, ',');
                GenericAgentConfigSetBundleSequence(config, bundlesequence);
                RlistDestroy(bundlesequence);
            }
            break;

        case 'p':
            if (strcmp("none", optarg) == 0)
            {
                config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_NONE;
            }
            else if (strcmp("cf", optarg) == 0)
            {
                config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_CF;
            }
            else if (strcmp("json", optarg) == 0)
            {
                config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_JSON;
            }
            else
            {
                Log(LOG_LEVEL_ERR, "Invalid policy output format: '%s'. Possible values are 'none', 'cf', 'json'", optarg);
                exit(EXIT_FAILURE);
            }
            break;

        case 's':
            if (strcmp("none", optarg) == 0)
            {
                break;
            }
            else if (strcmp("json", optarg) == 0)
            {
                JsonElement *json_syntax = SyntaxToJson();
                Writer *out = FileWriter(stdout);
                JsonWrite(out, json_syntax, 0);
                FileWriterDetach(out);
                JsonDestroy(json_syntax);
                exit(EXIT_SUCCESS);
            }
            else
            {
                Log(LOG_LEVEL_ERR, "Invalid syntax description output format: '%s'. Possible values are 'none', 'json'", optarg);
                exit(EXIT_FAILURE);
            }
            break;

        case 'K':
            config->ignore_locks = true;
            break;

        case 'D':
            config->heap_soft = StringSetFromString(optarg, ',');
            break;

        case 'N':
            config->heap_negated = StringSetFromString(optarg, ',');
            break;

        case 'I':
            LogSetGlobalLevel(LOG_LEVEL_INFO);
            break;

        case 'v':
            LogSetGlobalLevel(LOG_LEVEL_VERBOSE);
            break;

        case 'n':
            DONTDO = true;
            config->ignore_locks = true;
            break;

        case 'V':
            {
                Writer *w = FileWriter(stdout);
                GenericAgentWriteVersion(w);
                FileWriterDetach(w);
            }
            exit(EXIT_SUCCESS);

        case 'h':
            {
                Writer *w = FileWriter(stdout);
                GenericAgentWriteHelp(w, "cf-promises", OPTIONS, HINTS, true);
                FileWriterDetach(w);
            }
            exit(EXIT_SUCCESS);

        case 'M':
            {
                Writer *out = FileWriter(stdout);
                ManPageWrite(out, "cf-promises", time(NULL),
                             CF_PROMISES_SHORT_DESCRIPTION,
                             CF_PROMISES_MANPAGE_LONG_DESCRIPTION,
                             OPTIONS, HINTS,
                             true);
                FileWriterDetach(out);
                exit(EXIT_SUCCESS);
            }

        case 'r':
            SHOWREPORTS = true;
            break;

        case 'W':
            if (!GenericAgentConfigParseWarningOptions(config, optarg))
            {
                Log(LOG_LEVEL_ERR, "Error parsing warning option");
                exit(EXIT_FAILURE);
            }
            break;

        case 'x':
            Log(LOG_LEVEL_ERR, "Self-diagnostic functionality is retired.");
            exit(EXIT_SUCCESS);

        case 'C':
            if (!GenericAgentConfigParseColor(config, optarg))
            {
                exit(EXIT_FAILURE);
            }
            break;

        default:
            {
                Writer *w = FileWriter(stdout);
                GenericAgentWriteHelp(w, "cf-promises", OPTIONS, HINTS, true);
                FileWriterDetach(w);
            }
            exit(EXIT_FAILURE);

        }
    }

    if (!GenericAgentConfigParseArguments(config, argc - optind, argv + optind))
    {
        Log(LOG_LEVEL_ERR, "Too many arguments");
        exit(EXIT_FAILURE);
    }

    return config;
}
Exemple #12
0
static int HailServer(EvalContext *ctx, char *host)
{
    AgentConnection *conn;
    char sendbuffer[CF_BUFSIZE], recvbuffer[CF_BUFSIZE], peer[CF_MAXVARSIZE], ipv4[CF_MAXVARSIZE],
        digest[CF_MAXVARSIZE], user[CF_SMALLBUF];
    bool gotkey;
    char reply[8];

    FileCopy fc = {
        .portnumber = (short) ParseHostname(host, peer),
    };

    snprintf(ipv4, CF_MAXVARSIZE, "%s", Hostname2IPString(peer));
    Address2Hostkey(ipv4, digest);
    GetCurrentUserName(user, CF_SMALLBUF);

    if (INTERACTIVE)
    {
        CfOut(OUTPUT_LEVEL_VERBOSE, "", " -> Using interactive key trust...\n");

        gotkey = HavePublicKey(user, peer, digest) != NULL;

        if (!gotkey)
        {
            gotkey = HavePublicKey(user, ipv4, digest) != NULL;
        }

        if (!gotkey)
        {
            printf("WARNING - You do not have a public key from host %s = %s\n", host, ipv4);
            printf("          Do you want to accept one on trust? (yes/no)\n\n--> ");

            while (true)
            {
                if (fgets(reply, 8, stdin) == NULL)
                {
                    FatalError(ctx, "EOF trying to read answer from terminal");
                }

                if (Chop(reply, CF_EXPANDSIZE) == -1)
                {
                    CfOut(OUTPUT_LEVEL_ERROR, "", "Chop was called on a string that seemed to have no terminator");
                }

                if (strcmp(reply, "yes") == 0)
                {
                    printf(" -> Will trust the key...\n");
                    fc.trustkey = true;
                    break;
                }
                else if (strcmp(reply, "no") == 0)
                {
                    printf(" -> Will not trust the key...\n");
                    fc.trustkey = false;
                    break;
                }
                else
                {
                    printf(" !! Please reply yes or no...(%s)\n", reply);
                }
            }
        }
    }

/* Continue */

#ifdef __MINGW32__

    CfOut(OUTPUT_LEVEL_INFORM, "", "...........................................................................\n");
    CfOut(OUTPUT_LEVEL_INFORM, "", " * Hailing %s : %u, with options \"%s\" (serial)\n", peer, fc.portnumber,
          REMOTE_AGENT_OPTIONS);
    CfOut(OUTPUT_LEVEL_INFORM, "", "...........................................................................\n");

#else /* !__MINGW32__ */

    if (BACKGROUND)
    {
        CfOut(OUTPUT_LEVEL_INFORM, "", "Hailing %s : %u, with options \"%s\" (parallel)\n", peer, fc.portnumber,
              REMOTE_AGENT_OPTIONS);
    }
    else
    {
        CfOut(OUTPUT_LEVEL_INFORM, "", "...........................................................................\n");
        CfOut(OUTPUT_LEVEL_INFORM, "", " * Hailing %s : %u, with options \"%s\" (serial)\n", peer, fc.portnumber,
              REMOTE_AGENT_OPTIONS);
        CfOut(OUTPUT_LEVEL_INFORM, "", "...........................................................................\n");
    }

#endif /* !__MINGW32__ */

    fc.servers = RlistFromSplitString(peer, '*');

    if (fc.servers == NULL || strcmp(fc.servers->item, "localhost") == 0)
    {
        CfOut(OUTPUT_LEVEL_INFORM, "", "No hosts are registered to connect to");
        return false;
    }
    else
    {
        int err = 0;
        conn = NewServerConnection(fc, false, &err);

        if (conn == NULL)
        {
            RlistDestroy(fc.servers);
            CfOut(OUTPUT_LEVEL_VERBOSE, "", " -> No suitable server responded to hail\n");
            return false;
        }
    }

/* Check trust interaction*/

    HailExec(conn, peer, recvbuffer, sendbuffer);

    RlistDestroy(fc.servers);

    return true;
}

/********************************************************************/
/* Level 2                                                          */
/********************************************************************/

static void KeepControlPromises(EvalContext *ctx, Policy *policy)
{
    Rval retval;

    RUNATTR.copy.trustkey = false;
    RUNATTR.copy.encrypt = true;
    RUNATTR.copy.force_ipv4 = false;
    RUNATTR.copy.portnumber = SHORT_CFENGINEPORT;

/* Keep promised agent behaviour - control bodies */

    Seq *constraints = ControlBodyConstraints(policy, AGENT_TYPE_RUNAGENT);
    if (constraints)
    {
        for (size_t i = 0; i < SeqLength(constraints); i++)
        {
            Constraint *cp = SeqAt(constraints, i);

            if (!IsDefinedClass(ctx, cp->classes, NULL))
            {
                continue;
            }

            if (!EvalContextVariableGet(ctx, (VarRef) { NULL, "control_runagent", cp->lval }, &retval, NULL))
            {
                CfOut(OUTPUT_LEVEL_ERROR, "", "Unknown lval %s in runagent control body", cp->lval);
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_FORCE_IPV4].lval) == 0)
            {
                RUNATTR.copy.force_ipv4 = BooleanFromString(retval.item);
                CfOut(OUTPUT_LEVEL_VERBOSE, "", "SET force_ipv4 = %d\n", RUNATTR.copy.force_ipv4);
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_TRUSTKEY].lval) == 0)
            {
                RUNATTR.copy.trustkey = BooleanFromString(retval.item);
                CfOut(OUTPUT_LEVEL_VERBOSE, "", "SET trustkey = %d\n", RUNATTR.copy.trustkey);
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_ENCRYPT].lval) == 0)
            {
                RUNATTR.copy.encrypt = BooleanFromString(retval.item);
                CfOut(OUTPUT_LEVEL_VERBOSE, "", "SET encrypt = %d\n", RUNATTR.copy.encrypt);
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_PORT_NUMBER].lval) == 0)
            {
                RUNATTR.copy.portnumber = (short) IntFromString(retval.item);
                CfOut(OUTPUT_LEVEL_VERBOSE, "", "SET default portnumber = %u\n", (int) RUNATTR.copy.portnumber);
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_BACKGROUND].lval) == 0)
            {
                /*
                 * Only process this option if are is no -b or -i options specified on
                 * command line.
                 */
                if (BACKGROUND || INTERACTIVE)
                {
                    CfOut(OUTPUT_LEVEL_ERROR, "",
                          "Warning: 'background_children' setting from 'body runagent control' is overriden by command-line option.");
                }
                else
                {
                    BACKGROUND = BooleanFromString(retval.item);
                }
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_MAX_CHILD].lval) == 0)
            {
                MAXCHILD = (short) IntFromString(retval.item);
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_OUTPUT_TO_FILE].lval) == 0)
            {
                OUTPUT_TO_FILE = BooleanFromString(retval.item);
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_OUTPUT_DIRECTORY].lval) == 0)
            {
                if (IsAbsPath(retval.item))
                {
                    strncpy(OUTPUT_DIRECTORY, retval.item, CF_BUFSIZE - 1);
                    CfOut(OUTPUT_LEVEL_VERBOSE, "", "SET output direcory to = %s\n", OUTPUT_DIRECTORY);
                }
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_TIMEOUT].lval) == 0)
            {
                RUNATTR.copy.timeout = (short) IntFromString(retval.item);
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_HOSTS].lval) == 0)
            {
                if (HOSTLIST == NULL)       // Don't override if command line setting
                {
                    HOSTLIST = retval.item;
                }

                continue;
            }
        }
    }

    if (EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_LASTSEEN_EXPIRE_AFTER, &retval))
    {
        LASTSEENEXPIREAFTER = IntFromString(retval.item) * 60;
    }

}
Exemple #13
0
static int NewSQLColumns(char *table, Rlist *columns, char ***name_table, char ***type_table, int **size_table,
                         int **done)
{
    int i, no_of_cols = RlistLen(columns);
    Rlist *cols, *rp;

    *name_table = (char **) xmalloc(sizeof(char *) * (no_of_cols + 1));
    *type_table = (char **) xmalloc(sizeof(char *) * (no_of_cols + 1));
    *size_table = (int *) xmalloc(sizeof(int) * (no_of_cols + 1));
    *done = (int *) xmalloc(sizeof(int) * (no_of_cols + 1));

    for (i = 0, rp = columns; rp != NULL; rp = rp->next, i++)
    {
        (*done)[i] = 0;

        cols = RlistFromSplitString(RlistScalarValue(rp), ',');

        if (!cols)
        {
            Log(LOG_LEVEL_ERR, "No columns promised for table '%s' - makes no sense", table);
            return false;
        }

        if (cols->val.item == NULL)
        {
            Log(LOG_LEVEL_ERR, "Malformed column promise for table '%s' - found not even a name", table);
            free(*name_table);
            free(*type_table);
            free(*size_table);
            free(*done);
            return false;
        }

        (*name_table)[i] = xstrdup(RlistScalarValue(cols));

        if (cols->next == NULL)
        {
            Log(LOG_LEVEL_ERR, "Malformed column '%s' promised for table '%s' - missing a type", (*name_table)[i],
                  table);
            free(*name_table);
            free(*type_table);
            free(*size_table);
            free(*done);
            return false;
        }

        (*type_table)[i] = xstrdup(RlistScalarValue(cols->next));

        if (cols->next->next == NULL)
        {
            (*size_table)[i] = 0;
        }
        else
        {
            if (cols->next->next->val.item)
            {
                (*size_table)[i] = IntFromString(RlistScalarValue(cols->next->next));
            }
            else
            {
                (*size_table)[i] = 0;
            }
        }

        RlistDestroy(cols);
    }

    return true;
}
Exemple #14
0
static GenericAgentConfig *CheckOpts(EvalContext *ctx, int argc, char **argv)
{
    extern char *optarg;
    int optindex = 0;
    int c;
    GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_RUNAGENT);

    DEFINECLASSES[0] = '\0';
    SENDCLASSES[0] = '\0';

    while ((c = getopt_long(argc, argv, "t:q:db:vnKhIif:D:VSxo:s:MH:", OPTIONS, &optindex)) != EOF)
    {
        switch ((char) c)
        {
        case 'f':
            GenericAgentConfigSetInputFile(config, optarg);
            MINUSF = true;
            break;

        case 'b':
            BACKGROUND = true;
            if (optarg)
            {
                MAXCHILD = atoi(optarg);
            }
            break;

        case 'd':
            config->debug_mode = true;
            break;

        case 'K':
            IGNORELOCK = true;
            break;

        case 's':
            strncpy(SENDCLASSES, optarg, CF_MAXVARSIZE);

            if (strlen(optarg) > CF_MAXVARSIZE)
            {
                CfOut(OUTPUT_LEVEL_ERROR, "", "Argument too long\n");
                exit(EXIT_FAILURE);
            }
            break;

        case 'D':
            strncpy(DEFINECLASSES, optarg, CF_MAXVARSIZE);

            if (strlen(optarg) > CF_MAXVARSIZE)
            {
                CfOut(OUTPUT_LEVEL_ERROR, "", "Argument too long\n");
                exit(EXIT_FAILURE);
            }
            break;

        case 'H':
            HOSTLIST = RlistFromSplitString(optarg, ',');
            break;

        case 'o':
            strncpy(REMOTE_AGENT_OPTIONS, optarg, CF_MAXVARSIZE);
            break;

        case 'I':
            INFORM = true;
            break;

        case 'i':
            INTERACTIVE = true;
            break;

        case 'v':
            VERBOSE = true;
            break;

        case 'n':
            DONTDO = true;
            IGNORELOCK = true;
            EvalContextHeapAddHard(ctx, "opt_dry_run");
            break;

        case 't':
            CONNTIMEOUT = atoi(optarg);
            break;

        case 'V':
            PrintVersion();
            exit(0);

        case 'h':
            Syntax("cf-runagent - Run agent", OPTIONS, HINTS, ID);
            exit(0);

        case 'M':
            ManPage("cf-runagent - Run agent", OPTIONS, HINTS, ID);
            exit(0);

        case 'x':
            CfOut(OUTPUT_LEVEL_ERROR, "", "Self-diagnostic functionality is retired.");
            exit(0);

        default:
            Syntax("cf-runagent - Run agent", OPTIONS, HINTS, ID);
            exit(1);

        }
    }

    CfDebug("Set debugging\n");

    return config;
}
Exemple #15
0
static GenericAgentConfig *CheckOpts(int argc, char **argv)
{
    extern char *optarg;
    int c;
    GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_RUNAGENT);

    DEFINECLASSES[0] = '\0';
    SENDCLASSES[0] = '\0';

    while ((c = getopt_long(argc, argv, "t:q:db:vnKhIif:D:VSxo:s:MH:C::l",
                            OPTIONS, NULL)) != -1)
    {
        switch (c)
        {
        case 'f':
            GenericAgentConfigSetInputFile(config, GetInputDir(), optarg);
            MINUSF = true;
            break;

        case 'b':
            BACKGROUND = true;
            if (optarg)
            {
                MAXCHILD = atoi(optarg);
            }
            break;

        case 'd':
            LogSetGlobalLevel(LOG_LEVEL_DEBUG);
            break;

        case 'K':
            config->ignore_locks = true;
            break;

        case 's':
            strlcpy(SENDCLASSES, optarg, CF_MAXVARSIZE);

            if (strlen(optarg) > CF_MAXVARSIZE)
            {
                Log(LOG_LEVEL_ERR, "Argument too long (-s)");
                exit(EXIT_FAILURE);
            }
            break;

        case 'D':
            strlcpy(DEFINECLASSES, optarg, CF_MAXVARSIZE);

            if (strlen(optarg) > CF_MAXVARSIZE)
            {
                Log(LOG_LEVEL_ERR, "Argument too long (-D)");
                exit(EXIT_FAILURE);
            }
            break;

        case 'H':
            HOSTLIST = RlistFromSplitString(optarg, ',');
            break;

        case 'o':
            Log(LOG_LEVEL_ERR, "Option \"-o\" has been deprecated,"
                " you can not pass arbitrary arguments to remote cf-agent");
            exit(EXIT_FAILURE);
            break;

        case 'I':
            LogSetGlobalLevel(LOG_LEVEL_INFO);
            break;

        case 'i':
            INTERACTIVE = true;
            break;

        case 'v':
            LogSetGlobalLevel(LOG_LEVEL_VERBOSE);
            break;

        case 'n':
            DONTDO = true;
            config->ignore_locks = true;
            break;

        case 't':
            CONNTIMEOUT = atoi(optarg);
            break;

        case 'V':
        {
            Writer *w = FileWriter(stdout);
            GenericAgentWriteVersion(w);
            FileWriterDetach(w);
        }
        exit(EXIT_SUCCESS);

        case 'h':
        {
            Writer *w = FileWriter(stdout);
            GenericAgentWriteHelp(w, "cf-runagent", OPTIONS, HINTS, true);
            FileWriterDetach(w);
        }
        exit(EXIT_SUCCESS);

        case 'M':
        {
            Writer *out = FileWriter(stdout);
            ManPageWrite(out, "cf-runagent", time(NULL),
                         CF_RUNAGENT_SHORT_DESCRIPTION,
                         CF_RUNAGENT_MANPAGE_LONG_DESCRIPTION,
                         OPTIONS, HINTS,
                         true);
            FileWriterDetach(out);
            exit(EXIT_SUCCESS);
        }

        case 'x':
            Log(LOG_LEVEL_ERR, "Self-diagnostic functionality is retired.");
            exit(EXIT_SUCCESS);

        case 'C':
            if (!GenericAgentConfigParseColor(config, optarg))
            {
                exit(EXIT_FAILURE);
            }
            break;

        case 'l':
            LoggingEnableTimestamps(true);
            break;

        default:
        {
            Writer *w = FileWriter(stdout);
            GenericAgentWriteHelp(w, "cf-runagent", OPTIONS, HINTS, true);
            FileWriterDetach(w);
        }
        exit(EXIT_FAILURE);

        }
    }

    if (!GenericAgentConfigParseArguments(config, argc - optind, argv + optind))
    {
        Log(LOG_LEVEL_ERR, "Too many arguments");
        exit(EXIT_FAILURE);
    }

    return config;
}
Exemple #16
0
GenericAgentConfig *CheckOpts(int argc, char **argv)
{
    extern char *optarg;
    int c;
    GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_COMMON, GetTTYInteractive());
    config->tag_release_dir = NULL;

    while ((c = getopt_long(argc, argv, "dvnIw:f:D:N:VSrxMb:i:p:s:cg:hW:C::T:l",
                            OPTIONS, NULL))
           != -1)
    {
        switch (c)
        {
        case OPT_EVAL_FUNCTIONS:
            if (!optarg)
            {
                optarg = "yes";
            }
            config->agent_specific.common.eval_functions = strcmp("yes", optarg) == 0;
            break;

        case OPT_SHOW_CLASSES:
            config->agent_specific.common.show_classes = true;
            break;

        case OPT_SHOW_VARS:
            config->agent_specific.common.show_variables = true;
            break;

        case 'w':
            Log(LOG_LEVEL_INFO, "Setting workdir to '%s'", optarg);
            putenv(StringConcatenate(2, "CFENGINE_TEST_OVERRIDE_WORKDIR=", optarg));
            break;

        case 'c':
            config->check_runnable = true;
            break;

        case 'f':
            GenericAgentConfigSetInputFile(config, GetInputDir(), optarg);
            MINUSF = true;
            break;

        case 'd':
            LogSetGlobalLevel(LOG_LEVEL_DEBUG);
            break;

        case 'b':
            if (optarg)
            {
                Rlist *bundlesequence = RlistFromSplitString(optarg, ',');
                GenericAgentConfigSetBundleSequence(config, bundlesequence);
                RlistDestroy(bundlesequence);
            }
            break;

        case 'p':
            if (strcmp("none", optarg) == 0)
            {
                config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_NONE;
            }
            else if (strcmp("cf", optarg) == 0)
            {
                config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_CF;
            }
            else if (strcmp("json", optarg) == 0)
            {
                config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_JSON;
            }
             else if (strcmp("cf-full", optarg) == 0)
            {
                config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_CF_FULL;
            }
            else if (strcmp("json-full", optarg) == 0)
            {
                config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_JSON_FULL;
            }
            else
            {
                Log(LOG_LEVEL_ERR, "Invalid policy output format: '%s'. Possible values are 'none', 'cf', 'json', 'cf-full', 'json-full'", optarg);
                exit(EXIT_FAILURE);
            }
            break;

        case 's':
            if (strcmp("none", optarg) == 0)
            {
                break;
            }
            else if (strcmp("json", optarg) == 0)
            {
                JsonElement *json_syntax = SyntaxToJson();
                Writer *out = FileWriter(stdout);
                JsonWrite(out, json_syntax, 0);
                FileWriterDetach(out);
                JsonDestroy(json_syntax);
                exit(EXIT_SUCCESS);
            }
            else
            {
                Log(LOG_LEVEL_ERR, "Invalid syntax description output format: '%s'. Possible values are 'none', 'json'", optarg);
                exit(EXIT_FAILURE);
            }
            break;

        case 'K':
            config->ignore_locks = true;
            break;

        case 'D':
            {
                StringSet *defined_classes = StringSetFromString(optarg, ',');
                if (! config->heap_soft)
                {
                    config->heap_soft = defined_classes;
                }
                else
                {
                    StringSetJoin(config->heap_soft, defined_classes);
                    free(defined_classes);
                }
            }
            break;

        case 'N':
            {
                StringSet *negated_classes = StringSetFromString(optarg, ',');
                if (! config->heap_negated)
                {
                    config->heap_negated = negated_classes;
                }
                else
                {
                    StringSetJoin(config->heap_negated, negated_classes);
                    free(negated_classes);
                }
            }
            break;

        case 'I':
            LogSetGlobalLevel(LOG_LEVEL_INFO);
            break;

        case 'v':
            LogSetGlobalLevel(LOG_LEVEL_VERBOSE);
            break;

        case 'n':
            DONTDO = true;
            config->ignore_locks = true;
            break;

        case 'V':
        {
            Writer *w = FileWriter(stdout);
            GenericAgentWriteVersion(w);
            FileWriterDetach(w);
        }
        exit(EXIT_SUCCESS);

        case 'h':
        {
            Writer *w = FileWriter(stdout);
            GenericAgentWriteHelp(w, "cf-promises", OPTIONS, HINTS, true);
            FileWriterDetach(w);
        }
        exit(EXIT_SUCCESS);

        case 'M':
        {
            Writer *out = FileWriter(stdout);
            ManPageWrite(out, "cf-promises", time(NULL),
                         CF_PROMISES_SHORT_DESCRIPTION,
                         CF_PROMISES_MANPAGE_LONG_DESCRIPTION,
                         OPTIONS, HINTS,
                         true);
            FileWriterDetach(out);
            exit(EXIT_SUCCESS);
        }

        case 'r':
            Log(LOG_LEVEL_ERR, "Option '-r' has been deprecated");
            exit(EXIT_FAILURE);
            break;

        case 'W':
            if (!GenericAgentConfigParseWarningOptions(config, optarg))
            {
                Log(LOG_LEVEL_ERR, "Error parsing warning option");
                exit(EXIT_FAILURE);
            }
            break;

        case 'x':
            Log(LOG_LEVEL_ERR, "Self-diagnostic functionality is retired.");
            exit(EXIT_SUCCESS);

        case 'C':
            if (!GenericAgentConfigParseColor(config, optarg))
            {
                exit(EXIT_FAILURE);
            }
            break;

        case 'T':
            GenericAgentConfigSetInputFile(config, optarg, "promises.cf");
            MINUSF = true;
            config->tag_release_dir = xstrdup(optarg);
            break;

        case 'l':
            LoggingEnableTimestamps(true);
            break;

        default:
        {
            Writer *w = FileWriter(stdout);
            GenericAgentWriteHelp(w, "cf-promises", OPTIONS, HINTS, true);
            FileWriterDetach(w);
        }
        exit(EXIT_FAILURE);

        }
    }

    if (!GenericAgentConfigParseArguments(config, argc - optind, argv + optind))
    {
        Log(LOG_LEVEL_ERR, "Too many arguments");
        exit(EXIT_FAILURE);
    }

    return config;
}
Exemple #17
0
static int HailServer(EvalContext *ctx, char *host)
{
    AgentConnection *conn;
    char sendbuffer[CF_BUFSIZE], recvbuffer[CF_BUFSIZE], peer[CF_MAXVARSIZE],
        digest[CF_MAXVARSIZE], user[CF_SMALLBUF];
    bool gotkey;
    char reply[8];

    FileCopy fc = {
        .portnumber = (unsigned short) ParseHostname(host, peer),
    };

    char ipaddr[CF_MAX_IP_LEN];
    if (Hostname2IPString(ipaddr, peer, sizeof(ipaddr)) == -1)
    {
        Log(LOG_LEVEL_ERR,
            "HailServer: ERROR, could not resolve '%s'", peer);
        return false;
    }

    Address2Hostkey(ipaddr, digest);
    GetCurrentUserName(user, CF_SMALLBUF);

    if (INTERACTIVE)
    {
        Log(LOG_LEVEL_VERBOSE, "Using interactive key trust...");

        gotkey = HavePublicKey(user, peer, digest) != NULL;

        if (!gotkey)
        {
            gotkey = HavePublicKey(user, ipaddr, digest) != NULL;
        }

        if (!gotkey)
        {
            printf("WARNING - You do not have a public key from host %s = %s\n",
                   host, ipaddr);
            printf("          Do you want to accept one on trust? (yes/no)\n\n--> ");

            while (true)
            {
                if (fgets(reply, sizeof(reply), stdin) == NULL)
                {
                    FatalError(ctx, "EOF trying to read answer from terminal");
                }

                if (Chop(reply, CF_EXPANDSIZE) == -1)
                {
                    Log(LOG_LEVEL_ERR, "Chop was called on a string that seemed to have no terminator");
                }

                if (strcmp(reply, "yes") == 0)
                {
                    printf("Will trust the key...\n");
                    fc.trustkey = true;
                    break;
                }
                else if (strcmp(reply, "no") == 0)
                {
                    printf("Will not trust the key...\n");
                    fc.trustkey = false;
                    break;
                }
                else
                {
                    printf("Please reply yes or no...(%s)\n", reply);
                }
            }
        }
    }

/* Continue */

#ifdef __MINGW32__

    if (LEGACY_OUTPUT)
    {
        Log(LOG_LEVEL_INFO, "...........................................................................");
        Log(LOG_LEVEL_INFO, " * Hailing %s : %u, with options \"%s\" (serial)", peer, fc.portnumber,
              REMOTE_AGENT_OPTIONS);
        Log(LOG_LEVEL_INFO, "...........................................................................");
    }
    else
    {
        Log(LOG_LEVEL_INFO, "Hailing '%s' : %u, with options '%s' (serial)", peer, fc.portnumber,
            REMOTE_AGENT_OPTIONS);
    }


#else /* !__MINGW32__ */

    if (BACKGROUND)
    {
        Log(LOG_LEVEL_INFO, "Hailing '%s' : %u, with options '%s' (parallel)", peer, fc.portnumber,
              REMOTE_AGENT_OPTIONS);
    }
    else
    {
        if (LEGACY_OUTPUT)
        {
            Log(LOG_LEVEL_INFO, "...........................................................................");
            Log(LOG_LEVEL_INFO, " * Hailing %s : %u, with options \"%s\" (serial)", peer, fc.portnumber,
                  REMOTE_AGENT_OPTIONS);
            Log(LOG_LEVEL_INFO, "...........................................................................");
        }
        else
        {
            Log(LOG_LEVEL_INFO, "Hailing '%s' : %u, with options '%s' (serial)", peer, fc.portnumber,
                  REMOTE_AGENT_OPTIONS);
        }
    }

#endif /* !__MINGW32__ */

    fc.servers = RlistFromSplitString(peer, '*');

    if (fc.servers == NULL || strcmp(RlistScalarValue(fc.servers), "localhost") == 0)
    {
        Log(LOG_LEVEL_INFO, "No hosts are registered to connect to");
        return false;
    }
    else
    {
        int err = 0;
        conn = NewServerConnection(fc, false, &err, -1);

        if (conn == NULL)
        {
            RlistDestroy(fc.servers);
            Log(LOG_LEVEL_VERBOSE, "No suitable server responded to hail");
            return false;
        }
    }

/* Check trust interaction*/

    HailExec(conn, peer, recvbuffer, sendbuffer);

    RlistDestroy(fc.servers);

    return true;
}

/********************************************************************/
/* Level 2                                                          */
/********************************************************************/

static void KeepControlPromises(EvalContext *ctx, const Policy *policy)
{
    Seq *constraints = ControlBodyConstraints(policy, AGENT_TYPE_RUNAGENT);
    if (constraints)
    {
        for (size_t i = 0; i < SeqLength(constraints); i++)
        {
            Constraint *cp = SeqAt(constraints, i);

            if (!IsDefinedClass(ctx, cp->classes))
            {
                continue;
            }

            VarRef *ref = VarRefParseFromScope(cp->lval, "control_runagent");
            const void *value = EvalContextVariableGet(ctx, ref, NULL);
            VarRefDestroy(ref);

            if (!value)
            {
                Log(LOG_LEVEL_ERR, "Unknown lval '%s' in runagent control body", cp->lval);
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_FORCE_IPV4].lval) == 0)
            {
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_TRUSTKEY].lval) == 0)
            {
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_ENCRYPT].lval) == 0)
            {
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_PORT_NUMBER].lval) == 0)
            {
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_BACKGROUND].lval) == 0)
            {
                /*
                 * Only process this option if are is no -b or -i options specified on
                 * command line.
                 */
                if (BACKGROUND || INTERACTIVE)
                {
                    Log(LOG_LEVEL_WARNING,
                          "'background_children' setting from 'body runagent control' is overridden by command-line option.");
                }
                else
                {
                    BACKGROUND = BooleanFromString(value);
                }
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_MAX_CHILD].lval) == 0)
            {
                MAXCHILD = (short) IntFromString(value);
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_OUTPUT_TO_FILE].lval) == 0)
            {
                OUTPUT_TO_FILE = BooleanFromString(value);
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_OUTPUT_DIRECTORY].lval) == 0)
            {
                if (IsAbsPath(value))
                {
                    strncpy(OUTPUT_DIRECTORY, value, CF_BUFSIZE - 1);
                    Log(LOG_LEVEL_VERBOSE, "Setting output direcory to '%s'", OUTPUT_DIRECTORY);
                }
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_TIMEOUT].lval) == 0)
            {
                continue;
            }

            if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_HOSTS].lval) == 0)
            {
                if (HOSTLIST == NULL)       // Don't override if command line setting
                {
                    HOSTLIST = value;
                }

                continue;
            }
        }
    }

    const char *expire_after = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_LASTSEEN_EXPIRE_AFTER);
    if (expire_after)
    {
        LASTSEENEXPIREAFTER = IntFromString(expire_after) * 60;
    }

}
Exemple #18
0
static int NewSQLColumns(char *table, Rlist *columns, char ***name_table, char ***type_table, int **size_table,
                         int **done)
{
    int i, no_of_cols = RlistLen(columns);
    Rlist *cols, *rp;

    *name_table = (char **) xmalloc(sizeof(char *) * (no_of_cols + 1));
    *type_table = (char **) xmalloc(sizeof(char *) * (no_of_cols + 1));
    *size_table = (int *) xmalloc(sizeof(int) * (no_of_cols + 1));
    *done = (int *) xmalloc(sizeof(int) * (no_of_cols + 1));

    for (i = 0, rp = columns; rp != NULL; rp = rp->next, i++)
    {
        (*done)[i] = 0;

        cols = RlistFromSplitString((char *) rp->item, ',');

        if (!cols)
        {
            CfOut(OUTPUT_LEVEL_ERROR, "", "No columns promised for table \"%s\" - makes no sense", table);
            return false;
        }

        if (cols->item == NULL)
        {
            CfOut(OUTPUT_LEVEL_ERROR, "", "Malformed column promise for table \"%s\" - found not even a name", table);
            free(*name_table);
            free(*type_table);
            free(*size_table);
            free(*done);
            return false;
        }

        (*name_table)[i] = xstrdup((char *) cols->item);

        if (cols->next == NULL)
        {
            CfOut(OUTPUT_LEVEL_ERROR, "", "Malformed column \"%s\" promised for table \"%s\" - missing a type", (*name_table)[i],
                  table);
            free(*name_table);
            free(*type_table);
            free(*size_table);
            free(*done);
            return false;
        }

        (*type_table)[i] = xstrdup(cols->next->item);

        if (cols->next->next == NULL)
        {
            (*size_table)[i] = 0;
        }
        else
        {
            if (cols->next->next->item)
            {
                (*size_table)[i] = IntFromString(cols->next->next->item);
            }
            else
            {
                (*size_table)[i] = 0;
            }
        }

        RlistDestroy(cols);
    }

    return true;
}
Exemple #19
0
static int HailServer(char *host, Attributes a, Promise *pp)
{
    AgentConnection *conn;
    char sendbuffer[CF_BUFSIZE], recvbuffer[CF_BUFSIZE], peer[CF_MAXVARSIZE], ipv4[CF_MAXVARSIZE],
        digest[CF_MAXVARSIZE], user[CF_SMALLBUF];
    bool gotkey;
    char reply[8];

    a.copy.portnumber = (short) ParseHostname(host, peer);

    snprintf(ipv4, CF_MAXVARSIZE, "%s", Hostname2IPString(peer));
    Address2Hostkey(ipv4, digest);
    GetCurrentUserName(user, CF_SMALLBUF);

    if (INTERACTIVE)
    {
        CfOut(OUTPUT_LEVEL_VERBOSE, "", " -> Using interactive key trust...\n");

        gotkey = HavePublicKey(user, peer, digest) != NULL;

        if (!gotkey)
        {
            gotkey = HavePublicKey(user, ipv4, digest) != NULL;
        }

        if (!gotkey)
        {
            printf("WARNING - You do not have a public key from host %s = %s\n", host, ipv4);
            printf("          Do you want to accept one on trust? (yes/no)\n\n--> ");

            while (true)
            {
                if (fgets(reply, 8, stdin) == NULL)
                {
                    FatalError("EOF trying to read answer from terminal");
                }

                if (Chop(reply, CF_EXPANDSIZE) == -1)
                {
                    CfOut(OUTPUT_LEVEL_ERROR, "", "Chop was called on a string that seemed to have no terminator");
                }

                if (strcmp(reply, "yes") == 0)
                {
                    printf(" -> Will trust the key...\n");
                    a.copy.trustkey = true;
                    break;
                }
                else if (strcmp(reply, "no") == 0)
                {
                    printf(" -> Will not trust the key...\n");
                    a.copy.trustkey = false;
                    break;
                }
                else
                {
                    printf(" !! Please reply yes or no...(%s)\n", reply);
                }
            }
        }
    }

/* Continue */

#ifdef __MINGW32__

    CfOut(OUTPUT_LEVEL_INFORM, "", "...........................................................................\n");
    CfOut(OUTPUT_LEVEL_INFORM, "", " * Hailing %s : %u, with options \"%s\" (serial)\n", peer, a.copy.portnumber,
          REMOTE_AGENT_OPTIONS);
    CfOut(OUTPUT_LEVEL_INFORM, "", "...........................................................................\n");

#else /* !__MINGW32__ */

    if (BACKGROUND)
    {
        CfOut(OUTPUT_LEVEL_INFORM, "", "Hailing %s : %u, with options \"%s\" (parallel)\n", peer, a.copy.portnumber,
              REMOTE_AGENT_OPTIONS);
    }
    else
    {
        CfOut(OUTPUT_LEVEL_INFORM, "", "...........................................................................\n");
        CfOut(OUTPUT_LEVEL_INFORM, "", " * Hailing %s : %u, with options \"%s\" (serial)\n", peer, a.copy.portnumber,
              REMOTE_AGENT_OPTIONS);
        CfOut(OUTPUT_LEVEL_INFORM, "", "...........................................................................\n");
    }

#endif /* !__MINGW32__ */

    a.copy.servers = RlistFromSplitString(peer, '*');

    if (a.copy.servers == NULL || strcmp(a.copy.servers->item, "localhost") == 0)
    {
        cfPS(OUTPUT_LEVEL_INFORM, CF_NOP, "", pp, a, "No hosts are registered to connect to");
        return false;
    }
    else
    {
        conn = NewServerConnection(a, pp);

        if (conn == NULL)
        {
            RlistDestroy(a.copy.servers);
            CfOut(OUTPUT_LEVEL_VERBOSE, "", " -> No suitable server responded to hail\n");
            return false;
        }
    }

/* Check trust interaction*/

    pp->cache = NULL;

    if (strlen(MENU) > 0)
    {
#if defined(HAVE_NOVA)
        if (!ExecuteRunagent(conn, MENU))
        {
            DisconnectServer(conn);
            RlistDestroy(a.copy.servers);
            return false;
        }
#endif
    }
    else
    {
        HailExec(conn, peer, recvbuffer, sendbuffer);
    }

    RlistDestroy(a.copy.servers);

    return true;
}
Exemple #20
0
GenericAgentConfig *CheckOpts(EvalContext *ctx, int argc, char **argv)
{
    extern char *optarg;
    int optindex = 0;
    int c;
    GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_COMMON);

    while ((c = getopt_long(argc, argv, "dvnIf:D:N:VSrxMb:i:p:cg:h", OPTIONS, &optindex)) != EOF)
    {
        switch ((char) c)
        {
        case 'c':
            config->check_runnable = true;
            break;

        case 'f':

            if (optarg && (strlen(optarg) < 5))
            {
                CfOut(OUTPUT_LEVEL_ERROR, "", " -f used but argument \"%s\" incorrect", optarg);
                exit(EXIT_FAILURE);
            }

            GenericAgentConfigSetInputFile(config, optarg);
            MINUSF = true;
            break;

        case 'd':
            config->debug_mode = true;
            break;

        case 'b':
            if (optarg)
            {
                Rlist *bundlesequence = RlistFromSplitString(optarg, ',');
                GenericAgentConfigSetBundleSequence(config, bundlesequence);
                RlistDestroy(bundlesequence);
                CBUNDLESEQUENCE_STR = optarg; // TODO: wtf is this
            }
            break;

        case 'p':
            if (strcmp("none", optarg) == 0)
            {
                config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_NONE;
            }
            else if (strcmp("cf", optarg) == 0)
            {
                config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_CF;
            }
            else if (strcmp("json", optarg) == 0)
            {
                config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_JSON;
            }
            else
            {
                CfOut(OUTPUT_LEVEL_ERROR, "", "Invalid policy output format: '%s'. Possible values are 'none', 'cf', 'json'", optarg);
                exit(EXIT_FAILURE);
            }
            break;

        case 'K':
            IGNORELOCK = true;
            break;

        case 'D':
            config->heap_soft = StringSetFromString(optarg, ',');
            break;

        case 'N':
            config->heap_negated = StringSetFromString(optarg, ',');
            break;

        case 'I':
            INFORM = true;
            break;

        case 'v':
            VERBOSE = true;
            break;

        case 'n':
            DONTDO = true;
            IGNORELOCK = true;
            LOOKUP = true;
            EvalContextHeapAddHard(ctx, "opt_dry_run");
            break;

        case 'V':
            PrintVersionBanner("cf-promises");
            exit(0);

        case 'h':
            Syntax("cf-promises - cfengine's promise analyzer", OPTIONS, HINTS, ID);
            exit(0);

        case 'M':
            ManPage("cf-promises - cfengine's promise analyzer", OPTIONS, HINTS, ID);
            exit(0);

        case 'r':
            SHOWREPORTS = true;
            break;

        case 'x':
            CfOut(OUTPUT_LEVEL_ERROR, "", "Self-diagnostic functionality is retired.");
            exit(0);

        default:
            Syntax("cf-promises - cfengine's promise analyzer", OPTIONS, HINTS, ID);
            exit(1);

        }
    }

    if (argv[optind] != NULL)
    {
        CfOut(OUTPUT_LEVEL_ERROR, "", "Unexpected argument: %s\n", argv[optind]);
    }

    CfDebug("Set debugging\n");

    return config;
}
Exemple #21
0
static GenericAgentConfig *CheckOpts(int argc, char **argv)
{
    extern char *optarg;
    int c;
    GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_RUNAGENT, GetTTYInteractive());

    DEFINECLASSES[0] = '\0';
    SENDCLASSES[0]   = '\0';
    REMOTEBUNDLES[0] = '\0';

    int longopt_idx;
    while ((c = getopt_long(argc, argv, "t:q:db:vnKhIif:g:D:VSxo:s:MH:C::l",
                            OPTIONS, &longopt_idx))
           != -1)
    {
        switch (c)
        {
        case 'f':
            GenericAgentConfigSetInputFile(config, GetInputDir(), optarg);
            MINUSF = true;
            break;

        case 'b':
            BACKGROUND = true;
            if (optarg)
            {
                MAXCHILD = StringToLongExitOnError(optarg);
            }
            break;

        case 'd':
            LogSetGlobalLevel(LOG_LEVEL_DEBUG);
            break;

        case 'K':
            config->ignore_locks = true;
            break;

        case 's':
        {
            size_t len = strlen(SENDCLASSES);
            StrCatDelim(SENDCLASSES, sizeof(SENDCLASSES), &len,
                        optarg, ',');
            if (len >= sizeof(SENDCLASSES))
            {
                Log(LOG_LEVEL_ERR, "Argument too long (-s)");
                exit(EXIT_FAILURE);
            }
            break;
        }
        case 'D':
        {
            size_t len = strlen(DEFINECLASSES);
            StrCatDelim(DEFINECLASSES, sizeof(DEFINECLASSES), &len,
                        optarg, ',');
            if (len >= sizeof(DEFINECLASSES))
            {
                Log(LOG_LEVEL_ERR, "Argument too long (-D)");
                exit(EXIT_FAILURE);
            }
            break;
        }
        case 'H':
            HOSTLIST = RlistFromSplitString(optarg, ',');
            break;

        case 'o':
            Log(LOG_LEVEL_ERR, "Option \"-o\" has been deprecated,"
                " you can not pass arbitrary arguments to remote cf-agent");
            exit(EXIT_FAILURE);
            break;

        case 'I':
            LogSetGlobalLevel(LOG_LEVEL_INFO);
            break;

        case 'i':
            INTERACTIVE = true;
            break;

        case 'v':
            LogSetGlobalLevel(LOG_LEVEL_VERBOSE);
            break;

        case 'g':
            LogSetGlobalLevelArgOrExit(optarg);
            break;

        case 'n':
            DONTDO = true;
            config->ignore_locks = true;
            break;

        case 't':
            CONNTIMEOUT = StringToLongExitOnError(optarg);
            break;

        case 'V':
        {
            Writer *w = FileWriter(stdout);
            GenericAgentWriteVersion(w);
            FileWriterDetach(w);
        }
        exit(EXIT_SUCCESS);

        case 'h':
        {
            Writer *w = FileWriter(stdout);
            WriterWriteHelp(w, "cf-runagent", OPTIONS, HINTS, true, NULL);
            FileWriterDetach(w);
        }
        exit(EXIT_SUCCESS);

        case 'M':
        {
            Writer *out = FileWriter(stdout);
            ManPageWrite(out, "cf-runagent", time(NULL),
                         CF_RUNAGENT_SHORT_DESCRIPTION,
                         CF_RUNAGENT_MANPAGE_LONG_DESCRIPTION,
                         OPTIONS, HINTS,
                         true);
            FileWriterDetach(out);
            exit(EXIT_SUCCESS);
        }

        case 'x':
            Log(LOG_LEVEL_ERR, "Option \"-x\" has been deprecated");
            exit(EXIT_FAILURE);

        case 'C':
            if (!GenericAgentConfigParseColor(config, optarg))
            {
                exit(EXIT_FAILURE);
            }
            break;

        case 'l':
            LoggingEnableTimestamps(true);
            break;

        /* long options only */
        case 0:

            if (strcmp(OPTIONS[longopt_idx].name, "log-modules") == 0)
            {
                bool ret = LogEnableModulesFromString(optarg);
                if (!ret)
                {
                    exit(EXIT_FAILURE);
                }
            }
            else if (strcmp(OPTIONS[longopt_idx].name, "remote-bundles") == 0)
            {
                size_t len = strlen(REMOTEBUNDLES);
                StrCatDelim(REMOTEBUNDLES, sizeof(REMOTEBUNDLES), &len,
                            optarg, ',');
                if (len >= sizeof(REMOTEBUNDLES))
                {
                    Log(LOG_LEVEL_ERR, "Argument too long (--remote-bundles)");
                    exit(EXIT_FAILURE);
                }
            }
            break;

        default:
        {
            Writer *w = FileWriter(stdout);
            WriterWriteHelp(w, "cf-runagent", OPTIONS, HINTS, true, NULL);
            FileWriterDetach(w);
        }
        exit(EXIT_FAILURE);

        }
    }

    if (!GenericAgentConfigParseArguments(config, argc - optind, argv + optind))
    {
        Log(LOG_LEVEL_ERR, "Too many arguments");
        exit(EXIT_FAILURE);
    }

    return config;
}