1f08c3bdfSopenharmony_ci/* 2f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2001 3f08c3bdfSopenharmony_ci * 4f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or modify 5f08c3bdfSopenharmony_ci * it under the terms of the GNU General Public License as published by 6f08c3bdfSopenharmony_ci * the Free Software Foundation; either version 2 of the License, or 7f08c3bdfSopenharmony_ci * (at your option) any later version. 8f08c3bdfSopenharmony_ci * 9f08c3bdfSopenharmony_ci * This program is distributed in the hope that it will be useful, 10f08c3bdfSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 11f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 12f08c3bdfSopenharmony_ci * the GNU General Public License for more details. 13f08c3bdfSopenharmony_ci * 14f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License 15f08c3bdfSopenharmony_ci * along with this program; if not, write to the Free Software 16f08c3bdfSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17f08c3bdfSopenharmony_ci */ 18f08c3bdfSopenharmony_ci 19f08c3bdfSopenharmony_ci/* 20f08c3bdfSopenharmony_ci * Test Description: 21f08c3bdfSopenharmony_ci * Verify that, lchown(2) succeeds to change the owner and group of a file 22f08c3bdfSopenharmony_ci * specified by path to any numeric owner(uid)/group(gid) values when invoked 23f08c3bdfSopenharmony_ci * by super-user. 24f08c3bdfSopenharmony_ci * 25f08c3bdfSopenharmony_ci * Expected Result: 26f08c3bdfSopenharmony_ci * lchown(2) should return 0 and the ownership set on the file should match 27f08c3bdfSopenharmony_ci * the numeric values contained in owner and group respectively. 28f08c3bdfSopenharmony_ci * 29f08c3bdfSopenharmony_ci * HISTORY 30f08c3bdfSopenharmony_ci * 07/2001 Ported by Wayne Boyer 31f08c3bdfSopenharmony_ci * 11/2010 Code cleanup by Cyril Hrubis chrubis@suse.cz 32f08c3bdfSopenharmony_ci */ 33f08c3bdfSopenharmony_ci 34f08c3bdfSopenharmony_ci#include <stdio.h> 35f08c3bdfSopenharmony_ci#include <sys/types.h> 36f08c3bdfSopenharmony_ci#include <sys/stat.h> 37f08c3bdfSopenharmony_ci#include <fcntl.h> 38f08c3bdfSopenharmony_ci#include <errno.h> 39f08c3bdfSopenharmony_ci#include <string.h> 40f08c3bdfSopenharmony_ci#include <signal.h> 41f08c3bdfSopenharmony_ci 42f08c3bdfSopenharmony_ci#include "test.h" 43f08c3bdfSopenharmony_ci#include "safe_macros.h" 44f08c3bdfSopenharmony_ci#include "compat_16.h" 45f08c3bdfSopenharmony_ci 46f08c3bdfSopenharmony_ci#define FILE_MODE (S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) 47f08c3bdfSopenharmony_ci#define TESTFILE "testfile" 48f08c3bdfSopenharmony_ci#define SFILE "slink_file" 49f08c3bdfSopenharmony_ci 50f08c3bdfSopenharmony_ciTCID_DEFINE(lchown01); 51f08c3bdfSopenharmony_ciint TST_TOTAL = 5; 52f08c3bdfSopenharmony_ci 53f08c3bdfSopenharmony_cistruct test_case_t { 54f08c3bdfSopenharmony_ci char *desc; 55f08c3bdfSopenharmony_ci uid_t user_id; 56f08c3bdfSopenharmony_ci gid_t group_id; 57f08c3bdfSopenharmony_ci}; 58f08c3bdfSopenharmony_ci 59f08c3bdfSopenharmony_cistatic struct test_case_t test_cases[] = { 60f08c3bdfSopenharmony_ci {"Change Owner/Group ids", 700, 701}, 61f08c3bdfSopenharmony_ci {"Change Owner id only", 702, -1}, 62f08c3bdfSopenharmony_ci {"Change Owner/Group ids", 703, 701}, 63f08c3bdfSopenharmony_ci {"Change Group id only", -1, 704}, 64f08c3bdfSopenharmony_ci {"Change Group/Group ids", 703, 705}, 65f08c3bdfSopenharmony_ci {"Change none", -1, -1}, 66f08c3bdfSopenharmony_ci {NULL, 0, 0} 67f08c3bdfSopenharmony_ci}; 68f08c3bdfSopenharmony_ci 69f08c3bdfSopenharmony_cistatic void setup(void); 70f08c3bdfSopenharmony_cistatic void cleanup(void); 71f08c3bdfSopenharmony_ci 72f08c3bdfSopenharmony_ciint main(int argc, char *argv[]) 73f08c3bdfSopenharmony_ci{ 74f08c3bdfSopenharmony_ci struct stat stat_buf; 75f08c3bdfSopenharmony_ci int lc; 76f08c3bdfSopenharmony_ci int i; 77f08c3bdfSopenharmony_ci 78f08c3bdfSopenharmony_ci tst_parse_opts(argc, argv, NULL, NULL); 79f08c3bdfSopenharmony_ci 80f08c3bdfSopenharmony_ci setup(); 81f08c3bdfSopenharmony_ci 82f08c3bdfSopenharmony_ci for (lc = 0; TEST_LOOPING(lc); lc++) { 83f08c3bdfSopenharmony_ci 84f08c3bdfSopenharmony_ci tst_count = 0; 85f08c3bdfSopenharmony_ci 86f08c3bdfSopenharmony_ci for (i = 0; test_cases[i].desc != NULL; i++) { 87f08c3bdfSopenharmony_ci uid_t user_id = test_cases[i].user_id; 88f08c3bdfSopenharmony_ci gid_t group_id = test_cases[i].group_id; 89f08c3bdfSopenharmony_ci char *test_desc = test_cases[i].desc; 90f08c3bdfSopenharmony_ci 91f08c3bdfSopenharmony_ci /* 92f08c3bdfSopenharmony_ci * Call lchown(2) with different user id and 93f08c3bdfSopenharmony_ci * group id (numeric values) to set it on 94f08c3bdfSopenharmony_ci * symlink of testfile. 95f08c3bdfSopenharmony_ci */ 96f08c3bdfSopenharmony_ci TEST(LCHOWN(cleanup, SFILE, user_id, group_id)); 97f08c3bdfSopenharmony_ci 98f08c3bdfSopenharmony_ci if (TEST_RETURN == -1) { 99f08c3bdfSopenharmony_ci tst_resm(TFAIL, 100f08c3bdfSopenharmony_ci "lchown() Fails to %s, errno %d", 101f08c3bdfSopenharmony_ci test_desc, TEST_ERRNO); 102f08c3bdfSopenharmony_ci continue; 103f08c3bdfSopenharmony_ci } 104f08c3bdfSopenharmony_ci 105f08c3bdfSopenharmony_ci if (lstat(SFILE, &stat_buf) < 0) { 106f08c3bdfSopenharmony_ci tst_brkm(TFAIL, cleanup, "lstat(2) " 107f08c3bdfSopenharmony_ci "%s failed, errno %d", 108f08c3bdfSopenharmony_ci SFILE, TEST_ERRNO); 109f08c3bdfSopenharmony_ci } 110f08c3bdfSopenharmony_ci 111f08c3bdfSopenharmony_ci if ((int)user_id == -1) { 112f08c3bdfSopenharmony_ci if (i > 0) 113f08c3bdfSopenharmony_ci user_id = 114f08c3bdfSopenharmony_ci test_cases[i - 1].user_id; 115f08c3bdfSopenharmony_ci else 116f08c3bdfSopenharmony_ci user_id = geteuid(); 117f08c3bdfSopenharmony_ci } 118f08c3bdfSopenharmony_ci 119f08c3bdfSopenharmony_ci if ((int)group_id == -1) { 120f08c3bdfSopenharmony_ci if (i > 0) 121f08c3bdfSopenharmony_ci group_id = 122f08c3bdfSopenharmony_ci test_cases[i - 1].group_id; 123f08c3bdfSopenharmony_ci else 124f08c3bdfSopenharmony_ci group_id = getegid(); 125f08c3bdfSopenharmony_ci } 126f08c3bdfSopenharmony_ci 127f08c3bdfSopenharmony_ci /* 128f08c3bdfSopenharmony_ci * Check for expected Ownership ids 129f08c3bdfSopenharmony_ci * set on testfile. 130f08c3bdfSopenharmony_ci */ 131f08c3bdfSopenharmony_ci if ((stat_buf.st_uid != user_id) || 132f08c3bdfSopenharmony_ci (stat_buf.st_gid != group_id)) { 133f08c3bdfSopenharmony_ci tst_resm(TFAIL, 134f08c3bdfSopenharmony_ci "%s: incorrect ownership set, " 135f08c3bdfSopenharmony_ci "Expected %d %d", SFILE, 136f08c3bdfSopenharmony_ci user_id, group_id); 137f08c3bdfSopenharmony_ci } else { 138f08c3bdfSopenharmony_ci tst_resm(TPASS, "lchown() succeeds to " 139f08c3bdfSopenharmony_ci "%s of %s", test_desc, SFILE); 140f08c3bdfSopenharmony_ci } 141f08c3bdfSopenharmony_ci } 142f08c3bdfSopenharmony_ci } 143f08c3bdfSopenharmony_ci 144f08c3bdfSopenharmony_ci cleanup(); 145f08c3bdfSopenharmony_ci tst_exit(); 146f08c3bdfSopenharmony_ci} 147f08c3bdfSopenharmony_ci 148f08c3bdfSopenharmony_cistatic void setup(void) 149f08c3bdfSopenharmony_ci{ 150f08c3bdfSopenharmony_ci int fd; 151f08c3bdfSopenharmony_ci 152f08c3bdfSopenharmony_ci tst_sig(NOFORK, DEF_HANDLER, cleanup); 153f08c3bdfSopenharmony_ci 154f08c3bdfSopenharmony_ci tst_require_root(); 155f08c3bdfSopenharmony_ci 156f08c3bdfSopenharmony_ci TEST_PAUSE; 157f08c3bdfSopenharmony_ci tst_tmpdir(); 158f08c3bdfSopenharmony_ci 159f08c3bdfSopenharmony_ci if ((fd = open(TESTFILE, O_RDWR | O_CREAT, FILE_MODE)) == -1) { 160f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, "open failed"); 161f08c3bdfSopenharmony_ci } 162f08c3bdfSopenharmony_ci SAFE_CLOSE(cleanup, fd); 163f08c3bdfSopenharmony_ci 164f08c3bdfSopenharmony_ci SAFE_SYMLINK(cleanup, TESTFILE, SFILE); 165f08c3bdfSopenharmony_ci} 166f08c3bdfSopenharmony_ci 167f08c3bdfSopenharmony_cistatic void cleanup(void) 168f08c3bdfSopenharmony_ci{ 169f08c3bdfSopenharmony_ci tst_rmdir(); 170f08c3bdfSopenharmony_ci} 171