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
13 * Copyright (C) Guenter Kukkukk, 2013
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 3 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see <http://www.gnu.org/licenses/>.
31 #include "smbd/smbd.h"
33 static int vfs_catia_debug_level
= DBGC_VFS
;
36 #define DBGC_CLASS vfs_catia_debug_level
38 #define GLOBAL_SNUM 0xFFFFFFF
40 #define MAP_NUM 0x101 /* max unicode charval / MAP_SIZE */
41 #define T_OFFSET(_v_) ((_v_ % MAP_SIZE))
42 #define T_START(_v_) (((_v_ / MAP_SIZE) * MAP_SIZE))
43 #define T_PICK(_v_) ((_v_ / MAP_SIZE))
45 struct char_mappings
{
46 smb_ucs2_t entry
[MAP_SIZE
][2];
49 struct share_mapping_entry
{
51 struct share_mapping_entry
*next
;
52 struct char_mappings
**mappings
;
55 struct share_mapping_entry
*srt_head
= NULL
;
57 static bool build_table(struct char_mappings
**cmaps
, int value
)
60 int start
= T_START(value
);
62 (*cmaps
) = talloc_zero(NULL
, struct char_mappings
);
67 for (i
= 0; i
< MAP_SIZE
;i
++) {
68 (*cmaps
)->entry
[i
][vfs_translate_to_unix
] = start
+ i
;
69 (*cmaps
)->entry
[i
][vfs_translate_to_windows
] = start
+ i
;
75 static void set_tables(struct char_mappings
**cmaps
,
81 /* set unix -> windows */
82 i
= T_OFFSET(unix_map
);
83 cmaps
[T_PICK(unix_map
)]->entry
[i
][vfs_translate_to_windows
] = windows_map
;
85 /* set windows -> unix */
86 i
= T_OFFSET(windows_map
);
87 cmaps
[T_PICK(windows_map
)]->entry
[i
][vfs_translate_to_unix
] = unix_map
;
90 static bool build_ranges(struct char_mappings
**cmaps
,
95 if (!cmaps
[T_PICK(unix_map
)]) {
96 if (!build_table(&cmaps
[T_PICK(unix_map
)], unix_map
))
100 if (!cmaps
[T_PICK(windows_map
)]) {
101 if (!build_table(&cmaps
[T_PICK(windows_map
)], windows_map
))
105 set_tables(cmaps
, unix_map
, windows_map
);
110 static struct share_mapping_entry
*get_srt(connection_struct
*conn
,
111 struct share_mapping_entry
**global
)
113 struct share_mapping_entry
*share
;
115 for (share
= srt_head
; share
!= NULL
; share
= share
->next
) {
116 if (share
->snum
== GLOBAL_SNUM
)
119 if (share
->snum
== SNUM(conn
))
126 static struct share_mapping_entry
*add_srt(int snum
, const char **mappings
)
132 long unix_map
, windows_map
;
133 struct share_mapping_entry
*ret
= NULL
;
135 ret
= (struct share_mapping_entry
*)
136 TALLOC_ZERO(NULL
, sizeof(struct share_mapping_entry
) +
137 (mappings
? (MAP_NUM
* sizeof(struct char_mappings
*)) : 0));
145 ret
->mappings
= (struct char_mappings
**) ((unsigned char*) ret
+
146 sizeof(struct share_mapping_entry
));
147 memset(ret
->mappings
, 0,
148 MAP_NUM
* sizeof(struct char_mappings
*));
150 ret
->mappings
= NULL
;
155 * catia mappings are of the form :
156 * UNIX char (in 0xnn hex) : WINDOWS char (in 0xnn hex)
158 * multiple mappings are comma seperated in smb.conf
160 for (i
=0;mappings
[i
];i
++) {
161 fstrcpy(mapping
, mappings
[i
]);
162 unix_map
= strtol(mapping
, &tmp
, 16);
163 if (unix_map
== 0 && errno
== EINVAL
) {
164 DEBUG(0, ("INVALID CATIA MAPPINGS - %s\n", mapping
));
167 windows_map
= strtol(++tmp
, NULL
, 16);
168 if (windows_map
== 0 && errno
== EINVAL
) {
169 DEBUG(0, ("INVALID CATIA MAPPINGS - %s\n", mapping
));
173 if (!build_ranges(ret
->mappings
, unix_map
, windows_map
)) {
174 DEBUG(0, ("TABLE ERROR - CATIA MAPPINGS - %s\n", mapping
));
179 ret
->next
= srt_head
;
185 static bool init_mappings(connection_struct
*conn
,
186 struct share_mapping_entry
**selected_out
)
188 const char **mappings
= NULL
;
189 struct share_mapping_entry
*share_level
= NULL
;
190 struct share_mapping_entry
*global
= NULL
;
192 /* check srt cache */
193 share_level
= get_srt(conn
, &global
);
195 *selected_out
= share_level
;
196 return (share_level
->mappings
!= NULL
);
199 /* see if we have a global setting */
202 mappings
= lp_parm_string_list(-1, "catia", "mappings", NULL
);
203 global
= add_srt(GLOBAL_SNUM
, mappings
);
206 /* no global setting - what about share level ? */
207 mappings
= lp_parm_string_list(SNUM(conn
), "catia", "mappings", NULL
);
208 share_level
= add_srt(SNUM(conn
), mappings
);
210 if (share_level
->mappings
) {
211 (*selected_out
) = share_level
;
213 } else if (global
->mappings
) {
214 share_level
->mappings
= global
->mappings
;
215 (*selected_out
) = share_level
;
222 static NTSTATUS
catia_string_replace_allocate(connection_struct
*conn
,
227 static smb_ucs2_t
*tmpbuf
= NULL
;
229 struct share_mapping_entry
*selected
;
230 struct char_mappings
*map
= NULL
;
231 size_t converted_size
;
232 TALLOC_CTX
*ctx
= talloc_tos();
234 if (!init_mappings(conn
, &selected
)) {
235 /* No mappings found. Just use the old name */
236 *mapped_name
= talloc_strdup(NULL
, name_in
);
239 return NT_STATUS_NO_MEMORY
;
244 if ((push_ucs2_talloc(ctx
, &tmpbuf
, name_in
,
245 &converted_size
)) == false) {
246 return map_nt_error_from_unix(errno
);
252 map
= selected
->mappings
[T_PICK((*ptr
))];
258 *ptr
= map
->entry
[T_OFFSET((*ptr
))][direction
];
261 if ((pull_ucs2_talloc(ctx
, mapped_name
, tmpbuf
,
262 &converted_size
)) == false) {
264 return map_nt_error_from_unix(errno
);
270 static SMB_STRUCT_DIR
*catia_opendir(vfs_handle_struct
*handle
,
275 char *name_mapped
= NULL
;
279 status
= catia_string_replace_allocate(handle
->conn
, fname
,
280 &name_mapped
, vfs_translate_to_unix
);
281 if (!NT_STATUS_IS_OK(status
)) {
282 errno
= map_errno_from_nt_status(status
);
286 ret
= SMB_VFS_NEXT_OPENDIR(handle
, name_mapped
, mask
, attr
);
287 TALLOC_FREE(name_mapped
);
293 * TRANSLATE_NAME call which converts the given name to
294 * "WINDOWS displayable" name
296 static NTSTATUS
catia_translate_name(struct vfs_handle_struct
*handle
,
297 const char *orig_name
,
298 enum vfs_translate_direction direction
,
304 NTSTATUS status
, ret
;
307 * Copy the supplied name and free the memory for mapped_name,
308 * already allocated by the caller.
309 * We will be allocating new memory for mapped_name in
310 * catia_string_replace_allocate
312 name
= talloc_strdup(talloc_tos(), orig_name
);
315 return NT_STATUS_NO_MEMORY
;
317 status
= catia_string_replace_allocate(handle
->conn
, name
,
318 &mapped_name
, direction
);
321 if (!NT_STATUS_IS_OK(status
)) {
325 ret
= SMB_VFS_NEXT_TRANSLATE_NAME(handle
, mapped_name
, direction
,
326 mem_ctx
, pmapped_name
);
328 if (NT_STATUS_EQUAL(ret
, NT_STATUS_NONE_MAPPED
)) {
329 *pmapped_name
= talloc_move(mem_ctx
, &mapped_name
);
330 /* we need to return the former translation result here */
333 TALLOC_FREE(mapped_name
);
339 static int catia_open(vfs_handle_struct
*handle
,
340 struct smb_filename
*smb_fname
,
345 char *name_mapped
= NULL
;
350 tmp_base_name
= smb_fname
->base_name
;
351 status
= catia_string_replace_allocate(handle
->conn
,
352 smb_fname
->base_name
,
353 &name_mapped
, vfs_translate_to_unix
);
354 if (!NT_STATUS_IS_OK(status
)) {
355 errno
= map_errno_from_nt_status(status
);
359 smb_fname
->base_name
= name_mapped
;
360 ret
= SMB_VFS_NEXT_OPEN(handle
, smb_fname
, fsp
, flags
, mode
);
361 smb_fname
->base_name
= tmp_base_name
;
362 TALLOC_FREE(name_mapped
);
367 static int catia_rename(vfs_handle_struct
*handle
,
368 const struct smb_filename
*smb_fname_src
,
369 const struct smb_filename
*smb_fname_dst
)
371 TALLOC_CTX
*ctx
= talloc_tos();
372 struct smb_filename
*smb_fname_src_tmp
= NULL
;
373 struct smb_filename
*smb_fname_dst_tmp
= NULL
;
374 char *src_name_mapped
= NULL
;
375 char *dst_name_mapped
= NULL
;
379 status
= catia_string_replace_allocate(handle
->conn
,
380 smb_fname_src
->base_name
,
381 &src_name_mapped
, vfs_translate_to_unix
);
382 if (!NT_STATUS_IS_OK(status
)) {
383 errno
= map_errno_from_nt_status(status
);
387 status
= catia_string_replace_allocate(handle
->conn
,
388 smb_fname_dst
->base_name
,
389 &dst_name_mapped
, vfs_translate_to_unix
);
390 if (!NT_STATUS_IS_OK(status
)) {
391 errno
= map_errno_from_nt_status(status
);
395 /* Setup temporary smb_filename structs. */
396 status
= copy_smb_filename(ctx
, smb_fname_src
, &smb_fname_src_tmp
);
398 if (!NT_STATUS_IS_OK(status
)) {
399 errno
= map_errno_from_nt_status(status
);
403 status
= copy_smb_filename(ctx
, smb_fname_dst
, &smb_fname_dst_tmp
);
404 if (!NT_STATUS_IS_OK(status
)) {
405 errno
= map_errno_from_nt_status(status
);
409 smb_fname_src_tmp
->base_name
= src_name_mapped
;
410 smb_fname_dst_tmp
->base_name
= dst_name_mapped
;
411 DEBUG(10, ("converted old name: %s\n",
412 smb_fname_str_dbg(smb_fname_src_tmp
)));
413 DEBUG(10, ("converted new name: %s\n",
414 smb_fname_str_dbg(smb_fname_dst_tmp
)));
416 ret
= SMB_VFS_NEXT_RENAME(handle
, smb_fname_src_tmp
,
419 TALLOC_FREE(src_name_mapped
);
420 TALLOC_FREE(dst_name_mapped
);
421 TALLOC_FREE(smb_fname_src_tmp
);
422 TALLOC_FREE(smb_fname_dst_tmp
);
426 static int catia_stat(vfs_handle_struct
*handle
,
427 struct smb_filename
*smb_fname
)
434 status
= catia_string_replace_allocate(handle
->conn
,
435 smb_fname
->base_name
,
436 &name
, vfs_translate_to_unix
);
437 if (!NT_STATUS_IS_OK(status
)) {
438 errno
= map_errno_from_nt_status(status
);
442 tmp_base_name
= smb_fname
->base_name
;
443 smb_fname
->base_name
= name
;
445 ret
= SMB_VFS_NEXT_STAT(handle
, smb_fname
);
446 smb_fname
->base_name
= tmp_base_name
;
452 static int catia_lstat(vfs_handle_struct
*handle
,
453 struct smb_filename
*smb_fname
)
460 status
= catia_string_replace_allocate(handle
->conn
,
461 smb_fname
->base_name
,
462 &name
, vfs_translate_to_unix
);
463 if (!NT_STATUS_IS_OK(status
)) {
464 errno
= map_errno_from_nt_status(status
);
468 tmp_base_name
= smb_fname
->base_name
;
469 smb_fname
->base_name
= name
;
471 ret
= SMB_VFS_NEXT_LSTAT(handle
, smb_fname
);
472 smb_fname
->base_name
= tmp_base_name
;
478 static int catia_unlink(vfs_handle_struct
*handle
,
479 const struct smb_filename
*smb_fname
)
481 struct smb_filename
*smb_fname_tmp
= NULL
;
486 status
= catia_string_replace_allocate(handle
->conn
,
487 smb_fname
->base_name
,
488 &name
, vfs_translate_to_unix
);
489 if (!NT_STATUS_IS_OK(status
)) {
490 errno
= map_errno_from_nt_status(status
);
494 /* Setup temporary smb_filename structs. */
495 status
= copy_smb_filename(talloc_tos(), smb_fname
, &smb_fname_tmp
);
496 if (!NT_STATUS_IS_OK(status
)) {
497 errno
= map_errno_from_nt_status(status
);
501 smb_fname_tmp
->base_name
= name
;
502 ret
= SMB_VFS_NEXT_UNLINK(handle
, smb_fname_tmp
);
503 TALLOC_FREE(smb_fname_tmp
);
509 static int catia_chown(vfs_handle_struct
*handle
,
518 status
= catia_string_replace_allocate(handle
->conn
, path
,
519 &name
, vfs_translate_to_unix
);
520 if (!NT_STATUS_IS_OK(status
)) {
521 errno
= map_errno_from_nt_status(status
);
525 ret
= SMB_VFS_NEXT_CHOWN(handle
, name
, uid
, gid
);
531 static int catia_lchown(vfs_handle_struct
*handle
,
540 status
= catia_string_replace_allocate(handle
->conn
, path
,
541 &name
, vfs_translate_to_unix
);
542 if (!NT_STATUS_IS_OK(status
)) {
543 errno
= map_errno_from_nt_status(status
);
547 ret
= SMB_VFS_NEXT_LCHOWN(handle
, name
, uid
, gid
);
553 static int catia_rmdir(vfs_handle_struct
*handle
,
560 status
= catia_string_replace_allocate(handle
->conn
, path
,
561 &name
, vfs_translate_to_unix
);
562 if (!NT_STATUS_IS_OK(status
)) {
563 errno
= map_errno_from_nt_status(status
);
567 ret
= SMB_VFS_NEXT_RMDIR(handle
, name
);
573 static int catia_mkdir(vfs_handle_struct
*handle
,
581 status
= catia_string_replace_allocate(handle
->conn
, path
,
582 &name
, vfs_translate_to_unix
);
583 if (!NT_STATUS_IS_OK(status
)) {
584 errno
= map_errno_from_nt_status(status
);
588 ret
= SMB_VFS_NEXT_MKDIR(handle
, name
, mode
);
594 static int catia_chdir(vfs_handle_struct
*handle
,
601 status
= catia_string_replace_allocate(handle
->conn
, path
,
602 &name
, vfs_translate_to_unix
);
603 if (!NT_STATUS_IS_OK(status
)) {
604 errno
= map_errno_from_nt_status(status
);
608 ret
= SMB_VFS_NEXT_CHDIR(handle
, name
);
614 static int catia_ntimes(vfs_handle_struct
*handle
,
615 const struct smb_filename
*smb_fname
,
616 struct smb_file_time
*ft
)
618 struct smb_filename
*smb_fname_tmp
= NULL
;
623 status
= catia_string_replace_allocate(handle
->conn
,
624 smb_fname
->base_name
,
625 &name
, vfs_translate_to_unix
);
626 if (!NT_STATUS_IS_OK(status
)) {
627 errno
= map_errno_from_nt_status(status
);
631 status
= copy_smb_filename(talloc_tos(), smb_fname
, &smb_fname_tmp
);
632 if (!NT_STATUS_IS_OK(status
)) {
633 errno
= map_errno_from_nt_status(status
);
637 smb_fname_tmp
->base_name
= name
;
638 ret
= SMB_VFS_NEXT_NTIMES(handle
, smb_fname_tmp
, ft
);
640 TALLOC_FREE(smb_fname_tmp
);
646 catia_realpath(vfs_handle_struct
*handle
, const char *path
)
648 char *mapped_name
= NULL
;
652 status
= catia_string_replace_allocate(handle
->conn
, path
,
653 &mapped_name
, vfs_translate_to_unix
);
654 if (!NT_STATUS_IS_OK(status
)) {
655 errno
= map_errno_from_nt_status(status
);
659 ret
= SMB_VFS_NEXT_REALPATH(handle
, mapped_name
);
660 TALLOC_FREE(mapped_name
);
665 static int catia_chflags(struct vfs_handle_struct
*handle
,
666 const char *path
, unsigned int flags
)
668 char *mapped_name
= NULL
;
672 status
= catia_string_replace_allocate(handle
->conn
, path
,
673 &mapped_name
, vfs_translate_to_unix
);
674 if (!NT_STATUS_IS_OK(status
)) {
675 errno
= map_errno_from_nt_status(status
);
679 ret
= SMB_VFS_NEXT_CHFLAGS(handle
, mapped_name
, flags
);
680 TALLOC_FREE(mapped_name
);
686 catia_streaminfo(struct vfs_handle_struct
*handle
,
687 struct files_struct
*fsp
,
690 unsigned int *num_streams
,
691 struct stream_struct
**streams
)
693 char *mapped_name
= NULL
;
696 status
= catia_string_replace_allocate(handle
->conn
, path
,
697 &mapped_name
, vfs_translate_to_unix
);
698 if (!NT_STATUS_IS_OK(status
)) {
699 errno
= map_errno_from_nt_status(status
);
703 status
= SMB_VFS_NEXT_STREAMINFO(handle
, fsp
, mapped_name
,
704 mem_ctx
, num_streams
,streams
);
705 TALLOC_FREE(mapped_name
);
711 catia_get_nt_acl(struct vfs_handle_struct
*handle
,
713 uint32 security_info
,
714 struct security_descriptor
**ppdesc
)
716 char *mapped_name
= NULL
;
719 status
= catia_string_replace_allocate(handle
->conn
,
720 path
, &mapped_name
, vfs_translate_to_unix
);
721 if (!NT_STATUS_IS_OK(status
)) {
722 errno
= map_errno_from_nt_status(status
);
725 status
= SMB_VFS_NEXT_GET_NT_ACL(handle
, mapped_name
,
726 security_info
, ppdesc
);
727 TALLOC_FREE(mapped_name
);
733 catia_chmod_acl(vfs_handle_struct
*handle
,
737 char *mapped_name
= NULL
;
741 status
= catia_string_replace_allocate(handle
->conn
,
742 path
, &mapped_name
, vfs_translate_to_unix
);
743 if (!NT_STATUS_IS_OK(status
)) {
744 errno
= map_errno_from_nt_status(status
);
748 ret
= SMB_VFS_NEXT_CHMOD_ACL(handle
, mapped_name
, mode
);
749 TALLOC_FREE(mapped_name
);
754 catia_sys_acl_get_file(vfs_handle_struct
*handle
,
758 char *mapped_name
= NULL
;
762 status
= catia_string_replace_allocate(handle
->conn
,
763 path
, &mapped_name
, vfs_translate_to_unix
);
764 if (!NT_STATUS_IS_OK(status
)) {
765 errno
= map_errno_from_nt_status(status
);
769 ret
= SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle
, mapped_name
, type
);
770 TALLOC_FREE(mapped_name
);
776 catia_sys_acl_set_file(vfs_handle_struct
*handle
,
781 char *mapped_name
= NULL
;
785 status
= catia_string_replace_allocate(handle
->conn
,
786 path
, &mapped_name
, vfs_translate_to_unix
);
787 if (!NT_STATUS_IS_OK(status
)) {
788 errno
= map_errno_from_nt_status(status
);
792 ret
= SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle
, mapped_name
, type
, theacl
);
793 TALLOC_FREE(mapped_name
);
799 catia_sys_acl_delete_def_file(vfs_handle_struct
*handle
,
802 char *mapped_name
= NULL
;
806 status
= catia_string_replace_allocate(handle
->conn
,
807 path
, &mapped_name
, vfs_translate_to_unix
);
808 if (!NT_STATUS_IS_OK(status
)) {
809 errno
= map_errno_from_nt_status(status
);
813 ret
= SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle
, mapped_name
);
814 TALLOC_FREE(mapped_name
);
820 catia_getxattr(vfs_handle_struct
*handle
, const char *path
,
821 const char *name
, void *value
, size_t size
)
823 char *mapped_name
= NULL
;
827 status
= catia_string_replace_allocate(handle
->conn
,
828 name
, &mapped_name
, vfs_translate_to_unix
);
829 if (!NT_STATUS_IS_OK(status
)) {
830 errno
= map_errno_from_nt_status(status
);
835 ret
= SMB_VFS_NEXT_GETXATTR(handle
, path
, mapped_name
, value
, size
);
836 TALLOC_FREE(mapped_name
);
842 catia_lgetxattr(vfs_handle_struct
*handle
, const char *path
,
843 const char *name
, void *value
, size_t size
)
845 char *mapped_name
= NULL
;
849 status
= catia_string_replace_allocate(handle
->conn
,
850 name
, &mapped_name
, vfs_translate_to_unix
);
851 if (!NT_STATUS_IS_OK(status
)) {
852 errno
= map_errno_from_nt_status(status
);
857 ret
= SMB_VFS_NEXT_LGETXATTR(handle
, path
, mapped_name
, value
, size
);
858 TALLOC_FREE(mapped_name
);
864 catia_listxattr(vfs_handle_struct
*handle
, const char *path
,
865 char *list
, size_t size
)
867 char *mapped_name
= NULL
;
871 status
= catia_string_replace_allocate(handle
->conn
,
872 path
, &mapped_name
, vfs_translate_to_unix
);
873 if (!NT_STATUS_IS_OK(status
)) {
874 errno
= map_errno_from_nt_status(status
);
879 ret
= SMB_VFS_NEXT_LISTXATTR(handle
, mapped_name
, list
, size
);
880 TALLOC_FREE(mapped_name
);
886 catia_llistxattr(vfs_handle_struct
*handle
, const char *path
,
887 char *list
, size_t size
)
889 char *mapped_name
= NULL
;
893 status
= catia_string_replace_allocate(handle
->conn
,
894 path
, &mapped_name
, vfs_translate_to_unix
);
895 if (!NT_STATUS_IS_OK(status
)) {
896 errno
= map_errno_from_nt_status(status
);
901 ret
= SMB_VFS_NEXT_LLISTXATTR(handle
, mapped_name
, list
, size
);
902 TALLOC_FREE(mapped_name
);
908 catia_removexattr(vfs_handle_struct
*handle
, const char *path
,
911 char *mapped_name
= NULL
;
915 status
= catia_string_replace_allocate(handle
->conn
,
916 name
, &mapped_name
, vfs_translate_to_unix
);
917 if (!NT_STATUS_IS_OK(status
)) {
918 errno
= map_errno_from_nt_status(status
);
923 ret
= SMB_VFS_NEXT_REMOVEXATTR(handle
, path
, mapped_name
);
924 TALLOC_FREE(mapped_name
);
930 catia_lremovexattr(vfs_handle_struct
*handle
, const char *path
,
933 char *mapped_name
= NULL
;
937 status
= catia_string_replace_allocate(handle
->conn
,
938 name
, &mapped_name
, vfs_translate_to_unix
);
939 if (!NT_STATUS_IS_OK(status
)) {
940 errno
= map_errno_from_nt_status(status
);
945 ret
= SMB_VFS_NEXT_LREMOVEXATTR(handle
, path
, mapped_name
);
946 TALLOC_FREE(mapped_name
);
952 catia_setxattr(vfs_handle_struct
*handle
, const char *path
,
953 const char *name
, const void *value
, size_t size
,
956 char *mapped_name
= NULL
;
960 status
= catia_string_replace_allocate(handle
->conn
,
961 name
, &mapped_name
, vfs_translate_to_unix
);
962 if (!NT_STATUS_IS_OK(status
)) {
963 errno
= map_errno_from_nt_status(status
);
968 ret
= SMB_VFS_NEXT_SETXATTR(handle
, path
, mapped_name
, value
, size
, flags
);
969 TALLOC_FREE(mapped_name
);
975 catia_lsetxattr(vfs_handle_struct
*handle
, const char *path
,
976 const char *name
, const void *value
, size_t size
,
979 char *mapped_name
= NULL
;
983 status
= catia_string_replace_allocate(handle
->conn
,
984 name
, &mapped_name
, vfs_translate_to_unix
);
985 if (!NT_STATUS_IS_OK(status
)) {
986 errno
= map_errno_from_nt_status(status
);
991 ret
= SMB_VFS_NEXT_LSETXATTR(handle
, path
, mapped_name
, value
, size
, flags
);
992 TALLOC_FREE(mapped_name
);
997 static struct vfs_fn_pointers vfs_catia_fns
= {
998 .mkdir
= catia_mkdir
,
999 .rmdir
= catia_rmdir
,
1000 .opendir
= catia_opendir
,
1001 .open_fn
= catia_open
,
1002 .rename
= catia_rename
,
1004 .lstat
= catia_lstat
,
1005 .unlink
= catia_unlink
,
1006 .chown
= catia_chown
,
1007 .lchown
= catia_lchown
,
1008 .chdir
= catia_chdir
,
1009 .ntimes
= catia_ntimes
,
1010 .realpath
= catia_realpath
,
1011 .chflags
= catia_chflags
,
1012 .streaminfo
= catia_streaminfo
,
1013 .translate_name
= catia_translate_name
,
1014 .get_nt_acl
= catia_get_nt_acl
,
1015 .chmod_acl
= catia_chmod_acl
,
1016 .sys_acl_get_file
= catia_sys_acl_get_file
,
1017 .sys_acl_set_file
= catia_sys_acl_set_file
,
1018 .sys_acl_delete_def_file
= catia_sys_acl_delete_def_file
,
1019 .getxattr
= catia_getxattr
,
1020 .lgetxattr
= catia_lgetxattr
,
1021 .listxattr
= catia_listxattr
,
1022 .llistxattr
= catia_llistxattr
,
1023 .removexattr
= catia_removexattr
,
1024 .lremovexattr
= catia_lremovexattr
,
1025 .setxattr
= catia_setxattr
,
1026 .lsetxattr
= catia_lsetxattr
,
1029 NTSTATUS
vfs_catia_init(void)
1033 ret
= smb_register_vfs(SMB_VFS_INTERFACE_VERSION
, "catia",
1035 if (!NT_STATUS_IS_OK(ret
))
1038 vfs_catia_debug_level
= debug_add_class("catia");
1039 if (vfs_catia_debug_level
== -1) {
1040 vfs_catia_debug_level
= DBGC_VFS
;
1041 DEBUG(0, ("vfs_catia: Couldn't register custom debugging "
1044 DEBUG(10, ("vfs_catia: Debug class number of "
1045 "'catia': %d\n", vfs_catia_debug_level
));