• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /*
4  *  Copyright (c) International Business Machines  Corp., 2002
5  */
6 
7 /* 12/03/2002	Port to LTP     robbiew@us.ibm.com */
8 /* 06/30/2001	Port to Linux	nsharoff@us.ibm.com */
9 
10 /*\
11  * [DOCUMENTATION]
12  * Verify that acct() returns proper errno on failure.
13  */
14 
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <pwd.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <sys/mount.h>
24 
25 #include "tst_test.h"
26 
27 #define DIR_MODE	(S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP| \
28 			 S_IXGRP|S_IROTH|S_IXOTH)
29 #define FILE_EISDIR		"."
30 #define FILE_EACCES		"/dev/null"
31 #define FILE_ENOENT		"/tmp/does/not/exist"
32 #define FILE_ENOTDIR		"./tmpfile/"
33 #define TEST_TMPFILE		"./tmpfile"
34 #define TEST_ELOOP		"test_file_eloop1"
35 #define TEST_ENAMETOOLONG	nametoolong
36 #define TEST_EROFS		"mntpoint/file"
37 
38 static char nametoolong[PATH_MAX+2];
39 static struct passwd *ltpuser;
40 
setup_euid(void)41 static void setup_euid(void)
42 {
43 	SAFE_SETEUID(ltpuser->pw_uid);
44 }
45 
cleanup_euid(void)46 static void cleanup_euid(void)
47 {
48 	SAFE_SETEUID(0);
49 }
50 
51 static struct test_case {
52 	char *filename;
53 	char *exp_errval;
54 	int exp_errno;
55 	void (*setupfunc) ();
56 	void (*cleanfunc) ();
57 } tcases[] = {
58 	{FILE_EISDIR, "EISDIR",  EISDIR,  NULL,   NULL},
59 	{FILE_EACCES, "EACCES",  EACCES,  NULL,   NULL},
60 	{FILE_ENOENT, "ENOENT",  ENOENT,  NULL,   NULL},
61 	{FILE_ENOTDIR, "ENOTDIR", ENOTDIR, NULL,   NULL},
62 	{TEST_TMPFILE, "EPERM",   EPERM,   setup_euid, cleanup_euid},
63 	{NULL,       "EPERM",   EPERM,   setup_euid, cleanup_euid},
64 	{TEST_ELOOP, "ELOOP",        ELOOP,        NULL, NULL},
65 	{TEST_ENAMETOOLONG, "ENAMETOOLONG", ENAMETOOLONG, NULL, NULL},
66 	{TEST_EROFS, "EROFS",        EROFS,        NULL, NULL},
67 };
68 
setup(void)69 static void setup(void)
70 {
71 	int fd;
72 
73 	TEST(acct(NULL));
74 	if (TST_RET == -1 && TST_ERR == ENOSYS)
75 		tst_brk(TCONF, "acct() system call isn't configured in kernel");
76 
77 	ltpuser = SAFE_GETPWNAM("nobody");
78 
79 	fd = SAFE_CREAT(TEST_TMPFILE, 0777);
80 	SAFE_CLOSE(fd);
81 
82 	TEST(acct(TEST_TMPFILE));
83 	if (TST_RET == -1)
84 		tst_brk(TBROK | TTERRNO, "acct failed unexpectedly");
85 
86 	/* turn off acct, so we are in a known state */
87 	TEST(acct(NULL));
88 	if (TST_RET == -1)
89 		tst_brk(TBROK | TTERRNO, "acct(NULL) failed");
90 
91 	/* ELOOP SETTING */
92 	SAFE_SYMLINK(TEST_ELOOP, "test_file_eloop2");
93 	SAFE_SYMLINK("test_file_eloop2", TEST_ELOOP);
94 
95 	/* ENAMETOOLONG SETTING */
96 	memset(nametoolong, 'a', PATH_MAX+1);
97 }
98 
verify_acct(unsigned int nr)99 static void verify_acct(unsigned int nr)
100 {
101 	struct test_case *tcase = &tcases[nr];
102 
103 	if (tcase->setupfunc)
104 		tcase->setupfunc();
105 
106 	TEST(acct(tcase->filename));
107 
108 	if (tcase->cleanfunc)
109 		tcase->cleanfunc();
110 
111 	if (TST_RET != -1) {
112 		tst_res(TFAIL, "acct(%s) succeeded unexpectedly",
113 				tcase->filename);
114 		return;
115 	}
116 
117 	if (TST_ERR == tcase->exp_errno) {
118 		tst_res(TPASS | TTERRNO, "acct() failed as expected");
119 	} else {
120 		tst_res(TFAIL | TTERRNO,
121 				"acct() failed, expected: %s",
122 				tst_strerrno(tcase->exp_errno));
123 	}
124 }
125 
126 static struct tst_test test = {
127 	.needs_root = 1,
128 	.mntpoint = "mntpoint",
129 	.needs_rofs = 1,
130 	.tcnt = ARRAY_SIZE(tcases),
131 	.setup = setup,
132 	.test = verify_acct,
133 };
134