const char * fcgi_util_fs_is_path_ok(pool * const p, const char * const fs_path, struct stat *finfo) { const char *err; if (finfo == NULL) { finfo = (struct stat *)ap_palloc(p, sizeof(struct stat)); if (stat(fs_path, finfo) < 0) return ap_psprintf(p, "stat(%s) failed: %s", fs_path, strerror(errno)); } if (finfo->st_mode == 0) return ap_psprintf(p, "script not found or unable to stat()"); if (S_ISDIR(finfo->st_mode)) return ap_psprintf(p, "script is a directory!"); /* Let the wrapper determine what it can and can't execute */ if (! fcgi_wrapper) { #ifdef WIN32 err = fcgi_util_check_access(p, fs_path, finfo, _S_IEXEC, fcgi_user_id, fcgi_group_id); #else err = fcgi_util_check_access(p, fs_path, finfo, X_OK, fcgi_user_id, fcgi_group_id); #endif if (err) { return ap_psprintf(p, "access for server (uid %ld, gid %ld) not allowed: %s", (long)fcgi_user_id, (long)fcgi_group_id, err); } } return NULL; }
/******************************************************************************* * Create a directory to hold Unix/Domain sockets. */ const char *fcgi_config_make_dir(pool *tp, char *path) { struct stat finfo; const char *err = NULL; /* Is the directory spec'd correctly */ if (*path != '/') { return "path is not absolute (it must start with a \"/\")"; } else { int i = strlen(path) - 1; /* Strip trailing "/"s */ while(i > 0 && path[i] == '/') path[i--] = '\0'; } /* Does it exist? */ if (stat(path, &finfo) != 0) { /* No, but maybe we can create it */ #ifdef WIN32 if (mkdir(path) != 0) #else if (mkdir(path, S_IRWXU) != 0) #endif { return ap_psprintf(tp, "doesn't exist and can't be created: %s", strerror(errno)); } #ifndef WIN32 /* If we're root, we're gonna setuid/setgid so we need to chown */ if (geteuid() == 0 && chown(path, ap_user_id, ap_group_id) != 0) { return ap_psprintf(tp, "can't chown() to the server (uid %ld, gid %ld): %s", (long)ap_user_id, (long)ap_group_id, strerror(errno)); } #endif } else { /* Yes, is it a directory? */ if (!S_ISDIR(finfo.st_mode)) return "isn't a directory!"; /* Can we RWX in there? */ #ifdef WIN32 err = fcgi_util_check_access(tp, NULL, &finfo, _S_IREAD | _S_IWRITE | _S_IEXEC, fcgi_user_id, fcgi_group_id); #else err = fcgi_util_check_access(tp, NULL, &finfo, R_OK | W_OK | X_OK, fcgi_user_id, fcgi_group_id); #endif if (err != NULL) { return ap_psprintf(tp, "access for server (uid %ld, gid %ld) failed: %s", (long)fcgi_user_id, (long)fcgi_group_id, err); } } return NULL; }
/******************************************************************************* * Enable, disable, or specify the path to a wrapper used to invoke all * FastCGI applications. */ const char *fcgi_config_set_wrapper(cmd_parms *cmd, void *dummy, const char *arg) { #ifdef WIN32 return ap_psprintf(cmd->temp_pool, "the %s directive is not supported on WIN", cmd->cmd->name); #else const char *err = NULL; const char * const name = cmd->cmd->name; pool * const tp = cmd->temp_pool; char * wrapper = NULL; err = ap_check_cmd_context(cmd, GLOBAL_ONLY); if (err) { return err; } if (fcgi_wrapper) { return ap_psprintf(tp, "%s was already set to \"%s\"", name, fcgi_wrapper); } err = fcgi_config_set_fcgi_uid_n_gid(1); if (err != NULL) return ap_psprintf(tp, "%s %s: %s", name, arg, err); if (fcgi_servers != NULL) { return ap_psprintf(tp, "The %s command must preceed static FastCGI server definitions", name); } if (strcasecmp(arg, "Off") == 0) { fcgi_wrapper = NULL; return NULL; } if (strcasecmp(arg, "On") == 0) { wrapper = SUEXEC_BIN; } else { #ifdef APACHE2 if (apr_filepath_merge(&wrapper, "", arg, 0, cmd->pool)) return ap_psprintf(tp, "%s %s: invalid filepath", name, arg); #else wrapper = ap_os_canonical_filename(cmd->pool, (char *) arg); #endif wrapper = ap_server_root_relative(cmd->pool, wrapper); } err = fcgi_util_check_access(tp, wrapper, NULL, X_OK, fcgi_user_id, fcgi_group_id); if (err) { return ap_psprintf(tp, "%s: \"%s\" execute access for server " "(uid %ld, gid %ld) failed: %s", name, wrapper, (long) fcgi_user_id, (long) fcgi_group_id, err); } fcgi_wrapper = wrapper; return NULL; #endif /* !WIN32 */ }