Esempio n. 1
0
/* Spawn the piped logger process pl->program. */
static apr_status_t piped_log_spawn(piped_log *pl)
{
    apr_procattr_t *procattr;
    apr_proc_t *procnew = NULL;
    apr_status_t status;

    if (((status = apr_procattr_create(&procattr, pl->p)) != APR_SUCCESS) ||
        ((status = apr_procattr_cmdtype_set(procattr, pl->cmdtype))
         != APR_SUCCESS) ||
        ((status = apr_procattr_child_in_set(procattr,
                                             ap_piped_log_read_fd(pl),
                                             ap_piped_log_write_fd(pl)))
         != APR_SUCCESS) ||
        ((status = apr_procattr_child_errfn_set(procattr, log_child_errfn))
         != APR_SUCCESS) ||
        ((status = apr_procattr_error_check_set(procattr, 1)) != APR_SUCCESS)) {
        char buf[120];
        /* Something bad happened, give up and go away. */
        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
                     "piped_log_spawn: unable to setup child process '%s': %s",
                     pl->program, apr_strerror(status, buf, sizeof(buf)));
    }
    else {
        char **args;
        const char *pname;
        apr_file_t *outfile, *errfile;

        if ((status = apr_file_open_stdout(&outfile, pl->p)) == APR_SUCCESS)
            status = apr_procattr_child_out_set(procattr, outfile, NULL);
        if ((status = apr_file_open_stderr(&errfile, pl->p)) == APR_SUCCESS)
            status = apr_procattr_child_err_set(procattr, errfile, NULL);

        apr_tokenize_to_argv(pl->program, &args, pl->p);
        pname = apr_pstrdup(pl->p, args[0]);
        procnew = apr_pcalloc(pl->p, sizeof(apr_proc_t));
        status = apr_proc_create(procnew, pname, (const char * const *) args,
                                 NULL, procattr, pl->p);

        if (status == APR_SUCCESS) {
            pl->pid = procnew;
            /* procnew->in was dup2'd from ap_piped_log_write_fd(pl);
             * since the original fd is still valid, close the copy to
             * avoid a leak. */
            apr_file_close(procnew->in);
            procnew->in = NULL;
            apr_proc_other_child_register(procnew, piped_log_maintenance, pl,
                                          ap_piped_log_write_fd(pl), pl->p);
            close_handle_in_child(pl->p, ap_piped_log_read_fd(pl));
        }
        else {
            char buf[120];
            /* Something bad happened, give up and go away. */
            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
                         "unable to start piped log program '%s': %s",
                         pl->program, apr_strerror(status, buf, sizeof(buf)));
        }
    }

    return status;
}
Esempio n. 2
0
AP_DECLARE(piped_log *) ap_open_piped_log_ex(apr_pool_t *p,
                                             const char *program,
                                             apr_cmdtype_e cmdtype)
{
    piped_log *pl;

    pl = apr_palloc(p, sizeof (*pl));
    pl->p = p;
    pl->program = apr_pstrdup(p, program);
    pl->pid = NULL;
    pl->cmdtype = cmdtype;
    if (apr_file_pipe_create(&ap_piped_log_read_fd(pl),
                             &ap_piped_log_write_fd(pl), p) != APR_SUCCESS) {
        return NULL;
    }
    apr_pool_cleanup_register(p, pl, piped_log_cleanup,
                              piped_log_cleanup_for_exec);
    if (piped_log_spawn(pl) != APR_SUCCESS) {
        apr_pool_cleanup_kill(p, pl, piped_log_cleanup);
        apr_file_close(ap_piped_log_read_fd(pl));
        apr_file_close(ap_piped_log_write_fd(pl));
        return NULL;
    }
    return pl;
}
Esempio n. 3
0
static apr_status_t piped_log_cleanup(void *data)
{
    piped_log *pl = data;

    apr_file_close(ap_piped_log_write_fd(pl));
    return APR_SUCCESS;
}
Esempio n. 4
0
/**
 * This function is called when the "JSONMatchLog" configuration directive is parsed.
 */
static const char *set_jsonerrorlog_path(cmd_parms *cmd, void *cfg, const char *arg) {
    dir_config_t *dcfg = (dir_config_t *) cfg;

    char *jsonmatchlog_path = apr_pstrdup(cmd->pool, arg);

    if (jsonmatchlog_path[0] == '|') {
        const char *pipe_name = jsonmatchlog_path + 1;
        piped_log *pipe_log;

        pipe_log = ap_open_piped_log(cmd->pool, pipe_name);
        if (pipe_log == NULL)
            return apr_psprintf(cmd->pool, "mod_defender: Failed to open the json match log pipe: %s", pipe_name);
        dcfg->jsonmatchlog_file = ap_piped_log_write_fd(pipe_log);
    } else {
        const char *file_name = ap_server_root_relative(cmd->pool, jsonmatchlog_path);
        apr_status_t rc;

        rc = apr_file_open(&dcfg->jsonmatchlog_file, file_name,
                           APR_WRITE | APR_APPEND | APR_CREATE | APR_BINARY,
                           APR_UREAD | APR_UWRITE | APR_GREAD, cmd->pool);

        if (rc != APR_SUCCESS)
            return apr_psprintf(cmd->pool, "mod_defender: Failed to open the json match log file: %s", file_name);
    }

    return NULL; // success
}
Esempio n. 5
0
static void open_agent_log(server_rec *s, pool *p)
{
    agent_log_state *cls = ap_get_module_config(s->module_config,
                                             &agent_log_module);

    char *fname = ap_server_root_relative(p, cls->fname);

    if (cls->agent_fd > 0)
        return;                 /* virtual log shared w/main server */

    if (*cls->fname == '|') {
        piped_log *pl;

        pl = ap_open_piped_log(p, cls->fname + 1);
        if (pl == NULL) {
	    ap_log_error(APLOG_MARK, APLOG_ERR, s,
			 "couldn't spawn agent log pipe");
            exit(1);
        }
        cls->agent_fd = ap_piped_log_write_fd(pl);
    }
    else if (*cls->fname != '\0') {
        if ((cls->agent_fd = ap_popenf(p, fname, xfer_flags, xfer_mode)) < 0) {
            ap_log_error(APLOG_MARK, APLOG_ERR, s,
                         "could not open agent log file %s.", fname);
            exit(1);
        }
    }
}
Esempio n. 6
0
static void *ap_default_log_writer_init(apr_pool_t *p, server_rec *s,
                                        const char* name)
{
    if (*name == '|') {
        piped_log *pl;

        pl = ap_open_piped_log(p, name + 1);
        if (pl == NULL) {
           return NULL;;
        }
        return ap_piped_log_write_fd(pl);
    }
    else {
        const char *fname = ap_server_root_relative(p, name);
        apr_file_t *fd;
        apr_status_t rv;

        if (!fname) {
            ap_log_error(APLOG_MARK, APLOG_ERR, APR_EBADPATH, s,
                            "invalid transfer log path %s.", name);
            return NULL;
        }
        rv = apr_file_open(&fd, fname, xfer_flags, xfer_perms, p);
        if (rv != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
                            "could not open transfer log file %s.", fname);
            return NULL;
        }
        return fd;
    }
}
static int mod_stlog_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *server)
{
    stlog_config_t *conf = ap_get_module_config(server->module_config, &request_dumper_module);

    if (*conf->log_filename == '|') {
        piped_log *pl;

        pl = ap_open_piped_log(p, conf->log_filename + 1);
        if (pl == NULL) {
            ap_log_error(APLOG_MARK
                , APLOG_ERR
                , 0
                , NULL
                , "%s ERROR %s: dump pipe log oepn failed: %s"
                , MODULE_NAME
                , __func__
                , conf->log_filename
            );

            return OK;
        }

        mod_stlog_fp = ap_piped_log_write_fd(pl);

    } else {
        if(apr_file_open(&mod_stlog_fp, conf->log_filename, APR_WRITE|APR_APPEND|APR_CREATE,
               APR_OS_DEFAULT, p) != APR_SUCCESS){
            ap_log_error(APLOG_MARK
                , APLOG_ERR
                , 0
                , NULL
                , "%s ERROR %s: dump log file oepn failed: %s"
                , MODULE_NAME
                , __func__
                , conf->log_filename
            );

            return OK;
        }
    }

    ap_log_perror(APLOG_MARK
        , APLOG_NOTICE
        , 0
        , p
        , "%s %s: %s / %s mechanism enabled."
        , MODULE_NAME
        , __func__
        , MODULE_NAME
        , MODULE_VERSION
    );

    return OK;
}
/*
 * Open the SSL logfile
 */
void ssl_log_open(server_rec *s_main, server_rec *s, pool *p)
{
    char *szLogFile;
    SSLSrvConfigRec *sc_main = mySrvConfig(s_main);
    SSLSrvConfigRec *sc = mySrvConfig(s);
    piped_log *pl;
    char *cp;

    /* 
     * Short-circuit for inherited logfiles in order to save
     * filedescriptors in mass-vhost situation. Be careful, this works
     * fine because the close happens implicitly by the pool facility.
     */
    if (   s != s_main 
        && sc_main->fileLogFile != NULL
        && (   (sc->szLogFile == NULL)
            || (   sc->szLogFile != NULL 
                && sc_main->szLogFile != NULL 
                && strEQ(sc->szLogFile, sc_main->szLogFile)))) {
        sc->fileLogFile = sc_main->fileLogFile;
    }
    else if (sc->szLogFile != NULL) {
        if (strEQ(sc->szLogFile, "/dev/null"))
            return;
        else if (sc->szLogFile[0] == '|') {
            cp = sc->szLogFile+1;
            while (*cp == ' ' || *cp == '\t')
                cp++;
            szLogFile = ssl_util_server_root_relative(p, "log", cp);
            if ((pl = ap_open_piped_log(p, szLogFile)) == NULL) {
                ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,
                        "Cannot open reliable pipe to SSL logfile filter %s", szLogFile);
                ssl_die();
            }
            sc->fileLogFile = ap_pfdopen(p, ap_piped_log_write_fd(pl), "a");
            setbuf(sc->fileLogFile, NULL);
        }
        else {
            szLogFile = ssl_util_server_root_relative(p, "log", sc->szLogFile);
            if ((sc->fileLogFile = ap_pfopen(p, szLogFile, "a")) == NULL) {
                ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,
                        "Cannot open SSL logfile %s", szLogFile);
                ssl_die();
            }
            setbuf(sc->fileLogFile, NULL);
        }
    }
    return;
}
Esempio n. 9
0
AP_DECLARE(piped_log *) ap_open_piped_log(apr_pool_t *p, const char *program)
{
    piped_log *pl;
    apr_file_t *dummy = NULL;
    int rc;

    rc = log_child(p, program, &dummy, 0);
    if (rc != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL,
                     "Couldn't start piped log process");
        return NULL;
    }

    pl = apr_palloc(p, sizeof (*pl));
    pl->p = p;
    ap_piped_log_read_fd(pl) = NULL;
    ap_piped_log_write_fd(pl) = dummy;
    apr_pool_cleanup_register(p, pl, piped_log_cleanup, piped_log_cleanup);

    return pl;
}
Esempio n. 10
0
static config_log_state *open_config_log(server_rec *s, pool *p,
                                         config_log_state *cls,
                                         array_header *default_format)
{
    if (cls->log_fd > 0) {
        return cls;             /* virtual config shared w/main server */
    }

    if (cls->fname == NULL) {
        return cls;             /* Leave it NULL to decline.  */
    }

    if (*cls->fname == '|') {
        piped_log *pl;

        pl = ap_open_piped_log(p, cls->fname + 1);
        if (pl == NULL) {
            exit(1);
        }
        cls->log_fd = ap_piped_log_write_fd(pl);
    }
    else {
        char *fname = ap_server_root_relative(p, cls->fname);
        if ((cls->log_fd = ap_popenf_ex(p, fname, xfer_flags, xfer_mode, 1))
             < 0) {
            ap_log_error(APLOG_MARK, APLOG_ERR, s,
                         "could not open transfer log file %s.", fname);
            exit(1);
        }
    }
#ifdef BUFFERED_LOGS
    cls->outcnt = 0;
#endif

    return cls;
}
Esempio n. 11
0
static apr_file_t *ap_open_log(apr_pool_t *p, server_rec *s, const char *base, log_options *ls, apr_time_t tm) {
    if (*base == '|') {
        /* We have piped log handling here because once log rotation has been
         * enabled we become responsible for /all/ transfer log output server
         * wide. That's a consequence of the way the log output hooks in
         * mod_log_config are implemented. Unfortunately this means we have to
         * duplicate functionality from mod_log_config. Note that we don't
         * support the buffered logging mode that mlc implements.
         */
        piped_log *pl;

        if (ls->enabled) {
            /* Can't rotate a piped log */
            ls->enabled = 0;
            ap_log_error(APLOG_MARK, APLOG_WARNING, APR_SUCCESS, s,
                            "disabled log rotation for piped log %s.", base);
        }

        if (pl = ap_open_piped_log(p, base + 1), NULL == pl) {
           return NULL;
        }

        return ap_piped_log_write_fd(pl);
    }
    else
    {
        apr_file_t *fd;
        apr_status_t rv;
        const char *name = ap_server_root_relative(p, base);

        if (NULL == name) {
            ap_log_error(APLOG_MARK, APLOG_ERR, APR_EBADPATH, s,
                            "invalid transfer log path %s.", base);
            return NULL;
        }

        if (ls->enabled) {
            apr_time_t log_time = tm - ls->offset;
            if (strchr(base, '%') != NULL) {
                apr_time_exp_t e;

                apr_time_exp_gmt(&e, log_time);
                name = ap_pstrftime(p, name, &e);
            }
            else
            {
                /* Synthesize the log name using the specified time in seconds as a
                 * suffix.  We subtract the offset here because it was added when
                 * quantizing the time but we want the name to reflect the actual
                 * time when the log rotated. We don't reverse the local time
                 * adjustment because, presumably, if you've specified local time
                 * logging you want the filenames to use local time.
                 */
                name = apr_psprintf(p, "%s.%" APR_TIME_T_FMT, name, apr_time_sec(log_time));
            }
        }

        if (rv = apr_file_open(&fd, name, xfer_flags, xfer_perms, p), APR_SUCCESS != rv) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
                            "could not open transfer log file %s.", name);
            return NULL;
        }

        return fd;
    }
}