1 /* 2 * Copyright (c) International Business Machines Corp., 2001 3 * 07/2001 Ported by Wayne Boyer 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 * the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 /* 20 * Test Description: 21 * Verify that, fchown(2) succeeds to change the owner and group of a file 22 * specified by file descriptor to any numeric owner(uid)/group(gid) values 23 * when invoked by super-user. 24 */ 25 26 #include <stdio.h> 27 #include <sys/types.h> 28 #include <sys/stat.h> 29 #include <fcntl.h> 30 #include <errno.h> 31 #include <string.h> 32 #include <signal.h> 33 34 #include "test.h" 35 #include "safe_macros.h" 36 #include "compat_16.h" 37 38 #define FILE_MODE S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH 39 #define TESTFILE "testfile" 40 41 TCID_DEFINE(fchown05); 42 43 static struct test_case_t { 44 char *desc; 45 uid_t user_id; 46 gid_t group_id; 47 } tc[] = { 48 {"Change Owner/Group ids", 700, 701}, 49 {"Change Owner id only", 702, -1}, 50 {"Change Owner id only", 703, 701}, 51 {"Change Group id only", -1, 704}, 52 {"Change Group id only", 703, 705}, 53 {NULL, 0, 0} 54 }; 55 56 int TST_TOTAL = ARRAY_SIZE(tc); 57 58 static void setup(void); 59 static void cleanup(void); 60 static int fildes; 61 62 int main(int ac, char **av) 63 { 64 struct stat stat_buf; 65 int i, lc; 66 uid_t user_id; 67 gid_t group_id; 68 69 tst_parse_opts(ac, av, NULL, NULL); 70 71 setup(); 72 73 for (lc = 0; TEST_LOOPING(lc); lc++) { 74 tst_count = 0; 75 76 for (i = 0; tc[i].desc != NULL; i++) { 77 user_id = tc[i].user_id; 78 group_id = tc[i].group_id; 79 80 TEST(FCHOWN(cleanup, fildes, user_id, group_id)); 81 82 if (TEST_RETURN == -1) { 83 tst_resm(TFAIL | TTERRNO, 84 "fchown() Fails to %s", tc[i].desc); 85 continue; 86 } 87 88 SAFE_FSTAT(cleanup, fildes, &stat_buf); 89 90 if (user_id == (uid_t)-1) 91 user_id = tc[i - 1].user_id; 92 93 if (group_id == (gid_t)-1) 94 group_id = tc[i - 1].group_id; 95 96 if ((stat_buf.st_uid != user_id) || 97 (stat_buf.st_gid != group_id)) { 98 tst_resm(TFAIL, "%s: Incorrect owner" 99 "ship set, Expected %d %d", 100 TESTFILE, user_id, group_id); 101 } else { 102 tst_resm(TPASS, 103 "fchown() succeeds to %s of %s", 104 tc[i].desc, TESTFILE); 105 } 106 } 107 } 108 109 cleanup(); 110 tst_exit(); 111 } 112 113 static void setup(void) 114 { 115 tst_sig(NOFORK, DEF_HANDLER, cleanup); 116 117 tst_require_root(); 118 119 TEST_PAUSE; 120 121 tst_tmpdir(); 122 123 fildes = SAFE_OPEN(cleanup, TESTFILE, O_RDWR | O_CREAT, FILE_MODE); 124 } 125 126 static void cleanup(void) 127 { 128 if (fildes > 0 && close(fildes)) 129 tst_resm(TWARN | TERRNO, "close(%s) Failed", TESTFILE); 130 131 tst_rmdir(); 132 } 133