• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src/router/samba-3.5.8/source4/ntvfs/posix/
1/*
2   Unix SMB/CIFS implementation.
3
4   POSIX NTVFS backend - xattr support using filesystem xattrs
5
6   Copyright (C) Andrew Tridgell 2004
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 3 of the License, or
11   (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program.  If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "includes.h"
23#include "vfs_posix.h"
24#include "../lib/util/wrap_xattr.h"
25
26/*
27  pull a xattr as a blob, from either a file or a file descriptor
28*/
29NTSTATUS pull_xattr_blob_system(struct pvfs_state *pvfs,
30				TALLOC_CTX *mem_ctx,
31				const char *attr_name,
32				const char *fname,
33				int fd,
34				size_t estimated_size,
35				DATA_BLOB *blob)
36{
37	int ret;
38
39	*blob = data_blob_talloc(mem_ctx, NULL, estimated_size+16);
40	if (blob->data == NULL) {
41		return NT_STATUS_NO_MEMORY;
42	}
43
44again:
45	if (fd != -1) {
46		ret = wrap_fgetxattr(fd, attr_name, blob->data, estimated_size);
47	} else {
48		ret = wrap_getxattr(fname, attr_name, blob->data, estimated_size);
49	}
50	if (ret == -1 && errno == ERANGE) {
51		estimated_size *= 2;
52		blob->data = talloc_realloc(mem_ctx, blob->data,
53					    uint8_t, estimated_size);
54		if (blob->data == NULL) {
55			return NT_STATUS_NO_MEMORY;
56		}
57		blob->length = estimated_size;
58		goto again;
59	}
60	if (ret == -1 && errno == EPERM) {
61		struct stat statbuf;
62
63		if (fd != -1) {
64			ret = fstat(fd, &statbuf);
65		} else {
66			ret = stat(fname, &statbuf);
67		}
68		if (ret == 0) {
69			/* check if this is a directory and the sticky bit is set */
70			if (S_ISDIR(statbuf.st_mode) && (statbuf.st_mode & S_ISVTX)) {
71				/* pretend we could not find the xattr */
72
73				data_blob_free(blob);
74				return NT_STATUS_NOT_FOUND;
75
76			} else {
77				/* if not this was probably a legitimate error
78				 * reset ret and errno to the correct values */
79				errno = EPERM;
80				ret = -1;
81			}
82		}
83	}
84
85	if (ret == -1) {
86		data_blob_free(blob);
87		return pvfs_map_errno(pvfs, errno);
88	}
89
90	blob->length = ret;
91
92	return NT_STATUS_OK;
93}
94
95/*
96  push a xattr as a blob, from either a file or a file descriptor
97*/
98NTSTATUS push_xattr_blob_system(struct pvfs_state *pvfs,
99				const char *attr_name,
100				const char *fname,
101				int fd,
102				const DATA_BLOB *blob)
103{
104	int ret;
105
106	if (fd != -1) {
107		ret = wrap_fsetxattr(fd, attr_name, blob->data, blob->length, 0);
108	} else {
109		ret = wrap_setxattr(fname, attr_name, blob->data, blob->length, 0);
110	}
111	if (ret == -1) {
112		return pvfs_map_errno(pvfs, errno);
113	}
114
115	return NT_STATUS_OK;
116}
117
118
119/*
120  delete a xattr
121*/
122NTSTATUS delete_xattr_system(struct pvfs_state *pvfs, const char *attr_name,
123			     const char *fname, int fd)
124{
125	int ret;
126
127	if (fd != -1) {
128		ret = wrap_fremovexattr(fd, attr_name);
129	} else {
130		ret = wrap_removexattr(fname, attr_name);
131	}
132	if (ret == -1) {
133		return pvfs_map_errno(pvfs, errno);
134	}
135
136	return NT_STATUS_OK;
137}
138
139/*
140  unlink a file - cleanup any xattrs
141*/
142NTSTATUS unlink_xattr_system(struct pvfs_state *pvfs, const char *fname)
143{
144	/* nothing needs to be done for filesystem based xattrs */
145	return NT_STATUS_OK;
146}
147