1/* 2 * 3 * Copyright (c) International Business Machines Corp., 2001 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/* 21 * DESCRIPTION 22 * Testcase to check open(2) sets errno to EACCES correctly. 23 * 24 * ALGORITHM 25 * Create a file owned by root with no read permission for other users. 26 * Attempt to open it as ltpuser(1). The attempt should fail with EACCES. 27 * RESTRICTION 28 * Must run test as root. 29 */ 30#include <errno.h> 31#include <pwd.h> 32#include <fcntl.h> 33#include <sys/stat.h> 34#include <sys/types.h> 35#include <sys/wait.h> 36 37#include "test.h" 38#include "safe_macros.h" 39 40char *TCID = "open05"; 41int TST_TOTAL = 1; 42 43static char fname[20]; 44static int fd; 45 46static uid_t nobody_uid; 47 48static void cleanup(void); 49static void setup(void); 50 51int main(int ac, char **av) 52{ 53 int lc; 54 int e_code, status, retval = 0; 55 pid_t pid; 56 57 tst_parse_opts(ac, av, NULL, NULL); 58 59 setup(); 60 61 for (lc = 0; TEST_LOOPING(lc); lc++) { 62 /* reset tst_count in case we are looping */ 63 tst_count = 0; 64 65 pid = FORK_OR_VFORK(); 66 if (pid == -1) 67 tst_brkm(TBROK, cleanup, "fork() failed"); 68 69 if (pid == 0) { 70 if (seteuid(nobody_uid) == -1) { 71 tst_resm(TWARN, "seteuid() failed, errno: %d", 72 errno); 73 } 74 75 TEST(open(fname, O_RDWR)); 76 77 if (TEST_RETURN != -1) { 78 tst_resm(TFAIL, "open succeeded unexpectedly"); 79 continue; 80 } 81 82 if (TEST_ERRNO != EACCES) { 83 retval = 1; 84 tst_resm(TFAIL, "Expected EACCES got %d", 85 TEST_ERRNO); 86 } else { 87 tst_resm(TPASS, "open returned expected " 88 "EACCES error"); 89 } 90 91 /* set the id back to root */ 92 if (seteuid(0) == -1) 93 tst_resm(TWARN, "seteuid(0) failed"); 94 95 exit(retval); 96 97 } else { 98 /* wait for the child to finish */ 99 wait(&status); 100 /* make sure the child returned a good exit status */ 101 e_code = status >> 8; 102 if ((e_code != 0) || (retval != 0)) 103 tst_resm(TFAIL, "Failures reported above"); 104 105 close(fd); 106 cleanup(); 107 108 } 109 } 110 111 tst_exit(); 112} 113 114static void setup(void) 115{ 116 struct passwd *pw; 117 118 tst_require_root(); 119 120 pw = SAFE_GETPWNAM(NULL, "nobody"); 121 nobody_uid = pw->pw_uid; 122 123 tst_sig(FORK, DEF_HANDLER, cleanup); 124 125 TEST_PAUSE; 126 127 /* make a temporary directory and cd to it */ 128 tst_tmpdir(); 129 130 sprintf(fname, "file.%d", getpid()); 131 132 fd = open(fname, O_RDWR | O_CREAT, 0700); 133 if (fd == -1) 134 tst_brkm(TBROK, cleanup, "open() failed, errno: %d", errno); 135} 136 137static void cleanup(void) 138{ 139 unlink(fname); 140 141 /* delete the test directory created in setup() */ 142 tst_rmdir(); 143} 144