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 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);
174 static DIR *catia_opendir(vfs_handle_struct *handle,
175 const struct smb_filename *smb_fname,
179 char *name_mapped = NULL;
182 struct smb_filename *mapped_smb_fname = NULL;
184 status = catia_string_replace_allocate(handle->conn,
185 smb_fname->base_name,
187 vfs_translate_to_unix);
188 if (!NT_STATUS_IS_OK(status)) {
189 errno = map_errno_from_nt_status(status);
193 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
198 if (mapped_smb_fname == NULL) {
199 TALLOC_FREE(mapped_smb_fname);
204 ret = SMB_VFS_NEXT_OPENDIR(handle, mapped_smb_fname, mask, attr);
206 TALLOC_FREE(name_mapped);
207 TALLOC_FREE(mapped_smb_fname);
213 * TRANSLATE_NAME call which converts the given name to
214 * "WINDOWS displayable" name
216 static NTSTATUS catia_translate_name(struct vfs_handle_struct *handle,
217 const char *orig_name,
218 enum vfs_translate_direction direction,
224 NTSTATUS status, ret;
227 * Copy the supplied name and free the memory for mapped_name,
228 * already allocated by the caller.
229 * We will be allocating new memory for mapped_name in
230 * catia_string_replace_allocate
232 name = talloc_strdup(talloc_tos(), orig_name);
235 return NT_STATUS_NO_MEMORY;
237 status = catia_string_replace_allocate(handle->conn, name,
238 &mapped_name, direction);
241 if (!NT_STATUS_IS_OK(status)) {
245 ret = SMB_VFS_NEXT_TRANSLATE_NAME(handle, mapped_name, direction,
246 mem_ctx, pmapped_name);
248 if (NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) {
249 *pmapped_name = talloc_move(mem_ctx, &mapped_name);
250 /* we need to return the former translation result here */
253 TALLOC_FREE(mapped_name);
259 #define CATIA_DEBUG_CC(lvl, cc, fsp) \
260 catia_debug_cc((lvl), (cc), (fsp), __location__);
262 static void catia_debug_cc(int lvl,
263 struct catia_cache *cc,
265 const char *location)
267 DEBUG(lvl, ("%s: cc [%p] cc->busy [%p] "
269 "fsp [%p] fsp name [%s] "
272 "orig_base_fname [%s] "
276 cc->is_fsp_ext ? "yes" : "no",
277 fsp, fsp_str_dbg(fsp),
278 cc->orig_fname, cc->fname,
279 cc->orig_base_fname, cc->base_fname));
282 static void catia_free_cc(struct catia_cache **_cc,
283 vfs_handle_struct *handle,
286 struct catia_cache *cc = *_cc;
288 if (cc->is_fsp_ext) {
289 VFS_REMOVE_FSP_EXTENSION(handle, fsp);
298 static struct catia_cache *catia_validate_and_apply_cc(
299 vfs_handle_struct *handle,
301 const struct catia_cache * const *busy,
302 bool *make_tmp_cache)
304 struct catia_cache *cc = NULL;
306 *make_tmp_cache = false;
308 cc = (struct catia_cache *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
313 if (cc->busy != NULL) {
314 if (cc->busy == busy) {
315 /* This should never happen */
316 CATIA_DEBUG_CC(0, cc, fsp);
317 smb_panic(__location__);
321 * Recursion. Validate names, the names in the fsp's should be
322 * the translated names we had set.
325 if ((cc->fname != fsp->fsp_name->base_name)
327 ((fsp->base_fsp != NULL) &&
328 (cc->base_fname != fsp->base_fsp->fsp_name->base_name)))
330 CATIA_DEBUG_CC(10, cc, fsp);
333 * Names changed. Setting don't expose the cache on the
334 * fsp and ask the caller to create a temporary cache.
336 *make_tmp_cache = true;
341 * Ok, a validated cache while in a recursion, just let the
342 * caller detect that cc->busy is != busy and there's
343 * nothing else to do.
345 CATIA_DEBUG_CC(10, cc, fsp);
349 /* Not in a recursion */
351 if ((cc->orig_fname != fsp->fsp_name->base_name)
353 ((fsp->base_fsp != NULL) &&
354 (cc->orig_base_fname != fsp->base_fsp->fsp_name->base_name)))
357 * fsp names changed, this can happen in an rename op.
358 * Trigger recreation as a full fledged fsp extension.
361 CATIA_DEBUG_CC(10, cc, fsp);
362 catia_free_cc(&cc, handle, fsp);
368 * Ok, we found a valid cache entry, no recursion. Just set translated
369 * names from the cache and mark the cc as busy.
371 fsp->fsp_name->base_name = cc->fname;
372 if (fsp->base_fsp != NULL) {
373 fsp->base_fsp->fsp_name->base_name = cc->base_fname;
377 CATIA_DEBUG_CC(10, cc, fsp);
381 #define CATIA_FETCH_FSP_PRE_NEXT(mem_ctx, handle, fsp, _cc) \
382 catia_fetch_fsp_pre_next((mem_ctx), (handle), (fsp), (_cc), __func__);
384 static int catia_fetch_fsp_pre_next(TALLOC_CTX *mem_ctx,
385 vfs_handle_struct *handle,
387 struct catia_cache **_cc,
388 const char *function)
390 const struct catia_cache * const *busy =
391 (const struct catia_cache * const *)_cc;
392 struct catia_cache *cc = NULL;
394 bool make_tmp_cache = false;
398 DBG_DEBUG("Called from [%s]\n", function);
400 cc = catia_validate_and_apply_cc(handle,
405 if (cc->busy != busy) {
412 if (!make_tmp_cache) {
413 cc = VFS_ADD_FSP_EXTENSION(
414 handle, fsp, struct catia_cache, NULL);
418 *cc = (struct catia_cache) {
422 mem_ctx = VFS_MEMCTX_FSP_EXTENSION(handle, fsp);
423 if (mem_ctx == NULL) {
424 DBG_ERR("VFS_MEMCTX_FSP_EXTENSION failed\n");
425 catia_free_cc(&cc, handle, fsp);
429 cc = talloc_zero(mem_ctx, struct catia_cache);
437 status = catia_string_replace_allocate(handle->conn,
438 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->fname);
448 if (fsp->base_fsp != NULL) {
449 status = catia_string_replace_allocate(
451 fsp->base_fsp->fsp_name->base_name,
453 vfs_translate_to_unix);
454 if (!NT_STATUS_IS_OK(status)) {
455 catia_free_cc(&cc, handle, fsp);
456 errno = map_errno_from_nt_status(status);
459 talloc_steal(mem_ctx, cc->base_fname);
462 cc->orig_fname = fsp->fsp_name->base_name;
463 fsp->fsp_name->base_name = cc->fname;
465 if (fsp->base_fsp != NULL) {
466 cc->orig_base_fname = fsp->base_fsp->fsp_name->base_name;
467 fsp->base_fsp->fsp_name->base_name = cc->base_fname;
471 CATIA_DEBUG_CC(10, cc, fsp);
478 #define CATIA_FETCH_FSP_POST_NEXT(_cc, fsp) do { \
479 int saved_errno = errno; \
480 catia_fetch_fsp_post_next((_cc), (fsp), __func__); \
481 errno = saved_errno; \
484 static void catia_fetch_fsp_post_next(struct catia_cache **_cc,
486 const char *function)
488 const struct catia_cache * const *busy =
489 (const struct catia_cache * const *)_cc;
490 struct catia_cache *cc = *_cc;
492 DBG_DEBUG("Called from [%s]\n", function);
496 * This can happen when recursing in the VFS on the fsp when the
497 * pre_next func noticed the recursion and set out cc pointer to
503 if (cc->busy != busy) {
504 CATIA_DEBUG_CC(0, cc, fsp);
505 smb_panic(__location__);
512 fsp->fsp_name->base_name = cc->orig_fname;
513 if (fsp->base_fsp != NULL) {
514 fsp->base_fsp->fsp_name->base_name = cc->orig_base_fname;
517 CATIA_DEBUG_CC(10, cc, fsp);
519 if (!cc->is_fsp_ext) {
526 static int catia_open(vfs_handle_struct *handle,
527 struct smb_filename *smb_fname,
532 struct catia_cache *cc = NULL;
533 char *orig_smb_fname = smb_fname->base_name;
534 char *mapped_smb_fname = NULL;
538 status = catia_string_replace_allocate(handle->conn,
539 smb_fname->base_name,
541 vfs_translate_to_unix);
542 if (!NT_STATUS_IS_OK(status)) {
546 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
548 TALLOC_FREE(mapped_smb_fname);
552 smb_fname->base_name = mapped_smb_fname;
553 ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
554 smb_fname->base_name = orig_smb_fname;
556 TALLOC_FREE(mapped_smb_fname);
557 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
562 static int catia_rename(vfs_handle_struct *handle,
563 const struct smb_filename *smb_fname_src,
564 const struct smb_filename *smb_fname_dst)
566 TALLOC_CTX *ctx = talloc_tos();
567 struct smb_filename *smb_fname_src_tmp = NULL;
568 struct smb_filename *smb_fname_dst_tmp = NULL;
569 char *src_name_mapped = NULL;
570 char *dst_name_mapped = NULL;
574 status = catia_string_replace_allocate(handle->conn,
575 smb_fname_src->base_name,
576 &src_name_mapped, vfs_translate_to_unix);
577 if (!NT_STATUS_IS_OK(status)) {
578 errno = map_errno_from_nt_status(status);
582 status = catia_string_replace_allocate(handle->conn,
583 smb_fname_dst->base_name,
584 &dst_name_mapped, vfs_translate_to_unix);
585 if (!NT_STATUS_IS_OK(status)) {
586 errno = map_errno_from_nt_status(status);
590 /* Setup temporary smb_filename structs. */
591 smb_fname_src_tmp = cp_smb_filename(ctx, smb_fname_src);
592 if (smb_fname_src_tmp == NULL) {
597 smb_fname_dst_tmp = cp_smb_filename(ctx, smb_fname_dst);
598 if (smb_fname_dst_tmp == NULL) {
603 smb_fname_src_tmp->base_name = src_name_mapped;
604 smb_fname_dst_tmp->base_name = dst_name_mapped;
605 DEBUG(10, ("converted old name: %s\n",
606 smb_fname_str_dbg(smb_fname_src_tmp)));
607 DEBUG(10, ("converted new name: %s\n",
608 smb_fname_str_dbg(smb_fname_dst_tmp)));
610 ret = SMB_VFS_NEXT_RENAME(handle, smb_fname_src_tmp,
613 TALLOC_FREE(src_name_mapped);
614 TALLOC_FREE(dst_name_mapped);
615 TALLOC_FREE(smb_fname_src_tmp);
616 TALLOC_FREE(smb_fname_dst_tmp);
620 static int catia_stat(vfs_handle_struct *handle,
621 struct smb_filename *smb_fname)
628 status = catia_string_replace_allocate(handle->conn,
629 smb_fname->base_name,
630 &name, vfs_translate_to_unix);
631 if (!NT_STATUS_IS_OK(status)) {
632 errno = map_errno_from_nt_status(status);
636 tmp_base_name = smb_fname->base_name;
637 smb_fname->base_name = name;
639 ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
640 smb_fname->base_name = tmp_base_name;
646 static int catia_lstat(vfs_handle_struct *handle,
647 struct smb_filename *smb_fname)
654 status = catia_string_replace_allocate(handle->conn,
655 smb_fname->base_name,
656 &name, vfs_translate_to_unix);
657 if (!NT_STATUS_IS_OK(status)) {
658 errno = map_errno_from_nt_status(status);
662 tmp_base_name = smb_fname->base_name;
663 smb_fname->base_name = name;
665 ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
666 smb_fname->base_name = tmp_base_name;
672 static int catia_unlink(vfs_handle_struct *handle,
673 const struct smb_filename *smb_fname)
675 struct smb_filename *smb_fname_tmp = NULL;
680 status = catia_string_replace_allocate(handle->conn,
681 smb_fname->base_name,
682 &name, vfs_translate_to_unix);
683 if (!NT_STATUS_IS_OK(status)) {
684 errno = map_errno_from_nt_status(status);
688 /* Setup temporary smb_filename structs. */
689 smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
690 if (smb_fname_tmp == NULL) {
695 smb_fname_tmp->base_name = name;
696 ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname_tmp);
697 TALLOC_FREE(smb_fname_tmp);
703 static int catia_chown(vfs_handle_struct *handle,
704 const struct smb_filename *smb_fname,
712 struct smb_filename *catia_smb_fname = NULL;
714 status = catia_string_replace_allocate(handle->conn,
715 smb_fname->base_name,
717 vfs_translate_to_unix);
718 if (!NT_STATUS_IS_OK(status)) {
719 errno = map_errno_from_nt_status(status);
722 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
727 if (catia_smb_fname == NULL) {
733 ret = SMB_VFS_NEXT_CHOWN(handle, catia_smb_fname, uid, gid);
736 TALLOC_FREE(catia_smb_fname);
741 static int catia_lchown(vfs_handle_struct *handle,
742 const struct smb_filename *smb_fname,
750 struct smb_filename *catia_smb_fname = NULL;
752 status = catia_string_replace_allocate(handle->conn,
753 smb_fname->base_name,
755 vfs_translate_to_unix);
756 if (!NT_STATUS_IS_OK(status)) {
757 errno = map_errno_from_nt_status(status);
760 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
765 if (catia_smb_fname == NULL) {
771 ret = SMB_VFS_NEXT_LCHOWN(handle, catia_smb_fname, uid, gid);
774 TALLOC_FREE(catia_smb_fname);
779 static int catia_chmod(vfs_handle_struct *handle,
780 const struct smb_filename *smb_fname,
787 struct smb_filename *catia_smb_fname = NULL;
789 status = catia_string_replace_allocate(handle->conn,
790 smb_fname->base_name,
792 vfs_translate_to_unix);
793 if (!NT_STATUS_IS_OK(status)) {
794 errno = map_errno_from_nt_status(status);
797 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
802 if (catia_smb_fname == NULL) {
808 ret = SMB_VFS_NEXT_CHMOD(handle, catia_smb_fname, mode);
811 TALLOC_FREE(catia_smb_fname);
816 static int catia_rmdir(vfs_handle_struct *handle,
817 const struct smb_filename *smb_fname)
822 struct smb_filename *catia_smb_fname = NULL;
824 status = catia_string_replace_allocate(handle->conn,
825 smb_fname->base_name,
827 vfs_translate_to_unix);
828 if (!NT_STATUS_IS_OK(status)) {
829 errno = map_errno_from_nt_status(status);
832 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
837 if (catia_smb_fname == NULL) {
843 ret = SMB_VFS_NEXT_RMDIR(handle, catia_smb_fname);
845 TALLOC_FREE(catia_smb_fname);
850 static int catia_mkdir(vfs_handle_struct *handle,
851 const struct smb_filename *smb_fname,
857 struct smb_filename *catia_smb_fname = NULL;
859 status = catia_string_replace_allocate(handle->conn,
860 smb_fname->base_name,
862 vfs_translate_to_unix);
863 if (!NT_STATUS_IS_OK(status)) {
864 errno = map_errno_from_nt_status(status);
867 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
872 if (catia_smb_fname == NULL) {
878 ret = SMB_VFS_NEXT_MKDIR(handle, catia_smb_fname, mode);
880 TALLOC_FREE(catia_smb_fname);
885 static int catia_chdir(vfs_handle_struct *handle,
886 const struct smb_filename *smb_fname)
889 struct smb_filename *catia_smb_fname = NULL;
893 status = catia_string_replace_allocate(handle->conn,
894 smb_fname->base_name,
896 vfs_translate_to_unix);
897 if (!NT_STATUS_IS_OK(status)) {
898 errno = map_errno_from_nt_status(status);
902 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
907 if (catia_smb_fname == NULL) {
912 ret = SMB_VFS_NEXT_CHDIR(handle, catia_smb_fname);
914 TALLOC_FREE(catia_smb_fname);
919 static int catia_ntimes(vfs_handle_struct *handle,
920 const struct smb_filename *smb_fname,
921 struct smb_file_time *ft)
923 struct smb_filename *smb_fname_tmp = NULL;
928 status = catia_string_replace_allocate(handle->conn,
929 smb_fname->base_name,
930 &name, vfs_translate_to_unix);
931 if (!NT_STATUS_IS_OK(status)) {
932 errno = map_errno_from_nt_status(status);
936 smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
937 if (smb_fname_tmp == NULL) {
942 smb_fname_tmp->base_name = name;
943 ret = SMB_VFS_NEXT_NTIMES(handle, smb_fname_tmp, ft);
945 TALLOC_FREE(smb_fname_tmp);
950 static struct smb_filename *
951 catia_realpath(vfs_handle_struct *handle,
953 const struct smb_filename *smb_fname)
955 char *mapped_name = NULL;
956 struct smb_filename *catia_smb_fname = NULL;
957 struct smb_filename *return_fname = NULL;
960 status = catia_string_replace_allocate(handle->conn,
961 smb_fname->base_name,
962 &mapped_name, vfs_translate_to_unix);
963 if (!NT_STATUS_IS_OK(status)) {
964 errno = map_errno_from_nt_status(status);
968 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
973 if (catia_smb_fname == NULL) {
974 TALLOC_FREE(mapped_name);
978 return_fname = SMB_VFS_NEXT_REALPATH(handle, ctx, catia_smb_fname);
979 TALLOC_FREE(mapped_name);
980 TALLOC_FREE(catia_smb_fname);
984 static int catia_chflags(struct vfs_handle_struct *handle,
985 const struct smb_filename *smb_fname,
989 struct smb_filename *catia_smb_fname = NULL;
993 status = catia_string_replace_allocate(handle->conn,
994 smb_fname->base_name,
996 vfs_translate_to_unix);
997 if (!NT_STATUS_IS_OK(status)) {
998 errno = map_errno_from_nt_status(status);
1001 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
1006 if (catia_smb_fname == NULL) {
1012 ret = SMB_VFS_NEXT_CHFLAGS(handle, catia_smb_fname, flags);
1014 TALLOC_FREE(catia_smb_fname);
1020 catia_streaminfo(struct vfs_handle_struct *handle,
1021 struct files_struct *fsp,
1022 const struct smb_filename *smb_fname,
1023 TALLOC_CTX *mem_ctx,
1024 unsigned int *_num_streams,
1025 struct stream_struct **_streams)
1027 char *mapped_name = NULL;
1030 struct smb_filename *catia_smb_fname = NULL;
1031 unsigned int num_streams = 0;
1032 struct stream_struct *streams = NULL;
1037 status = catia_string_replace_allocate(handle->conn,
1038 smb_fname->base_name,
1040 vfs_translate_to_unix);
1041 if (!NT_STATUS_IS_OK(status)) {
1042 errno = map_errno_from_nt_status(status);
1046 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
1051 if (catia_smb_fname == NULL) {
1052 TALLOC_FREE(mapped_name);
1053 return NT_STATUS_NO_MEMORY;
1056 status = SMB_VFS_NEXT_STREAMINFO(handle, fsp, catia_smb_fname,
1057 mem_ctx, &num_streams, &streams);
1058 TALLOC_FREE(mapped_name);
1059 TALLOC_FREE(catia_smb_fname);
1060 if (!NT_STATUS_IS_OK(status)) {
1065 * Translate stream names just like the base names
1067 for (i = 0; i < num_streams; i++) {
1069 * Strip ":" prefix and ":$DATA" suffix to get a
1070 * "pure" stream name and only translate that.
1072 void *old_ptr = streams[i].name;
1073 char *stream_name = streams[i].name + 1;
1074 char *stream_type = strrchr_m(stream_name, ':');
1076 if (stream_type != NULL) {
1077 *stream_type = '\0';
1081 status = catia_string_replace_allocate(handle->conn, stream_name,
1082 &mapped_name, vfs_translate_to_windows);
1083 if (!NT_STATUS_IS_OK(status)) {
1084 TALLOC_FREE(streams);
1088 if (stream_type != NULL) {
1089 streams[i].name = talloc_asprintf(streams, ":%s:%s",
1090 mapped_name, stream_type);
1092 streams[i].name = talloc_asprintf(streams, ":%s",
1095 TALLOC_FREE(mapped_name);
1096 TALLOC_FREE(old_ptr);
1097 if (streams[i].name == NULL) {
1098 TALLOC_FREE(streams);
1099 return NT_STATUS_NO_MEMORY;
1103 *_num_streams = num_streams;
1104 *_streams = streams;
1105 return NT_STATUS_OK;
1109 catia_get_nt_acl(struct vfs_handle_struct *handle,
1110 const struct smb_filename *smb_fname,
1111 uint32_t security_info,
1112 TALLOC_CTX *mem_ctx,
1113 struct security_descriptor **ppdesc)
1115 char *mapped_name = NULL;
1116 const char *path = smb_fname->base_name;
1117 struct smb_filename *mapped_smb_fname = NULL;
1120 status = catia_string_replace_allocate(handle->conn,
1121 path, &mapped_name, vfs_translate_to_unix);
1122 if (!NT_STATUS_IS_OK(status)) {
1123 errno = map_errno_from_nt_status(status);
1126 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1131 if (mapped_smb_fname == NULL) {
1132 TALLOC_FREE(mapped_name);
1133 return NT_STATUS_NO_MEMORY;
1136 status = SMB_VFS_NEXT_GET_NT_ACL(handle, mapped_smb_fname,
1137 security_info, mem_ctx, ppdesc);
1138 TALLOC_FREE(mapped_name);
1139 TALLOC_FREE(mapped_smb_fname);
1145 catia_sys_acl_get_file(vfs_handle_struct *handle,
1146 const struct smb_filename *smb_fname,
1147 SMB_ACL_TYPE_T type,
1148 TALLOC_CTX *mem_ctx)
1150 char *mapped_name = NULL;
1151 struct smb_filename *mapped_smb_fname = NULL;
1154 int saved_errno = 0;
1156 status = catia_string_replace_allocate(handle->conn,
1157 smb_fname->base_name,
1159 vfs_translate_to_unix);
1160 if (!NT_STATUS_IS_OK(status)) {
1161 errno = map_errno_from_nt_status(status);
1162 return (SMB_ACL_T)NULL;
1165 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1170 if (mapped_smb_fname == NULL) {
1171 TALLOC_FREE(mapped_name);
1173 return (SMB_ACL_T)NULL;
1176 ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, mapped_smb_fname,
1178 if (ret == (SMB_ACL_T)NULL) {
1179 saved_errno = errno;
1181 TALLOC_FREE(mapped_smb_fname);
1182 TALLOC_FREE(mapped_name);
1183 if (saved_errno != 0) {
1184 errno = saved_errno;
1190 catia_sys_acl_set_file(vfs_handle_struct *handle,
1191 const struct smb_filename *smb_fname,
1192 SMB_ACL_TYPE_T type,
1195 struct smb_filename *mapped_smb_fname = NULL;
1196 int saved_errno = 0;
1197 char *mapped_name = NULL;
1201 status = catia_string_replace_allocate(handle->conn,
1202 smb_fname->base_name,
1204 vfs_translate_to_unix);
1205 if (!NT_STATUS_IS_OK(status)) {
1206 errno = map_errno_from_nt_status(status);
1210 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1215 if (mapped_smb_fname == NULL) {
1216 TALLOC_FREE(mapped_name);
1221 ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, mapped_smb_fname,
1224 saved_errno = errno;
1226 TALLOC_FREE(mapped_smb_fname);
1227 TALLOC_FREE(mapped_name);
1228 if (saved_errno != 0) {
1229 errno = saved_errno;
1235 catia_sys_acl_delete_def_file(vfs_handle_struct *handle,
1236 const struct smb_filename *smb_fname)
1238 struct smb_filename *mapped_smb_fname = NULL;
1239 int saved_errno = 0;
1240 char *mapped_name = NULL;
1244 status = catia_string_replace_allocate(handle->conn,
1245 smb_fname->base_name,
1247 vfs_translate_to_unix);
1248 if (!NT_STATUS_IS_OK(status)) {
1249 errno = map_errno_from_nt_status(status);
1253 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1258 if (mapped_smb_fname == NULL) {
1259 TALLOC_FREE(mapped_name);
1263 ret = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, mapped_smb_fname);
1265 saved_errno = errno;
1267 TALLOC_FREE(mapped_smb_fname);
1268 TALLOC_FREE(mapped_name);
1269 if (saved_errno != 0) {
1270 errno = saved_errno;
1276 catia_getxattr(vfs_handle_struct *handle,
1277 const struct smb_filename *smb_fname,
1282 struct smb_filename *mapped_smb_fname = NULL;
1283 char *mapped_name = NULL;
1284 char *mapped_ea_name = NULL;
1287 int saved_errno = 0;
1289 status = catia_string_replace_allocate(handle->conn,
1290 smb_fname->base_name,
1292 vfs_translate_to_unix);
1293 if (!NT_STATUS_IS_OK(status)) {
1294 errno = map_errno_from_nt_status(status);
1298 status = catia_string_replace_allocate(handle->conn,
1299 name, &mapped_ea_name, vfs_translate_to_unix);
1300 if (!NT_STATUS_IS_OK(status)) {
1301 TALLOC_FREE(mapped_name);
1302 errno = map_errno_from_nt_status(status);
1306 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1311 if (mapped_smb_fname == NULL) {
1312 TALLOC_FREE(mapped_name);
1313 TALLOC_FREE(mapped_ea_name);
1318 ret = SMB_VFS_NEXT_GETXATTR(handle, mapped_smb_fname,
1319 mapped_ea_name, value, size);
1321 saved_errno = errno;
1323 TALLOC_FREE(mapped_name);
1324 TALLOC_FREE(mapped_ea_name);
1325 TALLOC_FREE(mapped_smb_fname);
1326 if (saved_errno != 0) {
1327 errno = saved_errno;
1334 catia_listxattr(vfs_handle_struct *handle,
1335 const struct smb_filename *smb_fname,
1336 char *list, size_t size)
1338 struct smb_filename *mapped_smb_fname = NULL;
1339 char *mapped_name = NULL;
1342 int saved_errno = 0;
1344 status = catia_string_replace_allocate(handle->conn,
1345 smb_fname->base_name,
1347 vfs_translate_to_unix);
1348 if (!NT_STATUS_IS_OK(status)) {
1349 errno = map_errno_from_nt_status(status);
1353 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1358 if (mapped_smb_fname == NULL) {
1359 TALLOC_FREE(mapped_name);
1364 ret = SMB_VFS_NEXT_LISTXATTR(handle, mapped_smb_fname, list, size);
1366 saved_errno = errno;
1368 TALLOC_FREE(mapped_name);
1369 TALLOC_FREE(mapped_smb_fname);
1370 if (saved_errno != 0) {
1371 errno = saved_errno;
1378 catia_removexattr(vfs_handle_struct *handle,
1379 const struct smb_filename *smb_fname,
1382 struct smb_filename *mapped_smb_fname = NULL;
1383 char *mapped_name = NULL;
1384 char *mapped_ea_name = NULL;
1387 int saved_errno = 0;
1389 status = catia_string_replace_allocate(handle->conn,
1390 smb_fname->base_name,
1392 vfs_translate_to_unix);
1393 if (!NT_STATUS_IS_OK(status)) {
1394 errno = map_errno_from_nt_status(status);
1398 status = catia_string_replace_allocate(handle->conn,
1399 name, &mapped_ea_name, vfs_translate_to_unix);
1400 if (!NT_STATUS_IS_OK(status)) {
1401 TALLOC_FREE(mapped_name);
1402 errno = map_errno_from_nt_status(status);
1406 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1411 if (mapped_smb_fname == NULL) {
1412 TALLOC_FREE(mapped_name);
1413 TALLOC_FREE(mapped_ea_name);
1418 ret = SMB_VFS_NEXT_REMOVEXATTR(handle, mapped_smb_fname,
1421 saved_errno = errno;
1423 TALLOC_FREE(mapped_name);
1424 TALLOC_FREE(mapped_ea_name);
1425 TALLOC_FREE(mapped_smb_fname);
1426 if (saved_errno != 0) {
1427 errno = saved_errno;
1434 catia_setxattr(vfs_handle_struct *handle,
1435 const struct smb_filename *smb_fname,
1441 struct smb_filename *mapped_smb_fname = NULL;
1442 char *mapped_name = NULL;
1443 char *mapped_ea_name = NULL;
1446 int saved_errno = 0;
1448 status = catia_string_replace_allocate(handle->conn,
1449 smb_fname->base_name,
1451 vfs_translate_to_unix);
1452 if (!NT_STATUS_IS_OK(status)) {
1453 errno = map_errno_from_nt_status(status);
1457 status = catia_string_replace_allocate(handle->conn,
1458 name, &mapped_ea_name, vfs_translate_to_unix);
1459 if (!NT_STATUS_IS_OK(status)) {
1460 TALLOC_FREE(mapped_name);
1461 errno = map_errno_from_nt_status(status);
1465 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1470 if (mapped_smb_fname == NULL) {
1471 TALLOC_FREE(mapped_name);
1472 TALLOC_FREE(mapped_ea_name);
1477 ret = SMB_VFS_NEXT_SETXATTR(handle, mapped_smb_fname, mapped_ea_name,
1478 value, size, flags);
1480 saved_errno = errno;
1482 TALLOC_FREE(mapped_name);
1483 TALLOC_FREE(mapped_ea_name);
1484 TALLOC_FREE(mapped_smb_fname);
1485 if (saved_errno != 0) {
1486 errno = saved_errno;
1492 static int catia_fstat(vfs_handle_struct *handle,
1494 SMB_STRUCT_STAT *sbuf)
1496 struct catia_cache *cc = NULL;
1499 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1504 ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
1506 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1511 static ssize_t catia_pread(vfs_handle_struct *handle,
1512 files_struct *fsp, void *data,
1513 size_t n, off_t offset)
1515 struct catia_cache *cc = NULL;
1519 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1524 result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
1526 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1531 static ssize_t catia_pwrite(vfs_handle_struct *handle,
1532 files_struct *fsp, const void *data,
1533 size_t n, off_t offset)
1535 struct catia_cache *cc = NULL;
1539 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1544 result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
1546 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1551 static int catia_ftruncate(struct vfs_handle_struct *handle,
1552 struct files_struct *fsp,
1555 struct catia_cache *cc = NULL;
1558 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1563 ret = SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset);
1565 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1570 static int catia_fallocate(struct vfs_handle_struct *handle,
1571 struct files_struct *fsp,
1576 struct catia_cache *cc = NULL;
1579 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1584 ret = SMB_VFS_NEXT_FALLOCATE(handle, fsp, mode, offset, len);
1586 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1591 static ssize_t catia_fgetxattr(struct vfs_handle_struct *handle,
1592 struct files_struct *fsp,
1597 char *mapped_xattr_name = NULL;
1601 status = catia_string_replace_allocate(handle->conn,
1602 name, &mapped_xattr_name,
1603 vfs_translate_to_unix);
1604 if (!NT_STATUS_IS_OK(status)) {
1605 errno = map_errno_from_nt_status(status);
1609 result = SMB_VFS_NEXT_FGETXATTR(handle, fsp, mapped_xattr_name,
1612 TALLOC_FREE(mapped_xattr_name);
1617 static ssize_t catia_flistxattr(struct vfs_handle_struct *handle,
1618 struct files_struct *fsp,
1622 struct catia_cache *cc = NULL;
1626 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1631 result = SMB_VFS_NEXT_FLISTXATTR(handle, fsp, list, size);
1633 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1638 static int catia_fremovexattr(struct vfs_handle_struct *handle,
1639 struct files_struct *fsp,
1642 char *mapped_name = NULL;
1646 status = catia_string_replace_allocate(handle->conn,
1647 name, &mapped_name, vfs_translate_to_unix);
1648 if (!NT_STATUS_IS_OK(status)) {
1649 errno = map_errno_from_nt_status(status);
1653 ret = SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, mapped_name);
1655 TALLOC_FREE(mapped_name);
1660 static int catia_fsetxattr(struct vfs_handle_struct *handle,
1661 struct files_struct *fsp,
1667 char *mapped_xattr_name = NULL;
1671 status = catia_string_replace_allocate(
1672 handle->conn, name, &mapped_xattr_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_FSETXATTR(handle, fsp, mapped_xattr_name,
1679 value, size, flags);
1681 TALLOC_FREE(mapped_xattr_name);
1686 static SMB_ACL_T catia_sys_acl_get_fd(vfs_handle_struct *handle,
1688 TALLOC_CTX *mem_ctx)
1690 struct catia_cache *cc = NULL;
1691 struct smb_acl_t *result = NULL;
1694 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1699 result = SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp, mem_ctx);
1701 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1706 static int catia_sys_acl_blob_get_fd(vfs_handle_struct *handle,
1708 TALLOC_CTX *mem_ctx,
1709 char **blob_description,
1712 struct catia_cache *cc = NULL;
1715 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1720 ret = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle, fsp, mem_ctx,
1721 blob_description, blob);
1723 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1728 static int catia_sys_acl_set_fd(vfs_handle_struct *handle,
1732 struct catia_cache *cc = NULL;
1735 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1740 ret = SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, theacl);
1742 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1747 static NTSTATUS catia_fget_nt_acl(vfs_handle_struct *handle,
1749 uint32_t security_info,
1750 TALLOC_CTX *mem_ctx,
1751 struct security_descriptor **ppdesc)
1753 struct catia_cache *cc = NULL;
1757 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1759 return map_nt_error_from_unix(errno);
1762 status = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info,
1765 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1770 static NTSTATUS catia_fset_nt_acl(vfs_handle_struct *handle,
1772 uint32_t security_info_sent,
1773 const struct security_descriptor *psd)
1775 struct catia_cache *cc = NULL;
1779 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1781 return map_nt_error_from_unix(errno);
1784 status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
1786 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1791 static NTSTATUS catia_fset_dos_attributes(struct vfs_handle_struct *handle,
1792 struct files_struct *fsp,
1795 struct catia_cache *cc = NULL;
1799 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1801 return map_nt_error_from_unix(errno);
1804 status = SMB_VFS_NEXT_FSET_DOS_ATTRIBUTES(handle, fsp, dosmode);
1806 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1811 static NTSTATUS catia_fget_dos_attributes(struct vfs_handle_struct *handle,
1812 struct files_struct *fsp,
1815 struct catia_cache *cc = NULL;
1819 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1821 return map_nt_error_from_unix(errno);
1824 status = SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle, fsp, dosmode);
1826 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1831 static int catia_fchown(vfs_handle_struct *handle,
1836 struct catia_cache *cc = NULL;
1839 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1844 ret = SMB_VFS_NEXT_FCHOWN(handle, fsp, uid, gid);
1846 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1851 static int catia_fchmod(vfs_handle_struct *handle,
1855 struct catia_cache *cc = NULL;
1858 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1863 ret = SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
1865 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1870 struct catia_pread_state {
1872 struct vfs_aio_state vfs_aio_state;
1873 struct files_struct *fsp;
1874 struct catia_cache *cc;
1877 static void catia_pread_done(struct tevent_req *subreq);
1879 static struct tevent_req *catia_pread_send(struct vfs_handle_struct *handle,
1880 TALLOC_CTX *mem_ctx,
1881 struct tevent_context *ev,
1882 struct files_struct *fsp,
1887 struct tevent_req *req = NULL, *subreq = NULL;
1888 struct catia_pread_state *state = NULL;
1891 req = tevent_req_create(mem_ctx, &state,
1892 struct catia_pread_state);
1898 ret = CATIA_FETCH_FSP_PRE_NEXT(state, handle, fsp, &state->cc);
1900 tevent_req_error(req, errno);
1901 return tevent_req_post(req, ev);
1904 subreq = SMB_VFS_NEXT_PREAD_SEND(state, ev, handle, fsp, data,
1906 if (tevent_req_nomem(subreq, req)) {
1907 return tevent_req_post(req, ev);
1909 tevent_req_set_callback(subreq, catia_pread_done, req);
1914 static void catia_pread_done(struct tevent_req *subreq)
1916 struct tevent_req *req = tevent_req_callback_data(
1917 subreq, struct tevent_req);
1918 struct catia_pread_state *state = tevent_req_data(
1919 req, struct catia_pread_state);
1921 state->ret = SMB_VFS_PREAD_RECV(subreq, &state->vfs_aio_state);
1922 TALLOC_FREE(subreq);
1924 CATIA_FETCH_FSP_POST_NEXT(&state->cc, state->fsp);
1926 tevent_req_done(req);
1929 static ssize_t catia_pread_recv(struct tevent_req *req,
1930 struct vfs_aio_state *vfs_aio_state)
1932 struct catia_pread_state *state = tevent_req_data(
1933 req, struct catia_pread_state);
1935 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1939 *vfs_aio_state = state->vfs_aio_state;
1943 struct catia_pwrite_state {
1945 struct vfs_aio_state vfs_aio_state;
1946 struct files_struct *fsp;
1947 struct catia_cache *cc;
1950 static void catia_pwrite_done(struct tevent_req *subreq);
1952 static struct tevent_req *catia_pwrite_send(struct vfs_handle_struct *handle,
1953 TALLOC_CTX *mem_ctx,
1954 struct tevent_context *ev,
1955 struct files_struct *fsp,
1960 struct tevent_req *req = NULL, *subreq = NULL;
1961 struct catia_pwrite_state *state = NULL;
1964 req = tevent_req_create(mem_ctx, &state,
1965 struct catia_pwrite_state);
1971 ret = CATIA_FETCH_FSP_PRE_NEXT(state, handle, fsp, &state->cc);
1973 tevent_req_error(req, errno);
1974 return tevent_req_post(req, ev);
1977 subreq = SMB_VFS_NEXT_PWRITE_SEND(state, ev, handle, fsp, data,
1979 if (tevent_req_nomem(subreq, req)) {
1980 return tevent_req_post(req, ev);
1982 tevent_req_set_callback(subreq, catia_pwrite_done, req);
1987 static void catia_pwrite_done(struct tevent_req *subreq)
1989 struct tevent_req *req = tevent_req_callback_data(
1990 subreq, struct tevent_req);
1991 struct catia_pwrite_state *state = tevent_req_data(
1992 req, struct catia_pwrite_state);
1994 state->ret = SMB_VFS_PWRITE_RECV(subreq, &state->vfs_aio_state);
1995 TALLOC_FREE(subreq);
1997 CATIA_FETCH_FSP_POST_NEXT(&state->cc, state->fsp);
1999 tevent_req_done(req);
2002 static ssize_t catia_pwrite_recv(struct tevent_req *req,
2003 struct vfs_aio_state *vfs_aio_state)
2005 struct catia_pwrite_state *state = tevent_req_data(
2006 req, struct catia_pwrite_state);
2008 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
2012 *vfs_aio_state = state->vfs_aio_state;
2016 static off_t catia_lseek(vfs_handle_struct *handle,
2021 struct catia_cache *cc = NULL;
2025 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2030 result = SMB_VFS_NEXT_LSEEK(handle, fsp, offset, whence);
2032 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2037 struct catia_fsync_state {
2039 struct vfs_aio_state vfs_aio_state;
2040 struct files_struct *fsp;
2041 struct catia_cache *cc;
2044 static void catia_fsync_done(struct tevent_req *subreq);
2046 static struct tevent_req *catia_fsync_send(struct vfs_handle_struct *handle,
2047 TALLOC_CTX *mem_ctx,
2048 struct tevent_context *ev,
2049 struct files_struct *fsp)
2051 struct tevent_req *req = NULL, *subreq = NULL;
2052 struct catia_fsync_state *state = NULL;
2055 req = tevent_req_create(mem_ctx, &state,
2056 struct catia_fsync_state);
2062 ret = CATIA_FETCH_FSP_PRE_NEXT(state, handle, fsp, &state->cc);
2064 tevent_req_error(req, errno);
2065 return tevent_req_post(req, ev);
2068 subreq = SMB_VFS_NEXT_FSYNC_SEND(state, ev, handle, fsp);
2069 if (tevent_req_nomem(subreq, req)) {
2070 return tevent_req_post(req, ev);
2072 tevent_req_set_callback(subreq, catia_fsync_done, req);
2077 static void catia_fsync_done(struct tevent_req *subreq)
2079 struct tevent_req *req = tevent_req_callback_data(
2080 subreq, struct tevent_req);
2081 struct catia_fsync_state *state = tevent_req_data(
2082 req, struct catia_fsync_state);
2084 state->ret = SMB_VFS_FSYNC_RECV(subreq, &state->vfs_aio_state);
2085 TALLOC_FREE(subreq);
2087 CATIA_FETCH_FSP_POST_NEXT(&state->cc, state->fsp);
2089 tevent_req_done(req);
2092 static int catia_fsync_recv(struct tevent_req *req,
2093 struct vfs_aio_state *vfs_aio_state)
2095 struct catia_fsync_state *state = tevent_req_data(
2096 req, struct catia_fsync_state);
2098 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
2102 *vfs_aio_state = state->vfs_aio_state;
2106 static bool catia_lock(vfs_handle_struct *handle,
2113 struct catia_cache *cc = NULL;
2117 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2122 ok = SMB_VFS_NEXT_LOCK(handle, fsp, op, offset, count, type);
2124 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2129 static int catia_kernel_flock(struct vfs_handle_struct *handle,
2130 struct files_struct *fsp,
2131 uint32_t share_mode,
2132 uint32_t access_mask)
2134 struct catia_cache *cc = NULL;
2137 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2142 ret = SMB_VFS_NEXT_KERNEL_FLOCK(handle, fsp, share_mode, access_mask);
2144 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2149 static int catia_linux_setlease(vfs_handle_struct *handle,
2153 struct catia_cache *cc = NULL;
2156 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2161 ret = SMB_VFS_NEXT_LINUX_SETLEASE(handle, fsp, leasetype);
2163 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2168 static bool catia_getlock(vfs_handle_struct *handle,
2175 struct catia_cache *cc = NULL;
2179 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2184 ok = SMB_VFS_NEXT_GETLOCK(handle, fsp, poffset, pcount, ptype, ppid);
2186 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2191 static bool catia_strict_lock_check(struct vfs_handle_struct *handle,
2192 struct files_struct *fsp,
2193 struct lock_struct *plock)
2195 struct catia_cache *cc = NULL;
2199 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2204 ok = SMB_VFS_NEXT_STRICT_LOCK_CHECK(handle, fsp, plock);
2206 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2211 static NTSTATUS catia_fsctl(struct vfs_handle_struct *handle,
2212 struct files_struct *fsp,
2216 const uint8_t *_in_data,
2218 uint8_t **_out_data,
2219 uint32_t max_out_len,
2223 struct catia_cache *cc = NULL;
2226 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2228 return map_nt_error_from_unix(errno);
2231 result = SMB_VFS_NEXT_FSCTL(handle,
2242 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2247 static NTSTATUS catia_get_compression(vfs_handle_struct *handle,
2248 TALLOC_CTX *mem_ctx,
2249 struct files_struct *fsp,
2250 struct smb_filename *smb_fname,
2251 uint16_t *_compression_fmt)
2254 struct catia_cache *cc = NULL;
2256 struct smb_filename *mapped_smb_fname = NULL;
2257 char *mapped_name = NULL;
2260 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2262 return map_nt_error_from_unix(errno);
2264 mapped_smb_fname = fsp->fsp_name;
2266 result = catia_string_replace_allocate(handle->conn,
2267 smb_fname->base_name,
2269 vfs_translate_to_unix);
2270 if (!NT_STATUS_IS_OK(result)) {
2274 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
2279 if (mapped_smb_fname == NULL) {
2280 TALLOC_FREE(mapped_name);
2281 return NT_STATUS_NO_MEMORY;
2284 TALLOC_FREE(mapped_name);
2287 result = SMB_VFS_NEXT_GET_COMPRESSION(handle,
2294 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2296 TALLOC_FREE(mapped_smb_fname);
2302 static NTSTATUS catia_set_compression(vfs_handle_struct *handle,
2303 TALLOC_CTX *mem_ctx,
2304 struct files_struct *fsp,
2305 uint16_t compression_fmt)
2308 struct catia_cache *cc = NULL;
2311 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2313 return map_nt_error_from_unix(errno);
2316 result = SMB_VFS_NEXT_SET_COMPRESSION(handle, mem_ctx, fsp,
2319 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2324 static NTSTATUS catia_readdir_attr(struct vfs_handle_struct *handle,
2325 const struct smb_filename *smb_fname_in,
2326 TALLOC_CTX *mem_ctx,
2327 struct readdir_attr_data **pattr_data)
2329 struct smb_filename *smb_fname;
2333 status = catia_string_replace_allocate(handle->conn,
2334 smb_fname_in->base_name,
2336 vfs_translate_to_unix);
2337 if (!NT_STATUS_IS_OK(status)) {
2338 errno = map_errno_from_nt_status(status);
2342 smb_fname = synthetic_smb_fname(talloc_tos(), fname, NULL,
2343 &smb_fname_in->st, 0);
2345 status = SMB_VFS_NEXT_READDIR_ATTR(handle, smb_fname, mem_ctx, pattr_data);
2347 TALLOC_FREE(smb_fname);
2352 static NTSTATUS catia_get_dos_attributes(struct vfs_handle_struct *handle,
2353 struct smb_filename *smb_fname,
2356 char *mapped_name = NULL;
2357 const char *path = smb_fname->base_name;
2358 struct smb_filename *mapped_smb_fname = NULL;
2361 status = catia_string_replace_allocate(handle->conn,
2362 path, &mapped_name, vfs_translate_to_unix);
2363 if (!NT_STATUS_IS_OK(status)) {
2364 errno = map_errno_from_nt_status(status);
2367 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
2372 if (mapped_smb_fname == NULL) {
2373 TALLOC_FREE(mapped_name);
2374 return NT_STATUS_NO_MEMORY;
2377 status = SMB_VFS_NEXT_GET_DOS_ATTRIBUTES(handle,
2380 TALLOC_FREE(mapped_name);
2381 TALLOC_FREE(mapped_smb_fname);
2386 static NTSTATUS catia_set_dos_attributes(struct vfs_handle_struct *handle,
2387 const struct smb_filename *smb_fname,
2390 char *mapped_name = NULL;
2391 const char *path = smb_fname->base_name;
2392 struct smb_filename *mapped_smb_fname = NULL;
2395 status = catia_string_replace_allocate(handle->conn,
2396 path, &mapped_name, vfs_translate_to_unix);
2397 if (!NT_STATUS_IS_OK(status)) {
2398 errno = map_errno_from_nt_status(status);
2401 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
2406 if (mapped_smb_fname == NULL) {
2407 TALLOC_FREE(mapped_name);
2408 return NT_STATUS_NO_MEMORY;
2411 status = SMB_VFS_NEXT_SET_DOS_ATTRIBUTES(handle,
2414 TALLOC_FREE(mapped_name);
2415 TALLOC_FREE(mapped_smb_fname);
2420 static struct vfs_fn_pointers vfs_catia_fns = {
2421 .connect_fn = catia_connect,
2423 /* Directory operations */
2424 .mkdir_fn = catia_mkdir,
2425 .rmdir_fn = catia_rmdir,
2426 .opendir_fn = catia_opendir,
2427 .readdir_attr_fn = catia_readdir_attr,
2429 /* File operations */
2430 .open_fn = catia_open,
2431 .pread_fn = catia_pread,
2432 .pread_send_fn = catia_pread_send,
2433 .pread_recv_fn = catia_pread_recv,
2434 .pwrite_fn = catia_pwrite,
2435 .pwrite_send_fn = catia_pwrite_send,
2436 .pwrite_recv_fn = catia_pwrite_recv,
2437 .lseek_fn = catia_lseek,
2438 .rename_fn = catia_rename,
2439 .fsync_send_fn = catia_fsync_send,
2440 .fsync_recv_fn = catia_fsync_recv,
2441 .stat_fn = catia_stat,
2442 .fstat_fn = catia_fstat,
2443 .lstat_fn = catia_lstat,
2444 .unlink_fn = catia_unlink,
2445 .chmod_fn = catia_chmod,
2446 .fchmod_fn = catia_fchmod,
2447 .chown_fn = catia_chown,
2448 .fchown_fn = catia_fchown,
2449 .lchown_fn = catia_lchown,
2450 .chdir_fn = catia_chdir,
2451 .ntimes_fn = catia_ntimes,
2452 .ftruncate_fn = catia_ftruncate,
2453 .fallocate_fn = catia_fallocate,
2454 .lock_fn = catia_lock,
2455 .kernel_flock_fn = catia_kernel_flock,
2456 .linux_setlease_fn = catia_linux_setlease,
2457 .getlock_fn = catia_getlock,
2458 .realpath_fn = catia_realpath,
2459 .chflags_fn = catia_chflags,
2460 .streaminfo_fn = catia_streaminfo,
2461 .strict_lock_check_fn = catia_strict_lock_check,
2462 .translate_name_fn = catia_translate_name,
2463 .fsctl_fn = catia_fsctl,
2464 .get_dos_attributes_fn = catia_get_dos_attributes,
2465 .get_dos_attributes_send_fn = vfs_not_implemented_get_dos_attributes_send,
2466 .get_dos_attributes_recv_fn = vfs_not_implemented_get_dos_attributes_recv,
2467 .set_dos_attributes_fn = catia_set_dos_attributes,
2468 .fset_dos_attributes_fn = catia_fset_dos_attributes,
2469 .fget_dos_attributes_fn = catia_fget_dos_attributes,
2470 .get_compression_fn = catia_get_compression,
2471 .set_compression_fn = catia_set_compression,
2473 /* NT ACL operations. */
2474 .get_nt_acl_fn = catia_get_nt_acl,
2475 .fget_nt_acl_fn = catia_fget_nt_acl,
2476 .fset_nt_acl_fn = catia_fset_nt_acl,
2478 /* POSIX ACL operations. */
2479 .sys_acl_get_file_fn = catia_sys_acl_get_file,
2480 .sys_acl_get_fd_fn = catia_sys_acl_get_fd,
2481 .sys_acl_blob_get_fd_fn = catia_sys_acl_blob_get_fd,
2482 .sys_acl_set_file_fn = catia_sys_acl_set_file,
2483 .sys_acl_set_fd_fn = catia_sys_acl_set_fd,
2484 .sys_acl_delete_def_file_fn = catia_sys_acl_delete_def_file,
2486 /* EA operations. */
2487 .getxattr_fn = catia_getxattr,
2488 .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
2489 .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
2490 .listxattr_fn = catia_listxattr,
2491 .removexattr_fn = catia_removexattr,
2492 .setxattr_fn = catia_setxattr,
2493 .fgetxattr_fn = catia_fgetxattr,
2494 .flistxattr_fn = catia_flistxattr,
2495 .fremovexattr_fn = catia_fremovexattr,
2496 .fsetxattr_fn = catia_fsetxattr,
2500 NTSTATUS vfs_catia_init(TALLOC_CTX *ctx)
2504 ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "catia",
2506 if (!NT_STATUS_IS_OK(ret))
2509 vfs_catia_debug_level = debug_add_class("catia");
2510 if (vfs_catia_debug_level == -1) {
2511 vfs_catia_debug_level = DBGC_VFS;
2512 DEBUG(0, ("vfs_catia: Couldn't register custom debugging "
2515 DEBUG(10, ("vfs_catia: Debug class number of "
2516 "'catia': %d\n", vfs_catia_debug_level));