1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) Linux Test Project, 2002-2022 4f08c3bdfSopenharmony_ci * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. 5f08c3bdfSopenharmony_ci */ 6f08c3bdfSopenharmony_ci 7f08c3bdfSopenharmony_ci/*\ 8f08c3bdfSopenharmony_ci * [Description] 9f08c3bdfSopenharmony_ci * 10f08c3bdfSopenharmony_ci * Verify that unlink(2) fails with 11f08c3bdfSopenharmony_ci * 12f08c3bdfSopenharmony_ci * - EACCES when no write access to the directory containing pathname 13f08c3bdfSopenharmony_ci * - EACCES when one of the directories in pathname did not allow search 14f08c3bdfSopenharmony_ci * - EISDIR when deleting directory as root user 15f08c3bdfSopenharmony_ci * - EISDIR when deleting directory as non-root user 16f08c3bdfSopenharmony_ci */ 17f08c3bdfSopenharmony_ci 18f08c3bdfSopenharmony_ci#include <errno.h> 19f08c3bdfSopenharmony_ci#include <pwd.h> 20f08c3bdfSopenharmony_ci#include <stdlib.h> 21f08c3bdfSopenharmony_ci#include <unistd.h> 22f08c3bdfSopenharmony_ci#include "tst_test.h" 23f08c3bdfSopenharmony_ci 24f08c3bdfSopenharmony_cistatic struct passwd *pw; 25f08c3bdfSopenharmony_ci 26f08c3bdfSopenharmony_cistatic struct test_case_t { 27f08c3bdfSopenharmony_ci char *name; 28f08c3bdfSopenharmony_ci char *desc; 29f08c3bdfSopenharmony_ci int exp_errno; 30f08c3bdfSopenharmony_ci int exp_user; 31f08c3bdfSopenharmony_ci} tcases[] = { 32f08c3bdfSopenharmony_ci {"unwrite_dir/file", "unwritable directory", EACCES, 1}, 33f08c3bdfSopenharmony_ci {"unsearch_dir/file", "unsearchable directory", EACCES, 1}, 34f08c3bdfSopenharmony_ci {"regdir", "directory", EISDIR, 0}, 35f08c3bdfSopenharmony_ci {"regdir", "directory", EISDIR, 1}, 36f08c3bdfSopenharmony_ci}; 37f08c3bdfSopenharmony_ci 38f08c3bdfSopenharmony_cistatic void verify_unlink(struct test_case_t *tc) 39f08c3bdfSopenharmony_ci{ 40f08c3bdfSopenharmony_ci TST_EXP_FAIL(unlink(tc->name), tc->exp_errno, "%s", tc->desc); 41f08c3bdfSopenharmony_ci} 42f08c3bdfSopenharmony_ci 43f08c3bdfSopenharmony_cistatic void do_unlink(unsigned int n) 44f08c3bdfSopenharmony_ci{ 45f08c3bdfSopenharmony_ci struct test_case_t *cases = &tcases[n]; 46f08c3bdfSopenharmony_ci pid_t pid; 47f08c3bdfSopenharmony_ci 48f08c3bdfSopenharmony_ci if (cases->exp_user) { 49f08c3bdfSopenharmony_ci pid = SAFE_FORK(); 50f08c3bdfSopenharmony_ci if (!pid) { 51f08c3bdfSopenharmony_ci SAFE_SETUID(pw->pw_uid); 52f08c3bdfSopenharmony_ci verify_unlink(cases); 53f08c3bdfSopenharmony_ci exit(0); 54f08c3bdfSopenharmony_ci } 55f08c3bdfSopenharmony_ci SAFE_WAITPID(pid, NULL, 0); 56f08c3bdfSopenharmony_ci } else { 57f08c3bdfSopenharmony_ci verify_unlink(cases); 58f08c3bdfSopenharmony_ci } 59f08c3bdfSopenharmony_ci} 60f08c3bdfSopenharmony_ci 61f08c3bdfSopenharmony_cistatic void setup(void) 62f08c3bdfSopenharmony_ci{ 63f08c3bdfSopenharmony_ci SAFE_MKDIR("unwrite_dir", 0777); 64f08c3bdfSopenharmony_ci SAFE_TOUCH("unwrite_dir/file", 0777, NULL); 65f08c3bdfSopenharmony_ci SAFE_CHMOD("unwrite_dir", 0555); 66f08c3bdfSopenharmony_ci 67f08c3bdfSopenharmony_ci SAFE_MKDIR("unsearch_dir", 0777); 68f08c3bdfSopenharmony_ci SAFE_TOUCH("unsearch_dir/file", 0777, NULL); 69f08c3bdfSopenharmony_ci SAFE_CHMOD("unsearch_dir", 0666); 70f08c3bdfSopenharmony_ci 71f08c3bdfSopenharmony_ci SAFE_MKDIR("regdir", 0777); 72f08c3bdfSopenharmony_ci 73f08c3bdfSopenharmony_ci pw = SAFE_GETPWNAM("nobody"); 74f08c3bdfSopenharmony_ci} 75f08c3bdfSopenharmony_ci 76f08c3bdfSopenharmony_cistatic struct tst_test test = { 77f08c3bdfSopenharmony_ci .needs_root = 1, 78f08c3bdfSopenharmony_ci .forks_child = 1, 79f08c3bdfSopenharmony_ci .needs_tmpdir = 1, 80f08c3bdfSopenharmony_ci .setup = setup, 81f08c3bdfSopenharmony_ci .tcnt = ARRAY_SIZE(tcases), 82f08c3bdfSopenharmony_ci .test = do_unlink, 83f08c3bdfSopenharmony_ci}; 84