示例#1
0
文件: procops.c 项目: crab2313/MoarVM
/* gets the homedir of the current user. Probably should take username as an argument */
MVMString * MVM_proc_gethomedir(MVMThreadContext *tc) {
    apr_uid_t userid = (apr_uid_t)MVM_proc_getuid(tc);
    MVMString *result;
    apr_status_t rv;
    char *namestring;
    apr_pool_t *tmp_pool;
    char *dirname;

    /* need a temporary pool */
    if ((rv = apr_pool_create(&tmp_pool, POOL(tc))) != APR_SUCCESS) {
        MVM_exception_throw_apr_error(tc, rv, "Failed to get user name from uid: ");
    }

    if ((rv = apr_uid_name_get(&namestring, (apr_uid_t)userid, tmp_pool)) != APR_SUCCESS) {
        apr_pool_destroy(tmp_pool);
        MVM_exception_throw_apr_error(tc, rv, "Failed to get user name from uid: ");
    }

    if ((rv = apr_uid_homepath_get(&dirname, namestring, tmp_pool)) != APR_SUCCESS) {
        apr_pool_destroy(tmp_pool);
        MVM_exception_throw_apr_error(tc, rv, "Failed to get homedir: ");
    }

    result = MVM_string_utf8_decode(tc, tc->instance->VMString, dirname, strlen(dirname));

    apr_pool_destroy(tmp_pool);

    return result;
}
示例#2
0
static void fail_userinfo(CuTest *tc)
{
    apr_uid_t uid;
    apr_gid_t gid;
    apr_status_t rv;
    char *tmp;

    errno = 0;
    gid = uid = 9999999;
    tmp = NULL;
    rv = apr_uid_name_get(&tmp, uid, p);
    CuAssert(tc, "apr_uid_name_get should fail or "
                "return a user name",
                rv != APR_SUCCESS || tmp != NULL);

    errno = 0;
    tmp = NULL;
    rv = apr_gid_name_get(&tmp, gid, p);
    CuAssert(tc, "apr_gid_name_get should fail or "
             "return a group name",
             rv != APR_SUCCESS || tmp != NULL);
    
    gid = 424242;
    errno = 0;
    rv = apr_gid_get(&gid, "I_AM_NOT_A_GROUP", p);
    CuAssert(tc, "apr_gid_get should fail or "
             "set a group number",
             rv != APR_SUCCESS || gid == 424242);

    gid = uid = 424242;
    errno = 0;
    rv = apr_uid_get(&uid, &gid, "I_AM_NOT_A_USER", p);
    CuAssert(tc, "apr_gid_get should fail or "
             "set a user and group number",
             rv != APR_SUCCESS || uid == 424242 || gid == 4242442);

    errno = 0;
    tmp = NULL;
    rv = apr_uid_homepath_get(&tmp, "I_AM_NOT_A_USER", p);
    CuAssert(tc, "apr_uid_homepath_get should fail or "
             "set a path name",
             rv != APR_SUCCESS || tmp != NULL);
}
示例#3
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;
}
示例#4
0
/* deprecated */
APR_DECLARE(apr_status_t) apr_get_home_directory(char **dirname,
                                                 const char *username,
                                                 apr_pool_t *p)
{
    return apr_uid_homepath_get(dirname, username, p);
}