Esempio n. 1
0
static int SelectExecRegexMatch(char *filename, char *crit, char *prog)
{
    char line[CF_BUFSIZE];
    FILE *pp;
    char buf[CF_MAXVARSIZE];

// insert real value of $(this.promiser) in command

    ReplaceStr(prog, buf, sizeof(buf), "$(this.promiser)", filename);
    ReplaceStr(prog, buf, sizeof(buf), "${this.promiser}", filename);

    if ((pp = cf_popen(buf, "r")) == NULL)
    {
        CfOut(cf_error, "cf_popen", "Couldn't open pipe to command %s\n", buf);
        return false;
    }

    while (!feof(pp))
    {
        line[0] = '\0';
        CfReadLine(line, CF_BUFSIZE, pp);       /* One buffer only */

        if (FullTextMatch(crit, line))
        {
            cf_pclose(pp);
            return true;
        }
    }

    cf_pclose(pp);
    return false;
}
Esempio n. 2
0
int VerifyMount(char *name, Attributes a, Promise *pp)
{
    char comm[CF_BUFSIZE], line[CF_BUFSIZE];
    FILE *pfp;
    char *host, *rmountpt, *mountpt;

    host = a.mount.mount_server;
    rmountpt = a.mount.mount_source;
    mountpt = name;

    if (!DONTDO)
    {
        snprintf(comm, CF_BUFSIZE, "%s %s:%s %s", GetArg0(VMOUNTCOMM[VSYSTEMHARDCLASS]), host, rmountpt, mountpt);

        if ((pfp = cf_popen(comm, "r")) == NULL)
        {
            CfOut(cf_error, "", " !! Failed to open pipe from %s\n", GetArg0(VMOUNTCOMM[VSYSTEMHARDCLASS]));
            return 0;
        }

        CfReadLine(line, CF_BUFSIZE, pfp);

        if (strstr(line, "busy") || strstr(line, "Busy"))
        {
            cfPS(cf_inform, CF_INTERPT, "", pp, a, " !! The device under %s cannot be mounted\n", mountpt);
            cf_pclose(pfp);
            return 1;
        }

        cf_pclose(pfp);
    }

    cfPS(cf_inform, CF_CHG, "", pp, a, " -> Mounting %s to keep promise\n", mountpt);
    return 0;
}
Esempio n. 3
0
int VerifyUnmount(char *name, Attributes a, Promise *pp)
{
    char comm[CF_BUFSIZE], line[CF_BUFSIZE];
    FILE *pfp;
    char *mountpt;

    mountpt = name;

    if (!DONTDO)
    {
        snprintf(comm, CF_BUFSIZE, "%s %s", VUNMOUNTCOMM[VSYSTEMHARDCLASS], mountpt);

        if ((pfp = cf_popen(comm, "r")) == NULL)
        {
            CfOut(cf_error, "", " !! Failed to open pipe from %s\n", VUNMOUNTCOMM[VSYSTEMHARDCLASS]);
            return 0;
        }

        CfReadLine(line, CF_BUFSIZE, pfp);

        if ((strstr(line, "busy")) || (strstr(line, "Busy")))
        {
            cfPS(cf_inform, CF_INTERPT, "", pp, a, " !! The device under %s cannot be unmounted\n", mountpt);
            cf_pclose(pfp);
            return 1;
        }

        cf_pclose(pfp);
    }

    cfPS(cf_inform, CF_CHG, "", pp, a, " -> Unmounting %s to keep promise\n", mountpt);
    return 0;
}
Esempio n. 4
0
File: nfs.c Progetto: ouafae31/core
int VerifyMount(EvalContext *ctx, char *name, Attributes a, Promise *pp)
{
    char comm[CF_BUFSIZE], line[CF_BUFSIZE];
    FILE *pfp;
    char *host, *rmountpt, *mountpt, *opts=NULL;

    host = a.mount.mount_server;
    rmountpt = a.mount.mount_source;
    mountpt = name;

    /* Check for options required for this mount - i.e., -o ro,rsize, etc. */
    if (a.mount.mount_options)
    {
        opts = Rlist2String(a.mount.mount_options, ",");
    }
    else
    {
        opts = xstrdup(VMOUNTOPTS[VSYSTEMHARDCLASS]);
    }

    if (!DONTDO)
    {
        snprintf(comm, CF_BUFSIZE, "%s -o %s %s:%s %s", CommandArg0(VMOUNTCOMM[VSYSTEMHARDCLASS]), opts, host, rmountpt, mountpt);

        if ((pfp = cf_popen(comm, "r", true)) == NULL)
        {
            Log(LOG_LEVEL_ERR, "Failed to open pipe from %s", CommandArg0(VMOUNTCOMM[VSYSTEMHARDCLASS]));
            return 0;
        }

        ssize_t res = CfReadLine(line, CF_BUFSIZE, pfp);

        if (res == -1)
        {
            Log(LOG_LEVEL_ERR, "Unable to read output of mount command. (fread: %s)", GetErrorStr());
            cf_pclose(pfp);
            return 0;
        }

        if (res != 0 && ((strstr(line, "busy")) || (strstr(line, "Busy"))))
        {
            cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_INTERRUPTED, pp, a, "The device under %s cannot be mounted\n", mountpt);
            cf_pclose(pfp);
            return 1;
        }

        cf_pclose(pfp);
    }

    /* Since opts is either Rlist2String or xstrdup'd, we need to always free it */
    free(opts);

    cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "Mounting %s to keep promise\n", mountpt);
    return 0;
}
Esempio n. 5
0
int VerifyMount(char *name, Attributes a, Promise *pp)
{
    char comm[CF_BUFSIZE], line[CF_BUFSIZE];
    FILE *pfp;
    char *host, *rmountpt, *mountpt, *opts=NULL;

    host = a.mount.mount_server;
    rmountpt = a.mount.mount_source;
    mountpt = name;

    /* Check for options required for this mount - i.e., -o ro,rsize, etc. */
    if (a.mount.mount_options)
    {
        opts = Rlist2String(a.mount.mount_options, ",");
    }
    else
    {
        opts = xstrdup(VMOUNTOPTS[VSYSTEMHARDCLASS]);
    }

    if (!DONTDO)
    {
        snprintf(comm, CF_BUFSIZE, "%s -o %s %s:%s %s", GetArg0(VMOUNTCOMM[VSYSTEMHARDCLASS]), opts, host, rmountpt, mountpt);

        if ((pfp = cf_popen(comm, "r")) == NULL)
        {
            CfOut(cf_error, "", " !! Failed to open pipe from %s\n", GetArg0(VMOUNTCOMM[VSYSTEMHARDCLASS]));
            return 0;
        }

        if (CfReadLine(line, CF_BUFSIZE, pfp) == -1)
        {
            FatalError("Error in CfReadLine");
        }

        if ((strstr(line, "busy")) || (strstr(line, "Busy")))
        {
            cfPS(cf_inform, CF_INTERPT, "", pp, a, " !! The device under %s cannot be mounted\n", mountpt);
            cf_pclose(pfp);
            return 1;
        }

        cf_pclose(pfp);
    }

    /* Since opts is either Rlist2String or xstrdup'd, we need to always free it */
    free(opts);

    cfPS(cf_inform, CF_CHG, "", pp, a, " -> Mounting %s to keep promise\n", mountpt);
    return 0;
}
Esempio n. 6
0
PromiseResult VerifyUnmount(EvalContext *ctx, char *name, const Attributes *a, const Promise *pp)
{
    char comm[CF_BUFSIZE];
    FILE *pfp;
    char *mountpt;

    mountpt = name;

    PromiseResult result = PROMISE_RESULT_NOOP;
    if (!DONTDO)
    {
        snprintf(comm, CF_BUFSIZE, "%s %s", VUNMOUNTCOMM[VSYSTEMHARDCLASS], mountpt);

        if ((pfp = cf_popen(comm, "r", true)) == NULL)
        {
            Log(LOG_LEVEL_ERR, "Failed to open pipe from %s", VUNMOUNTCOMM[VSYSTEMHARDCLASS]);
            return result;
        }

        size_t line_size = CF_BUFSIZE;
        char *line = xmalloc(line_size);

        ssize_t res = CfReadLine(&line, &line_size, pfp);
        if (res == -1)
        {
            cf_pclose(pfp);
            free(line);

            if (!feof(pfp))
            {
                Log(LOG_LEVEL_ERR, "Unable to read output of unmount command. (fread: %s)", GetErrorStr());
                return result;
            }
        }
        else if (res > 0 && ((strstr(line, "busy")) || (strstr(line, "Busy"))))
        {
            cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_INTERRUPTED, pp, a, "The device under '%s' cannot be unmounted", mountpt);
            result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED);
            cf_pclose(pfp);
            free(line);
            return result;
        }
    }

    cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "Unmounting '%s' to keep promise", mountpt);
    result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE);
    return result;
}
Esempio n. 7
0
static bool SelectExecRegexMatch(EvalContext *ctx, char *filename, char *crit, char *prog)
{
    // insert real value of $(this.promiser) in command

    char *buf_tmp = SearchAndReplace(prog, "$(this.promiser)", filename);
    char *buf = SearchAndReplace(buf_tmp, "${this.promiser}", filename);
    free(buf_tmp);

    FILE *pp = cf_popen(buf, "r", true);
    if (pp == NULL)
    {
        Log(LOG_LEVEL_ERR, "Couldn't open pipe to command '%s'. (cf_popen: %s)", buf, GetErrorStr());
        free(buf);
        return false;
    }

    size_t line_size = CF_BUFSIZE;
    char *line = xmalloc(line_size);

    for (;;)
    {
        ssize_t res = CfReadLine(&line, &line_size, pp);
        if (res == -1)
        {
            if (!feof(pp))
            {
                Log(LOG_LEVEL_ERR, "Error reading output from command '%s'. (fgets: %s)", buf, GetErrorStr());
            }
            cf_pclose(pp);
            free(line);
            free(buf);
            return false;
        }

        if (FullTextMatch(ctx, crit, line))
        {
            cf_pclose(pp);
            free(line);
            free(buf);
            return true;
        }
    }

    cf_pclose(pp);
    free(line);
    free(buf);
    return false;
}
Esempio n. 8
0
static VersionCmpResult RunCmpCommand(const char *command, const char *v1, const char *v2, Attributes a, Promise *pp)
{
    char expanded_command[CF_EXPANDSIZE];

    SetNewScope("cf_pack_context");
    NewScalar("cf_pack_context", "v1", v1, cf_str);
    NewScalar("cf_pack_context", "v2", v2, cf_str);
    ExpandScalar(command, expanded_command);
    DeleteScope("cf_pack_context");

    FILE *pfp = a.packages.package_commands_useshell ? cf_popen_sh(expanded_command, "w") : cf_popen(expanded_command, "w");

    if (pfp == NULL)
    {
        cfPS(cf_error, CF_FAIL, "cf_popen", pp, a, "Can not start package version comparison command: %s", expanded_command);
        return VERCMP_ERROR;
    }

    CfOut(cf_verbose, "", "Executing %s", expanded_command);

    int retcode = cf_pclose(pfp);

    if (retcode == -1)
    {
        cfPS(cf_error, CF_FAIL, "cf_pclose", pp, a, "Error during package version comparison command execution: %s",
            expanded_command);
        return VERCMP_ERROR;
    }

    return retcode == 0;
}
void MonNetworkSnifferOpen(void)
{
    char tcpbuffer[CF_BUFSIZE];

    if (TCPDUMP)
    {
        struct stat statbuf;
        char buffer[CF_MAXVARSIZE];

        sscanf(CF_TCPDUMP_COMM, "%s", buffer);

        if (stat(buffer, &statbuf) != -1)
        {
            if ((TCPPIPE = cf_popen(CF_TCPDUMP_COMM, "r", true)) == NULL)
            {
                TCPDUMP = false;
            }

            /* Skip first banner */
            if (fgets(tcpbuffer, sizeof(tcpbuffer), TCPPIPE) == NULL)
            {
                UnexpectedError("Failed to read output from '%s'", CF_TCPDUMP_COMM);
                cf_pclose(TCPPIPE);
                TCPPIPE = NULL;
                TCPDUMP = false;
            }
        }
        else
        {
            TCPDUMP = false;
        }
    }
}
Esempio n. 10
0
static bool SupportsOption(const char *cmd, const char *option)
{
    bool supports_option = false;
    char help_argument[] = " --help";
    char help_command[strlen(cmd) + sizeof(help_argument)];
    xsnprintf(help_command, sizeof(help_command), "%s%s", cmd, help_argument);

    FILE *fptr = cf_popen(help_command, "r", true);
    char *buf = NULL;
    size_t bufsize = 0;
    size_t optlen = strlen(option);
    while (CfReadLine(&buf, &bufsize, fptr) >= 0)
    {
        char *m_pos = buf;
        while ((m_pos = strstr(m_pos, option)))
        {
            // Check against false alarms, e.g. hyphenated words in normal text or an
            // option (say, "-M") that is part of "--M".
            if ((m_pos == buf
                    || (m_pos[-1] != '-' && (isspace(m_pos[-1]) || ispunct(m_pos[-1]))))
                && (m_pos[optlen] == '\0'
                    || (isspace(m_pos[optlen]) || ispunct(m_pos[optlen]))))
            {
                supports_option = true;
                // Break out of strstr loop, but read till the end to avoid broken pipes.
                break;
            }
            m_pos++;
        }
    }
    cf_pclose(fptr);
    free(buf);

    return supports_option;
}
Esempio n. 11
0
static bool SelectExecRegexMatch(EvalContext *ctx, char *filename, char *crit, char *prog)
{
    char line[CF_BUFSIZE];
    FILE *pp;
    char buf[CF_MAXVARSIZE];

// insert real value of $(this.promiser) in command

    ReplaceStr(prog, buf, sizeof(buf), "$(this.promiser)", filename);
    ReplaceStr(prog, buf, sizeof(buf), "${this.promiser}", filename);

    if ((pp = cf_popen(buf, "r", true)) == NULL)
    {
        Log(LOG_LEVEL_ERR, "Couldn't open pipe to command '%s'. (cf_popen: %s)", buf, GetErrorStr());
        return false;
    }

    for (;;)
    {
        ssize_t res = CfReadLine(line, CF_BUFSIZE, pp);
        if (res == -1)
        {
            Log(LOG_LEVEL_ERR, "Error reading output from command '%s'. (fgets: %s)", buf, GetErrorStr());
            cf_pclose(pp);
            return false;
        }

        if (res == 0)
        {
            cf_pclose(pp);
            return false;
        }

        if (FullTextMatch(ctx, crit, line))
        {
            cf_pclose(pp);
            return true;
        }
    }

    cf_pclose(pp);
    return false;
}
Esempio n. 12
0
static bool ChangePasswordHashUsingChpasswd(const char *puser, const char *password)
{
    int status;
    const char *cmd_str = CHPASSWD " -e";
    Log(LOG_LEVEL_VERBOSE, "Changing password hash for user '%s'. (command: '%s')", puser, cmd_str);
    FILE *cmd = cf_popen_sh(cmd_str, "w");
    if (!cmd)
    {
        Log(LOG_LEVEL_ERR, "Could not launch password changing command '%s': %s.", cmd_str, GetErrorStr());
        return false;
    }

    // String lengths plus a ':' and a '\n', but not including '\0'.
    size_t total_len = strlen(puser) + strlen(password) + 2;
    char change_string[total_len + 1];
    xsnprintf(change_string, total_len + 1, "%s:%s\n", puser, password);
    clearerr(cmd);
    if (fwrite(change_string, total_len, 1, cmd) != 1)
    {
        const char *error_str;
        if (ferror(cmd))
        {
            error_str = GetErrorStr();
        }
        else
        {
            error_str = "Unknown error";
        }
        Log(LOG_LEVEL_ERR, "Could not write password to password changing command '%s': %s.", cmd_str, error_str);
        cf_pclose(cmd);
        return false;
    }
    status = cf_pclose(cmd);
    if (status)
    {
        Log(LOG_LEVEL_ERR, "'%s' returned non-zero status: %i\n", cmd_str, status);
        return false;
    }

    return true;
}
Esempio n. 13
0
File: nfs.c Progetto: ouafae31/core
int VerifyUnmount(EvalContext *ctx, char *name, Attributes a, Promise *pp)
{
    char comm[CF_BUFSIZE], line[CF_BUFSIZE];
    FILE *pfp;
    char *mountpt;

    mountpt = name;

    if (!DONTDO)
    {
        snprintf(comm, CF_BUFSIZE, "%s %s", VUNMOUNTCOMM[VSYSTEMHARDCLASS], mountpt);

        if ((pfp = cf_popen(comm, "r", true)) == NULL)
        {
            Log(LOG_LEVEL_ERR, "Failed to open pipe from %s", VUNMOUNTCOMM[VSYSTEMHARDCLASS]);
            return 0;
        }

        ssize_t res = CfReadLine(line, CF_BUFSIZE, pfp);

        if (res == -1)
        {
            Log(LOG_LEVEL_ERR, "Unable to read output of unmount command. (fread: %s)", GetErrorStr());
            cf_pclose(pfp);
            return 0;
        }

        if (res != 0 && ((strstr(line, "busy")) || (strstr(line, "Busy"))))
        {
            cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_INTERRUPTED, pp, a, "The device under %s cannot be unmounted\n", mountpt);
            cf_pclose(pfp);
            return 1;
        }

        cf_pclose(pfp);
    }

    cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "Unmounting %s to keep promise\n", mountpt);
    return 0;
}
Esempio n. 14
0
static void MD5Random(unsigned char digest[EVP_MAX_MD_SIZE + 1])
   /* Make a decent random number by crunching some system states & garbage through
      MD5. We can use this as a seed for pseudo random generator */
{
    unsigned char buffer[CF_BUFSIZE];
    char pscomm[CF_BUFSIZE];
    char uninitbuffer[100];
    int md_len;
    const EVP_MD *md;
    EVP_MD_CTX context;
    FILE *pp;

    CfOut(cf_verbose, "", "Looking for a random number seed...\n");

#ifdef HAVE_NOVA
    md = EVP_get_digestbyname("sha256");
#else
    md = EVP_get_digestbyname("md5");
#endif

    EVP_DigestInit(&context, md);

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

    snprintf(buffer, CF_BUFSIZE, "%d%d%25s", (int) CFSTARTTIME, (int) *digest, VFQNAME);

    EVP_DigestUpdate(&context, buffer, CF_BUFSIZE);

    snprintf(pscomm, CF_BUFSIZE, "%s %s", VPSCOMM[VSYSTEMHARDCLASS], VPSOPTS[VSYSTEMHARDCLASS]);

    if ((pp = cf_popen(pscomm, "r")) != NULL)
    {
        CfOut(cf_error, "cf_popen", "Couldn't open the process list with command %s\n", pscomm);

        while (!feof(pp))
        {
            CfReadLine(buffer, CF_BUFSIZE, pp);
            EVP_DigestUpdate(&context, buffer, CF_BUFSIZE);
        }
    }

    uninitbuffer[99] = '\0';
    snprintf(buffer, CF_BUFSIZE - 1, "%ld %s", time(NULL), uninitbuffer);
    EVP_DigestUpdate(&context, buffer, CF_BUFSIZE);

    cf_pclose(pp);

    EVP_DigestFinal(&context, digest, &md_len);
}
Esempio n. 15
0
static VersionCmpResult RunCmpCommand(EvalContext *ctx, const char *command, const char *v1, const char *v2, Attributes a,
                                      const Promise *pp, PromiseResult *result)
{
    Buffer *expanded_command = BufferNew();
    {
        VarRef *ref_v1 = VarRefParseFromScope("v1", PACKAGES_CONTEXT);
        EvalContextVariablePut(ctx, ref_v1, v1, CF_DATA_TYPE_STRING, "source=promise");

        VarRef *ref_v2 = VarRefParseFromScope("v2", PACKAGES_CONTEXT);
        EvalContextVariablePut(ctx, ref_v2, v2, CF_DATA_TYPE_STRING, "source=promise");

        ExpandScalar(ctx, NULL, PACKAGES_CONTEXT, command, expanded_command);

        EvalContextVariableRemove(ctx, ref_v1);
        VarRefDestroy(ref_v1);

        EvalContextVariableRemove(ctx, ref_v2);
        VarRefDestroy(ref_v2);
    }

    FILE *pfp = a.packages.package_commands_useshell ? cf_popen_sh(BufferData(expanded_command), "w") : cf_popen(BufferData(expanded_command), "w", true);

    if (pfp == NULL)
    {
        cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Can not start package version comparison command '%s'. (cf_popen: %s)",
             BufferData(expanded_command), GetErrorStr());
        *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL);
        BufferDestroy(expanded_command);
        return VERCMP_ERROR;
    }

    Log(LOG_LEVEL_VERBOSE, "Executing '%s'", BufferData(expanded_command));

    int retcode = cf_pclose(pfp);

    if (retcode == -1)
    {
        cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Error during package version comparison command execution '%s'. (cf_pclose: %s)",
             BufferData(expanded_command), GetErrorStr());
        *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL);
        BufferDestroy(expanded_command);
        return VERCMP_ERROR;
    }

    BufferDestroy(expanded_command);

    return retcode == 0;
}
Esempio n. 16
0
static void Sniff(Item *ip_addresses, long iteration, double *cf_this)
{
    char tcpbuffer[CF_BUFSIZE];

    Log(LOG_LEVEL_VERBOSE, "Reading from tcpdump...");
    memset(tcpbuffer, 0, CF_BUFSIZE);
    signal(SIGALRM, CfenvTimeOut);
    alarm(SLEEPTIME);
    TCPPAUSE = false;

    while (!feof(TCPPIPE) && !IsPendingTermination())
    {
        if (TCPPAUSE)
        {
            break;
        }

        if (fgets(tcpbuffer, sizeof(tcpbuffer), TCPPIPE) == NULL)
        {
            UnexpectedError("Unable to read data from tcpdump; closing pipe");
            cf_pclose(TCPPIPE);
            TCPPIPE = NULL;
            TCPDUMP = false;
            break;
        }

        if (TCPPAUSE)
        {
            break;
        }

        if (strstr(tcpbuffer, "tcpdump:"))      /* Error message protect sleeptime */
        {
            Log(LOG_LEVEL_DEBUG, "Error - '%s'", tcpbuffer);
            alarm(0);
            TCPDUMP = false;
            break;
        }

        AnalyzeArrival(ip_addresses, iteration, tcpbuffer, cf_this);
    }

    signal(SIGALRM, SIG_DFL);
    TCPPAUSE = false;
    fflush(TCPPIPE);
}
Esempio n. 17
0
static int Unix_GatherProcessUsers(struct Item **userList, int *userListSz, int *numRootProcs, int *numOtherProcs)
{
FILE *pp;
char pscomm[CF_BUFSIZE];
char user[CF_MAXVARSIZE];
char vbuff[CF_BUFSIZE];

snprintf(pscomm,CF_BUFSIZE,"%s %s",VPSCOMM[VSYSTEMHARDCLASS],VPSOPTS[VSYSTEMHARDCLASS]);

if ((pp = cf_popen(pscomm,"r")) == NULL)
   {
   return false;
   }

CfReadLine(vbuff,CF_BUFSIZE,pp); 

while (!feof(pp))
   {
   CfReadLine(vbuff,CF_BUFSIZE,pp);
   sscanf(vbuff,"%s",user);

   if (strcmp(user,"USER") == 0)
      {
      continue;
      }

   if (!IsItemIn(*userList,user))
      {
      PrependItem(userList,user,NULL);
      (*userListSz)++;
      }

   if (strcmp(user,"root") == 0)
      {
      (*numRootProcs)++;
      }
   else
      {
      (*numOtherProcs)++;
      }
   }

cf_pclose(pp);
return true;
}
Esempio n. 18
0
static VersionCmpResult RunCmpCommand(EvalContext *ctx, const char *command, const char *v1, const char *v2, Attributes a, Promise *pp)
{
    char expanded_command[CF_EXPANDSIZE];

    {
        VarRef *ref_v1 = VarRefParseFromScope("v1", "cf_pack_context");
        EvalContextVariablePut(ctx, ref_v1, (Rval) { v1, RVAL_TYPE_SCALAR }, DATA_TYPE_STRING);

        VarRef *ref_v2 = VarRefParseFromScope("v2", "cf_pack_context");
        EvalContextVariablePut(ctx, ref_v2, (Rval) { v2, RVAL_TYPE_SCALAR }, DATA_TYPE_STRING);

        ExpandScalar(ctx, NULL, "cf_pack_context", command, expanded_command);

        EvalContextVariableRemove(ctx, ref_v1);
        VarRefDestroy(ref_v1);

        EvalContextVariableRemove(ctx, ref_v2);
        VarRefDestroy(ref_v2);
    }

    FILE *pfp = a.packages.package_commands_useshell ? cf_popen_sh(expanded_command, "w") : cf_popen(expanded_command, "w", true);

    if (pfp == NULL)
    {
        cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Can not start package version comparison command '%s'. (cf_popen: %s)",
             expanded_command, GetErrorStr());
        return VERCMP_ERROR;
    }

    Log(LOG_LEVEL_VERBOSE, "Executing '%s'", expanded_command);

    int retcode = cf_pclose(pfp);

    if (retcode == -1)
    {
        cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Error during package version comparison command execution '%s'. (cf_pclose: %s)",
            expanded_command, GetErrorStr());
        return VERCMP_ERROR;
    }

    return retcode == 0;
}
Esempio n. 19
0
static void LoadPlatformExtraTable(void)
{
    if (UCB_PS_MAP)
    {
        return;
    }

    UCB_PS_MAP = StringMapNew();

    FILE *cmd = OpenUcbPsPipe();
    if (!cmd)
    {
        return;
    }
    ReadFromUcbPsPipe(cmd);
    if (cf_pclose(cmd) != 0)
    {
        Log(LOG_LEVEL_WARNING, "Command returned non-zero while gathering "
            "extra process information.");
        // Make an empty map, in this case. The information can't be trusted.
        StringMapClear(UCB_PS_MAP);
    }
}
Esempio n. 20
0
void MountAll()
{
    char line[CF_BUFSIZE];
    FILE *pp;

    if (DONTDO)
    {
        CfOut(cf_verbose, "", "Promised to mount filesystem, but not on this trial run\n");
        return;
    }
    else
    {
        CfOut(cf_verbose, "", " -> Attempting to mount all filesystems.\n");
    }

#if defined(__CYGWIN__)
    /* This is a shell script. Make sure it hasn't been compromised. */

    struct stat sb;

    if (cfstat("/etc/fstab", &sb) == -1)
    {
        int fd;
        if ((fd = creat("/etc/fstab", 0755)) > 0)
        {
            if (write(fd, "#!/bin/sh\n\n", 10) != 10)
            {
                UnexpectedError("Failed to write to file '/etc/fstab'");
            }
            close(fd);
        }
        else
        {
            if (sb.st_mode & (S_IWOTH | S_IWGRP))
            {
                CfOut(cf_error, "", "File /etc/fstab was insecure. Cannot mount filesystems.\n");
                return;
            }
        }
    }
#endif

    SetTimeOut(RPCTIMEOUT);

    if ((pp = cf_popen(VMOUNTCOMM[VSYSTEMHARDCLASS], "r")) == NULL)
    {
        CfOut(cf_error, "cf_popen", "Failed to open pipe from %s\n", VMOUNTCOMM[VSYSTEMHARDCLASS]);
        return;
    }

    while (!feof(pp))
    {
        if (ferror(pp))         /* abortable */
        {
            CfOut(cf_inform, "ferror", "Error mounting filesystems\n");
            break;
        }

        if (CfReadLine(line, CF_BUFSIZE, pp) == -1)
        {
            FatalError("Error in CfReadLine");
        }

        if (ferror(pp))         /* abortable */
        {
            CfOut(cf_inform, "ferror", "Error mounting filesystems\n");
            break;
        }

        if ((strstr(line, "already mounted")) || (strstr(line, "exceeded")) || (strstr(line, "determined")))
        {
            continue;
        }

        if (strstr(line, "not supported"))
        {
            continue;
        }

        if ((strstr(line, "denied")) || (strstr(line, "RPC")))
        {
            CfOut(cf_error, "", "There was a mount error, trying to mount one of the filesystems on this host.\n");
            break;
        }

        if ((strstr(line, "trying")) && (!strstr(line, "NFS version 2")) && (!strstr(line, "vers 3")))
        {
            CfOut(cf_error, "", "Attempting abort because mount went into a retry loop.\n");
            break;
        }
    }

    alarm(0);
    signal(SIGALRM, SIG_DFL);
    cf_pclose(pp);
}
Esempio n. 21
0
void MonNetworkGatherData(double *cf_this)
{
    FILE *pp;
    char local[CF_BUFSIZE], remote[CF_BUFSIZE], comm[CF_BUFSIZE];
    Item *in[ATTR], *out[ATTR];
    char *sp;
    int i;
    char vbuff[CF_BUFSIZE];
    enum cf_netstat_type { cfn_new, cfn_old } type = cfn_new;
    enum cf_packet_type { cfn_tcp4, cfn_tcp6 } packet = cfn_tcp4;

    CfDebug("GatherSocketData()\n");

    for (i = 0; i < ATTR; i++)
    {
        in[i] = out[i] = NULL;
    }

    DeleteItemList(ALL_INCOMING);
    ALL_INCOMING = NULL;

    sscanf(VNETSTAT[VSYSTEMHARDCLASS], "%s", comm);

    strcat(comm, " -an");

    if ((pp = cf_popen(comm, "r")) == NULL)
    {
        return;
    }

    while (!feof(pp))
    {
        memset(local, 0, CF_BUFSIZE);
        memset(remote, 0, CF_BUFSIZE);

        CfReadLine(vbuff, CF_BUFSIZE, pp);

        if (strstr(vbuff, "UNIX"))
        {
            break;
        }

        if (!(strstr(vbuff, ":") || strstr(vbuff, ".")))
        {
            continue;
        }

        /* Different formats here ... ugh.. pick a model */

        // If this is old style, we look for chapter headings, e.g. "TCP: IPv4"

        if (strncmp(vbuff,"TCP:",4) == 0 && strstr(vbuff+4,"6"))
        {
            packet = cfn_tcp6;
            type = cfn_old;
            continue;
        }
        else if (strncmp(vbuff,"TCP:",4) == 0 && strstr(vbuff+4,"4"))
        {
            packet = cfn_tcp4;
            type = cfn_old;
            continue;
        }

        // Line by line state in modern/linux output

        if (strncmp(vbuff,"tcp6",4) == 0)
        {
            packet = cfn_tcp6;
            type = cfn_new;
        }
        else if (strncmp(vbuff,"tcp",3) == 0)
        {
            packet = cfn_tcp4;
            type = cfn_new;
        }

        // End extract type
        
        switch (type)
        {
        case cfn_new:  sscanf(vbuff, "%*s %*s %*s %s %s", local, remote);  /* linux-like */
            break;
            
        case cfn_old:
            sscanf(vbuff, "%s %s", local, remote);
            break;
        }

        if (strlen(local) == 0)
        {
            continue;
        }

        // Extract the port number from the end of the string
        
        for (sp = local + strlen(local); (*sp != '.') && (*sp != ':')  && (sp > local); sp--)
        {
        }

        *sp = '\0'; // Separate address from port number
        sp++;

        if (strstr(vbuff, "LISTEN"))
        {
            // General bucket

            IdempPrependItem(&ALL_INCOMING, sp, NULL);

            // Categories the incoming ports by packet types

            switch (packet)
            {
            case cfn_tcp4:
                IdempPrependItem(&MON_TCP4, sp, local);
                break;
            case cfn_tcp6:
                IdempPrependItem(&MON_TCP6, sp, local);
                break;
            default:
                break;
            }
        }


        // Now look at outgoing
        
        for (sp = remote + strlen(remote); (sp >= remote) && !isdigit((int) *sp); sp--)
        {
        }

        sp++;

        // Now look for the specific vital signs to count frequencies
        
        for (i = 0; i < ATTR; i++)
        {
            char *spend;

            for (spend = local + strlen(local) - 1; isdigit((int) *spend); spend--)
            {
            }

            spend++;

            if (strcmp(spend, ECGSOCKS[i].portnr) == 0)
            {
                cf_this[ECGSOCKS[i].in]++;
                AppendItem(&in[i], vbuff, "");
            }

            for (spend = remote + strlen(remote) - 1; (sp >= remote) && isdigit((int) *spend); spend--)
            {
            }

            spend++;

            if (strcmp(spend, ECGSOCKS[i].portnr) == 0)
            {
                cf_this[ECGSOCKS[i].out]++;
                AppendItem(&out[i], vbuff, "");
            }
        }
    }

    cf_pclose(pp);

/* Now save the state for ShowState() 
   the state is not smaller than the last or at least 40 minutes
   older. This mirrors the persistence of the maxima classes */

    for (i = 0; i < ATTR; i++)
    {
        struct stat statbuf;
        time_t now = time(NULL);

        CfDebug("save incoming %s\n", ECGSOCKS[i].name);
        snprintf(vbuff, CF_MAXVARSIZE, "%s/state/cf_incoming.%s", CFWORKDIR, ECGSOCKS[i].name);
        if (cfstat(vbuff, &statbuf) != -1)
        {
            if ((ByteSizeList(in[i]) < statbuf.st_size) && (now < statbuf.st_mtime + 40 * 60))
            {
                CfOut(cf_verbose, "", "New state %s is smaller, retaining old for 40 mins longer\n", ECGSOCKS[i].name);
                DeleteItemList(in[i]);
                continue;
            }
        }

        SetNetworkEntropyClasses(ECGSOCKS[i].name, "in", in[i]);
        RawSaveItemList(in[i], vbuff);
        DeleteItemList(in[i]);
        CfDebug("Saved in netstat data in %s\n", vbuff);
    }

    for (i = 0; i < ATTR; i++)
    {
        struct stat statbuf;
        time_t now = time(NULL);

        CfDebug("save outgoing %s\n", ECGSOCKS[i].name);
        snprintf(vbuff, CF_MAXVARSIZE, "%s/state/cf_outgoing.%s", CFWORKDIR, ECGSOCKS[i].name);

        if (cfstat(vbuff, &statbuf) != -1)
        {
            if ((ByteSizeList(out[i]) < statbuf.st_size) && (now < statbuf.st_mtime + 40 * 60))
            {
                CfOut(cf_verbose, "", "New state %s is smaller, retaining old for 40 mins longer\n", ECGSOCKS[i].name);
                DeleteItemList(out[i]);
                continue;
            }
        }

        SetNetworkEntropyClasses(ECGSOCKS[i].name, "out", out[i]);
        RawSaveItemList(out[i], vbuff);
        CfDebug("Saved out netstat data in %s\n", vbuff);
        DeleteItemList(out[i]);
    }
}
Esempio n. 22
0
bool GetExecOutput(const char *command, char *buffer, bool useshell)
/* Buffer initially contains whole exec string */
{
    int offset = 0;
    char line[CF_EXPANDSIZE];
    FILE *pp;

    CfDebug("GetExecOutput(%s,%s) - use shell = %d\n", command, buffer, useshell);

    if (useshell)
    {
        pp = cf_popen_sh(command, "r");
    }
    else
    {
        pp = cf_popen(command, "r", true);
    }

    if (pp == NULL)
    {
        CfOut(OUTPUT_LEVEL_ERROR, "cf_popen", "Couldn't open pipe to command %s\n", command);
        return false;
    }

    memset(buffer, 0, CF_EXPANDSIZE);

    for (;;)
    {
        ssize_t res = CfReadLine(line, CF_EXPANDSIZE, pp);
        if (res == 0)
        {
            break;
        }

        if (res == -1)
        {
            CfOut(OUTPUT_LEVEL_ERROR, "fread", "Unable to read output of command %s", command);
            cf_pclose(pp);
            return false;
        }

        if (strlen(line) + offset > CF_EXPANDSIZE - 10)
        {
            CfOut(OUTPUT_LEVEL_ERROR, "", "Buffer exceeded %d bytes in exec %s\n", CF_EXPANDSIZE, command);
            break;
        }

        snprintf(buffer + offset, CF_EXPANDSIZE, "%s\n", line);

        offset += strlen(line) + 1;
    }

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

    CfDebug("GetExecOutput got: [%s]\n", buffer);

    cf_pclose(pp);
    return true;
}
Esempio n. 23
0
int LoadMountInfo(Rlist **list)
/* This is, in fact, the most portable way to read the mount info! */
/* Depressing, isn't it? */
{
    FILE *pp;
    char buf1[CF_BUFSIZE], buf2[CF_BUFSIZE], buf3[CF_BUFSIZE];
    char host[CF_MAXVARSIZE], source[CF_BUFSIZE], mounton[CF_BUFSIZE], vbuff[CF_BUFSIZE];
    int i, nfs = false;

    for (i = 0; VMOUNTCOMM[VSYSTEMHARDCLASS][i] != ' '; i++)
    {
        buf1[i] = VMOUNTCOMM[VSYSTEMHARDCLASS][i];
    }

    buf1[i] = '\0';

    SetTimeOut(RPCTIMEOUT);

    if ((pp = cf_popen(buf1, "r")) == NULL)
    {
        CfOut(cf_error, "cf_popen", "Can't open %s\n", buf1);
        return false;
    }

    do
    {
        vbuff[0] = buf1[0] = buf2[0] = buf3[0] = source[0] = '\0';

        if (ferror(pp))         /* abortable */
        {
            CfOut(cf_error, "ferror", "Error getting mount info\n");
            break;
        }

        CfReadLine(vbuff, CF_BUFSIZE, pp);

        if (ferror(pp))         /* abortable */
        {
            CfOut(cf_error, "ferror", "Error getting mount info\n");
            break;
        }

        if (strstr(vbuff, "nfs"))
        {
            nfs = true;
        }

        sscanf(vbuff, "%s%s%s", buf1, buf2, buf3);

        if ((vbuff[0] == '\0') || (vbuff[0] == '\n'))
        {
            break;
        }

        if (strstr(vbuff, "not responding"))
        {
            CfOut(cf_error, "", "%s\n", vbuff);
        }

        if (strstr(vbuff, "be root"))
        {
            CfOut(cf_error, "", "Mount access is denied. You must be root.\n");
            CfOut(cf_error, "", "Use the -n option to run safely.");
        }

        if ((strstr(vbuff, "retrying")) || (strstr(vbuff, "denied")) || (strstr(vbuff, "backgrounding")))
        {
            continue;
        }

        if ((strstr(vbuff, "exceeded")) || (strstr(vbuff, "busy")))
        {
            continue;
        }

        if (strstr(vbuff, "RPC"))
        {
            CfOut(cf_inform, "", "There was an RPC timeout. Aborting mount operations.\n");
            CfOut(cf_inform, "", "Session failed while trying to talk to remote host\n");
            CfOut(cf_inform, "", "%s\n", vbuff);
            cf_pclose(pp);
            return false;
        }

        switch (VSYSTEMHARDCLASS)
        {
        case darwin:
        case linuxx:
        case unix_sv:
        case freebsd:
        case netbsd:
        case openbsd:
        case qnx:
        case crayos:
        case dragonfly:
            if (IsAbsoluteFileName(buf1))
            {
                strcpy(host, "localhost");
                strcpy(mounton, buf3);
            }
            else
            {
                sscanf(buf1, "%[^:]:%s", host, source);
                strcpy(mounton, buf3);
            }

            break;
        case solaris:

        case hp:
            if (IsAbsoluteFileName(buf3))
            {
                strcpy(host, "localhost");
                strcpy(mounton, buf1);
            }
            else
            {
                sscanf(buf1, "%[^:]:%s", host, source);
                strcpy(mounton, buf1);
            }

            break;
        case aix:
            /* skip header */

            if (IsAbsoluteFileName(buf1))
            {
                strcpy(host, "localhost");
                strcpy(mounton, buf2);
            }
            else
            {
                strcpy(host, buf1);
                strcpy(source, buf1);
                strcpy(mounton, buf3);
            }
            break;

        case cfnt:
            strcpy(mounton, buf2);
            strcpy(host, buf1);
            break;

        case cfsco:
            CfOut(cf_error, "", "Don't understand SCO mount format, no data");

        default:
            printf("cfengine software error: case %d = %s\n", VSYSTEMHARDCLASS, CLASSTEXT[VSYSTEMHARDCLASS]);
            FatalError("System error in GetMountInfo - no such class!");
        }

        CfDebug("GOT: host=%s, source=%s, mounton=%s\n", host, source, mounton);

        if (nfs)
        {
            AugmentMountInfo(list, host, source, mounton, "nfs");
        }
        else
        {
            AugmentMountInfo(list, host, source, mounton, NULL);
        }
    }
    while (!feof(pp));

    alarm(0);
    signal(SIGALRM, SIG_DFL);
    cf_pclose(pp);
    return true;
}
Esempio n. 24
0
static bool GetLMSensors(double *cf_this)
{
    FILE *pp;
    Item *ip, *list = NULL;
    double temp = 0;
    char name[CF_BUFSIZE];
    int count;

    cf_this[ob_temp0] = 0.0;
    cf_this[ob_temp1] = 0.0;
    cf_this[ob_temp2] = 0.0;
    cf_this[ob_temp3] = 0.0;

    if ((pp = cf_popen("/usr/bin/sensors", "r", true)) == NULL)
    {
        LMSENSORS = false;      /* Broken */
        return false;
    }

    {
        size_t vbuff_size = CF_BUFSIZE;
        char *vbuff = xmalloc(vbuff_size);

        ssize_t res = CfReadLine(&vbuff, &vbuff_size, pp);
        if (res <= 0)
        {
            /* FIXME: do we need to log anything here? */
            cf_pclose(pp);
            free(vbuff);
            return false;
        }

        for (;;)
        {
            ssize_t res = CfReadLine(&vbuff, &vbuff_size, pp);
            if (res == -1)
            {
                if (!feof(pp))
                {
                    /* FIXME: Do we need to log anything here? */
                    cf_pclose(pp);
                    free(vbuff);
                    return false;
                }
                else
                {
                    break;
                }
            }

            if (strstr(vbuff, "Temp") || strstr(vbuff, "temp"))
            {
                PrependItem(&list, vbuff, NULL);
            }
        }

        cf_pclose(pp);
        free(vbuff);
    }

    if (ListLen(list) > 0)
    {
        Log(LOG_LEVEL_DEBUG, "LM Sensors seemed to return ok data");
    }
    else
    {
        return false;
    }

/* lmsensor names are hopelessly inconsistent - so try a few things */

    for (ip = list; ip != NULL; ip = ip->next)
    {
        for (count = 0; count < 4; count++)
        {
            snprintf(name, 16, "CPU%d Temp:", count);

            if (strncmp(ip->name, name, strlen(name)) == 0)
            {
                sscanf(ip->name, "%*[^:]: %lf", &temp);

                switch (count)
                {
                case 0:
                    cf_this[ob_temp0] = temp;
                    break;
                case 1:
                    cf_this[ob_temp1] = temp;
                    break;
                case 2:
                    cf_this[ob_temp2] = temp;
                    break;
                case 3:
                    cf_this[ob_temp3] = temp;
                    break;
                }

                Log(LOG_LEVEL_DEBUG, "Set temp%d to %lf from what looks like cpu temperature", count, temp);
            }
        }
    }

    if (cf_this[ob_temp0] != 0)
    {
        /* We got something plausible */
        return true;
    }

/* Alternative name Core x: */

    for (ip = list; ip != NULL; ip = ip->next)
    {
        for (count = 0; count < 4; count++)
        {
            snprintf(name, 16, "Core %d:", count);

            if (strncmp(ip->name, name, strlen(name)) == 0)
            {
                sscanf(ip->name, "%*[^:]: %lf", &temp);

                switch (count)
                {
                case 0:
                    cf_this[ob_temp0] = temp;
                    break;
                case 1:
                    cf_this[ob_temp1] = temp;
                    break;
                case 2:
                    cf_this[ob_temp2] = temp;
                    break;
                case 3:
                    cf_this[ob_temp3] = temp;
                    break;
                }

                Log(LOG_LEVEL_DEBUG, "Set temp%d to %lf from what looks like core temperatures", count, temp);
            }
        }
    }

    if (cf_this[ob_temp0] != 0)
    {
        /* We got something plausible */
        return true;
    }

    for (ip = list; ip != NULL; ip = ip->next)
    {
        if (strncmp(ip->name, "CPU Temp:", strlen("CPU Temp:")) == 0)
        {
            sscanf(ip->name, "%*[^:]: %lf", &temp);
            Log(LOG_LEVEL_DEBUG, "Setting temp0 to CPU Temp");
            cf_this[ob_temp0] = temp;
        }

        if (strncmp(ip->name, "M/B Temp:", strlen("M/B Temp:")) == 0)
        {
            sscanf(ip->name, "%*[^:]: %lf", &temp);
            Log(LOG_LEVEL_DEBUG, "Setting temp0 to M/B Temp");
            cf_this[ob_temp1] = temp;
        }

        if (strncmp(ip->name, "Sys Temp:", strlen("Sys Temp:")) == 0)
        {
            sscanf(ip->name, "%*[^:]: %lf", &temp);
            Log(LOG_LEVEL_DEBUG, "Setting temp0 to Sys Temp");
            cf_this[ob_temp2] = temp;
        }

        if (strncmp(ip->name, "AUX Temp:", strlen("AUX Temp:")) == 0)
        {
            sscanf(ip->name, "%*[^:]: %lf", &temp);
            Log(LOG_LEVEL_DEBUG, "Setting temp0 to AUX Temp");
            cf_this[ob_temp3] = temp;
        }
    }

    if (cf_this[ob_temp0] != 0)
    {
        /* We got something plausible */
        return true;
    }

/* Alternative name Core x: */

    for (ip = list; ip != NULL; ip = ip->next)
    {
        for (count = 0; count < 4; count++)
        {
            snprintf(name, 16, "temp%d:", count);

            if (strncmp(ip->name, name, strlen(name)) == 0)
            {
                sscanf(ip->name, "%*[^:]: %lf", &temp);

                switch (count)
                {
                case 0:
                    cf_this[ob_temp0] = temp;
                    break;
                case 1:
                    cf_this[ob_temp1] = temp;
                    break;
                case 2:
                    cf_this[ob_temp2] = temp;
                    break;
                case 3:
                    cf_this[ob_temp3] = temp;
                    break;
                }

                Log(LOG_LEVEL_DEBUG, "Set temp%d to %lf", count, temp);
            }
        }
    }

/* Give up? */
    DeleteItemList(list);
    return true;
}
Esempio n. 25
0
void LocalExec(const ExecConfig *config)
{
    FILE *pp;
    char line[CF_BUFSIZE], line_escaped[sizeof(line) * 2], filename[CF_BUFSIZE], *sp;
    char cmd[CF_BUFSIZE], esc_command[CF_BUFSIZE];
    int print, count = 0;
    void *thread_name;
    time_t starttime = time(NULL);
    char starttime_str[64];
    FILE *fp;
    char canonified_fq_name[CF_BUFSIZE];

    thread_name = ThreadUniqueName();

    cf_strtimestamp_local(starttime, starttime_str);

    CfOut(cf_verbose, "", "------------------------------------------------------------------\n\n");
    CfOut(cf_verbose, "", "  LocalExec(%sscheduled) at %s\n", config->scheduled_run ? "" : "not ", starttime_str);
    CfOut(cf_verbose, "", "------------------------------------------------------------------\n");

/* Need to make sure we have LD_LIBRARY_PATH here or children will die  */

    if (strlen(config->exec_command) > 0)
    {
        strncpy(cmd, config->exec_command, CF_BUFSIZE - 1);

        if (!strstr(cmd, "-Dfrom_cfexecd"))
        {
            strcat(cmd, " -Dfrom_cfexecd");
        }
    }
    else
    {
        ConstructFailsafeCommand(config->scheduled_run, cmd);
    }

    strncpy(esc_command, MapName(cmd), CF_BUFSIZE - 1);

    snprintf(line, CF_BUFSIZE - 1, "_%jd_%s", (intmax_t) starttime, CanonifyName(cf_ctime(&starttime)));

    strlcpy(canonified_fq_name, config->fq_name, CF_BUFSIZE);
    CanonifyNameInPlace(canonified_fq_name);

    snprintf(filename, CF_BUFSIZE - 1, "%s/outputs/cf_%s_%s_%p", CFWORKDIR, canonified_fq_name, line, thread_name);
    MapName(filename);

/* What if no more processes? Could sacrifice and exec() - but we need a sentinel */

    if ((fp = fopen(filename, "w")) == NULL)
    {
        CfOut(cf_error, "fopen", "!! Couldn't open \"%s\" - aborting exec\n", filename);
        return;
    }

#if !defined(__MINGW32__)
/*
 * Don't inherit this file descriptor on fork/exec
 */

    if (fileno(fp) != -1)
    {
        fcntl(fileno(fp), F_SETFD, FD_CLOEXEC);
    }
#endif

    CfOut(cf_verbose, "", " -> Command => %s\n", cmd);

    if ((pp = cf_popen_sh(esc_command, "r")) == NULL)
    {
        CfOut(cf_error, "cf_popen", "!! Couldn't open pipe to command \"%s\"\n", cmd);
        fclose(fp);
        return;
    }

    CfOut(cf_verbose, "", " -> Command is executing...%s\n", esc_command);

    while (!feof(pp))
    {
        if(!IsReadReady(fileno(pp), (config->agent_expireafter * SECONDS_PER_MINUTE)))
        {
            char errmsg[CF_MAXVARSIZE];
            snprintf(errmsg, sizeof(errmsg), "cf-execd: !! Timeout waiting for output from agent (agent_expireafter=%d) - terminating it",
                     config->agent_expireafter);

            CfOut(cf_error, "", "%s", errmsg);
            fprintf(fp, "%s\n", errmsg);
            count++;

            pid_t pid_agent;

            if(PipeToPid(&pid_agent, pp))
            {
                ProcessSignalTerminate(pid_agent);
            }
            else
            {
                CfOut(cf_error, "", "!! Could not get PID of agent");
            }

            break;
        }

        {
            ssize_t num_read = CfReadLine(line, CF_BUFSIZE, pp);
            if (num_read == -1)
            {
                FatalError("Cannot continue on CfReadLine error");
            }
            else if (num_read == 0)
            {
                break;
            }
        }

        if(!CfReadLine(line, CF_BUFSIZE, pp))
        {
            break;
        }

        if (ferror(pp))
        {
            fflush(pp);
            break;
        }

        print = false;

        for (sp = line; *sp != '\0'; sp++)
        {
            if (!isspace((int) *sp))
            {
                print = true;
                break;
            }
        }

        if (print)
        {
            // we must escape print format chars (%) from output

            ReplaceStr(line, line_escaped, sizeof(line_escaped), "%", "%%");

            fprintf(fp, "%s\n", line_escaped);
            count++;

            /* If we can't send mail, log to syslog */

            if (strlen(config->mail_to_address) == 0)
            {
                strncat(line_escaped, "\n", sizeof(line_escaped) - 1 - strlen(line_escaped));
                if ((strchr(line_escaped, '\n')) == NULL)
                {
                    line_escaped[sizeof(line_escaped) - 2] = '\n';
                }

                CfOut(cf_inform, "", "%s", line_escaped);
            }

            line[0] = '\0';
            line_escaped[0] = '\0';
        }
    }

    cf_pclose(pp);
    CfDebug("Closing fp\n");
    fclose(fp);

    CfOut(cf_verbose, "", " -> Command is complete\n");

    if (count)
    {
        CfOut(cf_verbose, "", " -> Mailing result\n");
        MailResult(config, filename);
    }
    else
    {
        CfOut(cf_verbose, "", " -> No output\n");
        unlink(filename);
    }
}
Esempio n. 26
0
int LoadProcessTable(EvalContext *ctx, Item **procdata)
{
    FILE *prp;
    char pscomm[CF_MAXLINKSIZE], vbuff[CF_BUFSIZE], *sp;
    Item *rootprocs = NULL;
    Item *otherprocs = NULL;

    if (PROCESSTABLE)
    {
        Log(LOG_LEVEL_VERBOSE, "Reusing cached process table");
        return true;
    }

    const char *psopts = GetProcessOptions();

    snprintf(pscomm, CF_MAXLINKSIZE, "%s %s", VPSCOMM[VSYSTEMHARDCLASS], psopts);

    Log(LOG_LEVEL_VERBOSE, "Observe process table with %s", pscomm);

    if ((prp = cf_popen(pscomm, "r", false)) == NULL)
    {
        Log(LOG_LEVEL_ERR, "Couldn't open the process list with command '%s'. (popen: %s)", pscomm, GetErrorStr());
        return false;
    }

    for (;;)
    {
        ssize_t res = CfReadLine(vbuff, CF_BUFSIZE, prp);
        if (res == 0)
        {
            break;
        }

        if (res == -1)
        {
            Log(LOG_LEVEL_ERR, "Unable to read process list with command '%s'. (fread: %s)", pscomm, GetErrorStr());
            cf_pclose(prp);
            return false;
        }

        for (sp = vbuff + strlen(vbuff) - 1; (sp > vbuff) && (isspace((int)*sp)); sp--)
        {
            *sp = '\0';
        }

        if (ForeignZone(vbuff))
        {
            continue;
        }

        AppendItem(procdata, vbuff, "");
    }

    cf_pclose(prp);

/* Now save the data */

    snprintf(vbuff, CF_MAXVARSIZE, "%s/state/cf_procs", CFWORKDIR);
    RawSaveItemList(*procdata, vbuff);

    CopyList(&rootprocs, *procdata);
    CopyList(&otherprocs, *procdata);

    while (DeleteItemNotContaining(ctx, &rootprocs, "root"))
    {
    }

    while (DeleteItemContaining(ctx, &otherprocs, "root"))
    {
    }

    if (otherprocs)
    {
        PrependItem(&rootprocs, otherprocs->name, NULL);
    }

    snprintf(vbuff, CF_MAXVARSIZE, "%s/state/cf_rootprocs", CFWORKDIR);
    RawSaveItemList(rootprocs, vbuff);
    DeleteItemList(rootprocs);

    snprintf(vbuff, CF_MAXVARSIZE, "%s/state/cf_otherprocs", CFWORKDIR);
    RawSaveItemList(otherprocs, vbuff);
    DeleteItemList(otherprocs);

    return true;
}
Esempio n. 27
0
int LoadMountInfo(Rlist **list)
/* This is, in fact, the most portable way to read the mount info! */
/* Depressing, isn't it? */
{
    FILE *pp;
    char buf1[CF_BUFSIZE], buf2[CF_BUFSIZE], buf3[CF_BUFSIZE];
    char host[CF_MAXVARSIZE], source[CF_BUFSIZE], mounton[CF_BUFSIZE], vbuff[CF_BUFSIZE];
    int i, nfs = false;

    for (i = 0; VMOUNTCOMM[VSYSTEMHARDCLASS][i] != ' '; i++)
    {
        buf1[i] = VMOUNTCOMM[VSYSTEMHARDCLASS][i];
    }

    buf1[i] = '\0';

    SetTimeOut(RPCTIMEOUT);

    if ((pp = cf_popen(buf1, "r")) == NULL)
    {
        CfOut(cf_error, "cf_popen", "Can't open %s\n", buf1);
        return false;
    }

    do
    {
        vbuff[0] = buf1[0] = buf2[0] = buf3[0] = source[0] = '\0';

        if (ferror(pp))         /* abortable */
        {
            CfOut(cf_error, "ferror", "Error getting mount info\n");
            break;
        }

        if (CfReadLine(vbuff, CF_BUFSIZE, pp) == -1)
        {
            FatalError("Error in CfReadLine");
        }

        if (ferror(pp))         /* abortable */
        {
            CfOut(cf_error, "ferror", "Error getting mount info\n");
            break;
        }

        if (strstr(vbuff, "nfs"))
        {
            nfs = true;
        }

        sscanf(vbuff, "%s%s%s", buf1, buf2, buf3);

        if ((vbuff[0] == '\0') || (vbuff[0] == '\n'))
        {
            break;
        }

        if (strstr(vbuff, "not responding"))
        {
            CfOut(cf_error, "", "%s\n", vbuff);
        }

        if (strstr(vbuff, "be root"))
        {
            CfOut(cf_error, "", "Mount access is denied. You must be root.\n");
            CfOut(cf_error, "", "Use the -n option to run safely.");
        }

        if ((strstr(vbuff, "retrying")) || (strstr(vbuff, "denied")) || (strstr(vbuff, "backgrounding")))
        {
            continue;
        }

        if ((strstr(vbuff, "exceeded")) || (strstr(vbuff, "busy")))
        {
            continue;
        }

        if (strstr(vbuff, "RPC"))
        {
            CfOut(cf_inform, "", "There was an RPC timeout. Aborting mount operations.\n");
            CfOut(cf_inform, "", "Session failed while trying to talk to remote host\n");
            CfOut(cf_inform, "", "%s\n", vbuff);
            cf_pclose(pp);
            return false;
        }

#if defined(__sun) || defined(__hpux)
        if (IsAbsoluteFileName(buf3))
        {
            strcpy(host, "localhost");
            strcpy(mounton, buf1);
        }
        else
        {
            sscanf(buf1, "%[^:]:%s", host, source);
            strcpy(mounton, buf1);
        }
#elif defined(_AIX)
        /* skip header */

        if (IsAbsoluteFileName(buf1))
        {
            strcpy(host, "localhost");
            strcpy(mounton, buf2);
        }
        else
        {
            strcpy(host, buf1);
            strcpy(source, buf1);
            strcpy(mounton, buf3);
        }
#elif defined(__CYGWIN__)
        strcpy(mounton, buf2);
        strcpy(host, buf1);
#elif defined(sco) || defined(__SCO_DS)
        CfOut(cf_error, "", "Don't understand SCO mount format, no data");
#else
        if (IsAbsoluteFileName(buf1))
        {
            strcpy(host, "localhost");
            strcpy(mounton, buf3);
        }
        else
        {
            sscanf(buf1, "%[^:]:%s", host, source);
            strcpy(mounton, buf3);
        }
#endif

        CfDebug("GOT: host=%s, source=%s, mounton=%s\n", host, source, mounton);

        if (nfs)
        {
            AugmentMountInfo(list, host, source, mounton, "nfs");
        }
        else
        {
            AugmentMountInfo(list, host, source, mounton, NULL);
        }
    }
    while (!feof(pp));

    alarm(0);
    signal(SIGALRM, SIG_DFL);
    cf_pclose(pp);
    return true;
}
Esempio n. 28
0
int VerifyNotInFstab(char *name, Attributes a, Promise *pp)
/* Ensure filesystem is NOT in fstab, and return no of changes */
{
    char regex[CF_BUFSIZE];
    char *host, *mountpt, *opts;
    Item *ip;

    if (!FSTABLIST)
    {
        if (!LoadFileAsItemList(&FSTABLIST, VFSTAB[VSYSTEMHARDCLASS], a, pp))
        {
            CfOut(cf_error, "", "Couldn't open %s!\n", VFSTAB[VSYSTEMHARDCLASS]);
            return false;
        }
        else
        {
            FSTAB_EDITS = 0;
        }
    }

    if (a.mount.mount_options)
    {
        opts = Rlist2String(a.mount.mount_options, ",");
    }
    else
    {
        opts = xstrdup(VMOUNTOPTS[VSYSTEMHARDCLASS]);
    }

    host = a.mount.mount_server;
    mountpt = name;

    if (MatchFSInFstab(mountpt))
    {
        if (a.mount.editfstab)
        {
#if defined(_AIX)
            FILE *pfp;
            char line[CF_BUFSIZE], aixcomm[CF_BUFSIZE];

            snprintf(aixcomm, CF_BUFSIZE, "/usr/sbin/rmnfsmnt -f %s", mountpt);

            if ((pfp = cf_popen(aixcomm, "r")) == NULL)
            {
                cfPS(cf_error, CF_FAIL, "", pp, a, "Failed to invoke /usr/sbin/rmnfsmnt to edit fstab");
                return 0;
            }

            while (!feof(pfp))
            {
                if (CfReadLine(line, CF_BUFSIZE, pfp) == -1)
                {
                    FatalError("Error in CfReadLine");
                }

                if (line[0] == '#')
                {
                    continue;
                }

                if (strstr(line, "busy"))
                {
                    cfPS(cf_inform, CF_INTERPT, "", pp, a, "The device under %s cannot be removed from %s\n",
                         mountpt, VFSTAB[VSYSTEMHARDCLASS]);
                    return 0;
                }
            }

            cf_pclose(pfp);

            return 0;       /* ignore internal editing for aix , always returns 0 changes */
#else
            snprintf(regex, CF_BUFSIZE, ".*[\\s]+%s[\\s]+.*", mountpt);

            for (ip = FSTABLIST; ip != NULL; ip = ip->next)
            {
                if (FullTextMatch(regex, ip->name))
                {
                    cfPS(cf_inform, CF_CHG, "", pp, a, "Deleting file system mounted on %s.\n", host);
                    // Check host name matches too?
                    DeleteThisItem(&FSTABLIST, ip);
                    FSTAB_EDITS++;
                }
            }
#endif
        }
    }

    if (a.mount.mount_options)
    {
        free(opts);
    }

    return 0;
}
Esempio n. 29
0
static bool IsReadReady(int fd, int timeout_sec)
{
    fd_set  rset;
    FD_ZERO(&rset);
    FD_SET(fd, &rset);

    struct timeval tv = {
        .tv_sec = timeout_sec,
        .tv_usec = 0,
    };

    int ret = select(fd + 1, &rset, NULL, NULL, &tv);

    if(ret < 0)
    {
        Log(LOG_LEVEL_ERR, "IsReadReady: Failed checking for data. (select: %s)", GetErrorStr());
        return false;
    }

    if(FD_ISSET(fd, &rset))
    {
        return true;
    }

    if(ret == 0)  // timeout
    {
        return false;
    }

    // can we get here?
    Log(LOG_LEVEL_ERR, "IsReadReady: Unknown outcome (ret > 0 but our only fd is not set). (select: %s)", GetErrorStr());

    return false;
}
#if defined(__hpux) && defined(__GNUC__)
#pragma GCC diagnostic warning "-Wstrict-aliasing"
#endif

#endif  /* __MINGW32__ */

void LocalExec(const ExecConfig *config)
{
    time_t starttime = time(NULL);

    void *thread_name = ThreadUniqueName();

    {
        char starttime_str[64];
        cf_strtimestamp_local(starttime, starttime_str);

        if (LEGACY_OUTPUT)
        {
            Log(LOG_LEVEL_VERBOSE, "------------------------------------------------------------------");
            Log(LOG_LEVEL_VERBOSE, "  LocalExec(%sscheduled) at %s", config->scheduled_run ? "" : "not ", starttime_str);
            Log(LOG_LEVEL_VERBOSE, "------------------------------------------------------------------");
        }
        else
        {
            Log(LOG_LEVEL_VERBOSE, "LocalExec(%sscheduled) at %s", config->scheduled_run ? "" : "not ", starttime_str);
        }
    }

/* Need to make sure we have LD_LIBRARY_PATH here or children will die  */

    char cmd[CF_BUFSIZE];
    if (strlen(config->exec_command) > 0)
    {
        strncpy(cmd, config->exec_command, CF_BUFSIZE - 1);

        if (!strstr(cmd, "-Dfrom_cfexecd"))
        {
            strcat(cmd, " -Dfrom_cfexecd");
        }
    }
    else
    {
        ConstructFailsafeCommand(config->scheduled_run, cmd);
    }

    char esc_command[CF_BUFSIZE];
    strncpy(esc_command, MapName(cmd), CF_BUFSIZE - 1);

    char line[CF_BUFSIZE];
    snprintf(line, CF_BUFSIZE - 1, "_%jd_%s", (intmax_t) starttime, CanonifyName(ctime(&starttime)));

    char filename[CF_BUFSIZE];
    {
        char canonified_fq_name[CF_BUFSIZE];

        strlcpy(canonified_fq_name, config->fq_name, CF_BUFSIZE);
        CanonifyNameInPlace(canonified_fq_name);


        snprintf(filename, CF_BUFSIZE - 1, "%s/outputs/cf_%s_%s_%p", CFWORKDIR, canonified_fq_name, line, thread_name);
        MapName(filename);
    }


/* What if no more processes? Could sacrifice and exec() - but we need a sentinel */

    FILE *fp = fopen(filename, "w");
    if (!fp)
    {
        Log(LOG_LEVEL_ERR, "Couldn't open '%s' - aborting exec. (fopen: %s)", filename, GetErrorStr());
        return;
    }

#if !defined(__MINGW32__)
/*
 * Don't inherit this file descriptor on fork/exec
 */

    if (fileno(fp) != -1)
    {
        fcntl(fileno(fp), F_SETFD, FD_CLOEXEC);
    }
#endif

    Log(LOG_LEVEL_VERBOSE, "Command => %s", cmd);

    FILE *pp = cf_popen_sh(esc_command, "r");
    if (!pp)
    {
        Log(LOG_LEVEL_ERR, "Couldn't open pipe to command '%s'. (cf_popen: %s)", cmd, GetErrorStr());
        fclose(fp);
        return;
    }

    Log(LOG_LEVEL_VERBOSE, "Command is executing...%s", esc_command);

    int count = 0;
    for (;;)
    {
        if(!IsReadReady(fileno(pp), (config->agent_expireafter * SECONDS_PER_MINUTE)))
        {
            char errmsg[CF_MAXVARSIZE];
            snprintf(errmsg, sizeof(errmsg), "cf-execd: !! Timeout waiting for output from agent (agent_expireafter=%d) - terminating it",
                     config->agent_expireafter);

            Log(LOG_LEVEL_ERR, "%s", errmsg);
            fprintf(fp, "%s\n", errmsg);
            count++;

            pid_t pid_agent;

            if(PipeToPid(&pid_agent, pp))
            {
                ProcessSignalTerminate(pid_agent);
            }
            else
            {
                Log(LOG_LEVEL_ERR, "Could not get PID of agent");
            }

            break;
        }

        ssize_t res = CfReadLine(line, CF_BUFSIZE, pp);

        if (res == 0)
        {
            break;
        }

        if (res == -1)
        {
            Log(LOG_LEVEL_ERR, "Unable to read output from command '%s'. (cfread: %s)", cmd, GetErrorStr());
            cf_pclose(pp);
            return;
        }

        bool print = false;

        for (const char *sp = line; *sp != '\0'; sp++)
        {
            if (!isspace((int) *sp))
            {
                print = true;
                break;
            }
        }

        if (print)
        {
            char line_escaped[sizeof(line) * 2];

            // we must escape print format chars (%) from output

            ReplaceStr(line, line_escaped, sizeof(line_escaped), "%", "%%");

            fprintf(fp, "%s\n", line_escaped);
            count++;

            /* If we can't send mail, log to syslog */

            if (strlen(config->mail_to_address) == 0)
            {
                strncat(line_escaped, "\n", sizeof(line_escaped) - 1 - strlen(line_escaped));
                if ((strchr(line_escaped, '\n')) == NULL)
                {
                    line_escaped[sizeof(line_escaped) - 2] = '\n';
                }

                Log(LOG_LEVEL_INFO, "%s", line_escaped);
            }

            line[0] = '\0';
            line_escaped[0] = '\0';
        }
    }

    cf_pclose(pp);
    Log(LOG_LEVEL_DEBUG, "Closing fp");
    fclose(fp);

    Log(LOG_LEVEL_VERBOSE, "Command is complete");

    if (count)
    {
        Log(LOG_LEVEL_VERBOSE, "Mailing result");
        MailResult(config, filename);
    }
    else
    {
        Log(LOG_LEVEL_VERBOSE, "No output");
        unlink(filename);
    }
}
Esempio n. 30
0
int LoadProcessTable()
{
    FILE *prp;
    char pscomm[CF_MAXLINKSIZE];
    Item *rootprocs = NULL;
    Item *otherprocs = NULL;


    if (PROCESSTABLE)
    {
        Log(LOG_LEVEL_VERBOSE, "Reusing cached process table");
        return true;
    }

    LoadPlatformExtraTable();

    CheckPsLineLimitations();

    const char *psopts = GetProcessOptions();

    snprintf(pscomm, CF_MAXLINKSIZE, "%s %s", VPSCOMM[VPSHARDCLASS], psopts);

    Log(LOG_LEVEL_VERBOSE, "Observe process table with %s", pscomm);

    if ((prp = cf_popen(pscomm, "r", false)) == NULL)
    {
        Log(LOG_LEVEL_ERR, "Couldn't open the process list with command '%s'. (popen: %s)", pscomm, GetErrorStr());
        return false;
    }

    size_t vbuff_size = CF_BUFSIZE;
    char *vbuff = xmalloc(vbuff_size);

# ifdef HAVE_GETZONEID

    char *names[CF_PROCCOLS];
    int start[CF_PROCCOLS];
    int end[CF_PROCCOLS];
    Seq *pidlist = SeqNew(1, NULL);
    Seq *rootpidlist = SeqNew(1, NULL);
    bool global_zone = IsGlobalZone();

    if (global_zone)
    {
        int res = ZLoadProcesstable(pidlist, rootpidlist);

        if (res == false)
        {
            Log(LOG_LEVEL_ERR, "Unable to load solaris zone process table.");
            return false;
        }
    }

# endif

    ARG_UNUSED bool header = true;           /* used only if HAVE_GETZONEID */

    for (;;)
    {
        ssize_t res = CfReadLine(&vbuff, &vbuff_size, prp);
        if (res == -1)
        {
            if (!feof(prp))
            {
                Log(LOG_LEVEL_ERR, "Unable to read process list with command '%s'. (fread: %s)", pscomm, GetErrorStr());
                cf_pclose(prp);
                free(vbuff);
                return false;
            }
            else
            {
                break;
            }
        }
        Chop(vbuff, vbuff_size);

# ifdef HAVE_GETZONEID

        if (global_zone)
        {
            if (header)
            {   /* this is the banner so get the column header names for later use*/
                GetProcessColumnNames(vbuff, &names[0], start, end);
            }
            else
            {
               int gpid = ExtractPid(vbuff, names, end);

               if (!IsGlobalProcess(gpid, pidlist, rootpidlist))
               {
                    continue;
               }
            }
        }

# endif
        AppendItem(&PROCESSTABLE, vbuff, "");

        header = false;
    }

    cf_pclose(prp);

/* Now save the data */
    const char* const statedir = GetStateDir();

    snprintf(vbuff, CF_MAXVARSIZE, "%s%ccf_procs", statedir, FILE_SEPARATOR);
    RawSaveItemList(PROCESSTABLE, vbuff, NewLineMode_Unix);

# ifdef HAVE_GETZONEID
    if (global_zone) /* pidlist and rootpidlist are empty if we're not in the global zone */
    {
        Item *ip = PROCESSTABLE;
        while (ip != NULL)
        {
            ZCopyProcessList(&rootprocs, ip, rootpidlist, names, end);
            ip = ip->next;
        }
        ReverseItemList(rootprocs);
        ip = PROCESSTABLE;
        while (ip != NULL)
        {
            ZCopyProcessList(&otherprocs, ip, pidlist, names, end);
            ip = ip->next;
        }
        ReverseItemList(otherprocs);
    }
    else
# endif
    {
        CopyList(&rootprocs, PROCESSTABLE);
        CopyList(&otherprocs, PROCESSTABLE);

        while (DeleteItemNotContaining(&rootprocs, "root"))
        {
        }

        while (DeleteItemContaining(&otherprocs, "root"))
        {
        }
    }
    if (otherprocs)
    {
        PrependItem(&rootprocs, otherprocs->name, NULL);
    }

    snprintf(vbuff, CF_MAXVARSIZE, "%s%ccf_rootprocs", statedir, FILE_SEPARATOR);
    RawSaveItemList(rootprocs, vbuff, NewLineMode_Unix);
    DeleteItemList(rootprocs);

    snprintf(vbuff, CF_MAXVARSIZE, "%s%ccf_otherprocs", statedir, FILE_SEPARATOR);
    RawSaveItemList(otherprocs, vbuff, NewLineMode_Unix);
    DeleteItemList(otherprocs);

    free(vbuff);
    return true;
}