int mod_dirsize_handler(request_rec *r) { BUFF *pipe_output; char buf[MAX_STRING_LEN]; char *sizeink=NULL; regmatch_t pmatch[2]; r->path_info = ap_make_dirstr_parent(r->pool, r->filename); if(!ap_bspawn_child(r->pool,dirsize, (void *) r, kill_after_timeout, NULL, &pipe_output, NULL)) { ap_log_error(APLOG_MARK, APLOG_ERR, r->server, "problems with dirsize subprocess"); return HTTP_INTERNAL_SERVER_ERROR; } ap_bgets(buf, sizeof(buf), pipe_output); regex_t *cpat = ap_pregcomp(r->pool, "^(.+)\t", REG_EXTENDED); if(regexec(cpat, buf, cpat->re_nsub+1, pmatch, 0) == 0) { sizeink = ap_pregsub(r->pool, "$1", buf, cpat->re_nsub+1, pmatch); } #ifdef DEBUG r->content_type = "text/html"; ap_send_http_header(r); ap_rprintf(r, "<html>\n"); ap_rprintf(r, "<head>\n"); ap_rprintf(r, "<title>mod_dirsize</title>\n"); ap_rprintf(r, "</head>\n"); ap_rprintf(r, "<body>\n"); ap_rprintf(r, "Request: %s<br>\n", r->the_request); ap_rprintf(r, "Server Hostname: %s<br>\n", r->server->server_hostname); ap_rprintf(r, "Server Admin: %s<br>\n", r->server->server_admin); ap_rprintf(r, "Filename: %s<br>\n", r->filename); ap_rprintf(r, "ServerRoot: %s<br>\n", ap_server_root_relative(r->pool, "")); ap_rprintf(r, "Path Info: %s<br>\n", r->path_info); ap_send_fb(pipe_output, r); ap_rprintf(r, "</body>\n"); ap_rprintf(r, "</html>\n"); #else r->content_type = "text/xml"; ap_send_http_header(r); ap_rprintf(r, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); ap_rprintf(r, "<dirsize xmlns:html=\"http://www.w3.org/1999/html\">\n"); ap_rprintf(r, "<sizeink>%s</sizeink>\n", sizeink); ap_rprintf(r, "</dirsize>"); #endif ap_bclose(pipe_output); return(OK); }
apr_file_t *ssl_util_ppopen(server_rec *s, apr_pool_t *p, const char *cmd, const char * const *argv) { apr_procattr_t *procattr; apr_proc_t *proc; if (apr_procattr_create(&procattr, p) != APR_SUCCESS) return NULL; if (apr_procattr_io_set(procattr, APR_FULL_BLOCK, APR_FULL_BLOCK, APR_FULL_BLOCK) != APR_SUCCESS) return NULL; if (apr_procattr_dir_set(procattr, ap_make_dirstr_parent(p, cmd)) != APR_SUCCESS) return NULL; if (apr_procattr_cmdtype_set(procattr, APR_PROGRAM) != APR_SUCCESS) return NULL; proc = apr_pcalloc(p, sizeof(apr_proc_t)); if (apr_proc_create(proc, cmd, argv, NULL, procattr, p) != APR_SUCCESS) return NULL; return proc->out; }
/** * field -> "path" or "cpath" * sub_pat -> "?.lua" * rep_pat -> "./?.lua" * pool -> lifecycle pool for allocations * paths -> things to add * file -> ??? */ static void munge_path(lua_State *L, const char *field, const char *sub_pat, const char *rep_pat, apr_pool_t *pool, apr_array_header_t *paths, const char *file) { const char *current; const char *parent_dir; const char *pattern; const char *modified; char *part; lua_getglobal(L, "package"); lua_getfield(L, -1, field); current = lua_tostring(L, -1); parent_dir = ap_make_dirstr_parent(pool, file); pattern = apr_pstrcat(pool, parent_dir, sub_pat, NULL); luaL_gsub(L, current, rep_pat, pattern); lua_setfield(L, -3, field); lua_getfield(L, -2, field); modified = lua_tostring(L, -1); lua_pop(L, 2); part = apr_pstrcat(pool, modified, ";", apr_array_pstrcat(pool, paths, ';'), NULL); lua_pushstring(L, part); lua_setfield(L, -2, field); lua_pop(L, 1); /* pop "package" off the stack */ }
char *ApacheRequest_script_path(ApacheRequest *req) { return ap_make_dirstr_parent(req->r->pool, ApacheRequest_script_name(req)); }
apr_status_t proc_spawn_process(const char *cmdline, fcgid_proc_info *procinfo, fcgid_procnode *procnode) { HANDLE *finish_event, listen_handle; SECURITY_ATTRIBUTES SecurityAttributes; fcgid_server_conf *sconf; apr_procattr_t *proc_attr; apr_status_t rv; apr_file_t *file; const char * const *proc_environ; char sock_path[FCGID_PATH_MAX]; int argc; char const * wargv[APACHE_ARG_MAX + 1], *word; /* For wrapper */ const char *tmp; /* Build wrapper args */ argc = 0; tmp = cmdline; while (1) { word = ap_getword_white(procnode->proc_pool, &tmp); if (word == NULL || *word == '\0') break; if (argc >= APACHE_ARG_MAX) break; wargv[argc++] = word; } wargv[argc] = NULL; memset(&SecurityAttributes, 0, sizeof(SecurityAttributes)); /* Prepare finish event */ finish_event = apr_palloc(procnode->proc_pool, sizeof(HANDLE)); *finish_event = CreateEvent(NULL, TRUE, FALSE, NULL); if (*finish_event == NULL || !SetHandleInformation(*finish_event, HANDLE_FLAG_INHERIT, TRUE)) { ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(), procinfo->main_server, "mod_fcgid: can't create mutex for subprocess"); return APR_ENOLOCK; } apr_pool_cleanup_register(procnode->proc_pool, finish_event, close_finish_event, apr_pool_cleanup_null); /* For proc_kill_gracefully() */ apr_pool_userdata_set(finish_event, FINISH_EVENT_DATA_NAME, NULL, procnode->proc_pool); /* Pass the finish event id to subprocess */ apr_table_setn(procinfo->proc_environ, SHUTDOWN_EVENT_NAME, apr_ltoa(procnode->proc_pool, (long) *finish_event)); /* Prepare the listen namedpipe file name (no check for truncation) */ apr_snprintf(sock_path, sizeof sock_path, "\\\\.\\pipe\\fcgidpipe-%lu.%d", GetCurrentProcessId(), g_process_counter++); /* Prepare the listen namedpipe handle */ SecurityAttributes.bInheritHandle = TRUE; SecurityAttributes.nLength = sizeof(SecurityAttributes); SecurityAttributes.lpSecurityDescriptor = NULL; listen_handle = CreateNamedPipe(sock_path, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 8192, 8192, 0, &SecurityAttributes); if (listen_handle == INVALID_HANDLE_VALUE) { ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(), procinfo->main_server, "mod_fcgid: can't create namedpipe for subprocess"); return APR_ENOSOCKET; } apr_cpystrn(procnode->socket_path, sock_path, sizeof(procnode->socket_path)); apr_cpystrn(procnode->executable_path, wargv[0], sizeof(procnode->executable_path)); /* Build environment variables */ proc_environ = (const char * const *) ap_create_environment(procnode->proc_pool, procinfo->proc_environ); if (!proc_environ) { ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(), procinfo->main_server, "mod_fcgid: can't build environment variables"); return APR_ENOMEM; } /* Create process now */ if ((rv = apr_procattr_create(&proc_attr, procnode->proc_pool)) != APR_SUCCESS || (rv = apr_procattr_dir_set(proc_attr, ap_make_dirstr_parent(procnode->proc_pool, wargv[0]))) != APR_SUCCESS || (rv = apr_procattr_cmdtype_set(proc_attr, APR_PROGRAM)) != APR_SUCCESS || (rv = apr_procattr_detach_set(proc_attr, 1)) != APR_SUCCESS || (rv = apr_procattr_io_set(proc_attr, APR_NO_PIPE, APR_NO_FILE, APR_NO_FILE)) != APR_SUCCESS || (rv = apr_os_file_put(&file, &listen_handle, 0, procnode->proc_pool)) != APR_SUCCESS || (rv = apr_procattr_child_in_set(proc_attr, file, NULL)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_WARNING, rv, procinfo->main_server, "mod_fcgid: can't create FastCGI process attribute"); CloseHandle(listen_handle); return APR_ENOPROC; } /* fork and exec now */ rv = apr_proc_create(&(procnode->proc_id), wargv[0], wargv, proc_environ, proc_attr, procnode->proc_pool); /* OK, I created the process, now put it back to idle list */ CloseHandle(listen_handle); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, procinfo->main_server, "mod_fcgid: can't run %s", wargv[0]); return rv; } /* FcgidWin32PreventOrphans feature */ sconf = ap_get_module_config(procinfo->main_server->module_config, &fcgid_module); if (sconf->hJobObjectForAutoCleanup != NULL) { /* Associate cgi process to current process */ if (AssignProcessToJobObject(sconf->hJobObjectForAutoCleanup, procnode->proc_id.hproc) == 0) { ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(), procinfo->main_server, "mod_fcgid: unable to assign child process to " "job object"); } } return APR_SUCCESS; }
static apr_status_t run_cgi_child(apr_file_t **script_out, apr_file_t **script_in, apr_file_t **script_err, const char *command, const char * const argv[], request_rec *r, apr_pool_t *p, cgi_exec_info_t *e_info) { const char * const *env; apr_procattr_t *procattr; apr_proc_t *procnew; apr_status_t rc = APR_SUCCESS; #if defined(RLIMIT_CPU) || defined(RLIMIT_NPROC) || \ defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined (RLIMIT_AS) core_dir_config *conf = ap_get_module_config(r->per_dir_config, &core_module); #endif #ifdef DEBUG_CGI #ifdef OS2 /* Under OS/2 need to use device con. */ FILE *dbg = fopen("con", "w"); #else FILE *dbg = fopen("/dev/tty", "w"); #endif int i; #endif RAISE_SIGSTOP(CGI_CHILD); #ifdef DEBUG_CGI fprintf(dbg, "Attempting to exec %s as CGI child (argv0 = %s)\n", r->filename, argv[0]); #endif env = (const char * const *)ap_create_environment(p, r->subprocess_env); #ifdef DEBUG_CGI fprintf(dbg, "Environment: \n"); for (i = 0; env[i]; ++i) fprintf(dbg, "'%s'\n", env[i]); #endif /* Transmute ourselves into the script. * NB only ISINDEX scripts get decoded arguments. */ if (((rc = apr_procattr_create(&procattr, p)) != APR_SUCCESS) || ((rc = apr_procattr_io_set(procattr, e_info->in_pipe, e_info->out_pipe, e_info->err_pipe)) != APR_SUCCESS) || ((rc = apr_procattr_dir_set(procattr, ap_make_dirstr_parent(r->pool, r->filename))) != APR_SUCCESS) || #ifdef RLIMIT_CPU ((rc = apr_procattr_limit_set(procattr, APR_LIMIT_CPU, conf->limit_cpu)) != APR_SUCCESS) || #endif #if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS) ((rc = apr_procattr_limit_set(procattr, APR_LIMIT_MEM, conf->limit_mem)) != APR_SUCCESS) || #endif #ifdef RLIMIT_NPROC ((rc = apr_procattr_limit_set(procattr, APR_LIMIT_NPROC, conf->limit_nproc)) != APR_SUCCESS) || #endif ((rc = apr_procattr_cmdtype_set(procattr, e_info->cmd_type)) != APR_SUCCESS) || ((rc = apr_procattr_detach_set(procattr, e_info->detached)) != APR_SUCCESS) || ((rc = apr_procattr_addrspace_set(procattr, e_info->addrspace)) != APR_SUCCESS) || ((rc = apr_procattr_child_errfn_set(procattr, cgi_child_errfn)) != APR_SUCCESS)) { /* Something bad happened, tell the world. */ ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, "couldn't set child process attributes: %s", r->filename); } else { procnew = apr_pcalloc(p, sizeof(*procnew)); rc = ap_os_create_privileged_process(r, procnew, command, argv, env, procattr, p); if (rc != APR_SUCCESS) { /* Bad things happened. Everyone should have cleaned up. */ ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_TOCLIENT, rc, r, "couldn't create child process: %d: %s", rc, apr_filepath_name_get(r->filename)); } else { apr_pool_note_subprocess(p, procnew, APR_KILL_AFTER_TIMEOUT); *script_in = procnew->out; if (!*script_in) return APR_EBADF; apr_file_pipe_timeout_set(*script_in, r->server->timeout); if (e_info->prog_type == RUN_AS_CGI) { *script_out = procnew->in; if (!*script_out) return APR_EBADF; apr_file_pipe_timeout_set(*script_out, r->server->timeout); *script_err = procnew->err; if (!*script_err) return APR_EBADF; apr_file_pipe_timeout_set(*script_err, r->server->timeout); } } } #ifdef DEBUG_CGI fclose(dbg); #endif return (rc); }
static int check_request_acl(request_rec *r, int req_access) { char *dir_path, *acl_path; apr_finfo_t acl_finfo; const char *req_uri, *dir_uri, *acl_uri, *access; const char *port, *par_uri, *req_file; librdf_world *rdf_world = NULL; librdf_storage *rdf_storage = NULL; librdf_model *rdf_model = NULL; librdf_parser *rdf_parser = NULL; librdf_uri *rdf_uri_acl = NULL, *rdf_uri_base = NULL; int ret = HTTP_FORBIDDEN; // dir_path: parent directory of request filename // acl_path: absolute path to request ACL dir_path = ap_make_dirstr_parent(r->pool, r->filename); acl_path = ap_make_full_path(r->pool, dir_path, WEBID_ACL_FNAME); if (apr_filepath_merge(&acl_path, NULL, acl_path, APR_FILEPATH_NOTRELATIVE, r->pool) != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "Module bug? Request filename path %s is invalid or " "or not absolute for uri %s", r->filename, r->uri); return HTTP_FORBIDDEN; } // acl_path: 403 if missing if ((apr_stat(&acl_finfo, acl_path, APR_FINFO_TYPE, r->pool) != APR_SUCCESS) || (acl_finfo.filetype != APR_REG)) { return HTTP_FORBIDDEN; } // req_uri: fully qualified URI of request filename // dir_uri: fully qualified URI of request filename parent // acl_uri: fully qualified URI of request filename ACL // access: ACL URI of requested access port = ap_is_default_port(ap_get_server_port(r), r) ? "" : apr_psprintf(r->pool, ":%u", ap_get_server_port(r)); req_uri = apr_psprintf(r->pool, "%s://%s%s%s%s", ap_http_scheme(r), ap_get_server_name(r), port, (*r->uri == '/') ? "" : "/", r->uri); par_uri = ap_make_dirstr_parent(r->pool, r->uri); dir_uri = apr_psprintf(r->pool, "%s://%s%s%s%s", ap_http_scheme(r), ap_get_server_name(r), port, (*par_uri == '/') ? "" : "/", par_uri); acl_uri = ap_make_full_path(r->pool, dir_uri, WEBID_ACL_FNAME); if (req_access == WEBID_ACCESS_READ) { access = "Read"; } else if (req_access == WEBID_ACCESS_WRITE) { if ((req_file = strrchr(r->filename, '/')) != NULL && strcmp(++req_file, WEBID_ACL_FNAME) == 0) access = "Control"; else access = "Write"; } else { access = "Control"; } ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "[ACL] %s (%s) %s | URI: %s | DIR: %s (%s) | ACL: %s (%s) | status: %d", r->method, access, r->uri, req_uri, dir_uri, dir_path, acl_uri, acl_path, r->status); if ((rdf_world = librdf_new_world()) != NULL) { librdf_world_open(rdf_world); if ((rdf_storage = librdf_new_storage(rdf_world, "memory", NULL, NULL)) != NULL) { if ((rdf_model = librdf_new_model(rdf_world, rdf_storage, NULL)) != NULL) { if ((rdf_parser = librdf_new_parser(rdf_world, "turtle", NULL, NULL)) != NULL) { if ((rdf_uri_base = librdf_new_uri(rdf_world, (unsigned char*)acl_uri)) != NULL) { if ((rdf_uri_acl = librdf_new_uri_from_filename(rdf_world, acl_path)) != NULL) { if (!librdf_parser_parse_into_model(rdf_parser, rdf_uri_acl, rdf_uri_base, rdf_model)) { //log_stream_prefix(r, librdf_model_as_stream(rdf_model), "[ACL] [model]"); if (query_results(r, rdf_world, rdf_model, apr_psprintf(r->pool, SPARQL_URI_MODE_AGENT, "accessTo", req_uri, access, r->user)) > 0 || \ query_results(r, rdf_world, rdf_model, apr_psprintf(r->pool, SPARQL_URI_MODE_AGENTCLASS, "accessTo", req_uri, access, r->user)) > 0 || \ query_results(r, rdf_world, rdf_model, apr_psprintf(r->pool, SPARQL_URI_MODE_WORLD, "accessTo", req_uri, access)) > 0 || \ ( ( query_results(r, rdf_world, rdf_model, apr_psprintf(r->pool, SPARQL_URI_ACL_EXISTS, "accessTo", req_uri )) == 0 ) && ( query_results(r, rdf_world, rdf_model, apr_psprintf(r->pool, SPARQL_URI_MODE_AGENT, "defaultForNew", dir_uri, access, r->user)) > 0 || \ query_results(r, rdf_world, rdf_model, apr_psprintf(r->pool, SPARQL_URI_MODE_AGENTCLASS, "defaultForNew", dir_uri, access, r->user)) > 0 || \ query_results(r, rdf_world, rdf_model, apr_psprintf(r->pool, SPARQL_URI_MODE_WORLD, "defaultForNew", dir_uri, access)) > 0 ) ) ) { apr_table_set(r->headers_out, "Link", apr_psprintf(r->pool, "%s; rel=meta", acl_uri)); ret = OK; } } else ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "librdf_parser_parse_into_model failed"); librdf_free_uri(rdf_uri_acl); } else ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "librdf_new_uri_from_filename returned NULL"); librdf_free_uri(rdf_uri_base); } else ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "librdf_new_uri returned NULL"); librdf_free_parser(rdf_parser); } else ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "librdf_new_parser returned NULL"); librdf_free_model(rdf_model); } else ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "librdf_new_model returned NULL"); librdf_free_storage(rdf_storage); } else ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "librdf_new_storage returned NULL"); librdf_free_world(rdf_world); } else ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "librdf_new_world returned NULL"); return ret; }