4 * Implement a fixed mapping of forbidden NT characters in filenames that are
5 * used a lot by the CAD package Catia.
7 * Catia V4 on AIX uses characters like "<*$ a *lot*, all forbidden under
10 * Copyright (C) Volker Lendecke, 2005
11 * Copyright (C) Aravind Srinivasan, 2009
12 * Copyright (C) Guenter Kukkukk, 2013
13 * Copyright (C) Ralph Boehme, 2017
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"
32 #include "lib/util/tevent_unix.h"
33 #include "lib/util/tevent_ntstatus.h"
34 #include "string_replace.h"
36 static int vfs_catia_debug_level
= DBGC_VFS
;
39 #define DBGC_CLASS vfs_catia_debug_level
41 struct share_mapping_entry
{
43 struct share_mapping_entry
*next
;
44 struct char_mappings
**mappings
;
49 const struct catia_cache
* const *busy
;
52 char *orig_base_fname
;
56 static struct share_mapping_entry
*srt_head
= NULL
;
58 static struct share_mapping_entry
*get_srt(connection_struct
*conn
,
59 struct share_mapping_entry
**global
)
61 struct share_mapping_entry
*share
;
63 for (share
= srt_head
; share
!= NULL
; share
= share
->next
) {
64 if (share
->snum
== GLOBAL_SECTION_SNUM
)
67 if (share
->snum
== SNUM(conn
))
74 static struct share_mapping_entry
*add_srt(int snum
, const char **mappings
)
76 struct share_mapping_entry
*sme
= NULL
;
78 sme
= TALLOC_ZERO(NULL
, sizeof(struct share_mapping_entry
));
86 if (mappings
== NULL
) {
91 sme
->mappings
= string_replace_init_map(mappings
);
96 static bool init_mappings(connection_struct
*conn
,
97 struct share_mapping_entry
**selected_out
)
99 const char **mappings
= NULL
;
100 struct share_mapping_entry
*share_level
= NULL
;
101 struct share_mapping_entry
*global
= NULL
;
103 /* check srt cache */
104 share_level
= get_srt(conn
, &global
);
106 *selected_out
= share_level
;
107 return (share_level
->mappings
!= NULL
);
110 /* see if we have a global setting */
113 mappings
= lp_parm_string_list(-1, "catia", "mappings", NULL
);
114 global
= add_srt(GLOBAL_SECTION_SNUM
, mappings
);
117 /* no global setting - what about share level ? */
118 mappings
= lp_parm_string_list(SNUM(conn
), "catia", "mappings", NULL
);
119 share_level
= add_srt(SNUM(conn
), mappings
);
121 if (share_level
->mappings
) {
122 (*selected_out
) = share_level
;
125 if (global
->mappings
) {
126 share_level
->mappings
= global
->mappings
;
127 (*selected_out
) = share_level
;
134 static NTSTATUS
catia_string_replace_allocate(connection_struct
*conn
,
137 enum vfs_translate_direction direction
)
139 struct share_mapping_entry
*selected
;
142 if (!init_mappings(conn
, &selected
)) {
143 /* No mappings found. Just use the old name */
144 *mapped_name
= talloc_strdup(talloc_tos(), name_in
);
147 return NT_STATUS_NO_MEMORY
;
152 status
= string_replace_allocate(conn
,
161 static DIR *catia_opendir(vfs_handle_struct
*handle
,
162 const struct smb_filename
*smb_fname
,
166 char *name_mapped
= NULL
;
169 struct smb_filename
*mapped_smb_fname
= NULL
;
171 status
= catia_string_replace_allocate(handle
->conn
,
172 smb_fname
->base_name
,
174 vfs_translate_to_unix
);
175 if (!NT_STATUS_IS_OK(status
)) {
176 errno
= map_errno_from_nt_status(status
);
180 mapped_smb_fname
= synthetic_smb_fname(talloc_tos(),
185 if (mapped_smb_fname
== NULL
) {
186 TALLOC_FREE(mapped_smb_fname
);
191 ret
= SMB_VFS_NEXT_OPENDIR(handle
, mapped_smb_fname
, mask
, attr
);
193 TALLOC_FREE(name_mapped
);
194 TALLOC_FREE(mapped_smb_fname
);
200 * TRANSLATE_NAME call which converts the given name to
201 * "WINDOWS displayable" name
203 static NTSTATUS
catia_translate_name(struct vfs_handle_struct
*handle
,
204 const char *orig_name
,
205 enum vfs_translate_direction direction
,
211 NTSTATUS status
, ret
;
214 * Copy the supplied name and free the memory for mapped_name,
215 * already allocated by the caller.
216 * We will be allocating new memory for mapped_name in
217 * catia_string_replace_allocate
219 name
= talloc_strdup(talloc_tos(), orig_name
);
222 return NT_STATUS_NO_MEMORY
;
224 status
= catia_string_replace_allocate(handle
->conn
, name
,
225 &mapped_name
, direction
);
228 if (!NT_STATUS_IS_OK(status
)) {
232 ret
= SMB_VFS_NEXT_TRANSLATE_NAME(handle
, mapped_name
, direction
,
233 mem_ctx
, pmapped_name
);
235 if (NT_STATUS_EQUAL(ret
, NT_STATUS_NONE_MAPPED
)) {
236 *pmapped_name
= talloc_move(mem_ctx
, &mapped_name
);
237 /* we need to return the former translation result here */
240 TALLOC_FREE(mapped_name
);
246 #define CATIA_DEBUG_CC(lvl, cc, fsp) \
247 catia_debug_cc((lvl), (cc), (fsp), __location__);
249 static void catia_debug_cc(int lvl
,
250 struct catia_cache
*cc
,
252 const char *location
)
254 DEBUG(lvl
, ("%s: cc [0x%p] cc->busy [0x%p] "
256 "fsp [0x%p] fsp name [%s] "
259 "orig_base_fname [%s] "
263 cc
->is_fsp_ext
? "yes" : "no",
264 fsp
, fsp_str_dbg(fsp
),
265 cc
->orig_fname
, cc
->fname
,
266 cc
->orig_base_fname
, cc
->base_fname
));
269 static void catia_free_cc(struct catia_cache
**_cc
,
270 vfs_handle_struct
*handle
,
273 struct catia_cache
*cc
= *_cc
;
275 if (cc
->is_fsp_ext
) {
276 VFS_REMOVE_FSP_EXTENSION(handle
, fsp
);
285 static struct catia_cache
*catia_validate_and_apply_cc(
286 vfs_handle_struct
*handle
,
288 const struct catia_cache
* const *busy
,
289 bool *make_tmp_cache
)
291 struct catia_cache
*cc
= NULL
;
293 *make_tmp_cache
= false;
295 cc
= (struct catia_cache
*)VFS_FETCH_FSP_EXTENSION(handle
, fsp
);
300 if (cc
->busy
!= NULL
) {
301 if (cc
->busy
== busy
) {
302 /* This should never happen */
303 CATIA_DEBUG_CC(0, cc
, fsp
);
304 smb_panic(__location__
);
308 * Recursion. Validate names, the names in the fsp's should be
309 * the translated names we had set.
312 if ((cc
->fname
!= fsp
->fsp_name
->base_name
)
314 ((fsp
->base_fsp
!= NULL
) &&
315 (cc
->base_fname
!= fsp
->base_fsp
->fsp_name
->base_name
)))
317 CATIA_DEBUG_CC(10, cc
, fsp
);
320 * Names changed. Setting don't expose the cache on the
321 * fsp and ask the caller to create a temporary cache.
323 *make_tmp_cache
= true;
328 * Ok, a validated cache while in a recursion, just let the
329 * caller detect that cc->busy is != busy and there's
330 * nothing else to do.
332 CATIA_DEBUG_CC(10, cc
, fsp
);
336 /* Not in a recursion */
338 if ((cc
->orig_fname
!= fsp
->fsp_name
->base_name
)
340 ((fsp
->base_fsp
!= NULL
) &&
341 (cc
->orig_base_fname
!= fsp
->base_fsp
->fsp_name
->base_name
)))
344 * fsp names changed, this can happen in an rename op.
345 * Trigger recreation as a full fledged fsp extension.
348 CATIA_DEBUG_CC(10, cc
, fsp
);
349 catia_free_cc(&cc
, handle
, fsp
);
355 * Ok, we found a valid cache entry, no recursion. Just set translated
356 * names from the cache and mark the cc as busy.
358 fsp
->fsp_name
->base_name
= cc
->fname
;
359 if (fsp
->base_fsp
!= NULL
) {
360 fsp
->base_fsp
->fsp_name
->base_name
= cc
->base_fname
;
364 CATIA_DEBUG_CC(10, cc
, fsp
);
368 #define CATIA_FETCH_FSP_PRE_NEXT(mem_ctx, handle, fsp, _cc) \
369 catia_fetch_fsp_pre_next((mem_ctx), (handle), (fsp), (_cc), __func__);
371 static int catia_fetch_fsp_pre_next(TALLOC_CTX
*mem_ctx
,
372 vfs_handle_struct
*handle
,
374 struct catia_cache
**_cc
,
375 const char *function
)
377 const struct catia_cache
* const *busy
=
378 (const struct catia_cache
* const *)_cc
;
379 struct catia_cache
*cc
= NULL
;
381 bool make_tmp_cache
= false;
385 DBG_DEBUG("Called from [%s]\n", function
);
387 cc
= catia_validate_and_apply_cc(handle
,
392 if (cc
->busy
!= busy
) {
399 if (!make_tmp_cache
) {
400 cc
= VFS_ADD_FSP_EXTENSION(
401 handle
, fsp
, struct catia_cache
, NULL
);
405 *cc
= (struct catia_cache
) {
409 mem_ctx
= VFS_MEMCTX_FSP_EXTENSION(handle
, fsp
);
410 if (mem_ctx
== NULL
) {
411 DBG_ERR("VFS_MEMCTX_FSP_EXTENSION failed\n");
412 catia_free_cc(&cc
, handle
, fsp
);
416 cc
= talloc_zero(mem_ctx
, struct catia_cache
);
424 status
= catia_string_replace_allocate(handle
->conn
,
425 fsp
->fsp_name
->base_name
,
427 vfs_translate_to_unix
);
428 if (!NT_STATUS_IS_OK(status
)) {
429 catia_free_cc(&cc
, handle
, fsp
);
430 errno
= map_errno_from_nt_status(status
);
433 talloc_steal(mem_ctx
, cc
->fname
);
435 if (fsp
->base_fsp
!= NULL
) {
436 status
= catia_string_replace_allocate(
438 fsp
->base_fsp
->fsp_name
->base_name
,
440 vfs_translate_to_unix
);
441 if (!NT_STATUS_IS_OK(status
)) {
442 catia_free_cc(&cc
, handle
, fsp
);
443 errno
= map_errno_from_nt_status(status
);
446 talloc_steal(mem_ctx
, cc
->base_fname
);
449 cc
->orig_fname
= fsp
->fsp_name
->base_name
;
450 fsp
->fsp_name
->base_name
= cc
->fname
;
452 if (fsp
->base_fsp
!= NULL
) {
453 cc
->orig_base_fname
= fsp
->base_fsp
->fsp_name
->base_name
;
454 fsp
->base_fsp
->fsp_name
->base_name
= cc
->base_fname
;
458 CATIA_DEBUG_CC(10, cc
, fsp
);
465 #define CATIA_FETCH_FSP_POST_NEXT(_cc, fsp) do { \
466 int saved_errno = errno; \
467 catia_fetch_fsp_post_next((_cc), (fsp), __func__); \
468 errno = saved_errno; \
471 static void catia_fetch_fsp_post_next(struct catia_cache
**_cc
,
473 const char *function
)
475 const struct catia_cache
* const *busy
=
476 (const struct catia_cache
* const *)_cc
;
477 struct catia_cache
*cc
= *_cc
;
479 DBG_DEBUG("Called from [%s]\n", function
);
483 * This can happen when recursing in the VFS on the fsp when the
484 * pre_next func noticed the recursion and set out cc pointer to
490 if (cc
->busy
!= busy
) {
491 CATIA_DEBUG_CC(0, cc
, fsp
);
492 smb_panic(__location__
);
499 fsp
->fsp_name
->base_name
= cc
->orig_fname
;
500 if (fsp
->base_fsp
!= NULL
) {
501 fsp
->base_fsp
->fsp_name
->base_name
= cc
->orig_base_fname
;
504 CATIA_DEBUG_CC(10, cc
, fsp
);
506 if (!cc
->is_fsp_ext
) {
513 static int catia_open(vfs_handle_struct
*handle
,
514 struct smb_filename
*smb_fname
,
519 struct catia_cache
*cc
= NULL
;
520 char *orig_smb_fname
= smb_fname
->base_name
;
521 char *mapped_smb_fname
= NULL
;
525 status
= catia_string_replace_allocate(handle
->conn
,
526 smb_fname
->base_name
,
528 vfs_translate_to_unix
);
529 if (!NT_STATUS_IS_OK(status
)) {
533 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
535 TALLOC_FREE(mapped_smb_fname
);
539 smb_fname
->base_name
= mapped_smb_fname
;
540 ret
= SMB_VFS_NEXT_OPEN(handle
, smb_fname
, fsp
, flags
, mode
);
541 smb_fname
->base_name
= orig_smb_fname
;
543 TALLOC_FREE(mapped_smb_fname
);
544 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
549 static int catia_rename(vfs_handle_struct
*handle
,
550 const struct smb_filename
*smb_fname_src
,
551 const struct smb_filename
*smb_fname_dst
)
553 TALLOC_CTX
*ctx
= talloc_tos();
554 struct smb_filename
*smb_fname_src_tmp
= NULL
;
555 struct smb_filename
*smb_fname_dst_tmp
= NULL
;
556 char *src_name_mapped
= NULL
;
557 char *dst_name_mapped
= NULL
;
561 status
= catia_string_replace_allocate(handle
->conn
,
562 smb_fname_src
->base_name
,
563 &src_name_mapped
, vfs_translate_to_unix
);
564 if (!NT_STATUS_IS_OK(status
)) {
565 errno
= map_errno_from_nt_status(status
);
569 status
= catia_string_replace_allocate(handle
->conn
,
570 smb_fname_dst
->base_name
,
571 &dst_name_mapped
, vfs_translate_to_unix
);
572 if (!NT_STATUS_IS_OK(status
)) {
573 errno
= map_errno_from_nt_status(status
);
577 /* Setup temporary smb_filename structs. */
578 smb_fname_src_tmp
= cp_smb_filename(ctx
, smb_fname_src
);
579 if (smb_fname_src_tmp
== NULL
) {
584 smb_fname_dst_tmp
= cp_smb_filename(ctx
, smb_fname_dst
);
585 if (smb_fname_dst_tmp
== NULL
) {
590 smb_fname_src_tmp
->base_name
= src_name_mapped
;
591 smb_fname_dst_tmp
->base_name
= dst_name_mapped
;
592 DEBUG(10, ("converted old name: %s\n",
593 smb_fname_str_dbg(smb_fname_src_tmp
)));
594 DEBUG(10, ("converted new name: %s\n",
595 smb_fname_str_dbg(smb_fname_dst_tmp
)));
597 ret
= SMB_VFS_NEXT_RENAME(handle
, smb_fname_src_tmp
,
600 TALLOC_FREE(src_name_mapped
);
601 TALLOC_FREE(dst_name_mapped
);
602 TALLOC_FREE(smb_fname_src_tmp
);
603 TALLOC_FREE(smb_fname_dst_tmp
);
607 static int catia_stat(vfs_handle_struct
*handle
,
608 struct smb_filename
*smb_fname
)
615 status
= catia_string_replace_allocate(handle
->conn
,
616 smb_fname
->base_name
,
617 &name
, vfs_translate_to_unix
);
618 if (!NT_STATUS_IS_OK(status
)) {
619 errno
= map_errno_from_nt_status(status
);
623 tmp_base_name
= smb_fname
->base_name
;
624 smb_fname
->base_name
= name
;
626 ret
= SMB_VFS_NEXT_STAT(handle
, smb_fname
);
627 smb_fname
->base_name
= tmp_base_name
;
633 static int catia_lstat(vfs_handle_struct
*handle
,
634 struct smb_filename
*smb_fname
)
641 status
= catia_string_replace_allocate(handle
->conn
,
642 smb_fname
->base_name
,
643 &name
, vfs_translate_to_unix
);
644 if (!NT_STATUS_IS_OK(status
)) {
645 errno
= map_errno_from_nt_status(status
);
649 tmp_base_name
= smb_fname
->base_name
;
650 smb_fname
->base_name
= name
;
652 ret
= SMB_VFS_NEXT_LSTAT(handle
, smb_fname
);
653 smb_fname
->base_name
= tmp_base_name
;
659 static int catia_unlink(vfs_handle_struct
*handle
,
660 const struct smb_filename
*smb_fname
)
662 struct smb_filename
*smb_fname_tmp
= NULL
;
667 status
= catia_string_replace_allocate(handle
->conn
,
668 smb_fname
->base_name
,
669 &name
, vfs_translate_to_unix
);
670 if (!NT_STATUS_IS_OK(status
)) {
671 errno
= map_errno_from_nt_status(status
);
675 /* Setup temporary smb_filename structs. */
676 smb_fname_tmp
= cp_smb_filename(talloc_tos(), smb_fname
);
677 if (smb_fname_tmp
== NULL
) {
682 smb_fname_tmp
->base_name
= name
;
683 ret
= SMB_VFS_NEXT_UNLINK(handle
, smb_fname_tmp
);
684 TALLOC_FREE(smb_fname_tmp
);
690 static int catia_chown(vfs_handle_struct
*handle
,
691 const struct smb_filename
*smb_fname
,
699 struct smb_filename
*catia_smb_fname
= NULL
;
701 status
= catia_string_replace_allocate(handle
->conn
,
702 smb_fname
->base_name
,
704 vfs_translate_to_unix
);
705 if (!NT_STATUS_IS_OK(status
)) {
706 errno
= map_errno_from_nt_status(status
);
709 catia_smb_fname
= synthetic_smb_fname(talloc_tos(),
714 if (catia_smb_fname
== NULL
) {
720 ret
= SMB_VFS_NEXT_CHOWN(handle
, catia_smb_fname
, uid
, gid
);
723 TALLOC_FREE(catia_smb_fname
);
728 static int catia_lchown(vfs_handle_struct
*handle
,
729 const struct smb_filename
*smb_fname
,
737 struct smb_filename
*catia_smb_fname
= NULL
;
739 status
= catia_string_replace_allocate(handle
->conn
,
740 smb_fname
->base_name
,
742 vfs_translate_to_unix
);
743 if (!NT_STATUS_IS_OK(status
)) {
744 errno
= map_errno_from_nt_status(status
);
747 catia_smb_fname
= synthetic_smb_fname(talloc_tos(),
752 if (catia_smb_fname
== NULL
) {
758 ret
= SMB_VFS_NEXT_LCHOWN(handle
, catia_smb_fname
, uid
, gid
);
761 TALLOC_FREE(catia_smb_fname
);
766 static int catia_chmod(vfs_handle_struct
*handle
,
767 const struct smb_filename
*smb_fname
,
774 struct smb_filename
*catia_smb_fname
= NULL
;
776 status
= catia_string_replace_allocate(handle
->conn
,
777 smb_fname
->base_name
,
779 vfs_translate_to_unix
);
780 if (!NT_STATUS_IS_OK(status
)) {
781 errno
= map_errno_from_nt_status(status
);
784 catia_smb_fname
= synthetic_smb_fname(talloc_tos(),
789 if (catia_smb_fname
== NULL
) {
795 ret
= SMB_VFS_NEXT_CHMOD(handle
, catia_smb_fname
, mode
);
798 TALLOC_FREE(catia_smb_fname
);
803 static int catia_rmdir(vfs_handle_struct
*handle
,
804 const struct smb_filename
*smb_fname
)
809 struct smb_filename
*catia_smb_fname
= NULL
;
811 status
= catia_string_replace_allocate(handle
->conn
,
812 smb_fname
->base_name
,
814 vfs_translate_to_unix
);
815 if (!NT_STATUS_IS_OK(status
)) {
816 errno
= map_errno_from_nt_status(status
);
819 catia_smb_fname
= synthetic_smb_fname(talloc_tos(),
824 if (catia_smb_fname
== NULL
) {
830 ret
= SMB_VFS_NEXT_RMDIR(handle
, catia_smb_fname
);
832 TALLOC_FREE(catia_smb_fname
);
837 static int catia_mkdir(vfs_handle_struct
*handle
,
838 const struct smb_filename
*smb_fname
,
844 struct smb_filename
*catia_smb_fname
= NULL
;
846 status
= catia_string_replace_allocate(handle
->conn
,
847 smb_fname
->base_name
,
849 vfs_translate_to_unix
);
850 if (!NT_STATUS_IS_OK(status
)) {
851 errno
= map_errno_from_nt_status(status
);
854 catia_smb_fname
= synthetic_smb_fname(talloc_tos(),
859 if (catia_smb_fname
== NULL
) {
865 ret
= SMB_VFS_NEXT_MKDIR(handle
, catia_smb_fname
, mode
);
867 TALLOC_FREE(catia_smb_fname
);
872 static int catia_chdir(vfs_handle_struct
*handle
,
873 const struct smb_filename
*smb_fname
)
876 struct smb_filename
*catia_smb_fname
= NULL
;
880 status
= catia_string_replace_allocate(handle
->conn
,
881 smb_fname
->base_name
,
883 vfs_translate_to_unix
);
884 if (!NT_STATUS_IS_OK(status
)) {
885 errno
= map_errno_from_nt_status(status
);
889 catia_smb_fname
= synthetic_smb_fname(talloc_tos(),
894 if (catia_smb_fname
== NULL
) {
899 ret
= SMB_VFS_NEXT_CHDIR(handle
, catia_smb_fname
);
901 TALLOC_FREE(catia_smb_fname
);
906 static int catia_ntimes(vfs_handle_struct
*handle
,
907 const struct smb_filename
*smb_fname
,
908 struct smb_file_time
*ft
)
910 struct smb_filename
*smb_fname_tmp
= NULL
;
915 status
= catia_string_replace_allocate(handle
->conn
,
916 smb_fname
->base_name
,
917 &name
, vfs_translate_to_unix
);
918 if (!NT_STATUS_IS_OK(status
)) {
919 errno
= map_errno_from_nt_status(status
);
923 smb_fname_tmp
= cp_smb_filename(talloc_tos(), smb_fname
);
924 if (smb_fname_tmp
== NULL
) {
929 smb_fname_tmp
->base_name
= name
;
930 ret
= SMB_VFS_NEXT_NTIMES(handle
, smb_fname_tmp
, ft
);
932 TALLOC_FREE(smb_fname_tmp
);
937 static struct smb_filename
*
938 catia_realpath(vfs_handle_struct
*handle
,
940 const struct smb_filename
*smb_fname
)
942 char *mapped_name
= NULL
;
943 struct smb_filename
*catia_smb_fname
= NULL
;
944 struct smb_filename
*return_fname
= NULL
;
947 status
= catia_string_replace_allocate(handle
->conn
,
948 smb_fname
->base_name
,
949 &mapped_name
, vfs_translate_to_unix
);
950 if (!NT_STATUS_IS_OK(status
)) {
951 errno
= map_errno_from_nt_status(status
);
955 catia_smb_fname
= synthetic_smb_fname(talloc_tos(),
960 if (catia_smb_fname
== NULL
) {
961 TALLOC_FREE(mapped_name
);
965 return_fname
= SMB_VFS_NEXT_REALPATH(handle
, ctx
, catia_smb_fname
);
966 TALLOC_FREE(mapped_name
);
967 TALLOC_FREE(catia_smb_fname
);
971 static int catia_chflags(struct vfs_handle_struct
*handle
,
972 const struct smb_filename
*smb_fname
,
976 struct smb_filename
*catia_smb_fname
= NULL
;
980 status
= catia_string_replace_allocate(handle
->conn
,
981 smb_fname
->base_name
,
983 vfs_translate_to_unix
);
984 if (!NT_STATUS_IS_OK(status
)) {
985 errno
= map_errno_from_nt_status(status
);
988 catia_smb_fname
= synthetic_smb_fname(talloc_tos(),
993 if (catia_smb_fname
== NULL
) {
999 ret
= SMB_VFS_NEXT_CHFLAGS(handle
, catia_smb_fname
, flags
);
1001 TALLOC_FREE(catia_smb_fname
);
1007 catia_streaminfo(struct vfs_handle_struct
*handle
,
1008 struct files_struct
*fsp
,
1009 const struct smb_filename
*smb_fname
,
1010 TALLOC_CTX
*mem_ctx
,
1011 unsigned int *_num_streams
,
1012 struct stream_struct
**_streams
)
1014 char *mapped_name
= NULL
;
1017 struct smb_filename
*catia_smb_fname
= NULL
;
1018 unsigned int num_streams
= 0;
1019 struct stream_struct
*streams
= NULL
;
1024 status
= catia_string_replace_allocate(handle
->conn
,
1025 smb_fname
->base_name
,
1027 vfs_translate_to_unix
);
1028 if (!NT_STATUS_IS_OK(status
)) {
1029 errno
= map_errno_from_nt_status(status
);
1033 catia_smb_fname
= synthetic_smb_fname(talloc_tos(),
1038 if (catia_smb_fname
== NULL
) {
1039 TALLOC_FREE(mapped_name
);
1040 return NT_STATUS_NO_MEMORY
;
1043 status
= SMB_VFS_NEXT_STREAMINFO(handle
, fsp
, catia_smb_fname
,
1044 mem_ctx
, &num_streams
, &streams
);
1045 TALLOC_FREE(mapped_name
);
1046 TALLOC_FREE(catia_smb_fname
);
1047 if (!NT_STATUS_IS_OK(status
)) {
1052 * Translate stream names just like the base names
1054 for (i
= 0; i
< num_streams
; i
++) {
1056 * Strip ":" prefix and ":$DATA" suffix to get a
1057 * "pure" stream name and only translate that.
1059 void *old_ptr
= streams
[i
].name
;
1060 char *stream_name
= streams
[i
].name
+ 1;
1061 char *stream_type
= strrchr_m(stream_name
, ':');
1063 if (stream_type
!= NULL
) {
1064 *stream_type
= '\0';
1068 status
= catia_string_replace_allocate(handle
->conn
, stream_name
,
1069 &mapped_name
, vfs_translate_to_windows
);
1070 if (!NT_STATUS_IS_OK(status
)) {
1071 TALLOC_FREE(streams
);
1075 if (stream_type
!= NULL
) {
1076 streams
[i
].name
= talloc_asprintf(streams
, ":%s:%s",
1077 mapped_name
, stream_type
);
1079 streams
[i
].name
= talloc_asprintf(streams
, ":%s",
1082 TALLOC_FREE(mapped_name
);
1083 TALLOC_FREE(old_ptr
);
1084 if (streams
[i
].name
== NULL
) {
1085 TALLOC_FREE(streams
);
1086 return NT_STATUS_NO_MEMORY
;
1090 *_num_streams
= num_streams
;
1091 *_streams
= streams
;
1092 return NT_STATUS_OK
;
1096 catia_get_nt_acl(struct vfs_handle_struct
*handle
,
1097 const struct smb_filename
*smb_fname
,
1098 uint32_t security_info
,
1099 TALLOC_CTX
*mem_ctx
,
1100 struct security_descriptor
**ppdesc
)
1102 char *mapped_name
= NULL
;
1103 const char *path
= smb_fname
->base_name
;
1104 struct smb_filename
*mapped_smb_fname
= NULL
;
1107 status
= catia_string_replace_allocate(handle
->conn
,
1108 path
, &mapped_name
, vfs_translate_to_unix
);
1109 if (!NT_STATUS_IS_OK(status
)) {
1110 errno
= map_errno_from_nt_status(status
);
1113 mapped_smb_fname
= synthetic_smb_fname(talloc_tos(),
1118 if (mapped_smb_fname
== NULL
) {
1119 TALLOC_FREE(mapped_name
);
1120 return NT_STATUS_NO_MEMORY
;
1123 status
= SMB_VFS_NEXT_GET_NT_ACL(handle
, mapped_smb_fname
,
1124 security_info
, mem_ctx
, ppdesc
);
1125 TALLOC_FREE(mapped_name
);
1126 TALLOC_FREE(mapped_smb_fname
);
1132 catia_chmod_acl(vfs_handle_struct
*handle
,
1133 const struct smb_filename
*smb_fname
,
1136 char *mapped_name
= NULL
;
1137 struct smb_filename
*mapped_smb_fname
= NULL
;
1142 status
= catia_string_replace_allocate(handle
->conn
,
1143 smb_fname
->base_name
,
1145 vfs_translate_to_unix
);
1146 if (!NT_STATUS_IS_OK(status
)) {
1147 errno
= map_errno_from_nt_status(status
);
1151 mapped_smb_fname
= synthetic_smb_fname(talloc_tos(),
1156 if (mapped_smb_fname
== NULL
) {
1157 TALLOC_FREE(mapped_name
);
1161 ret
= SMB_VFS_NEXT_CHMOD_ACL(handle
, mapped_smb_fname
, mode
);
1162 saved_errno
= errno
;
1163 TALLOC_FREE(mapped_name
);
1164 TALLOC_FREE(mapped_smb_fname
);
1165 errno
= saved_errno
;
1170 catia_sys_acl_get_file(vfs_handle_struct
*handle
,
1171 const struct smb_filename
*smb_fname
,
1172 SMB_ACL_TYPE_T type
,
1173 TALLOC_CTX
*mem_ctx
)
1175 char *mapped_name
= NULL
;
1176 struct smb_filename
*mapped_smb_fname
= NULL
;
1179 int saved_errno
= 0;
1181 status
= catia_string_replace_allocate(handle
->conn
,
1182 smb_fname
->base_name
,
1184 vfs_translate_to_unix
);
1185 if (!NT_STATUS_IS_OK(status
)) {
1186 errno
= map_errno_from_nt_status(status
);
1187 return (SMB_ACL_T
)NULL
;
1190 mapped_smb_fname
= synthetic_smb_fname(talloc_tos(),
1195 if (mapped_smb_fname
== NULL
) {
1196 TALLOC_FREE(mapped_name
);
1198 return (SMB_ACL_T
)NULL
;
1201 ret
= SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle
, mapped_smb_fname
,
1203 if (ret
== (SMB_ACL_T
)NULL
) {
1204 saved_errno
= errno
;
1206 TALLOC_FREE(mapped_smb_fname
);
1207 TALLOC_FREE(mapped_name
);
1208 if (saved_errno
!= 0) {
1209 errno
= saved_errno
;
1215 catia_sys_acl_set_file(vfs_handle_struct
*handle
,
1216 const struct smb_filename
*smb_fname
,
1217 SMB_ACL_TYPE_T type
,
1220 struct smb_filename
*mapped_smb_fname
= NULL
;
1221 int saved_errno
= 0;
1222 char *mapped_name
= NULL
;
1226 status
= catia_string_replace_allocate(handle
->conn
,
1227 smb_fname
->base_name
,
1229 vfs_translate_to_unix
);
1230 if (!NT_STATUS_IS_OK(status
)) {
1231 errno
= map_errno_from_nt_status(status
);
1235 mapped_smb_fname
= synthetic_smb_fname(talloc_tos(),
1240 if (mapped_smb_fname
== NULL
) {
1241 TALLOC_FREE(mapped_name
);
1246 ret
= SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle
, mapped_smb_fname
,
1249 saved_errno
= errno
;
1251 TALLOC_FREE(mapped_smb_fname
);
1252 TALLOC_FREE(mapped_name
);
1253 if (saved_errno
!= 0) {
1254 errno
= saved_errno
;
1260 catia_sys_acl_delete_def_file(vfs_handle_struct
*handle
,
1261 const struct smb_filename
*smb_fname
)
1263 struct smb_filename
*mapped_smb_fname
= NULL
;
1264 int saved_errno
= 0;
1265 char *mapped_name
= NULL
;
1269 status
= catia_string_replace_allocate(handle
->conn
,
1270 smb_fname
->base_name
,
1272 vfs_translate_to_unix
);
1273 if (!NT_STATUS_IS_OK(status
)) {
1274 errno
= map_errno_from_nt_status(status
);
1278 mapped_smb_fname
= synthetic_smb_fname(talloc_tos(),
1283 if (mapped_smb_fname
== NULL
) {
1284 TALLOC_FREE(mapped_name
);
1288 ret
= SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle
, mapped_smb_fname
);
1290 saved_errno
= errno
;
1292 TALLOC_FREE(mapped_smb_fname
);
1293 TALLOC_FREE(mapped_name
);
1294 if (saved_errno
!= 0) {
1295 errno
= saved_errno
;
1301 catia_getxattr(vfs_handle_struct
*handle
,
1302 const struct smb_filename
*smb_fname
,
1307 struct smb_filename
*mapped_smb_fname
= NULL
;
1308 char *mapped_name
= NULL
;
1309 char *mapped_ea_name
= NULL
;
1312 int saved_errno
= 0;
1314 status
= catia_string_replace_allocate(handle
->conn
,
1315 smb_fname
->base_name
,
1317 vfs_translate_to_unix
);
1318 if (!NT_STATUS_IS_OK(status
)) {
1319 errno
= map_errno_from_nt_status(status
);
1323 status
= catia_string_replace_allocate(handle
->conn
,
1324 name
, &mapped_ea_name
, vfs_translate_to_unix
);
1325 if (!NT_STATUS_IS_OK(status
)) {
1326 TALLOC_FREE(mapped_name
);
1327 errno
= map_errno_from_nt_status(status
);
1331 mapped_smb_fname
= synthetic_smb_fname(talloc_tos(),
1336 if (mapped_smb_fname
== NULL
) {
1337 TALLOC_FREE(mapped_name
);
1338 TALLOC_FREE(mapped_ea_name
);
1343 ret
= SMB_VFS_NEXT_GETXATTR(handle
, mapped_smb_fname
,
1344 mapped_ea_name
, value
, size
);
1346 saved_errno
= errno
;
1348 TALLOC_FREE(mapped_name
);
1349 TALLOC_FREE(mapped_ea_name
);
1350 TALLOC_FREE(mapped_smb_fname
);
1351 if (saved_errno
!= 0) {
1352 errno
= saved_errno
;
1359 catia_listxattr(vfs_handle_struct
*handle
,
1360 const struct smb_filename
*smb_fname
,
1361 char *list
, size_t size
)
1363 struct smb_filename
*mapped_smb_fname
= NULL
;
1364 char *mapped_name
= NULL
;
1367 int saved_errno
= 0;
1369 status
= catia_string_replace_allocate(handle
->conn
,
1370 smb_fname
->base_name
,
1372 vfs_translate_to_unix
);
1373 if (!NT_STATUS_IS_OK(status
)) {
1374 errno
= map_errno_from_nt_status(status
);
1378 mapped_smb_fname
= synthetic_smb_fname(talloc_tos(),
1383 if (mapped_smb_fname
== NULL
) {
1384 TALLOC_FREE(mapped_name
);
1389 ret
= SMB_VFS_NEXT_LISTXATTR(handle
, mapped_smb_fname
, list
, size
);
1391 saved_errno
= errno
;
1393 TALLOC_FREE(mapped_name
);
1394 TALLOC_FREE(mapped_smb_fname
);
1395 if (saved_errno
!= 0) {
1396 errno
= saved_errno
;
1403 catia_removexattr(vfs_handle_struct
*handle
,
1404 const struct smb_filename
*smb_fname
,
1407 struct smb_filename
*mapped_smb_fname
= NULL
;
1408 char *mapped_name
= NULL
;
1409 char *mapped_ea_name
= NULL
;
1412 int saved_errno
= 0;
1414 status
= catia_string_replace_allocate(handle
->conn
,
1415 smb_fname
->base_name
,
1417 vfs_translate_to_unix
);
1418 if (!NT_STATUS_IS_OK(status
)) {
1419 errno
= map_errno_from_nt_status(status
);
1423 status
= catia_string_replace_allocate(handle
->conn
,
1424 name
, &mapped_ea_name
, vfs_translate_to_unix
);
1425 if (!NT_STATUS_IS_OK(status
)) {
1426 TALLOC_FREE(mapped_name
);
1427 errno
= map_errno_from_nt_status(status
);
1431 mapped_smb_fname
= synthetic_smb_fname(talloc_tos(),
1436 if (mapped_smb_fname
== NULL
) {
1437 TALLOC_FREE(mapped_name
);
1438 TALLOC_FREE(mapped_ea_name
);
1443 ret
= SMB_VFS_NEXT_REMOVEXATTR(handle
, mapped_smb_fname
,
1446 saved_errno
= errno
;
1448 TALLOC_FREE(mapped_name
);
1449 TALLOC_FREE(mapped_ea_name
);
1450 TALLOC_FREE(mapped_smb_fname
);
1451 if (saved_errno
!= 0) {
1452 errno
= saved_errno
;
1459 catia_setxattr(vfs_handle_struct
*handle
,
1460 const struct smb_filename
*smb_fname
,
1466 struct smb_filename
*mapped_smb_fname
= NULL
;
1467 char *mapped_name
= NULL
;
1468 char *mapped_ea_name
= NULL
;
1471 int saved_errno
= 0;
1473 status
= catia_string_replace_allocate(handle
->conn
,
1474 smb_fname
->base_name
,
1476 vfs_translate_to_unix
);
1477 if (!NT_STATUS_IS_OK(status
)) {
1478 errno
= map_errno_from_nt_status(status
);
1482 status
= catia_string_replace_allocate(handle
->conn
,
1483 name
, &mapped_ea_name
, vfs_translate_to_unix
);
1484 if (!NT_STATUS_IS_OK(status
)) {
1485 TALLOC_FREE(mapped_name
);
1486 errno
= map_errno_from_nt_status(status
);
1490 mapped_smb_fname
= synthetic_smb_fname(talloc_tos(),
1495 if (mapped_smb_fname
== NULL
) {
1496 TALLOC_FREE(mapped_name
);
1497 TALLOC_FREE(mapped_ea_name
);
1502 ret
= SMB_VFS_NEXT_SETXATTR(handle
, mapped_smb_fname
, mapped_ea_name
,
1503 value
, size
, flags
);
1505 saved_errno
= errno
;
1507 TALLOC_FREE(mapped_name
);
1508 TALLOC_FREE(mapped_ea_name
);
1509 TALLOC_FREE(mapped_smb_fname
);
1510 if (saved_errno
!= 0) {
1511 errno
= saved_errno
;
1517 static int catia_fstat(vfs_handle_struct
*handle
,
1519 SMB_STRUCT_STAT
*sbuf
)
1521 struct catia_cache
*cc
= NULL
;
1524 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
1529 ret
= SMB_VFS_NEXT_FSTAT(handle
, fsp
, sbuf
);
1531 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
1536 static ssize_t
catia_pread(vfs_handle_struct
*handle
,
1537 files_struct
*fsp
, void *data
,
1538 size_t n
, off_t offset
)
1540 struct catia_cache
*cc
= NULL
;
1544 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
1549 result
= SMB_VFS_NEXT_PREAD(handle
, fsp
, data
, n
, offset
);
1551 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
1556 static ssize_t
catia_pwrite(vfs_handle_struct
*handle
,
1557 files_struct
*fsp
, const void *data
,
1558 size_t n
, off_t offset
)
1560 struct catia_cache
*cc
= NULL
;
1564 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
1569 result
= SMB_VFS_NEXT_PWRITE(handle
, fsp
, data
, n
, offset
);
1571 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
1576 static int catia_ftruncate(struct vfs_handle_struct
*handle
,
1577 struct files_struct
*fsp
,
1580 struct catia_cache
*cc
= NULL
;
1583 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
1588 ret
= SMB_VFS_NEXT_FTRUNCATE(handle
, fsp
, offset
);
1590 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
1595 static int catia_fallocate(struct vfs_handle_struct
*handle
,
1596 struct files_struct
*fsp
,
1601 struct catia_cache
*cc
= NULL
;
1604 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
1609 ret
= SMB_VFS_NEXT_FALLOCATE(handle
, fsp
, mode
, offset
, len
);
1611 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
1616 static ssize_t
catia_fgetxattr(struct vfs_handle_struct
*handle
,
1617 struct files_struct
*fsp
,
1622 char *mapped_xattr_name
= NULL
;
1626 status
= catia_string_replace_allocate(handle
->conn
,
1627 name
, &mapped_xattr_name
,
1628 vfs_translate_to_unix
);
1629 if (!NT_STATUS_IS_OK(status
)) {
1630 errno
= map_errno_from_nt_status(status
);
1634 result
= SMB_VFS_NEXT_FGETXATTR(handle
, fsp
, mapped_xattr_name
,
1637 TALLOC_FREE(mapped_xattr_name
);
1642 static ssize_t
catia_flistxattr(struct vfs_handle_struct
*handle
,
1643 struct files_struct
*fsp
,
1647 struct catia_cache
*cc
= NULL
;
1651 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
1656 result
= SMB_VFS_NEXT_FLISTXATTR(handle
, fsp
, list
, size
);
1658 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
1663 static int catia_fremovexattr(struct vfs_handle_struct
*handle
,
1664 struct files_struct
*fsp
,
1667 char *mapped_name
= NULL
;
1671 status
= catia_string_replace_allocate(handle
->conn
,
1672 name
, &mapped_name
, vfs_translate_to_unix
);
1673 if (!NT_STATUS_IS_OK(status
)) {
1674 errno
= map_errno_from_nt_status(status
);
1678 ret
= SMB_VFS_NEXT_FREMOVEXATTR(handle
, fsp
, mapped_name
);
1680 TALLOC_FREE(mapped_name
);
1685 static int catia_fsetxattr(struct vfs_handle_struct
*handle
,
1686 struct files_struct
*fsp
,
1692 char *mapped_xattr_name
= NULL
;
1696 status
= catia_string_replace_allocate(
1697 handle
->conn
, name
, &mapped_xattr_name
, vfs_translate_to_unix
);
1698 if (!NT_STATUS_IS_OK(status
)) {
1699 errno
= map_errno_from_nt_status(status
);
1703 ret
= SMB_VFS_NEXT_FSETXATTR(handle
, fsp
, mapped_xattr_name
,
1704 value
, size
, flags
);
1706 TALLOC_FREE(mapped_xattr_name
);
1711 static SMB_ACL_T
catia_sys_acl_get_fd(vfs_handle_struct
*handle
,
1713 TALLOC_CTX
*mem_ctx
)
1715 struct catia_cache
*cc
= NULL
;
1716 struct smb_acl_t
*result
= NULL
;
1719 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
1724 result
= SMB_VFS_NEXT_SYS_ACL_GET_FD(handle
, fsp
, mem_ctx
);
1726 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
1731 static int catia_sys_acl_blob_get_fd(vfs_handle_struct
*handle
,
1733 TALLOC_CTX
*mem_ctx
,
1734 char **blob_description
,
1737 struct catia_cache
*cc
= NULL
;
1740 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
1745 ret
= SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle
, fsp
, mem_ctx
,
1746 blob_description
, blob
);
1748 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
1753 static int catia_sys_acl_set_fd(vfs_handle_struct
*handle
,
1757 struct catia_cache
*cc
= NULL
;
1760 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
1765 ret
= SMB_VFS_NEXT_SYS_ACL_SET_FD(handle
, fsp
, theacl
);
1767 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
1772 static int catia_fchmod_acl(vfs_handle_struct
*handle
,
1776 struct catia_cache
*cc
= NULL
;
1779 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
1784 ret
= SMB_VFS_NEXT_FCHMOD_ACL(handle
, fsp
, mode
);
1786 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
1791 static NTSTATUS
catia_fget_nt_acl(vfs_handle_struct
*handle
,
1793 uint32_t security_info
,
1794 TALLOC_CTX
*mem_ctx
,
1795 struct security_descriptor
**ppdesc
)
1797 struct catia_cache
*cc
= NULL
;
1801 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
1803 return map_nt_error_from_unix(errno
);
1806 status
= SMB_VFS_NEXT_FGET_NT_ACL(handle
, fsp
, security_info
,
1809 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
1814 static NTSTATUS
catia_fset_nt_acl(vfs_handle_struct
*handle
,
1816 uint32_t security_info_sent
,
1817 const struct security_descriptor
*psd
)
1819 struct catia_cache
*cc
= NULL
;
1823 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
1825 return map_nt_error_from_unix(errno
);
1828 status
= SMB_VFS_NEXT_FSET_NT_ACL(handle
, fsp
, security_info_sent
, psd
);
1830 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
1835 static NTSTATUS
catia_fset_dos_attributes(struct vfs_handle_struct
*handle
,
1836 struct files_struct
*fsp
,
1839 struct catia_cache
*cc
= NULL
;
1843 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
1845 return map_nt_error_from_unix(errno
);
1848 status
= SMB_VFS_NEXT_FSET_DOS_ATTRIBUTES(handle
, fsp
, dosmode
);
1850 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
1855 static NTSTATUS
catia_fget_dos_attributes(struct vfs_handle_struct
*handle
,
1856 struct files_struct
*fsp
,
1859 struct catia_cache
*cc
= NULL
;
1863 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
1865 return map_nt_error_from_unix(errno
);
1868 status
= SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle
, fsp
, dosmode
);
1870 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
1875 static int catia_fchown(vfs_handle_struct
*handle
,
1880 struct catia_cache
*cc
= NULL
;
1883 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
1888 ret
= SMB_VFS_NEXT_FCHOWN(handle
, fsp
, uid
, gid
);
1890 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
1895 static int catia_fchmod(vfs_handle_struct
*handle
,
1899 struct catia_cache
*cc
= NULL
;
1902 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
1907 ret
= SMB_VFS_NEXT_FCHMOD(handle
, fsp
, mode
);
1909 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
1914 struct catia_pread_state
{
1916 struct vfs_aio_state vfs_aio_state
;
1917 struct files_struct
*fsp
;
1918 struct catia_cache
*cc
;
1921 static void catia_pread_done(struct tevent_req
*subreq
);
1923 static struct tevent_req
*catia_pread_send(struct vfs_handle_struct
*handle
,
1924 TALLOC_CTX
*mem_ctx
,
1925 struct tevent_context
*ev
,
1926 struct files_struct
*fsp
,
1931 struct tevent_req
*req
= NULL
, *subreq
= NULL
;
1932 struct catia_pread_state
*state
= NULL
;
1935 req
= tevent_req_create(mem_ctx
, &state
,
1936 struct catia_pread_state
);
1942 ret
= CATIA_FETCH_FSP_PRE_NEXT(state
, handle
, fsp
, &state
->cc
);
1944 tevent_req_error(req
, errno
);
1945 return tevent_req_post(req
, ev
);
1948 subreq
= SMB_VFS_NEXT_PREAD_SEND(state
, ev
, handle
, fsp
, data
,
1950 if (tevent_req_nomem(subreq
, req
)) {
1951 return tevent_req_post(req
, ev
);
1953 tevent_req_set_callback(subreq
, catia_pread_done
, req
);
1958 static void catia_pread_done(struct tevent_req
*subreq
)
1960 struct tevent_req
*req
= tevent_req_callback_data(
1961 subreq
, struct tevent_req
);
1962 struct catia_pread_state
*state
= tevent_req_data(
1963 req
, struct catia_pread_state
);
1965 state
->ret
= SMB_VFS_PREAD_RECV(subreq
, &state
->vfs_aio_state
);
1966 TALLOC_FREE(subreq
);
1968 CATIA_FETCH_FSP_POST_NEXT(&state
->cc
, state
->fsp
);
1970 tevent_req_done(req
);
1973 static ssize_t
catia_pread_recv(struct tevent_req
*req
,
1974 struct vfs_aio_state
*vfs_aio_state
)
1976 struct catia_pread_state
*state
= tevent_req_data(
1977 req
, struct catia_pread_state
);
1979 if (tevent_req_is_unix_error(req
, &vfs_aio_state
->error
)) {
1983 *vfs_aio_state
= state
->vfs_aio_state
;
1987 struct catia_pwrite_state
{
1989 struct vfs_aio_state vfs_aio_state
;
1990 struct files_struct
*fsp
;
1991 struct catia_cache
*cc
;
1994 static void catia_pwrite_done(struct tevent_req
*subreq
);
1996 static struct tevent_req
*catia_pwrite_send(struct vfs_handle_struct
*handle
,
1997 TALLOC_CTX
*mem_ctx
,
1998 struct tevent_context
*ev
,
1999 struct files_struct
*fsp
,
2004 struct tevent_req
*req
= NULL
, *subreq
= NULL
;
2005 struct catia_pwrite_state
*state
= NULL
;
2008 req
= tevent_req_create(mem_ctx
, &state
,
2009 struct catia_pwrite_state
);
2015 ret
= CATIA_FETCH_FSP_PRE_NEXT(state
, handle
, fsp
, &state
->cc
);
2017 tevent_req_error(req
, errno
);
2018 return tevent_req_post(req
, ev
);
2021 subreq
= SMB_VFS_NEXT_PWRITE_SEND(state
, ev
, handle
, fsp
, data
,
2023 if (tevent_req_nomem(subreq
, req
)) {
2024 return tevent_req_post(req
, ev
);
2026 tevent_req_set_callback(subreq
, catia_pwrite_done
, req
);
2031 static void catia_pwrite_done(struct tevent_req
*subreq
)
2033 struct tevent_req
*req
= tevent_req_callback_data(
2034 subreq
, struct tevent_req
);
2035 struct catia_pwrite_state
*state
= tevent_req_data(
2036 req
, struct catia_pwrite_state
);
2038 state
->ret
= SMB_VFS_PWRITE_RECV(subreq
, &state
->vfs_aio_state
);
2039 TALLOC_FREE(subreq
);
2041 CATIA_FETCH_FSP_POST_NEXT(&state
->cc
, state
->fsp
);
2043 tevent_req_done(req
);
2046 static ssize_t
catia_pwrite_recv(struct tevent_req
*req
,
2047 struct vfs_aio_state
*vfs_aio_state
)
2049 struct catia_pwrite_state
*state
= tevent_req_data(
2050 req
, struct catia_pwrite_state
);
2052 if (tevent_req_is_unix_error(req
, &vfs_aio_state
->error
)) {
2056 *vfs_aio_state
= state
->vfs_aio_state
;
2060 static off_t
catia_lseek(vfs_handle_struct
*handle
,
2065 struct catia_cache
*cc
= NULL
;
2069 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
2074 result
= SMB_VFS_NEXT_LSEEK(handle
, fsp
, offset
, whence
);
2076 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
2081 static int catia_fsync(vfs_handle_struct
*handle
, files_struct
*fsp
)
2083 struct catia_cache
*cc
= NULL
;
2086 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
2091 ret
= SMB_VFS_NEXT_FSYNC(handle
, fsp
);
2093 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
2098 struct catia_fsync_state
{
2100 struct vfs_aio_state vfs_aio_state
;
2101 struct files_struct
*fsp
;
2102 struct catia_cache
*cc
;
2105 static void catia_fsync_done(struct tevent_req
*subreq
);
2107 static struct tevent_req
*catia_fsync_send(struct vfs_handle_struct
*handle
,
2108 TALLOC_CTX
*mem_ctx
,
2109 struct tevent_context
*ev
,
2110 struct files_struct
*fsp
)
2112 struct tevent_req
*req
= NULL
, *subreq
= NULL
;
2113 struct catia_fsync_state
*state
= NULL
;
2116 req
= tevent_req_create(mem_ctx
, &state
,
2117 struct catia_fsync_state
);
2123 ret
= CATIA_FETCH_FSP_PRE_NEXT(state
, handle
, fsp
, &state
->cc
);
2125 tevent_req_error(req
, errno
);
2126 return tevent_req_post(req
, ev
);
2129 subreq
= SMB_VFS_NEXT_FSYNC_SEND(state
, ev
, handle
, fsp
);
2130 if (tevent_req_nomem(subreq
, req
)) {
2131 return tevent_req_post(req
, ev
);
2133 tevent_req_set_callback(subreq
, catia_fsync_done
, req
);
2138 static void catia_fsync_done(struct tevent_req
*subreq
)
2140 struct tevent_req
*req
= tevent_req_callback_data(
2141 subreq
, struct tevent_req
);
2142 struct catia_fsync_state
*state
= tevent_req_data(
2143 req
, struct catia_fsync_state
);
2145 state
->ret
= SMB_VFS_FSYNC_RECV(subreq
, &state
->vfs_aio_state
);
2146 TALLOC_FREE(subreq
);
2148 CATIA_FETCH_FSP_POST_NEXT(&state
->cc
, state
->fsp
);
2150 tevent_req_done(req
);
2153 static int catia_fsync_recv(struct tevent_req
*req
,
2154 struct vfs_aio_state
*vfs_aio_state
)
2156 struct catia_fsync_state
*state
= tevent_req_data(
2157 req
, struct catia_fsync_state
);
2159 if (tevent_req_is_unix_error(req
, &vfs_aio_state
->error
)) {
2163 *vfs_aio_state
= state
->vfs_aio_state
;
2167 static bool catia_lock(vfs_handle_struct
*handle
,
2174 struct catia_cache
*cc
= NULL
;
2178 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
2183 ok
= SMB_VFS_NEXT_LOCK(handle
, fsp
, op
, offset
, count
, type
);
2185 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
2190 static int catia_kernel_flock(struct vfs_handle_struct
*handle
,
2191 struct files_struct
*fsp
,
2192 uint32_t share_mode
,
2193 uint32_t access_mask
)
2195 struct catia_cache
*cc
= NULL
;
2198 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
2203 ret
= SMB_VFS_NEXT_KERNEL_FLOCK(handle
, fsp
, share_mode
, access_mask
);
2205 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
2210 static int catia_linux_setlease(vfs_handle_struct
*handle
,
2214 struct catia_cache
*cc
= NULL
;
2217 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
2222 ret
= SMB_VFS_NEXT_LINUX_SETLEASE(handle
, fsp
, leasetype
);
2224 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
2229 static bool catia_getlock(vfs_handle_struct
*handle
,
2236 struct catia_cache
*cc
= NULL
;
2240 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
2245 ok
= SMB_VFS_NEXT_GETLOCK(handle
, fsp
, poffset
, pcount
, ptype
, ppid
);
2247 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
2252 static bool catia_strict_lock_check(struct vfs_handle_struct
*handle
,
2253 struct files_struct
*fsp
,
2254 struct lock_struct
*plock
)
2256 struct catia_cache
*cc
= NULL
;
2260 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
2265 ok
= SMB_VFS_NEXT_STRICT_LOCK_CHECK(handle
, fsp
, plock
);
2267 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
2272 static NTSTATUS
catia_fsctl(struct vfs_handle_struct
*handle
,
2273 struct files_struct
*fsp
,
2277 const uint8_t *_in_data
,
2279 uint8_t **_out_data
,
2280 uint32_t max_out_len
,
2284 struct catia_cache
*cc
= NULL
;
2287 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
2289 return map_nt_error_from_unix(errno
);
2292 result
= SMB_VFS_NEXT_FSCTL(handle
,
2303 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
2308 static NTSTATUS
catia_get_compression(vfs_handle_struct
*handle
,
2309 TALLOC_CTX
*mem_ctx
,
2310 struct files_struct
*fsp
,
2311 struct smb_filename
*smb_fname
,
2312 uint16_t *_compression_fmt
)
2315 struct catia_cache
*cc
= NULL
;
2317 struct smb_filename
*mapped_smb_fname
= NULL
;
2318 char *mapped_name
= NULL
;
2321 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
2323 return map_nt_error_from_unix(errno
);
2325 mapped_smb_fname
= fsp
->fsp_name
;
2327 result
= catia_string_replace_allocate(handle
->conn
,
2328 smb_fname
->base_name
,
2330 vfs_translate_to_unix
);
2331 if (!NT_STATUS_IS_OK(result
)) {
2335 mapped_smb_fname
= synthetic_smb_fname(talloc_tos(),
2340 if (mapped_smb_fname
== NULL
) {
2341 TALLOC_FREE(mapped_name
);
2342 return NT_STATUS_NO_MEMORY
;
2345 TALLOC_FREE(mapped_name
);
2348 result
= SMB_VFS_NEXT_GET_COMPRESSION(handle
,
2355 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
2357 TALLOC_FREE(mapped_smb_fname
);
2363 static NTSTATUS
catia_set_compression(vfs_handle_struct
*handle
,
2364 TALLOC_CTX
*mem_ctx
,
2365 struct files_struct
*fsp
,
2366 uint16_t compression_fmt
)
2369 struct catia_cache
*cc
= NULL
;
2372 ret
= CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle
, fsp
, &cc
);
2374 return map_nt_error_from_unix(errno
);
2377 result
= SMB_VFS_NEXT_SET_COMPRESSION(handle
, mem_ctx
, fsp
,
2380 CATIA_FETCH_FSP_POST_NEXT(&cc
, fsp
);
2385 static NTSTATUS
catia_readdir_attr(struct vfs_handle_struct
*handle
,
2386 const struct smb_filename
*smb_fname_in
,
2387 TALLOC_CTX
*mem_ctx
,
2388 struct readdir_attr_data
**pattr_data
)
2390 struct smb_filename
*smb_fname
;
2394 status
= catia_string_replace_allocate(handle
->conn
,
2395 smb_fname_in
->base_name
,
2397 vfs_translate_to_unix
);
2398 if (!NT_STATUS_IS_OK(status
)) {
2399 errno
= map_errno_from_nt_status(status
);
2403 smb_fname
= synthetic_smb_fname(talloc_tos(), fname
, NULL
,
2404 &smb_fname_in
->st
, 0);
2406 status
= SMB_VFS_NEXT_READDIR_ATTR(handle
, smb_fname
, mem_ctx
, pattr_data
);
2408 TALLOC_FREE(smb_fname
);
2413 static NTSTATUS
catia_get_dos_attributes(struct vfs_handle_struct
*handle
,
2414 struct smb_filename
*smb_fname
,
2417 char *mapped_name
= NULL
;
2418 const char *path
= smb_fname
->base_name
;
2419 struct smb_filename
*mapped_smb_fname
= NULL
;
2422 status
= catia_string_replace_allocate(handle
->conn
,
2423 path
, &mapped_name
, vfs_translate_to_unix
);
2424 if (!NT_STATUS_IS_OK(status
)) {
2425 errno
= map_errno_from_nt_status(status
);
2428 mapped_smb_fname
= synthetic_smb_fname(talloc_tos(),
2433 if (mapped_smb_fname
== NULL
) {
2434 TALLOC_FREE(mapped_name
);
2435 return NT_STATUS_NO_MEMORY
;
2438 status
= SMB_VFS_NEXT_GET_DOS_ATTRIBUTES(handle
,
2441 TALLOC_FREE(mapped_name
);
2442 TALLOC_FREE(mapped_smb_fname
);
2447 static NTSTATUS
catia_set_dos_attributes(struct vfs_handle_struct
*handle
,
2448 const struct smb_filename
*smb_fname
,
2451 char *mapped_name
= NULL
;
2452 const char *path
= smb_fname
->base_name
;
2453 struct smb_filename
*mapped_smb_fname
= NULL
;
2456 status
= catia_string_replace_allocate(handle
->conn
,
2457 path
, &mapped_name
, vfs_translate_to_unix
);
2458 if (!NT_STATUS_IS_OK(status
)) {
2459 errno
= map_errno_from_nt_status(status
);
2462 mapped_smb_fname
= synthetic_smb_fname(talloc_tos(),
2467 if (mapped_smb_fname
== NULL
) {
2468 TALLOC_FREE(mapped_name
);
2469 return NT_STATUS_NO_MEMORY
;
2472 status
= SMB_VFS_NEXT_SET_DOS_ATTRIBUTES(handle
,
2475 TALLOC_FREE(mapped_name
);
2476 TALLOC_FREE(mapped_smb_fname
);
2481 static struct vfs_fn_pointers vfs_catia_fns
= {
2482 /* Directory operations */
2483 .mkdir_fn
= catia_mkdir
,
2484 .rmdir_fn
= catia_rmdir
,
2485 .opendir_fn
= catia_opendir
,
2486 .readdir_attr_fn
= catia_readdir_attr
,
2488 /* File operations */
2489 .open_fn
= catia_open
,
2490 .pread_fn
= catia_pread
,
2491 .pread_send_fn
= catia_pread_send
,
2492 .pread_recv_fn
= catia_pread_recv
,
2493 .pwrite_fn
= catia_pwrite
,
2494 .pwrite_send_fn
= catia_pwrite_send
,
2495 .pwrite_recv_fn
= catia_pwrite_recv
,
2496 .lseek_fn
= catia_lseek
,
2497 .rename_fn
= catia_rename
,
2498 .fsync_fn
= catia_fsync
,
2499 .fsync_send_fn
= catia_fsync_send
,
2500 .fsync_recv_fn
= catia_fsync_recv
,
2501 .stat_fn
= catia_stat
,
2502 .fstat_fn
= catia_fstat
,
2503 .lstat_fn
= catia_lstat
,
2504 .unlink_fn
= catia_unlink
,
2505 .chmod_fn
= catia_chmod
,
2506 .fchmod_fn
= catia_fchmod
,
2507 .chown_fn
= catia_chown
,
2508 .fchown_fn
= catia_fchown
,
2509 .lchown_fn
= catia_lchown
,
2510 .chdir_fn
= catia_chdir
,
2511 .ntimes_fn
= catia_ntimes
,
2512 .ftruncate_fn
= catia_ftruncate
,
2513 .fallocate_fn
= catia_fallocate
,
2514 .lock_fn
= catia_lock
,
2515 .kernel_flock_fn
= catia_kernel_flock
,
2516 .linux_setlease_fn
= catia_linux_setlease
,
2517 .getlock_fn
= catia_getlock
,
2518 .realpath_fn
= catia_realpath
,
2519 .chflags_fn
= catia_chflags
,
2520 .streaminfo_fn
= catia_streaminfo
,
2521 .strict_lock_check_fn
= catia_strict_lock_check
,
2522 .translate_name_fn
= catia_translate_name
,
2523 .fsctl_fn
= catia_fsctl
,
2524 .get_dos_attributes_fn
= catia_get_dos_attributes
,
2525 .set_dos_attributes_fn
= catia_set_dos_attributes
,
2526 .fset_dos_attributes_fn
= catia_fset_dos_attributes
,
2527 .fget_dos_attributes_fn
= catia_fget_dos_attributes
,
2528 .get_compression_fn
= catia_get_compression
,
2529 .set_compression_fn
= catia_set_compression
,
2531 /* NT ACL operations. */
2532 .get_nt_acl_fn
= catia_get_nt_acl
,
2533 .fget_nt_acl_fn
= catia_fget_nt_acl
,
2534 .fset_nt_acl_fn
= catia_fset_nt_acl
,
2536 /* POSIX ACL operations. */
2537 .chmod_acl_fn
= catia_chmod_acl
,
2538 .fchmod_acl_fn
= catia_fchmod_acl
,
2540 .sys_acl_get_file_fn
= catia_sys_acl_get_file
,
2541 .sys_acl_get_fd_fn
= catia_sys_acl_get_fd
,
2542 .sys_acl_blob_get_fd_fn
= catia_sys_acl_blob_get_fd
,
2543 .sys_acl_set_file_fn
= catia_sys_acl_set_file
,
2544 .sys_acl_set_fd_fn
= catia_sys_acl_set_fd
,
2545 .sys_acl_delete_def_file_fn
= catia_sys_acl_delete_def_file
,
2547 /* EA operations. */
2548 .getxattr_fn
= catia_getxattr
,
2549 .listxattr_fn
= catia_listxattr
,
2550 .removexattr_fn
= catia_removexattr
,
2551 .setxattr_fn
= catia_setxattr
,
2552 .fgetxattr_fn
= catia_fgetxattr
,
2553 .flistxattr_fn
= catia_flistxattr
,
2554 .fremovexattr_fn
= catia_fremovexattr
,
2555 .fsetxattr_fn
= catia_fsetxattr
,
2559 NTSTATUS
vfs_catia_init(TALLOC_CTX
*ctx
)
2563 ret
= smb_register_vfs(SMB_VFS_INTERFACE_VERSION
, "catia",
2565 if (!NT_STATUS_IS_OK(ret
))
2568 vfs_catia_debug_level
= debug_add_class("catia");
2569 if (vfs_catia_debug_level
== -1) {
2570 vfs_catia_debug_level
= DBGC_VFS
;
2571 DEBUG(0, ("vfs_catia: Couldn't register custom debugging "
2574 DEBUG(10, ("vfs_catia: Debug class number of "
2575 "'catia': %d\n", vfs_catia_debug_level
));