コード例 #1
0
ファイル: util.c プロジェクト: igalic/ironbee
ib_status_t ib_util_mkpath(const char *path, mode_t mode)
{
    char *ppath = NULL;
    char *cpath = NULL;
    ib_status_t rc;

    if (strcmp(path, ".") == 0 || strcmp(path, "/") == 0) {
        return IB_OK;
    }

    /* Attempt to create the dir.  If it returns ENOENT, then 
     * recursivly attempt to create the parent dir(s) until
     * they are all created.
     */
    if ((mkdir(path, mode) == -1) && (errno == ENOENT)) {
        int ec;

        /* Some implementations may modify the path argument,
         * so make a copy first. */
        if ((cpath = strdup(path)) == NULL) {
            return IB_EALLOC;
        }

        if ((ppath = dirname(cpath)) == NULL) {
            rc = IB_EINVAL;
            goto cleanup;
        }

        rc = ib_util_mkpath(ppath, mode);
        if (rc != IB_OK) {
            goto cleanup;
        }

        /* Parent path was created, so try again. */
        ec = mkdir(path, mode);
        if (ec == -1) {
            ec = errno;
            ib_util_log_error(3, "Failed to create path \"%s\": %s (%d)",
                              path, strerror(ec), ec);
            rc = IB_EINVAL;
            goto cleanup;
        }
    }

    rc = IB_OK;

cleanup:
    if (cpath != NULL) {
        free(cpath);
    }

    return rc;
}
コード例 #2
0
ファイル: test_util_path.cpp プロジェクト: aburan28/ironbee
/// @test Test util path functions - ib_util_mkpath()
TEST_F(TestIBUtilMkPath, mkpath)
{
    ib_status_t  rc;
    char        *tmp;
    char         path[pathsize_full+1];
    struct stat  sbuf;

    strcpy(m_basedir, "/tmp/XXXXXX");
    tmp = mkdtemp(m_basedir);
    ASSERT_STRNE(NULL, tmp)
        << "mkdtemp() returned " << strerror(errno) << std::endl;

    snprintf(path, pathsize_full, "%s/a", m_basedir);
    rc = ib_util_mkpath(path, 0700);
    ASSERT_EQ(IB_OK, rc);

    ASSERT_EQ(0, stat(path, &sbuf));
    ASSERT_TRUE(S_ISDIR(sbuf.st_mode));
    ASSERT_EQ((mode_t)0700, (sbuf.st_mode & 0777));

    snprintf(path, pathsize_full, "%s/a/b", m_basedir);
    rc = ib_util_mkpath(path, 0750);
    ASSERT_EQ(IB_OK, rc);

    ASSERT_EQ(0, stat(path, &sbuf));
    ASSERT_TRUE(S_ISDIR(sbuf.st_mode));
    ASSERT_EQ((mode_t)0750, (sbuf.st_mode & 0777));

    snprintf(path, pathsize_full, "%s/b/c/d/e", m_basedir);
    rc = ib_util_mkpath(path, 0755);
    ASSERT_EQ(IB_OK, rc);

    ASSERT_EQ(0, stat(path, &sbuf));
    ASSERT_TRUE(S_ISDIR(sbuf.st_mode));
    ASSERT_EQ((mode_t)0755, (sbuf.st_mode & 0777));
}
コード例 #3
0
ファイル: core_audit.c プロジェクト: PutiZL/ironbee
ib_status_t core_audit_open_auditfile(ib_engine_t *ib,
                                      ib_auditlog_t *log,
                                      ib_core_audit_cfg_t *cfg,
                                      ib_core_cfg_t *corecfg)
{
    const int dtmp_sz = 64;
    const int dn_sz = 512;
    char *dtmp = (char *)malloc(dtmp_sz);
    char *dn = (char *)malloc(dn_sz);
    char *audit_filename;
    size_t audit_filename_sz;
    char *temp_filename;
    size_t temp_filename_sz;
    int fd;
    const time_t log_seconds = IB_CLOCK_SECS(log->tx->t.logtime);
    int sys_rc;
    ib_status_t ib_rc;
    struct tm gmtime_result;
    const ib_site_t *site;

    if (dtmp == NULL || dn == NULL) {
        if (dtmp != NULL) {
            free(dtmp);
        }
        if (dn != NULL) {
            free(dn);
        }
        return IB_EALLOC;
    }

    gmtime_r(&log_seconds, &gmtime_result);

    /* Generate the audit log filename template. */
    if (*(corecfg->auditlog_sdir_fmt) != 0) {
        size_t ret = strftime(dtmp, dtmp_sz,
                              corecfg->auditlog_sdir_fmt, &gmtime_result);
        if (ret == 0) {
            /// @todo Better error - probably should validate at cfg time
            ib_log_error(log->ib,
                         "Failed to create audit log filename template, "
                         "using default:"
                         " name too long");
            *dtmp = 0;
        }
    }
    else {
        *dtmp = 0;
    }

    /* Generate the full audit log directory name. */
    sys_rc = snprintf(dn, dn_sz, "%s%s%s",
                      corecfg->auditlog_dir, (*dtmp)?"/":"", dtmp);
    if (sys_rc >= dn_sz) {
        /// @todo Better error.
        ib_log_error(log->ib,
                     "Failed to create audit log directory: name too long");
        free(dtmp);
        free(dn);
        return IB_EINVAL;
    }

    /* Get the site */
    ib_rc = ib_context_site_get(log->ctx, &site);
    if (ib_rc != IB_OK) {
        free(dtmp);
        free(dn);
        return ib_rc;
    }

    /* Generate the full audit log filename. */
    if (site != NULL) {
        audit_filename_sz = strlen(dn) + strlen(cfg->tx->id) +
            strlen(site->id) + 7;
        audit_filename = (char *)ib_mm_alloc(cfg->tx->mm, audit_filename_sz);
        sys_rc = snprintf(audit_filename,
                          audit_filename_sz,
                          "%s/%s_%s.log", dn, cfg->tx->id,site->id);
    }
    else {
        audit_filename_sz = strlen(dn) + strlen(cfg->tx->id) + 6;
        audit_filename = (char *)ib_mm_alloc(cfg->tx->mm, audit_filename_sz);
        sys_rc = snprintf(audit_filename,
                          audit_filename_sz,
                          "%s/%s.log", dn, cfg->tx->id);
    }
    if (sys_rc >= (int)audit_filename_sz) {
        /// @todo Better error.
        ib_log_error(log->ib,
                     "Failed to create audit log filename: name too long");
        ib_rule_log_add_audit(cfg->tx->rule_exec, audit_filename, true);
        free(dtmp);
        free(dn);
        return IB_EINVAL;
    }

    ib_rc = ib_util_mkpath(dn, corecfg->auditlog_dmode);
    if (ib_rc != IB_OK) {
        ib_log_error(log->ib,
                     "Failed to create audit log dir: %s", dn);
        ib_rule_log_add_audit(cfg->tx->rule_exec, audit_filename, true);
        free(dtmp);
        free(dn);
        return ib_rc;
    }

    // Create temporary filename to use while writing the audit log
    temp_filename_sz = strlen(audit_filename) + 6;
    temp_filename = (char *)ib_mm_alloc(cfg->tx->mm, temp_filename_sz);
    if (temp_filename == NULL) {
      free(dtmp);
      free(dn);
      return IB_EALLOC;
    }
    sys_rc = snprintf(temp_filename,
                      temp_filename_sz,
                      "%s.part", audit_filename);
    if (sys_rc >= (int)temp_filename_sz) {
        /// @todo Better error.
        ib_log_error(log->ib,
                     "Failed to create temporary audit log filename: name too long");
        ib_rule_log_add_audit(cfg->tx->rule_exec, audit_filename, true);
        free(dtmp);
        free(dn);
        return IB_EINVAL;
    }

    /* Open the file.  Use open() & fdopen() to avoid chmod() */
    fd = open(temp_filename,
              (O_WRONLY|O_APPEND|O_CREAT|O_BINARY),
              corecfg->auditlog_fmode);
    if (fd >= 0) {
        cfg->fp = fdopen(fd, "ab");
        if (cfg->fp == NULL) {
            close(fd);
        }
    }
    if ( (fd < 0) || (cfg->fp == NULL) ) {
        sys_rc = errno;
        ib_log_error(log->ib,
                     "Error opening audit log \"%s\": %s (%d)",
                     temp_filename, strerror(sys_rc), sys_rc);
        ib_rule_log_add_audit(cfg->tx->rule_exec, audit_filename, true);
        free(dtmp);
        free(dn);
        return IB_EINVAL;
    }

    /* Track the relative audit log filename. */
    cfg->fn = audit_filename + (strlen(corecfg->auditlog_dir) + 1);
    cfg->full_path = audit_filename;
    cfg->temp_path = temp_filename;

    /* Log it via the rule logger */
    ib_rule_log_add_audit(cfg->tx->rule_exec, audit_filename, false);

    free(dtmp);
    free(dn);

    return IB_OK;
}
コード例 #4
0
ファイル: core_audit.c プロジェクト: PutiZL/ironbee
ib_status_t core_audit_open_auditindexfile(ib_engine_t *ib,
                                           ib_auditlog_t *log,
                                           ib_core_audit_cfg_t *cfg,
                                           ib_core_cfg_t *corecfg)
{
    char* index_file;
    size_t index_file_sz;
    ib_status_t ib_rc;
    int sys_rc;

    if (log->ctx->auditlog->index == NULL) {
        return IB_OK;
    }

    /* Lock the auditlog configuration for the context.
     * We lock up here to ensure that external resources are not
     * double-opened instead of locking only the assignment to
     * log->ctx->auditlog->index_fp at the bottom of this block. */
    ib_rc = ib_lock_lock(log->ctx->auditlog->index_fp_lock);
    if (ib_rc != IB_OK) {
        return ib_rc;
    }

    if (log->ctx->auditlog->index[0] == '/') {
        index_file_sz = strlen(log->ctx->auditlog->index) + 1;

        index_file = (char *)ib_mm_alloc(cfg->tx->mm, index_file_sz);
        if (index_file == NULL) {
            ib_lock_unlock(log->ctx->auditlog->index_fp_lock);
            return IB_EALLOC;
        }

        memcpy(index_file, log->ctx->auditlog->index, index_file_sz);
    }
    else if (log->ctx->auditlog->index[0] == '|') {
        /// @todo Probably should skip whitespace???
        index_file_sz = strlen(log->ctx->auditlog->index + 1) + 1;

        index_file = (char *)ib_mm_alloc(cfg->tx->mm, index_file_sz);
        if (index_file == NULL) {
            ib_lock_unlock(log->ctx->auditlog->index_fp_lock);
            return IB_EALLOC;
        }

        memcpy(index_file, log->ctx->auditlog->index + 1, index_file_sz);
    }
    else {
        ib_rc = ib_util_mkpath(corecfg->auditlog_dir, corecfg->auditlog_dmode);
        if (ib_rc != IB_OK) {
            ib_log_error(log->ib,
                         "Failed to create audit log dir: %s",
                         corecfg->auditlog_dir);
            ib_lock_unlock(log->ctx->auditlog->index_fp_lock);
            return ib_rc;
        }

        index_file_sz = strlen(corecfg->auditlog_dir) +
                        strlen(log->ctx->auditlog->index) + 2;

        index_file = (char *)ib_mm_alloc(cfg->tx->mm, index_file_sz);
        if (index_file == NULL) {
            ib_lock_unlock(log->ctx->auditlog->index_fp_lock);
            return IB_EALLOC;
        }

        sys_rc = snprintf(index_file, index_file_sz, "%s/%s",
                          corecfg->auditlog_dir,
                          log->ctx->auditlog->index);
        if ((size_t)sys_rc >= index_file_sz) {
            ib_log_error(log->ib,
                         "Failed to create audit log index \"%s/%s\":"
                         " name too long",
                         corecfg->auditlog_dir,
                         log->ctx->auditlog->index);
            ib_lock_unlock(log->ctx->auditlog->index_fp_lock);
            return IB_EINVAL;
        }
    }

    if (log->ctx->auditlog->index[0] == '|') {
        int p[2];
        pid_t pipe_pid;

        /// @todo Handle exit of pipe_pid???

        sys_rc = pipe(p);
        if (sys_rc != 0) {
            ib_log_error(log->ib,
                         "Error creating piped audit log index: %s (%d)",
                         strerror(errno), errno);
            ib_lock_unlock(log->ctx->auditlog->index_fp_lock);
            return IB_EINVAL;
        }

        /* Create a new process for executing the piped command. */
        pipe_pid = fork();
        if (pipe_pid == 0) {
            /* Child - piped audit log index process */
            char *parg[4];

            /// @todo Reset SIGCHLD in child???

            /* Setup the filehandles to read from pipe. */
            close(3); /// @todo stderr
            close(p[1]);
            dup2(p[0], 0);

            /* Execute piped command. */
            parg[0] = (char *)ib_pipe_shell;
            parg[1] = (char *)"-c";
            parg[2] = index_file;
            parg[3] = NULL;
            execvp(ib_pipe_shell, (char * const *)parg); /// @todo define shell
            sys_rc = errno;
            ib_log_error(log->ib,
                         "Error executing piped audit log index "
                         "\"%s\": %s (%d)",
                         index_file, strerror(sys_rc), sys_rc);
            exit(1);
        }
        else if (pipe_pid == -1) {
            /* Error - no process created */
            sys_rc = errno;
            ib_log_error(log->ib,
                         "Error creating piped audit log index process: "
                         "%s (%d)",
                         strerror(sys_rc), sys_rc);
            ib_lock_unlock(log->ctx->auditlog->index_fp_lock);
            return IB_EINVAL;
        }

        /* Parent - IronBee process */

        /* Setup the filehandles to write to the pipe. */
        close(p[0]);
        cfg->index_fp = fdopen(p[1], "w");
        if (cfg->index_fp == NULL) {
            sys_rc = errno;
            ib_log_error(log->ib,
                         "Error opening piped audit log index: %s (%d)",
                         strerror(sys_rc), sys_rc);
            ib_lock_unlock(log->ctx->auditlog->index_fp_lock);
            return IB_EINVAL;
        }
    }
    else {
        /// @todo Use corecfg->auditlog_fmode as file mode for new file
        cfg->index_fp = fopen(index_file, "ab");
        if (cfg->index_fp == NULL) {
            sys_rc = errno;
            ib_log_error(log->ib,
                         "Error opening audit log index \"%s\": %s (%d)",
                         index_file, strerror(sys_rc), sys_rc);
            ib_lock_unlock(log->ctx->auditlog->index_fp_lock);
            return IB_EINVAL;
        }
    }

    log->ctx->auditlog->index_fp = cfg->index_fp;
    ib_lock_unlock(log->ctx->auditlog->index_fp_lock);

    return IB_OK;
}
コード例 #5
0
ファイル: core_audit.c プロジェクト: moon2l/ironbee
ib_status_t core_audit_open_auditfile(ib_provider_inst_t *lpi,
                                      ib_auditlog_t *log,
                                      core_audit_cfg_t *cfg,
                                      ib_core_cfg_t *corecfg)
{
    IB_FTRACE_INIT();

    const int dtmp_sz = 64;
    const int dn_sz = 512;
    char *dtmp = (char *)malloc(dtmp_sz);
    char *dn = (char *)malloc(dn_sz);
    char *audit_filename;
    int audit_filename_sz;
    char *temp_filename;
    int temp_filename_sz;
    const time_t log_seconds = IB_CLOCK_SECS(log->tx->t.logtime);
    int sys_rc;
    ib_status_t ib_rc;
    struct tm gmtime_result;
    ib_site_t *site;

    if (dtmp == NULL || dn == NULL) {
        ib_log_error(log->ib,  "Failed to allocate internal buffers.");
        if (dtmp != NULL) {
            free(dtmp);
        }
        if (dn != NULL) {
            free(dn);
        }
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    gmtime_r(&log_seconds, &gmtime_result);

    /* Generate the audit log filename template. */
    if (*(corecfg->auditlog_sdir_fmt) != 0) {
        size_t ret = strftime(dtmp, dtmp_sz,
                              corecfg->auditlog_sdir_fmt, &gmtime_result);
        if (ret == 0) {
            /// @todo Better error - probably should validate at cfg time
            ib_log_error(log->ib,
                         "Could not create audit log filename template, "
                         "using default:"
                         " too long");
            *dtmp = 0;
        }
    }
    else {
        *dtmp = 0;
    }

    /* Generate the full audit log directory name. */
    sys_rc = snprintf(dn, dn_sz, "%s%s%s",
                  corecfg->auditlog_dir, (*dtmp)?"/":"", dtmp);
    if (sys_rc >= dn_sz) {
        /// @todo Better error.
        ib_log_error(log->ib,
                     "Could not create audit log directory: too long");
        free(dtmp);
        free(dn);
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    /* Generate the full audit log filename. */
    site = ib_context_site_get(log->ctx);
    if (site != NULL) {
        audit_filename_sz = strlen(dn) + strlen(cfg->tx->id) +
            strlen(site->id_str) + 7;
        audit_filename = (char *)ib_mpool_alloc(cfg->tx->mp, audit_filename_sz);
        sys_rc = snprintf(audit_filename,
                          audit_filename_sz,
                          "%s/%s_%s.log", dn, cfg->tx->id,site->id_str);
    }
    else {
        audit_filename_sz = strlen(dn) + strlen(cfg->tx->id) + 6;
        audit_filename = (char *)ib_mpool_alloc(cfg->tx->mp, audit_filename_sz);
        sys_rc = snprintf(audit_filename,
                          audit_filename_sz,
                          "%s/%s.log", dn, cfg->tx->id);
    }
    if (sys_rc >= (int)audit_filename_sz) {
        /// @todo Better error.
        ib_log_error(log->ib,
                     "Could not create audit log filename: too long");
        free(dtmp);
        free(dn);
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    ib_rc = ib_util_mkpath(dn, corecfg->auditlog_dmode);
    if (ib_rc != IB_OK) {
        ib_log_error(log->ib,
                     "Could not create audit log dir: %s", dn);
        free(dtmp);
        free(dn);
        IB_FTRACE_RET_STATUS(ib_rc);
    }

    // Create temporary filename to use while writing the audit log
    temp_filename_sz = strlen(audit_filename) + 6;
    temp_filename = (char *)ib_mpool_alloc(cfg->tx->mp, temp_filename_sz);
    sys_rc = snprintf(temp_filename,
                      temp_filename_sz,
                      "%s.part", audit_filename);
    if (sys_rc >= (int)temp_filename_sz) {
        /// @todo Better error.
        ib_log_error(log->ib,
                     "Could not create temporary audit log filename: too long");
        free(dtmp);
        free(dn);
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    /// @todo Use corecfg->auditlog_fmode as file mode for new file
    cfg->fp = fopen(temp_filename, "ab");
    if (cfg->fp == NULL) {
        sys_rc = errno;
        /// @todo Better error.
        ib_log_error(log->ib,
                     "Could not open audit log \"%s\": %s (%d)",
                     temp_filename, strerror(sys_rc), sys_rc);
        free(dtmp);
        free(dn);
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    /* Track the relative audit log filename. */
    cfg->fn = audit_filename + (strlen(corecfg->auditlog_dir) + 1);
    cfg->full_path = audit_filename;
    cfg->temp_path = temp_filename;

    free(dtmp);
    free(dn);

    IB_FTRACE_RET_STATUS(IB_OK);
}