Line data Source code
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 :
25 : /*
26 : pull a xattr as a blob, from either a file or a file descriptor
27 : */
28 0 : NTSTATUS pull_xattr_blob_system(struct pvfs_state *pvfs,
29 : TALLOC_CTX *mem_ctx,
30 : const char *attr_name,
31 : const char *fname,
32 : int fd,
33 : size_t estimated_size,
34 : DATA_BLOB *blob)
35 : {
36 0 : int ret;
37 :
38 0 : *blob = data_blob_talloc(mem_ctx, NULL, estimated_size+16);
39 0 : if (blob->data == NULL) {
40 0 : return NT_STATUS_NO_MEMORY;
41 : }
42 :
43 0 : again:
44 0 : if (fd != -1) {
45 0 : ret = fgetxattr(fd, attr_name, blob->data, estimated_size);
46 : } else {
47 0 : ret = getxattr(fname, attr_name, blob->data, estimated_size);
48 : }
49 0 : if (ret == -1 && errno == ERANGE) {
50 0 : estimated_size *= 2;
51 0 : blob->data = talloc_realloc(mem_ctx, blob->data,
52 : uint8_t, estimated_size);
53 0 : if (blob->data == NULL) {
54 0 : return NT_STATUS_NO_MEMORY;
55 : }
56 0 : blob->length = estimated_size;
57 0 : goto again;
58 : }
59 0 : if (ret == -1 && errno == EPERM) {
60 0 : struct stat statbuf;
61 :
62 0 : if (fd != -1) {
63 0 : ret = fstat(fd, &statbuf);
64 : } else {
65 0 : ret = stat(fname, &statbuf);
66 : }
67 0 : if (ret == 0) {
68 : /* check if this is a directory and the sticky bit is set */
69 0 : if (S_ISDIR(statbuf.st_mode) && (statbuf.st_mode & S_ISVTX)) {
70 : /* pretend we could not find the xattr */
71 :
72 0 : data_blob_free(blob);
73 0 : return NT_STATUS_NOT_FOUND;
74 :
75 : } else {
76 : /* if not this was probably a legitimate error
77 : * reset ret and errno to the correct values */
78 0 : errno = EPERM;
79 0 : ret = -1;
80 : }
81 : }
82 : }
83 :
84 0 : if (ret == -1) {
85 0 : data_blob_free(blob);
86 0 : return pvfs_map_errno(pvfs, errno);
87 : }
88 :
89 0 : blob->length = ret;
90 :
91 0 : return NT_STATUS_OK;
92 : }
93 :
94 : /*
95 : push a xattr as a blob, from either a file or a file descriptor
96 : */
97 0 : NTSTATUS push_xattr_blob_system(struct pvfs_state *pvfs,
98 : const char *attr_name,
99 : const char *fname,
100 : int fd,
101 : const DATA_BLOB *blob)
102 : {
103 0 : int ret;
104 :
105 0 : if (fd != -1) {
106 0 : ret = fsetxattr(fd, attr_name, blob->data, blob->length, 0);
107 : } else {
108 0 : ret = setxattr(fname, attr_name, blob->data, blob->length, 0);
109 : }
110 0 : if (ret == -1) {
111 0 : return pvfs_map_errno(pvfs, errno);
112 : }
113 :
114 0 : return NT_STATUS_OK;
115 : }
116 :
117 :
118 : /*
119 : delete a xattr
120 : */
121 0 : NTSTATUS delete_xattr_system(struct pvfs_state *pvfs, const char *attr_name,
122 : const char *fname, int fd)
123 : {
124 0 : int ret;
125 :
126 0 : if (fd != -1) {
127 0 : ret = fremovexattr(fd, attr_name);
128 : } else {
129 0 : ret = removexattr(fname, attr_name);
130 : }
131 0 : if (ret == -1) {
132 0 : return pvfs_map_errno(pvfs, errno);
133 : }
134 :
135 0 : return NT_STATUS_OK;
136 : }
137 :
138 : /*
139 : unlink a file - cleanup any xattrs
140 : */
141 0 : NTSTATUS unlink_xattr_system(struct pvfs_state *pvfs, const char *fname)
142 : {
143 : /* nothing needs to be done for filesystem based xattrs */
144 0 : return NT_STATUS_OK;
145 : }
|