Changes in samba vxfs plugin.
[samba.git] / source3 / modules / lib_vxfs.c
1 /*
2  Unix SMB/CIFS implementation.
3  Wrap VxFS xattr calls.
4
5  Copyright (C) Veritas Technologies LLC <www.veritas.com> 2016
6
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  GNU General Public License for more details.
16
17  You should have received a copy of the GNU General Public License
18  along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "smbd/smbd.h"
23 #include "system/filesys.h"
24 #include "string.h"
25 #include "vfs_vxfs.h"
26
27 /*
28  * Available under GPL at
29  * http://www.veritas.com/community/downloads/vxfsmisc-library
30  */
31 #define LIBVXFS "/usr/lib64/vxfsmisc.so"
32
33
34 static int (*vxfs_setxattr_fd_func) (int fd, const char *name,
35                                      const void *value, size_t len, int flags);
36 static int (*vxfs_getxattr_fd_func) (int fd, const char *name, void *value,
37                                      size_t *len);
38 static int (*vxfs_removexattr_fd_func) (int fd, const char *name);
39 static int (*vxfs_listxattr_fd_func) (int fd, void *value, size_t *len);
40 static int (*vxfs_setwxattr_fd_func) (int fd);
41 static int (*vxfs_clearwxattr_fd_func) (int fd);
42 static int (*vxfs_checkwxattr_fd_func) (int fd);
43
44 int vxfs_setxattr_fd(int fd, const char *name, const void *value,
45                      size_t len, int flags)
46 {
47         int ret = -1;
48
49         if (vxfs_setxattr_fd_func == NULL) {
50                 errno = ENOSYS;
51                 return ret;
52         }
53
54         DEBUG(10, ("Calling vxfs_setxattr_fd\n"));
55         ret = vxfs_setxattr_fd_func(fd, name, value, len, flags);
56         if (ret) {
57                 errno = ret;
58                 ret = -1;
59         }
60
61         return ret;
62 }
63
64 int vxfs_setxattr_path(const char *path, const char *name, const void *value,
65                        size_t len, int flags, bool is_dir)
66 {
67         int ret, fd = -1;
68
69         if (is_dir) {
70                 fd = open(path, O_RDONLY|O_DIRECTORY);
71         } else {
72                 fd = open(path, O_WRONLY);
73         }
74
75         if (fd == -1) {
76                 DEBUG(10, ("error in vxfs_setxattr_path: %s\n",
77                       strerror(errno)));
78                 return -1;
79         }
80
81         ret = vxfs_setxattr_fd(fd, name, value, len, flags);
82
83         close(fd);
84
85         return ret;
86 }
87
88 int vxfs_getxattr_fd(int fd, const char *name, void *value, size_t len)
89 {
90         int ret;
91         size_t size = len;
92
93         if (vxfs_getxattr_fd_func == NULL) {
94                 errno = ENOSYS;
95                 return -1;
96         }
97
98         DEBUG(10, ("Calling vxfs_getxattr_fd with %s\n", name));
99         ret = vxfs_getxattr_fd_func(fd, name, value, &size);
100         if (ret) {
101                 errno = ret;
102                 if (ret == EFBIG) {
103                         errno = ERANGE;
104                 }
105                 return -1;
106         }
107
108         return size;
109 }
110
111 int vxfs_getxattr_path(const char *path, const char *name, void *value,
112                        size_t len)
113 {
114         int ret, fd = -1;
115
116         fd = open(path, O_RDONLY);
117         if (fd == -1) {
118                 DEBUG(10, ("file not opened: vxfs_getxattr_path for %s\n",
119                            path));
120                 return -1;
121         }
122
123         ret = vxfs_getxattr_fd(fd, name, value, len);
124         close(fd);
125
126         return ret;
127 }
128
129 int vxfs_removexattr_fd(int fd, const char *name)
130 {
131         int ret = 0;
132
133         if (vxfs_removexattr_fd_func == NULL) {
134                 errno = ENOSYS;
135                 return -1;
136         }
137
138         DEBUG(10, ("Calling vxfs_removexattr_fd with %s\n", name));
139         ret = vxfs_removexattr_fd_func(fd, name);
140         if (ret) {
141                 errno = ret;
142                 ret = -1;
143         }
144
145         return ret;
146 }
147
148 int vxfs_removexattr_path(const char *path, const char *name, bool is_dir)
149 {
150         int ret, fd = -1;
151
152         if (is_dir) {
153                 fd = open(path, O_RDONLY|O_DIRECTORY);
154         } else {
155                 fd = open(path, O_WRONLY);
156         }
157         if (fd == -1) {
158                 DEBUG(10, ("file not opened: vxfs_removexattr_path for %s\n",
159                            path));
160                 return -1;
161         }
162
163         ret = vxfs_removexattr_fd(fd, name);
164         close(fd);
165
166         return ret;
167 }
168
169 int vxfs_listxattr_fd(int fd, char *list, size_t size)
170 {
171         int ret;
172         size_t len = size;
173
174         if (vxfs_listxattr_fd_func == NULL) {
175                 errno = ENOSYS;
176                 return -1;
177         }
178
179         ret = vxfs_listxattr_fd_func(fd, list, &len);
180         DEBUG(10, ("vxfs_listxattr_fd: returned ret = %d\n", ret));
181         if (ret) {
182                 errno = ret;
183                 if (ret == EFBIG) {
184                         errno = ERANGE;
185                 }
186                 return -1;
187         }
188
189         return len;
190 }
191
192 int vxfs_listxattr_path(const char *path, char *list, size_t size)
193 {
194         int ret, fd = -1;
195
196         fd = open(path, O_RDONLY);
197         if (fd == -1) {
198                 DEBUG(10, ("file not opened: vxfs_listxattr_path for %s\n",
199                            path));
200                 return -1;
201         }
202
203         ret = vxfs_listxattr_fd(fd, list, size);
204         close(fd);
205
206         return ret;
207 }
208
209 int vxfs_setwxattr_fd(int fd)
210 {
211         int ret = 0;
212
213         if (vxfs_setwxattr_fd_func == NULL) {
214                 errno = ENOSYS;
215                 return -1;
216         }
217         ret = vxfs_setwxattr_fd_func(fd);
218         DBG_DEBUG("ret = %d\n", ret);
219         if (ret != 0) {
220                 errno = ret;
221                 ret = -1;
222         }
223
224         return ret;
225 }
226
227 int vxfs_setwxattr_path(const char *path)
228 {
229         int ret, fd = -1;
230
231         fd = open(path, O_WRONLY);
232         if (fd == -1) {
233                 DBG_DEBUG("file %s not opened, errno:%s\n",
234                            path, strerror(errno));
235                 return -1;
236         }
237
238         ret = vxfs_setwxattr_fd(fd);
239         DBG_DEBUG("ret = %d\n", ret);
240         close(fd);
241
242         return ret;
243 }
244
245 int vxfs_clearwxattr_fd(int fd)
246 {
247         int ret;
248         if (vxfs_clearwxattr_fd_func == NULL) {
249                 errno = ENOSYS;
250                 return -1;
251         }
252         ret = vxfs_clearwxattr_fd_func(fd);
253         DBG_DEBUG("ret = %d\n", ret);
254         if (ret != 0) {
255                 errno = ret;
256                 ret = -1;
257         }
258
259         return ret;
260 }
261
262 int vxfs_clearwxattr_path(const char *path)
263 {
264         int ret, fd = -1;
265
266         fd = open(path, O_WRONLY);
267         if (fd == -1) {
268                 DBG_DEBUG("file %s not opened, errno:%s\n",
269                            path, strerror(errno));
270                 return -1;
271         }
272         ret = vxfs_clearwxattr_fd(fd);
273         DBG_DEBUG("ret = %d\n", ret);
274         close(fd);
275
276         return ret;
277 }
278
279 int vxfs_checkwxattr_fd(int fd)
280 {
281         int ret;
282
283         if (vxfs_checkwxattr_fd_func == NULL) {
284                 errno = ENOSYS;
285                 return -1;
286         }
287         ret = vxfs_checkwxattr_fd_func(fd);
288         DBG_DEBUG("ret = %d\n", ret);
289         if (ret != 0) {
290                 errno = ret;
291                 ret = -1;
292         }
293         return ret;
294 }
295
296 int vxfs_checkwxattr_path(const char *path)
297 {
298         int ret, fd = -1;
299
300         fd = open(path, O_WRONLY);
301         if (fd == -1) {
302                 DBG_DEBUG("file %s not opened, errno:%s\n",
303                            path, strerror(errno));
304                 return -1;
305         }
306         ret = vxfs_checkwxattr_fd(fd);
307         close(fd);
308
309         return ret;
310 }
311
312 static bool load_lib_vxfs_function(void *lib_handle, void *fn_ptr,
313                                    const char *fnc_name)
314 {
315         void **vlib_handle = (void **)lib_handle;
316         void **fn_pointer = (void **)fn_ptr;
317
318         *fn_pointer = dlsym(*vlib_handle, fnc_name);
319         if (*fn_pointer == NULL) {
320                 DEBUG(10, ("Cannot find symbol for %s\n", fnc_name));
321                 return true;
322         }
323
324         return false;
325 }
326
327 void vxfs_init()
328 {
329         static void *lib_handle = NULL;
330
331         if (lib_handle != NULL ) {
332                 return;
333         }
334
335         lib_handle = dlopen(LIBVXFS, RTLD_LAZY);
336         if (lib_handle == NULL) {
337                 DEBUG(10, ("Cannot get lib handle\n"));
338                 return;
339         }
340
341         DEBUG(10, ("Calling vxfs_init\n"));
342         load_lib_vxfs_function(&lib_handle, &vxfs_setxattr_fd_func,
343                                "vxfs_nxattr_set");
344         load_lib_vxfs_function(&lib_handle, &vxfs_getxattr_fd_func,
345                                "vxfs_nxattr_get");
346         load_lib_vxfs_function(&lib_handle, &vxfs_removexattr_fd_func,
347                                "vxfs_nxattr_remove");
348         load_lib_vxfs_function(&lib_handle, &vxfs_listxattr_fd_func,
349                                "vxfs_nxattr_list");
350         load_lib_vxfs_function(&lib_handle, &vxfs_setwxattr_fd_func,
351                                "vxfs_wattr_set");
352         load_lib_vxfs_function(&lib_handle, &vxfs_clearwxattr_fd_func,
353                                "vxfs_wattr_clear");
354         load_lib_vxfs_function(&lib_handle, &vxfs_checkwxattr_fd_func,
355                                "vxfs_wattr_check");
356
357 }