Exemple #1
0
/*******************************************************************************
 * Return absolute path to file in either "regular" FCGI socket directory or
 * the dynamic directory.  Result is allocated in pool p.
 */
const char *
fcgi_util_socket_make_path_absolute(pool * const p, 
        const char *const file, const int dynamic)
{
#ifdef APACHE2
    if (ap_os_is_path_absolute(p, (char *) file))
#else
    if (ap_os_is_path_absolute(file))
#endif
    {
	    return file;
    }
    else
    {
        const char * parent_dir = dynamic ? fcgi_dynamic_dir : fcgi_socket_dir;
        return (const char *) make_full_path(p, parent_dir, file);
    }
}
Exemple #2
0
static int translate_userdir(request_rec *r)
{
    ap_conf_vector_t *server_conf;
    const userdir_config *s_cfg;
    const char *userdirs;
    const char *user, *dname;
    char *redirect;
    apr_finfo_t statbuf;

    /*
     * If the URI doesn't match our basic pattern, we've nothing to do with
     * it.
     */
    if (r->uri[0] != '/' || r->uri[1] != '~') {
        return DECLINED;
    }
    server_conf = r->server->module_config;
    s_cfg = ap_get_module_config(server_conf, &userdir_module);
    userdirs = s_cfg->userdir;
    if (userdirs == NULL) {
        return DECLINED;
    }

    dname = r->uri + 2;
    user = ap_getword(r->pool, &dname, '/');

    /*
     * The 'dname' funny business involves backing it up to capture the '/'
     * delimiting the "/~user" part from the rest of the URL, in case there
     * was one (the case where there wasn't being just "GET /~user HTTP/1.0",
     * for which we don't want to tack on a '/' onto the filename).
     */

    if (dname[-1] == '/') {
        --dname;
    }

    /*
     * If there's no username, it's not for us.  Ignore . and .. as well.
     */
    if (user[0] == '\0' ||
        (user[1] == '.' && (user[2] == '\0' ||
                            (user[2] == '.' && user[3] == '\0')))) {
        return DECLINED;
    }
    /*
     * Nor if there's an username but it's in the disabled list.
     */
    if (apr_table_get(s_cfg->disabled_users, user) != NULL) {
        return DECLINED;
    }
    /*
     * If there's a global interdiction on UserDirs, check to see if this
     * name is one of the Blessed.
     */
    if (s_cfg->globally_disabled == O_DISABLE
        && apr_table_get(s_cfg->enabled_users, user) == NULL) {
        return DECLINED;
    }

    /*
     * Special cases all checked, onward to normal substitution processing.
     */

    while (*userdirs) {
        const char *userdir = ap_getword_conf(r->pool, &userdirs);
        char *filename = NULL, *prefix = NULL;
        apr_status_t rv;
        int is_absolute = ap_os_is_path_absolute(r->pool, userdir);

        if (ap_strchr_c(userdir, '*'))
            prefix = ap_getword(r->pool, &userdir, '*');

        if (userdir[0] == '\0' || is_absolute) {
            if (prefix) {
#ifdef HAVE_DRIVE_LETTERS
                /*
                 * Crummy hack. Need to figure out whether we have been
                 * redirected to a URL or to a file on some drive. Since I
                 * know of no protocols that are a single letter, ignore
                 * a : as the first or second character, and assume a file
                 * was specified
                 */
                if (strchr(prefix + 2, ':'))
#else
                if (strchr(prefix, ':') && !is_absolute)
#endif /* HAVE_DRIVE_LETTERS */
                {
                    redirect = apr_pstrcat(r->pool, prefix, user, userdir,
                                           dname, NULL);
                    apr_table_setn(r->headers_out, "Location", redirect);
                    return HTTP_MOVED_TEMPORARILY;
                }
                else
                    filename = apr_pstrcat(r->pool, prefix, user, userdir,
                                           NULL);
            }
            else
                filename = apr_pstrcat(r->pool, userdir, "/", user, NULL);
        }
        else if (prefix && ap_strchr_c(prefix, ':')) {
            redirect = apr_pstrcat(r->pool, prefix, user, dname, NULL);
            apr_table_setn(r->headers_out, "Location", redirect);
            return HTTP_MOVED_TEMPORARILY;
        }
        else {
#if APR_HAS_USER
            char *homedir;

            if (apr_uid_homepath_get(&homedir, user, r->pool) == APR_SUCCESS) {
                filename = apr_pstrcat(r->pool, homedir, "/", userdir, NULL);
            }
#else
            return DECLINED;
#endif
        }

        /*
         * Now see if it exists, or we're at the last entry. If we are at the
         * last entry, then use the filename generated (if there is one)
         * anyway, in the hope that some handler might handle it. This can be
         * used, for example, to run a CGI script for the user.
         */
        if (filename && (!*userdirs
                      || ((rv = apr_stat(&statbuf, filename, APR_FINFO_MIN,
                                         r->pool)) == APR_SUCCESS
                                             || rv == APR_INCOMPLETE))) {
            r->filename = apr_pstrcat(r->pool, filename, dname, NULL);
            ap_set_context_info(r, apr_pstrmemdup(r->pool, r->uri,
                                                  dname - r->uri),
                                filename);
            /* XXX: Does this walk us around FollowSymLink rules?
             * When statbuf contains info on r->filename we can save a syscall
             * by copying it to r->finfo
             */
            if (*userdirs && dname[0] == 0)
                r->finfo = statbuf;

            /* For use in the get_suexec_identity phase */
            apr_table_setn(r->notes, "mod_userdir_user", user);

            return OK;
        }
    }

    return DECLINED;
}
Exemple #3
0
static const char *vhost_alias_set(cmd_parms *cmd, void *dummy, const char *map)
{
    mva_sconf_t *conf;
    mva_mode_e mode, *pmode;
    const char **pmap;
    const char *p;
  
    conf = (mva_sconf_t *) ap_get_module_config(cmd->server->module_config,
						&vhost_alias_module);
    /* there ought to be a better way of doing this */
    if (&vhost_alias_set_doc_root_ip == cmd->info) {
	mode = VHOST_ALIAS_IP;
	pmap = &conf->doc_root;
	pmode = &conf->doc_root_mode;
    }
    else if (&vhost_alias_set_cgi_root_ip == cmd->info) {
	mode = VHOST_ALIAS_IP;
	pmap = &conf->cgi_root;
	pmode = &conf->cgi_root_mode;
    }
    else if (&vhost_alias_set_doc_root_name == cmd->info) {
	mode = VHOST_ALIAS_NAME;
	pmap = &conf->doc_root;
	pmode = &conf->doc_root_mode;
    }
    else if (&vhost_alias_set_cgi_root_name == cmd->info) {
	mode = VHOST_ALIAS_NAME;
	pmap = &conf->cgi_root;
	pmode = &conf->cgi_root_mode;
    }
    else {
	return "INTERNAL ERROR: unknown command info";
    }

    if (!ap_os_is_path_absolute(cmd->pool, map)) {
	if (strcasecmp(map, "none")) {
	    return "format string must be an absolute path, or 'none'";
	}
	*pmap = NULL;
	*pmode = VHOST_ALIAS_NONE;
	return NULL;
    }

    /* sanity check */
    p = map;
    while (*p != '\0') {
	if (*p++ != '%') {
	    continue;
	}
	/* we just found a '%' */
	if (*p == 'p' || *p == '%') {
	    ++p;
	    continue;
	}
	/* optional dash */
	if (*p == '-') {
	    ++p;
	}
	/* digit N */
	if (apr_isdigit(*p)) {
	    ++p;
	}
	else {
	    return "syntax error in format string";
	}
	/* optional plus */
	if (*p == '+') {
	    ++p;
	}
	/* do we end here? */
	if (*p != '.') {
	    continue;
	}
	++p;
	/* optional dash */
	if (*p == '-') {
	    ++p;
	}
	/* digit M */
	if (apr_isdigit(*p)) {
	    ++p;
	}
	else {
	    return "syntax error in format string";
	}
	/* optional plus */
	if (*p == '+') {
	    ++p;
	}
    }
    *pmap = map;
    *pmode = mode;
    return NULL;
}
Exemple #4
0
static const char *set_user_dir(cmd_parms *cmd, void *dummy, char *arg)
{
    userdir_config *s_cfg;
    char *username;
    const char *usernames = arg;
    char *kw = ap_getword_conf(cmd->pool, &usernames);
    table *usertable;

    s_cfg = (userdir_config *) ap_get_module_config(cmd->server->module_config,
                                                    &userdir_module);
    /*
     * Let's do the comparisons once.
     */
    if ((!strcasecmp(kw, "disable")) || (!strcasecmp(kw, "disabled"))) {
        /*
         * If there are no usernames specified, this is a global disable - we
         * need do no more at this point than record the fact.
         */
        if (strlen(usernames) == 0) {
            s_cfg->globally_disabled = 1;
            return NULL;
        }
        usertable = s_cfg->disabled_users;
    }
    else if ((!strcasecmp(kw, "enable")) || (!strcasecmp(kw, "enabled"))) {
        /*
         * The "disable" keyword can stand alone or take a list of names, but
         * the "enable" keyword requires the list.  Whinge if it doesn't have
         * it.
         */
        if (strlen(usernames) == 0) {
            return "UserDir \"enable\" keyword requires a list of usernames";
        }
        usertable = s_cfg->enabled_users;
    }
    else {
        /*
         * If the first (only?) value isn't one of our keywords, look at each
         * config 'word' for validity and copy the entire arg to the userdir 
         * if all paths are valid.
         */
        const char *userdirs = arg;
        while (*userdirs) {
            char *thisdir = ap_getword_conf(cmd->pool, &userdirs);
            if (!ap_os_is_path_absolute(thisdir) && !strchr(thisdir, ':')) {
#if defined(WIN32) || defined(NETWARE)
                return "UserDir must specify an absolute redirect "
                       "or absolute file path";
#else
                if (strchr(thisdir, '*')) {
                     return "UserDir cannot specify '*' substitution within "
                            "a relative path";
                }
#endif
            }
        }
        s_cfg->userdir = ap_pstrdup(cmd->pool, arg);
#if defined(WIN32) || defined(OS2) || defined(NETWARE)
        /* These are incomplete paths, so we cannot canonicalize them yet.
         * but any backslashes will confuse the parser, later, so simply
         * change them to slash form.
         */
        arg = s_cfg->userdir;
        while (arg = strchr(arg, '\\')) {
            *(arg++) = '/';
        }
#endif
        return NULL;
    }
    /*
     * Now we just take each word in turn from the command line and add it to
     * the appropriate table.
     */
    while (*usernames) {
        username = ap_getword_conf(cmd->pool, &usernames);
        ap_table_setn(usertable, username, kw);
    }
    return NULL;
}
Exemple #5
0
static int translate_userdir(request_rec *r)
{
    void *server_conf = r->server->module_config;
    const userdir_config *s_cfg =
    (userdir_config *) ap_get_module_config(server_conf, &userdir_module);
    char *name = r->uri;
    const char *userdirs = s_cfg->userdir;
    const char *w, *dname;
    char *redirect;
    struct stat statbuf;

    /*
     * If the URI doesn't match our basic pattern, we've nothing to do with
     * it.
     */
    if ((s_cfg->userdir == NULL)
        || (name[0] != '/')
        || (name[1] != '~')) {
        return DECLINED;
    }

    dname = name + 2;
    w = ap_getword(r->pool, &dname, '/');

    /*
     * The 'dname' funny business involves backing it up to capture the '/'
     * delimiting the "/~user" part from the rest of the URL, in case there
     * was one (the case where there wasn't being just "GET /~user HTTP/1.0",
     * for which we don't want to tack on a '/' onto the filename).
     */

    if (dname[-1] == '/') {
        --dname;
    }

    /*
     * If there's no username, it's not for us.  Ignore . and .. as well.
     */
    if ((w[0] == '\0')
        || ((w[1] == '.')
            && ((w[2] == '\0')
                || ((w[2] == '.') && (w[3] == '\0'))))) {
        return DECLINED;
    }
    /*
     * Nor if there's an username but it's in the disabled list.
     */
    if (ap_table_get(s_cfg->disabled_users, w) != NULL) {
        return DECLINED;
    }
    /*
     * If there's a global interdiction on UserDirs, check to see if this
     * name is one of the Blessed.
     */
    if (s_cfg->globally_disabled
        && (ap_table_get(s_cfg->enabled_users, w) == NULL)) {
        return DECLINED;
    }

    /*
     * Special cases all checked, onward to normal substitution processing.
     */

    while (*userdirs) {
        const char *userdir = ap_getword_conf(r->pool, &userdirs);
        char *filename = NULL;
        int is_absolute = ap_os_is_path_absolute(userdir);

        if (strchr(userdir, '*')) {
            /* token '*' embedded:
             */
            char *x = ap_getword(r->pool, &userdir, '*');
            if (is_absolute) {
                /* token '*' within absolute path
                 * serves [UserDir arg-pre*][user][UserDir arg-post*]
                 * /somepath/ * /somedir + /~smith -> /somepath/smith/somedir
                 */
                filename = ap_pstrcat(r->pool, x, w, userdir, NULL);
            }
            else if (strchr(x, ':')) {
                /* token '*' within a redirect path
                 * serves [UserDir arg-pre*][user][UserDir arg-post*]
                 * http://server/user/ * + /~smith/foo ->
                 *   http://server/user/smith/foo
                 */
                redirect = ap_pstrcat(r->pool, x, w, userdir, dname, NULL);
                ap_table_setn(r->headers_out, "Location", redirect);
                return REDIRECT;
            }
            else {
                /* Not a redirect, not an absolute path, '*' token:
                 * serves [homedir]/[UserDir arg]
                 * something/ * /public_html
                 * Shouldn't happen, we trap for this in set_user_dir
                 */
                return DECLINED;
            }
        }
        else if (is_absolute) {
            /* An absolute path, no * token:
             * serves [UserDir arg]/[user]
             * /home + /~smith -> /home/smith
             */
            if (userdir[strlen(userdir) - 1] == '/')
                filename = ap_pstrcat(r->pool, userdir, w, NULL);
            else
                filename = ap_pstrcat(r->pool, userdir, "/", w, NULL);
        }
        else if (strchr(userdir, ':')) {
            /* A redirect, not an absolute path, no * token:
             * serves [UserDir arg]/[user][dname]
             * http://server/ + /~smith/foo -> http://server/smith/foo
             */
            if (userdir[strlen(userdir) - 1] == '/') {
                redirect = ap_pstrcat(r->pool, userdir, w, dname, NULL);
            }
            else {
                redirect = ap_pstrcat(r->pool, userdir, "/", w, dname, NULL);
            }
            ap_table_setn(r->headers_out, "Location", redirect);
            return REDIRECT;
        }
        else {
            /* Not a redirect, not an absolute path, no * token:
             * serves [homedir]/[UserDir arg]
             * e.g. /~smith -> /home/smith/public_html
             */
#if defined(WIN32) || defined(NETWARE)
            /* Need to figure out home dirs on NT and NetWare 
             * Shouldn't happen here, though, we trap for this in set_user_dir
             */
            return DECLINED;
#else                           /* WIN32 & NetWare */
            struct passwd *pw;
            if ((pw = getpwnam(w))) {
#ifdef OS2
                /* Need to manually add user name for OS/2 */
                filename = ap_pstrcat(r->pool, pw->pw_dir, w, "/",
                                      userdir, NULL);
#else
                filename = ap_pstrcat(r->pool, pw->pw_dir, "/",
                                      userdir, NULL);
#endif
            }
#endif                          /* WIN32 & NetWare */
        }

        /*
         * Now see if it exists, or we're at the last entry. If we are at the
         * last entry, then use the filename generated (if there is one)
         * anyway, in the hope that some handler might handle it. This can be
         * used, for example, to run a CGI script for the user.
         */
        if (filename && (!*userdirs || stat(filename, &statbuf) != -1)) {
            r->filename = ap_pstrcat(r->pool, filename, dname, NULL);
	    /* when statbuf contains info on r->filename we can save a syscall
	     * by copying it to r->finfo
	     */
	    if (*userdirs && dname[0] == 0) {
		r->finfo = statbuf;
            }
            return OK;
        }
    }

    return DECLINED;
}
Exemple #6
0
static int sqlalias_redir(request_rec *r)
{
	MYSQL *dblink = NULL;

	server_rec *s = r->server;
	sqlalias_conf_t *s_cfg = (sqlalias_conf_t *) ap_get_module_config(s->module_config, &sqlalias_module);

	if (r->uri[0] != '/' && r->uri[0] != '\0') {
		return DECLINED;
	} else if(!s_cfg->enable || sqlalias_filter(r, s_cfg->filters) == FILTERED_URI || !(dblink = sqlalias_dbconnect(r->server, s_cfg))) { 
		return DECLINED;
	} else {
		MYSQL_RES *result = NULL;
		MYSQL_ROW row;

		char *query = NULL;
		int found = 0;
		int response = 0;

		const char *ccp;

		int uri_length = strlen(r->uri);
		char *uri = (char *) malloc(sizeof(char) * (uri_length * 2 + 1));
		strcpy(uri, r->uri);

#ifndef SQLALIAS_PERFECT_MATCH
		if (uri_length > 1 && uri[uri_length-1] == '/') {
			uri[uri_length-1] = '\0';
			uri_length--;
		}
#endif /* SQLALIAS_PERFECT_MATCH */

		mysql_real_escape_string(dblink, uri, uri, uri_length);
		query = apr_psprintf(r->pool, s_cfg->db_query, uri);
		free(uri);

		if(mysql_real_query(dblink, query, strlen(query))) {
			ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r->server, "sqlalias: %s.", mysql_error(dblink));
#ifdef SQLALIAS_USE_PCONNECT	
			apr_thread_mutex_unlock(sqlalias_mutex);
#else
			DEBUG_MSG(r->server, "sqlalias: Database connection closed. (pid:%d)", getpid());
			mysql_close(dblink);
#endif /* SQLALIAS_USE_PCONNECT */
			return DECLINED;
		}

		if (!(result = mysql_store_result(dblink))) {
			ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r->server, "sqlalias: %s.", mysql_error(dblink));

#ifdef SQLALIAS_USE_PCONNECT	
			apr_thread_mutex_unlock(sqlalias_mutex);
#else 
			DEBUG_MSG(r->server, "sqlalias: Database connection closed. (pid:%d)", getpid());
			mysql_close(dblink);
#endif /* SQLALIAS_USE_PCONNECT */

			return DECLINED;
		}


		if((row = mysql_fetch_row(result))) {
			found = 1;
			response = (mysql_num_fields(result) > 1) ? atoi(row[1]) : DECLINED ;

			if(ap_is_HTTP_REDIRECT(response) || (is_absolute_uri(row[0]) && (response = HTTP_MOVED_TEMPORARILY))) {
				char *destination = apr_pstrdup(r->pool, row[0]);
				DEBUG_MSG(r->server, "sqlalias: %s redirect to %s (R=%d)", r->uri, destination, response?response:HTTP_OK);
				apr_table_setn(r->headers_out, "Location", destination);
			} else { 
				DEBUG_MSG(r->server, "sqlalias: rewrite %s -> %s", r->uri, row[0]);
				/* the filename must be either an absolute local path or an
				 * absolute local URL.
				 */
				if (*row[0] != '/' && !ap_os_is_path_absolute(r->pool, row[0])) {
					ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "sqlalias: Bad redirection for %s (%s)", r->uri, row[0]);
					response = HTTP_BAD_REQUEST;
				} else if ((ccp = ap_document_root(r)) != NULL) {
					char *q = NULL;

					r->uri = apr_pstrdup(r->pool, row[0]);
					q = strchr(r->uri, '?');
					if (q != NULL) {
						char *olduri = NULL;
						olduri = apr_pstrdup(r->pool, r->uri);
						*q++ = '\0';

						if(r->args)
								r->args = apr_pstrcat(r->pool, q, "&", r->args, NULL);
						else
								r->args = apr_pstrdup(r->pool, q);

						if(strlen(r->args) == 0)
								r->args = NULL;
					}
				}
			}
#ifdef SQLALIAS_DEBUG
		} else {
			DEBUG_MSG(r->server, "sqlalias: No entry for %s", r->uri);
#endif /* SQLALIAS_DEBUG */                       
		}

		mysql_free_result(result);

#ifdef SQLALIAS_USE_PCONNECT
		apr_thread_mutex_unlock(sqlalias_mutex);
#else
		DEBUG_MSG(r->server, "sqlalias: Database connection closed. (pid:%d)", getpid());
		mysql_close(dblink);
#endif /* SQLALIAS_USE_PCONNECT */

		if(found && response != 200) return response;
	}

	return DECLINED;
}