Esempio n. 1
0
ATF_TC_BODY(is_root, tc)
{
    if (geteuid() == 0)
        ATF_REQUIRE(atf_user_is_root());
    else
        ATF_REQUIRE(!atf_user_is_root());
}
Esempio n. 2
0
/*
 * An implementation of access(2) but using the effective user value
 * instead of the real one.  Also avoids false positives for root when
 * asking for execute permissions, which appear in SunOS.
 */
atf_error_t
atf_fs_eaccess(const atf_fs_path_t *p, int mode)
{
    atf_error_t err;
    struct stat st;
    bool ok;

    PRE(mode & atf_fs_access_f || mode & atf_fs_access_r ||
        mode & atf_fs_access_w || mode & atf_fs_access_x);

    if (lstat(atf_fs_path_cstring(p), &st) == -1) {
        err = atf_libc_error(errno, "Cannot get information from file %s",
                             atf_fs_path_cstring(p));
        goto out;
    }

    err = atf_no_error();

    /* Early return if we are only checking for existence and the file
     * exists (stat call returned). */
    if (mode & atf_fs_access_f)
        goto out;

    ok = false;
    if (atf_user_is_root()) {
        if (!ok && !(mode & atf_fs_access_x)) {
            /* Allow root to read/write any file. */
            ok = true;
        }

        if (!ok && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
            /* Allow root to execute the file if any of its execution bits
             * are set. */
            ok = true;
        }
    } else {
        if (!ok && (atf_user_euid() == st.st_uid)) {
            ok = ((mode & atf_fs_access_r) && (st.st_mode & S_IRUSR)) ||
                 ((mode & atf_fs_access_w) && (st.st_mode & S_IWUSR)) ||
                 ((mode & atf_fs_access_x) && (st.st_mode & S_IXUSR));
        }
        if (!ok && atf_user_is_member_of_group(st.st_gid)) {
            ok = ((mode & atf_fs_access_r) && (st.st_mode & S_IRGRP)) ||
                 ((mode & atf_fs_access_w) && (st.st_mode & S_IWGRP)) ||
                 ((mode & atf_fs_access_x) && (st.st_mode & S_IXGRP));
        }
        if (!ok && ((atf_user_euid() != st.st_uid) &&
                    !atf_user_is_member_of_group(st.st_gid))) {
            ok = ((mode & atf_fs_access_r) && (st.st_mode & S_IROTH)) ||
                 ((mode & atf_fs_access_w) && (st.st_mode & S_IWOTH)) ||
                 ((mode & atf_fs_access_x) && (st.st_mode & S_IXOTH));
        }
    }

    if (!ok)
        err = atf_libc_error(EACCES, "Access check failed");

out:
    return err;
}
Esempio n. 3
0
ATF_TC_BODY(exists, tc)
{
    atf_error_t err;
    atf_fs_path_t pdir, pfile;
    bool b;

    RE(atf_fs_path_init_fmt(&pdir, "dir"));
    RE(atf_fs_path_init_fmt(&pfile, "dir/file"));

    create_dir(atf_fs_path_cstring(&pdir), 0755);
    create_file(atf_fs_path_cstring(&pfile), 0644);

    printf("Checking existence of a directory\n");
    RE(atf_fs_exists(&pdir, &b));
    ATF_REQUIRE(b);

    printf("Checking existence of a file\n");
    RE(atf_fs_exists(&pfile, &b));
    ATF_REQUIRE(b);

    /* XXX: This should probably be a separate test case to let the user
     * be aware that some tests were skipped because privileges were not
     * correct. */
    if (!atf_user_is_root()) {
        printf("Checking existence of a file inside a directory without "
               "permissions\n");
        ATF_REQUIRE(chmod(atf_fs_path_cstring(&pdir), 0000) != -1);
        err = atf_fs_exists(&pfile, &b);
        ATF_REQUIRE(atf_is_error(err));
        ATF_REQUIRE(atf_error_is(err, "libc"));
        ATF_REQUIRE(chmod(atf_fs_path_cstring(&pdir), 0755) != -1);
        atf_error_free(err);
    }

    printf("Checking existence of a non-existent file\n");
    ATF_REQUIRE(unlink(atf_fs_path_cstring(&pfile)) != -1);
    RE(atf_fs_exists(&pfile, &b));
    ATF_REQUIRE(!b);

    atf_fs_path_fini(&pfile);
    atf_fs_path_fini(&pdir);
}
Esempio n. 4
0
ATF_TC_BODY(rmdir_eperm, tc)
{
    atf_fs_path_t p;
    atf_error_t err;

    RE(atf_fs_path_init_fmt(&p, "test-dir/foo"));

    ATF_REQUIRE(mkdir("test-dir", 0755) != -1);
    ATF_REQUIRE(mkdir("test-dir/foo", 0755) != -1);
    ATF_REQUIRE(chmod("test-dir", 0555) != -1);
    ATF_REQUIRE(exists(&p));

    err = atf_fs_rmdir(&p);
    if (atf_user_is_root()) {
        ATF_REQUIRE(!atf_is_error(err));
    } else {
        ATF_REQUIRE(atf_is_error(err));
        ATF_REQUIRE(atf_error_is(err, "libc"));
        ATF_REQUIRE_EQ(atf_libc_error_code(err), EACCES);
        atf_error_free(err);
    }

    atf_fs_path_fini(&p);
}
Esempio n. 5
0
ATF_TC_BODY(eaccess, tc)
{
    const int modes[] = { atf_fs_access_f, atf_fs_access_r, atf_fs_access_w,
                          atf_fs_access_x, 0 };
    const int *m;
    struct tests {
        mode_t fmode;
        int amode;
        int uerror;
        int rerror;
    } tests[] = {
        { 0000, atf_fs_access_r, EACCES, 0 },
        { 0000, atf_fs_access_w, EACCES, 0 },
        { 0000, atf_fs_access_x, EACCES, EACCES },

        { 0001, atf_fs_access_r, EACCES, 0 },
        { 0001, atf_fs_access_w, EACCES, 0 },
        { 0001, atf_fs_access_x, EACCES, 0 },
        { 0002, atf_fs_access_r, EACCES, 0 },
        { 0002, atf_fs_access_w, EACCES, 0 },
        { 0002, atf_fs_access_x, EACCES, EACCES },
        { 0004, atf_fs_access_r, EACCES, 0 },
        { 0004, atf_fs_access_w, EACCES, 0 },
        { 0004, atf_fs_access_x, EACCES, EACCES },

        { 0010, atf_fs_access_r, EACCES, 0 },
        { 0010, atf_fs_access_w, EACCES, 0 },
        { 0010, atf_fs_access_x, 0,      0 },
        { 0020, atf_fs_access_r, EACCES, 0 },
        { 0020, atf_fs_access_w, 0,      0 },
        { 0020, atf_fs_access_x, EACCES, EACCES },
        { 0040, atf_fs_access_r, 0,      0 },
        { 0040, atf_fs_access_w, EACCES, 0 },
        { 0040, atf_fs_access_x, EACCES, EACCES },

        { 0100, atf_fs_access_r, EACCES, 0 },
        { 0100, atf_fs_access_w, EACCES, 0 },
        { 0100, atf_fs_access_x, 0,      0 },
        { 0200, atf_fs_access_r, EACCES, 0 },
        { 0200, atf_fs_access_w, 0,      0 },
        { 0200, atf_fs_access_x, EACCES, EACCES },
        { 0400, atf_fs_access_r, 0,      0 },
        { 0400, atf_fs_access_w, EACCES, 0 },
        { 0400, atf_fs_access_x, EACCES, EACCES },

        { 0, 0, 0, 0 }
    };
    struct tests *t;
    atf_fs_path_t p;
    atf_error_t err;

    RE(atf_fs_path_init_fmt(&p, "the-file"));

    printf("Non-existent file checks\n");
    for (m = &modes[0]; *m != 0; m++) {
        err = atf_fs_eaccess(&p, *m);
        ATF_REQUIRE(atf_is_error(err));
        ATF_REQUIRE(atf_error_is(err, "libc"));
        ATF_REQUIRE_EQ(atf_libc_error_code(err), ENOENT);
        atf_error_free(err);
    }

    create_file(atf_fs_path_cstring(&p), 0000);
    ATF_REQUIRE(chown(atf_fs_path_cstring(&p), geteuid(), getegid()) != -1);

    for (t = &tests[0]; t->amode != 0; t++) {
        const int experr = atf_user_is_root() ? t->rerror : t->uerror;

        printf("\n");
        printf("File mode     : %04o\n", (unsigned int)t->fmode);
        printf("Access mode   : 0x%02x\n", t->amode);

        ATF_REQUIRE(chmod(atf_fs_path_cstring(&p), t->fmode) != -1);

        /* First, existence check. */
        err = atf_fs_eaccess(&p, atf_fs_access_f);
        ATF_REQUIRE(!atf_is_error(err));

        /* Now do the specific test case. */
        printf("Expected error: %d\n", experr);
        err = atf_fs_eaccess(&p, t->amode);
        if (atf_is_error(err)) {
            if (atf_error_is(err, "libc"))
                printf("Error         : %d\n", atf_libc_error_code(err));
            else
                printf("Error         : Non-libc error\n");
        } else
                printf("Error         : None\n");
        if (experr == 0) {
            ATF_REQUIRE(!atf_is_error(err));
        } else {
            ATF_REQUIRE(atf_is_error(err));
            ATF_REQUIRE(atf_error_is(err, "libc"));
            ATF_REQUIRE_EQ(atf_libc_error_code(err), experr);
            atf_error_free(err);
        }
    }

    atf_fs_path_fini(&p);
}