4 * Implement a fixed mapping of forbidden NT characters in filenames that are
5 * used a lot by the CAD package Catia.
7 * Yes, this a BAD BAD UGLY INCOMPLETE hack, but it helps quite some people
8 * out there. Catia V4 on AIX uses characters like "<*$ a *lot*, all forbidden
11 * Copyright (C) Volker Lendecke, 2005
12 * Copyright (C) Aravind Srinivasan, 2009
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see <http://www.gnu.org/licenses/>.
34 #define GLOBAL_SNUM 0xFFFFFFF
36 #define MAP_NUM 0x101 /* max unicode charval / MAP_SIZE */
37 #define T_OFFSET(_v_) ((_v_ % MAP_SIZE))
38 #define T_START(_v_) (((_v_ / MAP_SIZE) * MAP_SIZE))
39 #define T_PICK(_v_) ((_v_ / MAP_SIZE))
41 struct char_mappings {
42 smb_ucs2_t entry[MAP_SIZE][2];
45 struct share_mapping_entry {
47 struct share_mapping_entry *next;
48 struct char_mappings **mappings;
51 struct share_mapping_entry *srt_head = NULL;
53 static bool build_table(struct char_mappings **cmaps, int value)
56 int start = T_START(value);
58 (*cmaps) = (struct char_mappings *)
59 TALLOC_ZERO(NULL, sizeof(struct char_mappings));
64 for (i = 0; i < MAP_SIZE;i++) {
65 (*cmaps)->entry[i][TO_UNIX] = start + i;
66 (*cmaps)->entry[i][TO_WINDOWS] = start + i;
72 static void set_tables(struct char_mappings **cmaps,
78 /* set unix -> windows */
79 i = T_OFFSET(unix_map);
80 cmaps[T_PICK(unix_map)]->entry[i][TO_WINDOWS] = windows_map;
82 /* set windows -> unix */
83 i = T_OFFSET(windows_map);
84 cmaps[T_PICK(windows_map)]->entry[i][TO_UNIX] = unix_map;
87 static bool build_ranges(struct char_mappings **cmaps,
92 if (!cmaps[T_PICK(unix_map)]) {
93 if (!build_table(&cmaps[T_PICK(unix_map)], unix_map))
97 if (!cmaps[T_PICK(windows_map)]) {
98 if (!build_table(&cmaps[T_PICK(windows_map)], windows_map))
102 set_tables(cmaps, unix_map, windows_map);
107 struct share_mapping_entry *get_srt(connection_struct *conn,
108 struct share_mapping_entry **global)
110 struct share_mapping_entry *share;
112 for (share = srt_head; share != NULL; share = share->next) {
113 if (share->snum == GLOBAL_SNUM)
116 if (share->snum == SNUM(conn))
123 struct share_mapping_entry *add_srt(int snum, const char **mappings)
129 long unix_map, windows_map;
130 struct share_mapping_entry *ret = NULL;
132 ret = (struct share_mapping_entry *)
133 TALLOC_ZERO(NULL, sizeof(struct share_mapping_entry) +
134 (mappings ? (MAP_NUM * sizeof(struct char_mappings *)) : 0));
142 ret->mappings = (struct char_mappings**) ((unsigned char*) ret +
143 sizeof(struct share_mapping_entry));
144 memset(ret->mappings, 0,
145 MAP_NUM * sizeof(struct char_mappings *));
147 ret->mappings = NULL;
152 * catia mappings are of the form :
153 * UNIX char (in 0xnn hex) : WINDOWS char (in 0xnn hex)
155 * multiple mappings are comma seperated in smb.conf
157 for (i=0;mappings[i];i++) {
158 fstrcpy(mapping, mappings[i]);
159 unix_map = strtol(mapping, &tmp, 16);
160 if (unix_map == 0 && errno == EINVAL) {
161 DEBUG(0, ("INVALID CATIA MAPPINGS - %s\n", mapping));
164 windows_map = strtol(++tmp, NULL, 16);
165 if (windows_map == 0 && errno == EINVAL) {
166 DEBUG(0, ("INVALID CATIA MAPPINGS - %s\n", mapping));
170 if (!build_ranges(ret->mappings, unix_map, windows_map)) {
171 DEBUG(0, ("TABLE ERROR - CATIA MAPPINGS - %s\n", mapping));
176 ret->next = srt_head;
182 static bool init_mappings(connection_struct *conn,
183 struct share_mapping_entry **selected_out)
185 const char **mappings = NULL;
186 struct share_mapping_entry *share_level = NULL;
187 struct share_mapping_entry *global = NULL;
189 /* check srt cache */
190 share_level = get_srt(conn, &global);
192 *selected_out = share_level;
193 return (share_level->mappings != NULL);
196 /* see if we have a global setting */
199 mappings = lp_parm_string_list(-1, "catia", "mappings", NULL);
200 global = add_srt(GLOBAL_SNUM, mappings);
203 /* no global setting - what about share level ? */
204 mappings = lp_parm_string_list(SNUM(conn), "catia", "mappings", NULL);
205 share_level = add_srt(SNUM(conn), mappings);
207 if (share_level->mappings) {
208 (*selected_out) = share_level;
210 } else if (global->mappings) {
211 share_level->mappings = global->mappings;
212 (*selected_out) = share_level;
219 static NTSTATUS catia_string_replace_allocate(connection_struct *conn,
224 static smb_ucs2_t *tmpbuf = NULL;
226 struct share_mapping_entry *selected;
227 struct char_mappings *map = NULL;
228 size_t converted_size;
229 TALLOC_CTX *ctx = talloc_tos();
231 if (!init_mappings(conn, &selected))
234 if ((push_ucs2_talloc(ctx, &tmpbuf, name_in,
235 &converted_size)) == -1) {
236 return map_nt_error_from_unix(errno);
242 map = selected->mappings[T_PICK((*ptr))];
248 *ptr = map->entry[T_OFFSET((*ptr))][direction];
251 if ((pull_ucs2_talloc(ctx, mapped_name, tmpbuf,
252 &converted_size)) == -1) {
254 return map_nt_error_from_unix(errno);
260 static SMB_STRUCT_DIR *catia_opendir(vfs_handle_struct *handle,
265 char *name_mapped = NULL;
269 status = catia_string_replace_allocate(handle->conn, fname,
270 &name_mapped, TO_UNIX);
271 if (!NT_STATUS_IS_OK(status)) {
272 errno = map_errno_from_nt_status(status);
276 ret = SMB_VFS_NEXT_OPENDIR(handle, name_mapped, mask, attr);
277 TALLOC_FREE(name_mapped);
283 * TRANSLATE_NAME call which converts the given name to
284 * "WINDOWS displayable" name
286 static NTSTATUS catia_translate_name(vfs_handle_struct *handle,
293 * Copy the supplied name and free the memory for mapped_name,
294 * already allocated by the caller.
295 * We will be allocating new memory for mapped_name in
296 * catia_string_replace_allocate
298 name = talloc_strdup(talloc_tos(), *mapped_name);
301 return NT_STATUS_NO_MEMORY;
303 TALLOC_FREE(*mapped_name);
304 ret = catia_string_replace_allocate(handle->conn, name,
305 mapped_name, TO_WINDOWS);
308 if (!NT_STATUS_IS_OK(ret)) {
312 ret = SMB_VFS_NEXT_TRANSLATE_NAME(handle, mapped_name);
317 static int catia_open(vfs_handle_struct *handle,
318 struct smb_filename *smb_fname,
323 char *name_mapped = NULL;
328 tmp_base_name = smb_fname->base_name;
329 status = catia_string_replace_allocate(handle->conn,
330 smb_fname->base_name,
331 &name_mapped, TO_UNIX);
332 if (!NT_STATUS_IS_OK(status)) {
333 errno = map_errno_from_nt_status(status);
337 smb_fname->base_name = name_mapped;
338 ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
339 smb_fname->base_name = tmp_base_name;
340 TALLOC_FREE(name_mapped);
345 /* @internal - Isilon create file support */
346 static NTSTATUS catia_createfile(vfs_handle_struct *handle,
347 struct smb_request *req,
348 uint16_t root_dir_fid,
349 struct smb_filename *smb_fname,
350 uint32_t access_mask,
351 uint32_t share_access,
352 uint32_t create_disposition,
353 uint32_t create_options,
354 uint32_t file_attributes,
355 uint32_t oplock_request,
356 uint64_t allocation_size,
357 struct security_descriptor *sd,
358 struct ea_list *ea_list,
359 files_struct **result,
362 char *name_mapped = NULL;
366 ret = catia_string_replace_allocate(handle->conn, smb_fname->base_name,
367 &name_mapped, TO_UNIX);
368 if (!NT_STATUS_IS_OK(ret)) {
369 errno = map_errno_from_nt_status(ret);
373 tmp_base_name = smb_fname->base_name;
374 DEBUG(5, ("catia_createfile converted %s->%s (orginally %s)\n",
375 tmp_base_name, name_mapped, tmp_base_name));
376 smb_fname->base_name = name_mapped;
377 ret = SMB_VFS_NEXT_CREATE_FILE(handle, req, root_dir_fid,
378 smb_fname, access_mask, share_access,
379 create_disposition, create_options,
380 file_attributes, oplock_request,
381 allocation_size, sd, ea_list,
384 smb_fname->base_name = tmp_base_name;
385 TALLOC_FREE(name_mapped);
390 static int catia_rename(vfs_handle_struct *handle,
391 const struct smb_filename *smb_fname_src,
392 const struct smb_filename *smb_fname_dst)
394 TALLOC_CTX *ctx = talloc_tos();
395 struct smb_filename *smb_fname_src_tmp = NULL;
396 struct smb_filename *smb_fname_dst_tmp = NULL;
400 status = catia_string_replace_allocate(handle->conn,
401 smb_fname_src->base_name,
402 &(smb_fname_src_tmp->base_name), TO_UNIX);
403 if (!NT_STATUS_IS_OK(status)) {
404 errno = map_errno_from_nt_status(status);
408 status = catia_string_replace_allocate(handle->conn,
409 smb_fname_dst->base_name,
410 &(smb_fname_dst_tmp->base_name), TO_UNIX);
411 if (!NT_STATUS_IS_OK(status)) {
412 errno = map_errno_from_nt_status(status);
416 /* Setup temporary smb_filename structs. */
417 status = copy_smb_filename(ctx, smb_fname_src, &smb_fname_src_tmp);
419 if (!NT_STATUS_IS_OK(status)) {
420 errno = map_errno_from_nt_status(status);
424 status = copy_smb_filename(ctx, smb_fname_dst, &smb_fname_dst_tmp);
425 if (!NT_STATUS_IS_OK(status)) {
426 errno = map_errno_from_nt_status(status);
430 DEBUG(10, ("converted old name: %s\n",
431 smb_fname_str_dbg(smb_fname_src_tmp)));
432 DEBUG(10, ("converted new name: %s\n",
433 smb_fname_str_dbg(smb_fname_dst_tmp)));
435 ret = SMB_VFS_NEXT_RENAME(handle, smb_fname_src_tmp,
438 TALLOC_FREE(smb_fname_src_tmp);
439 TALLOC_FREE(smb_fname_dst_tmp);
443 static int catia_stat(vfs_handle_struct *handle,
444 struct smb_filename *smb_fname)
451 status = catia_string_replace_allocate(handle->conn,
452 smb_fname->base_name,
454 if (!NT_STATUS_IS_OK(status)) {
455 errno = map_errno_from_nt_status(status);
459 tmp_base_name = smb_fname->base_name;
460 smb_fname->base_name = name;
462 ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
463 smb_fname->base_name = tmp_base_name;
469 static int catia_lstat(vfs_handle_struct *handle,
470 struct smb_filename *smb_fname)
477 status = catia_string_replace_allocate(handle->conn,
478 smb_fname->base_name,
480 if (!NT_STATUS_IS_OK(status)) {
481 errno = map_errno_from_nt_status(status);
485 tmp_base_name = smb_fname->base_name;
486 smb_fname->base_name = name;
488 ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
489 smb_fname->base_name = tmp_base_name;
495 static int catia_unlink(vfs_handle_struct *handle,
496 const struct smb_filename *smb_fname)
498 struct smb_filename *smb_fname_tmp = NULL;
503 status = catia_string_replace_allocate(handle->conn,
504 smb_fname->base_name,
506 if (!NT_STATUS_IS_OK(status)) {
507 errno = map_errno_from_nt_status(status);
511 /* Setup temporary smb_filename structs. */
512 status = copy_smb_filename(talloc_tos(), smb_fname, &smb_fname_tmp);
513 if (!NT_STATUS_IS_OK(status)) {
514 errno = map_errno_from_nt_status(status);
518 smb_fname_tmp->base_name = name;
519 ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname_tmp);
520 TALLOC_FREE(smb_fname_tmp);
526 static int catia_chown(vfs_handle_struct *handle,
535 status = catia_string_replace_allocate(handle->conn, path,
537 if (!NT_STATUS_IS_OK(status)) {
538 errno = map_errno_from_nt_status(status);
542 ret = SMB_VFS_NEXT_CHOWN(handle, name, uid, gid);
548 static int catia_lchown(vfs_handle_struct *handle,
557 status = catia_string_replace_allocate(handle->conn, path,
559 if (!NT_STATUS_IS_OK(status)) {
560 errno = map_errno_from_nt_status(status);
564 ret = SMB_VFS_NEXT_LCHOWN(handle, name, uid, gid);
570 static int catia_rmdir(vfs_handle_struct *handle,
577 status = catia_string_replace_allocate(handle->conn, path,
579 if (!NT_STATUS_IS_OK(status)) {
580 errno = map_errno_from_nt_status(status);
584 ret = SMB_VFS_NEXT_RMDIR(handle, name);
590 static int catia_mkdir(vfs_handle_struct *handle,
598 status = catia_string_replace_allocate(handle->conn, path,
600 if (!NT_STATUS_IS_OK(status)) {
601 errno = map_errno_from_nt_status(status);
605 ret = SMB_VFS_NEXT_MKDIR(handle, name, mode);
611 static int catia_chdir(vfs_handle_struct *handle,
618 status = catia_string_replace_allocate(handle->conn, path,
620 if (!NT_STATUS_IS_OK(status)) {
621 errno = map_errno_from_nt_status(status);
625 ret = SMB_VFS_NEXT_CHDIR(handle, name);
631 static int catia_ntimes(vfs_handle_struct *handle,
632 const struct smb_filename *smb_fname,
633 struct smb_file_time *ft)
635 struct smb_filename *smb_fname_tmp = NULL;
640 status = catia_string_replace_allocate(handle->conn,
641 smb_fname->base_name,
643 if (!NT_STATUS_IS_OK(status)) {
644 errno = map_errno_from_nt_status(status);
648 status = copy_smb_filename(talloc_tos(), smb_fname, &smb_fname_tmp);
649 if (!NT_STATUS_IS_OK(status)) {
650 errno = map_errno_from_nt_status(status);
654 smb_fname_tmp->base_name = name;
655 ret = SMB_VFS_NEXT_NTIMES(handle, smb_fname_tmp, ft);
656 TALLOC_FREE(smb_fname_tmp);
662 catia_realpath(vfs_handle_struct *handle, const char *path,
665 char *mapped_name = NULL;
669 status = catia_string_replace_allocate(handle->conn, path,
670 &mapped_name, TO_UNIX);
671 if (!NT_STATUS_IS_OK(status)) {
672 errno = map_errno_from_nt_status(status);
676 ret = SMB_VFS_NEXT_REALPATH(handle, mapped_name, resolved_path);
677 TALLOC_FREE(mapped_name);
682 static int catia_chflags(struct vfs_handle_struct *handle,
683 const char *path, unsigned int flags)
685 char *mapped_name = NULL;
689 status = catia_string_replace_allocate(handle->conn, path,
690 &mapped_name, TO_UNIX);
691 if (!NT_STATUS_IS_OK(status)) {
692 errno = map_errno_from_nt_status(status);
696 ret = SMB_VFS_NEXT_CHFLAGS(handle, mapped_name, flags);
697 TALLOC_FREE(mapped_name);
703 catia_streaminfo(struct vfs_handle_struct *handle,
704 struct files_struct *fsp,
707 unsigned int *num_streams,
708 struct stream_struct **streams)
710 char *mapped_name = NULL;
713 status = catia_string_replace_allocate(handle->conn, path,
714 &mapped_name, TO_UNIX);
715 if (!NT_STATUS_IS_OK(status)) {
716 errno = map_errno_from_nt_status(status);
720 status = SMB_VFS_NEXT_STREAMINFO(handle, fsp, mapped_name,
721 mem_ctx, num_streams,streams);
722 TALLOC_FREE(mapped_name);
728 catia_get_nt_acl(struct vfs_handle_struct *handle,
730 uint32 security_info,
731 struct security_descriptor **ppdesc)
733 char *mapped_name = NULL;
736 status = catia_string_replace_allocate(handle->conn,
737 path, &mapped_name, TO_UNIX);
738 if (!NT_STATUS_IS_OK(status)) {
739 errno = map_errno_from_nt_status(status);
742 status = SMB_VFS_NEXT_GET_NT_ACL(handle, mapped_name,
743 security_info, ppdesc);
744 TALLOC_FREE(mapped_name);
750 catia_chmod_acl(vfs_handle_struct *handle,
754 char *mapped_name = NULL;
758 status = catia_string_replace_allocate(handle->conn,
759 path, &mapped_name, TO_UNIX);
760 if (!NT_STATUS_IS_OK(status)) {
761 errno = map_errno_from_nt_status(status);
765 ret = SMB_VFS_NEXT_CHMOD_ACL(handle, mapped_name, mode);
766 TALLOC_FREE(mapped_name);
771 catia_sys_acl_get_file(vfs_handle_struct *handle,
775 char *mapped_name = NULL;
779 status = catia_string_replace_allocate(handle->conn,
780 path, &mapped_name, TO_UNIX);
781 if (!NT_STATUS_IS_OK(status)) {
782 errno = map_errno_from_nt_status(status);
786 ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, mapped_name, type);
787 TALLOC_FREE(mapped_name);
793 catia_sys_acl_set_file(vfs_handle_struct *handle,
798 char *mapped_name = NULL;
802 status = catia_string_replace_allocate(handle->conn,
803 path, &mapped_name, TO_UNIX);
804 if (!NT_STATUS_IS_OK(status)) {
805 errno = map_errno_from_nt_status(status);
809 ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, mapped_name, type, theacl);
810 TALLOC_FREE(mapped_name);
816 catia_sys_acl_delete_def_file(vfs_handle_struct *handle,
819 char *mapped_name = NULL;
823 status = catia_string_replace_allocate(handle->conn,
824 path, &mapped_name, TO_UNIX);
825 if (!NT_STATUS_IS_OK(status)) {
826 errno = map_errno_from_nt_status(status);
830 ret = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, mapped_name);
831 TALLOC_FREE(mapped_name);
837 catia_getxattr(vfs_handle_struct *handle, const char *path,
838 const char *name, void *value, size_t size)
840 char *mapped_name = NULL;
844 status = catia_string_replace_allocate(handle->conn,
845 name, &mapped_name, TO_UNIX);
846 if (!NT_STATUS_IS_OK(status)) {
847 errno = map_errno_from_nt_status(status);
852 ret = SMB_VFS_NEXT_GETXATTR(handle, path, mapped_name, value, size);
853 TALLOC_FREE(mapped_name);
859 catia_lgetxattr(vfs_handle_struct *handle, const char *path,
860 const char *name, void *value, size_t size)
862 char *mapped_name = NULL;
866 status = catia_string_replace_allocate(handle->conn,
867 name, &mapped_name, TO_UNIX);
868 if (!NT_STATUS_IS_OK(status)) {
869 errno = map_errno_from_nt_status(status);
874 ret = SMB_VFS_NEXT_LGETXATTR(handle, path, mapped_name, value, size);
875 TALLOC_FREE(mapped_name);
881 catia_listxattr(vfs_handle_struct *handle, const char *path,
882 char *list, size_t size)
884 char *mapped_name = NULL;
888 status = catia_string_replace_allocate(handle->conn,
889 path, &mapped_name, TO_UNIX);
890 if (!NT_STATUS_IS_OK(status)) {
891 errno = map_errno_from_nt_status(status);
896 ret = SMB_VFS_NEXT_LISTXATTR(handle, mapped_name, list, size);
897 TALLOC_FREE(mapped_name);
903 catia_llistxattr(vfs_handle_struct *handle, const char *path,
904 char *list, size_t size)
906 char *mapped_name = NULL;
910 status = catia_string_replace_allocate(handle->conn,
911 path, &mapped_name, TO_UNIX);
912 if (!NT_STATUS_IS_OK(status)) {
913 errno = map_errno_from_nt_status(status);
918 ret = SMB_VFS_NEXT_LLISTXATTR(handle, mapped_name, list, size);
919 TALLOC_FREE(mapped_name);
925 catia_removexattr(vfs_handle_struct *handle, const char *path,
928 char *mapped_name = NULL;
932 status = catia_string_replace_allocate(handle->conn,
933 name, &mapped_name, TO_UNIX);
934 if (!NT_STATUS_IS_OK(status)) {
935 errno = map_errno_from_nt_status(status);
940 ret = SMB_VFS_NEXT_REMOVEXATTR(handle, path, mapped_name);
941 TALLOC_FREE(mapped_name);
947 catia_lremovexattr(vfs_handle_struct *handle, const char *path,
950 char *mapped_name = NULL;
954 status = catia_string_replace_allocate(handle->conn,
955 name, &mapped_name, TO_UNIX);
956 if (!NT_STATUS_IS_OK(status)) {
957 errno = map_errno_from_nt_status(status);
962 ret = SMB_VFS_NEXT_LREMOVEXATTR(handle, path, mapped_name);
963 TALLOC_FREE(mapped_name);
969 catia_setxattr(vfs_handle_struct *handle, const char *path,
970 const char *name, const void *value, size_t size,
973 char *mapped_name = NULL;
977 status = catia_string_replace_allocate(handle->conn,
978 name, &mapped_name, TO_UNIX);
979 if (!NT_STATUS_IS_OK(status)) {
980 errno = map_errno_from_nt_status(status);
985 ret = SMB_VFS_NEXT_SETXATTR(handle, path, mapped_name, value, size, flags);
986 TALLOC_FREE(mapped_name);
992 catia_lsetxattr(vfs_handle_struct *handle, const char *path,
993 const char *name, const void *value, size_t size,
996 char *mapped_name = NULL;
1000 status = catia_string_replace_allocate(handle->conn,
1001 name, &mapped_name, TO_UNIX);
1002 if (!NT_STATUS_IS_OK(status)) {
1003 errno = map_errno_from_nt_status(status);
1008 ret = SMB_VFS_NEXT_LSETXATTR(handle, path, mapped_name, value, size, flags);
1009 TALLOC_FREE(mapped_name);
1014 static struct vfs_fn_pointers vfs_catia_fns = {
1015 .mkdir = catia_mkdir,
1016 .rmdir = catia_rmdir,
1017 .opendir = catia_opendir,
1019 .create_file = catia_createfile,
1020 .rename = catia_rename,
1022 .lstat = catia_lstat,
1023 .unlink = catia_unlink,
1024 .chown = catia_chown,
1025 .lchown = catia_lchown,
1026 .chdir = catia_chdir,
1027 .ntimes = catia_ntimes,
1028 .realpath = catia_realpath,
1029 .chflags = catia_chflags,
1030 .streaminfo = catia_streaminfo,
1031 .translate_name = catia_translate_name,
1032 .get_nt_acl = catia_get_nt_acl,
1033 .chmod_acl = catia_chmod_acl,
1034 .sys_acl_get_file = catia_sys_acl_get_file,
1035 .sys_acl_set_file = catia_sys_acl_set_file,
1036 .sys_acl_delete_def_file = catia_sys_acl_delete_def_file,
1037 .getxattr = catia_getxattr,
1038 .lgetxattr = catia_lgetxattr,
1039 .listxattr = catia_listxattr,
1040 .llistxattr = catia_llistxattr,
1041 .removexattr = catia_removexattr,
1042 .lremovexattr = catia_lremovexattr,
1043 .setxattr = catia_setxattr,
1044 .lsetxattr = catia_lsetxattr,
1047 NTSTATUS vfs_catia_init(void)
1049 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "catia",