s3/vfs_glusterfs_fuse: Dynamically determine NAME_MAX
[samba.git] / source3 / modules / vfs_glusterfs_fuse.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Copyright (c) 2019 Guenther Deschner <gd@samba.org>
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "includes.h"
21 #include "smbd/smbd.h"
22 #include "system/filesys.h"
23
24 static int vfs_gluster_fuse_get_real_filename(struct vfs_handle_struct *handle,
25                                               const char *path,
26                                               const char *name,
27                                               TALLOC_CTX *mem_ctx,
28                                               char **_found_name)
29 {
30         int ret;
31         char *key_buf = NULL, *val_buf = NULL;
32         long name_max;
33         char *found_name = NULL;
34
35         name_max = pathconf(path, _PC_NAME_MAX);
36         if ((name_max + 1) < 1) {
37                 errno = EINVAL;
38                 return -1;
39         }
40
41         if (strlen(name) >= name_max) {
42                 errno = ENAMETOOLONG;
43                 return -1;
44         }
45
46         key_buf = talloc_asprintf(mem_ctx, "glusterfs.get_real_filename:%s",
47                                   name);
48         if (key_buf == NULL) {
49                 errno = ENOMEM;
50                 return -1;
51         }
52
53         val_buf = talloc_zero_array(mem_ctx, char, name_max + 1);
54         if (val_buf == NULL) {
55                 errno = ENOMEM;
56                 return -1;
57         }
58
59         ret = getxattr(path, key_buf, val_buf, name_max + 1);
60         if (ret == -1) {
61                 if (errno == ENOATTR) {
62                         errno = EOPNOTSUPP;
63                 }
64                 return -1;
65         }
66
67         found_name = talloc_strdup(mem_ctx, val_buf);
68         if (found_name == NULL) {
69                 errno = ENOMEM;
70                 return -1;
71         }
72         *_found_name = found_name;
73
74         TALLOC_FREE(key_buf);
75         TALLOC_FREE(val_buf);
76
77         return 0;
78 }
79
80 struct vfs_fn_pointers glusterfs_fuse_fns = {
81
82         /* File Operations */
83         .get_real_filename_fn = vfs_gluster_fuse_get_real_filename,
84 };
85
86 static_decl_vfs;
87 NTSTATUS vfs_glusterfs_fuse_init(TALLOC_CTX *ctx)
88 {
89         return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
90                                 "glusterfs_fuse", &glusterfs_fuse_fns);
91 }