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
45static 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
61static 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
70static 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
91next:
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
107static 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