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(sme, 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 int catia_connect(struct vfs_handle_struct *handle,
166 * Unless we have an async implementation of get_dos_attributes turn
169 lp_do_parameter(SNUM(handle->conn), "smbd:async dosmode", "false");
171 return SMB_VFS_NEXT_CONNECT(handle, service, user);
175 * TRANSLATE_NAME call which converts the given name to
176 * "WINDOWS displayable" name
178 static NTSTATUS catia_translate_name(struct vfs_handle_struct *handle,
179 const char *orig_name,
180 enum vfs_translate_direction direction,
186 NTSTATUS status, ret;
189 * Copy the supplied name and free the memory for mapped_name,
190 * already allocated by the caller.
191 * We will be allocating new memory for mapped_name in
192 * catia_string_replace_allocate
194 name = talloc_strdup(talloc_tos(), orig_name);
197 return NT_STATUS_NO_MEMORY;
199 status = catia_string_replace_allocate(handle->conn, name,
200 &mapped_name, direction);
203 if (!NT_STATUS_IS_OK(status)) {
207 ret = SMB_VFS_NEXT_TRANSLATE_NAME(handle, mapped_name, direction,
208 mem_ctx, pmapped_name);
210 if (NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) {
211 *pmapped_name = talloc_move(mem_ctx, &mapped_name);
212 /* we need to return the former translation result here */
215 TALLOC_FREE(mapped_name);
221 #define CATIA_DEBUG_CC(lvl, cc, fsp) \
222 catia_debug_cc((lvl), (cc), (fsp), __location__);
224 static void catia_debug_cc(int lvl,
225 struct catia_cache *cc,
227 const char *location)
229 DEBUG(lvl, ("%s: cc [%p] cc->busy [%p] "
231 "fsp [%p] fsp name [%s] "
234 "orig_base_fname [%s] "
238 cc->is_fsp_ext ? "yes" : "no",
239 fsp, fsp_str_dbg(fsp),
240 cc->orig_fname, cc->fname,
241 cc->orig_base_fname, cc->base_fname));
244 static void catia_free_cc(struct catia_cache **_cc,
245 vfs_handle_struct *handle,
248 struct catia_cache *cc = *_cc;
250 if (cc->is_fsp_ext) {
251 VFS_REMOVE_FSP_EXTENSION(handle, fsp);
260 static struct catia_cache *catia_validate_and_apply_cc(
261 vfs_handle_struct *handle,
263 const struct catia_cache * const *busy,
264 bool *make_tmp_cache)
266 struct catia_cache *cc = NULL;
268 *make_tmp_cache = false;
270 cc = (struct catia_cache *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
275 if (cc->busy != NULL) {
276 if (cc->busy == busy) {
277 /* This should never happen */
278 CATIA_DEBUG_CC(0, cc, fsp);
279 smb_panic(__location__);
283 * Recursion. Validate names, the names in the fsp's should be
284 * the translated names we had set.
287 if ((cc->fname != fsp->fsp_name->base_name)
289 ((fsp->base_fsp != NULL) &&
290 (cc->base_fname != fsp->base_fsp->fsp_name->base_name)))
292 CATIA_DEBUG_CC(10, cc, fsp);
295 * Names changed. Setting don't expose the cache on the
296 * fsp and ask the caller to create a temporary cache.
298 *make_tmp_cache = true;
303 * Ok, a validated cache while in a recursion, just let the
304 * caller detect that cc->busy is != busy and there's
305 * nothing else to do.
307 CATIA_DEBUG_CC(10, cc, fsp);
311 /* Not in a recursion */
313 if ((cc->orig_fname != fsp->fsp_name->base_name)
315 ((fsp->base_fsp != NULL) &&
316 (cc->orig_base_fname != fsp->base_fsp->fsp_name->base_name)))
319 * fsp names changed, this can happen in an rename op.
320 * Trigger recreation as a full fledged fsp extension.
323 CATIA_DEBUG_CC(10, cc, fsp);
324 catia_free_cc(&cc, handle, fsp);
330 * Ok, we found a valid cache entry, no recursion. Just set translated
331 * names from the cache and mark the cc as busy.
333 fsp->fsp_name->base_name = cc->fname;
334 if (fsp->base_fsp != NULL) {
335 fsp->base_fsp->fsp_name->base_name = cc->base_fname;
339 CATIA_DEBUG_CC(10, cc, fsp);
343 #define CATIA_FETCH_FSP_PRE_NEXT(mem_ctx, handle, fsp, _cc) \
344 catia_fetch_fsp_pre_next((mem_ctx), (handle), (fsp), (_cc), __func__);
346 static int catia_fetch_fsp_pre_next(TALLOC_CTX *mem_ctx,
347 vfs_handle_struct *handle,
349 struct catia_cache **_cc,
350 const char *function)
352 const struct catia_cache * const *busy =
353 (const struct catia_cache * const *)_cc;
354 struct catia_cache *cc = NULL;
356 bool make_tmp_cache = false;
360 DBG_DEBUG("Called from [%s]\n", function);
362 cc = catia_validate_and_apply_cc(handle,
367 if (cc->busy != busy) {
374 if (!make_tmp_cache) {
375 cc = VFS_ADD_FSP_EXTENSION(
376 handle, fsp, struct catia_cache, NULL);
380 *cc = (struct catia_cache) {
384 mem_ctx = VFS_MEMCTX_FSP_EXTENSION(handle, fsp);
385 if (mem_ctx == NULL) {
386 DBG_ERR("VFS_MEMCTX_FSP_EXTENSION failed\n");
387 catia_free_cc(&cc, handle, fsp);
391 cc = talloc_zero(mem_ctx, struct catia_cache);
399 status = catia_string_replace_allocate(handle->conn,
400 fsp->fsp_name->base_name,
402 vfs_translate_to_unix);
403 if (!NT_STATUS_IS_OK(status)) {
404 catia_free_cc(&cc, handle, fsp);
405 errno = map_errno_from_nt_status(status);
408 talloc_steal(mem_ctx, cc->fname);
410 if (fsp->base_fsp != NULL) {
411 status = catia_string_replace_allocate(
413 fsp->base_fsp->fsp_name->base_name,
415 vfs_translate_to_unix);
416 if (!NT_STATUS_IS_OK(status)) {
417 catia_free_cc(&cc, handle, fsp);
418 errno = map_errno_from_nt_status(status);
421 talloc_steal(mem_ctx, cc->base_fname);
424 cc->orig_fname = fsp->fsp_name->base_name;
425 fsp->fsp_name->base_name = cc->fname;
427 if (fsp->base_fsp != NULL) {
428 cc->orig_base_fname = fsp->base_fsp->fsp_name->base_name;
429 fsp->base_fsp->fsp_name->base_name = cc->base_fname;
433 CATIA_DEBUG_CC(10, cc, fsp);
440 #define CATIA_FETCH_FSP_POST_NEXT(_cc, fsp) do { \
441 int saved_errno = errno; \
442 catia_fetch_fsp_post_next((_cc), (fsp), __func__); \
443 errno = saved_errno; \
446 static void catia_fetch_fsp_post_next(struct catia_cache **_cc,
448 const char *function)
450 const struct catia_cache * const *busy =
451 (const struct catia_cache * const *)_cc;
452 struct catia_cache *cc = *_cc;
454 DBG_DEBUG("Called from [%s]\n", function);
458 * This can happen when recursing in the VFS on the fsp when the
459 * pre_next func noticed the recursion and set out cc pointer to
465 if (cc->busy != busy) {
466 CATIA_DEBUG_CC(0, cc, fsp);
467 smb_panic(__location__);
474 fsp->fsp_name->base_name = cc->orig_fname;
475 if (fsp->base_fsp != NULL) {
476 fsp->base_fsp->fsp_name->base_name = cc->orig_base_fname;
479 CATIA_DEBUG_CC(10, cc, fsp);
481 if (!cc->is_fsp_ext) {
488 static int catia_open(vfs_handle_struct *handle,
489 struct smb_filename *smb_fname,
494 struct catia_cache *cc = NULL;
495 char *orig_smb_fname = smb_fname->base_name;
496 char *mapped_smb_fname = NULL;
500 status = catia_string_replace_allocate(handle->conn,
501 smb_fname->base_name,
503 vfs_translate_to_unix);
504 if (!NT_STATUS_IS_OK(status)) {
508 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
510 TALLOC_FREE(mapped_smb_fname);
514 smb_fname->base_name = mapped_smb_fname;
515 ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
516 smb_fname->base_name = orig_smb_fname;
518 TALLOC_FREE(mapped_smb_fname);
519 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
524 static int catia_renameat(vfs_handle_struct *handle,
525 files_struct *srcfsp,
526 const struct smb_filename *smb_fname_src,
527 files_struct *dstfsp,
528 const struct smb_filename *smb_fname_dst)
530 TALLOC_CTX *ctx = talloc_tos();
531 struct smb_filename *smb_fname_src_tmp = NULL;
532 struct smb_filename *smb_fname_dst_tmp = NULL;
533 char *src_name_mapped = NULL;
534 char *dst_name_mapped = NULL;
538 status = catia_string_replace_allocate(handle->conn,
539 smb_fname_src->base_name,
540 &src_name_mapped, vfs_translate_to_unix);
541 if (!NT_STATUS_IS_OK(status)) {
542 errno = map_errno_from_nt_status(status);
546 status = catia_string_replace_allocate(handle->conn,
547 smb_fname_dst->base_name,
548 &dst_name_mapped, vfs_translate_to_unix);
549 if (!NT_STATUS_IS_OK(status)) {
550 errno = map_errno_from_nt_status(status);
554 /* Setup temporary smb_filename structs. */
555 smb_fname_src_tmp = cp_smb_filename(ctx, smb_fname_src);
556 if (smb_fname_src_tmp == NULL) {
561 smb_fname_dst_tmp = cp_smb_filename(ctx, smb_fname_dst);
562 if (smb_fname_dst_tmp == NULL) {
567 smb_fname_src_tmp->base_name = src_name_mapped;
568 smb_fname_dst_tmp->base_name = dst_name_mapped;
569 DEBUG(10, ("converted old name: %s\n",
570 smb_fname_str_dbg(smb_fname_src_tmp)));
571 DEBUG(10, ("converted new name: %s\n",
572 smb_fname_str_dbg(smb_fname_dst_tmp)));
574 ret = SMB_VFS_NEXT_RENAMEAT(handle,
581 TALLOC_FREE(src_name_mapped);
582 TALLOC_FREE(dst_name_mapped);
583 TALLOC_FREE(smb_fname_src_tmp);
584 TALLOC_FREE(smb_fname_dst_tmp);
589 static int catia_stat(vfs_handle_struct *handle,
590 struct smb_filename *smb_fname)
597 status = catia_string_replace_allocate(handle->conn,
598 smb_fname->base_name,
599 &name, vfs_translate_to_unix);
600 if (!NT_STATUS_IS_OK(status)) {
601 errno = map_errno_from_nt_status(status);
605 tmp_base_name = smb_fname->base_name;
606 smb_fname->base_name = name;
608 ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
609 smb_fname->base_name = tmp_base_name;
615 static int catia_lstat(vfs_handle_struct *handle,
616 struct smb_filename *smb_fname)
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 tmp_base_name = smb_fname->base_name;
632 smb_fname->base_name = name;
634 ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
635 smb_fname->base_name = tmp_base_name;
641 static int catia_unlinkat(vfs_handle_struct *handle,
642 struct files_struct *dirfsp,
643 const struct smb_filename *smb_fname,
646 struct smb_filename *smb_fname_tmp = NULL;
651 status = catia_string_replace_allocate(handle->conn,
652 smb_fname->base_name,
653 &name, vfs_translate_to_unix);
654 if (!NT_STATUS_IS_OK(status)) {
655 errno = map_errno_from_nt_status(status);
659 /* Setup temporary smb_filename structs. */
660 smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
661 if (smb_fname_tmp == NULL) {
666 smb_fname_tmp->base_name = name;
667 ret = SMB_VFS_NEXT_UNLINKAT(handle,
671 TALLOC_FREE(smb_fname_tmp);
677 static int catia_lchown(vfs_handle_struct *handle,
678 const struct smb_filename *smb_fname,
686 struct smb_filename *catia_smb_fname = NULL;
688 status = catia_string_replace_allocate(handle->conn,
689 smb_fname->base_name,
691 vfs_translate_to_unix);
692 if (!NT_STATUS_IS_OK(status)) {
693 errno = map_errno_from_nt_status(status);
696 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
701 if (catia_smb_fname == NULL) {
707 ret = SMB_VFS_NEXT_LCHOWN(handle, catia_smb_fname, uid, gid);
710 TALLOC_FREE(catia_smb_fname);
715 static int catia_chmod(vfs_handle_struct *handle,
716 const struct smb_filename *smb_fname,
723 struct smb_filename *catia_smb_fname = NULL;
725 status = catia_string_replace_allocate(handle->conn,
726 smb_fname->base_name,
728 vfs_translate_to_unix);
729 if (!NT_STATUS_IS_OK(status)) {
730 errno = map_errno_from_nt_status(status);
733 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
738 if (catia_smb_fname == NULL) {
744 ret = SMB_VFS_NEXT_CHMOD(handle, catia_smb_fname, mode);
747 TALLOC_FREE(catia_smb_fname);
752 static int catia_mkdirat(vfs_handle_struct *handle,
753 struct files_struct *dirfsp,
754 const struct smb_filename *smb_fname,
760 struct smb_filename *catia_smb_fname = NULL;
762 status = catia_string_replace_allocate(handle->conn,
763 smb_fname->base_name,
765 vfs_translate_to_unix);
766 if (!NT_STATUS_IS_OK(status)) {
767 errno = map_errno_from_nt_status(status);
770 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
775 if (catia_smb_fname == NULL) {
781 ret = SMB_VFS_NEXT_MKDIRAT(handle,
786 TALLOC_FREE(catia_smb_fname);
791 static int catia_chdir(vfs_handle_struct *handle,
792 const struct smb_filename *smb_fname)
795 struct smb_filename *catia_smb_fname = NULL;
799 status = catia_string_replace_allocate(handle->conn,
800 smb_fname->base_name,
802 vfs_translate_to_unix);
803 if (!NT_STATUS_IS_OK(status)) {
804 errno = map_errno_from_nt_status(status);
808 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
813 if (catia_smb_fname == NULL) {
818 ret = SMB_VFS_NEXT_CHDIR(handle, catia_smb_fname);
820 TALLOC_FREE(catia_smb_fname);
825 static int catia_ntimes(vfs_handle_struct *handle,
826 const struct smb_filename *smb_fname,
827 struct smb_file_time *ft)
829 struct smb_filename *smb_fname_tmp = NULL;
834 status = catia_string_replace_allocate(handle->conn,
835 smb_fname->base_name,
836 &name, vfs_translate_to_unix);
837 if (!NT_STATUS_IS_OK(status)) {
838 errno = map_errno_from_nt_status(status);
842 smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
843 if (smb_fname_tmp == NULL) {
848 smb_fname_tmp->base_name = name;
849 ret = SMB_VFS_NEXT_NTIMES(handle, smb_fname_tmp, ft);
851 TALLOC_FREE(smb_fname_tmp);
856 static struct smb_filename *
857 catia_realpath(vfs_handle_struct *handle,
859 const struct smb_filename *smb_fname)
861 char *mapped_name = NULL;
862 struct smb_filename *catia_smb_fname = NULL;
863 struct smb_filename *return_fname = NULL;
866 status = catia_string_replace_allocate(handle->conn,
867 smb_fname->base_name,
868 &mapped_name, vfs_translate_to_unix);
869 if (!NT_STATUS_IS_OK(status)) {
870 errno = map_errno_from_nt_status(status);
874 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
879 if (catia_smb_fname == NULL) {
880 TALLOC_FREE(mapped_name);
884 return_fname = SMB_VFS_NEXT_REALPATH(handle, ctx, catia_smb_fname);
885 TALLOC_FREE(mapped_name);
886 TALLOC_FREE(catia_smb_fname);
890 static int catia_chflags(struct vfs_handle_struct *handle,
891 const struct smb_filename *smb_fname,
895 struct smb_filename *catia_smb_fname = NULL;
899 status = catia_string_replace_allocate(handle->conn,
900 smb_fname->base_name,
902 vfs_translate_to_unix);
903 if (!NT_STATUS_IS_OK(status)) {
904 errno = map_errno_from_nt_status(status);
907 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
912 if (catia_smb_fname == NULL) {
918 ret = SMB_VFS_NEXT_CHFLAGS(handle, catia_smb_fname, flags);
920 TALLOC_FREE(catia_smb_fname);
926 catia_streaminfo(struct vfs_handle_struct *handle,
927 struct files_struct *fsp,
928 const struct smb_filename *smb_fname,
930 unsigned int *_num_streams,
931 struct stream_struct **_streams)
933 char *mapped_name = NULL;
936 struct smb_filename *catia_smb_fname = NULL;
937 unsigned int num_streams = 0;
938 struct stream_struct *streams = NULL;
943 status = catia_string_replace_allocate(handle->conn,
944 smb_fname->base_name,
946 vfs_translate_to_unix);
947 if (!NT_STATUS_IS_OK(status)) {
948 errno = map_errno_from_nt_status(status);
952 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
957 if (catia_smb_fname == NULL) {
958 TALLOC_FREE(mapped_name);
959 return NT_STATUS_NO_MEMORY;
962 status = SMB_VFS_NEXT_STREAMINFO(handle, fsp, catia_smb_fname,
963 mem_ctx, &num_streams, &streams);
964 TALLOC_FREE(mapped_name);
965 TALLOC_FREE(catia_smb_fname);
966 if (!NT_STATUS_IS_OK(status)) {
971 * Translate stream names just like the base names
973 for (i = 0; i < num_streams; i++) {
975 * Strip ":" prefix and ":$DATA" suffix to get a
976 * "pure" stream name and only translate that.
978 void *old_ptr = streams[i].name;
979 char *stream_name = streams[i].name + 1;
980 char *stream_type = strrchr_m(stream_name, ':');
982 if (stream_type != NULL) {
987 status = catia_string_replace_allocate(handle->conn, stream_name,
988 &mapped_name, vfs_translate_to_windows);
989 if (!NT_STATUS_IS_OK(status)) {
990 TALLOC_FREE(streams);
994 if (stream_type != NULL) {
995 streams[i].name = talloc_asprintf(streams, ":%s:%s",
996 mapped_name, stream_type);
998 streams[i].name = talloc_asprintf(streams, ":%s",
1001 TALLOC_FREE(mapped_name);
1002 TALLOC_FREE(old_ptr);
1003 if (streams[i].name == NULL) {
1004 TALLOC_FREE(streams);
1005 return NT_STATUS_NO_MEMORY;
1009 *_num_streams = num_streams;
1010 *_streams = streams;
1011 return NT_STATUS_OK;
1015 catia_get_nt_acl(struct vfs_handle_struct *handle,
1016 const struct smb_filename *smb_fname,
1017 uint32_t security_info,
1018 TALLOC_CTX *mem_ctx,
1019 struct security_descriptor **ppdesc)
1021 char *mapped_name = NULL;
1022 const char *path = smb_fname->base_name;
1023 struct smb_filename *mapped_smb_fname = NULL;
1026 status = catia_string_replace_allocate(handle->conn,
1027 path, &mapped_name, vfs_translate_to_unix);
1028 if (!NT_STATUS_IS_OK(status)) {
1029 errno = map_errno_from_nt_status(status);
1032 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1037 if (mapped_smb_fname == NULL) {
1038 TALLOC_FREE(mapped_name);
1039 return NT_STATUS_NO_MEMORY;
1042 status = SMB_VFS_NEXT_GET_NT_ACL(handle, mapped_smb_fname,
1043 security_info, mem_ctx, ppdesc);
1044 TALLOC_FREE(mapped_name);
1045 TALLOC_FREE(mapped_smb_fname);
1051 catia_sys_acl_get_file(vfs_handle_struct *handle,
1052 const struct smb_filename *smb_fname,
1053 SMB_ACL_TYPE_T type,
1054 TALLOC_CTX *mem_ctx)
1056 char *mapped_name = NULL;
1057 struct smb_filename *mapped_smb_fname = NULL;
1060 int saved_errno = 0;
1062 status = catia_string_replace_allocate(handle->conn,
1063 smb_fname->base_name,
1065 vfs_translate_to_unix);
1066 if (!NT_STATUS_IS_OK(status)) {
1067 errno = map_errno_from_nt_status(status);
1068 return (SMB_ACL_T)NULL;
1071 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1076 if (mapped_smb_fname == NULL) {
1077 TALLOC_FREE(mapped_name);
1079 return (SMB_ACL_T)NULL;
1082 ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, mapped_smb_fname,
1084 if (ret == (SMB_ACL_T)NULL) {
1085 saved_errno = errno;
1087 TALLOC_FREE(mapped_smb_fname);
1088 TALLOC_FREE(mapped_name);
1089 if (saved_errno != 0) {
1090 errno = saved_errno;
1096 catia_sys_acl_set_file(vfs_handle_struct *handle,
1097 const struct smb_filename *smb_fname,
1098 SMB_ACL_TYPE_T type,
1101 struct smb_filename *mapped_smb_fname = NULL;
1102 int saved_errno = 0;
1103 char *mapped_name = NULL;
1107 status = catia_string_replace_allocate(handle->conn,
1108 smb_fname->base_name,
1110 vfs_translate_to_unix);
1111 if (!NT_STATUS_IS_OK(status)) {
1112 errno = map_errno_from_nt_status(status);
1116 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1121 if (mapped_smb_fname == NULL) {
1122 TALLOC_FREE(mapped_name);
1127 ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, mapped_smb_fname,
1130 saved_errno = errno;
1132 TALLOC_FREE(mapped_smb_fname);
1133 TALLOC_FREE(mapped_name);
1134 if (saved_errno != 0) {
1135 errno = saved_errno;
1141 catia_sys_acl_delete_def_file(vfs_handle_struct *handle,
1142 const struct smb_filename *smb_fname)
1144 struct smb_filename *mapped_smb_fname = NULL;
1145 int saved_errno = 0;
1146 char *mapped_name = NULL;
1150 status = catia_string_replace_allocate(handle->conn,
1151 smb_fname->base_name,
1153 vfs_translate_to_unix);
1154 if (!NT_STATUS_IS_OK(status)) {
1155 errno = map_errno_from_nt_status(status);
1159 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1164 if (mapped_smb_fname == NULL) {
1165 TALLOC_FREE(mapped_name);
1169 ret = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, mapped_smb_fname);
1171 saved_errno = errno;
1173 TALLOC_FREE(mapped_smb_fname);
1174 TALLOC_FREE(mapped_name);
1175 if (saved_errno != 0) {
1176 errno = saved_errno;
1182 catia_getxattr(vfs_handle_struct *handle,
1183 const struct smb_filename *smb_fname,
1188 struct smb_filename *mapped_smb_fname = NULL;
1189 char *mapped_name = NULL;
1190 char *mapped_ea_name = NULL;
1193 int saved_errno = 0;
1195 status = catia_string_replace_allocate(handle->conn,
1196 smb_fname->base_name,
1198 vfs_translate_to_unix);
1199 if (!NT_STATUS_IS_OK(status)) {
1200 errno = map_errno_from_nt_status(status);
1204 status = catia_string_replace_allocate(handle->conn,
1205 name, &mapped_ea_name, vfs_translate_to_unix);
1206 if (!NT_STATUS_IS_OK(status)) {
1207 TALLOC_FREE(mapped_name);
1208 errno = map_errno_from_nt_status(status);
1212 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1217 if (mapped_smb_fname == NULL) {
1218 TALLOC_FREE(mapped_name);
1219 TALLOC_FREE(mapped_ea_name);
1224 ret = SMB_VFS_NEXT_GETXATTR(handle, mapped_smb_fname,
1225 mapped_ea_name, value, size);
1227 saved_errno = errno;
1229 TALLOC_FREE(mapped_name);
1230 TALLOC_FREE(mapped_ea_name);
1231 TALLOC_FREE(mapped_smb_fname);
1232 if (saved_errno != 0) {
1233 errno = saved_errno;
1240 catia_listxattr(vfs_handle_struct *handle,
1241 const struct smb_filename *smb_fname,
1242 char *list, size_t size)
1244 struct smb_filename *mapped_smb_fname = NULL;
1245 char *mapped_name = NULL;
1248 int saved_errno = 0;
1250 status = catia_string_replace_allocate(handle->conn,
1251 smb_fname->base_name,
1253 vfs_translate_to_unix);
1254 if (!NT_STATUS_IS_OK(status)) {
1255 errno = map_errno_from_nt_status(status);
1259 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1264 if (mapped_smb_fname == NULL) {
1265 TALLOC_FREE(mapped_name);
1270 ret = SMB_VFS_NEXT_LISTXATTR(handle, mapped_smb_fname, list, size);
1272 saved_errno = errno;
1274 TALLOC_FREE(mapped_name);
1275 TALLOC_FREE(mapped_smb_fname);
1276 if (saved_errno != 0) {
1277 errno = saved_errno;
1284 catia_removexattr(vfs_handle_struct *handle,
1285 const struct smb_filename *smb_fname,
1288 struct smb_filename *mapped_smb_fname = NULL;
1289 char *mapped_name = NULL;
1290 char *mapped_ea_name = NULL;
1293 int saved_errno = 0;
1295 status = catia_string_replace_allocate(handle->conn,
1296 smb_fname->base_name,
1298 vfs_translate_to_unix);
1299 if (!NT_STATUS_IS_OK(status)) {
1300 errno = map_errno_from_nt_status(status);
1304 status = catia_string_replace_allocate(handle->conn,
1305 name, &mapped_ea_name, vfs_translate_to_unix);
1306 if (!NT_STATUS_IS_OK(status)) {
1307 TALLOC_FREE(mapped_name);
1308 errno = map_errno_from_nt_status(status);
1312 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1317 if (mapped_smb_fname == NULL) {
1318 TALLOC_FREE(mapped_name);
1319 TALLOC_FREE(mapped_ea_name);
1324 ret = SMB_VFS_NEXT_REMOVEXATTR(handle, mapped_smb_fname,
1327 saved_errno = errno;
1329 TALLOC_FREE(mapped_name);
1330 TALLOC_FREE(mapped_ea_name);
1331 TALLOC_FREE(mapped_smb_fname);
1332 if (saved_errno != 0) {
1333 errno = saved_errno;
1340 catia_setxattr(vfs_handle_struct *handle,
1341 const struct smb_filename *smb_fname,
1347 struct smb_filename *mapped_smb_fname = NULL;
1348 char *mapped_name = NULL;
1349 char *mapped_ea_name = NULL;
1352 int saved_errno = 0;
1354 status = catia_string_replace_allocate(handle->conn,
1355 smb_fname->base_name,
1357 vfs_translate_to_unix);
1358 if (!NT_STATUS_IS_OK(status)) {
1359 errno = map_errno_from_nt_status(status);
1363 status = catia_string_replace_allocate(handle->conn,
1364 name, &mapped_ea_name, vfs_translate_to_unix);
1365 if (!NT_STATUS_IS_OK(status)) {
1366 TALLOC_FREE(mapped_name);
1367 errno = map_errno_from_nt_status(status);
1371 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1376 if (mapped_smb_fname == NULL) {
1377 TALLOC_FREE(mapped_name);
1378 TALLOC_FREE(mapped_ea_name);
1383 ret = SMB_VFS_NEXT_SETXATTR(handle, mapped_smb_fname, mapped_ea_name,
1384 value, size, flags);
1386 saved_errno = errno;
1388 TALLOC_FREE(mapped_name);
1389 TALLOC_FREE(mapped_ea_name);
1390 TALLOC_FREE(mapped_smb_fname);
1391 if (saved_errno != 0) {
1392 errno = saved_errno;
1398 static int catia_fstat(vfs_handle_struct *handle,
1400 SMB_STRUCT_STAT *sbuf)
1402 struct catia_cache *cc = NULL;
1405 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1410 ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
1412 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1417 static ssize_t catia_pread(vfs_handle_struct *handle,
1418 files_struct *fsp, void *data,
1419 size_t n, off_t offset)
1421 struct catia_cache *cc = NULL;
1425 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1430 result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
1432 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1437 static ssize_t catia_pwrite(vfs_handle_struct *handle,
1438 files_struct *fsp, const void *data,
1439 size_t n, off_t offset)
1441 struct catia_cache *cc = NULL;
1445 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1450 result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
1452 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1457 static int catia_ftruncate(struct vfs_handle_struct *handle,
1458 struct files_struct *fsp,
1461 struct catia_cache *cc = NULL;
1464 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1469 ret = SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset);
1471 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1476 static int catia_fallocate(struct vfs_handle_struct *handle,
1477 struct files_struct *fsp,
1482 struct catia_cache *cc = NULL;
1485 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1490 ret = SMB_VFS_NEXT_FALLOCATE(handle, fsp, mode, offset, len);
1492 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1497 static ssize_t catia_fgetxattr(struct vfs_handle_struct *handle,
1498 struct files_struct *fsp,
1503 char *mapped_xattr_name = NULL;
1507 status = catia_string_replace_allocate(handle->conn,
1508 name, &mapped_xattr_name,
1509 vfs_translate_to_unix);
1510 if (!NT_STATUS_IS_OK(status)) {
1511 errno = map_errno_from_nt_status(status);
1515 result = SMB_VFS_NEXT_FGETXATTR(handle, fsp, mapped_xattr_name,
1518 TALLOC_FREE(mapped_xattr_name);
1523 static ssize_t catia_flistxattr(struct vfs_handle_struct *handle,
1524 struct files_struct *fsp,
1528 struct catia_cache *cc = NULL;
1532 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1537 result = SMB_VFS_NEXT_FLISTXATTR(handle, fsp, list, size);
1539 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1544 static int catia_fremovexattr(struct vfs_handle_struct *handle,
1545 struct files_struct *fsp,
1548 char *mapped_name = NULL;
1552 status = catia_string_replace_allocate(handle->conn,
1553 name, &mapped_name, vfs_translate_to_unix);
1554 if (!NT_STATUS_IS_OK(status)) {
1555 errno = map_errno_from_nt_status(status);
1559 ret = SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, mapped_name);
1561 TALLOC_FREE(mapped_name);
1566 static int catia_fsetxattr(struct vfs_handle_struct *handle,
1567 struct files_struct *fsp,
1573 char *mapped_xattr_name = NULL;
1577 status = catia_string_replace_allocate(
1578 handle->conn, name, &mapped_xattr_name, vfs_translate_to_unix);
1579 if (!NT_STATUS_IS_OK(status)) {
1580 errno = map_errno_from_nt_status(status);
1584 ret = SMB_VFS_NEXT_FSETXATTR(handle, fsp, mapped_xattr_name,
1585 value, size, flags);
1587 TALLOC_FREE(mapped_xattr_name);
1592 static SMB_ACL_T catia_sys_acl_get_fd(vfs_handle_struct *handle,
1594 TALLOC_CTX *mem_ctx)
1596 struct catia_cache *cc = NULL;
1597 struct smb_acl_t *result = NULL;
1600 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1605 result = SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp, mem_ctx);
1607 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1612 static int catia_sys_acl_blob_get_fd(vfs_handle_struct *handle,
1614 TALLOC_CTX *mem_ctx,
1615 char **blob_description,
1618 struct catia_cache *cc = NULL;
1621 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1626 ret = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle, fsp, mem_ctx,
1627 blob_description, blob);
1629 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1634 static int catia_sys_acl_set_fd(vfs_handle_struct *handle,
1638 struct catia_cache *cc = NULL;
1641 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1646 ret = SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, theacl);
1648 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1653 static NTSTATUS catia_fget_nt_acl(vfs_handle_struct *handle,
1655 uint32_t security_info,
1656 TALLOC_CTX *mem_ctx,
1657 struct security_descriptor **ppdesc)
1659 struct catia_cache *cc = NULL;
1663 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1665 return map_nt_error_from_unix(errno);
1668 status = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info,
1671 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1676 static NTSTATUS catia_fset_nt_acl(vfs_handle_struct *handle,
1678 uint32_t security_info_sent,
1679 const struct security_descriptor *psd)
1681 struct catia_cache *cc = NULL;
1685 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1687 return map_nt_error_from_unix(errno);
1690 status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
1692 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1697 static NTSTATUS catia_fset_dos_attributes(struct vfs_handle_struct *handle,
1698 struct files_struct *fsp,
1701 struct catia_cache *cc = NULL;
1705 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1707 return map_nt_error_from_unix(errno);
1710 status = SMB_VFS_NEXT_FSET_DOS_ATTRIBUTES(handle, fsp, dosmode);
1712 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1717 static NTSTATUS catia_fget_dos_attributes(struct vfs_handle_struct *handle,
1718 struct files_struct *fsp,
1721 struct catia_cache *cc = NULL;
1725 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1727 return map_nt_error_from_unix(errno);
1730 status = SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle, fsp, dosmode);
1732 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1737 static int catia_fchown(vfs_handle_struct *handle,
1742 struct catia_cache *cc = NULL;
1745 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1750 ret = SMB_VFS_NEXT_FCHOWN(handle, fsp, uid, gid);
1752 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1757 static int catia_fchmod(vfs_handle_struct *handle,
1761 struct catia_cache *cc = NULL;
1764 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1769 ret = SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
1771 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1776 struct catia_pread_state {
1778 struct vfs_aio_state vfs_aio_state;
1779 struct files_struct *fsp;
1780 struct catia_cache *cc;
1783 static void catia_pread_done(struct tevent_req *subreq);
1785 static struct tevent_req *catia_pread_send(struct vfs_handle_struct *handle,
1786 TALLOC_CTX *mem_ctx,
1787 struct tevent_context *ev,
1788 struct files_struct *fsp,
1793 struct tevent_req *req = NULL, *subreq = NULL;
1794 struct catia_pread_state *state = NULL;
1797 req = tevent_req_create(mem_ctx, &state,
1798 struct catia_pread_state);
1804 ret = CATIA_FETCH_FSP_PRE_NEXT(state, handle, fsp, &state->cc);
1806 tevent_req_error(req, errno);
1807 return tevent_req_post(req, ev);
1810 subreq = SMB_VFS_NEXT_PREAD_SEND(state, ev, handle, fsp, data,
1812 if (tevent_req_nomem(subreq, req)) {
1813 return tevent_req_post(req, ev);
1815 tevent_req_set_callback(subreq, catia_pread_done, req);
1820 static void catia_pread_done(struct tevent_req *subreq)
1822 struct tevent_req *req = tevent_req_callback_data(
1823 subreq, struct tevent_req);
1824 struct catia_pread_state *state = tevent_req_data(
1825 req, struct catia_pread_state);
1827 state->ret = SMB_VFS_PREAD_RECV(subreq, &state->vfs_aio_state);
1828 TALLOC_FREE(subreq);
1830 CATIA_FETCH_FSP_POST_NEXT(&state->cc, state->fsp);
1832 tevent_req_done(req);
1835 static ssize_t catia_pread_recv(struct tevent_req *req,
1836 struct vfs_aio_state *vfs_aio_state)
1838 struct catia_pread_state *state = tevent_req_data(
1839 req, struct catia_pread_state);
1841 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1845 *vfs_aio_state = state->vfs_aio_state;
1849 struct catia_pwrite_state {
1851 struct vfs_aio_state vfs_aio_state;
1852 struct files_struct *fsp;
1853 struct catia_cache *cc;
1856 static void catia_pwrite_done(struct tevent_req *subreq);
1858 static struct tevent_req *catia_pwrite_send(struct vfs_handle_struct *handle,
1859 TALLOC_CTX *mem_ctx,
1860 struct tevent_context *ev,
1861 struct files_struct *fsp,
1866 struct tevent_req *req = NULL, *subreq = NULL;
1867 struct catia_pwrite_state *state = NULL;
1870 req = tevent_req_create(mem_ctx, &state,
1871 struct catia_pwrite_state);
1877 ret = CATIA_FETCH_FSP_PRE_NEXT(state, handle, fsp, &state->cc);
1879 tevent_req_error(req, errno);
1880 return tevent_req_post(req, ev);
1883 subreq = SMB_VFS_NEXT_PWRITE_SEND(state, ev, handle, fsp, data,
1885 if (tevent_req_nomem(subreq, req)) {
1886 return tevent_req_post(req, ev);
1888 tevent_req_set_callback(subreq, catia_pwrite_done, req);
1893 static void catia_pwrite_done(struct tevent_req *subreq)
1895 struct tevent_req *req = tevent_req_callback_data(
1896 subreq, struct tevent_req);
1897 struct catia_pwrite_state *state = tevent_req_data(
1898 req, struct catia_pwrite_state);
1900 state->ret = SMB_VFS_PWRITE_RECV(subreq, &state->vfs_aio_state);
1901 TALLOC_FREE(subreq);
1903 CATIA_FETCH_FSP_POST_NEXT(&state->cc, state->fsp);
1905 tevent_req_done(req);
1908 static ssize_t catia_pwrite_recv(struct tevent_req *req,
1909 struct vfs_aio_state *vfs_aio_state)
1911 struct catia_pwrite_state *state = tevent_req_data(
1912 req, struct catia_pwrite_state);
1914 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1918 *vfs_aio_state = state->vfs_aio_state;
1922 static off_t catia_lseek(vfs_handle_struct *handle,
1927 struct catia_cache *cc = NULL;
1931 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1936 result = SMB_VFS_NEXT_LSEEK(handle, fsp, offset, whence);
1938 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1943 struct catia_fsync_state {
1945 struct vfs_aio_state vfs_aio_state;
1946 struct files_struct *fsp;
1947 struct catia_cache *cc;
1950 static void catia_fsync_done(struct tevent_req *subreq);
1952 static struct tevent_req *catia_fsync_send(struct vfs_handle_struct *handle,
1953 TALLOC_CTX *mem_ctx,
1954 struct tevent_context *ev,
1955 struct files_struct *fsp)
1957 struct tevent_req *req = NULL, *subreq = NULL;
1958 struct catia_fsync_state *state = NULL;
1961 req = tevent_req_create(mem_ctx, &state,
1962 struct catia_fsync_state);
1968 ret = CATIA_FETCH_FSP_PRE_NEXT(state, handle, fsp, &state->cc);
1970 tevent_req_error(req, errno);
1971 return tevent_req_post(req, ev);
1974 subreq = SMB_VFS_NEXT_FSYNC_SEND(state, ev, handle, fsp);
1975 if (tevent_req_nomem(subreq, req)) {
1976 return tevent_req_post(req, ev);
1978 tevent_req_set_callback(subreq, catia_fsync_done, req);
1983 static void catia_fsync_done(struct tevent_req *subreq)
1985 struct tevent_req *req = tevent_req_callback_data(
1986 subreq, struct tevent_req);
1987 struct catia_fsync_state *state = tevent_req_data(
1988 req, struct catia_fsync_state);
1990 state->ret = SMB_VFS_FSYNC_RECV(subreq, &state->vfs_aio_state);
1991 TALLOC_FREE(subreq);
1993 CATIA_FETCH_FSP_POST_NEXT(&state->cc, state->fsp);
1995 tevent_req_done(req);
1998 static int catia_fsync_recv(struct tevent_req *req,
1999 struct vfs_aio_state *vfs_aio_state)
2001 struct catia_fsync_state *state = tevent_req_data(
2002 req, struct catia_fsync_state);
2004 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
2008 *vfs_aio_state = state->vfs_aio_state;
2012 static bool catia_lock(vfs_handle_struct *handle,
2019 struct catia_cache *cc = NULL;
2023 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2028 ok = SMB_VFS_NEXT_LOCK(handle, fsp, op, offset, count, type);
2030 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2035 static int catia_kernel_flock(struct vfs_handle_struct *handle,
2036 struct files_struct *fsp,
2037 uint32_t share_access,
2038 uint32_t access_mask)
2040 struct catia_cache *cc = NULL;
2043 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2048 ret = SMB_VFS_NEXT_KERNEL_FLOCK(handle, fsp, share_access, access_mask);
2050 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2055 static int catia_linux_setlease(vfs_handle_struct *handle,
2059 struct catia_cache *cc = NULL;
2062 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2067 ret = SMB_VFS_NEXT_LINUX_SETLEASE(handle, fsp, leasetype);
2069 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2074 static bool catia_getlock(vfs_handle_struct *handle,
2081 struct catia_cache *cc = NULL;
2085 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2090 ok = SMB_VFS_NEXT_GETLOCK(handle, fsp, poffset, pcount, ptype, ppid);
2092 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2097 static bool catia_strict_lock_check(struct vfs_handle_struct *handle,
2098 struct files_struct *fsp,
2099 struct lock_struct *plock)
2101 struct catia_cache *cc = NULL;
2105 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2110 ok = SMB_VFS_NEXT_STRICT_LOCK_CHECK(handle, fsp, plock);
2112 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2117 static NTSTATUS catia_fsctl(struct vfs_handle_struct *handle,
2118 struct files_struct *fsp,
2122 const uint8_t *_in_data,
2124 uint8_t **_out_data,
2125 uint32_t max_out_len,
2129 struct catia_cache *cc = NULL;
2132 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2134 return map_nt_error_from_unix(errno);
2137 result = SMB_VFS_NEXT_FSCTL(handle,
2148 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2153 static NTSTATUS catia_get_compression(vfs_handle_struct *handle,
2154 TALLOC_CTX *mem_ctx,
2155 struct files_struct *fsp,
2156 struct smb_filename *smb_fname,
2157 uint16_t *_compression_fmt)
2160 struct catia_cache *cc = NULL;
2162 struct smb_filename *mapped_smb_fname = NULL;
2163 char *mapped_name = NULL;
2166 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2168 return map_nt_error_from_unix(errno);
2170 mapped_smb_fname = fsp->fsp_name;
2172 result = catia_string_replace_allocate(handle->conn,
2173 smb_fname->base_name,
2175 vfs_translate_to_unix);
2176 if (!NT_STATUS_IS_OK(result)) {
2180 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
2185 if (mapped_smb_fname == NULL) {
2186 TALLOC_FREE(mapped_name);
2187 return NT_STATUS_NO_MEMORY;
2190 TALLOC_FREE(mapped_name);
2193 result = SMB_VFS_NEXT_GET_COMPRESSION(handle,
2200 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2202 TALLOC_FREE(mapped_smb_fname);
2208 static NTSTATUS catia_set_compression(vfs_handle_struct *handle,
2209 TALLOC_CTX *mem_ctx,
2210 struct files_struct *fsp,
2211 uint16_t compression_fmt)
2214 struct catia_cache *cc = NULL;
2217 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2219 return map_nt_error_from_unix(errno);
2222 result = SMB_VFS_NEXT_SET_COMPRESSION(handle, mem_ctx, fsp,
2225 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2230 static NTSTATUS catia_readdir_attr(struct vfs_handle_struct *handle,
2231 const struct smb_filename *smb_fname_in,
2232 TALLOC_CTX *mem_ctx,
2233 struct readdir_attr_data **pattr_data)
2235 struct smb_filename *smb_fname;
2239 status = catia_string_replace_allocate(handle->conn,
2240 smb_fname_in->base_name,
2242 vfs_translate_to_unix);
2243 if (!NT_STATUS_IS_OK(status)) {
2244 errno = map_errno_from_nt_status(status);
2248 smb_fname = synthetic_smb_fname(talloc_tos(), fname, NULL,
2249 &smb_fname_in->st, 0);
2251 status = SMB_VFS_NEXT_READDIR_ATTR(handle, smb_fname, mem_ctx, pattr_data);
2253 TALLOC_FREE(smb_fname);
2258 static NTSTATUS catia_get_dos_attributes(struct vfs_handle_struct *handle,
2259 struct smb_filename *smb_fname,
2262 char *mapped_name = NULL;
2263 const char *path = smb_fname->base_name;
2264 struct smb_filename *mapped_smb_fname = NULL;
2267 status = catia_string_replace_allocate(handle->conn,
2268 path, &mapped_name, vfs_translate_to_unix);
2269 if (!NT_STATUS_IS_OK(status)) {
2270 errno = map_errno_from_nt_status(status);
2273 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
2278 if (mapped_smb_fname == NULL) {
2279 TALLOC_FREE(mapped_name);
2280 return NT_STATUS_NO_MEMORY;
2283 status = SMB_VFS_NEXT_GET_DOS_ATTRIBUTES(handle,
2286 if (NT_STATUS_IS_OK(status)) {
2287 smb_fname->st = mapped_smb_fname->st;
2290 TALLOC_FREE(mapped_name);
2291 TALLOC_FREE(mapped_smb_fname);
2296 static NTSTATUS catia_set_dos_attributes(struct vfs_handle_struct *handle,
2297 const struct smb_filename *smb_fname,
2300 char *mapped_name = NULL;
2301 const char *path = smb_fname->base_name;
2302 struct smb_filename *mapped_smb_fname = NULL;
2305 status = catia_string_replace_allocate(handle->conn,
2306 path, &mapped_name, vfs_translate_to_unix);
2307 if (!NT_STATUS_IS_OK(status)) {
2308 errno = map_errno_from_nt_status(status);
2311 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
2316 if (mapped_smb_fname == NULL) {
2317 TALLOC_FREE(mapped_name);
2318 return NT_STATUS_NO_MEMORY;
2321 status = SMB_VFS_NEXT_SET_DOS_ATTRIBUTES(handle,
2324 TALLOC_FREE(mapped_name);
2325 TALLOC_FREE(mapped_smb_fname);
2330 static NTSTATUS catia_create_dfs_pathat(struct vfs_handle_struct *handle,
2331 struct files_struct *dirfsp,
2332 const struct smb_filename *smb_fname,
2333 const struct referral *reflist,
2334 size_t referral_count)
2336 char *mapped_name = NULL;
2337 const char *path = smb_fname->base_name;
2338 struct smb_filename *mapped_smb_fname = NULL;
2341 status = catia_string_replace_allocate(handle->conn,
2344 vfs_translate_to_unix);
2345 if (!NT_STATUS_IS_OK(status)) {
2346 errno = map_errno_from_nt_status(status);
2349 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
2354 if (mapped_smb_fname == NULL) {
2355 TALLOC_FREE(mapped_name);
2356 return NT_STATUS_NO_MEMORY;
2359 status = SMB_VFS_NEXT_CREATE_DFS_PATHAT(handle,
2364 TALLOC_FREE(mapped_name);
2365 TALLOC_FREE(mapped_smb_fname);
2369 static NTSTATUS catia_read_dfs_pathat(struct vfs_handle_struct *handle,
2370 TALLOC_CTX *mem_ctx,
2371 struct files_struct *dirfsp,
2372 const struct smb_filename *smb_fname,
2373 struct referral **ppreflist,
2374 size_t *preferral_count)
2376 char *mapped_name = NULL;
2377 const char *path = smb_fname->base_name;
2378 struct smb_filename *mapped_smb_fname = NULL;
2381 status = catia_string_replace_allocate(handle->conn,
2384 vfs_translate_to_unix);
2385 if (!NT_STATUS_IS_OK(status)) {
2386 errno = map_errno_from_nt_status(status);
2389 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
2394 if (mapped_smb_fname == NULL) {
2395 TALLOC_FREE(mapped_name);
2396 return NT_STATUS_NO_MEMORY;
2399 status = SMB_VFS_NEXT_READ_DFS_PATHAT(handle,
2405 TALLOC_FREE(mapped_name);
2406 TALLOC_FREE(mapped_smb_fname);
2410 static struct vfs_fn_pointers vfs_catia_fns = {
2411 .connect_fn = catia_connect,
2413 /* Directory operations */
2414 .mkdirat_fn = catia_mkdirat,
2415 .readdir_attr_fn = catia_readdir_attr,
2417 /* File operations */
2418 .open_fn = catia_open,
2419 .pread_fn = catia_pread,
2420 .pread_send_fn = catia_pread_send,
2421 .pread_recv_fn = catia_pread_recv,
2422 .pwrite_fn = catia_pwrite,
2423 .pwrite_send_fn = catia_pwrite_send,
2424 .pwrite_recv_fn = catia_pwrite_recv,
2425 .lseek_fn = catia_lseek,
2426 .renameat_fn = catia_renameat,
2427 .fsync_send_fn = catia_fsync_send,
2428 .fsync_recv_fn = catia_fsync_recv,
2429 .stat_fn = catia_stat,
2430 .fstat_fn = catia_fstat,
2431 .lstat_fn = catia_lstat,
2432 .unlinkat_fn = catia_unlinkat,
2433 .chmod_fn = catia_chmod,
2434 .fchmod_fn = catia_fchmod,
2435 .fchown_fn = catia_fchown,
2436 .lchown_fn = catia_lchown,
2437 .chdir_fn = catia_chdir,
2438 .ntimes_fn = catia_ntimes,
2439 .ftruncate_fn = catia_ftruncate,
2440 .fallocate_fn = catia_fallocate,
2441 .lock_fn = catia_lock,
2442 .kernel_flock_fn = catia_kernel_flock,
2443 .linux_setlease_fn = catia_linux_setlease,
2444 .getlock_fn = catia_getlock,
2445 .realpath_fn = catia_realpath,
2446 .chflags_fn = catia_chflags,
2447 .streaminfo_fn = catia_streaminfo,
2448 .strict_lock_check_fn = catia_strict_lock_check,
2449 .translate_name_fn = catia_translate_name,
2450 .fsctl_fn = catia_fsctl,
2451 .get_dos_attributes_fn = catia_get_dos_attributes,
2452 .get_dos_attributes_send_fn = vfs_not_implemented_get_dos_attributes_send,
2453 .get_dos_attributes_recv_fn = vfs_not_implemented_get_dos_attributes_recv,
2454 .set_dos_attributes_fn = catia_set_dos_attributes,
2455 .fset_dos_attributes_fn = catia_fset_dos_attributes,
2456 .fget_dos_attributes_fn = catia_fget_dos_attributes,
2457 .get_compression_fn = catia_get_compression,
2458 .set_compression_fn = catia_set_compression,
2459 .create_dfs_pathat_fn = catia_create_dfs_pathat,
2460 .read_dfs_pathat_fn = catia_read_dfs_pathat,
2462 /* NT ACL operations. */
2463 .get_nt_acl_fn = catia_get_nt_acl,
2464 .fget_nt_acl_fn = catia_fget_nt_acl,
2465 .fset_nt_acl_fn = catia_fset_nt_acl,
2467 /* POSIX ACL operations. */
2468 .sys_acl_get_file_fn = catia_sys_acl_get_file,
2469 .sys_acl_get_fd_fn = catia_sys_acl_get_fd,
2470 .sys_acl_blob_get_fd_fn = catia_sys_acl_blob_get_fd,
2471 .sys_acl_set_file_fn = catia_sys_acl_set_file,
2472 .sys_acl_set_fd_fn = catia_sys_acl_set_fd,
2473 .sys_acl_delete_def_file_fn = catia_sys_acl_delete_def_file,
2475 /* EA operations. */
2476 .getxattr_fn = catia_getxattr,
2477 .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
2478 .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
2479 .listxattr_fn = catia_listxattr,
2480 .removexattr_fn = catia_removexattr,
2481 .setxattr_fn = catia_setxattr,
2482 .fgetxattr_fn = catia_fgetxattr,
2483 .flistxattr_fn = catia_flistxattr,
2484 .fremovexattr_fn = catia_fremovexattr,
2485 .fsetxattr_fn = catia_fsetxattr,
2489 NTSTATUS vfs_catia_init(TALLOC_CTX *ctx)
2493 ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "catia",
2495 if (!NT_STATUS_IS_OK(ret))
2498 vfs_catia_debug_level = debug_add_class("catia");
2499 if (vfs_catia_debug_level == -1) {
2500 vfs_catia_debug_level = DBGC_VFS;
2501 DEBUG(0, ("vfs_catia: Couldn't register custom debugging "
2504 DEBUG(10, ("vfs_catia: Debug class number of "
2505 "'catia': %d\n", vfs_catia_debug_level));