1 /*
2 * Copyright (c) 2016 Fujitsu Ltd.
3 * Author: Jinbao Huang <huangjb.jy@cn.fujitsu.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful, but
10 * WITHOUT ANY WARRANTY;  without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 *
13 * You should have received a copy of the GNU General Public License
14 * alone with this program.
15 */
16 
17 /*
18 * Test Name: lgetxattr01
19 *
20 * Description:
21 * The testcase checks the basic functionality of the lgetxattr(2).
22 * In the case of a symbolic link, we only get the value of the
23 * extended attribute related to the link itself by name.
24 *
25 */
26 
27 #include "config.h"
28 #include <errno.h>
29 #include <sys/types.h>
30 #include <string.h>
31 
32 #ifdef HAVE_SYS_XATTR_H
33 # include <sys/xattr.h>
34 #endif
35 
36 #include "tst_test.h"
37 
38 #ifdef HAVE_SYS_XATTR_H
39 
40 #define SECURITY_KEY1   "security.ltptest1"
41 #define SECURITY_KEY2   "security.ltptest2"
42 #define VALUE1   "test1"
43 #define VALUE2   "test2"
44 
45 static void set_xattr(char *path, char *key, void *value, size_t size)
46 {
47 	int res;
48 
49 	res = lsetxattr(path, key, value, size, XATTR_CREATE);
50 	if (res == -1) {
51 		if (errno == ENOTSUP) {
52 			tst_brk(TCONF,
53 				"no xattr support in fs or mounted "
54 				"without user_xattr option");
55 		} else {
56 			tst_brk(TBROK | TERRNO, "lsetxattr(%s) failed", key);
57 		}
58 	}
59 }
60 
61 static void setup(void)
62 {
63 	SAFE_TOUCH("testfile", 0644, NULL);
64 	SAFE_SYMLINK("testfile", "symlink");
65 
66 	set_xattr("testfile", SECURITY_KEY1, VALUE1, strlen(VALUE1));
67 	set_xattr("symlink", SECURITY_KEY2, VALUE2, strlen(VALUE2));
68 }
69 
70 static void verify_lgetxattr(void)
71 {
72 	int size = 64;
73 	char buf[size];
74 
75 	TEST(lgetxattr("symlink", SECURITY_KEY2, buf, size));
76 	if (TEST_RETURN == -1) {
77 		tst_res(TFAIL | TTERRNO, "lgetxattr() failed");
78 		goto next;
79 	}
80 
81 	if (TEST_RETURN != strlen(VALUE2)) {
82 		tst_res(TFAIL, "lgetxattr() got unexpected value size");
83 		goto next;
84 	}
85 
86 	if (!strncmp(buf, VALUE2, TEST_RETURN))
87 		tst_res(TPASS, "lgetxattr() got expected value");
88 	else
89 		tst_res(TFAIL, "lgetxattr() got unexpected value");
90 
91 next:
92 	TEST(lgetxattr("symlink", SECURITY_KEY1, buf, size));
93 
94 	if (TEST_RETURN != -1) {
95 		tst_res(TFAIL, "lgetxattr() succeeded unexpectedly");
96 		return;
97 	}
98 
99 	if (TEST_ERRNO == ENODATA) {
100 		tst_res(TPASS | TTERRNO, "lgetxattr() failed as expected");
101 	} else {
102 		tst_res(TFAIL | TTERRNO, "lgetxattr() failed unexpectedly,"
103 			"expected %s", tst_strerrno(ENODATA));
104 	}
105 }
106 
107 static struct tst_test test = {
108 	.needs_tmpdir = 1,
109 	.needs_root = 1,
110 	.test_all = verify_lgetxattr,
111 	.setup = setup
112 };
113 
114 #else
115 	TST_TEST_TCONF("<sys/xattr.h> does not exist.");
116 #endif /* HAVE_SYS_XATTR_H */
117